[U-Boot] [PATCH v3 0/4] armv8/fsl-layerscape: add dwc3 gadget driver support

From: Rajesh Bhagat rajesh.bhagat@nxp.com
Adds support for dwc3 gadget driver for ARM v8 platform of layerscape series. Currently this patch has been tested for LS1043A
Rajat Srivastava (3): usb: dwc3: Add helper functions to enable snooping and burst settings armv8/fsl-layerscape: add dwc3 gadget driver support armv8/fsl-layerscape: enable dwc3 gadget driver support
Rajesh Bhagat (1): usb: ums: support multiple controllers using controller_index
arch/arm/cpu/armv8/fsl-layerscape/soc.c | 93 ++++++++++++++++++++++ .../include/asm/arch-fsl-layerscape/immap_lsch2.h | 6 ++ cmd/usb_mass_storage.c | 2 +- drivers/usb/dwc3/core.c | 45 +++++++++++ drivers/usb/dwc3/core.h | 7 ++ drivers/usb/gadget/f_mass_storage.c | 11 ++- include/configs/ls1043aqds.h | 15 ++++ include/usb_mass_storage.h | 2 +- 8 files changed, 177 insertions(+), 4 deletions(-)

From: Rajesh Bhagat rajesh.bhagat@nxp.com
Adds a new field in fsg_common namely controller_index to support multiple controllers usb gadget support.
Signed-off-by: Rajat Srivastava rajat.srivastava@nxp.com Signed-off-by: Rajesh Bhagat rajesh.bhagat@nxp.com Acked-by: Lukasz Majewski l.majewski@samsung.com --- Changes in v3 - None
Changes for v2: - Changes type of fsg_main_thread argument to unsigned int
cmd/usb_mass_storage.c | 2 +- drivers/usb/gadget/f_mass_storage.c | 11 +++++++++-- include/usb_mass_storage.h | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index b05913a..bf80d37 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -214,7 +214,7 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, while (1) { usb_gadget_handle_interrupts(controller_index);
- rc = fsg_main_thread(NULL); + rc = fsg_main_thread(controller_index); if (rc) { /* Check I/O error */ if (rc == -EIO) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 1ecb92a..27ca5fe 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -362,6 +362,7 @@ struct fsg_common { char inquiry_string[8 + 16 + 4 + 1];
struct kref ref; + unsigned int controller_index; };
struct fsg_config { @@ -691,7 +692,7 @@ static int sleep_thread(struct fsg_common *common) k = 0; }
- usb_gadget_handle_interrupts(0); + usb_gadget_handle_interrupts(common->controller_index); } common->thread_wakeup_needed = 0; return rc; @@ -2402,10 +2403,14 @@ static void handle_exception(struct fsg_common *common)
/*-------------------------------------------------------------------------*/
-int fsg_main_thread(void *common_) +int fsg_main_thread(unsigned int controller_index) { int ret; struct fsg_common *common = the_fsg_common; + + /* update the controller_index */ + common->controller_index = controller_index; + /* The main loop */ do { if (exception_in_progress(common)) { @@ -2476,6 +2481,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
common->ops = NULL; common->private_data = NULL; + common->controller_index = 0;
common->gadget = gadget; common->ep0 = gadget->ep0; @@ -2770,6 +2776,7 @@ int fsg_add(struct usb_configuration *c)
fsg_common->ops = NULL; fsg_common->private_data = NULL; + fsg_common->controller_index = 0;
the_fsg_common = fsg_common;
diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h index 8229f62..f21cc7a 100644 --- a/include/usb_mass_storage.h +++ b/include/usb_mass_storage.h @@ -28,6 +28,6 @@ struct ums {
int fsg_init(struct ums *ums_devs, int count); void fsg_cleanup(void); -int fsg_main_thread(void *); +int fsg_main_thread(unsigned int); int fsg_add(struct usb_configuration *c); #endif /* __USB_MASS_STORAGE_H__ */

Adds helper functions to enable snooping and outstanding burst beat settings.
Signed-off-by: Rajat Srivastava rajat.srivastava@nxp.com Signed-off-by: Rajesh Bhagat rajesh.bhagat@nxp.com --- Changes in v3: - Changed operator for code cleanup
Changes in v2: - Removes SoC specific flags and added helper functions
drivers/usb/dwc3/core.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 7 +++++++ 2 files changed, 52 insertions(+)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 85cc96a..4ac599a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -599,6 +599,51 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
#define DWC3_ALIGN_MASK (16 - 1)
+void dwc3_core_incr_burst_enable(int index, int btype_incr_val, + int breq_limit) +{ + struct dwc3 *dwc; + u32 reg; + + list_for_each_entry(dwc, &dwc3_list, list) { + if (dwc->index != index) + continue; + + /* + * Change burst beat and outstanding pipelined + * transfers requests + */ + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + reg = (reg & ~DWC3_INCR_BTYPE_MASK) | btype_incr_val; + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg); + + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1); + reg = (reg & ~DWC3_BREQ_LIMIT_MASK) | (breq_limit << 8); + dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg); + break; + } +} + +void dwc3_core_set_snooping(int index, bool snoop) +{ + struct dwc3 *dwc; + u32 reg; + + list_for_each_entry(dwc, &dwc3_list, list) { + if (dwc->index != index) + continue; + + /* Enable/Disable snooping */ + reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + if (snoop) + reg |= DWC3_SNOOP_ENABLE; + else + reg &= ~DWC3_SNOOP_ENABLE; + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg); + break; + } +} + /** * dwc3_uboot_init - dwc3 core uboot initialization code * @dwc3_dev: struct dwc3_device containing initialization data diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 72d2fcd..455e7fa 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -593,6 +593,13 @@ struct dwc3_hwparams { /* HWPARAMS7 */ #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff)
+/* GSBUSCFG0 */ +#define DWC3_SNOOP_ENABLE (0x22220000) +#define DWC3_INCR_BTYPE_MASK (0xff) + +/* GSBUSCFG1 */ +#define DWC3_BREQ_LIMIT_MASK (0xf00) + struct dwc3_request { struct usb_request request; struct list_head list;

On 08/04/2016 11:26 AM, Rajat Srivastava wrote:
Adds helper functions to enable snooping and outstanding burst beat settings.
Signed-off-by: Rajat Srivastava rajat.srivastava@nxp.com Signed-off-by: Rajesh Bhagat rajesh.bhagat@nxp.com
Changes in v3:
- Changed operator for code cleanup
Changes in v2:
- Removes SoC specific flags and added helper functions
drivers/usb/dwc3/core.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 7 +++++++ 2 files changed, 52 insertions(+)
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 85cc96a..4ac599a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -599,6 +599,51 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
#define DWC3_ALIGN_MASK (16 - 1)
+void dwc3_core_incr_burst_enable(int index, int btype_incr_val,
int breq_limit)
+{
- struct dwc3 *dwc;
- u32 reg;
- list_for_each_entry(dwc, &dwc3_list, list) {
if (dwc->index != index)
continue;
/*
* Change burst beat and outstanding pipelined
* transfers requests
*/
reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
reg = (reg & ~DWC3_INCR_BTYPE_MASK) | btype_incr_val;
dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1);
reg = (reg & ~DWC3_BREQ_LIMIT_MASK) | (breq_limit << 8);
dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg);
You can use clrsetbits_le32() or such if this is not direct port from Linux.
break;
- }
+}
+void dwc3_core_set_snooping(int index, bool snoop) +{
- struct dwc3 *dwc;
- u32 reg;
- list_for_each_entry(dwc, &dwc3_list, list) {
if (dwc->index != index)
continue;
/* Enable/Disable snooping */
reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0);
if (snoop)
reg |= DWC3_SNOOP_ENABLE;
else
reg &= ~DWC3_SNOOP_ENABLE;
dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg);
break;
- }
+}
/**
- dwc3_uboot_init - dwc3 core uboot initialization code
- @dwc3_dev: struct dwc3_device containing initialization data
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 72d2fcd..455e7fa 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -593,6 +593,13 @@ struct dwc3_hwparams { /* HWPARAMS7 */ #define DWC3_RAM1_DEPTH(n) ((n) & 0xffff)
+/* GSBUSCFG0 */ +#define DWC3_SNOOP_ENABLE (0x22220000) +#define DWC3_INCR_BTYPE_MASK (0xff)
+/* GSBUSCFG1 */ +#define DWC3_BREQ_LIMIT_MASK (0xf00)
Parens around number are not necessary, please remove.
struct dwc3_request { struct usb_request request; struct list_head list;

Rajat,
On 08/04/2016 02:42 AM, Marek Vasut wrote:
On 08/04/2016 11:26 AM, Rajat Srivastava wrote:
You can use clrsetbits_le32() or such if this is not direct port from Linux.
<snip>
Parens around number are not necessary, please remove.
Are you going to update your patch?
York

Implements the dwc3 gadget driver support for LS1043 platform, and performs below operations: 1. Enables snooping support for DWC3 controller. 2. Enables cache coherency in LS1043 platform.
Signed-off-by: Rajat Srivastava rajat.srivastava@nxp.com Signed-off-by: Rajesh Bhagat rajesh.bhagat@nxp.com Reviewed-by: Lukasz Majewski l.majewski@samsung.com --- Changes in v3: - None
Changes in v2: - Moves DWC3 driver specific code to helper functions - Calls helper functions in SoC specific implementation
arch/arm/cpu/armv8/fsl-layerscape/soc.c | 93 ++++++++++++++++++++++ .../include/asm/arch-fsl-layerscape/immap_lsch2.h | 6 ++ 2 files changed, 99 insertions(+)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 0fb5c7f..cc07524 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -17,6 +17,10 @@ #ifdef CONFIG_CHAIN_OF_TRUST #include <fsl_validate.h> #endif +#include <usb.h> +#include <dwc3-uboot.h> +#include <linux/usb/xhci-fsl.h> +
DECLARE_GLOBAL_DATA_PTR;
@@ -318,9 +322,18 @@ void fsl_lsch2_early_init_f(void) #if defined(CONFIG_FSL_QSPI) && !defined(CONFIG_QSPI_BOOT) out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); #endif + /* Make SEC and USB reads and writes snoopable */ +#if defined(CONFIG_LS1043A) + setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | + SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP | + SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP | + SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP | + SCFG_SNPCNFGCR_USB3WRSNP); +#else /* Make SEC reads and writes snoopable */ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP); +#endif
/* * Enable snoop requests and DVM message requests for @@ -336,6 +349,86 @@ void fsl_lsch2_early_init_f(void) } #endif
+#ifdef CONFIG_USB_DWC3 + +#if defined(CONFIG_LS1043A) +static struct dwc3_device dwc3_device_data0 = { + .maximum_speed = USB_SPEED_HIGH, + .base = CONFIG_SYS_FSL_XHCI_USB1_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 0, +}; + +static struct dwc3_device dwc3_device_data1 = { + .maximum_speed = USB_SPEED_HIGH, + .base = CONFIG_SYS_FSL_XHCI_USB2_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 1, +}; + +static struct dwc3_device dwc3_device_data2 = { + .maximum_speed = USB_SPEED_HIGH, + .base = CONFIG_SYS_FSL_XHCI_USB3_ADDR, + .dr_mode = USB_DR_MODE_PERIPHERAL, + .index = 2, +}; + +int usb_gadget_handle_interrupts(int index) +{ + dwc3_uboot_handle_interrupt(index); + return 0; +} +#endif + +int board_usb_init(int index, enum usb_init_type init) +{ + switch (init) { + case USB_INIT_DEVICE: + switch (index) { +#if defined(CONFIG_LS1043A) + case 0: + dwc3_uboot_init(&dwc3_device_data0); + break; + case 1: + dwc3_uboot_init(&dwc3_device_data1); + break; + case 2: + dwc3_uboot_init(&dwc3_device_data2); + break; +#endif + default: + printf("Invalid Controller Index\n"); + return -1; + } +#if defined(CONFIG_LS1043A) + dwc3_core_incr_burst_enable(index, 0xf, 0xf); + dwc3_core_set_snooping(index, true); +#endif + break; + default: + break; + } + + return 0; +} + +int board_usb_cleanup(int index, enum usb_init_type init) +{ + switch (init) { + case USB_INIT_DEVICE: +#if defined(CONFIG_LS1043A) + dwc3_uboot_exit(index); +#endif + break; + default: + break; + } + return 0; +} +#endif + + + #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { diff --git a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h index 57b99d4..13ba1a6 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h @@ -328,6 +328,12 @@ struct ccsr_gur {
#define SCFG_SNPCNFGCR_SECRDSNP 0x80000000 #define SCFG_SNPCNFGCR_SECWRSNP 0x40000000 +#define SCFG_SNPCNFGCR_USB1RDSNP 0x00200000 +#define SCFG_SNPCNFGCR_USB1WRSNP 0x00100000 +#define SCFG_SNPCNFGCR_USB2RDSNP 0x00008000 +#define SCFG_SNPCNFGCR_USB2WRSNP 0x00010000 +#define SCFG_SNPCNFGCR_USB3RDSNP 0x00002000 +#define SCFG_SNPCNFGCR_USB3WRSNP 0x00004000
/* Supplemental Configuration Unit */ struct ccsr_scfg {

Enables dwc3 gadget driver support on LS1043QDS platform.
Signed-off-by: Rajat Srivastava rajat.srivastava@nxp.com Signed-off-by: Rajesh Bhagat rajesh.bhagat@nxp.com Reviewed-by: Lukasz Majewski l.majewski@samsung.com --- Changes in v3: - None
Changes in v2: - None
include/configs/ls1043aqds.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index af1f73d..8c99641 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -394,6 +394,21 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_USB_MAX_CONTROLLER_COUNT 3 #define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2 #define CONFIG_USB_STORAGE + +#define CONFIG_USB_DWC3 +#define CONFIG_USB_DWC3_GADGET + +#define CONFIG_USB_GADGET +#define CONFIG_USB_FUNCTION_MASS_STORAGE +#define CONFIG_USB_GADGET_DOWNLOAD +#define CONFIG_USB_GADGET_VBUS_DRAW 2 +#define CONFIG_G_DNL_MANUFACTURER "NXP Semiconductor" +#define CONFIG_G_DNL_VENDOR_NUM 0x0471 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234 +#define CONFIG_USB_GADGET_DUALSPEED + +/* USB Gadget ums command */ +#define CONFIG_CMD_USB_MASS_STORAGE #endif
/*
participants (3)
-
Marek Vasut
-
Rajat Srivastava
-
york sun