aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunfeng Yun <chunfeng.yun@mediatek.com>2019-03-20 22:53:45 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-03-26 03:40:13 -0400
commit48e0d3735aa557a8adaf94632ca3cf78798e8505 (patch)
tree8769798ea7b0a5a9410580bd5c15f0ad5b55ca06
parent09befc326eea250cf6a3175114e1578d498a21ea (diff)
usb: mtu3: supports new QMU format
In order to support U3gen2 ISOC transfer upto 96DPs, extend the data buffer length. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/mtu3/mtu3.h11
-rw-r--r--drivers/usb/mtu3/mtu3_core.c5
-rw-r--r--drivers/usb/mtu3/mtu3_gadget.c6
-rw-r--r--drivers/usb/mtu3/mtu3_hw_regs.h1
-rw-r--r--drivers/usb/mtu3/mtu3_qmu.c64
-rw-r--r--drivers/usb/mtu3/mtu3_qmu.h1
6 files changed, 66 insertions, 22 deletions
diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h
index 4dda7ed6e24e..76ecf12fdf62 100644
--- a/drivers/usb/mtu3/mtu3.h
+++ b/drivers/usb/mtu3/mtu3.h
@@ -148,22 +148,23 @@ struct mtu3_fifo_info {
148 * bit0: Hardware Own (HWO) 148 * bit0: Hardware Own (HWO)
149 * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported 149 * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported
150 * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1 150 * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1
151 * bit6: [EL] Zero Length Packet (ZLP), moved from @dw3_info[29]
151 * bit7: Interrupt On Completion (IOC) 152 * bit7: Interrupt On Completion (IOC)
152 * bit[31:16]: allow data buffer length (RX ONLY), 153 * bit[31:16]: ([EL] bit[31:12]) allow data buffer length (RX ONLY),
153 * the buffer length of the data to receive 154 * the buffer length of the data to receive
154 * bit[23:16]: extension address (TX ONLY), 155 * bit[23:16]: ([EL] bit[31:24]) extension address (TX ONLY),
155 * lower 4 bits are extension bits of @buffer, 156 * lower 4 bits are extension bits of @buffer,
156 * upper 4 bits are extension bits of @next_gpd 157 * upper 4 bits are extension bits of @next_gpd
157 * @next_gpd: Physical address of the next GPD 158 * @next_gpd: Physical address of the next GPD
158 * @buffer: Physical address of the data buffer 159 * @buffer: Physical address of the data buffer
159 * @dw3_info: 160 * @dw3_info:
160 * bit[15:0]: data buffer length, 161 * bit[15:0]: ([EL] bit[19:0]) data buffer length,
161 * (TX): the buffer length of the data to transmit 162 * (TX): the buffer length of the data to transmit
162 * (RX): The total length of data received 163 * (RX): The total length of data received
163 * bit[23:16]: extension address (RX ONLY), 164 * bit[23:16]: ([EL] bit[31:24]) extension address (RX ONLY),
164 * lower 4 bits are extension bits of @buffer, 165 * lower 4 bits are extension bits of @buffer,
165 * upper 4 bits are extension bits of @next_gpd 166 * upper 4 bits are extension bits of @next_gpd
166 * bit29: Zero Length Packet (ZLP) (TX ONLY) 167 * bit29: ([EL] abandoned) Zero Length Packet (ZLP) (TX ONLY)
167 */ 168 */
168struct qmu_gpd { 169struct qmu_gpd {
169 __le32 dw0_info; 170 __le32 dw0_info;
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index ef27c2052ad6..d354f5c3805a 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -601,6 +601,10 @@ static void mtu3_regs_init(struct mtu3 *mtu)
601 mtu3_clrbits(mbase, U3D_MISC_CTRL, VBUS_FRC_EN | VBUS_ON); 601 mtu3_clrbits(mbase, U3D_MISC_CTRL, VBUS_FRC_EN | VBUS_ON);
602 /* enable automatical HWRW from L1 */ 602 /* enable automatical HWRW from L1 */
603 mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, LPM_HRWE); 603 mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, LPM_HRWE);
604
605 /* use new QMU format when HW version >= 0x1003 */
606 if (mtu->gen2cp)
607 mtu3_writel(mbase, U3D_QFCR, ~0x0);
604} 608}
605 609
606static irqreturn_t mtu3_link_isr(struct mtu3 *mtu) 610static irqreturn_t mtu3_link_isr(struct mtu3 *mtu)
@@ -755,6 +759,7 @@ static int mtu3_hw_init(struct mtu3 *mtu)
755 759
756 value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS); 760 value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS);
757 mtu->hw_version = IP_TRUNK_VERS(value); 761 mtu->hw_version = IP_TRUNK_VERS(value);
762 mtu->gen2cp = !!(mtu->hw_version >= MTU3_TRUNK_VERS_1003);
758 763
759 value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP); 764 value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP);
760 mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value); 765 mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value);
diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index bbcd3332471d..fe798b94a357 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -278,10 +278,12 @@ static int mtu3_gadget_queue(struct usb_ep *ep,
278 __func__, mep->is_in ? "TX" : "RX", mreq->epnum, ep->name, 278 __func__, mep->is_in ? "TX" : "RX", mreq->epnum, ep->name,
279 mreq, ep->maxpacket, mreq->request.length); 279 mreq, ep->maxpacket, mreq->request.length);
280 280
281 if (req->length > GPD_BUF_SIZE) { 281 if (req->length > GPD_BUF_SIZE ||
282 (mtu->gen2cp && req->length > GPD_BUF_SIZE_EL)) {
282 dev_warn(mtu->dev, 283 dev_warn(mtu->dev,
283 "req length > supported MAX:%d requested:%d\n", 284 "req length > supported MAX:%d requested:%d\n",
284 GPD_BUF_SIZE, req->length); 285 mtu->gen2cp ? GPD_BUF_SIZE_EL : GPD_BUF_SIZE,
286 req->length);
285 return -EOPNOTSUPP; 287 return -EOPNOTSUPP;
286 } 288 }
287 289
diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h
index fae3b8de1092..bf70ea2426a9 100644
--- a/drivers/usb/mtu3/mtu3_hw_regs.h
+++ b/drivers/usb/mtu3/mtu3_hw_regs.h
@@ -49,6 +49,7 @@
49#define U3D_QCR1 (SSUSB_DEV_BASE + 0x0404) 49#define U3D_QCR1 (SSUSB_DEV_BASE + 0x0404)
50#define U3D_QCR2 (SSUSB_DEV_BASE + 0x0408) 50#define U3D_QCR2 (SSUSB_DEV_BASE + 0x0408)
51#define U3D_QCR3 (SSUSB_DEV_BASE + 0x040C) 51#define U3D_QCR3 (SSUSB_DEV_BASE + 0x040C)
52#define U3D_QFCR (SSUSB_DEV_BASE + 0x0428)
52#define U3D_TXQHIAR1 (SSUSB_DEV_BASE + 0x0484) 53#define U3D_TXQHIAR1 (SSUSB_DEV_BASE + 0x0484)
53#define U3D_RXQHIAR1 (SSUSB_DEV_BASE + 0x04C4) 54#define U3D_RXQHIAR1 (SSUSB_DEV_BASE + 0x04C4)
54 55
diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c
index 7a1919fc9f9e..9f017aa8fbeb 100644
--- a/drivers/usb/mtu3/mtu3_qmu.c
+++ b/drivers/usb/mtu3/mtu3_qmu.c
@@ -28,14 +28,42 @@
28#define GPD_FLAGS_HWO BIT(0) 28#define GPD_FLAGS_HWO BIT(0)
29#define GPD_FLAGS_BDP BIT(1) 29#define GPD_FLAGS_BDP BIT(1)
30#define GPD_FLAGS_BPS BIT(2) 30#define GPD_FLAGS_BPS BIT(2)
31#define GPD_FLAGS_ZLP BIT(6)
31#define GPD_FLAGS_IOC BIT(7) 32#define GPD_FLAGS_IOC BIT(7)
32#define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO) 33#define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO)
33 34
34#define GPD_RX_BUF_LEN(x) (((x) & 0xffff) << 16) 35#define GPD_RX_BUF_LEN_OG(x) (((x) & 0xffff) << 16)
35#define GPD_DATA_LEN(x) ((x) & 0xffff) 36#define GPD_RX_BUF_LEN_EL(x) (((x) & 0xfffff) << 12)
37#define GPD_RX_BUF_LEN(mtu, x) \
38({ \
39 typeof(x) x_ = (x); \
40 ((mtu)->gen2cp) ? GPD_RX_BUF_LEN_EL(x_) : GPD_RX_BUF_LEN_OG(x_); \
41})
42
43#define GPD_DATA_LEN_OG(x) ((x) & 0xffff)
44#define GPD_DATA_LEN_EL(x) ((x) & 0xfffff)
45#define GPD_DATA_LEN(mtu, x) \
46({ \
47 typeof(x) x_ = (x); \
48 ((mtu)->gen2cp) ? GPD_DATA_LEN_EL(x_) : GPD_DATA_LEN_OG(x_); \
49})
50
36#define GPD_EXT_FLAG_ZLP BIT(29) 51#define GPD_EXT_FLAG_ZLP BIT(29)
37#define GPD_EXT_NGP(x) (((x) & 0xf) << 20) 52#define GPD_EXT_NGP_OG(x) (((x) & 0xf) << 20)
38#define GPD_EXT_BUF(x) (((x) & 0xf) << 16) 53#define GPD_EXT_BUF_OG(x) (((x) & 0xf) << 16)
54#define GPD_EXT_NGP_EL(x) (((x) & 0xf) << 28)
55#define GPD_EXT_BUF_EL(x) (((x) & 0xf) << 24)
56#define GPD_EXT_NGP(mtu, x) \
57({ \
58 typeof(x) x_ = (x); \
59 ((mtu)->gen2cp) ? GPD_EXT_NGP_EL(x_) : GPD_EXT_NGP_OG(x_); \
60})
61
62#define GPD_EXT_BUF(mtu, x) \
63({ \
64 typeof(x) x_ = (x); \
65 ((mtu)->gen2cp) ? GPD_EXT_BUF_EL(x_) : GPD_EXT_BUF_OG(x_); \
66})
39 67
40#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo)) 68#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo))
41#define HILO_DMA(hi, lo) \ 69#define HILO_DMA(hi, lo) \
@@ -217,13 +245,14 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
217 struct mtu3_gpd_ring *ring = &mep->gpd_ring; 245 struct mtu3_gpd_ring *ring = &mep->gpd_ring;
218 struct qmu_gpd *gpd = ring->enqueue; 246 struct qmu_gpd *gpd = ring->enqueue;
219 struct usb_request *req = &mreq->request; 247 struct usb_request *req = &mreq->request;
248 struct mtu3 *mtu = mep->mtu;
220 dma_addr_t enq_dma; 249 dma_addr_t enq_dma;
221 u32 ext_addr; 250 u32 ext_addr;
222 251
223 gpd->dw0_info = 0; /* SW own it */ 252 gpd->dw0_info = 0; /* SW own it */
224 gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); 253 gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
225 ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); 254 ext_addr = GPD_EXT_BUF(mtu, upper_32_bits(req->dma));
226 gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(req->length)); 255 gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(mtu, req->length));
227 256
228 /* get the next GPD */ 257 /* get the next GPD */
229 enq = advance_enq_gpd(ring); 258 enq = advance_enq_gpd(ring);
@@ -233,11 +262,15 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
233 262
234 enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO); 263 enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
235 gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); 264 gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
236 ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); 265 ext_addr |= GPD_EXT_NGP(mtu, upper_32_bits(enq_dma));
237 gpd->dw0_info = cpu_to_le32(ext_addr); 266 gpd->dw0_info = cpu_to_le32(ext_addr);
238 267
239 if (req->zero) 268 if (req->zero) {
240 gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP); 269 if (mtu->gen2cp)
270 gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_ZLP);
271 else
272 gpd->dw3_info |= cpu_to_le32(GPD_EXT_FLAG_ZLP);
273 }
241 274
242 gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO); 275 gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
243 276
@@ -252,13 +285,14 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
252 struct mtu3_gpd_ring *ring = &mep->gpd_ring; 285 struct mtu3_gpd_ring *ring = &mep->gpd_ring;
253 struct qmu_gpd *gpd = ring->enqueue; 286 struct qmu_gpd *gpd = ring->enqueue;
254 struct usb_request *req = &mreq->request; 287 struct usb_request *req = &mreq->request;
288 struct mtu3 *mtu = mep->mtu;
255 dma_addr_t enq_dma; 289 dma_addr_t enq_dma;
256 u32 ext_addr; 290 u32 ext_addr;
257 291
258 gpd->dw0_info = 0; /* SW own it */ 292 gpd->dw0_info = 0; /* SW own it */
259 gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); 293 gpd->buffer = cpu_to_le32(lower_32_bits(req->dma));
260 ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); 294 ext_addr = GPD_EXT_BUF(mtu, upper_32_bits(req->dma));
261 gpd->dw0_info = cpu_to_le32(GPD_RX_BUF_LEN(req->length)); 295 gpd->dw0_info = cpu_to_le32(GPD_RX_BUF_LEN(mtu, req->length));
262 296
263 /* get the next GPD */ 297 /* get the next GPD */
264 enq = advance_enq_gpd(ring); 298 enq = advance_enq_gpd(ring);
@@ -268,7 +302,7 @@ static int mtu3_prepare_rx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq)
268 302
269 enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO); 303 enq->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO);
270 gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); 304 gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma));
271 ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); 305 ext_addr |= GPD_EXT_NGP(mtu, upper_32_bits(enq_dma));
272 gpd->dw3_info = cpu_to_le32(ext_addr); 306 gpd->dw3_info = cpu_to_le32(ext_addr);
273 gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO); 307 gpd->dw0_info |= cpu_to_le32(GPD_FLAGS_IOC | GPD_FLAGS_HWO);
274 308
@@ -391,7 +425,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum)
391 cur_gpd_dma = read_txq_cur_addr(mbase, epnum); 425 cur_gpd_dma = read_txq_cur_addr(mbase, epnum);
392 gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma); 426 gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma);
393 427
394 if (GPD_DATA_LEN(le32_to_cpu(gpd_current->dw3_info)) != 0) { 428 if (GPD_DATA_LEN(mtu, le32_to_cpu(gpd_current->dw3_info)) != 0) {
395 dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum); 429 dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum);
396 return; 430 return;
397 } 431 }
@@ -451,7 +485,7 @@ static void qmu_done_tx(struct mtu3 *mtu, u8 epnum)
451 } 485 }
452 486
453 request = &mreq->request; 487 request = &mreq->request;
454 request->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info)); 488 request->actual = GPD_DATA_LEN(mtu, le32_to_cpu(gpd->dw3_info));
455 mtu3_req_complete(mep, request, 0); 489 mtu3_req_complete(mep, request, 0);
456 490
457 gpd = advance_deq_gpd(ring); 491 gpd = advance_deq_gpd(ring);
@@ -489,7 +523,7 @@ static void qmu_done_rx(struct mtu3 *mtu, u8 epnum)
489 } 523 }
490 req = &mreq->request; 524 req = &mreq->request;
491 525
492 req->actual = GPD_DATA_LEN(le32_to_cpu(gpd->dw3_info)); 526 req->actual = GPD_DATA_LEN(mtu, le32_to_cpu(gpd->dw3_info));
493 mtu3_req_complete(mep, req, 0); 527 mtu3_req_complete(mep, req, 0);
494 528
495 gpd = advance_deq_gpd(ring); 529 gpd = advance_deq_gpd(ring);
diff --git a/drivers/usb/mtu3/mtu3_qmu.h b/drivers/usb/mtu3/mtu3_qmu.h
index 81f5151a55ed..9cfde201db63 100644
--- a/drivers/usb/mtu3/mtu3_qmu.h
+++ b/drivers/usb/mtu3/mtu3_qmu.h
@@ -15,6 +15,7 @@
15#define QMU_GPD_RING_SIZE (MAX_GPD_NUM * QMU_GPD_SIZE) 15#define QMU_GPD_RING_SIZE (MAX_GPD_NUM * QMU_GPD_SIZE)
16 16
17#define GPD_BUF_SIZE 65532 17#define GPD_BUF_SIZE 65532
18#define GPD_BUF_SIZE_EL 1048572
18 19
19void mtu3_qmu_stop(struct mtu3_ep *mep); 20void mtu3_qmu_stop(struct mtu3_ep *mep);
20int mtu3_qmu_start(struct mtu3_ep *mep); 21int mtu3_qmu_start(struct mtu3_ep *mep);