From f32a5e2325caf3dd0d720932cc241d8ba22875a8 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Wed, 4 Jun 2014 14:34:52 +0530 Subject: usb: dwc3: Keeping 'resource' related code together Putting together the code related to getting the 'IORESOURCE_MEM' and assigning the same to dwc->xhci_resources, for increasing the readability. Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index eb69eb9f06c8..fbe446350e28 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -656,6 +656,31 @@ static int dwc3_probe(struct platform_device *pdev) return -ENODEV; } + dwc->xhci_resources[0].start = res->start; + dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + + DWC3_XHCI_REGS_END; + dwc->xhci_resources[0].flags = res->flags; + dwc->xhci_resources[0].name = res->name; + + res->start += DWC3_GLOBALS_REGS_START; + + /* + * Request memory region but exclude xHCI regs, + * since it will be requested by the xhci-plat driver. + */ + regs = devm_ioremap_resource(dev, res); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + dwc->regs = regs; + dwc->regs_size = resource_size(res); + /* + * restore res->start back to its original value so that, + * in case the probe is deferred, we don't end up getting error in + * request the memory region the next time probe is called. + */ + res->start -= DWC3_GLOBALS_REGS_START; + if (node) { dwc->maximum_speed = of_usb_get_maximum_speed(node); @@ -676,28 +701,9 @@ static int dwc3_probe(struct platform_device *pdev) if (ret) return ret; - dwc->xhci_resources[0].start = res->start; - dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + - DWC3_XHCI_REGS_END; - dwc->xhci_resources[0].flags = res->flags; - dwc->xhci_resources[0].name = res->name; - - res->start += DWC3_GLOBALS_REGS_START; - - /* - * Request memory region but exclude xHCI regs, - * since it will be requested by the xhci-plat driver. - */ - regs = devm_ioremap_resource(dev, res); - if (IS_ERR(regs)) - return PTR_ERR(regs); - spin_lock_init(&dwc->lock); platform_set_drvdata(pdev, dwc); - dwc->regs = regs; - dwc->regs_size = resource_size(res); - dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); -- cgit v1.2.3 From 0e1e5c47f7a92853a92ef97494fb4fee26d333ac Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Fri, 23 May 2014 11:39:24 -0700 Subject: usb: dwc3: add support for USB 2.0-only core configuration Newer DWC3 controllers can be built for USB 2.0-only mode, where most of the USB 3.0 circuitry is left out. To support this mode, the driver must limit the speed programmed into the DCFG register to Hi-Speed or lower. Reads and writes to the PIPECTL register are left as-is, since they should be no-ops in USB 2.0-only mode. Calls to phy_init() etc. for the USB3 phy are also left as-is, since the no-op USB3 phy should be used for USB 2.0-only mode controllers. Signed-off-by: Paul Zimmerman Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 7 +++++++ drivers/usb/dwc3/core.h | 13 +++++++++++++ 2 files changed, 20 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index fbe446350e28..b769c1faaf03 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -386,6 +386,13 @@ static int dwc3_core_init(struct dwc3 *dwc) } dwc->revision = reg; + /* Handle USB2.0-only core configuration */ + if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == + DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { + if (dwc->maximum_speed == USB_SPEED_SUPER) + dwc->maximum_speed = USB_SPEED_HIGH; + } + /* issue device SoftReset too */ timeout = jiffies + msecs_to_jiffies(500); dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 57332e3768e4..48fb264065db 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -191,6 +191,19 @@ #define DWC3_GHWPARAMS1_PWROPT(n) ((n) << 24) #define DWC3_GHWPARAMS1_PWROPT_MASK DWC3_GHWPARAMS1_PWROPT(3) +/* Global HWPARAMS3 Register */ +#define DWC3_GHWPARAMS3_SSPHY_IFC(n) ((n) & 3) +#define DWC3_GHWPARAMS3_SSPHY_IFC_DIS 0 +#define DWC3_GHWPARAMS3_SSPHY_IFC_ENA 1 +#define DWC3_GHWPARAMS3_HSPHY_IFC(n) (((n) & (3 << 2)) >> 2) +#define DWC3_GHWPARAMS3_HSPHY_IFC_DIS 0 +#define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI 1 +#define DWC3_GHWPARAMS3_HSPHY_IFC_ULPI 2 +#define DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI 3 +#define DWC3_GHWPARAMS3_FSPHY_IFC(n) (((n) & (3 << 4)) >> 4) +#define DWC3_GHWPARAMS3_FSPHY_IFC_DIS 0 +#define DWC3_GHWPARAMS3_FSPHY_IFC_ENA 1 + /* Global HWPARAMS4 Register */ #define DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(n) (((n) & (0x0f << 13)) >> 13) #define DWC3_MAX_HIBER_SCRATCHBUFS 15 -- cgit v1.2.3 From 029d97ff543219762685805e15d71f7005ad7c5e Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 4 Jul 2014 15:00:51 +0900 Subject: usb: dwc3: gadget: remove unnecessary 'start_new' variable Remove 'start_new' variable from dwc3_endpoint_transfer_complete(), since this variable has not been used. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9d64dd02c57e..d9304a8ceef3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1971,8 +1971,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, } static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, - struct dwc3_ep *dep, const struct dwc3_event_depevt *event, - int start_new) + struct dwc3_ep *dep, const struct dwc3_event_depevt *event) { unsigned status = 0; int clean_busy; @@ -2039,7 +2038,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, return; } - dwc3_endpoint_transfer_complete(dwc, dep, event, 1); + dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERINPROGRESS: if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { @@ -2048,7 +2047,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, return; } - dwc3_endpoint_transfer_complete(dwc, dep, event, 0); + dwc3_endpoint_transfer_complete(dwc, dep, event); break; case DWC3_DEPEVT_XFERNOTREADY: if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { -- cgit v1.2.3 From ca632a0d2fec10e62377a78a424d68c90f2e4345 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Wed, 16 Jul 2014 18:37:05 +0530 Subject: usb: dwc3: omap: remove x_major calculation from revision register Remove the x_major calculation logic from the wrapper revision register to differentiate between OMAP5 and AM437x. This was done to find the register offsets of wrapper register. Now that We do it using dt compatible, remove the whole logic. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 4af4c3567656..25a6075ef319 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -77,10 +77,6 @@ #define USBOTGSS_DEV_EBC_EN 0x0110 #define USBOTGSS_DEBUG_OFFSET 0x0600 -/* REVISION REGISTER */ -#define USBOTGSS_REVISION_XMAJOR(reg) ((reg >> 8) & 0x7) -#define USBOTGSS_REVISION_XMAJOR1 1 -#define USBOTGSS_REVISION_XMAJOR2 2 /* SYSCONFIG REGISTER */ #define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16) @@ -129,7 +125,6 @@ struct dwc3_omap { u32 irq_eoi_offset; u32 debug_offset; u32 irq0_offset; - u32 revision; u32 dma_status:1; @@ -397,7 +392,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) int irq; int utmi_mode = 0; - int x_major; u32 reg; @@ -448,32 +442,13 @@ static int dwc3_omap_probe(struct platform_device *pdev) goto err0; } - reg = dwc3_omap_readl(omap->base, USBOTGSS_REVISION); - omap->revision = reg; - x_major = USBOTGSS_REVISION_XMAJOR(reg); - - /* Differentiate between OMAP5 and AM437x */ - switch (x_major) { - case USBOTGSS_REVISION_XMAJOR1: - case USBOTGSS_REVISION_XMAJOR2: - omap->irq_eoi_offset = 0; - omap->irq0_offset = 0; - omap->irqmisc_offset = 0; - omap->utmi_otg_offset = 0; - omap->debug_offset = 0; - break; - default: - /* Default to the latest revision */ - omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; - omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; - omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; - omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; - omap->debug_offset = USBOTGSS_DEBUG_OFFSET; - break; - } - - /* For OMAP5(ES2.0) and AM437x x_major is 2 even though there are - * changes in wrapper registers, Using dt compatible for aegis + /* + * Differentiate between OMAP5 and AM437x. + * + * For OMAP5(ES2.0) and AM437x wrapper revision is same, even + * though there are changes in wrapper register offsets. + * + * Using dt compatible to differentiate AM437x. */ if (of_device_is_compatible(node, "ti,am437x-dwc3")) { -- cgit v1.2.3 From 30fef1a97fb6551abb50b5208993726b878fe40f Mon Sep 17 00:00:00 2001 From: George Cherian Date: Wed, 16 Jul 2014 18:37:06 +0530 Subject: usb: dwc3: omap: add dwc3_omap_map_offset() function Move map offset to its own separate function. Improve code readability, decrease the dwc3_probe() size. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 25a6075ef319..22fca6291ff5 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -378,6 +378,27 @@ static int dwc3_omap_vbus_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static void dwc3_omap_map_offset(struct dwc3_omap *omap) +{ + struct device_node *node = omap->dev->of_node; + + /* + * Differentiate between OMAP5 and AM437x. + * + * For OMAP5(ES2.0) and AM437x wrapper revision is same, even + * though there are changes in wrapper register offsets. + * + * Using dt compatible to differentiate AM437x. + */ + if (of_device_is_compatible(node, "ti,am437x-dwc3")) { + omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; + omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; + omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; + omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; + omap->debug_offset = USBOTGSS_DEBUG_OFFSET; + } +} + static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -442,22 +463,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) goto err0; } - /* - * Differentiate between OMAP5 and AM437x. - * - * For OMAP5(ES2.0) and AM437x wrapper revision is same, even - * though there are changes in wrapper register offsets. - * - * Using dt compatible to differentiate AM437x. - */ - - if (of_device_is_compatible(node, "ti,am437x-dwc3")) { - omap->irq_eoi_offset = USBOTGSS_EOI_OFFSET; - omap->irq0_offset = USBOTGSS_IRQ0_OFFSET; - omap->irqmisc_offset = USBOTGSS_IRQMISC_OFFSET; - omap->utmi_otg_offset = USBOTGSS_UTMI_OTG_OFFSET; - omap->debug_offset = USBOTGSS_DEBUG_OFFSET; - } + dwc3_omap_map_offset(omap); reg = dwc3_omap_read_utmi_status(omap); -- cgit v1.2.3 From d2f0cf89ca2deca59cc4ca0c80c14100831428db Mon Sep 17 00:00:00 2001 From: George Cherian Date: Wed, 16 Jul 2014 18:37:07 +0530 Subject: usb: dwc3: omap: add dwc3_omap_set_utmi_mode() function Move find and set the utmi mode to its own separate function. Improve code readability, decrease the dwc3_probe() size. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 22fca6291ff5..6a90b96c9d14 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -399,6 +399,30 @@ static void dwc3_omap_map_offset(struct dwc3_omap *omap) } } +static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) +{ + u32 reg; + struct device_node *node = omap->dev->of_node; + int utmi_mode = 0; + + reg = dwc3_omap_read_utmi_status(omap); + + of_property_read_u32(node, "utmi-mode", &utmi_mode); + + switch (utmi_mode) { + case DWC3_OMAP_UTMI_MODE_SW: + reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + break; + case DWC3_OMAP_UTMI_MODE_HW: + reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; + break; + default: + dev_dbg(omap->dev, "UNKNOWN utmi mode %d\n", utmi_mode); + } + + dwc3_omap_write_utmi_status(omap, reg); +} + static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -412,8 +436,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) int ret; int irq; - int utmi_mode = 0; - u32 reg; void __iomem *base; @@ -464,23 +486,7 @@ static int dwc3_omap_probe(struct platform_device *pdev) } dwc3_omap_map_offset(omap); - - reg = dwc3_omap_read_utmi_status(omap); - - of_property_read_u32(node, "utmi-mode", &utmi_mode); - - switch (utmi_mode) { - case DWC3_OMAP_UTMI_MODE_SW: - reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE; - break; - case DWC3_OMAP_UTMI_MODE_HW: - reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE; - break; - default: - dev_dbg(dev, "UNKNOWN utmi mode %d\n", utmi_mode); - } - - dwc3_omap_write_utmi_status(omap, reg); + dwc3_omap_set_utmi_mode(omap); /* check the DMA Status */ reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG); -- cgit v1.2.3 From 025b431b0ed3d4d3363427661c53ed8b60487a44 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Wed, 16 Jul 2014 18:37:08 +0530 Subject: usb: dwc3: omap: add dwc3_omap_extcon_register function Move the extcon related code to its own function. Improve code readability, decrease the dwc3_probe() size. Signed-off-by: George Cherian Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 65 ++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 6a90b96c9d14..961295d7042f 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -423,6 +423,42 @@ static void dwc3_omap_set_utmi_mode(struct dwc3_omap *omap) dwc3_omap_write_utmi_status(omap, reg); } +static int dwc3_omap_extcon_register(struct dwc3_omap *omap) +{ + u32 ret; + struct device_node *node = omap->dev->of_node; + struct extcon_dev *edev; + + if (of_property_read_bool(node, "extcon")) { + edev = extcon_get_edev_by_phandle(omap->dev, 0); + if (IS_ERR(edev)) { + dev_vdbg(omap->dev, "couldn't get extcon device\n"); + return -EPROBE_DEFER; + } + + omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; + ret = extcon_register_interest(&omap->extcon_vbus_dev, + edev->name, "USB", + &omap->vbus_nb); + if (ret < 0) + dev_vdbg(omap->dev, "failed to register notifier for USB\n"); + + omap->id_nb.notifier_call = dwc3_omap_id_notifier; + ret = extcon_register_interest(&omap->extcon_id_dev, + edev->name, "USB-HOST", + &omap->id_nb); + if (ret < 0) + dev_vdbg(omap->dev, "failed to register notifier for USB-HOST\n"); + + if (extcon_get_cable_state(edev, "USB") == true) + dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); + if (extcon_get_cable_state(edev, "USB-HOST") == true) + dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); + } + + return 0; +} + static int dwc3_omap_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; @@ -430,7 +466,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) struct dwc3_omap *omap; struct resource *res; struct device *dev = &pdev->dev; - struct extcon_dev *edev; struct regulator *vbus_reg = NULL; int ret; @@ -502,31 +537,9 @@ static int dwc3_omap_probe(struct platform_device *pdev) dwc3_omap_enable_irqs(omap); - if (of_property_read_bool(node, "extcon")) { - edev = extcon_get_edev_by_phandle(dev, 0); - if (IS_ERR(edev)) { - dev_vdbg(dev, "couldn't get extcon device\n"); - ret = -EPROBE_DEFER; - goto err2; - } - - omap->vbus_nb.notifier_call = dwc3_omap_vbus_notifier; - ret = extcon_register_interest(&omap->extcon_vbus_dev, - edev->name, "USB", &omap->vbus_nb); - if (ret < 0) - dev_vdbg(dev, "failed to register notifier for USB\n"); - omap->id_nb.notifier_call = dwc3_omap_id_notifier; - ret = extcon_register_interest(&omap->extcon_id_dev, edev->name, - "USB-HOST", &omap->id_nb); - if (ret < 0) - dev_vdbg(dev, - "failed to register notifier for USB-HOST\n"); - - if (extcon_get_cable_state(edev, "USB") == true) - dwc3_omap_set_mailbox(omap, OMAP_DWC3_VBUS_VALID); - if (extcon_get_cable_state(edev, "USB-HOST") == true) - dwc3_omap_set_mailbox(omap, OMAP_DWC3_ID_GROUND); - } + ret = dwc3_omap_extcon_register(omap); + if (ret < 0) + goto err2; ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { -- cgit v1.2.3