openwrtv4/package/boot/uboot-layerscape/patches/0017-armv8-fsl-layerscape-add-dwc3-gadget-driver-support.patch

466 lines
14 KiB
Diff
Raw Normal View History

From f160c56c71c59d2d865142fdeb3040e9cc4b6a77 Mon Sep 17 00:00:00 2001
From: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
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 <rajat.srivastava@nxp.com>
Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
---
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 <fsl_validate.h>
#endif
+#include <usb.h>
+#include <dwc3-uboot.h>
+#include <linux/usb/xhci-fsl.h>
+
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