[PATCH 0/6] i.MXRT1050 add Usb Host support

This patchset adds Usb Host support for imxrt1050-evk board adjusting the compatible driver ehci-mx6. This allows to read a FAT usb key connected to usbotg1 port of imxrt1050-evk board.
Giulio Benetti (6): ARM: IMXRT: introduce is_imxrt*() macros and get_cpu_rev() clk: imx: clk-imxrt1050: introduce IMXRT1050_CLK_USBOH3 usb: ehci-mx6: add support for i.MXRT ARM: dts: imxrt1050: add usbotg1, usbphy1 and usbmisc nodes ARM: dts: imxrt1050-evk: enable usbotg1 node as host configs: imxrt1050-evk: enable host usb support and its command
arch/arm/dts/imxrt1050-evk.dts | 5 ++++ arch/arm/dts/imxrt1050.dtsi | 27 +++++++++++++++++++++ arch/arm/include/asm/arch-imx/cpu.h | 3 +++ arch/arm/include/asm/arch-imxrt/imx-regs.h | 4 +++ arch/arm/include/asm/mach-imx/sys_proto.h | 4 +++ arch/arm/mach-imx/imxrt/soc.c | 12 +++++++++ configs/imxrt1050-evk_defconfig | 7 +++++- drivers/clk/imx/clk-imxrt1050.c | 2 ++ drivers/usb/host/Kconfig | 2 +- drivers/usb/host/ehci-mx6.c | 13 +++++----- include/dt-bindings/clock/imxrt1050-clock.h | 3 ++- 11 files changed, 73 insertions(+), 9 deletions(-)

We need those macros to instruct drivers on how to behave for SoC specific quirks, so let's add it as done for other i.MX SoCs.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/include/asm/arch-imx/cpu.h | 3 +++ arch/arm/include/asm/mach-imx/sys_proto.h | 4 ++++ arch/arm/mach-imx/imxrt/soc.c | 12 ++++++++++++ 3 files changed, 19 insertions(+)
diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index bb13e07b66..267a094e5a 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -50,6 +50,8 @@ #define MXC_CPU_IMX8QXP_A0 0x90 /* dummy ID */ #define MXC_CPU_IMX8QM 0x91 /* dummy ID */ #define MXC_CPU_IMX8QXP 0x92 /* dummy ID */ +#define MXC_CPU_IMXRT1020 0xB4 /* dummy ID */ +#define MXC_CPU_IMXRT1050 0xB6 /* dummy ID */ #define MXC_CPU_MX7ULP 0xE1 /* Temporally hard code */ #define MXC_CPU_VF610 0xF6 /* dummy ID */
@@ -57,6 +59,7 @@ #define MXC_SOC_MX7 0x70 #define MXC_SOC_IMX8M 0x80 #define MXC_SOC_IMX8 0x90 /* dummy */ +#define MXC_SOC_IMXRT 0xB0 /* dummy */ #define MXC_SOC_MX7ULP 0xE0 /* dummy */
#define CHIP_REV_1_0 0x10 diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index c7668ffc4d..b612189849 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -31,6 +31,7 @@ struct bd_info; #define is_mx7() (is_soc_type(MXC_SOC_MX7)) #define is_imx8m() (is_soc_type(MXC_SOC_IMX8M)) #define is_imx8() (is_soc_type(MXC_SOC_IMX8)) +#define is_imxrt() (is_soc_type(MXC_SOC_IMXRT))
#define is_mx6dqp() (is_cpu_type(MXC_CPU_MX6QP) || is_cpu_type(MXC_CPU_MX6DP)) #define is_mx6dq() (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) @@ -78,6 +79,9 @@ struct bd_info;
#define is_imx8qxp() (is_cpu_type(MXC_CPU_IMX8QXP))
+#define is_imxrt1020() (is_cpu_type(MXC_CPU_IMXRT1020)) +#define is_imxrt1050() (is_cpu_type(MXC_CPU_IMXRT1050)) + #ifdef CONFIG_MX6 #define IMX6_SRC_GPR10_BMODE BIT(28) #define IMX6_SRC_GPR10_PERSIST_SECONDARY_BOOT BIT(30) diff --git a/arch/arm/mach-imx/imxrt/soc.c b/arch/arm/mach-imx/imxrt/soc.c index c533f3554a..ba015992ee 100644 --- a/arch/arm/mach-imx/imxrt/soc.c +++ b/arch/arm/mach-imx/imxrt/soc.c @@ -8,6 +8,7 @@ #include <init.h> #include <asm/io.h> #include <asm/armv7_mpu.h> +#include <asm/mach-imx/sys_proto.h> #include <linux/bitops.h>
int arch_cpu_init(void) @@ -35,3 +36,14 @@ int arch_cpu_init(void)
return 0; } + +u32 get_cpu_rev(void) +{ +#if defined(CONFIG_IMXRT1020) + return MXC_CPU_IMXRT1020 << 12; +#elif defined(CONFIG_IMXRT1050) + return MXC_CPU_IMXRT1050 << 12; +#else +#error This IMXRT SoC is not supported +#endif +}

We need those macros to instruct drivers on how to behave for SoC specific quirks, so let's add it as done for other i.MX SoCs. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Usb needs IMXRT1050_CLK_USBOH3 clock to be enabled, so let's add it to clock driver.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- drivers/clk/imx/clk-imxrt1050.c | 2 ++ include/dt-bindings/clock/imxrt1050-clock.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c index eb6847f865..3e17161002 100644 --- a/drivers/clk/imx/clk-imxrt1050.c +++ b/drivers/clk/imx/clk-imxrt1050.c @@ -259,6 +259,8 @@ static int imxrt1050_clk_probe(struct udevice *dev) imx_clk_gate2("lcdif", "lcdif_podf", base + 0x70, 28)); clk_dm(IMXRT1050_CLK_LCDIF_PIX, imx_clk_gate2("lcdif_pix", "lcdif", base + 0x74, 10)); + clk_dm(IMXRT1050_CLK_USBOH3, + imx_clk_gate2("usboh3", "pll3_usb_otg", base + 0x80, 0));
struct clk *clk, *clk1;
diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h index 09b65e5df2..f74dbbcf93 100644 --- a/include/dt-bindings/clock/imxrt1050-clock.h +++ b/include/dt-bindings/clock/imxrt1050-clock.h @@ -61,6 +61,7 @@ #define IMXRT1050_CLK_PLL6_ENET 52 #define IMXRT1050_CLK_PLL7_USB_HOST 53 #define IMXRT1050_CLK_LCDIF_PIX 54 -#define IMXRT1050_CLK_END 55 +#define IMXRT1050_CLK_USBOH3 55 +#define IMXRT1050_CLK_END 56
#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */

Usb needs IMXRT1050_CLK_USBOH3 clock to be enabled, so let's add it to clock driver. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Add support for usb1 and usb2 present on i.IMXRT.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/include/asm/arch-imxrt/imx-regs.h | 4 ++++ drivers/usb/host/Kconfig | 2 +- drivers/usb/host/ehci-mx6.c | 13 +++++++------ 3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/arch-imxrt/imx-regs.h b/arch/arm/include/asm/arch-imxrt/imx-regs.h index 44c95dcd11..d01e6ca2e0 100644 --- a/arch/arm/include/asm/arch-imxrt/imx-regs.h +++ b/arch/arm/include/asm/arch-imxrt/imx-regs.h @@ -23,4 +23,8 @@ #include <asm/mach-imx/regs-lcdif.h> #endif
+#define USB_BASE_ADDR 0x402E0000 +#define USB_PHY0_BASE_ADDR 0x400D9000 +#define USB_PHY1_BASE_ADDR 0x400DA000 + #endif /* __ASM_ARCH_IMX_REGS_H__ */ diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bf5d82f035..f34cba2395 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -149,7 +149,7 @@ config USB_EHCI_MX5
config USB_EHCI_MX6 bool "Support for i.MX6/i.MX7ULP on-chip EHCI USB controller" - depends on ARCH_MX6 || ARCH_MX7ULP + depends on ARCH_MX6 || ARCH_MX7ULP || ARCH_IMXRT default y ---help--- Enables support for the on-chip EHCI controller on i.MX6 SoCs. diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 06be9deaaa..238c93183b 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -177,7 +177,7 @@ static void __maybe_unused usb_power_config_mx7ulp(void *usbphy) { } #endif
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) static const unsigned phy_bases[] = { USB_PHY0_BASE_ADDR, #if defined(USB_PHY1_BASE_ADDR) @@ -340,7 +340,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { enum usb_init_type type; -#if defined(CONFIG_MX6) +#if defined(CONFIG_MX6) || defined(CONFIG_IMXRT) u32 controller_spacing = 0x200; struct anatop_regs __iomem *anatop = (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; @@ -382,7 +382,7 @@ int ehci_hcd_init(int index, enum usb_init_type init, return ret; }
-#if defined(CONFIG_MX6) +#if defined(CONFIG_MX6) || defined(CONFIG_IMXRT) usb_power_config_mx6(anatop, index); #elif defined (CONFIG_MX7) usb_power_config_mx7(usbnc); @@ -392,7 +392,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
usb_oc_config(usbnc, index);
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) 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]); @@ -504,7 +504,7 @@ static int ehci_usb_phy_mode(struct udevice *dev) * About fsl,usbphy, Refer to * Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt. */ - if (is_mx6() || is_mx7ulp()) { + if (is_mx6() || is_mx7ulp() || is_imxrt()) { phy_off = fdtdec_lookup_phandle(blob, offset, "fsl,usbphy"); @@ -671,7 +671,7 @@ static int ehci_usb_probe(struct udevice *dev)
usb_oc_config(priv->misc_addr, priv->portnr);
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) usb_internal_phy_clock_gate(priv->phy_addr, 1); usb_phy_enable(ehci, priv->phy_addr); #endif @@ -757,6 +757,7 @@ int ehci_usb_remove(struct udevice *dev) static const struct udevice_id mx6_usb_ids[] = { { .compatible = "fsl,imx27-usb" }, { .compatible = "fsl,imx7d-usb" }, + { .compatible = "fsl,imxrt-usb" }, { } };

On 5/20/21 4:10 PM, Giulio Benetti wrote:
[...]
diff --git a/arch/arm/include/asm/arch-imxrt/imx-regs.h b/arch/arm/include/asm/arch-imxrt/imx-regs.h index 44c95dcd11..d01e6ca2e0 100644 --- a/arch/arm/include/asm/arch-imxrt/imx-regs.h +++ b/arch/arm/include/asm/arch-imxrt/imx-regs.h @@ -23,4 +23,8 @@ #include <asm/mach-imx/regs-lcdif.h> #endif
+#define USB_BASE_ADDR 0x402E0000 +#define USB_PHY0_BASE_ADDR 0x400D9000 +#define USB_PHY1_BASE_ADDR 0x400DA000
This should come from the DT, see how iMX8M was implemented and drop this.
#endif /* __ASM_ARCH_IMX_REGS_H__ */ diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index bf5d82f035..f34cba2395 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -149,7 +149,7 @@ config USB_EHCI_MX5
config USB_EHCI_MX6 bool "Support for i.MX6/i.MX7ULP on-chip EHCI USB controller"
- depends on ARCH_MX6 || ARCH_MX7ULP
- depends on ARCH_MX6 || ARCH_MX7ULP || ARCH_IMXRT default y ---help--- Enables support for the on-chip EHCI controller on i.MX6 SoCs.
diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 06be9deaaa..238c93183b 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -177,7 +177,7 @@ static void __maybe_unused usb_power_config_mx7ulp(void *usbphy) { } #endif
-#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) +#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP) || defined(CONFIG_IMXRT) static const unsigned phy_bases[] = { USB_PHY0_BASE_ADDR, #if defined(USB_PHY1_BASE_ADDR)
All this non-DT code will go away soon, use the DT-based probing, like MX8M does.
[...]

Add support for usb1 and usb2 present on i.IMXRT. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Usb is now supported so add all required nodes for it in imxrt1050.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050.dtsi | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/arch/arm/dts/imxrt1050.dtsi b/arch/arm/dts/imxrt1050.dtsi index ec1eb88e45..6814352d9a 100644 --- a/arch/arm/dts/imxrt1050.dtsi +++ b/arch/arm/dts/imxrt1050.dtsi @@ -23,6 +23,7 @@ gpio4 = &gpio5; mmc0 = &usdhc1; serial0 = &lpuart1; + usbphy0 = &usbphy1; };
clocks { @@ -165,5 +166,31 @@ clocks = <&osc>; status = "disabled"; }; + + usbphy1: usbphy@400d9000 { + compatible = "fsl,imxrt-usbphy"; + reg = <0x400d9000 0x1000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + }; + + usbmisc: usbmisc@402e0800 { + #index-cells = <1>; + compatible = "fsl,imxrt-usbmisc"; + reg = <0x402e0800 0x200>; + clocks = <&clks IMXRT1050_CLK_USBOH3>; + }; + + usbotg1: usb@402e0000 { + compatible = "fsl,imxrt-usb", "fsl,imx27-usb"; + reg = <0x402e0000 0x200>; + interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMXRT1050_CLK_USBOH3>; + fsl,usbphy = <&usbphy1>; + fsl,usbmisc = <&usbmisc 0>; + ahb-burst-config = <0x0>; + tx-burst-size-dword = <0x10>; + rx-burst-size-dword = <0x10>; + status = "disabled"; + }; }; };

On 5/20/21 4:10 PM, Giulio Benetti wrote:
[...]
@@ -165,5 +166,31 @@ clocks = <&osc>; status = "disabled"; };
usbphy1: usbphy@400d9000 {
compatible = "fsl,imxrt-usbphy";
Is there a PHY driver which can match on this compatible ?
reg = <0x400d9000 0x1000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
};
usbmisc: usbmisc@402e0800 {
#index-cells = <1>;
compatible = "fsl,imxrt-usbmisc";
reg = <0x402e0800 0x200>;
clocks = <&clks IMXRT1050_CLK_USBOH3>;
};
usbotg1: usb@402e0000 {
compatible = "fsl,imxrt-usb", "fsl,imx27-usb";
reg = <0x402e0000 0x200>;
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMXRT1050_CLK_USBOH3>;
fsl,usbphy = <&usbphy1>;
Use phys = <...> .

Usb is now supported so add all required nodes for it in imxrt1050. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Enable usbotg1 port node as host usb.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- arch/arm/dts/imxrt1050-evk.dts | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm/dts/imxrt1050-evk.dts b/arch/arm/dts/imxrt1050-evk.dts index 81db1a446d..324cf7af96 100644 --- a/arch/arm/dts/imxrt1050-evk.dts +++ b/arch/arm/dts/imxrt1050-evk.dts @@ -260,3 +260,8 @@ }; }; }; + +&usbotg1 { + dr_mode = "host"; + status = "okay"; +};

Enable usbotg1 port node as host usb. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic

Now that usb host is supported let's enable it on this board.
Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com --- configs/imxrt1050-evk_defconfig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/configs/imxrt1050-evk_defconfig b/configs/imxrt1050-evk_defconfig index 9c8bdb07dc..9f509f3b9f 100644 --- a/configs/imxrt1050-evk_defconfig +++ b/configs/imxrt1050-evk_defconfig @@ -32,8 +32,9 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x100 # CONFIG_BOOTM_PLAN9 is not set # CONFIG_BOOTM_RTEMS is not set # CONFIG_BOOTM_VXWORKS is not set +CONFIG_CMD_USB=y # CONFIG_CMD_MII is not set -# CONFIG_DOS_PARTITION is not set +# CONFIG_SPL_DOS_PARTITION is not set # CONFIG_ISO_PARTITION is not set # CONFIG_EFI_PARTITION is not set CONFIG_OF_CONTROL=y @@ -65,6 +66,10 @@ CONFIG_FSL_LPUART=y CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_IMX_GPT_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB=y +# CONFIG_SPL_DM_USB is not set +CONFIG_USB_EHCI_HCD=y CONFIG_DM_VIDEO=y CONFIG_BACKLIGHT_GPIO=y CONFIG_SYS_WHITE_ON_BLACK=y

Now that usb host is supported let's enable it on this board. Signed-off-by: Giulio Benetti giulio.benetti@benettiengineering.com
Applied to u-boot-imx, master, thanks !
Best regards, Stefano Babic
participants (3)
-
Giulio Benetti
-
Marek Vasut
-
sbabic@denx.de