diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/imx/Makefile | 5 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8.c | 298 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8.h | 19 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8qm.c | 307 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8qxp.c | 311 | ||||
-rw-r--r-- | drivers/ddr/imx/imx8m/Kconfig | 4 | ||||
-rw-r--r-- | drivers/misc/imx8/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/imx8/fuse.c | 86 | ||||
-rw-r--r-- | drivers/misc/imx8/scu.c | 16 | ||||
-rw-r--r-- | drivers/misc/mxc_ocotp.c | 23 | ||||
-rw-r--r-- | drivers/pinctrl/nxp/pinctrl-imx8.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 7 | ||||
-rw-r--r-- | drivers/usb/host/ehci-mx5.c | 103 |
13 files changed, 882 insertions, 299 deletions
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 5505ae52e2..eb379c188a 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -3,3 +3,8 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CLK_IMX8) += clk-imx8.o + +ifdef CONFIG_CLK_IMX8 +obj-$(CONFIG_IMX8QXP) += clk-imx8qxp.o +obj-$(CONFIG_IMX8QM) += clk-imx8qm.o +endif diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c index d03fcc2fdd..a755e26501 100644 --- a/drivers/clk/imx/clk-imx8.c +++ b/drivers/clk/imx/clk-imx8.c @@ -13,302 +13,21 @@ #include <dt-bindings/soc/imx_rsrc.h> #include <misc.h> -struct imx8_clks { - ulong id; - const char *name; -}; - -#if CONFIG_IS_ENABLED(CMD_CLK) -static struct imx8_clks imx8_clk_names[] = { - { IMX8QXP_A35_DIV, "A35_DIV" }, - { IMX8QXP_I2C0_CLK, "I2C0" }, - { IMX8QXP_I2C1_CLK, "I2C1" }, - { IMX8QXP_I2C2_CLK, "I2C2" }, - { IMX8QXP_I2C3_CLK, "I2C3" }, - { IMX8QXP_UART0_CLK, "UART0" }, - { IMX8QXP_UART1_CLK, "UART1" }, - { IMX8QXP_UART2_CLK, "UART2" }, - { IMX8QXP_UART3_CLK, "UART3" }, - { IMX8QXP_SDHC0_CLK, "SDHC0" }, - { IMX8QXP_SDHC1_CLK, "SDHC1" }, - { IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" }, - { IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" }, - { IMX8QXP_ENET0_REF_DIV, "ENET0_REF" }, - { IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" }, - { IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" }, - { IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" }, - { IMX8QXP_ENET1_REF_DIV, "ENET1_REF" }, - { IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" }, -}; -#endif +#include "clk-imx8.h" -static ulong imx8_clk_get_rate(struct clk *clk) +__weak ulong imx8_clk_get_rate(struct clk *clk) { - sc_pm_clk_t pm_clk; - ulong rate; - u16 resource; - int ret; - - debug("%s(#%lu)\n", __func__, clk->id); - - switch (clk->id) { - case IMX8QXP_A35_DIV: - resource = SC_R_A35; - pm_clk = SC_PM_CLK_CPU; - break; - case IMX8QXP_I2C0_CLK: - resource = SC_R_I2C_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C1_CLK: - resource = SC_R_I2C_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C2_CLK: - resource = SC_R_I2C_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C3_CLK: - resource = SC_R_I2C_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC0_IPG_CLK: - case IMX8QXP_SDHC0_CLK: - case IMX8QXP_SDHC0_DIV: - resource = SC_R_SDHC_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC1_IPG_CLK: - case IMX8QXP_SDHC1_CLK: - case IMX8QXP_SDHC1_DIV: - resource = SC_R_SDHC_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART0_IPG_CLK: - case IMX8QXP_UART0_CLK: - resource = SC_R_UART_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART1_CLK: - resource = SC_R_UART_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART2_CLK: - resource = SC_R_UART_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART3_CLK: - resource = SC_R_UART_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET0_IPG_CLK: - case IMX8QXP_ENET0_AHB_CLK: - case IMX8QXP_ENET0_REF_DIV: - case IMX8QXP_ENET0_PTP_CLK: - resource = SC_R_ENET_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET1_IPG_CLK: - case IMX8QXP_ENET1_AHB_CLK: - case IMX8QXP_ENET1_REF_DIV: - case IMX8QXP_ENET1_PTP_CLK: - resource = SC_R_ENET_1; - pm_clk = SC_PM_CLK_PER; - break; - default: - if (clk->id < IMX8QXP_UART0_IPG_CLK || - clk->id >= IMX8QXP_CLK_END) { - printf("%s(Invalid clk ID #%lu)\n", - __func__, clk->id); - return -EINVAL; - } - return -ENOTSUPP; - }; - - ret = sc_pm_get_clock_rate(-1, resource, pm_clk, - (sc_pm_clock_rate_t *)&rate); - if (ret) { - printf("%s err %d\n", __func__, ret); - return ret; - } - - return rate; + return 0; } -static ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) +__weak ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) { - sc_pm_clk_t pm_clk; - u32 new_rate = rate; - u16 resource; - int ret; - - debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); - - switch (clk->id) { - case IMX8QXP_I2C0_CLK: - resource = SC_R_I2C_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C1_CLK: - resource = SC_R_I2C_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C2_CLK: - resource = SC_R_I2C_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C3_CLK: - resource = SC_R_I2C_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART0_CLK: - resource = SC_R_UART_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART1_CLK: - resource = SC_R_UART_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART2_CLK: - resource = SC_R_UART_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART3_CLK: - resource = SC_R_UART_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC0_IPG_CLK: - case IMX8QXP_SDHC0_CLK: - case IMX8QXP_SDHC0_DIV: - resource = SC_R_SDHC_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC1_SEL: - case IMX8QXP_SDHC0_SEL: - return 0; - case IMX8QXP_SDHC1_IPG_CLK: - case IMX8QXP_SDHC1_CLK: - case IMX8QXP_SDHC1_DIV: - resource = SC_R_SDHC_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET0_IPG_CLK: - case IMX8QXP_ENET0_AHB_CLK: - case IMX8QXP_ENET0_REF_DIV: - case IMX8QXP_ENET0_PTP_CLK: - resource = SC_R_ENET_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET1_IPG_CLK: - case IMX8QXP_ENET1_AHB_CLK: - case IMX8QXP_ENET1_REF_DIV: - case IMX8QXP_ENET1_PTP_CLK: - resource = SC_R_ENET_1; - pm_clk = SC_PM_CLK_PER; - break; - default: - if (clk->id < IMX8QXP_UART0_IPG_CLK || - clk->id >= IMX8QXP_CLK_END) { - printf("%s(Invalid clk ID #%lu)\n", - __func__, clk->id); - return -EINVAL; - } - return -ENOTSUPP; - }; - - ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate); - if (ret) { - printf("%s err %d\n", __func__, ret); - return ret; - } - - return new_rate; + return 0; } -static int __imx8_clk_enable(struct clk *clk, bool enable) +__weak int __imx8_clk_enable(struct clk *clk, bool enable) { - sc_pm_clk_t pm_clk; - u16 resource; - int ret; - - debug("%s(#%lu)\n", __func__, clk->id); - - switch (clk->id) { - case IMX8QXP_I2C0_CLK: - resource = SC_R_I2C_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C1_CLK: - resource = SC_R_I2C_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C2_CLK: - resource = SC_R_I2C_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_I2C3_CLK: - resource = SC_R_I2C_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART0_CLK: - resource = SC_R_UART_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART1_CLK: - resource = SC_R_UART_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART2_CLK: - resource = SC_R_UART_2; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_UART3_CLK: - resource = SC_R_UART_3; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC0_IPG_CLK: - case IMX8QXP_SDHC0_CLK: - case IMX8QXP_SDHC0_DIV: - resource = SC_R_SDHC_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_SDHC1_IPG_CLK: - case IMX8QXP_SDHC1_CLK: - case IMX8QXP_SDHC1_DIV: - resource = SC_R_SDHC_1; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET0_IPG_CLK: - case IMX8QXP_ENET0_AHB_CLK: - case IMX8QXP_ENET0_REF_DIV: - case IMX8QXP_ENET0_PTP_CLK: - resource = SC_R_ENET_0; - pm_clk = SC_PM_CLK_PER; - break; - case IMX8QXP_ENET1_IPG_CLK: - case IMX8QXP_ENET1_AHB_CLK: - case IMX8QXP_ENET1_REF_DIV: - case IMX8QXP_ENET1_PTP_CLK: - resource = SC_R_ENET_1; - pm_clk = SC_PM_CLK_PER; - break; - default: - if (clk->id < IMX8QXP_UART0_IPG_CLK || - clk->id >= IMX8QXP_CLK_END) { - printf("%s(Invalid clk ID #%lu)\n", - __func__, clk->id); - return -EINVAL; - } - return -ENOTSUPP; - } - - ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0); - if (ret) { - printf("%s err %d\n", __func__, ret); - return ret; - } - - return 0; + return -ENOTSUPP; } static int imx8_clk_disable(struct clk *clk) @@ -336,7 +55,7 @@ int soc_clk_dump(void) printf("Clk\t\tHz\n"); - for (i = 0; i < ARRAY_SIZE(imx8_clk_names); i++) { + for (i = 0; i < num_clks; i++) { clk.id = imx8_clk_names[i].id; ret = clk_request(dev, &clk); if (ret < 0) { @@ -382,6 +101,7 @@ static int imx8_clk_probe(struct udevice *dev) static const struct udevice_id imx8_clk_ids[] = { { .compatible = "fsl,imx8qxp-clk" }, + { .compatible = "fsl,imx8qm-clk" }, { }, }; diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h new file mode 100644 index 0000000000..68ad6755e8 --- /dev/null +++ b/drivers/clk/imx/clk-imx8.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + * Peng Fan <peng.fan@nxp.com> + */ + +struct imx8_clks { + ulong id; + const char *name; +}; + +#if CONFIG_IS_ENABLED(CMD_CLK) +extern struct imx8_clks imx8_clk_names[]; +extern int num_clks; +#endif + +ulong imx8_clk_get_rate(struct clk *clk); +ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate); +int __imx8_clk_enable(struct clk *clk, bool enable); diff --git a/drivers/clk/imx/clk-imx8qm.c b/drivers/clk/imx/clk-imx8qm.c new file mode 100644 index 0000000000..6b5561e178 --- /dev/null +++ b/drivers/clk/imx/clk-imx8qm.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2018 NXP + * Peng Fan <peng.fan@nxp.com> + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/clock.h> +#include <dt-bindings/clock/imx8qm-clock.h> +#include <dt-bindings/soc/imx_rsrc.h> +#include <misc.h> + +#include "clk-imx8.h" + +#if CONFIG_IS_ENABLED(CMD_CLK) +struct imx8_clks imx8_clk_names[] = { + { IMX8QM_A53_DIV, "A53_DIV" }, + { IMX8QM_UART0_CLK, "UART0" }, + { IMX8QM_UART1_CLK, "UART1" }, + { IMX8QM_UART2_CLK, "UART2" }, + { IMX8QM_UART3_CLK, "UART3" }, + { IMX8QM_SDHC0_CLK, "SDHC0" }, + { IMX8QM_SDHC1_CLK, "SDHC1" }, + { IMX8QM_SDHC2_CLK, "SDHC2" }, + { IMX8QM_ENET0_AHB_CLK, "ENET0_AHB" }, + { IMX8QM_ENET0_IPG_CLK, "ENET0_IPG" }, + { IMX8QM_ENET0_REF_DIV, "ENET0_REF" }, + { IMX8QM_ENET0_PTP_CLK, "ENET0_PTP" }, + { IMX8QM_ENET1_AHB_CLK, "ENET1_AHB" }, + { IMX8QM_ENET1_IPG_CLK, "ENET1_IPG" }, + { IMX8QM_ENET1_REF_DIV, "ENET1_REF" }, + { IMX8QM_ENET1_PTP_CLK, "ENET1_PTP" }, +}; + +int num_clks = ARRAY_SIZE(imx8_clk_names); +#endif + +ulong imx8_clk_get_rate(struct clk *clk) +{ + sc_pm_clk_t pm_clk; + ulong rate; + u16 resource; + int ret; + + debug("%s(#%lu)\n", __func__, clk->id); + + switch (clk->id) { + case IMX8QM_A53_DIV: + resource = SC_R_A53; + pm_clk = SC_PM_CLK_CPU; + break; + case IMX8QM_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC0_IPG_CLK: + case IMX8QM_SDHC0_CLK: + case IMX8QM_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC1_IPG_CLK: + case IMX8QM_SDHC1_CLK: + case IMX8QM_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART0_IPG_CLK: + case IMX8QM_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET0_IPG_CLK: + case IMX8QM_ENET0_AHB_CLK: + case IMX8QM_ENET0_REF_DIV: + case IMX8QM_ENET0_PTP_CLK: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET1_IPG_CLK: + case IMX8QM_ENET1_AHB_CLK: + case IMX8QM_ENET1_REF_DIV: + case IMX8QM_ENET1_PTP_CLK: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QM_UART0_IPG_CLK || + clk->id >= IMX8QM_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + }; + + ret = sc_pm_get_clock_rate(-1, resource, pm_clk, + (sc_pm_clock_rate_t *)&rate); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return rate; +} + +ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) +{ + sc_pm_clk_t pm_clk; + u32 new_rate = rate; + u16 resource; + int ret; + + debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); + + switch (clk->id) { + case IMX8QM_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC0_IPG_CLK: + case IMX8QM_SDHC0_CLK: + case IMX8QM_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC1_IPG_CLK: + case IMX8QM_SDHC1_CLK: + case IMX8QM_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET0_IPG_CLK: + case IMX8QM_ENET0_AHB_CLK: + case IMX8QM_ENET0_REF_DIV: + case IMX8QM_ENET0_PTP_CLK: + case IMX8QM_ENET0_ROOT_DIV: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET1_IPG_CLK: + case IMX8QM_ENET1_AHB_CLK: + case IMX8QM_ENET1_REF_DIV: + case IMX8QM_ENET1_PTP_CLK: + case IMX8QM_ENET1_ROOT_DIV: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QM_UART0_IPG_CLK || + clk->id >= IMX8QM_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + }; + + ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return new_rate; +} + +int __imx8_clk_enable(struct clk *clk, bool enable) +{ + sc_pm_clk_t pm_clk; + u16 resource; + int ret; + + debug("%s(#%lu)\n", __func__, clk->id); + + switch (clk->id) { + case IMX8QM_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC0_IPG_CLK: + case IMX8QM_SDHC0_CLK: + case IMX8QM_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_SDHC1_IPG_CLK: + case IMX8QM_SDHC1_CLK: + case IMX8QM_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET0_IPG_CLK: + case IMX8QM_ENET0_AHB_CLK: + case IMX8QM_ENET0_REF_DIV: + case IMX8QM_ENET0_PTP_CLK: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QM_ENET1_IPG_CLK: + case IMX8QM_ENET1_AHB_CLK: + case IMX8QM_ENET1_REF_DIV: + case IMX8QM_ENET1_PTP_CLK: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QM_UART0_IPG_CLK || + clk->id >= IMX8QM_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + } + + ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return 0; +} diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c new file mode 100644 index 0000000000..1fca36ac91 --- /dev/null +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2018 NXP + * Peng Fan <peng.fan@nxp.com> + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/clock.h> +#include <dt-bindings/clock/imx8qxp-clock.h> +#include <dt-bindings/soc/imx_rsrc.h> +#include <misc.h> + +#include "clk-imx8.h" + +#if CONFIG_IS_ENABLED(CMD_CLK) +struct imx8_clks imx8_clk_names[] = { + { IMX8QXP_A35_DIV, "A35_DIV" }, + { IMX8QXP_I2C0_CLK, "I2C0" }, + { IMX8QXP_I2C1_CLK, "I2C1" }, + { IMX8QXP_I2C2_CLK, "I2C2" }, + { IMX8QXP_I2C3_CLK, "I2C3" }, + { IMX8QXP_UART0_CLK, "UART0" }, + { IMX8QXP_UART1_CLK, "UART1" }, + { IMX8QXP_UART2_CLK, "UART2" }, + { IMX8QXP_UART3_CLK, "UART3" }, + { IMX8QXP_SDHC0_CLK, "SDHC0" }, + { IMX8QXP_SDHC1_CLK, "SDHC1" }, + { IMX8QXP_ENET0_AHB_CLK, "ENET0_AHB" }, + { IMX8QXP_ENET0_IPG_CLK, "ENET0_IPG" }, + { IMX8QXP_ENET0_REF_DIV, "ENET0_REF" }, + { IMX8QXP_ENET0_PTP_CLK, "ENET0_PTP" }, + { IMX8QXP_ENET1_AHB_CLK, "ENET1_AHB" }, + { IMX8QXP_ENET1_IPG_CLK, "ENET1_IPG" }, + { IMX8QXP_ENET1_REF_DIV, "ENET1_REF" }, + { IMX8QXP_ENET1_PTP_CLK, "ENET1_PTP" }, +}; + +int num_clks = ARRAY_SIZE(imx8_clk_names); +#endif + +ulong imx8_clk_get_rate(struct clk *clk) +{ + sc_pm_clk_t pm_clk; + ulong rate; + u16 resource; + int ret; + + debug("%s(#%lu)\n", __func__, clk->id); + + switch (clk->id) { + case IMX8QXP_A35_DIV: + resource = SC_R_A35; + pm_clk = SC_PM_CLK_CPU; + break; + case IMX8QXP_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC0_IPG_CLK: + case IMX8QXP_SDHC0_CLK: + case IMX8QXP_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC1_IPG_CLK: + case IMX8QXP_SDHC1_CLK: + case IMX8QXP_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART0_IPG_CLK: + case IMX8QXP_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET0_IPG_CLK: + case IMX8QXP_ENET0_AHB_CLK: + case IMX8QXP_ENET0_REF_DIV: + case IMX8QXP_ENET0_PTP_CLK: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET1_IPG_CLK: + case IMX8QXP_ENET1_AHB_CLK: + case IMX8QXP_ENET1_REF_DIV: + case IMX8QXP_ENET1_PTP_CLK: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QXP_UART0_IPG_CLK || + clk->id >= IMX8QXP_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + }; + + ret = sc_pm_get_clock_rate(-1, resource, pm_clk, + (sc_pm_clock_rate_t *)&rate); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return rate; +} + +ulong imx8_clk_set_rate(struct clk *clk, unsigned long rate) +{ + sc_pm_clk_t pm_clk; + u32 new_rate = rate; + u16 resource; + int ret; + + debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); + + switch (clk->id) { + case IMX8QXP_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC0_IPG_CLK: + case IMX8QXP_SDHC0_CLK: + case IMX8QXP_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC1_SEL: + case IMX8QXP_SDHC0_SEL: + return 0; + case IMX8QXP_SDHC1_IPG_CLK: + case IMX8QXP_SDHC1_CLK: + case IMX8QXP_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET0_IPG_CLK: + case IMX8QXP_ENET0_AHB_CLK: + case IMX8QXP_ENET0_REF_DIV: + case IMX8QXP_ENET0_PTP_CLK: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET1_IPG_CLK: + case IMX8QXP_ENET1_AHB_CLK: + case IMX8QXP_ENET1_REF_DIV: + case IMX8QXP_ENET1_PTP_CLK: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QXP_UART0_IPG_CLK || + clk->id >= IMX8QXP_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + }; + + ret = sc_pm_set_clock_rate(-1, resource, pm_clk, &new_rate); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return new_rate; +} + +int __imx8_clk_enable(struct clk *clk, bool enable) +{ + sc_pm_clk_t pm_clk; + u16 resource; + int ret; + + debug("%s(#%lu)\n", __func__, clk->id); + + switch (clk->id) { + case IMX8QXP_I2C0_CLK: + resource = SC_R_I2C_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C1_CLK: + resource = SC_R_I2C_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C2_CLK: + resource = SC_R_I2C_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_I2C3_CLK: + resource = SC_R_I2C_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART0_CLK: + resource = SC_R_UART_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART1_CLK: + resource = SC_R_UART_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART2_CLK: + resource = SC_R_UART_2; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_UART3_CLK: + resource = SC_R_UART_3; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC0_IPG_CLK: + case IMX8QXP_SDHC0_CLK: + case IMX8QXP_SDHC0_DIV: + resource = SC_R_SDHC_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_SDHC1_IPG_CLK: + case IMX8QXP_SDHC1_CLK: + case IMX8QXP_SDHC1_DIV: + resource = SC_R_SDHC_1; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET0_IPG_CLK: + case IMX8QXP_ENET0_AHB_CLK: + case IMX8QXP_ENET0_REF_DIV: + case IMX8QXP_ENET0_PTP_CLK: + resource = SC_R_ENET_0; + pm_clk = SC_PM_CLK_PER; + break; + case IMX8QXP_ENET1_IPG_CLK: + case IMX8QXP_ENET1_AHB_CLK: + case IMX8QXP_ENET1_REF_DIV: + case IMX8QXP_ENET1_PTP_CLK: + resource = SC_R_ENET_1; + pm_clk = SC_PM_CLK_PER; + break; + default: + if (clk->id < IMX8QXP_UART0_IPG_CLK || + clk->id >= IMX8QXP_CLK_END) { + printf("%s(Invalid clk ID #%lu)\n", + __func__, clk->id); + return -EINVAL; + } + return -ENOTSUPP; + } + + ret = sc_pm_clock_enable(-1, resource, pm_clk, enable, 0); + if (ret) { + printf("%s err %d\n", __func__, ret); + return ret; + } + + return 0; +} diff --git a/drivers/ddr/imx/imx8m/Kconfig b/drivers/ddr/imx/imx8m/Kconfig index 71f466f5ec..a83b0f43d7 100644 --- a/drivers/ddr/imx/imx8m/Kconfig +++ b/drivers/ddr/imx/imx8m/Kconfig @@ -1,3 +1,6 @@ +menu "i.MX8M DDR controllers" + depends on ARCH_IMX8M + config IMX8M_DRAM bool "imx8m dram" @@ -20,3 +23,4 @@ config SAVED_DRAM_TIMING_BASE info into memory for low power use. OCRAM_S is used for this purpose on i.MX8MM. default 0x180000 +endmenu diff --git a/drivers/misc/imx8/Makefile b/drivers/misc/imx8/Makefile index ee05893cbb..48fdb5b61c 100644 --- a/drivers/misc/imx8/Makefile +++ b/drivers/misc/imx8/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += scu_api.o scu.o +obj-$(CONFIG_CMD_FUSE) += fuse.o diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c new file mode 100644 index 0000000000..29d2256a22 --- /dev/null +++ b/drivers/misc/imx8/fuse.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 NXP + */ + +#include <common.h> +#include <console.h> +#include <errno.h> +#include <fuse.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/sys_proto.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define FSL_ECC_WORD_START_1 0x10 +#define FSL_ECC_WORD_END_1 0x10F + +#ifdef CONFIG_IMX8QXP +#define FSL_ECC_WORD_START_2 0x220 +#define FSL_ECC_WORD_END_2 0x31F + +#define FSL_QXP_FUSE_GAP_START 0x110 +#define FSL_QXP_FUSE_GAP_END 0x21F +#endif + +#define FSL_SIP_OTP_READ 0xc200000A +#define FSL_SIP_OTP_WRITE 0xc200000B + +int fuse_read(u32 bank, u32 word, u32 *val) +{ + return fuse_sense(bank, word, val); +} + +int fuse_sense(u32 bank, u32 word, u32 *val) +{ + unsigned long ret = 0, value = 0; + + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + ret = call_imx_sip_ret2(FSL_SIP_OTP_READ, (unsigned long)word, &value, + 0, 0); + *val = (u32)value; + + return ret; +} + +int fuse_prog(u32 bank, u32 word, u32 val) +{ + if (bank != 0) { + printf("Invalid bank argument, ONLY bank 0 is supported\n"); + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_IMX8QXP)) { + if (word >= FSL_QXP_FUSE_GAP_START && + word <= FSL_QXP_FUSE_GAP_END) { + printf("Invalid word argument for this SoC\n"); + return -EINVAL; + } + } + + if ((word >= FSL_ECC_WORD_START_1 && word <= FSL_ECC_WORD_END_1) || + (word >= FSL_ECC_WORD_START_2 && word <= FSL_ECC_WORD_END_2)) { + puts("Warning: Words in this index range have ECC protection\n" + "and can only be programmed once per word. Individual bit\n" + "operations will be rejected after the first one.\n" + "\n\n Really program this word? <y/N>\n"); + + if (!confirm_yesno()) { + puts("Word programming aborted\n"); + return -EPERM; + } + } + + return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word, + (unsigned long)val, 0); +} + +int fuse_override(u32 bank, u32 word, u32 val) +{ + printf("Override fuse to i.MX8 in u-boot is forbidden\n"); + return -EPERM; +} diff --git a/drivers/misc/imx8/scu.c b/drivers/misc/imx8/scu.c index 1b9c49c99c..9ec00457b8 100644 --- a/drivers/misc/imx8/scu.c +++ b/drivers/misc/imx8/scu.c @@ -219,11 +219,21 @@ static int imx8_scu_bind(struct udevice *dev) int ret; struct udevice *child; int node; + char *clk_compatible, *iomuxc_compatible; + + if (IS_ENABLED(CONFIG_IMX8QXP)) { + clk_compatible = "fsl,imx8qxp-clk"; + iomuxc_compatible = "fsl,imx8qxp-iomuxc"; + } else if (IS_ENABLED(CONFIG_IMX8QM)) { + clk_compatible = "fsl,imx8qm-clk"; + iomuxc_compatible = "fsl,imx8qm-iomuxc"; + } else { + return -EINVAL; + } debug("%s(dev=%p)\n", __func__, dev); - node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, - "fsl,imx8qxp-clk"); + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, clk_compatible); if (node < 0) panic("No clk node found\n"); @@ -234,7 +244,7 @@ static int imx8_scu_bind(struct udevice *dev) plat->clk = child; node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, - "fsl,imx8qxp-iomuxc"); + iomuxc_compatible); if (node < 0) panic("No iomuxc node found\n"); diff --git a/drivers/misc/mxc_ocotp.c b/drivers/misc/mxc_ocotp.c index f84fe88db1..1b945e9727 100644 --- a/drivers/misc/mxc_ocotp.c +++ b/drivers/misc/mxc_ocotp.c @@ -321,6 +321,11 @@ int fuse_sense(u32 bank, u32 word, u32 *val) struct ocotp_regs *regs; int ret; + if (is_imx8mq() && is_soc_rev(CHIP_REV_2_1)) { + printf("mxc_ocotp %s(): fuse sense is disabled\n", __func__); + return -EPERM; + } + ret = prepare_read(®s, bank, word, val, __func__); if (ret) return ret; @@ -354,13 +359,17 @@ static int prepare_write(struct ocotp_regs **regs, u32 bank, u32 word, /* Only bank 0 and 1 are redundancy mode, others are ECC mode */ if (bank != 0 && bank != 1) { - ret = fuse_sense(bank, word, &val); - if (ret) - return ret; - - if (val != 0) { - printf("mxc_ocotp: The word has been programmed, no more write\n"); - return -EPERM; + if ((soc_rev() < CHIP_REV_2_0) || + ((soc_rev() >= CHIP_REV_2_0) && + bank != 9 && bank != 10 && bank != 28)) { + ret = fuse_sense(bank, word, &val); + if (ret) + return ret; + + if (val != 0) { + printf("mxc_ocotp: The word has been programmed, no more write\n"); + return -EPERM; + } } } #endif diff --git a/drivers/pinctrl/nxp/pinctrl-imx8.c b/drivers/pinctrl/nxp/pinctrl-imx8.c index 0738da0ebe..c1b0ca438a 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx8.c +++ b/drivers/pinctrl/nxp/pinctrl-imx8.c @@ -25,6 +25,7 @@ static int imx8_pinctrl_probe(struct udevice *dev) static const struct udevice_id imx8_pinctrl_match[] = { { .compatible = "fsl,imx8qxp-iomuxc", .data = (ulong)&imx8_pinctrl_soc_info }, + { .compatible = "fsl,imx8qm-iomuxc", .data = (ulong)&imx8_pinctrl_soc_info }, { /* sentinel */ } }; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0fbc115801..1c2212f547 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -132,6 +132,13 @@ config USB_EHCI_MARVELL ---help--- Enables support for the on-chip EHCI controller on MVEBU SoCs. +config USB_EHCI_MX5 + bool "Support for i.MX5 on-chip EHCI USB controller" + depends on ARCH_MX5 + default n + help + Enables support for the on-chip EHCI controller on i.MX5 SoCs. + config USB_EHCI_MX6 bool "Support for i.MX6 on-chip EHCI USB controller" depends on ARCH_MX6 diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c index 60f1470860..0b32728c57 100644 --- a/drivers/usb/host/ehci-mx5.c +++ b/drivers/usb/host/ehci-mx5.c @@ -12,6 +12,8 @@ #include <asm/io.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> +#include <dm.h> +#include <power/regulator.h> #include "ehci.h" @@ -223,6 +225,7 @@ __weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg, mdelay(50); } +#if !CONFIG_IS_ENABLED(DM_USB) static const struct ehci_ops mx5_ehci_ops = { .powerup_fixup = mx5_ehci_powerup_fixup, }; @@ -267,3 +270,103 @@ int ehci_hcd_stop(int index) { return 0; } +#else /* CONFIG_IS_ENABLED(DM_USB) */ +struct ehci_mx5_priv_data { + struct ehci_ctrl ctrl; + struct usb_ehci *ehci; + struct udevice *vbus_supply; + enum usb_init_type init_type; + int portnr; +}; + +static const struct ehci_ops mx5_ehci_ops = { + .powerup_fixup = mx5_ehci_powerup_fixup, +}; + +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + const char *mode; + + mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "dr_mode", NULL); + if (mode) { + if (strcmp(mode, "peripheral") == 0) + plat->init_type = USB_INIT_DEVICE; + else if (strcmp(mode, "host") == 0) + plat->init_type = USB_INIT_HOST; + else + return -EINVAL; + } + + return 0; +} + +static int ehci_usb_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct usb_ehci *ehci = (struct usb_ehci *)devfdt_get_addr(dev); + struct ehci_mx5_priv_data *priv = dev_get_priv(dev); + enum usb_init_type type = plat->init_type; + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + int ret; + + set_usboh3_clk(); + enable_usboh3_clk(true); + set_usb_phy_clk(); + enable_usb_phy1_clk(true); + enable_usb_phy2_clk(true); + mdelay(1); + + priv->ehci = ehci; + priv->portnr = dev->seq; + priv->init_type = type; + + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); + if (ret) + debug("%s: No vbus supply\n", dev->name); + + if (!ret && priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + } + + hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength); + hcor = (struct ehci_hcor *)((uint32_t)hccr + + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); + setbits_le32(&ehci->usbmode, CM_HOST); + + __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc); + setbits_le32(&ehci->portsc, USB_EN); + + mxc_set_usbcontrol(priv->portnr, CONFIG_MXC_USB_FLAGS); + mdelay(10); + + return ehci_register(dev, hccr, hcor, &mx5_ehci_ops, 0, + priv->init_type); +} + +static const struct udevice_id mx5_usb_ids[] = { + { .compatible = "fsl,imx53-usb" }, + { } +}; + +U_BOOT_DRIVER(usb_mx5) = { + .name = "ehci_mx5", + .id = UCLASS_USB, + .of_match = mx5_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_deregister, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct ehci_mx5_priv_data), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif /* !CONFIG_IS_ENABLED(DM_USB) */ |