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
6 Implements the dwc3 gadget driver support for LS1043
9 NOTE: Do not upstream this patch.It needs rework for open source
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>
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
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
36 #ifdef CONFIG_CHAIN_OF_TRUST
37 #include <fsl_validate.h>
40 +#include <dwc3-uboot.h>
41 +#include <linux/usb/xhci-fsl.h>
44 DECLARE_GLOBAL_DATA_PTR;
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);
50 - /* Make SEC reads and writes snoopable */
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);
67 * Enable snoop requests and DVM message requests for
68 @@ -428,6 +442,86 @@ void fsl_lsch2_early_init_f(void)
72 +#ifdef CONFIG_USB_DWC3
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,
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,
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,
98 +int usb_gadget_handle_interrupts(int index)
100 + dwc3_uboot_handle_interrupt(index);
105 +int board_usb_init(int index, enum usb_init_type init)
108 + case USB_INIT_DEVICE:
110 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
112 + dwc3_uboot_init(&dwc3_device_data0);
115 +#if defined(CONFIG_LS1043A)
117 + dwc3_uboot_init(&dwc3_device_data1);
120 + dwc3_uboot_init(&dwc3_device_data2);
125 + printf("Invalid Controller Index\n");
135 +int board_usb_cleanup(int index, enum usb_init_type init)
138 + case USB_INIT_DEVICE:
139 +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A)
140 + dwc3_uboot_exit(index);
152 #ifdef CONFIG_BOARD_LATE_INIT
153 int board_late_init(void)
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 {
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
170 /* Supplemental Configuration Unit */
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
174 index 0000000..1e31d3d
176 +++ b/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h
179 + * Copyright 2015 Freescale Semiconductor
181 + * SPDX-License-Identifier: GPL-2.0+
184 +#ifndef _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_
185 +#define _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_
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,
194 usb_gadget_handle_interrupts(controller_index);
196 - rc = fsg_main_thread(NULL);
197 + rc = fsg_main_thread(&controller_index);
199 /* Check I/O error */
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)
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);
216 + /* Enable snooping */
217 + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0,
218 + dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) | 0x22220000);
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);
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));
239 @@ -790,7 +790,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
243 - dwc3_flush_cache((long)trb, sizeof(*trb));
244 + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
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;
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;
257 @@ -831,7 +831,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
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);
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,
272 list_del(&req->list);
274 - dwc3_flush_cache((long)req->request.dma, req->request.length);
275 + dwc3_flush_cache((uintptr_t)req->request.dma, req->request.length);
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,
281 trb->ctrl |= DWC3_TRB_CTRL_HWO;
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));
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];
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);
299 @@ -2447,6 +2447,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
304 evt = dwc->ev_buffs[buf];
307 @@ -2670,7 +2671,7 @@ void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc)
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);
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);
324 -static inline void dwc3_flush_cache(int addr, int length)
325 +static inline void dwc3_flush_cache(uintptr_t addr, int length)
327 flush_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE));
330 +static inline void dwc3_inval_cache(uintptr_t addr, int length)
332 + invalidate_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE));
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];
344 + unsigned int controller_index;
348 @@ -690,7 +691,7 @@ static int sleep_thread(struct fsg_common *common)
352 - usb_gadget_handle_interrupts(0);
353 + usb_gadget_handle_interrupts(common->controller_index);
355 common->thread_wakeup_needed = 0;
357 @@ -2405,6 +2406,11 @@ int fsg_main_thread(void *common_)
360 struct fsg_common *common = the_fsg_common;
362 + /* update the controller_index */
364 + common->controller_index = *(unsigned int *)common_;
368 if (exception_in_progress(common)) {
369 @@ -2475,6 +2481,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
372 common->private_data = NULL;
373 + common->controller_index = 0;
375 common->gadget = gadget;
376 common->ep0 = gadget->ep0;
377 @@ -2769,6 +2776,7 @@ int fsg_add(struct usb_configuration *c)
379 fsg_common->ops = NULL;
380 fsg_common->private_data = NULL;
381 + fsg_common->controller_index = 0;
383 the_fsg_common = fsg_common;
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
390 #define CONFIG_CMD_USB
391 #define CONFIG_USB_STORAGE
392 #define CONFIG_CMD_EXT2
394 +#define CONFIG_USB_DWC3
395 +#define CONFIG_USB_DWC3_GADGET
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
406 +/* USB Gadget ums command */
407 +#define CONFIG_CMD_USB_MASS_STORAGE
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
416 #define CONFIG_CMD_USB
417 #define CONFIG_USB_STORAGE
418 #define CONFIG_CMD_EXT2
420 +#define CONFIG_USB_DWC3
421 +#define CONFIG_USB_DWC3_GADGET
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
432 +/* USB Gadget ums command */
433 +#define CONFIG_CMD_USB_MASS_STORAGE
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
446 +#define CONFIG_USB_DWC3
447 +#define CONFIG_USB_DWC3_GADGET
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
458 +/* USB Gadget ums command */
459 +#define CONFIG_CMD_USB_MASS_STORAGE