* bit0: Hardware Own (HWO)
* bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported
* bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1
+ * bit6: [EL] Zero Length Packet (ZLP), moved from @dw3_info[29]
* bit7: Interrupt On Completion (IOC)
- * bit[31:16]: allow data buffer length (RX ONLY),
+ * bit[31:16]: ([EL] bit[31:12]) allow data buffer length (RX ONLY),
* the buffer length of the data to receive
- * bit[23:16]: extension address (TX ONLY),
+ * bit[23:16]: ([EL] bit[31:24]) extension address (TX ONLY),
* lower 4 bits are extension bits of @buffer,
* upper 4 bits are extension bits of @next_gpd
* @next_gpd: Physical address of the next GPD
* @buffer: Physical address of the data buffer
* @dw3_info:
- * bit[15:0]: data buffer length,
+ * bit[15:0]: ([EL] bit[19:0]) data buffer length,
* (TX): the buffer length of the data to transmit
* (RX): The total length of data received
- * bit[23:16]: extension address (RX ONLY),
+ * bit[23:16]: ([EL] bit[31:24]) extension address (RX ONLY),
* lower 4 bits are extension bits of @buffer,
* upper 4 bits are extension bits of @next_gpd
- * bit29: Zero Length Packet (ZLP) (TX ONLY)
+ * bit29: ([EL] abandoned) Zero Length Packet (ZLP) (TX ONLY)
*/
struct qmu_gpd {
__le32 dw0_info;
#define GPD_FLAGS_HWO BIT(0)
#define GPD_FLAGS_BDP BIT(1)
#define GPD_FLAGS_BPS BIT(2)
+#define GPD_FLAGS_ZLP BIT(6)
#define GPD_FLAGS_IOC BIT(7)
#define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO)
-#define GPD_RX_BUF_LEN(x) (((x) & 0xffff) << 16)
-#define GPD_DATA_LEN(x) ((x) & 0xffff)
+#define GPD_RX_BUF_LEN_OG(x) (((x) & 0xffff) << 16)
+#define GPD_RX_BUF_LEN_EL(x) (((x) & 0xfffff) << 12)
+#define GPD_RX_BUF_LEN(mtu, x) \
+({ \
+ typeof(x) x_ = (x); \
+ ((mtu)->gen2cp) ? GPD_RX_BUF_LEN_EL(x_) : GPD_RX_BUF_LEN_OG(x_); \
+})
+
+#define GPD_DATA_LEN_OG(x) ((x) & 0xffff)
+#define GPD_DATA_LEN_EL(x) ((x) & 0xfffff)
+#define GPD_DATA_LEN(mtu, x) \
+({ \
+ typeof(x) x_ = (x); \
+ ((mtu)->gen2cp) ? GPD_DATA_LEN_EL(x_) : GPD_DATA_LEN_OG(x_); \
+})
+
#define GPD_EXT_FLAG_ZLP BIT(29)
-#define GPD_EXT_NGP(x) (((x) & 0xf) << 20)
-#define GPD_EXT_BUF(x) (((x) & 0xf) << 16)
+#define GPD_EXT_NGP_OG(x) (((x) & 0xf) << 20)
+#define GPD_EXT_BUF_OG(x) (((x) & 0xf) << 16)
+#define GPD_EXT_NGP_EL(x) (((x) & 0xf) << 28)
+#define GPD_EXT_BUF_EL(x) (((x) & 0xf) << 24)
+#define GPD_EXT_NGP(mtu, x) \
+({ \
+ typeof(x) x_ = (x); \
+ ((mtu)->gen2cp) ? GPD_EXT_NGP_EL(x_) : GPD_EXT_NGP_OG(x_); \
+})
+
+#define GPD_EXT_BUF(mtu, x) \
+({ \
+ typeof(x) x_ = (x); \
+ ((mtu)->gen2cp) ? GPD_EXT_BUF_EL(x_) : GPD_EXT_BUF_OG(x_); \
+})
#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo))
#define HILO_DMA(hi, lo) \
struct mtu3_gpd_ring *ring = &mep->gpd_ring;
struct qmu_gpd *gpd = ring->enqueue;
struct usb_request *req = &mreq->request;
+ struct mtu3 *mtu = mep->mtu;
dma_addr_t enq_dma;
u32 ext_addr;
gpd->dw0_info = 0; /* SW own it */
gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
- ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
- gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(req->length));
+ ext_addr = GPD_EXT_BUF(mtu, upper_32_bits(req->dma));
+ gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(mtu, req->length));
/* get the next GPD */
enq = advance_enq_gpd(ring);
enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
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(mtu, upper_32_bits(enq_dma));
gpd->dw0_info = cpu_to_le32(ext_addr);
- if (req->zero)
- gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
+ if (req->zero) {
+ if (mtu->gen2cp)
+ gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_ZLP);
+ else
+ gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
+ }
gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
struct mtu3_gpd_ring *ring = &mep->gpd_ring;
struct qmu_gpd *gpd = ring->enqueue;
struct usb_request *req = &mreq->request;
+ struct mtu3 *mtu = mep->mtu;
dma_addr_t enq_dma;
u32 ext_addr;
gpd->dw0_info = 0; /* SW own it */
gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
- ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma));
- gpd->dw0_info = cpu_to_le32(GPD_RX_BUF_LEN(req->length));
+ ext_addr = GPD_EXT_BUF(mtu, upper_32_bits(req->dma));
+ gpd->dw0_info = cpu_to_le32(GPD_RX_BUF_LEN(mtu, req->length));
/* get the next GPD */
enq = advance_enq_gpd(ring);
enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
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(mtu, upper_32_bits(enq_dma));
gpd->dw3_info = cpu_to_le32(ext_addr);
gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
cur_gpd_dma = read_txq_cur_addr(mbase, epnum);
gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
- if (GPD_DATA_LEN(le32_to_cpu(gpd_current->dw3_info)) != 0) {
+ if (GPD_DATA_LEN(mtu, le32_to_cpu(gpd_current->dw3_info)) != 0) {
dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum);
return;
}
}
request = &mreq->request;
- request->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info));
+ request->actual = GPD_DATA_LEN(mtu, le32_to_cpu(gpd->dw3_info));
mtu3_req_complete(mep, request, 0);
gpd = advance_deq_gpd(ring);
}
req = &mreq->request;
- req->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info));
+ req->actual = GPD_DATA_LEN(mtu, le32_to_cpu(gpd->dw3_info));
mtu3_req_complete(mep, req, 0);
gpd = advance_deq_gpd(ring);