OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From d366bf086a61b7a895d8819a3c1349b9c6b8e40f Mon Sep 17 00:00:00 2001 |
2 | From: Chunfeng Yun <chunfeng.yun@mediatek.com> |
||
3 | Date: Fri, 13 Oct 2017 17:10:41 +0800 |
||
4 | Subject: [PATCH 107/224] usb: mtu3: support 36-bit DMA address |
||
5 | |||
6 | add support for 36-bit DMA address |
||
7 | |||
8 | [ Felipe Balbi: fix printk format for dma_addr_t ] |
||
9 | |||
10 | Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> |
||
11 | Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> |
||
12 | --- |
||
13 | drivers/usb/mtu3/mtu3.h | 17 ++++++- |
||
14 | drivers/usb/mtu3/mtu3_core.c | 34 +++++++++++++- |
||
15 | drivers/usb/mtu3/mtu3_hw_regs.h | 10 ++++ |
||
16 | drivers/usb/mtu3/mtu3_qmu.c | 102 +++++++++++++++++++++++++++++++++------- |
||
17 | 4 files changed, 142 insertions(+), 21 deletions(-) |
||
18 | |||
19 | --- a/drivers/usb/mtu3/mtu3.h |
||
20 | +++ b/drivers/usb/mtu3/mtu3.h |
||
21 | @@ -46,6 +46,9 @@ struct mtu3_request; |
||
22 | #define MU3D_EP_RXCR1(epnum) (U3D_RX1CSR1 + (((epnum) - 1) * 0x10)) |
||
23 | #define MU3D_EP_RXCR2(epnum) (U3D_RX1CSR2 + (((epnum) - 1) * 0x10)) |
||
24 | |||
25 | +#define USB_QMU_TQHIAR(epnum) (U3D_TXQHIAR1 + (((epnum) - 1) * 0x4)) |
||
26 | +#define USB_QMU_RQHIAR(epnum) (U3D_RXQHIAR1 + (((epnum) - 1) * 0x4)) |
||
27 | + |
||
28 | #define USB_QMU_RQCSR(epnum) (U3D_RXQCSR1 + (((epnum) - 1) * 0x10)) |
||
29 | #define USB_QMU_RQSAR(epnum) (U3D_RXQSAR1 + (((epnum) - 1) * 0x10)) |
||
30 | #define USB_QMU_RQCPR(epnum) (U3D_RXQCPR1 + (((epnum) - 1) * 0x10)) |
||
31 | @@ -138,23 +141,33 @@ struct mtu3_fifo_info { |
||
32 | * Checksum value is calculated over the 16 bytes of the GPD by default; |
||
33 | * @data_buf_len (RX ONLY): This value indicates the length of |
||
34 | * the assigned data buffer |
||
35 | + * @tx_ext_addr (TX ONLY): [3:0] are 4 extension bits of @buffer, |
||
36 | + * [7:4] are 4 extension bits of @next_gpd |
||
37 | * @next_gpd: Physical address of the next GPD |
||
38 | * @buffer: Physical address of the data buffer |
||
39 | * @buf_len: |
||
40 | * (TX): This value indicates the length of the assigned data buffer |
||
41 | * (RX): The total length of data received |
||
42 | * @ext_len: reserved |
||
43 | + * @rx_ext_addr(RX ONLY): [3:0] are 4 extension bits of @buffer, |
||
44 | + * [7:4] are 4 extension bits of @next_gpd |
||
45 | * @ext_flag: |
||
46 | * bit5 (TX ONLY): Zero Length Packet (ZLP), |
||
47 | */ |
||
48 | struct qmu_gpd { |
||
49 | __u8 flag; |
||
50 | __u8 chksum; |
||
51 | - __le16 data_buf_len; |
||
52 | + union { |
||
53 | + __le16 data_buf_len; |
||
54 | + __le16 tx_ext_addr; |
||
55 | + }; |
||
56 | __le32 next_gpd; |
||
57 | __le32 buffer; |
||
58 | __le16 buf_len; |
||
59 | - __u8 ext_len; |
||
60 | + union { |
||
61 | + __u8 ext_len; |
||
62 | + __u8 rx_ext_addr; |
||
63 | + }; |
||
64 | __u8 ext_flag; |
||
65 | } __packed; |
||
66 | |||
67 | --- a/drivers/usb/mtu3/mtu3_core.c |
||
68 | +++ b/drivers/usb/mtu3/mtu3_core.c |
||
69 | @@ -17,6 +17,7 @@ |
||
70 | * |
||
71 | */ |
||
72 | |||
73 | +#include <linux/dma-mapping.h> |
||
74 | #include <linux/kernel.h> |
||
75 | #include <linux/module.h> |
||
76 | #include <linux/of_address.h> |
||
77 | @@ -761,7 +762,31 @@ static void mtu3_hw_exit(struct mtu3 *mt |
||
78 | mtu3_mem_free(mtu); |
||
79 | } |
||
80 | |||
81 | -/*-------------------------------------------------------------------------*/ |
||
82 | +/** |
||
83 | + * we set 32-bit DMA mask by default, here check whether the controller |
||
84 | + * supports 36-bit DMA or not, if it does, set 36-bit DMA mask. |
||
85 | + */ |
||
86 | +static int mtu3_set_dma_mask(struct mtu3 *mtu) |
||
87 | +{ |
||
88 | + struct device *dev = mtu->dev; |
||
89 | + bool is_36bit = false; |
||
90 | + int ret = 0; |
||
91 | + u32 value; |
||
92 | + |
||
93 | + value = mtu3_readl(mtu->mac_base, U3D_MISC_CTRL); |
||
94 | + if (value & DMA_ADDR_36BIT) { |
||
95 | + is_36bit = true; |
||
96 | + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36)); |
||
97 | + /* If set 36-bit DMA mask fails, fall back to 32-bit DMA mask */ |
||
98 | + if (ret) { |
||
99 | + is_36bit = false; |
||
100 | + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); |
||
101 | + } |
||
102 | + } |
||
103 | + dev_info(dev, "dma mask: %s bits\n", is_36bit ? "36" : "32"); |
||
104 | + |
||
105 | + return ret; |
||
106 | +} |
||
107 | |||
108 | int ssusb_gadget_init(struct ssusb_mtk *ssusb) |
||
109 | { |
||
110 | @@ -822,6 +847,12 @@ int ssusb_gadget_init(struct ssusb_mtk * |
||
111 | return ret; |
||
112 | } |
||
113 | |||
114 | + ret = mtu3_set_dma_mask(mtu); |
||
115 | + if (ret) { |
||
116 | + dev_err(dev, "mtu3 set dma_mask failed:%d\n", ret); |
||
117 | + goto dma_mask_err; |
||
118 | + } |
||
119 | + |
||
120 | ret = devm_request_irq(dev, mtu->irq, mtu3_irq, 0, dev_name(dev), mtu); |
||
121 | if (ret) { |
||
122 | dev_err(dev, "request irq %d failed!\n", mtu->irq); |
||
123 | @@ -847,6 +878,7 @@ int ssusb_gadget_init(struct ssusb_mtk * |
||
124 | gadget_err: |
||
125 | device_init_wakeup(dev, false); |
||
126 | |||
127 | +dma_mask_err: |
||
128 | irq_err: |
||
129 | mtu3_hw_exit(mtu); |
||
130 | ssusb->u3d = NULL; |
||
131 | --- a/drivers/usb/mtu3/mtu3_hw_regs.h |
||
132 | +++ b/drivers/usb/mtu3/mtu3_hw_regs.h |
||
133 | @@ -58,6 +58,8 @@ |
||
134 | #define U3D_QCR1 (SSUSB_DEV_BASE + 0x0404) |
||
135 | #define U3D_QCR2 (SSUSB_DEV_BASE + 0x0408) |
||
136 | #define U3D_QCR3 (SSUSB_DEV_BASE + 0x040C) |
||
137 | +#define U3D_TXQHIAR1 (SSUSB_DEV_BASE + 0x0484) |
||
138 | +#define U3D_RXQHIAR1 (SSUSB_DEV_BASE + 0x04C4) |
||
139 | |||
140 | #define U3D_TXQCSR1 (SSUSB_DEV_BASE + 0x0510) |
||
141 | #define U3D_TXQSAR1 (SSUSB_DEV_BASE + 0x0514) |
||
142 | @@ -189,6 +191,13 @@ |
||
143 | #define QMU_RX_COZ(x) (BIT(16) << (x)) |
||
144 | #define QMU_RX_ZLP(x) (BIT(0) << (x)) |
||
145 | |||
146 | +/* U3D_TXQHIAR1 */ |
||
147 | +/* U3D_RXQHIAR1 */ |
||
148 | +#define QMU_LAST_DONE_PTR_HI(x) (((x) >> 16) & 0xf) |
||
149 | +#define QMU_CUR_GPD_ADDR_HI(x) (((x) >> 8) & 0xf) |
||
150 | +#define QMU_START_ADDR_HI_MSK GENMASK(3, 0) |
||
151 | +#define QMU_START_ADDR_HI(x) (((x) & 0xf) << 0) |
||
152 | + |
||
153 | /* U3D_TXQCSR1 */ |
||
154 | /* U3D_RXQCSR1 */ |
||
155 | #define QMU_Q_ACTIVE BIT(15) |
||
156 | @@ -225,6 +234,7 @@ |
||
157 | #define CAP_TX_EP_NUM(x) ((x) & 0x1f) |
||
158 | |||
159 | /* U3D_MISC_CTRL */ |
||
160 | +#define DMA_ADDR_36BIT BIT(31) |
||
161 | #define VBUS_ON BIT(1) |
||
162 | #define VBUS_FRC_EN BIT(0) |
||
163 | |||
164 | --- a/drivers/usb/mtu3/mtu3_qmu.c |
||
165 | +++ b/drivers/usb/mtu3/mtu3_qmu.c |
||
166 | @@ -40,7 +40,58 @@ |
||
167 | #define GPD_FLAGS_IOC BIT(7) |
||
168 | |||
169 | #define GPD_EXT_FLAG_ZLP BIT(5) |
||
170 | +#define GPD_EXT_NGP(x) (((x) & 0xf) << 4) |
||
171 | +#define GPD_EXT_BUF(x) (((x) & 0xf) << 0) |
||
172 | |||
173 | +#define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo)) |
||
174 | +#define HILO_DMA(hi, lo) \ |
||
175 | + ((dma_addr_t)HILO_GEN64((le32_to_cpu(hi)), (le32_to_cpu(lo)))) |
||
176 | + |
||
177 | +static dma_addr_t read_txq_cur_addr(void __iomem *mbase, u8 epnum) |
||
178 | +{ |
||
179 | + u32 txcpr; |
||
180 | + u32 txhiar; |
||
181 | + |
||
182 | + txcpr = mtu3_readl(mbase, USB_QMU_TQCPR(epnum)); |
||
183 | + txhiar = mtu3_readl(mbase, USB_QMU_TQHIAR(epnum)); |
||
184 | + |
||
185 | + return HILO_DMA(QMU_CUR_GPD_ADDR_HI(txhiar), txcpr); |
||
186 | +} |
||
187 | + |
||
188 | +static dma_addr_t read_rxq_cur_addr(void __iomem *mbase, u8 epnum) |
||
189 | +{ |
||
190 | + u32 rxcpr; |
||
191 | + u32 rxhiar; |
||
192 | + |
||
193 | + rxcpr = mtu3_readl(mbase, USB_QMU_RQCPR(epnum)); |
||
194 | + rxhiar = mtu3_readl(mbase, USB_QMU_RQHIAR(epnum)); |
||
195 | + |
||
196 | + return HILO_DMA(QMU_CUR_GPD_ADDR_HI(rxhiar), rxcpr); |
||
197 | +} |
||
198 | + |
||
199 | +static void write_txq_start_addr(void __iomem *mbase, u8 epnum, dma_addr_t dma) |
||
200 | +{ |
||
201 | + u32 tqhiar; |
||
202 | + |
||
203 | + mtu3_writel(mbase, USB_QMU_TQSAR(epnum), |
||
204 | + cpu_to_le32(lower_32_bits(dma))); |
||
205 | + tqhiar = mtu3_readl(mbase, USB_QMU_TQHIAR(epnum)); |
||
206 | + tqhiar &= ~QMU_START_ADDR_HI_MSK; |
||
207 | + tqhiar |= QMU_START_ADDR_HI(upper_32_bits(dma)); |
||
208 | + mtu3_writel(mbase, USB_QMU_TQHIAR(epnum), tqhiar); |
||
209 | +} |
||
210 | + |
||
211 | +static void write_rxq_start_addr(void __iomem *mbase, u8 epnum, dma_addr_t dma) |
||
212 | +{ |
||
213 | + u32 rqhiar; |
||
214 | + |
||
215 | + mtu3_writel(mbase, USB_QMU_RQSAR(epnum), |
||
216 | + cpu_to_le32(lower_32_bits(dma))); |
||
217 | + rqhiar = mtu3_readl(mbase, USB_QMU_RQHIAR(epnum)); |
||
218 | + rqhiar &= ~QMU_START_ADDR_HI_MSK; |
||
219 | + rqhiar |= QMU_START_ADDR_HI(upper_32_bits(dma)); |
||
220 | + mtu3_writel(mbase, USB_QMU_RQHIAR(epnum), rqhiar); |
||
221 | +} |
||
222 | |||
223 | static struct qmu_gpd *gpd_dma_to_virt(struct mtu3_gpd_ring *ring, |
||
224 | dma_addr_t dma_addr) |
||
225 | @@ -193,21 +244,27 @@ static int mtu3_prepare_tx_gpd(struct mt |
||
226 | struct mtu3_gpd_ring *ring = &mep->gpd_ring; |
||
227 | struct qmu_gpd *gpd = ring->enqueue; |
||
228 | struct usb_request *req = &mreq->request; |
||
229 | + dma_addr_t enq_dma; |
||
230 | + u16 ext_addr; |
||
231 | |||
232 | /* set all fields to zero as default value */ |
||
233 | memset(gpd, 0, sizeof(*gpd)); |
||
234 | |||
235 | - gpd->buffer = cpu_to_le32((u32)req->dma); |
||
236 | + gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); |
||
237 | + ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); |
||
238 | gpd->buf_len = cpu_to_le16(req->length); |
||
239 | gpd->flag |= GPD_FLAGS_IOC; |
||
240 | |||
241 | /* get the next GPD */ |
||
242 | enq = advance_enq_gpd(ring); |
||
243 | - dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p\n", |
||
244 | - mep->epnum, gpd, enq); |
||
245 | + enq_dma = gpd_virt_to_dma(ring, enq); |
||
246 | + dev_dbg(mep->mtu->dev, "TX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n", |
||
247 | + mep->epnum, gpd, enq, enq_dma); |
||
248 | |||
249 | enq->flag &= ~GPD_FLAGS_HWO; |
||
250 | - gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq)); |
||
251 | + gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); |
||
252 | + ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); |
||
253 | + gpd->tx_ext_addr = cpu_to_le16(ext_addr); |
||
254 | |||
255 | if (req->zero) |
||
256 | gpd->ext_flag |= GPD_EXT_FLAG_ZLP; |
||
257 | @@ -226,21 +283,27 @@ static int mtu3_prepare_rx_gpd(struct mt |
||
258 | struct mtu3_gpd_ring *ring = &mep->gpd_ring; |
||
259 | struct qmu_gpd *gpd = ring->enqueue; |
||
260 | struct usb_request *req = &mreq->request; |
||
261 | + dma_addr_t enq_dma; |
||
262 | + u16 ext_addr; |
||
263 | |||
264 | /* set all fields to zero as default value */ |
||
265 | memset(gpd, 0, sizeof(*gpd)); |
||
266 | |||
267 | - gpd->buffer = cpu_to_le32((u32)req->dma); |
||
268 | + gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); |
||
269 | + ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); |
||
270 | gpd->data_buf_len = cpu_to_le16(req->length); |
||
271 | gpd->flag |= GPD_FLAGS_IOC; |
||
272 | |||
273 | /* get the next GPD */ |
||
274 | enq = advance_enq_gpd(ring); |
||
275 | - dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p\n", |
||
276 | - mep->epnum, gpd, enq); |
||
277 | + enq_dma = gpd_virt_to_dma(ring, enq); |
||
278 | + dev_dbg(mep->mtu->dev, "RX-EP%d queue gpd=%p, enq=%p, qdma=%pad\n", |
||
279 | + mep->epnum, gpd, enq, enq_dma); |
||
280 | |||
281 | enq->flag &= ~GPD_FLAGS_HWO; |
||
282 | - gpd->next_gpd = cpu_to_le32((u32)gpd_virt_to_dma(ring, enq)); |
||
283 | + gpd->next_gpd = cpu_to_le32(lower_32_bits(enq_dma)); |
||
284 | + ext_addr |= GPD_EXT_NGP(upper_32_bits(enq_dma)); |
||
285 | + gpd->rx_ext_addr = cpu_to_le16(ext_addr); |
||
286 | gpd->chksum = qmu_calc_checksum((u8 *)gpd); |
||
287 | gpd->flag |= GPD_FLAGS_HWO; |
||
288 | |||
289 | @@ -267,8 +330,8 @@ int mtu3_qmu_start(struct mtu3_ep *mep) |
||
290 | |||
291 | if (mep->is_in) { |
||
292 | /* set QMU start address */ |
||
293 | - mtu3_writel(mbase, USB_QMU_TQSAR(mep->epnum), ring->dma); |
||
294 | - mtu3_setbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_DMAREQEN); |
||
295 | + write_txq_start_addr(mbase, epnum, ring->dma); |
||
296 | + mtu3_setbits(mbase, MU3D_EP_TXCR0(epnum), TX_DMAREQEN); |
||
297 | mtu3_setbits(mbase, U3D_QCR0, QMU_TX_CS_EN(epnum)); |
||
298 | /* send zero length packet according to ZLP flag in GPD */ |
||
299 | mtu3_setbits(mbase, U3D_QCR1, QMU_TX_ZLP(epnum)); |
||
300 | @@ -282,8 +345,8 @@ int mtu3_qmu_start(struct mtu3_ep *mep) |
||
301 | mtu3_writel(mbase, USB_QMU_TQCSR(epnum), QMU_Q_START); |
||
302 | |||
303 | } else { |
||
304 | - mtu3_writel(mbase, USB_QMU_RQSAR(mep->epnum), ring->dma); |
||
305 | - mtu3_setbits(mbase, MU3D_EP_RXCR0(mep->epnum), RX_DMAREQEN); |
||
306 | + write_rxq_start_addr(mbase, epnum, ring->dma); |
||
307 | + mtu3_setbits(mbase, MU3D_EP_RXCR0(epnum), RX_DMAREQEN); |
||
308 | mtu3_setbits(mbase, U3D_QCR0, QMU_RX_CS_EN(epnum)); |
||
309 | /* don't expect ZLP */ |
||
310 | mtu3_clrbits(mbase, U3D_QCR3, QMU_RX_ZLP(epnum)); |
||
311 | @@ -353,9 +416,9 @@ static void qmu_tx_zlp_error_handler(str |
||
312 | struct mtu3_gpd_ring *ring = &mep->gpd_ring; |
||
313 | void __iomem *mbase = mtu->mac_base; |
||
314 | struct qmu_gpd *gpd_current = NULL; |
||
315 | - dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_TQCPR(epnum)); |
||
316 | struct usb_request *req = NULL; |
||
317 | struct mtu3_request *mreq; |
||
318 | + dma_addr_t cur_gpd_dma; |
||
319 | u32 txcsr = 0; |
||
320 | int ret; |
||
321 | |||
322 | @@ -365,7 +428,8 @@ static void qmu_tx_zlp_error_handler(str |
||
323 | else |
||
324 | return; |
||
325 | |||
326 | - gpd_current = gpd_dma_to_virt(ring, gpd_dma); |
||
327 | + cur_gpd_dma = read_txq_cur_addr(mbase, epnum); |
||
328 | + gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma); |
||
329 | |||
330 | if (le16_to_cpu(gpd_current->buf_len) != 0) { |
||
331 | dev_err(mtu->dev, "TX EP%d buffer length error(!=0)\n", epnum); |
||
332 | @@ -408,12 +472,13 @@ static void qmu_done_tx(struct mtu3 *mtu |
||
333 | void __iomem *mbase = mtu->mac_base; |
||
334 | struct qmu_gpd *gpd = ring->dequeue; |
||
335 | struct qmu_gpd *gpd_current = NULL; |
||
336 | - dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_TQCPR(epnum)); |
||
337 | struct usb_request *request = NULL; |
||
338 | struct mtu3_request *mreq; |
||
339 | + dma_addr_t cur_gpd_dma; |
||
340 | |||
341 | /*transfer phy address got from QMU register to virtual address */ |
||
342 | - gpd_current = gpd_dma_to_virt(ring, gpd_dma); |
||
343 | + cur_gpd_dma = read_txq_cur_addr(mbase, epnum); |
||
344 | + gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma); |
||
345 | |||
346 | dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", |
||
347 | __func__, epnum, gpd, gpd_current, ring->enqueue); |
||
348 | @@ -446,11 +511,12 @@ static void qmu_done_rx(struct mtu3 *mtu |
||
349 | void __iomem *mbase = mtu->mac_base; |
||
350 | struct qmu_gpd *gpd = ring->dequeue; |
||
351 | struct qmu_gpd *gpd_current = NULL; |
||
352 | - dma_addr_t gpd_dma = mtu3_readl(mbase, USB_QMU_RQCPR(epnum)); |
||
353 | struct usb_request *req = NULL; |
||
354 | struct mtu3_request *mreq; |
||
355 | + dma_addr_t cur_gpd_dma; |
||
356 | |||
357 | - gpd_current = gpd_dma_to_virt(ring, gpd_dma); |
||
358 | + cur_gpd_dma = read_rxq_cur_addr(mbase, epnum); |
||
359 | + gpd_current = gpd_dma_to_virt(ring, cur_gpd_dma); |
||
360 | |||
361 | dev_dbg(mtu->dev, "%s EP%d, last=%p, current=%p, enq=%p\n", |
||
362 | __func__, epnum, gpd, gpd_current, ring->enqueue); |