From 3fe314ca8c970aefc2d2a96dd93df6de1f4f1a4b Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 12 Jun 2018 14:26:43 -0700 Subject: usb: dwc3: Add a glue driver for Synopsys HAPS platform This driver is to be used for Synopsys PCIe-base HAPS platform. Move the the HAPS support from dwc3-pci to this driver. Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 13 ++-- drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-haps.c | 137 +++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/dwc3-pci.c | 30 ---------- 4 files changed, 147 insertions(+), 34 deletions(-) create mode 100644 drivers/usb/dwc3/dwc3-haps.c (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 451012ea1294..518ead12458d 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -74,11 +74,16 @@ config USB_DWC3_PCI depends on USB_PCI && ACPI default USB_DWC3 help - If you're using the DesignWare Core IP with a PCIe, please say - 'Y' or 'M' here. + If you're using the DesignWare Core IP with a PCIe (but not HAPS + platform), please say 'Y' or 'M' here. - One such PCIe-based platform is Synopsys' PCIe HAPS model of - this IP. +config USB_DWC3_HAPS + tristate "Synopsys PCIe-based HAPS Platforms" + depends on USB_PCI + default USB_DWC3 + help + If you're using the DesignWare Core IP with a Synopsys PCIe HAPS + platform, please say 'Y' or 'M' here. config USB_DWC3_KEYSTONE tristate "Texas Instruments Keystone2 Platforms" diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 5c07d8f925e0..6e3ef6144e5d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -45,6 +45,7 @@ endif obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o +obj-$(CONFIG_USB_DWC3_HAPS) += dwc3-haps.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o diff --git a/drivers/usb/dwc3/dwc3-haps.c b/drivers/usb/dwc3/dwc3-haps.c new file mode 100644 index 000000000000..c9cc33881bef --- /dev/null +++ b/drivers/usb/dwc3/dwc3-haps.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * dwc3-haps.c - Synopsys HAPS PCI Specific glue layer + * + * Copyright (C) 2018 Synopsys, Inc. + * + * Authors: Thinh Nguyen , + * John Youn + */ + +#include +#include +#include +#include +#include +#include + +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf + +/** + * struct dwc3_haps - Driver private structure + * @dwc3: child dwc3 platform_device + * @pci: our link to PCI bus + */ +struct dwc3_haps { + struct platform_device *dwc3; + struct pci_dev *pci; +}; + +static const struct property_entry initial_properties[] = { + PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), + PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), + PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + { }, +}; + +static int dwc3_haps_probe(struct pci_dev *pci, + const struct pci_device_id *id) +{ + struct dwc3_haps *dwc; + struct device *dev = &pci->dev; + struct resource res[2]; + int ret; + + ret = pcim_enable_device(pci); + if (ret) { + dev_err(dev, "failed to enable pci device\n"); + return -ENODEV; + } + + pci_set_master(pci); + + dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); + if (!dwc) + return -ENOMEM; + + dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); + if (!dwc->dwc3) + return -ENOMEM; + + memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); + + res[0].start = pci_resource_start(pci, 0); + res[0].end = pci_resource_end(pci, 0); + res[0].name = "dwc_usb3"; + res[0].flags = IORESOURCE_MEM; + + res[1].start = pci->irq; + res[1].name = "dwc_usb3"; + res[1].flags = IORESOURCE_IRQ; + + ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res)); + if (ret) { + dev_err(dev, "couldn't add resources to dwc3 device\n"); + goto err; + } + + dwc->pci = pci; + dwc->dwc3->dev.parent = dev; + + ret = platform_device_add_properties(dwc->dwc3, initial_properties); + if (ret) + goto err; + + ret = platform_device_add(dwc->dwc3); + if (ret) { + dev_err(dev, "failed to register dwc3 device\n"); + goto err; + } + + pci_set_drvdata(pci, dwc); + + return 0; +err: + platform_device_put(dwc->dwc3); + return ret; +} + +static void dwc3_haps_remove(struct pci_dev *pci) +{ + struct dwc3_haps *dwc = pci_get_drvdata(pci); + + platform_device_unregister(dwc->dwc3); +} + +static const struct pci_device_id dwc3_haps_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), + }, + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI), + }, + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31), + }, + { } /* Terminating Entry */ +}; +MODULE_DEVICE_TABLE(pci, dwc3_haps_id_table); + +static struct pci_driver dwc3_haps_driver = { + .name = "dwc3-haps", + .id_table = dwc3_haps_id_table, + .probe = dwc3_haps_probe, + .remove = dwc3_haps_remove, +}; + +MODULE_AUTHOR("Thinh Nguyen "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Synopsys HAPS PCI Glue Layer"); + +module_pci_driver(dwc3_haps_driver); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index f57e7c94b8e5..80f5dc691038 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -19,9 +19,6 @@ #include #include -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e #define PCI_DEVICE_ID_INTEL_BSW 0x22b7 @@ -151,21 +148,6 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) } } - if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS && - (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 || - pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI || - pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) { - struct property_entry properties[] = { - PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), - PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), - PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), - PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), - { }, - }; - - return platform_device_add_properties(dwc3, properties); - } - return 0; } @@ -266,18 +248,6 @@ static void dwc3_pci_remove(struct pci_dev *pci) } static const struct pci_device_id dwc3_pci_id_table[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, - PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), - }, - { - PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, - PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI), - }, - { - PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, - PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31), - }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, -- cgit v1.2.3 From 5741022cbdf3616a9def13b15ab5667a36c65706 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 10 Jun 2018 16:01:20 +0200 Subject: usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources Bay Trail / BYT SoCs do not have a builtin device-mode phy, instead they require an external ULPI phy for device-mode. Only some BYT devices have an external phy, but even on those devices device-mode is not working because the dwc3 does not see the phy. The problem is that the ACPI fwnode for the dwc3 does not contain the expected GPIO resources for the GPIOs connected to the chip-select and reset pins of the phy. I've found the workaround which some Android x86 kernels use for this: https://github.com/BORETS24/Kernel-for-Asus-Zenfone-2/blob/master/arch/x86/platform/intel-mid/device_libs/pci/platform_usb_otg.c Which boils down to hardcoding the GPIOs for these devices. The good news it that all boards (*) use the same GPIOs. This commit fixes the ULPI phy not woring by adding a gpiod_lookup_table call which adds a hardcoded mapping for BYT devices. Note that the mapping added by gpiod_add_lookup_table is a fallback mapping, so boards which properly provide GPIO resources in the ACPI firmware-node resources will not use this. *) Except for the first revision of the evalulation-kit, which normal users don't have Signed-off-by: Hans de Goede Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 80f5dc691038..5c175f839efd 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,15 @@ static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = { { }, }; +static struct gpiod_lookup_table platform_bytcr_gpios = { + .dev_id = "0000:00:16.0", + .table = { + GPIO_LOOKUP("INT33FC:00", 54, "reset", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("INT33FC:02", 14, "cs", GPIO_ACTIVE_HIGH), + {} + }, +}; + static int dwc3_pci_quirks(struct dwc3_pci *dwc) { struct platform_device *dwc3 = dwc->dwc3; @@ -124,6 +134,13 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) if (ret) dev_dbg(&pdev->dev, "failed to add mapping table\n"); + /* + * A lot of BYT devices lack ACPI resource entries for + * the GPIOs, add a fallback mapping to the reference + * design GPIOs which all boards seem to use. + */ + gpiod_add_lookup_table(&platform_bytcr_gpios); + /* * These GPIOs will turn on the USB2 PHY. Note that we have to * put the gpio descriptors again here because the phy driver @@ -239,6 +256,7 @@ static void dwc3_pci_remove(struct pci_dev *pci) { struct dwc3_pci *dwc = pci_get_drvdata(pci); + gpiod_remove_lookup_table(&platform_bytcr_gpios); #ifdef CONFIG_PM cancel_work_sync(&dwc->wakeup_work); #endif -- cgit v1.2.3 From 7740d04d901db7fe631b89dc4f695093327e2124 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 10 Jun 2018 16:01:21 +0200 Subject: usb: dwc3: pci: Enable ULPI Refclk on platforms where the firmware does not On some Bay Trail (BYT) systems the firmware does not enable the ULPI Refclk. This commit adds a helper which checks and if necessary enabled the Refclk and calls this helper for BYT machines. Signed-off-by: Hans de Goede Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 5c175f839efd..26829b299482 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -39,6 +39,10 @@ #define PCI_INTEL_BXT_STATE_D0 0 #define PCI_INTEL_BXT_STATE_D3 3 +#define GP_RWBAR 1 +#define GP_RWREG1 0xa0 +#define GP_RWREG1_ULPI_REFCLK_DISABLE (1 << 17) + /** * struct dwc3_pci - Driver private structure * @dwc3: child dwc3 platform_device @@ -74,6 +78,28 @@ static struct gpiod_lookup_table platform_bytcr_gpios = { }, }; +static int dwc3_byt_enable_ulpi_refclock(struct pci_dev *pci) +{ + void __iomem *reg; + u32 value; + + reg = pcim_iomap(pci, GP_RWBAR, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + + value = readl(reg + GP_RWREG1); + if (!(value & GP_RWREG1_ULPI_REFCLK_DISABLE)) + goto unmap; /* ULPI refclk already enabled */ + + value &= ~GP_RWREG1_ULPI_REFCLK_DISABLE; + writel(value, reg + GP_RWREG1); + /* This comes from the Intel Android x86 tree w/o any explanation */ + msleep(100); +unmap: + pcim_iounmap(pci, reg); + return 0; +} + static int dwc3_pci_quirks(struct dwc3_pci *dwc) { struct platform_device *dwc3 = dwc->dwc3; @@ -129,6 +155,11 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { struct gpio_desc *gpio; + /* On BYT the FW does not always enable the refclock */ + ret = dwc3_byt_enable_ulpi_refclock(pdev); + if (ret) + return ret; + ret = devm_acpi_dev_add_driver_gpios(&pdev->dev, acpi_dwc3_byt_gpios); if (ret) -- cgit v1.2.3 From 211f658b7b40fd3355a0920481132645e24ffb16 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 10 Jun 2018 16:01:22 +0200 Subject: usb: dwc3: pci: Use devm functions to get the phy GPIOs Even though we only use them once, it is better to not put/release the GPIOs immediately after use, so that others cannot claim them. Use devm functions to get the phy GPIOs, so that they will be automatically released when were unbound from the device and remove the gpio_put calls. Signed-off-by: Hans de Goede Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 26829b299482..08713398073d 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -177,20 +177,20 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) * put the gpio descriptors again here because the phy driver * might want to grab them, too. */ - gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW); + gpio = devm_gpiod_get_optional(&pdev->dev, "cs", + GPIOD_OUT_LOW); if (IS_ERR(gpio)) return PTR_ERR(gpio); gpiod_set_value_cansleep(gpio, 1); - gpiod_put(gpio); - gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); + gpio = devm_gpiod_get_optional(&pdev->dev, "reset", + GPIOD_OUT_LOW); if (IS_ERR(gpio)) return PTR_ERR(gpio); if (gpio) { gpiod_set_value_cansleep(gpio, 1); - gpiod_put(gpio); usleep_range(10000, 11000); } } -- cgit v1.2.3 From 76251db8656194d27629300c852b53c471e9b586 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Mon, 16 Jul 2018 12:25:47 +0200 Subject: usb: dwc3: of-simple: reset host controller at suspend/resume If we power off the SoC logic rail in S3, we can find that the Type-C PHY can't initialize correctly after system resume. We need to toggle the USB3-OTG reset before trying to initialize the PHY, or else it times out. phy phy-ff800000.phy.9: phy poweron failed --> -110 dwc3 fe900000.dwc3: failed to initialize core dwc3: probe of fe900000.dwc3 failed with error -110 Note that the RK3399 TRM suggests that we should keep the whole usb3 controller in reset for the duration of the Type-C PHY initialization. However, it's hard to assert the reset in the current framework of reset. We're still skeptical about that, and we haven't yet found a case where this seems to have mattered. This approach is much easier, it simply holds the USB3-OTG reset while device is supended. The dwc3 core is going to reinitialize the controller at suspend/resume anyway (including a "soft reset"), so it should be safe to do this. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-of-simple.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index dbeff5e6ad14..40bf9e0bbc59 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -28,6 +28,7 @@ struct dwc3_of_simple { int num_clocks; struct reset_control *resets; bool pulse_resets; + bool need_reset; }; static int dwc3_of_simple_clk_init(struct dwc3_of_simple *simple, int count) @@ -93,6 +94,13 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) platform_set_drvdata(pdev, simple); simple->dev = dev; + /* + * Some controllers need to toggle the usb3-otg reset before trying to + * initialize the PHY, otherwise the PHY times out. + */ + if (of_device_is_compatible(np, "rockchip,rk3399-dwc3")) + simple->need_reset = true; + if (of_device_is_compatible(np, "amlogic,meson-axg-dwc3") || of_device_is_compatible(np, "amlogic,meson-gxl-dwc3")) { shared_resets = true; @@ -201,9 +209,30 @@ static int dwc3_of_simple_runtime_resume(struct device *dev) return 0; } + +static int dwc3_of_simple_suspend(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + + if (simple->need_reset) + reset_control_assert(simple->resets); + + return 0; +} + +static int dwc3_of_simple_resume(struct device *dev) +{ + struct dwc3_of_simple *simple = dev_get_drvdata(dev); + + if (simple->need_reset) + reset_control_deassert(simple->resets); + + return 0; +} #endif static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_of_simple_suspend, dwc3_of_simple_resume) SET_RUNTIME_PM_OPS(dwc3_of_simple_runtime_suspend, dwc3_of_simple_runtime_resume, NULL) }; -- cgit v1.2.3 From 9a7faac3650216112e034b157289bf1a48a99e2d Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 19 Jul 2018 17:26:24 -0600 Subject: usb: dwc3: change stream event enable bit back to 13 Commit ff3f0789b3dc ("usb: dwc3: use BIT() macro where possible") changed DWC3_DEPCFG_STREAM_EVENT_EN from bit 13 to bit 12. Spotted this cleanup typo while looking at diffs between 4.9.35 and 4.14.16 for a separate issue. Fixes: ff3f0789b3dc ("usb: dwc3: use BIT() macro where possible") Signed-off-by: Erich E. Hoover Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index db610c56f1d6..2aacd1afd9ff 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -25,7 +25,7 @@ struct dwc3; #define DWC3_DEPCFG_XFER_IN_PROGRESS_EN BIT(9) #define DWC3_DEPCFG_XFER_NOT_READY_EN BIT(10) #define DWC3_DEPCFG_FIFO_ERROR_EN BIT(11) -#define DWC3_DEPCFG_STREAM_EVENT_EN BIT(12) +#define DWC3_DEPCFG_STREAM_EVENT_EN BIT(13) #define DWC3_DEPCFG_BINTERVAL_M1(n) (((n) & 0xff) << 16) #define DWC3_DEPCFG_STREAM_CAPABLE BIT(24) #define DWC3_DEPCFG_EP_NUMBER(n) (((n) & 0x1f) << 25) -- cgit v1.2.3 From 87d852de94d606010faf283bf1df70e3e825e6d0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 20 Jul 2018 19:54:01 +0300 Subject: usb: dwc3: Describe 'wakeup_work' field of struct dwc3_pci Describe 'wakeup_work' field of struct dwc3_pci to avoid a warning: drivers/usb/dwc3/dwc3-pci.c:59: warning: Function parameter or member 'wakeup_work' not described in 'dwc3_pci' Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 08713398073d..b29f031dfc23 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -49,6 +49,7 @@ * @pci: our link to PCI bus * @guid: _DSM GUID * @has_dsm_for_pm: true for devices which need to run _DSM on runtime PM + * @wakeup_work: work for asynchronous resume */ struct dwc3_pci { struct platform_device *dwc3; -- cgit v1.2.3 From d635db5508b0b01142d44739717d7122469f59b1 Mon Sep 17 00:00:00 2001 From: Pengbo Mu Date: Mon, 23 Jul 2018 18:32:36 +0800 Subject: usb: dwc3: add global soc bus configuration reg0 Add the macro definition for global soc bus configuration register 0 Signed-off-by: Changming Huang Signed-off-by: Ran Wang Signed-off-by: Pengbo Mu Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 285ce0ef3b91..213b939ad011 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -163,6 +163,17 @@ /* Bit fields */ +/* Global SoC Bus Configuration INCRx Register 0 */ +#define DWC3_GSBUSCFG0_INCR256BRSTENA (1 << 7) /* INCR256 burst */ +#define DWC3_GSBUSCFG0_INCR128BRSTENA (1 << 6) /* INCR128 burst */ +#define DWC3_GSBUSCFG0_INCR64BRSTENA (1 << 5) /* INCR64 burst */ +#define DWC3_GSBUSCFG0_INCR32BRSTENA (1 << 4) /* INCR32 burst */ +#define DWC3_GSBUSCFG0_INCR16BRSTENA (1 << 3) /* INCR16 burst */ +#define DWC3_GSBUSCFG0_INCR8BRSTENA (1 << 2) /* INCR8 burst */ +#define DWC3_GSBUSCFG0_INCR4BRSTENA (1 << 1) /* INCR4 burst */ +#define DWC3_GSBUSCFG0_INCRBRSTENA (1 << 0) /* undefined length enable */ +#define DWC3_GSBUSCFG0_INCRBRST_MASK 0xff + /* Global Debug Queue/FIFO Space Available Register */ #define DWC3_GDBGFIFOSPACE_NUM(n) ((n) & 0x1f) #define DWC3_GDBGFIFOSPACE_TYPE(n) (((n) << 5) & 0x1e0) -- cgit v1.2.3 From d9612c2f0449e24983a8b689603210486a930c90 Mon Sep 17 00:00:00 2001 From: Pengbo Mu Date: Mon, 23 Jul 2018 18:32:37 +0800 Subject: usb: dwc3: Enable undefined length INCR burst type Enable the undefined length INCR burst type and set INCRx. Different platform may has the different burst size type. In order to get best performance, we need to tune the burst size to one special value, instead of the default value. Signed-off-by: Changming Huang Signed-off-by: Ran Wang Signed-off-by: Pengbo Mu Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 3 ++ 2 files changed, 97 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 103807587dc6..21e4931d0cc0 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -778,6 +778,98 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) static int dwc3_core_get_phy(struct dwc3 *dwc); static int dwc3_core_ulpi_init(struct dwc3 *dwc); +/* set global incr burst type configuration registers */ +static void dwc3_set_incr_burst_type(struct dwc3 *dwc) +{ + struct device *dev = dwc->dev; + /* incrx_mode : for INCR burst type. */ + bool incrx_mode; + /* incrx_size : for size of INCRX burst. */ + u32 incrx_size; + u32 *vals; + u32 cfg; + int ntype; + int ret; + int i; + + cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + + /* + * Handle property "snps,incr-burst-type-adjustment". + * Get the number of value from this property: + * result <= 0, means this property is not supported. + * result = 1, means INCRx burst mode supported. + * result > 1, means undefined length burst mode supported. + */ + ntype = device_property_read_u32_array(dev, + "snps,incr-burst-type-adjustment", NULL, 0); + if (ntype <= 0) + return; + + vals = kcalloc(ntype, sizeof(u32), GFP_KERNEL); + if (!vals) { + dev_err(dev, "Error to get memory\n"); + return; + } + + /* Get INCR burst type, and parse it */ + ret = device_property_read_u32_array(dev, + "snps,incr-burst-type-adjustment", vals, ntype); + if (ret) { + dev_err(dev, "Error to get property\n"); + return; + } + + incrx_size = *vals; + + if (ntype > 1) { + /* INCRX (undefined length) burst mode */ + incrx_mode = INCRX_UNDEF_LENGTH_BURST_MODE; + for (i = 1; i < ntype; i++) { + if (vals[i] > incrx_size) + incrx_size = vals[i]; + } + } else { + /* INCRX burst mode */ + incrx_mode = INCRX_BURST_MODE; + } + + /* Enable Undefined Length INCR Burst and Enable INCRx Burst */ + cfg &= ~DWC3_GSBUSCFG0_INCRBRST_MASK; + if (incrx_mode) + cfg |= DWC3_GSBUSCFG0_INCRBRSTENA; + switch (incrx_size) { + case 256: + cfg |= DWC3_GSBUSCFG0_INCR256BRSTENA; + break; + case 128: + cfg |= DWC3_GSBUSCFG0_INCR128BRSTENA; + break; + case 64: + cfg |= DWC3_GSBUSCFG0_INCR64BRSTENA; + break; + case 32: + cfg |= DWC3_GSBUSCFG0_INCR32BRSTENA; + break; + case 16: + cfg |= DWC3_GSBUSCFG0_INCR16BRSTENA; + break; + case 8: + cfg |= DWC3_GSBUSCFG0_INCR8BRSTENA; + break; + case 4: + cfg |= DWC3_GSBUSCFG0_INCR4BRSTENA; + break; + case 1: + break; + default: + dev_err(dev, "Invalid property\n"); + break; + } + + dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg); +} + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -840,6 +932,8 @@ static int dwc3_core_init(struct dwc3 *dwc) /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc); + dwc3_set_incr_burst_type(dwc); + usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 213b939ad011..5f14fb7121b1 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1168,6 +1168,9 @@ struct dwc3 { u16 imod_interval; }; +#define INCRX_BURST_MODE 0 +#define INCRX_UNDEF_LENGTH_BURST_MODE 1 + #define work_to_dwc(w) (container_of((w), struct dwc3, drd_work)) /* -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 1a7b12f69a9434a766e77c43d113826f0413b032 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 26 Jul 2018 14:48:56 +0300 Subject: usb: dwc3: pci: Supply device properties via driver data For now all PCI enumerated dwc3 devices require some properties to be present. This allows us to unconditionally append them and supply via driver_data. No functional change intended. Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 131 +++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 57 deletions(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b29f031dfc23..740ed561f353 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -101,52 +101,37 @@ unmap: return 0; } +static const struct property_entry dwc3_pci_intel_properties[] = { + PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + {} +}; + +static const struct property_entry dwc3_pci_amd_properties[] = { + PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), + PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), + PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"), + PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"), + PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"), + PROPERTY_ENTRY_BOOL("snps,del_p1p2p3_quirk"), + PROPERTY_ENTRY_BOOL("snps,del_phy_power_chg_quirk"), + PROPERTY_ENTRY_BOOL("snps,lfps_filter_quirk"), + PROPERTY_ENTRY_BOOL("snps,rx_detect_poll_quirk"), + PROPERTY_ENTRY_BOOL("snps,tx_de_emphasis_quirk"), + PROPERTY_ENTRY_U8("snps,tx_de_emphasis", 1), + /* FIXME these quirks should be removed when AMD NL tapes out */ + PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), + PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), + PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + {} +}; + static int dwc3_pci_quirks(struct dwc3_pci *dwc) { - struct platform_device *dwc3 = dwc->dwc3; struct pci_dev *pdev = dwc->pci; - if (pdev->vendor == PCI_VENDOR_ID_AMD && - pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { - struct property_entry properties[] = { - PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), - PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), - PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"), - PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"), - PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"), - PROPERTY_ENTRY_BOOL("snps,del_p1p2p3_quirk"), - PROPERTY_ENTRY_BOOL("snps,del_phy_power_chg_quirk"), - PROPERTY_ENTRY_BOOL("snps,lfps_filter_quirk"), - PROPERTY_ENTRY_BOOL("snps,rx_detect_poll_quirk"), - PROPERTY_ENTRY_BOOL("snps,tx_de_emphasis_quirk"), - PROPERTY_ENTRY_U8("snps,tx_de_emphasis", 1), - /* - * FIXME these quirks should be removed when AMD NL - * tapes out - */ - PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), - PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), - PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), - PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), - { }, - }; - - return platform_device_add_properties(dwc3, properties); - } - if (pdev->vendor == PCI_VENDOR_ID_INTEL) { - int ret; - - struct property_entry properties[] = { - PROPERTY_ENTRY_STRING("dr_mode", "peripheral"), - PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), - { } - }; - - ret = platform_device_add_properties(dwc3, properties); - if (ret < 0) - return ret; - if (pdev->device == PCI_DEVICE_ID_INTEL_BXT || pdev->device == PCI_DEVICE_ID_INTEL_BXT_M) { guid_parse(PCI_INTEL_BXT_DSM_GUID, &dwc->guid); @@ -155,6 +140,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc) if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { struct gpio_desc *gpio; + int ret; /* On BYT the FW does not always enable the refclock */ ret = dwc3_byt_enable_ulpi_refclock(pdev); @@ -216,9 +202,9 @@ static void dwc3_pci_resume_work(struct work_struct *work) } #endif -static int dwc3_pci_probe(struct pci_dev *pci, - const struct pci_device_id *id) +static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { + struct property_entry *p = (struct property_entry *)id->driver_data; struct dwc3_pci *dwc; struct resource res[2]; int ret; @@ -261,6 +247,10 @@ static int dwc3_pci_probe(struct pci_dev *pci, dwc->dwc3->dev.parent = dev; ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev)); + ret = platform_device_add_properties(dwc->dwc3, p); + if (ret < 0) + return ret; + ret = dwc3_pci_quirks(dwc); if (ret) goto err; @@ -298,20 +288,47 @@ static void dwc3_pci_remove(struct pci_dev *pci) } static const struct pci_device_id dwc3_pci_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPLP), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPH), }, - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICLLP), }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BSW), + (kernel_ulong_t) &dwc3_pci_intel_properties }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BYT), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SPTLP), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SPTH), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BXT), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BXT_M), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_APL), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_KBP), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_GLK), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPLP), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPH), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICLLP), + (kernel_ulong_t) &dwc3_pci_intel_properties, }, + + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_NL_USB), + (kernel_ulong_t) &dwc3_pci_amd_properties, }, { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); -- cgit v1.2.3 From c31d983beaf04e6754918aa1073f053b12efb700 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 26 Jul 2018 14:48:57 +0300 Subject: usb: dwc3: pci: Intel Merrifield can be host On Intel Edison board the OTG function is enabled, thus, USB can switch to the host mode. Allow that by changing dr_mode property to "otg" for Intel Merrifield. Signed-off-by: Andy Shevchenko Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 740ed561f353..5edd79470368 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -107,6 +107,12 @@ static const struct property_entry dwc3_pci_intel_properties[] = { {} }; +static const struct property_entry dwc3_pci_mrfld_properties[] = { + PROPERTY_ENTRY_STRING("dr_mode", "otg"), + PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), + {} +}; + static const struct property_entry dwc3_pci_amd_properties[] = { PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), @@ -295,7 +301,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { (kernel_ulong_t) &dwc3_pci_intel_properties, }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD), - (kernel_ulong_t) &dwc3_pci_intel_properties, }, + (kernel_ulong_t) &dwc3_pci_mrfld_properties, }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SPTLP), (kernel_ulong_t) &dwc3_pci_intel_properties, }, -- cgit v1.2.3 From a77004681148f5773c20370812ca7d14443fb091 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Thu, 26 Jul 2018 13:52:11 -0700 Subject: usb: dwc3: Set default mode for dwc_usb31 dwc_usb31 does not support OTG mode. If the controller supports DRD but the dr_mode is not specified or set to OTG, then set the mode to peripheral. Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 21e4931d0cc0..64ba664d467c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -78,6 +78,14 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc) mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) mode = USB_DR_MODE_PERIPHERAL; + + /* + * dwc_usb31 does not support OTG mode. If the controller + * supports DRD but the dr_mode is not specified or set to OTG, + * then set the mode to peripheral. + */ + if (mode == USB_DR_MODE_OTG && dwc3_is_usb31(dwc)) + mode = USB_DR_MODE_PERIPHERAL; } if (mode != dwc->dr_mode) { -- cgit v1.2.3 From b138e23d3dff90c0494925b4c1874227b81bddf7 Mon Sep 17 00:00:00 2001 From: Anurag Kumar Vulisha Date: Fri, 27 Jul 2018 13:11:20 +0530 Subject: usb: dwc3: core: Enable AutoRetry feature in the controller By default when core sees any transaction error (CRC or overflow) it replies with terminating retry ACK (Retry=1 and Nump == 0). Enabling this Auto Retry feature in controller will make the core send a non-terminanting ACK upon such transaction errors. That is, ACK TP with Retry=1 and Nump != 0. Doing so will give controller a chance to recover from transient error conditions. Signed-off-by: Anurag Kumar Vulisha Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 16 ++++++++++++++++ drivers/usb/dwc3/core.h | 3 +++ 2 files changed, 19 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 64ba664d467c..88c80fcc39f5 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -985,6 +985,22 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); } + if (dwc->dr_mode == USB_DR_MODE_HOST || + dwc->dr_mode == USB_DR_MODE_OTG) { + reg = dwc3_readl(dwc->regs, DWC3_GUCTL); + + /* + * Enable Auto retry Feature to make the controller operating in + * Host mode on seeing transaction errors(CRC errors or internal + * overrun scenerios) on IN transfers to reply to the device + * with a non-terminating retry ACK (i.e, an ACK transcation + * packet with Retry=1 & Nump != 0) + */ + reg |= DWC3_GUCTL_HSTINAUTORETRY; + + dwc3_writel(dwc->regs, DWC3_GUCTL, reg); + } + /* * Must config both number of packets and max burst settings to enable * RX and/or TX threshold. diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5f14fb7121b1..5bfb62533e0f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -238,6 +238,9 @@ #define DWC3_GCTL_GBLHIBERNATIONEN BIT(1) #define DWC3_GCTL_DSBLCLKGTNG BIT(0) +/* Global User Control Register */ +#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) + /* Global User Control 1 Register */ #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW BIT(24) -- cgit v1.2.3 From 4ea438da76f4277627347147f6f7004affae07b9 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Fri, 27 Jul 2018 18:52:41 -0700 Subject: usb: dwc3: gadget: Check MaxPacketSize from descriptor endpoint->maxpacket is not updated after setting the usb_set_maxpacket_limit() on endpoint enable. The MaxPacketSize can be different than the endpoint->maxpacket_limit. DWC3 has been consistently using MaxPacketSize from the endpoint's descriptor, so let's keep it consistent and use the MaxPacketSize from the endpoint's descriptor instead. Signed-off-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 69bf137aab37..032ea7d709ba 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1121,7 +1121,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, req->request.short_not_ok, req->request.no_interrupt); } else if (req->request.zero && req->request.length && - (IS_ALIGNED(req->request.length,dep->endpoint.maxpacket))) { + (IS_ALIGNED(req->request.length, maxp))) { struct dwc3 *dwc = dep->dwc; struct dwc3_trb *trb; -- cgit v1.2.3