6095082c13e161cf25509dcce60dc3f5a866fa1a
[openwrt/staging/thess.git] /
1 From f160c56c71c59d2d865142fdeb3040e9cc4b6a77 Mon Sep 17 00:00:00 2001
2 From: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
3 Date: Mon, 25 Apr 2016 17:14:25 +0530
4 Subject: [PATCH 17/93] armv8/fsl-layerscape: add dwc3 gadget driver support
5
6 Implements the dwc3 gadget driver support for LS1043
7 and LS1012 platform.
8
9 NOTE: Do not upstream this patch.It needs rework for open source
10 submission.
11
12 Signed-off-by: Rajat Srivastava <rajat.srivastava@nxp.com>
13 Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
14 Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
15 ---
16 arch/arm/cpu/armv8/fsl-layerscape/soc.c | 98 +++++++++++++++++++-
17 .../include/asm/arch-fsl-layerscape/immap_lsch2.h | 6 ++
18 .../include/asm/arch-fsl-layerscape/sys_proto.h | 10 ++
19 common/cmd_usb_mass_storage.c | 2 +-
20 drivers/usb/dwc3/core.c | 12 +++
21 drivers/usb/dwc3/ep0.c | 10 +-
22 drivers/usb/dwc3/gadget.c | 11 ++-
23 drivers/usb/dwc3/io.h | 8 +-
24 drivers/usb/gadget/f_mass_storage.c | 10 +-
25 include/configs/ls1012aqds.h | 15 +++
26 include/configs/ls1012ardb.h | 15 +++
27 include/configs/ls1043aqds.h | 15 +++
28 12 files changed, 197 insertions(+), 15 deletions(-)
29 create mode 100644 arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h
30
31 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
32 index ec561a7..0a170eb 100644
33 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
34 +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
35 @@ -19,6 +19,10 @@
36 #ifdef CONFIG_CHAIN_OF_TRUST
37 #include <fsl_validate.h>
38 #endif
39 +#include <usb.h>
40 +#include <dwc3-uboot.h>
41 +#include <linux/usb/xhci-fsl.h>
42 +
43
44 DECLARE_GLOBAL_DATA_PTR;
45
46 @@ -406,9 +410,19 @@ void fsl_lsch2_early_init_f(void)
47 #if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT)
48 out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
49 #endif
50 - /* Make SEC reads and writes snoopable */
51 +
52 +#if defined(CONFIG_LS1043A)
53 + /* Make SEC and USB reads and writes snoopable */
54 setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP |
55 - SCFG_SNPCNFGCR_SECWRSNP);
56 + SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP |
57 + SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP |
58 + SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP |
59 + SCFG_SNPCNFGCR_USB3WRSNP);
60 +#elif defined(CONFIG_LS1012A)
61 + /* Make SEC and reads and writes snoopable */
62 + setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP |
63 + SCFG_SNPCNFGCR_USB1RDSNP | SCFG_SNPCNFGCR_USB1WRSNP);
64 +#endif
65
66 /*
67 * Enable snoop requests and DVM message requests for
68 @@ -428,6 +442,86 @@ void fsl_lsch2_early_init_f(void)
69 }
70 #endif
71
72 +#ifdef CONFIG_USB_DWC3
73 +
74 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
75 +static struct dwc3_device dwc3_device_data0 = {
76 + .maximum_speed = USB_SPEED_HIGH,
77 + .base = CONFIG_SYS_FSL_XHCI_USB1_ADDR,
78 + .dr_mode = USB_DR_MODE_PERIPHERAL,
79 + .index = 0,
80 +};
81 +
82 +#if defined(CONFIG_LS1043A)
83 +static struct dwc3_device dwc3_device_data1 = {
84 + .maximum_speed = USB_SPEED_HIGH,
85 + .base = CONFIG_SYS_FSL_XHCI_USB2_ADDR,
86 + .dr_mode = USB_DR_MODE_PERIPHERAL,
87 + .index = 1,
88 +};
89 +
90 +static struct dwc3_device dwc3_device_data2 = {
91 + .maximum_speed = USB_SPEED_HIGH,
92 + .base = CONFIG_SYS_FSL_XHCI_USB3_ADDR,
93 + .dr_mode = USB_DR_MODE_PERIPHERAL,
94 + .index = 2,
95 +};
96 +#endif
97 +
98 +int usb_gadget_handle_interrupts(int index)
99 +{
100 + dwc3_uboot_handle_interrupt(index);
101 + return 0;
102 +}
103 +#endif
104 +
105 +int board_usb_init(int index, enum usb_init_type init)
106 +{
107 + switch (init) {
108 + case USB_INIT_DEVICE:
109 + switch (index) {
110 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
111 + case 0:
112 + dwc3_uboot_init(&dwc3_device_data0);
113 + break;
114 +
115 +#if defined(CONFIG_LS1043A)
116 + case 1:
117 + dwc3_uboot_init(&dwc3_device_data1);
118 + break;
119 + case 2:
120 + dwc3_uboot_init(&dwc3_device_data2);
121 + break;
122 +#endif
123 +#endif
124 + default:
125 + printf("Invalid Controller Index\n");
126 + return -1;
127 + }
128 + break;
129 + default:
130 + break;
131 + }
132 + return 0;
133 +}
134 +
135 +int board_usb_cleanup(int index, enum usb_init_type init)
136 +{
137 + switch (init) {
138 + case USB_INIT_DEVICE:
139 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
140 + dwc3_uboot_exit(index);
141 +#endif
142 + break;
143 + default:
144 + break;
145 + }
146 + return 0;
147 +}
148 +#endif
149 +
150 +
151 +
152 #ifdef CONFIG_BOARD_LATE_INIT
153 int board_late_init(void)
154 {
155 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
156 index 5b026f8..414a222 100644
157 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
158 +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h
159 @@ -355,6 +355,12 @@ struct ccsr_gur {
160
161 #define SCFG_SNPCNFGCR_SECRDSNP 0x80000000
162 #define SCFG_SNPCNFGCR_SECWRSNP 0x40000000
163 +#define SCFG_SNPCNFGCR_USB1RDSNP 0x00200000
164 +#define SCFG_SNPCNFGCR_USB1WRSNP 0x00100000
165 +#define SCFG_SNPCNFGCR_USB2RDSNP 0x00008000
166 +#define SCFG_SNPCNFGCR_USB2WRSNP 0x00010000
167 +#define SCFG_SNPCNFGCR_USB3RDSNP 0x00002000
168 +#define SCFG_SNPCNFGCR_USB3WRSNP 0x00004000
169
170 /* Supplemental Configuration Unit */
171 struct ccsr_scfg {
172 diff --git a/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h b/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h
173 new file mode 100644
174 index 0000000..1e31d3d
175 --- /dev/null
176 +++ b/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h
177 @@ -0,0 +1,10 @@
178 +/*
179 + * Copyright 2015 Freescale Semiconductor
180 + *
181 + * SPDX-License-Identifier: GPL-2.0+
182 + */
183 +
184 +#ifndef _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_
185 +#define _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_
186 +
187 +#endif /* _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_ */
188 diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c
189 index 0407389..7d507b5 100644
190 --- a/common/cmd_usb_mass_storage.c
191 +++ b/common/cmd_usb_mass_storage.c
192 @@ -140,7 +140,7 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
193 while (1) {
194 usb_gadget_handle_interrupts(controller_index);
195
196 - rc = fsg_main_thread(NULL);
197 + rc = fsg_main_thread(&controller_index);
198 if (rc) {
199 /* Check I/O error */
200 if (rc == -EIO)
201 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
202 index 85cc96a..b8e4066 100644
203 --- a/drivers/usb/dwc3/core.c
204 +++ b/drivers/usb/dwc3/core.c
205 @@ -690,6 +690,18 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
206 return -ENOMEM;
207 }
208
209 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
210 + /* Change burst beat and outstanding pipelined transfers requests */
211 + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0,
212 + (dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) & ~0xff) | 0xf);
213 + dwc3_writel(dwc->regs, DWC3_GSBUSCFG1,
214 + dwc3_readl(dwc->regs, DWC3_GSBUSCFG1) | 0xf00);
215 +
216 + /* Enable snooping */
217 + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0,
218 + dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) | 0x22220000);
219 +#endif
220 +
221 if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
222 dwc->dr_mode = USB_DR_MODE_HOST;
223 else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
224 diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
225 index 12b133f..e61d980 100644
226 --- a/drivers/usb/dwc3/ep0.c
227 +++ b/drivers/usb/dwc3/ep0.c
228 @@ -81,8 +81,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
229 trb->ctrl |= (DWC3_TRB_CTRL_IOC
230 | DWC3_TRB_CTRL_LST);
231
232 - dwc3_flush_cache((long)buf_dma, len);
233 - dwc3_flush_cache((long)trb, sizeof(*trb));
234 + dwc3_flush_cache((uintptr_t)buf_dma, len);
235 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
236
237 if (chain)
238 return 0;
239 @@ -790,7 +790,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
240 if (!r)
241 return;
242
243 - dwc3_flush_cache((long)trb, sizeof(*trb));
244 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
245
246 status = DWC3_TRB_SIZE_TRBSTS(trb->size);
247 if (status == DWC3_TRBSTS_SETUP_PENDING) {
248 @@ -821,7 +821,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
249 ur->actual += transferred;
250
251 trb++;
252 - dwc3_flush_cache((long)trb, sizeof(*trb));
253 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
254 length = trb->size & DWC3_TRB_SIZE_MASK;
255
256 ep0->free_slot = 0;
257 @@ -831,7 +831,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
258 maxp);
259 transferred = min_t(u32, ur->length - transferred,
260 transfer_size - length);
261 - dwc3_flush_cache((long)dwc->ep0_bounce, DWC3_EP0_BOUNCE_SIZE);
262 + dwc3_flush_cache((uintptr_t)dwc->ep0_bounce, DWC3_EP0_BOUNCE_SIZE);
263 memcpy(buf, dwc->ep0_bounce, transferred);
264 } else {
265 transferred = ur->length - length;
266 diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
267 index 8ff949d..649f1a4 100644
268 --- a/drivers/usb/dwc3/gadget.c
269 +++ b/drivers/usb/dwc3/gadget.c
270 @@ -244,7 +244,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
271
272 list_del(&req->list);
273 req->trb = NULL;
274 - dwc3_flush_cache((long)req->request.dma, req->request.length);
275 + dwc3_flush_cache((uintptr_t)req->request.dma, req->request.length);
276
277 if (req->request.status == -EINPROGRESS)
278 req->request.status = status;
279 @@ -771,8 +771,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
280
281 trb->ctrl |= DWC3_TRB_CTRL_HWO;
282
283 - dwc3_flush_cache((long)dma, length);
284 - dwc3_flush_cache((long)trb, sizeof(*trb));
285 + dwc3_flush_cache((uintptr_t)dma, length);
286 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
287 }
288
289 /*
290 @@ -1769,7 +1769,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
291 slot %= DWC3_TRB_NUM;
292 trb = &dep->trb_pool[slot];
293
294 - dwc3_flush_cache((long)trb, sizeof(*trb));
295 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
296 __dwc3_cleanup_done_trbs(dwc, dep, req, trb, event, status);
297 dwc3_gadget_giveback(dep, req, status);
298
299 @@ -2447,6 +2447,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
300 int left;
301 u32 reg;
302
303 +
304 evt = dwc->ev_buffs[buf];
305 left = evt->count;
306
307 @@ -2670,7 +2671,7 @@ void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc)
308
309 for (i = 0; i < dwc->num_event_buffers; i++) {
310 evt = dwc->ev_buffs[i];
311 - dwc3_flush_cache((long)evt->buf, evt->length);
312 + dwc3_flush_cache((uintptr_t)evt->buf, evt->length);
313 }
314
315 dwc3_thread_interrupt(0, dwc);
316 diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
317 index 0d9fa22..cab5122 100644
318 --- a/drivers/usb/dwc3/io.h
319 +++ b/drivers/usb/dwc3/io.h
320 @@ -48,8 +48,14 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
321 writel(value, base + offs);
322 }
323
324 -static inline void dwc3_flush_cache(int addr, int length)
325 +static inline void dwc3_flush_cache(uintptr_t addr, int length)
326 {
327 flush_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE));
328 }
329 +
330 +static inline void dwc3_inval_cache(uintptr_t addr, int length)
331 +{
332 + invalidate_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE));
333 +}
334 +
335 #endif /* __DRIVERS_USB_DWC3_IO_H */
336 diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
337 index ec1f23a..ec0229f 100644
338 --- a/drivers/usb/gadget/f_mass_storage.c
339 +++ b/drivers/usb/gadget/f_mass_storage.c
340 @@ -362,6 +362,7 @@ struct fsg_common {
341 char inquiry_string[8 + 16 + 4 + 1];
342
343 struct kref ref;
344 + unsigned int controller_index;
345 };
346
347 struct fsg_config {
348 @@ -690,7 +691,7 @@ static int sleep_thread(struct fsg_common *common)
349 k = 0;
350 }
351
352 - usb_gadget_handle_interrupts(0);
353 + usb_gadget_handle_interrupts(common->controller_index);
354 }
355 common->thread_wakeup_needed = 0;
356 return rc;
357 @@ -2405,6 +2406,11 @@ int fsg_main_thread(void *common_)
358 {
359 int ret;
360 struct fsg_common *common = the_fsg_common;
361 +
362 + /* update the controller_index */
363 + if (common_)
364 + common->controller_index = *(unsigned int *)common_;
365 +
366 /* The main loop */
367 do {
368 if (exception_in_progress(common)) {
369 @@ -2475,6 +2481,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
370
371 common->ops = NULL;
372 common->private_data = NULL;
373 + common->controller_index = 0;
374
375 common->gadget = gadget;
376 common->ep0 = gadget->ep0;
377 @@ -2769,6 +2776,7 @@ int fsg_add(struct usb_configuration *c)
378
379 fsg_common->ops = NULL;
380 fsg_common->private_data = NULL;
381 + fsg_common->controller_index = 0;
382
383 the_fsg_common = fsg_common;
384
385 diff --git a/include/configs/ls1012aqds.h b/include/configs/ls1012aqds.h
386 index 6346d3e..fdada18 100644
387 --- a/include/configs/ls1012aqds.h
388 +++ b/include/configs/ls1012aqds.h
389 @@ -123,6 +123,21 @@
390 #define CONFIG_CMD_USB
391 #define CONFIG_USB_STORAGE
392 #define CONFIG_CMD_EXT2
393 +
394 +#define CONFIG_USB_DWC3
395 +#define CONFIG_USB_DWC3_GADGET
396 +
397 +#define CONFIG_USB_GADGET
398 +#define CONFIG_USB_FUNCTION_MASS_STORAGE
399 +#define CONFIG_USB_GADGET_DOWNLOAD
400 +#define CONFIG_USB_GADGET_VBUS_DRAW 2
401 +#define CONFIG_G_DNL_MANUFACTURER "NXP Semiconductor"
402 +#define CONFIG_G_DNL_VENDOR_NUM 0x1234
403 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234
404 +#define CONFIG_USB_GADGET_DUALSPEED
405 +
406 +/* USB Gadget ums command */
407 +#define CONFIG_CMD_USB_MASS_STORAGE
408 #endif
409
410 #define CONFIG_CMD_MEMINFO
411 diff --git a/include/configs/ls1012ardb.h b/include/configs/ls1012ardb.h
412 index 9ff5935..af3d33f 100644
413 --- a/include/configs/ls1012ardb.h
414 +++ b/include/configs/ls1012ardb.h
415 @@ -38,6 +38,21 @@
416 #define CONFIG_CMD_USB
417 #define CONFIG_USB_STORAGE
418 #define CONFIG_CMD_EXT2
419 +
420 +#define CONFIG_USB_DWC3
421 +#define CONFIG_USB_DWC3_GADGET
422 +
423 +#define CONFIG_USB_GADGET
424 +#define CONFIG_USB_FUNCTION_MASS_STORAGE
425 +#define CONFIG_USB_GADGET_DOWNLOAD
426 +#define CONFIG_USB_GADGET_VBUS_DRAW 2
427 +#define CONFIG_G_DNL_MANUFACTURER "NXP Semiconductor"
428 +#define CONFIG_G_DNL_VENDOR_NUM 0x1234
429 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234
430 +#define CONFIG_USB_GADGET_DUALSPEED
431 +
432 +/* USB Gadget ums command */
433 +#define CONFIG_CMD_USB_MASS_STORAGE
434 #endif
435
436 /*
437 diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h
438 index 9828360..9e23615 100644
439 --- a/include/configs/ls1043aqds.h
440 +++ b/include/configs/ls1043aqds.h
441 @@ -400,6 +400,21 @@ unsigned long get_board_ddr_clk(void);
442 #define CONFIG_CMD_USB
443 #define CONFIG_USB_STORAGE
444 #define CONFIG_CMD_EXT2
445 +
446 +#define CONFIG_USB_DWC3
447 +#define CONFIG_USB_DWC3_GADGET
448 +
449 +#define CONFIG_USB_GADGET
450 +#define CONFIG_USB_FUNCTION_MASS_STORAGE
451 +#define CONFIG_USB_GADGET_DOWNLOAD
452 +#define CONFIG_USB_GADGET_VBUS_DRAW 2
453 +#define CONFIG_G_DNL_MANUFACTURER "NXP Semiconductor"
454 +#define CONFIG_G_DNL_VENDOR_NUM 0x1234
455 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234
456 +#define CONFIG_USB_GADGET_DUALSPEED
457 +
458 +/* USB Gadget ums command */
459 +#define CONFIG_CMD_USB_MASS_STORAGE
460 #endif
461
462 /*
463 --
464 1.7.9.5
465