* [U-Boot] [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs
@ 2018-04-11 15:07 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:07 UTC (permalink / raw)
To: u-boot
This patchset adds support for USB for the Amlogic Meson GXL SoCs following
the work done for Linux by Martin Blumenstingl at [1] [2] [3].
The support consist of :
- A port of dwc3-of-simple from Linux to U-boot
- A change to support more than 2 PHYs in the DWC3 DM driver
- An USB2 PHY Driver and an USB3 PHY Driver
The DWC3 Controller has up to 4 PHYs connected :
- 2 USB2 PHYs and an USB3 PHY for GXL SoCs
- 3 USB2 PHYs and an USB3 PHY for the GXM SoC Variant
This is enabled by the "usb: host: dwc3: Add support for multiple PHYs" patch.
This patch is based on the "xhci-dwc3: Couple of fixes for USB3 support"
serie from Vignesh R, on the u-boot-usb tree.
The DWC3 Controller glue is generic enough to use the dwc3-of-simple from Linux
and can be easily ported to U-Boot as a Simple-Bus with Glue-Specific clocks
and Reset lines setup.
This depends on the recently applied :
- clk: Add get/enable/disable/release for a bulk of clocks at [4]
- reset: Add get/assert/deassert/release for bulk of reset signals at [5]
in order to manage the clocks and resets of the Glue in a clean fashion.
The USB PHY driver supports the standard generic PHY interface and supports
the power-on/off calls and set the Host mode by default.
They are based on the excellent work from Martin Blumenstingl merged in linux.
Changes since v2:
- Drop #if and use the empty stubs for clock & reset API
Changes since v1:
- switch to submitted clk/reset bulk API
- splitted dwc3 multiple phy init error between poweroff & exit
[1] https://lkml.kernel.org/r/20180303184700.21480-1-martin.blumenstingl at googlemail.com
[2] https://lkml.kernel.org/r/20180128202245.25021-1-martin.blumenstingl at googlemail.com
[3] https://lkml.kernel.org/r/20180303214309.25643-1-martin.blumenstingl at googlemail.com
[4] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/006952.html
[5] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/006949.html
Neil Armstrong (3):
usb: host: Add simple of glue driver for DWC3 USB Controllers
integration
usb: host: dwc3: Add support for multiple PHYs
phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
drivers/phy/Kconfig | 8 ++
drivers/phy/Makefile | 1 +
drivers/phy/meson-gxl-usb2.c | 238 ++++++++++++++++++++++++++++++++++++++
drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++
drivers/usb/host/Kconfig | 7 ++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/dwc3-of-simple.c | 109 +++++++++++++++++
drivers/usb/host/xhci-dwc3.c | 113 ++++++++++--------
8 files changed, 631 insertions(+), 47 deletions(-)
create mode 100644 drivers/phy/meson-gxl-usb2.c
create mode 100644 drivers/phy/meson-gxl-usb3.c
create mode 100644 drivers/usb/host/dwc3-of-simple.c
--
2.7.4
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs
@ 2018-04-11 15:07 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:07 UTC (permalink / raw)
To: linus-amlogic
This patchset adds support for USB for the Amlogic Meson GXL SoCs following
the work done for Linux by Martin Blumenstingl at [1] [2] [3].
The support consist of :
- A port of dwc3-of-simple from Linux to U-boot
- A change to support more than 2 PHYs in the DWC3 DM driver
- An USB2 PHY Driver and an USB3 PHY Driver
The DWC3 Controller has up to 4 PHYs connected :
- 2 USB2 PHYs and an USB3 PHY for GXL SoCs
- 3 USB2 PHYs and an USB3 PHY for the GXM SoC Variant
This is enabled by the "usb: host: dwc3: Add support for multiple PHYs" patch.
This patch is based on the "xhci-dwc3: Couple of fixes for USB3 support"
serie from Vignesh R, on the u-boot-usb tree.
The DWC3 Controller glue is generic enough to use the dwc3-of-simple from Linux
and can be easily ported to U-Boot as a Simple-Bus with Glue-Specific clocks
and Reset lines setup.
This depends on the recently applied :
- clk: Add get/enable/disable/release for a bulk of clocks at [4]
- reset: Add get/assert/deassert/release for bulk of reset signals at [5]
in order to manage the clocks and resets of the Glue in a clean fashion.
The USB PHY driver supports the standard generic PHY interface and supports
the power-on/off calls and set the Host mode by default.
They are based on the excellent work from Martin Blumenstingl merged in linux.
Changes since v2:
- Drop #if and use the empty stubs for clock & reset API
Changes since v1:
- switch to submitted clk/reset bulk API
- splitted dwc3 multiple phy init error between poweroff & exit
[1] https://lkml.kernel.org/r/20180303184700.21480-1-martin.blumenstingl at googlemail.com
[2] https://lkml.kernel.org/r/20180128202245.25021-1-martin.blumenstingl at googlemail.com
[3] https://lkml.kernel.org/r/20180303214309.25643-1-martin.blumenstingl at googlemail.com
[4] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/006952.html
[5] http://lists.infradead.org/pipermail/linux-amlogic/2018-April/006949.html
Neil Armstrong (3):
usb: host: Add simple of glue driver for DWC3 USB Controllers
integration
usb: host: dwc3: Add support for multiple PHYs
phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
drivers/phy/Kconfig | 8 ++
drivers/phy/Makefile | 1 +
drivers/phy/meson-gxl-usb2.c | 238 ++++++++++++++++++++++++++++++++++++++
drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++
drivers/usb/host/Kconfig | 7 ++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/dwc3-of-simple.c | 109 +++++++++++++++++
drivers/usb/host/xhci-dwc3.c | 113 ++++++++++--------
8 files changed, 631 insertions(+), 47 deletions(-)
create mode 100644 drivers/phy/meson-gxl-usb2.c
create mode 100644 drivers/phy/meson-gxl-usb3.c
create mode 100644 drivers/usb/host/dwc3-of-simple.c
--
2.7.4
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
2018-04-11 15:07 ` Neil Armstrong
@ 2018-04-11 15:08 ` Neil Armstrong
-1 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: u-boot
This is a port of the dwc3-of-simple driver from Linux to enable/deassert
clock and resets of a simple DWC3 Controller HW glue.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/usb/host/Kconfig | 7 +++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
3 files changed, 117 insertions(+)
create mode 100644 drivers/usb/host/dwc3-of-simple.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a7249b7..6caa615 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -21,6 +21,13 @@ config USB_XHCI_DWC3
Say Y or if your system has a Dual Role SuperSpeed
USB controller based on the DesignWare USB3 IP Core.
+config USB_XHCI_DWC3_OF_SIMPLE
+ bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
+ select MISC
+ help
+ Support USB2/3 functionality in simple SoC integrations with
+ USB controller based on the DesignWare USB3 IP Core.
+
config USB_XHCI_MVEBU
bool "MVEBU USB 3.0 support"
default y
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9819489..abe4f90 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
# xhci
obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
+obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
new file mode 100644
index 0000000..54a5f60
--- /dev/null
+++ b/drivers/usb/host/dwc3-of-simple.c
@@ -0,0 +1,109 @@
+/*
+ * dwc3-of-simple.c - OF glue layer for simple integrations
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Felipe Balbi <balbi@ti.com>
+ *
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <reset.h>
+#include <clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct dwc3_of_simple {
+ struct clk_bulk clks;
+ struct reset_ctl_bulk resets;
+};
+
+static int dwc3_of_simple_reset_init(struct udevice *dev,
+ struct dwc3_of_simple *simple)
+{
+ int ret;
+
+ ret = reset_get_bulk(dev, &simple->resets);
+ if (ret == -ENOTSUPP)
+ return 0;
+ else if (ret)
+ return ret;
+
+ ret = reset_deassert_bulk(&simple->resets);
+ if (ret) {
+ reset_release_bulk(&simple->resets);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dwc3_of_simple_clk_init(struct udevice *dev,
+ struct dwc3_of_simple *simple)
+{
+ int ret;
+
+ ret = clk_get_bulk(dev, &simple->clks);
+ if (ret == -ENOTSUPP)
+ return 0;
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_enable_bulk(&simple->clks);
+ if (ret) {
+ clk_release_bulk(&simple->clks);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static int dwc3_of_simple_probe(struct udevice *dev)
+{
+ struct dwc3_of_simple *simple = dev_get_platdata(dev);
+ int ret;
+
+ ret = dwc3_of_simple_clk_init(dev, simple);
+ if (ret)
+ return ret;
+
+ ret = dwc3_of_simple_reset_init(dev, simple);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int dwc3_of_simple_remove(struct udevice *dev)
+{
+ struct dwc3_of_simple *simple = dev_get_platdata(dev);
+
+ reset_release_bulk(&simple->resets);
+
+ clk_release_bulk(&simple->clks);
+
+ return dm_scan_fdt_dev(dev);
+}
+
+static const struct udevice_id dwc3_of_simple_ids[] = {
+ { .compatible = "amlogic,meson-gxl-dwc3" },
+ { }
+};
+
+U_BOOT_DRIVER(dwc3_of_simple) = {
+ .name = "dwc3-of-simple",
+ .id = UCLASS_SIMPLE_BUS,
+ .of_match = dwc3_of_simple_ids,
+ .probe = dwc3_of_simple_probe,
+ .remove = dwc3_of_simple_remove,
+ .platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
@ 2018-04-11 15:08 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: linus-amlogic
This is a port of the dwc3-of-simple driver from Linux to enable/deassert
clock and resets of a simple DWC3 Controller HW glue.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/usb/host/Kconfig | 7 +++
drivers/usb/host/Makefile | 1 +
drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
3 files changed, 117 insertions(+)
create mode 100644 drivers/usb/host/dwc3-of-simple.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index a7249b7..6caa615 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -21,6 +21,13 @@ config USB_XHCI_DWC3
Say Y or if your system has a Dual Role SuperSpeed
USB controller based on the DesignWare USB3 IP Core.
+config USB_XHCI_DWC3_OF_SIMPLE
+ bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
+ select MISC
+ help
+ Support USB2/3 functionality in simple SoC integrations with
+ USB controller based on the DesignWare USB3 IP Core.
+
config USB_XHCI_MVEBU
bool "MVEBU USB 3.0 support"
default y
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 9819489..abe4f90 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
# xhci
obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
+obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
new file mode 100644
index 0000000..54a5f60
--- /dev/null
+++ b/drivers/usb/host/dwc3-of-simple.c
@@ -0,0 +1,109 @@
+/*
+ * dwc3-of-simple.c - OF glue layer for simple integrations
+ *
+ * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Felipe Balbi <balbi@ti.com>
+ *
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <reset.h>
+#include <clk.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct dwc3_of_simple {
+ struct clk_bulk clks;
+ struct reset_ctl_bulk resets;
+};
+
+static int dwc3_of_simple_reset_init(struct udevice *dev,
+ struct dwc3_of_simple *simple)
+{
+ int ret;
+
+ ret = reset_get_bulk(dev, &simple->resets);
+ if (ret == -ENOTSUPP)
+ return 0;
+ else if (ret)
+ return ret;
+
+ ret = reset_deassert_bulk(&simple->resets);
+ if (ret) {
+ reset_release_bulk(&simple->resets);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dwc3_of_simple_clk_init(struct udevice *dev,
+ struct dwc3_of_simple *simple)
+{
+ int ret;
+
+ ret = clk_get_bulk(dev, &simple->clks);
+ if (ret == -ENOTSUPP)
+ return 0;
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_enable_bulk(&simple->clks);
+ if (ret) {
+ clk_release_bulk(&simple->clks);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static int dwc3_of_simple_probe(struct udevice *dev)
+{
+ struct dwc3_of_simple *simple = dev_get_platdata(dev);
+ int ret;
+
+ ret = dwc3_of_simple_clk_init(dev, simple);
+ if (ret)
+ return ret;
+
+ ret = dwc3_of_simple_reset_init(dev, simple);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int dwc3_of_simple_remove(struct udevice *dev)
+{
+ struct dwc3_of_simple *simple = dev_get_platdata(dev);
+
+ reset_release_bulk(&simple->resets);
+
+ clk_release_bulk(&simple->clks);
+
+ return dm_scan_fdt_dev(dev);
+}
+
+static const struct udevice_id dwc3_of_simple_ids[] = {
+ { .compatible = "amlogic,meson-gxl-dwc3" },
+ { }
+};
+
+U_BOOT_DRIVER(dwc3_of_simple) = {
+ .name = "dwc3-of-simple",
+ .id = UCLASS_SIMPLE_BUS,
+ .of_match = dwc3_of_simple_ids,
+ .probe = dwc3_of_simple_probe,
+ .remove = dwc3_of_simple_remove,
+ .platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs
2018-04-11 15:07 ` Neil Armstrong
@ 2018-04-11 15:08 ` Neil Armstrong
-1 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: u-boot
DWC3 Ips can have more than 1 PHY for USB2 and 1 PHY for USB3, add support
for a generic number of PHYs and adapt the code to handle a generic
number of PHYs.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/usb/host/xhci-dwc3.c | 113 +++++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 47 deletions(-)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 1022dd5..c100735 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -22,8 +22,8 @@
DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
- struct phy usb_phy;
- struct phy usb3_phy;
+ struct phy *usb_phys;
+ int num_phys;
};
void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
@@ -113,45 +113,82 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
}
#ifdef CONFIG_DM_USB
-static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
+static int xhci_dwc3_setup_phy(struct udevice *dev, int count)
{
- int ret = 0;
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+ int i, ret;
+
+ if (!count)
+ return 0;
- ret = generic_phy_get_by_index(dev, index, phy);
- if (ret) {
- if (ret != -ENOENT) {
- pr_err("Failed to get USB PHY for %s\n", dev->name);
+ plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
+ GFP_KERNEL);
+ if (!plat->usb_phys)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
+ if (ret && ret != -ENOENT) {
+ pr_err("Failed to get USB PHY%d for %s\n",
+ i, dev->name);
return ret;
}
- } else {
- ret = generic_phy_init(phy);
+
+ ++plat->num_phys;
+ }
+
+ for (i = 0; i < plat->num_phys; i++) {
+ ret = generic_phy_init(&plat->usb_phys[i]);
if (ret) {
- pr_err("Can't init USB PHY for %s\n", dev->name);
- return ret;
+ pr_err("Can't init USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_init_err;
}
- ret = generic_phy_power_on(phy);
+ }
+
+ for (i = 0; i < plat->num_phys; i++) {
+ ret = generic_phy_power_on(&plat->usb_phys[i]);
if (ret) {
- pr_err("Can't power on USB PHY for %s\n", dev->name);
- generic_phy_exit(phy);
- return ret;
+ pr_err("Can't power USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_poweron_err;
}
}
return 0;
+
+
+phys_poweron_err:
+ for (; i >= 0; i--)
+ generic_phy_power_off(&plat->usb_phys[i]);
+
+ for (i = 0; i < plat->num_phys; i++)
+ generic_phy_exit(&plat->usb_phys[i]);
+
+ return ret;
+
+phys_init_err:
+ for (; i >= 0; i--)
+ generic_phy_exit(&plat->usb_phys[i]);
+
+ return ret;
}
-static int xhci_dwc3_shutdown_phy(struct phy *phy)
+static int xhci_dwc3_shutdown_phy(struct udevice *dev)
{
- int ret = 0;
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+ int i, ret;
- if (generic_phy_valid(phy)) {
- ret = generic_phy_power_off(phy);
- if (ret)
- return ret;
+ for (i = 0; i < plat->num_phys; i++) {
+ if (!generic_phy_valid(&plat->usb_phys[i]))
+ continue;
- ret = generic_phy_exit(phy);
- if (ret)
- return ret;
+ ret = generic_phy_power_off(&plat->usb_phys[i]);
+ ret |= generic_phy_exit(&plat->usb_phys[i]);
+ if (ret) {
+ pr_err("Can't shutdown USB PHY%d for %s\n",
+ i, dev->name);
+ }
}
return 0;
@@ -159,7 +196,6 @@ static int xhci_dwc3_shutdown_phy(struct phy *phy)
static int xhci_dwc3_probe(struct udevice *dev)
{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
struct xhci_hcor *hcor;
struct xhci_hccr *hccr;
struct dwc3 *dwc3_reg;
@@ -170,18 +206,10 @@ static int xhci_dwc3_probe(struct udevice *dev)
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_phy);
- if (ret) {
- pr_err("Failed to setup USB PHY for %s\n", dev->name);
+ ret = xhci_dwc3_setup_phy(dev, dev_count_phandle_with_args(
+ dev, "phys", "#phy-cells"));
+ if (ret)
return ret;
- }
-
- ret = xhci_dwc3_setup_phy(dev, 1, &plat->usb3_phy);
- if (ret) {
- pr_err("Failed to setup USB3 PHY for %s\n", dev->name);
- xhci_dwc3_shutdown_phy(&plat->usb_phy);
- return ret;
- }
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
@@ -199,16 +227,7 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev)
{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int ret;
-
- ret = xhci_dwc3_shutdown_phy(&plat->usb_phy);
- if (ret)
- pr_err("Can't shutdown USB PHY for %s\n", dev->name);
-
- ret = xhci_dwc3_shutdown_phy(&plat->usb3_phy);
- if (ret)
- pr_err("Can't shutdown USB3 PHY for %s\n", dev->name);
+ xhci_dwc3_shutdown_phy(dev);
return xhci_deregister(dev);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs
@ 2018-04-11 15:08 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: linus-amlogic
DWC3 Ips can have more than 1 PHY for USB2 and 1 PHY for USB3, add support
for a generic number of PHYs and adapt the code to handle a generic
number of PHYs.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/usb/host/xhci-dwc3.c | 113 +++++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 47 deletions(-)
diff --git a/drivers/usb/host/xhci-dwc3.c b/drivers/usb/host/xhci-dwc3.c
index 1022dd5..c100735 100644
--- a/drivers/usb/host/xhci-dwc3.c
+++ b/drivers/usb/host/xhci-dwc3.c
@@ -22,8 +22,8 @@
DECLARE_GLOBAL_DATA_PTR;
struct xhci_dwc3_platdata {
- struct phy usb_phy;
- struct phy usb3_phy;
+ struct phy *usb_phys;
+ int num_phys;
};
void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
@@ -113,45 +113,82 @@ void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
}
#ifdef CONFIG_DM_USB
-static int xhci_dwc3_setup_phy(struct udevice *dev, int index, struct phy *phy)
+static int xhci_dwc3_setup_phy(struct udevice *dev, int count)
{
- int ret = 0;
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+ int i, ret;
+
+ if (!count)
+ return 0;
- ret = generic_phy_get_by_index(dev, index, phy);
- if (ret) {
- if (ret != -ENOENT) {
- pr_err("Failed to get USB PHY for %s\n", dev->name);
+ plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
+ GFP_KERNEL);
+ if (!plat->usb_phys)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
+ if (ret && ret != -ENOENT) {
+ pr_err("Failed to get USB PHY%d for %s\n",
+ i, dev->name);
return ret;
}
- } else {
- ret = generic_phy_init(phy);
+
+ ++plat->num_phys;
+ }
+
+ for (i = 0; i < plat->num_phys; i++) {
+ ret = generic_phy_init(&plat->usb_phys[i]);
if (ret) {
- pr_err("Can't init USB PHY for %s\n", dev->name);
- return ret;
+ pr_err("Can't init USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_init_err;
}
- ret = generic_phy_power_on(phy);
+ }
+
+ for (i = 0; i < plat->num_phys; i++) {
+ ret = generic_phy_power_on(&plat->usb_phys[i]);
if (ret) {
- pr_err("Can't power on USB PHY for %s\n", dev->name);
- generic_phy_exit(phy);
- return ret;
+ pr_err("Can't power USB PHY%d for %s\n",
+ i, dev->name);
+ goto phys_poweron_err;
}
}
return 0;
+
+
+phys_poweron_err:
+ for (; i >= 0; i--)
+ generic_phy_power_off(&plat->usb_phys[i]);
+
+ for (i = 0; i < plat->num_phys; i++)
+ generic_phy_exit(&plat->usb_phys[i]);
+
+ return ret;
+
+phys_init_err:
+ for (; i >= 0; i--)
+ generic_phy_exit(&plat->usb_phys[i]);
+
+ return ret;
}
-static int xhci_dwc3_shutdown_phy(struct phy *phy)
+static int xhci_dwc3_shutdown_phy(struct udevice *dev)
{
- int ret = 0;
+ struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
+ int i, ret;
- if (generic_phy_valid(phy)) {
- ret = generic_phy_power_off(phy);
- if (ret)
- return ret;
+ for (i = 0; i < plat->num_phys; i++) {
+ if (!generic_phy_valid(&plat->usb_phys[i]))
+ continue;
- ret = generic_phy_exit(phy);
- if (ret)
- return ret;
+ ret = generic_phy_power_off(&plat->usb_phys[i]);
+ ret |= generic_phy_exit(&plat->usb_phys[i]);
+ if (ret) {
+ pr_err("Can't shutdown USB PHY%d for %s\n",
+ i, dev->name);
+ }
}
return 0;
@@ -159,7 +196,6 @@ static int xhci_dwc3_shutdown_phy(struct phy *phy)
static int xhci_dwc3_probe(struct udevice *dev)
{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
struct xhci_hcor *hcor;
struct xhci_hccr *hccr;
struct dwc3 *dwc3_reg;
@@ -170,18 +206,10 @@ static int xhci_dwc3_probe(struct udevice *dev)
hcor = (struct xhci_hcor *)((uintptr_t)hccr +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
- ret = xhci_dwc3_setup_phy(dev, 0, &plat->usb_phy);
- if (ret) {
- pr_err("Failed to setup USB PHY for %s\n", dev->name);
+ ret = xhci_dwc3_setup_phy(dev, dev_count_phandle_with_args(
+ dev, "phys", "#phy-cells"));
+ if (ret)
return ret;
- }
-
- ret = xhci_dwc3_setup_phy(dev, 1, &plat->usb3_phy);
- if (ret) {
- pr_err("Failed to setup USB3 PHY for %s\n", dev->name);
- xhci_dwc3_shutdown_phy(&plat->usb_phy);
- return ret;
- }
dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
@@ -199,16 +227,7 @@ static int xhci_dwc3_probe(struct udevice *dev)
static int xhci_dwc3_remove(struct udevice *dev)
{
- struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
- int ret;
-
- ret = xhci_dwc3_shutdown_phy(&plat->usb_phy);
- if (ret)
- pr_err("Can't shutdown USB PHY for %s\n", dev->name);
-
- ret = xhci_dwc3_shutdown_phy(&plat->usb3_phy);
- if (ret)
- pr_err("Can't shutdown USB3 PHY for %s\n", dev->name);
+ xhci_dwc3_shutdown_phy(dev);
return xhci_deregister(dev);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
2018-04-11 15:07 ` Neil Armstrong
@ 2018-04-11 15:08 ` Neil Armstrong
-1 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: u-boot
The Amlogic Meson GXL and GXM (simple variant) embeds up to 3 USB2 PHYs
and an USB3 PHY. This patch adds drivers for these for the standard generic
PHY interface and supports the power-on/off calls and set the Host mode by
default.
They are based on the excellent work from Martin Blumenstingl merged in linux.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/phy/Kconfig | 8 ++
drivers/phy/Makefile | 1 +
drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
4 files changed, 448 insertions(+)
create mode 100644 drivers/phy/meson-gxl-usb2.c
create mode 100644 drivers/phy/meson-gxl-usb3.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 3b9a09c..99a6d95 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -85,4 +85,12 @@ config STI_USB_PHY
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
+config MESON_GXL_USB_PHY
+ bool "Amlogic Meson GXL USB PHYs"
+ depends on PHY && ARCH_MESON && MESON_GXL
+ imply REGMAP
+ help
+ This is the generic phy driver for the Amlogic Meson GXL
+ USB2 and USB3 PHYS.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 668040b..6c1610e 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
+obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
new file mode 100644
index 0000000..15c9c89
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -0,0 +1,238 @@
+/*
+ * Meson GXL and GXM USB2 PHY driver
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <power/regulator.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* bits [31:27] are read-only */
+#define U2P_R0 0x0
+ #define U2P_R0_BYPASS_SEL BIT(0)
+ #define U2P_R0_BYPASS_DM_EN BIT(1)
+ #define U2P_R0_BYPASS_DP_EN BIT(2)
+ #define U2P_R0_TXBITSTUFF_ENH BIT(3)
+ #define U2P_R0_TXBITSTUFF_EN BIT(4)
+ #define U2P_R0_DM_PULLDOWN BIT(5)
+ #define U2P_R0_DP_PULLDOWN BIT(6)
+ #define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
+ #define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
+ #define U2P_R0_ADP_PRB_EN BIT(9)
+ #define U2P_R0_ADP_DISCHARGE BIT(10)
+ #define U2P_R0_ADP_CHARGE BIT(11)
+ #define U2P_R0_DRV_VBUS BIT(12)
+ #define U2P_R0_ID_PULLUP BIT(13)
+ #define U2P_R0_LOOPBACK_EN_B BIT(14)
+ #define U2P_R0_OTG_DISABLE BIT(15)
+ #define U2P_R0_COMMON_ONN BIT(16)
+ #define U2P_R0_FSEL_MASK GENMASK(19, 17)
+ #define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
+ #define U2P_R0_POWER_ON_RESET BIT(22)
+ #define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
+ #define U2P_R0_ID_SET_ID_DQ BIT(25)
+ #define U2P_R0_ATE_RESET BIT(26)
+ #define U2P_R0_FSV_MINUS BIT(27)
+ #define U2P_R0_FSV_PLUS BIT(28)
+ #define U2P_R0_BYPASS_DM_DATA BIT(29)
+ #define U2P_R0_BYPASS_DP_DATA BIT(30)
+
+#define U2P_R1 0x4
+ #define U2P_R1_BURN_IN_TEST BIT(0)
+ #define U2P_R1_ACA_ENABLE BIT(1)
+ #define U2P_R1_DCD_ENABLE BIT(2)
+ #define U2P_R1_VDAT_SRC_EN_B BIT(3)
+ #define U2P_R1_VDAT_DET_EN_B BIT(4)
+ #define U2P_R1_CHARGES_SEL BIT(5)
+ #define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
+ #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
+ #define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
+ #define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
+ #define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
+ #define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
+ #define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
+ #define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
+ #define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
+ #define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
+
+/* bits [31:14] are read-only */
+#define U2P_R2 0x8
+ #define U2P_R2_TESTDATA_IN_MASK GENMASK(7, 0)
+ #define U2P_R2_TESTADDR_MASK GENMASK(11, 8)
+ #define U2P_R2_TESTDATA_OUT_SEL BIT(12)
+ #define U2P_R2_TESTCLK BIT(13)
+ #define U2P_R2_TESTDATA_OUT_MASK GENMASK(17, 14)
+ #define U2P_R2_ACA_PIN_RANGE_C BIT(18)
+ #define U2P_R2_ACA_PIN_RANGE_B BIT(19)
+ #define U2P_R2_ACA_PIN_RANGE_A BIT(20)
+ #define U2P_R2_ACA_PIN_GND BIT(21)
+ #define U2P_R2_ACA_PIN_FLOAT BIT(22)
+ #define U2P_R2_CHARGE_DETECT BIT(23)
+ #define U2P_R2_DEVICE_SESSION_VALID BIT(24)
+ #define U2P_R2_ADP_PROBE BIT(25)
+ #define U2P_R2_ADP_SENSE BIT(26)
+ #define U2P_R2_SESSION_END BIT(27)
+ #define U2P_R2_VBUS_VALID BIT(28)
+ #define U2P_R2_B_VALID BIT(29)
+ #define U2P_R2_A_VALID BIT(30)
+ #define U2P_R2_ID_DIG BIT(31)
+
+#define U2P_R3 0xc
+
+#define RESET_COMPLETE_TIME 500
+
+struct phy_meson_gxl_usb2_priv {
+ struct regmap *regmap;
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ struct udevice *phy_supply;
+#endif
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+#endif
+};
+
+static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+
+ /* reset the PHY and wait until settings are stabilized */
+ val |= U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+ udelay(RESET_COMPLETE_TIME);
+
+ val &= ~U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+ udelay(RESET_COMPLETE_TIME);
+}
+
+static void
+phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ val |= U2P_R0_DM_PULLDOWN;
+ val |= U2P_R0_DP_PULLDOWN;
+ val &= ~U2P_R0_ID_PULLUP;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+ phy_meson_gxl_usb2_reset(priv);
+}
+
+static int phy_meson_gxl_usb2_power_on(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ /* power on the PHY by taking it out of reset mode */
+ val &= ~U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+ phy_meson_gxl_usb2_set_host_mode(priv);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ if (priv->phy_supply) {
+ int ret = regulator_set_enable(priv->phy_supply, true);
+ if (ret)
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb2_power_off(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ /* power off the PHY by putting it into reset mode */
+ val |= U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ if (priv->phy_supply) {
+ int ret = regulator_set_enable(priv->phy_supply, false);
+ if (ret) {
+ pr_err("Error disabling PHY supply\n");
+ return ret;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+struct phy_ops meson_gxl_usb2_phy_ops = {
+ .power_on = phy_meson_gxl_usb2_power_on,
+ .power_off = phy_meson_gxl_usb2_power_off,
+};
+
+int meson_gxl_usb2_phy_probe(struct udevice *dev)
+{
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = regmap_init_mem(dev, &priv->regmap);
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+ pr_err("failed to enable PHY clock\n");
+ clk_free(&priv->clk);
+ return ret;
+ }
+#endif
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply);
+ if (ret && ret != -ENOENT) {
+ pr_err("Failed to get PHY regulator\n");
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id meson_gxl_usb2_phy_ids[] = {
+ { .compatible = "amlogic,meson-gxl-usb2-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb2_phy) = {
+ .name = "meson_gxl_usb2_phy",
+ .id = UCLASS_PHY,
+ .of_match = meson_gxl_usb2_phy_ids,
+ .probe = meson_gxl_usb2_phy_probe,
+ .ops = &meson_gxl_usb2_phy_ops,
+ .priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb2_priv),
+};
diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
new file mode 100644
index 0000000..a385fbd
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb3.c
@@ -0,0 +1,201 @@
+/*
+ * Meson GXL USB3 PHY driver
+ *
+ * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+#include <linux/bitfield.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define USB_R0 0x00
+ #define USB_R0_P30_FSEL_MASK GENMASK(5, 0)
+ #define USB_R0_P30_PHY_RESET BIT(6)
+ #define USB_R0_P30_TEST_POWERDOWN_HSP BIT(7)
+ #define USB_R0_P30_TEST_POWERDOWN_SSP BIT(8)
+ #define USB_R0_P30_ACJT_LEVEL_MASK GENMASK(13, 9)
+ #define USB_R0_P30_TX_BOOST_LEVEL_MASK GENMASK(16, 14)
+ #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17)
+ #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18)
+ #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19)
+ #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29)
+ #define USB_R0_U2D_ACT BIT(31)
+
+#define USB_R1 0x04
+ #define USB_R1_U3H_BIGENDIAN_GS BIT(0)
+ #define USB_R1_U3H_PME_ENABLE BIT(1)
+ #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(6, 2)
+ #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(11, 7)
+ #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(15, 12)
+ #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16)
+ #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17)
+ #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18)
+ #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19)
+ #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25)
+
+#define USB_R2 0x08
+ #define USB_R2_P30_CR_DATA_IN_MASK GENMASK(15, 0)
+ #define USB_R2_P30_CR_READ BIT(16)
+ #define USB_R2_P30_CR_WRITE BIT(17)
+ #define USB_R2_P30_CR_CAP_ADDR BIT(18)
+ #define USB_R2_P30_CR_CAP_DATA BIT(19)
+ #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20)
+ #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26)
+
+#define USB_R3 0x0c
+ #define USB_R3_P30_SSC_ENABLE BIT(0)
+ #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1)
+ #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
+ #define USB_R3_P30_REF_SSP_EN BIT(13)
+ #define USB_R3_P30_LOS_BIAS_MASK GENMASK(18, 16)
+ #define USB_R3_P30_LOS_LEVEL_MASK GENMASK(23, 19)
+ #define USB_R3_P30_MPLL_MULTIPLIER_MASK GENMASK(30, 24)
+
+#define USB_R4 0x10
+ #define USB_R4_P21_PORT_RESET_0 BIT(0)
+ #define USB_R4_P21_SLEEP_M0 BIT(1)
+ #define USB_R4_MEM_PD_MASK GENMASK(3, 2)
+ #define USB_R4_P21_ONLY BIT(4)
+
+#define USB_R5 0x14
+ #define USB_R5_ID_DIG_SYNC BIT(0)
+ #define USB_R5_ID_DIG_REG BIT(1)
+ #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2)
+ #define USB_R5_ID_DIG_EN_0 BIT(4)
+ #define USB_R5_ID_DIG_EN_1 BIT(5)
+ #define USB_R5_ID_DIG_CURR BIT(6)
+ #define USB_R5_ID_DIG_IRQ BIT(7)
+ #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8)
+ #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16)
+
+/* read-only register */
+#define USB_R6 0x18
+ #define USB_R6_P30_CR_DATA_OUT_MASK GENMASK(15, 0)
+ #define USB_R6_P30_CR_ACK BIT(16)
+
+struct phy_meson_gxl_usb3_priv {
+ struct regmap *regmap;
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+#endif
+};
+
+static int
+phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, USB_R0, &val);
+ val &= ~USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val &= ~USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb3_power_on(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R5, &val);
+ val |= USB_R5_ID_DIG_EN_0;
+ val |= USB_R5_ID_DIG_EN_1;
+ val &= ~USB_R5_ID_DIG_TH_MASK;
+ val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
+ regmap_write(priv->regmap, USB_R5, val);
+
+ return phy_meson_gxl_usb3_set_host_mode(priv);
+}
+
+static int phy_meson_gxl_usb3_power_off(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R5, &val);
+ val &= ~USB_R5_ID_DIG_EN_0;
+ val &= ~USB_R5_ID_DIG_EN_1;
+ regmap_write(priv->regmap, USB_R5, val);
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb3_init(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R1, &val);
+ val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
+ val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
+ regmap_write(priv->regmap, USB_R1, val);
+
+ return 0;
+}
+
+struct phy_ops meson_gxl_usb3_phy_ops = {
+ .init = phy_meson_gxl_usb3_init,
+ .power_on = phy_meson_gxl_usb3_power_on,
+ .power_off = phy_meson_gxl_usb3_power_off,
+};
+
+int meson_gxl_usb3_phy_probe(struct udevice *dev)
+{
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = regmap_init_mem(dev, &priv->regmap);
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+ pr_err("failed to enable PHY clock\n");
+ clk_free(&priv->clk);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id meson_gxl_usb3_phy_ids[] = {
+ { .compatible = "amlogic,meson-gxl-usb3-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb3_phy) = {
+ .name = "meson_gxl_usb3_phy",
+ .id = UCLASS_PHY,
+ .of_match = meson_gxl_usb3_phy_ids,
+ .probe = meson_gxl_usb3_phy_probe,
+ .ops = &meson_gxl_usb3_phy_ops,
+ .priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb3_priv),
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers
@ 2018-04-11 15:08 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-11 15:08 UTC (permalink / raw)
To: linus-amlogic
The Amlogic Meson GXL and GXM (simple variant) embeds up to 3 USB2 PHYs
and an USB3 PHY. This patch adds drivers for these for the standard generic
PHY interface and supports the power-on/off calls and set the Host mode by
default.
They are based on the excellent work from Martin Blumenstingl merged in linux.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/phy/Kconfig | 8 ++
drivers/phy/Makefile | 1 +
drivers/phy/meson-gxl-usb2.c | 238 +++++++++++++++++++++++++++++++++++++++++++
drivers/phy/meson-gxl-usb3.c | 201 ++++++++++++++++++++++++++++++++++++
4 files changed, 448 insertions(+)
create mode 100644 drivers/phy/meson-gxl-usb2.c
create mode 100644 drivers/phy/meson-gxl-usb3.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 3b9a09c..99a6d95 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -85,4 +85,12 @@ config STI_USB_PHY
used by USB2 and USB3 Host controllers available on
STiH407 SoC families.
+config MESON_GXL_USB_PHY
+ bool "Amlogic Meson GXL USB PHYs"
+ depends on PHY && ARCH_MESON && MESON_GXL
+ imply REGMAP
+ help
+ This is the generic phy driver for the Amlogic Meson GXL
+ USB2 and USB3 PHYS.
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 668040b..6c1610e 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_$(SPL_)NOP_PHY) += nop-phy.o
obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o
obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o
+obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o meson-gxl-usb3.o
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
new file mode 100644
index 0000000..15c9c89
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -0,0 +1,238 @@
+/*
+ * Meson GXL and GXM USB2 PHY driver
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <power/regulator.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* bits [31:27] are read-only */
+#define U2P_R0 0x0
+ #define U2P_R0_BYPASS_SEL BIT(0)
+ #define U2P_R0_BYPASS_DM_EN BIT(1)
+ #define U2P_R0_BYPASS_DP_EN BIT(2)
+ #define U2P_R0_TXBITSTUFF_ENH BIT(3)
+ #define U2P_R0_TXBITSTUFF_EN BIT(4)
+ #define U2P_R0_DM_PULLDOWN BIT(5)
+ #define U2P_R0_DP_PULLDOWN BIT(6)
+ #define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
+ #define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
+ #define U2P_R0_ADP_PRB_EN BIT(9)
+ #define U2P_R0_ADP_DISCHARGE BIT(10)
+ #define U2P_R0_ADP_CHARGE BIT(11)
+ #define U2P_R0_DRV_VBUS BIT(12)
+ #define U2P_R0_ID_PULLUP BIT(13)
+ #define U2P_R0_LOOPBACK_EN_B BIT(14)
+ #define U2P_R0_OTG_DISABLE BIT(15)
+ #define U2P_R0_COMMON_ONN BIT(16)
+ #define U2P_R0_FSEL_MASK GENMASK(19, 17)
+ #define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
+ #define U2P_R0_POWER_ON_RESET BIT(22)
+ #define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
+ #define U2P_R0_ID_SET_ID_DQ BIT(25)
+ #define U2P_R0_ATE_RESET BIT(26)
+ #define U2P_R0_FSV_MINUS BIT(27)
+ #define U2P_R0_FSV_PLUS BIT(28)
+ #define U2P_R0_BYPASS_DM_DATA BIT(29)
+ #define U2P_R0_BYPASS_DP_DATA BIT(30)
+
+#define U2P_R1 0x4
+ #define U2P_R1_BURN_IN_TEST BIT(0)
+ #define U2P_R1_ACA_ENABLE BIT(1)
+ #define U2P_R1_DCD_ENABLE BIT(2)
+ #define U2P_R1_VDAT_SRC_EN_B BIT(3)
+ #define U2P_R1_VDAT_DET_EN_B BIT(4)
+ #define U2P_R1_CHARGES_SEL BIT(5)
+ #define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
+ #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
+ #define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
+ #define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
+ #define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
+ #define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
+ #define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
+ #define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
+ #define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
+ #define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
+
+/* bits [31:14] are read-only */
+#define U2P_R2 0x8
+ #define U2P_R2_TESTDATA_IN_MASK GENMASK(7, 0)
+ #define U2P_R2_TESTADDR_MASK GENMASK(11, 8)
+ #define U2P_R2_TESTDATA_OUT_SEL BIT(12)
+ #define U2P_R2_TESTCLK BIT(13)
+ #define U2P_R2_TESTDATA_OUT_MASK GENMASK(17, 14)
+ #define U2P_R2_ACA_PIN_RANGE_C BIT(18)
+ #define U2P_R2_ACA_PIN_RANGE_B BIT(19)
+ #define U2P_R2_ACA_PIN_RANGE_A BIT(20)
+ #define U2P_R2_ACA_PIN_GND BIT(21)
+ #define U2P_R2_ACA_PIN_FLOAT BIT(22)
+ #define U2P_R2_CHARGE_DETECT BIT(23)
+ #define U2P_R2_DEVICE_SESSION_VALID BIT(24)
+ #define U2P_R2_ADP_PROBE BIT(25)
+ #define U2P_R2_ADP_SENSE BIT(26)
+ #define U2P_R2_SESSION_END BIT(27)
+ #define U2P_R2_VBUS_VALID BIT(28)
+ #define U2P_R2_B_VALID BIT(29)
+ #define U2P_R2_A_VALID BIT(30)
+ #define U2P_R2_ID_DIG BIT(31)
+
+#define U2P_R3 0xc
+
+#define RESET_COMPLETE_TIME 500
+
+struct phy_meson_gxl_usb2_priv {
+ struct regmap *regmap;
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ struct udevice *phy_supply;
+#endif
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+#endif
+};
+
+static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+
+ /* reset the PHY and wait until settings are stabilized */
+ val |= U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+ udelay(RESET_COMPLETE_TIME);
+
+ val &= ~U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+ udelay(RESET_COMPLETE_TIME);
+}
+
+static void
+phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ val |= U2P_R0_DM_PULLDOWN;
+ val |= U2P_R0_DP_PULLDOWN;
+ val &= ~U2P_R0_ID_PULLUP;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+ phy_meson_gxl_usb2_reset(priv);
+}
+
+static int phy_meson_gxl_usb2_power_on(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ /* power on the PHY by taking it out of reset mode */
+ val &= ~U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+ phy_meson_gxl_usb2_set_host_mode(priv);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ if (priv->phy_supply) {
+ int ret = regulator_set_enable(priv->phy_supply, true);
+ if (ret)
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb2_power_off(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, U2P_R0, &val);
+ /* power off the PHY by putting it into reset mode */
+ val |= U2P_R0_POWER_ON_RESET;
+ regmap_write(priv->regmap, U2P_R0, val);
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ if (priv->phy_supply) {
+ int ret = regulator_set_enable(priv->phy_supply, false);
+ if (ret) {
+ pr_err("Error disabling PHY supply\n");
+ return ret;
+ }
+ }
+#endif
+
+ return 0;
+}
+
+struct phy_ops meson_gxl_usb2_phy_ops = {
+ .power_on = phy_meson_gxl_usb2_power_on,
+ .power_off = phy_meson_gxl_usb2_power_off,
+};
+
+int meson_gxl_usb2_phy_probe(struct udevice *dev)
+{
+ struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = regmap_init_mem(dev, &priv->regmap);
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+ pr_err("failed to enable PHY clock\n");
+ clk_free(&priv->clk);
+ return ret;
+ }
+#endif
+
+#if CONFIG_IS_ENABLED(DM_REGULATOR)
+ ret = device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply);
+ if (ret && ret != -ENOENT) {
+ pr_err("Failed to get PHY regulator\n");
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id meson_gxl_usb2_phy_ids[] = {
+ { .compatible = "amlogic,meson-gxl-usb2-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb2_phy) = {
+ .name = "meson_gxl_usb2_phy",
+ .id = UCLASS_PHY,
+ .of_match = meson_gxl_usb2_phy_ids,
+ .probe = meson_gxl_usb2_phy_probe,
+ .ops = &meson_gxl_usb2_phy_ops,
+ .priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb2_priv),
+};
diff --git a/drivers/phy/meson-gxl-usb3.c b/drivers/phy/meson-gxl-usb3.c
new file mode 100644
index 0000000..a385fbd
--- /dev/null
+++ b/drivers/phy/meson-gxl-usb3.c
@@ -0,0 +1,201 @@
+/*
+ * Meson GXL USB3 PHY driver
+ *
+ * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstron@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <bitfield.h>
+#include <dm.h>
+#include <errno.h>
+#include <generic-phy.h>
+#include <regmap.h>
+#include <clk.h>
+
+#include <linux/bitops.h>
+#include <linux/compat.h>
+#include <linux/bitfield.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define USB_R0 0x00
+ #define USB_R0_P30_FSEL_MASK GENMASK(5, 0)
+ #define USB_R0_P30_PHY_RESET BIT(6)
+ #define USB_R0_P30_TEST_POWERDOWN_HSP BIT(7)
+ #define USB_R0_P30_TEST_POWERDOWN_SSP BIT(8)
+ #define USB_R0_P30_ACJT_LEVEL_MASK GENMASK(13, 9)
+ #define USB_R0_P30_TX_BOOST_LEVEL_MASK GENMASK(16, 14)
+ #define USB_R0_P30_LANE0_TX2RX_LOOPBACK BIT(17)
+ #define USB_R0_P30_LANE0_EXT_PCLK_REQ BIT(18)
+ #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK GENMASK(28, 19)
+ #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK GENMASK(30, 29)
+ #define USB_R0_U2D_ACT BIT(31)
+
+#define USB_R1 0x04
+ #define USB_R1_U3H_BIGENDIAN_GS BIT(0)
+ #define USB_R1_U3H_PME_ENABLE BIT(1)
+ #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK GENMASK(6, 2)
+ #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK GENMASK(11, 7)
+ #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK GENMASK(15, 12)
+ #define USB_R1_U3H_HOST_U3_PORT_DISABLE BIT(16)
+ #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT BIT(17)
+ #define USB_R1_U3H_HOST_MSI_ENABLE BIT(18)
+ #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK GENMASK(24, 19)
+ #define USB_R1_P30_PCS_TX_SWING_FULL_MASK GENMASK(31, 25)
+
+#define USB_R2 0x08
+ #define USB_R2_P30_CR_DATA_IN_MASK GENMASK(15, 0)
+ #define USB_R2_P30_CR_READ BIT(16)
+ #define USB_R2_P30_CR_WRITE BIT(17)
+ #define USB_R2_P30_CR_CAP_ADDR BIT(18)
+ #define USB_R2_P30_CR_CAP_DATA BIT(19)
+ #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK GENMASK(25, 20)
+ #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK GENMASK(31, 26)
+
+#define USB_R3 0x0c
+ #define USB_R3_P30_SSC_ENABLE BIT(0)
+ #define USB_R3_P30_SSC_RANGE_MASK GENMASK(3, 1)
+ #define USB_R3_P30_SSC_REF_CLK_SEL_MASK GENMASK(12, 4)
+ #define USB_R3_P30_REF_SSP_EN BIT(13)
+ #define USB_R3_P30_LOS_BIAS_MASK GENMASK(18, 16)
+ #define USB_R3_P30_LOS_LEVEL_MASK GENMASK(23, 19)
+ #define USB_R3_P30_MPLL_MULTIPLIER_MASK GENMASK(30, 24)
+
+#define USB_R4 0x10
+ #define USB_R4_P21_PORT_RESET_0 BIT(0)
+ #define USB_R4_P21_SLEEP_M0 BIT(1)
+ #define USB_R4_MEM_PD_MASK GENMASK(3, 2)
+ #define USB_R4_P21_ONLY BIT(4)
+
+#define USB_R5 0x14
+ #define USB_R5_ID_DIG_SYNC BIT(0)
+ #define USB_R5_ID_DIG_REG BIT(1)
+ #define USB_R5_ID_DIG_CFG_MASK GENMASK(3, 2)
+ #define USB_R5_ID_DIG_EN_0 BIT(4)
+ #define USB_R5_ID_DIG_EN_1 BIT(5)
+ #define USB_R5_ID_DIG_CURR BIT(6)
+ #define USB_R5_ID_DIG_IRQ BIT(7)
+ #define USB_R5_ID_DIG_TH_MASK GENMASK(15, 8)
+ #define USB_R5_ID_DIG_CNT_MASK GENMASK(23, 16)
+
+/* read-only register */
+#define USB_R6 0x18
+ #define USB_R6_P30_CR_DATA_OUT_MASK GENMASK(15, 0)
+ #define USB_R6_P30_CR_ACK BIT(16)
+
+struct phy_meson_gxl_usb3_priv {
+ struct regmap *regmap;
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+#endif
+};
+
+static int
+phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+{
+ uint val;
+
+ regmap_read(priv->regmap, USB_R0, &val);
+ val &= ~USB_R0_U2D_ACT;
+ regmap_write(priv->regmap, USB_R0, val);
+
+ regmap_read(priv->regmap, USB_R4, &val);
+ val &= ~USB_R4_P21_SLEEP_M0;
+ regmap_write(priv->regmap, USB_R4, val);
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb3_power_on(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R5, &val);
+ val |= USB_R5_ID_DIG_EN_0;
+ val |= USB_R5_ID_DIG_EN_1;
+ val &= ~USB_R5_ID_DIG_TH_MASK;
+ val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
+ regmap_write(priv->regmap, USB_R5, val);
+
+ return phy_meson_gxl_usb3_set_host_mode(priv);
+}
+
+static int phy_meson_gxl_usb3_power_off(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R5, &val);
+ val &= ~USB_R5_ID_DIG_EN_0;
+ val &= ~USB_R5_ID_DIG_EN_1;
+ regmap_write(priv->regmap, USB_R5, val);
+
+ return 0;
+}
+
+static int phy_meson_gxl_usb3_init(struct phy *phy)
+{
+ struct udevice *dev = phy->dev;
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ uint val;
+
+ regmap_read(priv->regmap, USB_R1, &val);
+ val &= ~USB_R1_U3H_FLADJ_30MHZ_REG_MASK;
+ val |= FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20);
+ regmap_write(priv->regmap, USB_R1, val);
+
+ return 0;
+}
+
+struct phy_ops meson_gxl_usb3_phy_ops = {
+ .init = phy_meson_gxl_usb3_init,
+ .power_on = phy_meson_gxl_usb3_power_on,
+ .power_off = phy_meson_gxl_usb3_power_off,
+};
+
+int meson_gxl_usb3_phy_probe(struct udevice *dev)
+{
+ struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = regmap_init_mem(dev, &priv->regmap);
+ if (ret)
+ return ret;
+
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_get_by_index(dev, 0, &priv->clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_enable(&priv->clk);
+ if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
+ pr_err("failed to enable PHY clock\n");
+ clk_free(&priv->clk);
+ return ret;
+ }
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id meson_gxl_usb3_phy_ids[] = {
+ { .compatible = "amlogic,meson-gxl-usb3-phy" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_gxl_usb3_phy) = {
+ .name = "meson_gxl_usb3_phy",
+ .id = UCLASS_PHY,
+ .of_match = meson_gxl_usb3_phy_ids,
+ .probe = meson_gxl_usb3_phy_probe,
+ .ops = &meson_gxl_usb3_phy_ops,
+ .priv_auto_alloc_size = sizeof(struct phy_meson_gxl_usb3_priv),
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs
2018-04-11 15:07 ` Neil Armstrong
@ 2018-04-11 15:20 ` Marek Vasut
-1 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2018-04-11 15:20 UTC (permalink / raw)
To: u-boot
On 04/11/2018 05:07 PM, Neil Armstrong wrote:
> This patchset adds support for USB for the Amlogic Meson GXL SoCs following
> the work done for Linux by Martin Blumenstingl at [1] [2] [3].
>
> The support consist of :
> - A port of dwc3-of-simple from Linux to U-boot
> - A change to support more than 2 PHYs in the DWC3 DM driver
> - An USB2 PHY Driver and an USB3 PHY Driver
>
> The DWC3 Controller has up to 4 PHYs connected :
> - 2 USB2 PHYs and an USB3 PHY for GXL SoCs
> - 3 USB2 PHYs and an USB3 PHY for the GXM SoC Variant
> This is enabled by the "usb: host: dwc3: Add support for multiple PHYs" patch.
> This patch is based on the "xhci-dwc3: Couple of fixes for USB3 support"
> serie from Vignesh R, on the u-boot-usb tree.
>
> The DWC3 Controller glue is generic enough to use the dwc3-of-simple from Linux
> and can be easily ported to U-Boot as a Simple-Bus with Glue-Specific clocks
> and Reset lines setup.
>
> This depends on the recently applied :
> - clk: Add get/enable/disable/release for a bulk of clocks at [4]
> - reset: Add get/assert/deassert/release for bulk of reset signals at [5]
> in order to manage the clocks and resets of the Glue in a clean fashion.
>
> The USB PHY driver supports the standard generic PHY interface and supports
> the power-on/off calls and set the Host mode by default.
> They are based on the excellent work from Martin Blumenstingl merged in linux.
>
> Changes since v2:
> - Drop #if and use the empty stubs for clock & reset API
>
> Changes since v1:
> - switch to submitted clk/reset bulk API
> - splitted dwc3 multiple phy init error between poweroff & exit
>
Applied all, thanks.
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs
@ 2018-04-11 15:20 ` Marek Vasut
0 siblings, 0 replies; 18+ messages in thread
From: Marek Vasut @ 2018-04-11 15:20 UTC (permalink / raw)
To: linus-amlogic
On 04/11/2018 05:07 PM, Neil Armstrong wrote:
> This patchset adds support for USB for the Amlogic Meson GXL SoCs following
> the work done for Linux by Martin Blumenstingl at [1] [2] [3].
>
> The support consist of :
> - A port of dwc3-of-simple from Linux to U-boot
> - A change to support more than 2 PHYs in the DWC3 DM driver
> - An USB2 PHY Driver and an USB3 PHY Driver
>
> The DWC3 Controller has up to 4 PHYs connected :
> - 2 USB2 PHYs and an USB3 PHY for GXL SoCs
> - 3 USB2 PHYs and an USB3 PHY for the GXM SoC Variant
> This is enabled by the "usb: host: dwc3: Add support for multiple PHYs" patch.
> This patch is based on the "xhci-dwc3: Couple of fixes for USB3 support"
> serie from Vignesh R, on the u-boot-usb tree.
>
> The DWC3 Controller glue is generic enough to use the dwc3-of-simple from Linux
> and can be easily ported to U-Boot as a Simple-Bus with Glue-Specific clocks
> and Reset lines setup.
>
> This depends on the recently applied :
> - clk: Add get/enable/disable/release for a bulk of clocks at [4]
> - reset: Add get/assert/deassert/release for bulk of reset signals at [5]
> in order to manage the clocks and resets of the Glue in a clean fashion.
>
> The USB PHY driver supports the standard generic PHY interface and supports
> the power-on/off calls and set the Host mode by default.
> They are based on the excellent work from Martin Blumenstingl merged in linux.
>
> Changes since v2:
> - Drop #if and use the empty stubs for clock & reset API
>
> Changes since v1:
> - switch to submitted clk/reset bulk API
> - splitted dwc3 multiple phy init error between poweroff & exit
>
Applied all, thanks.
--
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
2018-04-11 15:08 ` Neil Armstrong
@ 2018-04-11 16:17 ` Jean-Jacques Hiblot
-1 siblings, 0 replies; 18+ messages in thread
From: Jean-Jacques Hiblot @ 2018-04-11 16:17 UTC (permalink / raw)
To: u-boot
On 11/04/2018 17:08, Neil Armstrong wrote:
> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
> clock and resets of a simple DWC3 Controller HW glue.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> drivers/usb/host/Kconfig | 7 +++
> drivers/usb/host/Makefile | 1 +
> drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 117 insertions(+)
> create mode 100644 drivers/usb/host/dwc3-of-simple.c
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index a7249b7..6caa615 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
> Say Y or if your system has a Dual Role SuperSpeed
> USB controller based on the DesignWare USB3 IP Core.
>
> +config USB_XHCI_DWC3_OF_SIMPLE
> + bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
> + select MISC
> + help
> + Support USB2/3 functionality in simple SoC integrations with
> + USB controller based on the DesignWare USB3 IP Core.
> +
> config USB_XHCI_MVEBU
> bool "MVEBU USB 3.0 support"
> default y
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 9819489..abe4f90 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
> # xhci
> obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
> obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
> obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
> obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
> obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
> new file mode 100644
> index 0000000..54a5f60
> --- /dev/null
> +++ b/drivers/usb/host/dwc3-of-simple.c
> @@ -0,0 +1,109 @@
> +/*
> + * dwc3-of-simple.c - OF glue layer for simple integrations
> + *
> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *
> + * Author: Felipe Balbi <balbi@ti.com>
> + *
> + * Copyright (C) 2018 BayLibre, SAS
> + * Author: Neil Armstrong <narmstron@baylibre.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <fdtdec.h>
> +#include <reset.h>
> +#include <clk.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct dwc3_of_simple {
> + struct clk_bulk clks;
> + struct reset_ctl_bulk resets;
> +};
> +
> +static int dwc3_of_simple_reset_init(struct udevice *dev,
> + struct dwc3_of_simple *simple)
> +{
> + int ret;
> +
> + ret = reset_get_bulk(dev, &simple->resets);
> + if (ret == -ENOTSUPP)
> + return 0;
> + else if (ret)
> + return ret;
> +
> + ret = reset_deassert_bulk(&simple->resets);
> + if (ret) {
> + reset_release_bulk(&simple->resets);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_clk_init(struct udevice *dev,
> + struct dwc3_of_simple *simple)
> +{
> + int ret;
> +
> + ret = clk_get_bulk(dev, &simple->clks);
> + if (ret == -ENOTSUPP)
Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
> + return 0;
> + if (ret)
> + return ret;
> +
> +#if CONFIG_IS_ENABLED(CLK)
> + ret = clk_enable_bulk(&simple->clks);
> + if (ret) {
> + clk_release_bulk(&simple->clks);
> + return ret;
> + }
> +#endif
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_probe(struct udevice *dev)
> +{
> + struct dwc3_of_simple *simple = dev_get_platdata(dev);
> + int ret;
> +
> + ret = dwc3_of_simple_clk_init(dev, simple);
> + if (ret)
> + return ret;
> +
> + ret = dwc3_of_simple_reset_init(dev, simple);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_remove(struct udevice *dev)
> +{
> + struct dwc3_of_simple *simple = dev_get_platdata(dev);
> +
> + reset_release_bulk(&simple->resets);
> +
> + clk_release_bulk(&simple->clks);
> +
> + return dm_scan_fdt_dev(dev);
> +}
> +
> +static const struct udevice_id dwc3_of_simple_ids[] = {
> + { .compatible = "amlogic,meson-gxl-dwc3" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(dwc3_of_simple) = {
> + .name = "dwc3-of-simple",
> + .id = UCLASS_SIMPLE_BUS,
> + .of_match = dwc3_of_simple_ids,
> + .probe = dwc3_of_simple_probe,
> + .remove = dwc3_of_simple_remove,
> + .platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
> + .flags = DM_FLAG_ALLOC_PRIV_DMA,
> +};
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
@ 2018-04-11 16:17 ` Jean-Jacques Hiblot
0 siblings, 0 replies; 18+ messages in thread
From: Jean-Jacques Hiblot @ 2018-04-11 16:17 UTC (permalink / raw)
To: linus-amlogic
On 11/04/2018 17:08, Neil Armstrong wrote:
> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
> clock and resets of a simple DWC3 Controller HW glue.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> drivers/usb/host/Kconfig | 7 +++
> drivers/usb/host/Makefile | 1 +
> drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 117 insertions(+)
> create mode 100644 drivers/usb/host/dwc3-of-simple.c
>
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index a7249b7..6caa615 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
> Say Y or if your system has a Dual Role SuperSpeed
> USB controller based on the DesignWare USB3 IP Core.
>
> +config USB_XHCI_DWC3_OF_SIMPLE
> + bool "DesignWare USB3 DRD Generic OF Simple Glue Layer"
> + select MISC
> + help
> + Support USB2/3 functionality in simple SoC integrations with
> + USB controller based on the DesignWare USB3 IP Core.
> +
> config USB_XHCI_MVEBU
> bool "MVEBU USB 3.0 support"
> default y
> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
> index 9819489..abe4f90 100644
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o
> # xhci
> obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
> obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
> +obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
> obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
> obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
> obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
> diff --git a/drivers/usb/host/dwc3-of-simple.c b/drivers/usb/host/dwc3-of-simple.c
> new file mode 100644
> index 0000000..54a5f60
> --- /dev/null
> +++ b/drivers/usb/host/dwc3-of-simple.c
> @@ -0,0 +1,109 @@
> +/*
> + * dwc3-of-simple.c - OF glue layer for simple integrations
> + *
> + * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *
> + * Author: Felipe Balbi <balbi@ti.com>
> + *
> + * Copyright (C) 2018 BayLibre, SAS
> + * Author: Neil Armstrong <narmstron@baylibre.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <fdtdec.h>
> +#include <reset.h>
> +#include <clk.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct dwc3_of_simple {
> + struct clk_bulk clks;
> + struct reset_ctl_bulk resets;
> +};
> +
> +static int dwc3_of_simple_reset_init(struct udevice *dev,
> + struct dwc3_of_simple *simple)
> +{
> + int ret;
> +
> + ret = reset_get_bulk(dev, &simple->resets);
> + if (ret == -ENOTSUPP)
> + return 0;
> + else if (ret)
> + return ret;
> +
> + ret = reset_deassert_bulk(&simple->resets);
> + if (ret) {
> + reset_release_bulk(&simple->resets);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_clk_init(struct udevice *dev,
> + struct dwc3_of_simple *simple)
> +{
> + int ret;
> +
> + ret = clk_get_bulk(dev, &simple->clks);
> + if (ret == -ENOTSUPP)
Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
> + return 0;
> + if (ret)
> + return ret;
> +
> +#if CONFIG_IS_ENABLED(CLK)
> + ret = clk_enable_bulk(&simple->clks);
> + if (ret) {
> + clk_release_bulk(&simple->clks);
> + return ret;
> + }
> +#endif
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_probe(struct udevice *dev)
> +{
> + struct dwc3_of_simple *simple = dev_get_platdata(dev);
> + int ret;
> +
> + ret = dwc3_of_simple_clk_init(dev, simple);
> + if (ret)
> + return ret;
> +
> + ret = dwc3_of_simple_reset_init(dev, simple);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int dwc3_of_simple_remove(struct udevice *dev)
> +{
> + struct dwc3_of_simple *simple = dev_get_platdata(dev);
> +
> + reset_release_bulk(&simple->resets);
> +
> + clk_release_bulk(&simple->clks);
> +
> + return dm_scan_fdt_dev(dev);
> +}
> +
> +static const struct udevice_id dwc3_of_simple_ids[] = {
> + { .compatible = "amlogic,meson-gxl-dwc3" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(dwc3_of_simple) = {
> + .name = "dwc3-of-simple",
> + .id = UCLASS_SIMPLE_BUS,
> + .of_match = dwc3_of_simple_ids,
> + .probe = dwc3_of_simple_probe,
> + .remove = dwc3_of_simple_remove,
> + .platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
> + .flags = DM_FLAG_ALLOC_PRIV_DMA,
> +};
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
2018-04-11 16:17 ` Jean-Jacques Hiblot
@ 2018-04-12 8:05 ` Neil Armstrong
-1 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-12 8:05 UTC (permalink / raw)
To: u-boot
Hi Jean-Jacques,
On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>
>
> On 11/04/2018 17:08, Neil Armstrong wrote:
>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>> clock and resets of a simple DWC3 Controller HW glue.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> drivers/usb/host/Kconfig | 7 +++
>> drivers/usb/host/Makefile | 1 +
>> drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 117 insertions(+)
>> create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index a7249b7..6caa615 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
[...]
>> +
>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>> + struct dwc3_of_simple *simple)
>> +{
>> + int ret;
>> +
>> + ret = clk_get_bulk(dev, &simple->clks);
>> + if (ret == -ENOTSUPP)
>
> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
You are right, I naively used the same between reset and clock...
>
> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>
>> + return 0;
>> + if (ret)
>> + return ret;
>> +
>> +#if CONFIG_IS_ENABLED(CLK)
>> + ret = clk_enable_bulk(&simple->clks);
>> + if (ret) {
>> + clk_release_bulk(&simple->clks);
>> + return ret;
>> + }
>> +#endif
>> +
>> + return 0;
>> +}
[...]
Thanks,
Neil
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
@ 2018-04-12 8:05 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-12 8:05 UTC (permalink / raw)
To: linus-amlogic
Hi Jean-Jacques,
On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>
>
> On 11/04/2018 17:08, Neil Armstrong wrote:
>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>> clock and resets of a simple DWC3 Controller HW glue.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> ? drivers/usb/host/Kconfig????????? |?? 7 +++
>> ? drivers/usb/host/Makefile???????? |?? 1 +
>> ? drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>> ? 3 files changed, 117 insertions(+)
>> ? create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index a7249b7..6caa615 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
[...]
>> +
>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>> +?????????????????? struct dwc3_of_simple *simple)
>> +{
>> +??? int ret;
>> +
>> +??? ret = clk_get_bulk(dev, &simple->clks);
>> +??? if (ret == -ENOTSUPP)
>
> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
You are right, I naively used the same between reset and clock...
>
> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>
>> +??????? return 0;
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +#if CONFIG_IS_ENABLED(CLK)
>> +??? ret = clk_enable_bulk(&simple->clks);
>> +??? if (ret) {
>> +??????? clk_release_bulk(&simple->clks);
>> +??????? return ret;
>> +??? }
>> +#endif
>> +
>> +??? return 0;
>> +}
[...]
Thanks,
Neil
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
2018-04-12 8:05 ` Neil Armstrong
@ 2018-04-12 8:07 ` Ben Dooks
-1 siblings, 0 replies; 18+ messages in thread
From: Ben Dooks @ 2018-04-12 8:07 UTC (permalink / raw)
To: u-boot
On 12/04/18 09:05, Neil Armstrong wrote:
> Hi Jean-Jacques,
>
> On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>>
>>
>> On 11/04/2018 17:08, Neil Armstrong wrote:
>>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>>> clock and resets of a simple DWC3 Controller HW glue.
>>>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>> drivers/usb/host/Kconfig | 7 +++
>>> drivers/usb/host/Makefile | 1 +
>>> drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 117 insertions(+)
>>> create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>
>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>> index a7249b7..6caa615 100644
>>> --- a/drivers/usb/host/Kconfig
>>> +++ b/drivers/usb/host/Kconfig
>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
> [...]
>
>>> +
>>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>>> + struct dwc3_of_simple *simple)
>>> +{
>>> + int ret;
>>> +
>>> + ret = clk_get_bulk(dev, &simple->clks);
>>> + if (ret == -ENOTSUPP)
>>
>> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
>
> You are right, I naively used the same between reset and clock...
>
>>
>> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>>
>>> + return 0;
>>> + if (ret)
>>> + return ret;
>>> +
>>> +#if CONFIG_IS_ENABLED(CLK)
>>> + ret = clk_enable_bulk(&simple->clks);
>>> + if (ret) {
>>> + clk_release_bulk(&simple->clks);
>>> + return ret;
>>> + }
>>> +#endif
>>> +
>>> + return 0;
>>> +}
Is the above #if CONFIG_IS_ENABLED(CLK) avoidable?
>
> [...]
> Thanks,
> Neil
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
>
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
@ 2018-04-12 8:07 ` Ben Dooks
0 siblings, 0 replies; 18+ messages in thread
From: Ben Dooks @ 2018-04-12 8:07 UTC (permalink / raw)
To: linus-amlogic
On 12/04/18 09:05, Neil Armstrong wrote:
> Hi Jean-Jacques,
>
> On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>>
>>
>> On 11/04/2018 17:08, Neil Armstrong wrote:
>>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>>> clock and resets of a simple DWC3 Controller HW glue.
>>>
>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>> ---
>>> ? drivers/usb/host/Kconfig????????? |?? 7 +++
>>> ? drivers/usb/host/Makefile???????? |?? 1 +
>>> ? drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>>> ? 3 files changed, 117 insertions(+)
>>> ? create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>
>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>> index a7249b7..6caa615 100644
>>> --- a/drivers/usb/host/Kconfig
>>> +++ b/drivers/usb/host/Kconfig
>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
> [...]
>
>>> +
>>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>>> +?????????????????? struct dwc3_of_simple *simple)
>>> +{
>>> +??? int ret;
>>> +
>>> +??? ret = clk_get_bulk(dev, &simple->clks);
>>> +??? if (ret == -ENOTSUPP)
>>
>> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
>
> You are right, I naively used the same between reset and clock...
>
>>
>> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>>
>>> +??????? return 0;
>>> +??? if (ret)
>>> +??????? return ret;
>>> +
>>> +#if CONFIG_IS_ENABLED(CLK)
>>> +??? ret = clk_enable_bulk(&simple->clks);
>>> +??? if (ret) {
>>> +??????? clk_release_bulk(&simple->clks);
>>> +??????? return ret;
>>> +??? }
>>> +#endif
>>> +
>>> +??? return 0;
>>> +}
Is the above #if CONFIG_IS_ENABLED(CLK) avoidable?
>
> [...]
> Thanks,
> Neil
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
>
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
2018-04-12 8:07 ` Ben Dooks
@ 2018-04-12 8:08 ` Neil Armstrong
-1 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-12 8:08 UTC (permalink / raw)
To: u-boot
On 12/04/2018 10:07, Ben Dooks wrote:
> On 12/04/18 09:05, Neil Armstrong wrote:
>> Hi Jean-Jacques,
>>
>> On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>>>
>>>
>>> On 11/04/2018 17:08, Neil Armstrong wrote:
>>>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>>>> clock and resets of a simple DWC3 Controller HW glue.
>>>>
>>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>>> ---
>>>> drivers/usb/host/Kconfig | 7 +++
>>>> drivers/usb/host/Makefile | 1 +
>>>> drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 117 insertions(+)
>>>> create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>>
>>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>>> index a7249b7..6caa615 100644
>>>> --- a/drivers/usb/host/Kconfig
>>>> +++ b/drivers/usb/host/Kconfig
>>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>> [...]
>>
>>>> +
>>>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>>>> + struct dwc3_of_simple *simple)
>>>> +{
>>>> + int ret;
>>>> +
>>>> + ret = clk_get_bulk(dev, &simple->clks);
>>>> + if (ret == -ENOTSUPP)
>>>
>>> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
>>
>> You are right, I naively used the same between reset and clock...
>>
>>>
>>> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>>>
>>>> + return 0;
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> +#if CONFIG_IS_ENABLED(CLK)
>>>> + ret = clk_enable_bulk(&simple->clks);
>>>> + if (ret) {
>>>> + clk_release_bulk(&simple->clks);
>>>> + return ret;
>>>> + }
>>>> +#endif
>>>> +
>>>> + return 0;
>>>> +}
>
> Is the above #if CONFIG_IS_ENABLED(CLK) avoidable?
No unless some changes in clk.h
Neil
>
>>
>> [...]
>> Thanks,
>> Neil
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
>>
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration
@ 2018-04-12 8:08 ` Neil Armstrong
0 siblings, 0 replies; 18+ messages in thread
From: Neil Armstrong @ 2018-04-12 8:08 UTC (permalink / raw)
To: linus-amlogic
On 12/04/2018 10:07, Ben Dooks wrote:
> On 12/04/18 09:05, Neil Armstrong wrote:
>> Hi Jean-Jacques,
>>
>> On 11/04/2018 18:17, Jean-Jacques Hiblot wrote:
>>>
>>>
>>> On 11/04/2018 17:08, Neil Armstrong wrote:
>>>> This is a port of the dwc3-of-simple driver from Linux to enable/deassert
>>>> clock and resets of a simple DWC3 Controller HW glue.
>>>>
>>>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>>>> ---
>>>> ?? drivers/usb/host/Kconfig????????? |?? 7 +++
>>>> ?? drivers/usb/host/Makefile???????? |?? 1 +
>>>> ?? drivers/usb/host/dwc3-of-simple.c | 109 ++++++++++++++++++++++++++++++++++++++
>>>> ?? 3 files changed, 117 insertions(+)
>>>> ?? create mode 100644 drivers/usb/host/dwc3-of-simple.c
>>>>
>>>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>>>> index a7249b7..6caa615 100644
>>>> --- a/drivers/usb/host/Kconfig
>>>> +++ b/drivers/usb/host/Kconfig
>>>> @@ -21,6 +21,13 @@ config USB_XHCI_DWC3
>> [...]
>>
>>>> +
>>>> +static int dwc3_of_simple_clk_init(struct udevice *dev,
>>>> +?????????????????? struct dwc3_of_simple *simple)
>>>> +{
>>>> +??? int ret;
>>>> +
>>>> +??? ret = clk_get_bulk(dev, &simple->clks);
>>>> +??? if (ret == -ENOTSUPP)
>>>
>>> Must be ENOSYS instead of ENOTSUPP, otherwise probe fails on platform not using the clk framework
>>
>> You are right, I naively used the same between reset and clock...
>>
>>>
>>> tested-by: Jean-Jacques hiblot <jjhiblot@ti.com>
>>>
>>>> +??????? return 0;
>>>> +??? if (ret)
>>>> +??????? return ret;
>>>> +
>>>> +#if CONFIG_IS_ENABLED(CLK)
>>>> +??? ret = clk_enable_bulk(&simple->clks);
>>>> +??? if (ret) {
>>>> +??????? clk_release_bulk(&simple->clks);
>>>> +??????? return ret;
>>>> +??? }
>>>> +#endif
>>>> +
>>>> +??? return 0;
>>>> +}
>
> Is the above #if CONFIG_IS_ENABLED(CLK) avoidable?
No unless some changes in clk.h
Neil
>
>>
>> [...]
>> Thanks,
>> Neil
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
>>
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2018-04-12 8:08 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-11 15:07 [U-Boot] [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Neil Armstrong
2018-04-11 15:07 ` Neil Armstrong
2018-04-11 15:08 ` [U-Boot] [PATCH v3 u-boot 1/3] usb: host: Add simple of glue driver for DWC3 USB Controllers integration Neil Armstrong
2018-04-11 15:08 ` Neil Armstrong
2018-04-11 16:17 ` [U-Boot] " Jean-Jacques Hiblot
2018-04-11 16:17 ` Jean-Jacques Hiblot
2018-04-12 8:05 ` Neil Armstrong
2018-04-12 8:05 ` Neil Armstrong
2018-04-12 8:07 ` Ben Dooks
2018-04-12 8:07 ` Ben Dooks
2018-04-12 8:08 ` Neil Armstrong
2018-04-12 8:08 ` Neil Armstrong
2018-04-11 15:08 ` [U-Boot] [PATCH v3 u-boot 2/3] usb: host: dwc3: Add support for multiple PHYs Neil Armstrong
2018-04-11 15:08 ` Neil Armstrong
2018-04-11 15:08 ` [U-Boot] [PATCH v3 u-boot 3/3] phy: Add Amlogic Meson USB2 & USB3 Generic PHY drivers Neil Armstrong
2018-04-11 15:08 ` Neil Armstrong
2018-04-11 15:20 ` [U-Boot] [PATCH v3 u-boot 0/3] Add USB Support for Amlogic Meson GXL SoCs Marek Vasut
2018-04-11 15:20 ` Marek Vasut
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.