6095082c13e161cf25509dcce60dc3f5a866fa1a
[oweals/openwrt.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