[PATCH 01/19] phy: nop-phy: Add standard usb-nop-xceiv compat string

The USB no-op PHY uses "usb-nop-xceiv" compatible string. This driver is compatible with USB no-op PHY, so add the compatible string.
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexey Brodkin alexey.brodkin@synopsys.com Cc: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Cc: Fabio Estevam festevam@gmail.com Cc: Jean-Jacques Hiblot jjhiblot@ti.com Cc: Murali Karicheri m-karicheri2@ti.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/phy/nop-phy.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c index 84aac806230..9f12ebc0624 100644 --- a/drivers/phy/nop-phy.c +++ b/drivers/phy/nop-phy.c @@ -43,6 +43,7 @@ static int nop_phy_probe(struct udevice *dev)
static const struct udevice_id nop_phy_ids[] = { { .compatible = "nop-phy" }, + { .compatible = "usb-nop-xceiv" }, { } };

The standard compatible string is "usb-nop-xceiv", use it.
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexey Brodkin alexey.brodkin@synopsys.com Cc: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Cc: Fabio Estevam festevam@gmail.com Cc: Jean-Jacques Hiblot jjhiblot@ti.com Cc: Murali Karicheri m-karicheri2@ti.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- arch/arc/dts/iot_devkit.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arc/dts/iot_devkit.dts b/arch/arc/dts/iot_devkit.dts index c0173fa5ab4..2122827527e 100644 --- a/arch/arc/dts/iot_devkit.dts +++ b/arch/arc/dts/iot_devkit.dts @@ -39,7 +39,7 @@ };
usbphy: phy { - compatible = "nop-phy"; + compatible = "usb-nop-xceiv"; #phy-cells = <0>; };

The standard compatible string is "usb-nop-xceiv", use it. Note that keystone-k2g.dtsi already uses the aforementioned compat string, so this patch can only remove the override.
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexey Brodkin alexey.brodkin@synopsys.com Cc: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Cc: Fabio Estevam festevam@gmail.com Cc: Jean-Jacques Hiblot jjhiblot@ti.com Cc: Murali Karicheri m-karicheri2@ti.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- arch/arm/dts/keystone-k2g-evm.dts | 2 -- 1 file changed, 2 deletions(-)
diff --git a/arch/arm/dts/keystone-k2g-evm.dts b/arch/arm/dts/keystone-k2g-evm.dts index 7c5deef8083..b5b511cbd61 100644 --- a/arch/arm/dts/keystone-k2g-evm.dts +++ b/arch/arm/dts/keystone-k2g-evm.dts @@ -38,7 +38,6 @@
&usb0_phy { status = "okay"; - compatible = "nop-phy"; };
&usb0 { @@ -51,7 +50,6 @@ };
&usb1_phy { - compatible = "nop-phy"; status = "okay"; };

The fsl,usbphy DT property is deprecated, replace it with phys DT property and specify #phy-cells, so that the generic PHY framework can parse the PHY bindings without any extra hacking.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- arch/arm/dts/imx8mm.dtsi | 6 ++++-- arch/arm/dts/imx8mn.dtsi | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm/dts/imx8mm.dtsi b/arch/arm/dts/imx8mm.dtsi index c824f2615fe..fa2d73f1803 100644 --- a/arch/arm/dts/imx8mm.dtsi +++ b/arch/arm/dts/imx8mm.dtsi @@ -241,6 +241,7 @@ };
usbphynop1: usbphynop1 { + #phy-cells = <0>; compatible = "usb-nop-xceiv"; clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; @@ -249,6 +250,7 @@ };
usbphynop2: usbphynop2 { + #phy-cells = <0>; compatible = "usb-nop-xceiv"; clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; @@ -936,7 +938,7 @@ clock-names = "usb1_ctrl_root_clk"; assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; - fsl,usbphy = <&usbphynop1>; + phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; status = "disabled"; }; @@ -955,7 +957,7 @@ clock-names = "usb1_ctrl_root_clk"; assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; - fsl,usbphy = <&usbphynop2>; + phys = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>; status = "disabled"; }; diff --git a/arch/arm/dts/imx8mn.dtsi b/arch/arm/dts/imx8mn.dtsi index ee179023049..f77b223682c 100644 --- a/arch/arm/dts/imx8mn.dtsi +++ b/arch/arm/dts/imx8mn.dtsi @@ -930,7 +930,7 @@ clock-names = "usb1_ctrl_root_clk"; assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>; assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>; - fsl,usbphy = <&usbphynop1>; + phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; status = "disabled"; }; @@ -998,6 +998,7 @@ };
usbphynop1: usbphynop1 { + #phy-cells = <0>; compatible = "usb-nop-xceiv"; clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;

Add power domain nodes to DT.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- arch/arm/dts/imx8mm.dtsi | 73 ++++++++++++++++++++++++ include/dt-bindings/power/imx8mm-power.h | 22 +++++++ 2 files changed, 95 insertions(+) create mode 100644 include/dt-bindings/power/imx8mm-power.h
diff --git a/arch/arm/dts/imx8mm.dtsi b/arch/arm/dts/imx8mm.dtsi index fa2d73f1803..b142b80734d 100644 --- a/arch/arm/dts/imx8mm.dtsi +++ b/arch/arm/dts/imx8mm.dtsi @@ -4,6 +4,8 @@ */
#include <dt-bindings/clock/imx8mm-clock.h> +#include <dt-bindings/power/imx8mm-power.h> +#include <dt-bindings/reset/imx8mq-reset.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -592,6 +594,75 @@ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; #reset-cells = <1>; }; + + gpc: gpc@303a0000 { + compatible = "fsl,imx8mm-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <3>; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + pgc_hsiomix: power-domain@0 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_HSIOMIX>; + clocks = <&clk IMX8MM_CLK_USB_BUS>; + }; + + pgc_pcie: power-domain@1 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_PCIE>; + power-domains = <&pgc_hsiomix>; + }; + + pgc_otg1: power-domain@2 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_OTG1>; + power-domains = <&pgc_hsiomix>; + }; + + pgc_otg2: power-domain@3 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_OTG2>; + power-domains = <&pgc_hsiomix>; + }; + + pgc_gpumix: power-domain@4 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_GPUMIX>; + clocks = <&clk IMX8MM_CLK_GPU_BUS_ROOT>, + <&clk IMX8MM_CLK_GPU_AHB>; + }; + + pgc_gpu: power-domain@5 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_GPU>; + clocks = <&clk IMX8MM_CLK_GPU_AHB>, + <&clk IMX8MM_CLK_GPU_BUS_ROOT>, + <&clk IMX8MM_CLK_GPU2D_ROOT>, + <&clk IMX8MM_CLK_GPU3D_ROOT>; + resets = <&src IMX8MQ_RESET_GPU_RESET>; + power-domains = <&pgc_gpumix>; + }; + + dispmix_pd: power-domain@10 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_DISPMIX>; + clocks = <&clk IMX8MM_CLK_DISP_ROOT>, + <&clk IMX8MM_CLK_DISP_AXI_ROOT>, + <&clk IMX8MM_CLK_DISP_APB_ROOT>; + }; + + mipi_pd: power-domain@11 { + #power-domain-cells = <0>; + reg = <IMX8MM_POWER_DOMAIN_MIPI>; + power-domains = <&dispmix_pd>; + }; + }; + }; };
aips2: bus@30400000 { @@ -940,6 +1011,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; + power-domains = <&pgc_otg1>; status = "disabled"; };
@@ -959,6 +1031,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>; + power-domains = <&pgc_otg2>; status = "disabled"; };
diff --git a/include/dt-bindings/power/imx8mm-power.h b/include/dt-bindings/power/imx8mm-power.h new file mode 100644 index 00000000000..fc9c2e16aad --- /dev/null +++ b/include/dt-bindings/power/imx8mm-power.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (C) 2020 Pengutronix, Lucas Stach kernel@pengutronix.de + */ + +#ifndef __DT_BINDINGS_IMX8MM_POWER_H__ +#define __DT_BINDINGS_IMX8MM_POWER_H__ + +#define IMX8MM_POWER_DOMAIN_HSIOMIX 0 +#define IMX8MM_POWER_DOMAIN_PCIE 1 +#define IMX8MM_POWER_DOMAIN_OTG1 2 +#define IMX8MM_POWER_DOMAIN_OTG2 3 +#define IMX8MM_POWER_DOMAIN_GPUMIX 4 +#define IMX8MM_POWER_DOMAIN_GPU 5 +#define IMX8MM_POWER_DOMAIN_VPUMIX 6 +#define IMX8MM_POWER_DOMAIN_VPUG1 7 +#define IMX8MM_POWER_DOMAIN_VPUG2 8 +#define IMX8MM_POWER_DOMAIN_VPUH1 9 +#define IMX8MM_POWER_DOMAIN_DISPMIX 10 +#define IMX8MM_POWER_DOMAIN_MIPI 11 + +#endif

On 4/2/21 9:47 PM, Marek Vasut wrote:
Add power domain nodes to DT.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
arch/arm/dts/imx8mm.dtsi | 73 ++++++++++++++++++++++++ include/dt-bindings/power/imx8mm-power.h | 22 +++++++ 2 files changed, 95 insertions(+) create mode 100644 include/dt-bindings/power/imx8mm-power.h
diff --git a/arch/arm/dts/imx8mm.dtsi b/arch/arm/dts/imx8mm.dtsi index fa2d73f1803..b142b80734d 100644 --- a/arch/arm/dts/imx8mm.dtsi +++ b/arch/arm/dts/imx8mm.dtsi @@ -4,6 +4,8 @@ */
#include <dt-bindings/clock/imx8mm-clock.h> +#include <dt-bindings/power/imx8mm-power.h> +#include <dt-bindings/reset/imx8mq-reset.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/interrupt-controller/arm-gic.h> @@ -592,6 +594,75 @@ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; #reset-cells = <1>; };
gpc: gpc@303a0000 {
compatible = "fsl,imx8mm-gpc";
reg = <0x303a0000 0x10000>;
interrupt-parent = <&gic>;
interrupt-controller;
#interrupt-cells = <3>;
pgc {
#address-cells = <1>;
#size-cells = <0>;
pgc_hsiomix: power-domain@0 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_HSIOMIX>;
clocks = <&clk IMX8MM_CLK_USB_BUS>;
};
pgc_pcie: power-domain@1 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_PCIE>;
power-domains = <&pgc_hsiomix>;
};
pgc_otg1: power-domain@2 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_OTG1>;
power-domains = <&pgc_hsiomix>;
};
pgc_otg2: power-domain@3 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_OTG2>;
power-domains = <&pgc_hsiomix>;
};
pgc_gpumix: power-domain@4 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_GPUMIX>;
clocks = <&clk IMX8MM_CLK_GPU_BUS_ROOT>,
<&clk IMX8MM_CLK_GPU_AHB>;
};
pgc_gpu: power-domain@5 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_GPU>;
clocks = <&clk IMX8MM_CLK_GPU_AHB>,
<&clk IMX8MM_CLK_GPU_BUS_ROOT>,
<&clk IMX8MM_CLK_GPU2D_ROOT>,
<&clk IMX8MM_CLK_GPU3D_ROOT>;
resets = <&src IMX8MQ_RESET_GPU_RESET>;
power-domains = <&pgc_gpumix>;
};
dispmix_pd: power-domain@10 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_DISPMIX>;
clocks = <&clk IMX8MM_CLK_DISP_ROOT>,
<&clk IMX8MM_CLK_DISP_AXI_ROOT>,
<&clk IMX8MM_CLK_DISP_APB_ROOT>;
};
mipi_pd: power-domain@11 {
#power-domain-cells = <0>;
reg = <IMX8MM_POWER_DOMAIN_MIPI>;
power-domains = <&dispmix_pd>;
};
};
};
};
aips2: bus@30400000 {
@@ -940,6 +1011,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>;
power-domains = <&pgc_otg1>; status = "disabled"; };
@@ -959,6 +1031,7 @@ assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; phys = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>;
power-domains = <&pgc_otg2>; status = "disabled"; };
diff --git a/include/dt-bindings/power/imx8mm-power.h b/include/dt-bindings/power/imx8mm-power.h new file mode 100644 index 00000000000..fc9c2e16aad --- /dev/null +++ b/include/dt-bindings/power/imx8mm-power.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/*
- Copyright (C) 2020 Pengutronix, Lucas Stach kernel@pengutronix.de
- */
+#ifndef __DT_BINDINGS_IMX8MM_POWER_H__ +#define __DT_BINDINGS_IMX8MM_POWER_H__
+#define IMX8MM_POWER_DOMAIN_HSIOMIX 0 +#define IMX8MM_POWER_DOMAIN_PCIE 1 +#define IMX8MM_POWER_DOMAIN_OTG1 2 +#define IMX8MM_POWER_DOMAIN_OTG2 3 +#define IMX8MM_POWER_DOMAIN_GPUMIX 4 +#define IMX8MM_POWER_DOMAIN_GPU 5 +#define IMX8MM_POWER_DOMAIN_VPUMIX 6 +#define IMX8MM_POWER_DOMAIN_VPUG1 7 +#define IMX8MM_POWER_DOMAIN_VPUG2 8 +#define IMX8MM_POWER_DOMAIN_VPUH1 9 +#define IMX8MM_POWER_DOMAIN_DISPMIX 10 +#define IMX8MM_POWER_DOMAIN_MIPI 11
+#endif

The driver is compatible with iMX8MM, add missing compatible string.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/power/domain/imx8m-power-domain.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index c4cd07ffaf4..ebac90d81c1 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -120,6 +120,7 @@ static int imx8m_power_domain_of_to_plat(struct udevice *dev)
static const struct udevice_id imx8m_power_domain_ids[] = { { .compatible = "fsl,imx8mq-gpc" }, + { .compatible = "fsl,imx8mm-gpc" }, { } };

On 4/2/21 9:47 PM, Marek Vasut wrote:
The driver is compatible with iMX8MM, add missing compatible string.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com
Best Regards, Jaehoon Chung
drivers/power/domain/imx8m-power-domain.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index c4cd07ffaf4..ebac90d81c1 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -120,6 +120,7 @@ static int imx8m_power_domain_of_to_plat(struct udevice *dev)
static const struct udevice_id imx8m_power_domain_ids[] = { { .compatible = "fsl,imx8mq-gpc" },
- { .compatible = "fsl,imx8mm-gpc" }, { }
};

The driver turns on Vbus regulator in probe, but fails to turn it back off in case of probe failure. Add the missing code.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index aeea5399995..6fb596633a3 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -640,7 +640,32 @@ static int ehci_usb_probe(struct udevice *dev) hcor = (struct ehci_hcor *)((uint32_t)hccr + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
- return ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type); + ret = ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type); + if (ret) + goto err_regulator; + + return ret; + +err_regulator: +#if CONFIG_IS_ENABLED(DM_REGULATOR) + if (priv->vbus_supply) + regulator_set_enable(priv->vbus_supply, false); +#endif + return ret; +} + +int ehci_usb_remove(struct udevice *dev) +{ + struct ehci_mx6_priv_data *priv = dev_get_priv(dev); + + ehci_deregister(dev); + +#if CONFIG_IS_ENABLED(DM_REGULATOR) + if (priv->vbus_supply) + regulator_set_enable(priv->vbus_supply, false); +#endif + + return 0; }
static const struct udevice_id mx6_usb_ids[] = { @@ -655,7 +680,7 @@ U_BOOT_DRIVER(usb_mx6) = { .of_to_plat = ehci_usb_of_to_plat, .bind = ehci_usb_bind, .probe = ehci_usb_probe, - .remove = ehci_deregister, + .remove = ehci_usb_remove, .ops = &ehci_usb_ops, .plat_auto = sizeof(struct usb_plat), .priv_auto = sizeof(struct ehci_mx6_priv_data),

Add support for using DM clock framework to enable and disable all the necessary clock for the USB controller.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 6fb596633a3..ecc79cb54b6 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -5,6 +5,7 @@ */
#include <common.h> +#include <clk.h> #include <log.h> #include <usb.h> #include <errno.h> @@ -347,9 +348,6 @@ int ehci_mx6_common_init(struct usb_ehci *ehci, int index) { int ret;
- enable_usboh3_clk(1); - mdelay(1); - /* Do board specific initialization */ ret = board_ehci_hcd_init(index); if (ret) @@ -391,6 +389,9 @@ int ehci_hcd_init(int index, enum usb_init_type init, } }
+ enable_usboh3_clk(1); + mdelay(1); + ret = ehci_mx6_common_init(ehci, index); if (ret) return ret; @@ -428,6 +429,7 @@ struct ehci_mx6_priv_data { struct ehci_ctrl ctrl; struct usb_ehci *ehci; struct udevice *vbus_supply; + struct clk clk; enum usb_init_type init_type; int portnr; }; @@ -606,6 +608,20 @@ static int ehci_usb_probe(struct udevice *dev) priv->portnr = dev_seq(dev); priv->init_type = type;
+#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) + return ret; +#else + /* Compatibility with DM_USB and !CLK */ + enable_usboh3_clk(1); + mdelay(1); +#endif + #if CONFIG_IS_ENABLED(DM_REGULATOR) ret = device_get_supply_regulator(dev, "vbus-supply", &priv->vbus_supply); @@ -614,7 +630,7 @@ static int ehci_usb_probe(struct udevice *dev) #endif ret = ehci_mx6_common_init(ehci, priv->portnr); if (ret) - return ret; + goto err_clk;
#if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) { @@ -623,7 +639,7 @@ static int ehci_usb_probe(struct udevice *dev) false : true); if (ret && ret != -ENOSYS) { printf("Error enabling VBUS supply (ret=%i)\n", ret); - return ret; + goto err_clk; } } #endif @@ -650,6 +666,13 @@ err_regulator: #if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) regulator_set_enable(priv->vbus_supply, false); +#endif +err_clk: +#if CONFIG_IS_ENABLED(CLK) + clk_disable(&priv->clk); +#else + /* Compatibility with DM_USB and !CLK */ + enable_usboh3_clk(0); #endif return ret; } @@ -665,6 +688,10 @@ int ehci_usb_remove(struct udevice *dev) regulator_set_enable(priv->vbus_supply, false); #endif
+#if CONFIG_IS_ENABLED(CLK) + clk_disable(&priv->clk); +#endif + return 0; }

Merge USBNC register layout structure into a single one, instead of having three separate structures and a lot of ifdeffery. No functional change.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 53 +++++++++++++------------------------ 1 file changed, 19 insertions(+), 34 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index ecc79cb54b6..b0703502db0 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -68,6 +68,24 @@ DECLARE_GLOBAL_DATA_PTR; #define UCMD_RUN_STOP (1 << 0) /* controller run/stop */ #define UCMD_RESET (1 << 1) /* controller reset */
+/* Base address for this IP block is 0x02184800 */ +struct usbnc_regs { + u32 ctrl[4]; /* otg/host1-3 */ + u32 uh2_hsic_ctrl; + u32 uh3_hsic_ctrl; + u32 otg_phy_ctrl_0; + u32 uh1_phy_ctrl_0; + u32 reserve1[4]; + u32 phy_cfg1; + u32 phy_cfg2; + u32 reserve2; + u32 phy_status; + u32 reserve3[4]; + u32 adp_cfg1; + u32 adp_cfg2; + u32 adp_status; +}; + #if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) static const unsigned phy_bases[] = { USB_PHY0_BASE_ADDR, @@ -207,39 +225,7 @@ int usb_phy_mode(int port) return USB_INIT_HOST; }
-#if defined(CONFIG_MX7ULP) -struct usbnc_regs { - u32 ctrl1; - u32 ctrl2; - u32 reserve0[2]; - u32 hsic_ctrl; -}; -#else -/* Base address for this IP block is 0x02184800 */ -struct usbnc_regs { - u32 ctrl[4]; /* otg/host1-3 */ - u32 uh2_hsic_ctrl; - u32 uh3_hsic_ctrl; - u32 otg_phy_ctrl_0; - u32 uh1_phy_ctrl_0; -}; -#endif - #elif defined(CONFIG_MX7) -struct usbnc_regs { - u32 ctrl1; - u32 ctrl2; - u32 reserve1[10]; - u32 phy_cfg1; - u32 phy_cfg2; - u32 reserve2; - u32 phy_status; - u32 reserve3[4]; - u32 adp_cfg1; - u32 adp_cfg2; - u32 adp_status; -}; - static void usb_power_config(int index) { struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + @@ -274,12 +260,11 @@ static void usb_oc_config(int index) #if defined(CONFIG_MX6) struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + USB_OTHERREGS_OFFSET); - void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]); #elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP) struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + (0x10000 * index) + USBNC_OFFSET); - void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl1); #endif + void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
#if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2 /* mx6qarm2 seems to required a different setting*/

In case DM and OF controler is enabled, but PHY support is disabled, parse USB PHY and MISC component addresses from DT manually. Those component addresses will be used in subsequent patches to access the ANATOP, PHY and MISC registers matching the controller and thus get rid of the ad-hoc controller sequence number mapping.
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index b0703502db0..008dca9bae7 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -417,6 +417,12 @@ struct ehci_mx6_priv_data { struct clk clk; enum usb_init_type init_type; int portnr; +#if !defined(CONFIG_PHY) + /* Legacy iMX6/iMX7/iMX7ULP compat, they do not use PHY framework yet */ + void __iomem *phy_addr; + void __iomem *misc_addr; + void __iomem *anatop_addr; +#endif };
static int mx6_init_after_reset(struct ehci_ctrl *dev) @@ -571,6 +577,55 @@ static int ehci_usb_bind(struct udevice *dev) return 0; }
+static int mx6_parse_dt_addrs(struct udevice *dev) +{ +#if !defined(CONFIG_PHY) + /* + * Parse USB PHY/MISC/ANATOP addresses out of DT on platforms + * which do not use PHY framework yet, that is MX6/MX7/MX7ULP. + */ + struct ehci_mx6_priv_data *priv = dev_get_priv(dev); + int phy_off, misc_off, anatop_off; + const void *blob = gd->fdt_blob; + int offset = dev_of_offset(dev); + void *__iomem addr; + + phy_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbphy"); + if (phy_off < 0) + return -EINVAL; + + misc_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbmisc"); + if (misc_off < 0) + return -EINVAL; + + addr = (void __iomem *)fdtdec_get_addr(blob, phy_off, "reg"); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->phy_addr = addr; + + addr = (void __iomem *)fdtdec_get_addr(blob, misc_off, "reg"); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->misc_addr = addr; + +#if defined(CONFIG_MX6) + /* Resolve ANATOP offset through USB PHY node */ + anatop_off = fdtdec_lookup_phandle(blob, phy_off, "fsl,anatop"); + if (anatop_off < 0) + return -EINVAL; + + addr = (void __iomem *)fdtdec_get_addr(blob, anatop_off, "reg"); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->anatop_addr = addr; +#endif +#endif + return 0; +} + static int ehci_usb_probe(struct udevice *dev) { struct usb_plat *plat = dev_get_plat(dev); @@ -589,6 +644,10 @@ static int ehci_usb_probe(struct udevice *dev) } }
+ ret = mx6_parse_dt_addrs(dev); + if (ret) + return ret; + priv->ehci = ehci; priv->portnr = dev_seq(dev); priv->init_type = type;

In order to pass component addresses around easily instead of passing ad-hoc sequence numbers, it is necessary to split ehci_mx6_common_init(). Make it so and call the separate functions instead.
Since board_ehci_hcd_init() makes no sense in DM case, do not call it in DM case.
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 008dca9bae7..b195ba4c89b 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -283,6 +283,7 @@ static void usb_oc_config(int index) #endif }
+#if !CONFIG_IS_ENABLED(DM_USB) /** * board_usb_phy_mode - override usb phy mode * @port: usb host/otg port @@ -329,27 +330,6 @@ int __weak board_ehci_power(int port, int on) return 0; }
-int ehci_mx6_common_init(struct usb_ehci *ehci, int index) -{ - int ret; - - /* Do board specific initialization */ - ret = board_ehci_hcd_init(index); - if (ret) - return ret; - - usb_power_config(index); - usb_oc_config(index); - -#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) - usb_internal_phy_clock_gate(index, 1); - usb_phy_enable(index, ehci); -#endif - - return 0; -} - -#if !CONFIG_IS_ENABLED(DM_USB) int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { @@ -377,9 +357,20 @@ int ehci_hcd_init(int index, enum usb_init_type init, enable_usboh3_clk(1); mdelay(1);
- ret = ehci_mx6_common_init(ehci, index); - if (ret) + /* Do board specific initialization */ + ret = board_ehci_hcd_init(index); + if (ret) { + enable_usboh3_clk(0); return ret; + } + + usb_power_config(index); + usb_oc_config(index); + +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) + usb_internal_phy_clock_gate(index, 1); + usb_phy_enable(index, ehci); +#endif
type = board_usb_phy_mode(index);
@@ -432,9 +423,13 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) struct usb_ehci *ehci = priv->ehci; int ret;
- ret = ehci_mx6_common_init(priv->ehci, priv->portnr); - if (ret) - return ret; + usb_power_config(priv->portnr); + usb_oc_config(priv->portnr); + +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) + usb_internal_phy_clock_gate(priv->portnr, 1); + usb_phy_enable(priv->portnr, ehci); +#endif
#if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) { @@ -672,9 +667,14 @@ static int ehci_usb_probe(struct udevice *dev) if (ret) debug("%s: No vbus supply\n", dev->name); #endif - ret = ehci_mx6_common_init(ehci, priv->portnr); - if (ret) - goto err_clk; + + usb_power_config(priv->portnr); + usb_oc_config(priv->portnr); + +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) + usb_internal_phy_clock_gate(priv->portnr, 1); + usb_phy_enable(priv->portnr, ehci); +#endif
#if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) {

Instead of passing ad-hoc index to USB PHY handling functions and then try and figure out the PHY address, pass in the PHY address itself. For DM case, this address comes easily from DT. For non-DM case, the previous method is still present, however the non-DM case will soon be removed.
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index b195ba4c89b..800a25d1d9d 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -94,14 +94,8 @@ static const unsigned phy_bases[] = { #endif };
-static void usb_internal_phy_clock_gate(int index, int on) +static void usb_internal_phy_clock_gate(void __iomem *phy_reg, int on) { - void __iomem *phy_reg; - - if (index >= ARRAY_SIZE(phy_bases)) - return; - - phy_reg = (void __iomem *)phy_bases[index]; phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET; writel(USBPHY_CTRL_CLKGATE, phy_reg); } @@ -166,17 +160,12 @@ static void usb_power_config(int index) }
/* Return 0 : host node, <>0 : device mode */ -static int usb_phy_enable(int index, struct usb_ehci *ehci) +static int usb_phy_enable(struct usb_ehci *ehci, void __iomem *phy_reg) { - void __iomem *phy_reg; void __iomem *phy_ctrl; void __iomem *usb_cmd; int ret;
- if (index >= ARRAY_SIZE(phy_bases)) - return 0; - - phy_reg = (void __iomem *)phy_bases[index]; phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL); usb_cmd = (void __iomem *)&ehci->usbcmd;
@@ -368,8 +357,10 @@ int ehci_hcd_init(int index, enum usb_init_type init, usb_oc_config(index);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) - usb_internal_phy_clock_gate(index, 1); - usb_phy_enable(index, ehci); + if (index < ARRAY_SIZE(phy_bases)) { + usb_internal_phy_clock_gate((void __iomem *)phy_bases[index], 1); + usb_phy_enable(ehci, (void __iomem *)phy_bases[index]); + } #endif
type = board_usb_phy_mode(index); @@ -427,8 +418,8 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) usb_oc_config(priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) - usb_internal_phy_clock_gate(priv->portnr, 1); - usb_phy_enable(priv->portnr, ehci); + usb_internal_phy_clock_gate(priv->phy_addr, 1); + usb_phy_enable(ehci, priv->phy_addr); #endif
#if CONFIG_IS_ENABLED(DM_REGULATOR) @@ -672,8 +663,8 @@ static int ehci_usb_probe(struct udevice *dev) usb_oc_config(priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) - usb_internal_phy_clock_gate(priv->portnr, 1); - usb_phy_enable(priv->portnr, ehci); + usb_internal_phy_clock_gate(priv->phy_addr, 1); + usb_phy_enable(ehci, priv->phy_addr); #endif
#if CONFIG_IS_ENABLED(DM_REGULATOR)

Split usb_power_config() per SoC and pass in USB PHY, USBNC and ANATOP addresses instead of ad-hoc sequence numbers. This is only applicable on legacy systems which do not implement proper PHY support. Once PHY support is available, parts of this can be removed altogether and moved to the PHY driver, similar to Linux phy-mxs-usb.c .
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 127 ++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 49 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 800a25d1d9d..5001a8e74fb 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -86,43 +86,17 @@ struct usbnc_regs { u32 adp_status; };
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) -static const unsigned phy_bases[] = { - USB_PHY0_BASE_ADDR, -#if defined(USB_PHY1_BASE_ADDR) - USB_PHY1_BASE_ADDR, -#endif -}; - -static void usb_internal_phy_clock_gate(void __iomem *phy_reg, int on) -{ - phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET; - writel(USBPHY_CTRL_CLKGATE, phy_reg); -} - -static void usb_power_config(int index) +#if defined(CONFIG_MX6) +static void usb_power_config_mx6(void __iomem *anatop, int anatop_bits_index) { -#if defined(CONFIG_MX7ULP) - struct usbphy_regs __iomem *usbphy = - (struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR; - - if (index > 0) - return; - - writel(ANADIG_USB2_CHRG_DETECT_EN_B | - ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, - &usbphy->usb1_chrg_detect); - - scg_enable_usb_pll(true); - -#else - struct anatop_regs __iomem *anatop = - (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; void __iomem *chrg_detect; void __iomem *pll_480_ctrl_clr; void __iomem *pll_480_ctrl_set;
- switch (index) { + if (!is_mx6()) + return; + + switch (anatop_bits_index) { case 0: chrg_detect = &anatop->usb1_chrg_detect; pll_480_ctrl_clr = &anatop->usb1_pll_480_ctrl_clr; @@ -155,8 +129,51 @@ static void usb_power_config(int index) ANADIG_USB2_PLL_480_CTRL_POWER | ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, pll_480_ctrl_set); +} +#endif + +#if defined(CONFIG_MX7) +static void usb_power_config_mx7(struct usbnc_regs *usbnc) +{ + void __iomem *phy_cfg2 = (void __iomem *)(&usbnc->phy_cfg2); + + if (!is_mx7()) + return; + + /* + * Clear the ACAENB to enable usb_otg_id detection, + * otherwise it is the ACA detection enabled. + */ + clrbits_le32(phy_cfg2, USBNC_PHYCFG2_ACAENB); +} +#endif + +#if defined(CONFIG_MX7ULP) +static void usb_power_config_mx7ulp(struct usbphy_regs __iomem *usbphy) +{ + if (!is_mx7ulp()) + return; + + writel(ANADIG_USB2_CHRG_DETECT_EN_B | + ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, + &usbphy->usb1_chrg_detect); + + scg_enable_usb_pll(true); +} +#endif
+#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) +static const unsigned phy_bases[] = { + USB_PHY0_BASE_ADDR, +#if defined(USB_PHY1_BASE_ADDR) + USB_PHY1_BASE_ADDR, #endif +}; + +static void usb_internal_phy_clock_gate(void __iomem *phy_reg, int on) +{ + phy_reg += on ? USBPHY_CTRL_CLR : USBPHY_CTRL_SET; + writel(USBPHY_CTRL_CLKGATE, phy_reg); }
/* Return 0 : host node, <>0 : device mode */ @@ -215,19 +232,6 @@ int usb_phy_mode(int port) }
#elif defined(CONFIG_MX7) -static void usb_power_config(int index) -{ - struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + - (0x10000 * index) + USBNC_OFFSET); - void __iomem *phy_cfg2 = (void __iomem *)(&usbnc->phy_cfg2); - - /* - * Clear the ACAENB to enable usb_otg_id detection, - * otherwise it is the ACA detection enabled. - */ - clrbits_le32(phy_cfg2, USBNC_PHYCFG2_ACAENB); -} - int usb_phy_mode(int port) { struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + @@ -325,8 +329,16 @@ int ehci_hcd_init(int index, enum usb_init_type init, enum usb_init_type type; #if defined(CONFIG_MX6) u32 controller_spacing = 0x200; -#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP) + struct anatop_regs __iomem *anatop = + (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; +#elif defined(CONFIG_MX7) + u32 controller_spacing = 0x10000; + struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + + (0x10000 * index) + USBNC_OFFSET); +#elif defined(CONFIG_MX7ULP) u32 controller_spacing = 0x10000; + struct usbphy_regs __iomem *usbphy = + (struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR; #endif struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR + (controller_spacing * index)); @@ -353,7 +365,14 @@ int ehci_hcd_init(int index, enum usb_init_type init, return ret; }
- usb_power_config(index); +#if defined(CONFIG_MX6) + usb_power_config_mx6(anatop, index); +#elif defined (CONFIG_MX7) + usb_power_config_mx7(usbnc); +#elif defined (CONFIG_MX7ULP) + usb_power_config_mx7ulp(usbphy); +#endif + usb_oc_config(index);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) @@ -414,13 +433,18 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) struct usb_ehci *ehci = priv->ehci; int ret;
- usb_power_config(priv->portnr); +#if !defined(CONFIG_PHY) + usb_power_config_mx6(priv->anatop_addr, priv->portnr); + usb_power_config_mx7(priv->misc_addr); + usb_power_config_mx7ulp(priv->phy_addr); + usb_oc_config(priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) usb_internal_phy_clock_gate(priv->phy_addr, 1); usb_phy_enable(ehci, priv->phy_addr); #endif +#endif
#if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) { @@ -659,13 +683,18 @@ static int ehci_usb_probe(struct udevice *dev) debug("%s: No vbus supply\n", dev->name); #endif
- usb_power_config(priv->portnr); +#if !defined(CONFIG_PHY) + usb_power_config_mx6(priv->anatop_addr, priv->portnr); + usb_power_config_mx7(priv->usbnc); + usb_power_config_mx7ulp(priv->usbphy); + usb_oc_config(priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) usb_internal_phy_clock_gate(priv->phy_addr, 1); usb_phy_enable(ehci, priv->phy_addr); #endif +#endif
#if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) {

Instead of passing ad-hoc sequence number to usb_oc_config(), pass in the USB MISC address itself. The USB MISC address comes from DT in DM case, and from the old method using controller index in non-DM case.
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 5001a8e74fb..345be528739 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -248,15 +248,8 @@ int usb_phy_mode(int port) } #endif
-static void usb_oc_config(int index) +static void usb_oc_config(struct usbnc_regs *usbnc, int index) { -#if defined(CONFIG_MX6) - struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + - USB_OTHERREGS_OFFSET); -#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP) - struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + - (0x10000 * index) + USBNC_OFFSET); -#endif void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
#if CONFIG_MACH_TYPE == MACH_TYPE_MX6Q_ARM2 @@ -331,6 +324,8 @@ int ehci_hcd_init(int index, enum usb_init_type init, u32 controller_spacing = 0x200; struct anatop_regs __iomem *anatop = (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; + struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + + USB_OTHERREGS_OFFSET); #elif defined(CONFIG_MX7) u32 controller_spacing = 0x10000; struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + @@ -339,6 +334,8 @@ int ehci_hcd_init(int index, enum usb_init_type init, u32 controller_spacing = 0x10000; struct usbphy_regs __iomem *usbphy = (struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR; + struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR + + (0x10000 * index) + USBNC_OFFSET); #endif struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR + (controller_spacing * index)); @@ -373,7 +370,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, usb_power_config_mx7ulp(usbphy); #endif
- usb_oc_config(index); + usb_oc_config(usbnc, index);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) if (index < ARRAY_SIZE(phy_bases)) { @@ -438,7 +435,7 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) usb_power_config_mx7(priv->misc_addr); usb_power_config_mx7ulp(priv->phy_addr);
- usb_oc_config(priv->portnr); + usb_oc_config(priv->misc_addr, priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) usb_internal_phy_clock_gate(priv->phy_addr, 1); @@ -688,7 +685,7 @@ static int ehci_usb_probe(struct udevice *dev) usb_power_config_mx7(priv->usbnc); usb_power_config_mx7ulp(priv->usbphy);
- usb_oc_config(priv->portnr); + usb_oc_config(priv->misc_addr, priv->portnr);
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) usb_internal_phy_clock_gate(priv->phy_addr, 1);

In case of legacy platforms which do not implement PHY support, determine portnr from PHY node DT aliases, just like Linux does. This is not necessary in case PHY support is enabled and a PHY driver is available, so only enable the portnr handling for the legacy platforms.
Fixes: 4de51cc25b5 ("usb: ehci-mx6: Drop assignment of sequence number") Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 54 ++++++------------------------------- 1 file changed, 8 insertions(+), 46 deletions(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 345be528739..b1cc62fcc37 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -414,12 +414,12 @@ struct ehci_mx6_priv_data { struct udevice *vbus_supply; struct clk clk; enum usb_init_type init_type; - int portnr; #if !defined(CONFIG_PHY) /* Legacy iMX6/iMX7/iMX7ULP compat, they do not use PHY framework yet */ void __iomem *phy_addr; void __iomem *misc_addr; void __iomem *anatop_addr; + int portnr; #endif };
@@ -541,49 +541,6 @@ static int ehci_usb_of_to_plat(struct udevice *dev) return 0; }
-static int ehci_usb_bind(struct udevice *dev) -{ - /* - * TODO: - * This driver is only partly converted to DT probing and still uses - * a tremendous amount of hard-coded addresses. To make things worse, - * the driver depends on specific sequential indexing of controllers, - * from which it derives offsets in the PHY and ANATOP register sets. - * - * Here we attempt to calculate these indexes from DT information as - * well as we can. The USB controllers on all existing iMX6 SoCs - * are placed next to each other, at addresses incremented by 0x200, - * and iMX7 their addresses are shifted by 0x10000. - * Thus, the index is derived from the multiple of 0x200 (0x10000 for - * iMX7) offset from the first controller address. - * - * However, to complete conversion of this driver to DT probing, the - * following has to be done: - * - DM clock framework support for iMX must be implemented - * - usb_power_config() has to be converted to clock framework - * -> Thus, the ad-hoc "index" variable goes away. - * - USB PHY handling has to be factored out into separate driver - * -> Thus, the ad-hoc "index" variable goes away from the PHY - * code, the PHY driver must parse it's address from DT. This - * USB driver must find the PHY driver via DT phandle. - * -> usb_power_config() shall be moved to PHY driver - * With these changes in place, the ad-hoc indexing goes away and - * the driver is fully converted to DT probing. - */ - - /* - * FIXME: This cannot work with the new sequence numbers. - * Please complete the DM conversion. - * - * u32 controller_spacing = is_mx7() ? 0x10000 : 0x200; - * fdt_addr_t addr = devfdt_get_addr_index(dev, 0); - * - * dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing; - */ - - return 0; -} - static int mx6_parse_dt_addrs(struct udevice *dev) { #if !defined(CONFIG_PHY) @@ -596,11 +553,17 @@ static int mx6_parse_dt_addrs(struct udevice *dev) const void *blob = gd->fdt_blob; int offset = dev_of_offset(dev); void *__iomem addr; + int ret, devnump;
phy_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbphy"); if (phy_off < 0) return -EINVAL;
+ ret = fdtdec_get_alias_seq(blob, dev->uclass->uc_drv->name, + phy_off, &devnump); + if (ret < 0) + return ret; + misc_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbmisc"); if (misc_off < 0) return -EINVAL; @@ -610,6 +573,7 @@ static int mx6_parse_dt_addrs(struct udevice *dev) return -EINVAL;
priv->phy_addr = addr; + priv->portnr = devnump;
addr = (void __iomem *)fdtdec_get_addr(blob, misc_off, "reg"); if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) @@ -656,7 +620,6 @@ static int ehci_usb_probe(struct udevice *dev) return ret;
priv->ehci = ehci; - priv->portnr = dev_seq(dev); priv->init_type = type;
#if CONFIG_IS_ENABLED(CLK) @@ -766,7 +729,6 @@ U_BOOT_DRIVER(usb_mx6) = { .id = UCLASS_USB, .of_match = mx6_usb_ids, .of_to_plat = ehci_usb_of_to_plat, - .bind = ehci_usb_bind, .probe = ehci_usb_probe, .remove = ehci_usb_remove, .ops = &ehci_usb_ops,

In case PHY support is enabled, use the generic EHCI PHY support to start and stop the PHY.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index b1cc62fcc37..855a1bdaaa2 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -413,6 +413,7 @@ struct ehci_mx6_priv_data { struct usb_ehci *ehci; struct udevice *vbus_supply; struct clk clk; + struct phy phy; enum usb_init_type init_type; #if !defined(CONFIG_PHY) /* Legacy iMX6/iMX7/iMX7ULP compat, they do not use PHY framework yet */ @@ -676,16 +677,26 @@ static int ehci_usb_probe(struct udevice *dev)
mdelay(10);
+#if defined(CONFIG_PHY) + ret = ehci_setup_phy(dev, &priv->phy, 0); + if (ret) + goto err_regulator; +#endif + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); hcor = (struct ehci_hcor *)((uint32_t)hccr + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
ret = ehci_register(dev, hccr, hcor, &mx6_ehci_ops, 0, priv->init_type); if (ret) - goto err_regulator; + goto err_phy;
return ret;
+err_phy: +#if defined(CONFIG_PHY) + ehci_shutdown_phy(dev, &priv->phy); +#endif err_regulator: #if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) @@ -707,6 +718,10 @@ int ehci_usb_remove(struct udevice *dev)
ehci_deregister(dev);
+#if defined(CONFIG_PHY) + ehci_shutdown_phy(dev, &priv->phy); +#endif + #if CONFIG_IS_ENABLED(DM_REGULATOR) if (priv->vbus_supply) regulator_set_enable(priv->vbus_supply, false);

Add new compatible string, used by some more up-to-date DTs.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/ehci-mx6.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 855a1bdaaa2..c218bdc0574 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -736,6 +736,7 @@ int ehci_usb_remove(struct udevice *dev)
static const struct udevice_id mx6_usb_ids[] = { { .compatible = "fsl,imx27-usb" }, + { .compatible = "fsl,imx7d-usb" }, { } };

The iMX8M uses nop PHY, select PHY and NOP_PHY automatically. Otherwise, the DM capable driver is now perfectly compatible.
Signed-off-by: Marek Vasut marex@denx.de Cc: Fabio Estevam festevam@gmail.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com --- drivers/usb/host/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0971a7c8139..a51183d4d3c 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -156,7 +156,9 @@ config USB_EHCI_MX6
config USB_EHCI_MX7 bool "Support for i.MX7 on-chip EHCI USB controller" - depends on ARCH_MX7 + depends on ARCH_MX7 || IMX8MM + select PHY if IMX8MM + select NOP_PHY if IMX8MM default y ---help--- Enables support for the on-chip EHCI controller on i.MX7 SoCs.

Enable USB host support on MX8MM Verdin.
Signed-off-by: Marek Vasut marex@denx.de Cc: Marcel Ziswiler marcel.ziswiler@toradex.com Cc: Max Krummenacher max.krummenacher@toradex.com Cc: Oleksandr Suvorov oleksandr.suvorov@toradex.com --- configs/verdin-imx8mm_defconfig | 8 +++++++- include/configs/verdin-imx8mm.h | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig index ea0b5978f1f..c8c3420b6a5 100644 --- a/configs/verdin-imx8mm_defconfig +++ b/configs/verdin-imx8mm_defconfig @@ -37,7 +37,6 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_POWER_SUPPORT=y -CONFIG_SPL_USB_HOST_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SYS_PROMPT="Verdin iMX8MM # " # CONFIG_BOOTM_NETBSD is not set @@ -50,6 +49,7 @@ CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y CONFIG_CMD_CACHE=y CONFIG_CMD_UUID=y CONFIG_CMD_REGULATOR=y @@ -89,6 +89,8 @@ CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8M_POWER_DOMAIN=y CONFIG_DM_PMIC=y CONFIG_SPL_DM_PMIC_PCA9450=y CONFIG_DM_PMIC_PFUZE100=y @@ -101,5 +103,9 @@ CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +# CONFIG_SPL_DM_USB is not set +CONFIG_USB_EHCI_HCD=y CONFIG_IMX_WATCHDOG=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/verdin-imx8mm.h b/include/configs/verdin-imx8mm.h index 4751bf5a5af..e3ba08dc69c 100644 --- a/include/configs/verdin-imx8mm.h +++ b/include/configs/verdin-imx8mm.h @@ -117,5 +117,11 @@ #define FEC_QUIRK_ENET_MAC #define IMX_FEC_BASE 0x30BE0000
+/* USB Configs */ +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#define CONFIG_MXC_USB_FLAGS 0 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 + #endif /*_VERDIN_IMX8MM_H */

On Fri, Apr 2, 2021 at 3:52 PM Marek Vasut marex@denx.de wrote:
Enable USB host support on MX8MM Verdin.
Signed-off-by: Marek Vasut marex@denx.de
Reviewed-by: Oleksandr Suvorov oleksandr.suvorov@toradex.com
Cc: Marcel Ziswiler marcel.ziswiler@toradex.com Cc: Max Krummenacher max.krummenacher@toradex.com Cc: Oleksandr Suvorov oleksandr.suvorov@toradex.com
configs/verdin-imx8mm_defconfig | 8 +++++++- include/configs/verdin-imx8mm.h | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig index ea0b5978f1f..c8c3420b6a5 100644 --- a/configs/verdin-imx8mm_defconfig +++ b/configs/verdin-imx8mm_defconfig @@ -37,7 +37,6 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_POWER_SUPPORT=y -CONFIG_SPL_USB_HOST_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SYS_PROMPT="Verdin iMX8MM # " # CONFIG_BOOTM_NETBSD is not set @@ -50,6 +49,7 @@ CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y CONFIG_CMD_CACHE=y CONFIG_CMD_UUID=y CONFIG_CMD_REGULATOR=y @@ -89,6 +89,8 @@ CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8M_POWER_DOMAIN=y CONFIG_DM_PMIC=y CONFIG_SPL_DM_PMIC_PCA9450=y CONFIG_DM_PMIC_PFUZE100=y @@ -101,5 +103,9 @@ CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +# CONFIG_SPL_DM_USB is not set +CONFIG_USB_EHCI_HCD=y CONFIG_IMX_WATCHDOG=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/verdin-imx8mm.h b/include/configs/verdin-imx8mm.h index 4751bf5a5af..e3ba08dc69c 100644 --- a/include/configs/verdin-imx8mm.h +++ b/include/configs/verdin-imx8mm.h @@ -117,5 +117,11 @@ #define FEC_QUIRK_ENET_MAC #define IMX_FEC_BASE 0x30BE0000
+/* USB Configs */ +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#define CONFIG_MXC_USB_FLAGS 0 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#endif /*_VERDIN_IMX8MM_H */
-- 2.30.2

Hi Marek
Upon compiling I noticed the following but I do realize that it is not this patch set which introduced this issue.
drivers/usb/host/ehci-mx6.c: In function ‘ehci_usb_probe’: drivers/usb/host/ehci-mx6.c:686:30: warning: cast from pointer to integer of different size [-Wpointer-to-int- cast] 686 | hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); | ^ drivers/usb/host/ehci-mx6.c:686:9: warning: cast to pointer from integer of different size [-Wint-to-pointer- cast] 686 | hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); | ^ drivers/usb/host/ehci-mx6.c:687:30: warning: cast from pointer to integer of different size [-Wpointer-to-int- cast] 687 | hcor = (struct ehci_hcor *)((uint32_t)hccr + | ^ drivers/usb/host/ehci-mx6.c:687:9: warning: cast to pointer from integer of different size [-Wint-to-pointer- cast] 687 | hcor = (struct ehci_hcor *)((uint32_t)hccr + | ^ At top level: drivers/usb/host/ehci-mx6.c:251:13: warning: ‘usb_oc_config’ defined but not used [-Wunused-function] 251 | static void usb_oc_config(struct usbnc_regs *usbnc, int index) | ^~~~~~~~~~~~~
Then upon booting I noticed the following two issues. Did you also see that?
write error to device: 930f90 register: x!write error to device: 930f90 register: x!write error to device: 930f90 register: x!write error to device: 930f90 register: x!Normal Boot
imx_wdt watchdog@30280000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19
Anyway, the USB host stuff this patch is about works perfectly. Thanks!
Cheers
Marcel
On Fri, 2021-04-02 at 14:48 +0200, Marek Vasut wrote:
Enable USB host support on MX8MM Verdin.
Signed-off-by: Marek Vasut marex@denx.de Cc: Marcel Ziswiler marcel.ziswiler@toradex.com
Whole patch set (BTW: you don't like cover letters?).
Tested-by: Marcel Ziswiler marcel.ziswiler@toradex.com # Verdin iMX8M Mini V1.0B and V1.1A
Cc: Max Krummenacher max.krummenacher@toradex.com Cc: Oleksandr Suvorov oleksandr.suvorov@toradex.com
configs/verdin-imx8mm_defconfig | 8 +++++++- include/configs/verdin-imx8mm.h | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/configs/verdin-imx8mm_defconfig b/configs/verdin-imx8mm_defconfig index ea0b5978f1f..c8c3420b6a5 100644 --- a/configs/verdin-imx8mm_defconfig +++ b/configs/verdin-imx8mm_defconfig @@ -37,7 +37,6 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_POWER_SUPPORT=y -CONFIG_SPL_USB_HOST_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SYS_PROMPT="Verdin iMX8MM # " # CONFIG_BOOTM_NETBSD is not set @@ -50,6 +49,7 @@ CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y CONFIG_CMD_CACHE=y CONFIG_CMD_UUID=y CONFIG_CMD_REGULATOR=y @@ -89,6 +89,8 @@ CONFIG_MII=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8M_POWER_DOMAIN=y CONFIG_DM_PMIC=y CONFIG_SPL_DM_PMIC_PCA9450=y CONFIG_DM_PMIC_PFUZE100=y @@ -101,5 +103,9 @@ CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB=y +# CONFIG_SPL_DM_USB is not set +CONFIG_USB_EHCI_HCD=y CONFIG_IMX_WATCHDOG=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/verdin-imx8mm.h b/include/configs/verdin-imx8mm.h index 4751bf5a5af..e3ba08dc69c 100644 --- a/include/configs/verdin-imx8mm.h +++ b/include/configs/verdin-imx8mm.h @@ -117,5 +117,11 @@ #define FEC_QUIRK_ENET_MAC #define IMX_FEC_BASE 0x30BE0000 +/* USB Configs */ +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) +#define CONFIG_MXC_USB_FLAGS 0 +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#endif /*_VERDIN_IMX8MM_H */

On 4/8/21 9:08 AM, Marcel Ziswiler wrote:
Hi Marek
Hi,
Upon compiling I noticed the following but I do realize that it is not this patch set which introduced this issue.
drivers/usb/host/ehci-mx6.c: In function ‘ehci_usb_probe’: drivers/usb/host/ehci-mx6.c:686:30: warning: cast from pointer to integer of different size [-Wpointer-to-int- cast] 686 | hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
That's easy enough to fix.
[...]
Then upon booting I noticed the following two issues. Did you also see that?
write error to device: 930f90 register: x!write error to device: 930f90 register: x!write error to device: 930f90 register: x!write error to device: 930f90 register: x!Normal Boot
imx_wdt watchdog@30280000: pinctrl_select_state_full: uclass_get_device_by_phandle_id: err=-19
I suspect this has nothing to do with USB, but rather PMIC and then WDT?
Anyway, the USB host stuff this patch is about works perfectly. Thanks!
Great. Except V2 as soon as I sort out a few remaining CI issues.

On Fri, 2021-04-02 at 14:47 +0200, Marek Vasut wrote:
The USB no-op PHY uses "usb-nop-xceiv" compatible string. This driver is compatible with USB no-op PHY, so add the compatible string.
Signed-off-by: Marek Vasut marex@denx.de Cc: Alexey Brodkin alexey.brodkin@synopsys.com Cc: Eugeniy Paltsev Eugeniy.Paltsev@synopsys.com Cc: Fabio Estevam festevam@gmail.com Cc: Jean-Jacques Hiblot jjhiblot@ti.com Cc: Murali Karicheri m-karicheri2@ti.com Cc: Peng Fan peng.fan@nxp.com Cc: Stefano Babic sbabic@denx.de Cc: Ye Li ye.li@nxp.com Cc: uboot-imx uboot-imx@nxp.com
drivers/phy/nop-phy.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c index 84aac806230..9f12ebc0624 100644 --- a/drivers/phy/nop-phy.c +++ b/drivers/phy/nop-phy.c @@ -43,6 +43,7 @@ static int nop_phy_probe(struct udevice *dev) static const struct udevice_id nop_phy_ids[] = { { .compatible = "nop-phy" }, + { .compatible = "usb-nop-xceiv" }, { } };
Hi Marek,
I've tested this patch series on my IMX8MN board, the USB host functionality works!
For other IMX8MN users who want to test this:
Add IMX8MN to the Kconfig:
--- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -156,7 +156,7 @@ config USB_EHCI_MX6
config USB_EHCI_MX7 bool "Support for i.MX7 on-chip EHCI USB controller" - depends on ARCH_MX7 || IMX8MM + depends on ARCH_MX7 || IMX8MM || IMX8MN
And add the following to your board header:
#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
Kind regards, Harm Berntsen

On 4/6/21 9:34 PM, Harm Berntsen wrote: [...]
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c index 84aac806230..9f12ebc0624 100644 --- a/drivers/phy/nop-phy.c +++ b/drivers/phy/nop-phy.c @@ -43,6 +43,7 @@ static int nop_phy_probe(struct udevice *dev)
static const struct udevice_id nop_phy_ids[] = { { .compatible = "nop-phy" }, + { .compatible = "usb-nop-xceiv" }, { } };
Hi Marek,
I've tested this patch series on my IMX8MN board, the USB host functionality works!
For other IMX8MN users who want to test this:
Add IMX8MN to the Kconfig:
--- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -156,7 +156,7 @@ config USB_EHCI_MX6
config USB_EHCI_MX7 bool "Support for i.MX7 on-chip EHCI USB controller"
depends on ARCH_MX7 || IMX8MM
depends on ARCH_MX7 || IMX8MM || IMX8MN
And add the following to your board header:
#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
Nice. I still need to sort out a few details regarding the older MX6/7, so expect a V2. Once that's out, feel free to submit a patch adding MX8MN too.
participants (5)
-
Harm Berntsen
-
Jaehoon Chung
-
Marcel Ziswiler
-
Marek Vasut
-
Oleksandr Suvorov