From f160c56c71c59d2d865142fdeb3040e9cc4b6a77 Mon Sep 17 00:00:00 2001 From: Prabhakar Kushwaha Date: Mon, 25 Apr 2016 17:14:25 +0530 Subject: [PATCH 17/93] armv8/fsl-layerscape: add dwc3 gadget driver support Implements the dwc3 gadget driver support for LS1043 and LS1012 platform. NOTE: Do not upstream this patch.It needs rework for open source submission. Signed-off-by: Rajat Srivastava Signed-off-by: Rajesh Bhagat Signed-off-by: Prabhakar Kushwaha --- arch/arm/cpu/armv8/fsl-layerscape/soc.c | 98 +++++++++++++++++++- .../include/asm/arch-fsl-layerscape/immap_lsch2.h | 6 ++ .../include/asm/arch-fsl-layerscape/sys_proto.h | 10 ++ common/cmd_usb_mass_storage.c | 2 +- drivers/usb/dwc3/core.c | 12 +++ drivers/usb/dwc3/ep0.c | 10 +- drivers/usb/dwc3/gadget.c | 11 ++- drivers/usb/dwc3/io.h | 8 +- drivers/usb/gadget/f_mass_storage.c | 10 +- include/configs/ls1012aqds.h | 15 +++ include/configs/ls1012ardb.h | 15 +++ include/configs/ls1043aqds.h | 15 +++ 12 files changed, 197 insertions(+), 15 deletions(-) create mode 100644 arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index ec561a7..0a170eb 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -19,6 +19,10 @@ #ifdef CONFIG_CHAIN_OF_TRUST #include #endif +#include +#include +#include + DECLARE_GLOBAL_DATA_PTR; @@ -406,9 +410,19 @@ 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 reads and writes snoopable */ + +#if defined(CONFIG_LS1043A) + /* Make SEC and USB reads and writes snoopable */ setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | - SCFG_SNPCNFGCR_SECWRSNP); + SCFG_SNPCNFGCR_SECWRSNP | SCFG_SNPCNFGCR_USB1RDSNP | + SCFG_SNPCNFGCR_USB1WRSNP | SCFG_SNPCNFGCR_USB2RDSNP | + SCFG_SNPCNFGCR_USB2WRSNP | SCFG_SNPCNFGCR_USB3RDSNP | + SCFG_SNPCNFGCR_USB3WRSNP); +#elif defined(CONFIG_LS1012A) + /* Make SEC and reads and writes snoopable */ + setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SECRDSNP | SCFG_SNPCNFGCR_SECWRSNP | + SCFG_SNPCNFGCR_USB1RDSNP | SCFG_SNPCNFGCR_USB1WRSNP); +#endif /* * Enable snoop requests and DVM message requests for @@ -428,6 +442,86 @@ void fsl_lsch2_early_init_f(void) } #endif +#ifdef CONFIG_USB_DWC3 + +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A) +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, +}; + +#if defined(CONFIG_LS1043A) +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, +}; +#endif + +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) || defined(CONFIG_LS1012A) + case 0: + dwc3_uboot_init(&dwc3_device_data0); + break; + +#if defined(CONFIG_LS1043A) + case 1: + dwc3_uboot_init(&dwc3_device_data1); + break; + case 2: + dwc3_uboot_init(&dwc3_device_data2); + break; +#endif +#endif + default: + printf("Invalid Controller Index\n"); + return -1; + } + 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) || defined(CONFIG_LS1012A) + 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 5b026f8..414a222 100644 --- a/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h +++ b/arch/arm/include/asm/arch-fsl-layerscape/immap_lsch2.h @@ -355,6 +355,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 { diff --git a/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h b/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h new file mode 100644 index 0000000..1e31d3d --- /dev/null +++ b/arch/arm/include/asm/arch-fsl-layerscape/sys_proto.h @@ -0,0 +1,10 @@ +/* + * Copyright 2015 Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_ +#define _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_ + +#endif /* _ASM_ARMV8_FSL_LAYERSCAPE_SYS_PROTO_H_ */ diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index 0407389..7d507b5 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -140,7 +140,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/dwc3/core.c b/drivers/usb/dwc3/core.c index 85cc96a..b8e4066 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -690,6 +690,18 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev) return -ENOMEM; } +#if defined(CONFIG_LS1043A) || defined(CONFIG_LS1012A) + /* Change burst beat and outstanding pipelined transfers requests */ + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, + (dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) & ~0xff) | 0xf); + dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, + dwc3_readl(dwc->regs, DWC3_GSBUSCFG1) | 0xf00); + + /* Enable snooping */ + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, + dwc3_readl(dwc->regs, DWC3_GSBUSCFG0) | 0x22220000); +#endif + if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc->dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 12b133f..e61d980 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -81,8 +81,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb->ctrl |= (DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_LST); - dwc3_flush_cache((long)buf_dma, len); - dwc3_flush_cache((long)trb, sizeof(*trb)); + dwc3_flush_cache((uintptr_t)buf_dma, len); + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); if (chain) return 0; @@ -790,7 +790,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, if (!r) return; - dwc3_flush_cache((long)trb, sizeof(*trb)); + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); status = DWC3_TRB_SIZE_TRBSTS(trb->size); if (status == DWC3_TRBSTS_SETUP_PENDING) { @@ -821,7 +821,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ur->actual += transferred; trb++; - dwc3_flush_cache((long)trb, sizeof(*trb)); + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); length = trb->size & DWC3_TRB_SIZE_MASK; ep0->free_slot = 0; @@ -831,7 +831,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp); transferred = min_t(u32, ur->length - transferred, transfer_size - length); - dwc3_flush_cache((long)dwc->ep0_bounce, DWC3_EP0_BOUNCE_SIZE); + dwc3_flush_cache((uintptr_t)dwc->ep0_bounce, DWC3_EP0_BOUNCE_SIZE); memcpy(buf, dwc->ep0_bounce, transferred); } else { transferred = ur->length - length; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8ff949d..649f1a4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -244,7 +244,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, list_del(&req->list); req->trb = NULL; - dwc3_flush_cache((long)req->request.dma, req->request.length); + dwc3_flush_cache((uintptr_t)req->request.dma, req->request.length); if (req->request.status == -EINPROGRESS) req->request.status = status; @@ -771,8 +771,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, trb->ctrl |= DWC3_TRB_CTRL_HWO; - dwc3_flush_cache((long)dma, length); - dwc3_flush_cache((long)trb, sizeof(*trb)); + dwc3_flush_cache((uintptr_t)dma, length); + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); } /* @@ -1769,7 +1769,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, slot %= DWC3_TRB_NUM; trb = &dep->trb_pool[slot]; - dwc3_flush_cache((long)trb, sizeof(*trb)); + dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); __dwc3_cleanup_done_trbs(dwc, dep, req, trb, event, status); dwc3_gadget_giveback(dep, req, status); @@ -2447,6 +2447,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) int left; u32 reg; + evt = dwc->ev_buffs[buf]; left = evt->count; @@ -2670,7 +2671,7 @@ void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - dwc3_flush_cache((long)evt->buf, evt->length); + dwc3_flush_cache((uintptr_t)evt->buf, evt->length); } dwc3_thread_interrupt(0, dwc); diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h index 0d9fa22..cab5122 100644 --- a/drivers/usb/dwc3/io.h +++ b/drivers/usb/dwc3/io.h @@ -48,8 +48,14 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) writel(value, base + offs); } -static inline void dwc3_flush_cache(int addr, int length) +static inline void dwc3_flush_cache(uintptr_t addr, int length) { flush_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE)); } + +static inline void dwc3_inval_cache(uintptr_t addr, int length) +{ + invalidate_dcache_range(addr, addr + ROUND(length, CACHELINE_SIZE)); +} + #endif /* __DRIVERS_USB_DWC3_IO_H */ diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index ec1f23a..ec0229f 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 { @@ -690,7 +691,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; @@ -2405,6 +2406,11 @@ int fsg_main_thread(void *common_) { int ret; struct fsg_common *common = the_fsg_common; + + /* update the controller_index */ + if (common_) + common->controller_index = *(unsigned int *)common_; + /* The main loop */ do { if (exception_in_progress(common)) { @@ -2475,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; @@ -2769,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/configs/ls1012aqds.h b/include/configs/ls1012aqds.h index 6346d3e..fdada18 100644 --- a/include/configs/ls1012aqds.h +++ b/include/configs/ls1012aqds.h @@ -123,6 +123,21 @@ #define CONFIG_CMD_USB #define CONFIG_USB_STORAGE #define CONFIG_CMD_EXT2 + +#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 0x1234 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234 +#define CONFIG_USB_GADGET_DUALSPEED + +/* USB Gadget ums command */ +#define CONFIG_CMD_USB_MASS_STORAGE #endif #define CONFIG_CMD_MEMINFO diff --git a/include/configs/ls1012ardb.h b/include/configs/ls1012ardb.h index 9ff5935..af3d33f 100644 --- a/include/configs/ls1012ardb.h +++ b/include/configs/ls1012ardb.h @@ -38,6 +38,21 @@ #define CONFIG_CMD_USB #define CONFIG_USB_STORAGE #define CONFIG_CMD_EXT2 + +#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 0x1234 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234 +#define CONFIG_USB_GADGET_DUALSPEED + +/* USB Gadget ums command */ +#define CONFIG_CMD_USB_MASS_STORAGE #endif /* diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index 9828360..9e23615 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -400,6 +400,21 @@ unsigned long get_board_ddr_clk(void); #define CONFIG_CMD_USB #define CONFIG_USB_STORAGE #define CONFIG_CMD_EXT2 + +#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 0x1234 +#define CONFIG_G_DNL_PRODUCT_NUM 0x1234 +#define CONFIG_USB_GADGET_DUALSPEED + +/* USB Gadget ums command */ +#define CONFIG_CMD_USB_MASS_STORAGE #endif /* -- 1.7.9.5