Commit 09befc32 authored by Chunfeng Yun's avatar Chunfeng Yun Committed by Greg Kroah-Hartman

usb: mtu3: rebuild qmu_gpd struct to prepare to support new QMU format

To support USB3 Gen2 ISOC, the data buffer length need be extended,
it's hard to make the current qmu_gpd struct compatible, so here
rebuild qmu_gpd struct and make easy to support new QMU format
Signed-off-by: default avatarChunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4c5964b4
...@@ -144,45 +144,32 @@ struct mtu3_fifo_info { ...@@ -144,45 +144,32 @@ struct mtu3_fifo_info {
* The format of TX GPD is a little different from RX one. * The format of TX GPD is a little different from RX one.
* And the size of GPD is 16 bytes. * And the size of GPD is 16 bytes.
* *
* @flag: * @dw0_info:
* bit0: Hardware Own (HWO) * bit0: Hardware Own (HWO)
* bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported
* bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1 * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1
* bit7: Interrupt On Completion (IOC) * bit7: Interrupt On Completion (IOC)
* @chksum: This is used to validate the contents of this GPD; * bit[31:16]: allow data buffer length (RX ONLY),
* If TXQ_CS_EN / RXQ_CS_EN bit is set, an interrupt is issued * the buffer length of the data to receive
* when checksum validation fails; * bit[23:16]: extension address (TX ONLY),
* Checksum value is calculated over the 16 bytes of the GPD by default; * lower 4 bits are extension bits of @buffer,
* @data_buf_len (RX ONLY): This value indicates the length of * upper 4 bits are extension bits of @next_gpd
* the assigned data buffer
* @tx_ext_addr (TX ONLY): [3:0] are 4 extension bits of @buffer,
* [7:4] are 4 extension bits of @next_gpd
* @next_gpd: Physical address of the next GPD * @next_gpd: Physical address of the next GPD
* @buffer: Physical address of the data buffer * @buffer: Physical address of the data buffer
* @buf_len: * @dw3_info:
* (TX): This value indicates the length of the assigned data buffer * bit[15:0]: data buffer length,
* (RX): The total length of data received * (TX): the buffer length of the data to transmit
* @ext_len: reserved * (RX): The total length of data received
* @rx_ext_addr(RX ONLY): [3:0] are 4 extension bits of @buffer, * bit[23:16]: extension address (RX ONLY),
* [7:4] are 4 extension bits of @next_gpd * lower 4 bits are extension bits of @buffer,
* @ext_flag: * upper 4 bits are extension bits of @next_gpd
* bit5 (TX ONLY): Zero Length Packet (ZLP), * bit29: Zero Length Packet (ZLP) (TX ONLY)
*/ */
struct qmu_gpd { struct qmu_gpd {
__u8 flag; __le32 dw0_info;
__u8 chksum;
union {
__le16 data_buf_len;
__le16 tx_ext_addr;
};
__le32 next_gpd; __le32 next_gpd;
__le32 buffer; __le32 buffer;
__le16 buf_len; __le32 dw3_info;
union {
__u8 ext_len;
__u8 rx_ext_addr;
};
__u8 ext_flag;
} __packed; } __packed;
/** /**
......
...@@ -29,10 +29,13 @@ ...@@ -29,10 +29,13 @@
#define GPD_FLAGS_BDP BIT(1) #define GPD_FLAGS_BDP BIT(1)
#define GPD_FLAGS_BPS BIT(2) #define GPD_FLAGS_BPS BIT(2)
#define GPD_FLAGS_IOC BIT(7) #define GPD_FLAGS_IOC BIT(7)
#define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO)
#define GPD_EXT_FLAG_ZLP BIT(5) #define GPD_RX_BUF_LEN(x) (((x) & 0xffff) << 16)
#define GPD_EXT_NGP(x) (((x) & 0xf) << 4) #define GPD_DATA_LEN(x) ((x) & 0xffff)
#define GPD_EXT_BUF(x) (((x) & 0xf) << 0) #define GPD_EXT_FLAG_ZLP BIT(29)
#define GPD_EXT_NGP(x) (((x) & 0xf) << 20)
#define GPD_EXT_BUF(x) (((x) & 0xf) << 16)
#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo)) #define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo))
#define HILO_DMA(hi, lo) \ #define HILO_DMA(hi, lo) \
...@@ -125,7 +128,7 @@ static void reset_gpd_list(struct mtu3_ep *mep) ...@@ -125,7 +128,7 @@ static void reset_gpd_list(struct mtu3_ep *mep)
struct qmu_gpd *gpd = ring->start; struct qmu_gpd *gpd = ring->start;
if (gpd) { if (gpd) {
gpd->flag &= ~GPD_FLAGS_HWO; gpd->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
gpd_ring_init(ring, gpd); gpd_ring_init(ring, gpd);
} }
} }
...@@ -215,15 +218,12 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) ...@@ -215,15 +218,12 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
struct qmu_gpd *gpd = ring->enqueue; struct qmu_gpd *gpd = ring->enqueue;
struct usb_request *req = &mreq->request; struct usb_request *req = &mreq->request;
dma_addr_t enq_dma; dma_addr_t enq_dma;
u16 ext_addr; u32 ext_addr;
/* set all fields to zero as default value */
memset(gpd, 0, sizeof(*gpd));
gpd->dw0_info = 0; /* SW own it */
gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
gpd->buf_len = cpu_to_le16(req->length); gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(req->length));
gpd->flag |= GPD_FLAGS_IOC;
/* get the next GPD */ /* get the next GPD */
enq = advance_enq_gpd(ring); enq = advance_enq_gpd(ring);
...@@ -231,15 +231,15 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) ...@@ -231,15 +231,15 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n", dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n",
mep->epnum, gpd, enq, &enq_dma); mep->epnum, gpd, enq, &enq_dma);
enq->flag &= ~GPD_FLAGS_HWO; enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma));
gpd->tx_ext_addr = cpu_to_le16(ext_addr); gpd->dw0_info = cpu_to_le32(ext_addr);
if (req->zero) if (req->zero)
gpd->ext_flag |= GPD_EXT_FLAG_ZLP; gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
gpd->flag |= GPD_FLAGS_HWO; gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
mreq->gpd = gpd; mreq->gpd = gpd;
...@@ -253,15 +253,12 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) ...@@ -253,15 +253,12 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
struct qmu_gpd *gpd = ring->enqueue; struct qmu_gpd *gpd = ring->enqueue;
struct usb_request *req = &mreq->request; struct usb_request *req = &mreq->request;
dma_addr_t enq_dma; dma_addr_t enq_dma;
u16 ext_addr; u32 ext_addr;
/* set all fields to zero as default value */
memset(gpd, 0, sizeof(*gpd));
gpd->dw0_info = 0; /* SW own it */
gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
gpd->data_buf_len = cpu_to_le16(req->length); gpd->dw0_info = cpu_to_le32(GPD_RX_BUF_LEN(req->length));
gpd->flag |= GPD_FLAGS_IOC;
/* get the next GPD */ /* get the next GPD */
enq = advance_enq_gpd(ring); enq = advance_enq_gpd(ring);
...@@ -269,11 +266,11 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) ...@@ -269,11 +266,11 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n", dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n",
mep->epnum, gpd, enq, &enq_dma); mep->epnum, gpd, enq, &enq_dma);
enq->flag &= ~GPD_FLAGS_HWO; enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma));
gpd->rx_ext_addr = cpu_to_le16(ext_addr); gpd->dw3_info = cpu_to_le32(ext_addr);
gpd->flag |= GPD_FLAGS_HWO; gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
mreq->gpd = gpd; mreq->gpd = gpd;
...@@ -394,7 +391,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum) ...@@ -394,7 +391,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
cur_gpd_dma = read_txq_cur_addr(mbase, epnum); cur_gpd_dma = read_txq_cur_addr(mbase, epnum);
gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma); gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
if (le16_to_cpu(gpd_current->buf_len) != 0) { if (GPD_DATA_LEN(le32_to_cpu(gpd_current->dw3_info)) != 0) {
dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum); dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum);
return; return;
} }
...@@ -412,8 +409,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum) ...@@ -412,8 +409,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_TXPKTRDY); mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_TXPKTRDY);
/* by pass the current GDP */ /* by pass the current GDP */
gpd_current->flag |= GPD_FLAGS_BPS; gpd_current->dw0_info |= cpu_to_le32(GPD_FLAGS_BPS | GPD_FLAGS_HWO);
gpd_current->flag |= GPD_FLAGS_HWO;
/*enable DMAREQEN, switch back to QMU mode */ /*enable DMAREQEN, switch back to QMU mode */
mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_DMAREQEN); mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_DMAREQEN);
...@@ -445,7 +441,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum) ...@@ -445,7 +441,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
__func__, epnum, gpd, gpd_current, ring->enqueue); __func__, epnum, gpd, gpd_current, ring->enqueue);
while (gpd != gpd_current && !(gpd->flag & GPD_FLAGS_HWO)) { while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
mreq = next_request(mep); mreq = next_request(mep);
...@@ -455,7 +451,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum) ...@@ -455,7 +451,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
} }
request = &mreq->request; request = &mreq->request;
request->actual = le16_to_cpu(gpd->buf_len); request->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info));
mtu3_req_complete(mep, request, 0); mtu3_req_complete(mep, request, 0);
gpd = advance_deq_gpd(ring); gpd = advance_deq_gpd(ring);
...@@ -483,7 +479,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum) ...@@ -483,7 +479,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n",
__func__, epnum, gpd, gpd_current, ring->enqueue); __func__, epnum, gpd, gpd_current, ring->enqueue);
while (gpd != gpd_current && !(gpd->flag & GPD_FLAGS_HWO)) { while (gpd != gpd_current && !GET_GPD_HWO(gpd)) {
mreq = next_request(mep); mreq = next_request(mep);
...@@ -493,7 +489,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum) ...@@ -493,7 +489,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
} }
req = &mreq->request; req = &mreq->request;
req->actual = le16_to_cpu(gpd->buf_len); req->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info));
mtu3_req_complete(mep, req, 0); mtu3_req_complete(mep, req, 0);
gpd = advance_deq_gpd(ring); gpd = advance_deq_gpd(ring);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment