diff --git a/arch/arm/configs/imx28_defconfig b/arch/arm/configs/imx28_defconfig index 1acc8dd..4442c79 100644 --- a/arch/arm/configs/imx28_defconfig +++ b/arch/arm/configs/imx28_defconfig @@ -20,7 +20,9 @@ CONFIG_BOOTM_VERBOSE=y CONFIG_BOOTM_INITRD=y CONFIG_BLSPEC=y +CONFIG_CONSOLE_ACTIVATE_NONE=y CONFIG_CONSOLE_ALLOW_COLOR=y +CONFIG_PBL_CONSOLE=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_RESET_SOURCE=y CONFIG_CMD_DMESG=y @@ -28,11 +30,13 @@ CONFIG_CMD_IOMEM=y CONFIG_CMD_IMD=y CONFIG_CMD_MEMINFO=y +CONFIG_CMD_REGULATOR=y # CONFIG_CMD_BOOTU is not set CONFIG_CMD_GO=y CONFIG_CMD_RESET=y CONFIG_CMD_UIMAGE=y CONFIG_CMD_PARTITION=y +CONFIG_CMD_UBIFORMAT=y CONFIG_CMD_EXPORT=y CONFIG_CMD_LOADENV=y CONFIG_CMD_PRINTENV=y @@ -72,16 +76,20 @@ CONFIG_CMD_SPI=y CONFIG_CMD_LED_TRIGGER=y CONFIG_CMD_USBGADGET=y +CONFIG_CMD_WD=y CONFIG_CMD_BAREBOX_UPDATE=y CONFIG_CMD_OF_NODE=y CONFIG_CMD_OF_PROPERTY=y CONFIG_CMD_OFTREE=y CONFIG_CMD_TIME=y CONFIG_NET=y -CONFIG_OFDEVICE=y CONFIG_OF_BAREBOX_DRIVERS=y CONFIG_DRIVER_SERIAL_AUART=y CONFIG_DRIVER_NET_FEC_IMX=y +CONFIG_NET_USB=y +CONFIG_NET_USB_ASIX=y +CONFIG_USB_NET_AX88179_178A=y +CONFIG_NET_USB_SMSC95XX=y CONFIG_DRIVER_SPI_MXS=y CONFIG_I2C=y CONFIG_MTD=y @@ -89,6 +97,10 @@ CONFIG_NAND_MXS=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_FASTMAP=y +CONFIG_USB_HOST=y +CONFIG_USB_IMX_CHIPIDEA=y +CONFIG_USB_EHCI=y +CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DFU=y CONFIG_USB_GADGET_SERIAL=y @@ -97,7 +109,6 @@ CONFIG_VIDEO=y CONFIG_DRIVER_VIDEO_STM=y CONFIG_MCI=y -CONFIG_MCI_STARTUP=y CONFIG_MCI_MXS=y CONFIG_LED=y CONFIG_LED_GPIO=y @@ -108,6 +119,7 @@ CONFIG_MXS_APBH_DMA=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y +CONFIG_GENERIC_PHY=y CONFIG_FS_EXT4=y CONFIG_FS_TFTP=y CONFIG_FS_NFS=y diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index b3a7c62..f4a9d3d 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -9,6 +9,12 @@ default 0x47000000 if MACH_MX28EVK default 0x47000000 if MACH_CFA10036 +config ARCH_MXS_OF_SUPPORT + bool + select COMMON_CLK_OF_PROVIDER + select OFTREE + select OFDEVICE + comment "Freescale i.MX System-on-Chip" choice @@ -57,12 +63,14 @@ config MACH_MX28EVK bool "mx28-evk" select MXS_OCOTP + select ARCH_MXS_OF_SUPPORT help Say Y here if you are using the Freescale i.MX28-EVK board config MACH_DUCKBILL bool "Duckbill" select MXS_OCOTP + select ARCH_MXS_OF_SUPPORT help Say Y here if you are using the I2SE Duckbill board diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index ca7c349..c89f1f5 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -1172,7 +1172,7 @@ writel(MX23_POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr); } -struct mxs_power_ctrl mxs_vddd_default = { .target = 1500, .brownout = 1325 }; +struct mxs_power_ctrl mxs_vddd_default = { .target = 1550, .brownout = 1400 }; struct mxs_power_ctrl mxs_vdda_default = { .target = 1800, .brownout = 1650 }; struct mxs_power_ctrl mxs_vddio_default = { .target = 3300, .brownout = 3150 }; struct mxs_power_ctrl mx23_vddmem_default = { .target = 2500, .brownout = 1700 }; diff --git a/common/filetype.c b/common/filetype.c index 799ede9..eda8ecb 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -78,6 +78,7 @@ "ubootvar" }, [filetype_stm32_image_v1] = { "STM32 image (v1)", "stm32-image-v1" }, [filetype_zynq_image] = { "Zynq image", "zynq-image" }, + [filetype_mxs_sd_image] = { "i.MX23/28 SD card image", "mxs-sd-image" }, }; const char *file_type_to_string(enum filetype f) @@ -339,6 +340,9 @@ if (buf[0] == 0x01ee0100 && buf[1] == 0xaa55aa55) return filetype_layerscape_qspi_image; + if (le32_to_cpu(buf[0]) == 0x00112233 && le32_to_cpu(buf[1]) == 0x1) + return filetype_mxs_sd_image; + if (bufsize < 64) return filetype_unknown; diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 4adb1c6..bf65a4a 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "clk.h" @@ -38,6 +39,9 @@ #define FRAC1 (regs + 0x01c0) #define CLKSEQ (regs + 0x01d0) +static void __iomem *digctrl; +#define DIGCTRL digctrl + static const char *sel_cpu[] = { "ref_cpu", "ref_xtal", }; static const char *sel_io0[] = { "ref_io0", "ref_xtal", }; static const char *sel_io1[] = { "ref_io1", "ref_xtal", }; @@ -56,14 +60,17 @@ emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div, clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0, ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm, - fec_sleep, fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out, - lcdif_comp, clk_max + fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out, + lcdif_comp, fec_sleep, clk_max }; static struct clk *clks[clk_max]; +static struct clk_onecell_data clk_data; -static int __init mx28_clocks_init(void __iomem *regs) +static int __init mx28_clocks_init(struct device_d *dev, void __iomem *regs) { + struct device_node *dcnp; + clks[ref_xtal] = clk_fixed("ref_xtal", 24000000); clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000); clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000); @@ -120,6 +127,13 @@ clks[lcdif_comp] = mxs_clk_lcdif("lcdif_comp", clks[ref_pix], clks[lcdif_div], clks[lcdif]); + dcnp = of_find_compatible_node(NULL, NULL, "fsl,imx28-digctl"); + if (dcnp) { + digctrl = of_iomap(dcnp, 0); + clks[usb0] = mxs_clk_gate("usb0", "usb0_phy", DIGCTRL, 2); + clks[usb1] = mxs_clk_gate("usb1", "usb1_phy", DIGCTRL, 16); + } + clk_set_rate(clks[ref_io0], 480000000); clk_set_rate(clks[ref_io1], 480000000); clk_set_parent(clks[ssp0_sel], clks[ref_io0]); @@ -131,25 +145,30 @@ clk_set_rate(clks[ssp2], 96000000); clk_set_rate(clks[ssp3], 96000000); clk_set_parent(clks[lcdif_sel], clks[ref_pix]); - clk_enable(clks[enet_out]); - clkdev_add_physbase(clks[ssp0], IMX_SSP0_BASE, NULL); - clkdev_add_physbase(clks[ssp1], IMX_SSP1_BASE, NULL); - clkdev_add_physbase(clks[ssp2], IMX_SSP2_BASE, NULL); - clkdev_add_physbase(clks[ssp3], IMX_SSP3_BASE, NULL); - clkdev_add_physbase(clks[fec], IMX_FEC0_BASE, NULL); - clkdev_add_physbase(clks[xbus], IMX_DBGUART_BASE, NULL); - clkdev_add_physbase(clks[hbus], IMX_OCOTP_BASE, NULL); - clkdev_add_physbase(clks[hbus], MXS_APBH_BASE, NULL); - clkdev_add_physbase(clks[uart], IMX_UART0_BASE, NULL); - clkdev_add_physbase(clks[uart], IMX_UART1_BASE, NULL); - clkdev_add_physbase(clks[uart], IMX_UART2_BASE, NULL); - clkdev_add_physbase(clks[uart], IMX_UART3_BASE, NULL); - clkdev_add_physbase(clks[uart], IMX_UART4_BASE, NULL); - clkdev_add_physbase(clks[gpmi], MXS_GPMI_BASE, NULL); - clkdev_add_physbase(clks[pwm], IMX_PWM_BASE, NULL); - if (IS_ENABLED(CONFIG_DRIVER_VIDEO_STM)) - clkdev_add_physbase(clks[lcdif_comp], IMX_FB_BASE, NULL); + if (dev->device_node) { + clk_data.clks = clks; + clk_data.clk_num = clk_max; + of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data); + } else { + clkdev_add_physbase(clks[ssp0], IMX_SSP0_BASE, NULL); + clkdev_add_physbase(clks[ssp1], IMX_SSP1_BASE, NULL); + clkdev_add_physbase(clks[ssp2], IMX_SSP2_BASE, NULL); + clkdev_add_physbase(clks[ssp3], IMX_SSP3_BASE, NULL); + clkdev_add_physbase(clks[fec], IMX_FEC0_BASE, NULL); + clkdev_add_physbase(clks[xbus], IMX_DBGUART_BASE, NULL); + clkdev_add_physbase(clks[hbus], IMX_OCOTP_BASE, NULL); + clkdev_add_physbase(clks[hbus], MXS_APBH_BASE, NULL); + clkdev_add_physbase(clks[uart], IMX_UART0_BASE, NULL); + clkdev_add_physbase(clks[uart], IMX_UART1_BASE, NULL); + clkdev_add_physbase(clks[uart], IMX_UART2_BASE, NULL); + clkdev_add_physbase(clks[uart], IMX_UART3_BASE, NULL); + clkdev_add_physbase(clks[uart], IMX_UART4_BASE, NULL); + clkdev_add_physbase(clks[gpmi], MXS_GPMI_BASE, NULL); + clkdev_add_physbase(clks[pwm], IMX_PWM_BASE, NULL); + if (IS_ENABLED(CONFIG_DRIVER_VIDEO_STM)) + clkdev_add_physbase(clks[lcdif_comp], IMX_FB_BASE, NULL); + } return 0; } @@ -164,7 +183,7 @@ return PTR_ERR(iores); regs = IOMEM(iores->start); - mx28_clocks_init(regs); + mx28_clocks_init(dev, regs); return 0; } diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c index afd6a56..5e9f17d 100644 --- a/drivers/mci/mxs.c +++ b/drivers/mci/mxs.c @@ -542,6 +542,13 @@ printf("\n"); } +static int mxs_mmc_detect(struct device_d *dev) +{ + struct mxs_mci_host *mxs_mci = dev->priv; + + return mci_detect_card(&mxs_mci->host); +} + static int mxs_mci_probe(struct device_d *hw_dev) { struct resource *iores; @@ -577,6 +584,8 @@ mci_of_parse(host); } + hw_dev->detect = mxs_mmc_detect; + mxs_mci->clk = clk_get(hw_dev, NULL); if (IS_ERR(mxs_mci->clk)) return PTR_ERR(mxs_mci->clk); diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index f814b3b..772f930 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -705,10 +705,10 @@ { int i, err = 0; static const char *clk_names[ARRAY_SIZE(fec->clk)] = { - "ipg", "ahb", "ptp" + "ipg", "ahb", }; static const char *opt_clk_names[ARRAY_SIZE(fec->opt_clk)] = { - "enet_clk_ref", "enet_out", + "enet_clk_ref", "enet_out", "ptp" }; for (i = 0; i < ARRAY_SIZE(fec->clk); i++) { @@ -716,7 +716,7 @@ if (IS_ERR(fec->clk[i])) { err = PTR_ERR(fec->clk[i]); fec_clk_put(fec); - break; + return err; } } diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h index d1ac92f..316eefe 100644 --- a/drivers/net/fec_imx.h +++ b/drivers/net/fec_imx.h @@ -121,7 +121,6 @@ enum fec_clock { FEC_CLK_IPG, FEC_CLK_AHB, - FEC_CLK_PTP, FEC_CLK_NUM }; @@ -129,6 +128,7 @@ enum fec_opt_clock { FEC_OPT_CLK_REF, FEC_OPT_CLK_OUT, + FEC_OPT_CLK_PTP, FEC_OPT_CLK_NUM }; diff --git a/drivers/serial/serial_auart.c b/drivers/serial/serial_auart.c index 05cc757..ee64f2f 100644 --- a/drivers/serial/serial_auart.c +++ b/drivers/serial/serial_auart.c @@ -193,6 +193,7 @@ cdev->flush = auart_serial_flush; cdev->setbrg = auart_serial_setbaudrate; cdev->dev = dev; + cdev->linux_console_name = "ttyAPP"; dev->priv = priv; iores = dev_request_mem_resource(dev, 0); diff --git a/drivers/usb/imx/Kconfig b/drivers/usb/imx/Kconfig index 34f35e0..2b9e63b 100644 --- a/drivers/usb/imx/Kconfig +++ b/drivers/usb/imx/Kconfig @@ -1,7 +1,7 @@ config USB_IMX_CHIPIDEA bool "i.MX USB support (read help)" - depends on ARCH_IMX + depends on ARCH_IMX || ARCH_MXS select USB_OTGDEV help The Freescale i.MX SoCs have a variant of the chipidea ci13xxx for @@ -15,8 +15,12 @@ support to work. It's safe to say yes here. Also select EHCI support for USB host. +config USB_IMX_CHIPIDEA_USBMISC + bool + default y if ARCH_IMX + config USB_IMX_PHY bool - default y if (ARCH_IMX6 || ARCH_VF610) && GENERIC_PHY + default y if (ARCH_IMX6 || ARCH_VF610 || ARCH_MXS) && GENERIC_PHY select STMP_DEVICE select MFD_SYSCON diff --git a/drivers/usb/imx/Makefile b/drivers/usb/imx/Makefile index e15bc71..ac17e91 100644 --- a/drivers/usb/imx/Makefile +++ b/drivers/usb/imx/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_USB_IMX_CHIPIDEA) += imx-usb-misc.o chipidea-imx.o +obj-$(CONFIG_USB_IMX_CHIPIDEA) += chipidea-imx.o +obj-$(CONFIG_USB_IMX_CHIPIDEA_USBMISC) += imx-usb-misc.o obj-$(CONFIG_USB_IMX_PHY) += imx-usb-phy.o diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index 03301d9..635be02 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -31,6 +31,10 @@ #define MXC_EHCI_PORTSC_MASK ((0xf << 28) | (1 << 25)) +struct imx_chipidea_data { + bool have_usb_misc; +}; + struct imx_chipidea { struct device_d *dev; void __iomem *base; @@ -47,13 +51,14 @@ struct clk *clk; struct ehci_host *ehci; struct fsl_udc *udc; + bool have_usb_misc; }; static int imx_chipidea_port_init(void *drvdata) { struct imx_chipidea *ci = drvdata; uint32_t portsc; - int ret; + int ret = 0; if ((ci->flags & MXC_EHCI_PORTSC_MASK) == MXC_EHCI_MODE_ULPI) { dev_dbg(ci->dev, "using ULPI phy\n"); @@ -72,9 +77,11 @@ return ret; } - ret = imx_usbmisc_port_init(ci->usbmisc, ci->portno, ci->flags); - if (ret) - dev_err(ci->dev, "misc init failed: %s\n", strerror(-ret)); + if (ci->have_usb_misc) { + ret = imx_usbmisc_port_init(ci->usbmisc, ci->portno, ci->flags); + if (ret) + dev_err(ci->dev, "misc init failed: %s\n", strerror(-ret)); + } /* PFSC bit is reset by ehci_reset(), thus have to set it not in * probe but here, after ehci_reset() is already called */ @@ -90,11 +97,13 @@ static int imx_chipidea_port_post_init(void *drvdata) { struct imx_chipidea *ci = drvdata; - int ret; + int ret = 0; - ret = imx_usbmisc_port_post_init(ci->usbmisc, ci->portno, ci->flags); - if (ret) - dev_err(ci->dev, "post misc init failed: %s\n", strerror(-ret)); + if (ci->have_usb_misc) { + ret = imx_usbmisc_port_post_init(ci->usbmisc, ci->portno, ci->flags); + if (ret) + dev_err(ci->dev, "post misc init failed: %s\n", strerror(-ret)); + } return ret; } @@ -103,15 +112,18 @@ { struct of_phandle_args out_args; - if (of_parse_phandle_with_args(ci->dev->device_node, "fsl,usbmisc", - "#index-cells", 0, &out_args)) - return -ENODEV; + if (ci->have_usb_misc) { + if (of_parse_phandle_with_args(ci->dev->device_node, "fsl,usbmisc", + "#index-cells", 0, &out_args)) + return -ENODEV; - ci->usbmisc = of_find_device_by_node(out_args.np); - if (!ci->usbmisc) - return -ENODEV; + ci->usbmisc = of_find_device_by_node(out_args.np); + if (!ci->usbmisc) + return -ENODEV; - ci->portno = out_args.args[0]; + ci->portno = out_args.args[0]; + } + ci->flags = MXC_EHCI_MODE_UTMI_8BIT; ci->mode = of_usb_get_dr_mode(ci->dev->device_node, NULL); @@ -219,6 +231,7 @@ static int imx_chipidea_probe(struct device_d *dev) { struct resource *iores; + struct imx_chipidea_data *imx_data; struct imxusb_platformdata *pdata = dev->platform_data; int ret; void __iomem *base; @@ -229,6 +242,10 @@ ci->dev = dev; dev->priv = ci; + ret = dev_get_drvdata(dev, (const void **)&imx_data); + if (!ret) + ci->have_usb_misc = imx_data->have_usb_misc; + if (IS_ENABLED(CONFIG_OFDEVICE) && dev->device_node) { ret = imx_chipidea_probe_dt(ci); if (ret) @@ -319,11 +336,24 @@ ci_udc_unregister(ci->udc); } +static const struct imx_chipidea_data imx_data = { + .have_usb_misc = 1, +}; + +static const struct imx_chipidea_data imx28_data = { + .have_usb_misc = 0, +}; + static __maybe_unused struct of_device_id imx_chipidea_dt_ids[] = { { .compatible = "fsl,imx27-usb", + .data = &imx_data, + }, { + .compatible = "fsl,imx28-usb", + .data = &imx28_data, }, { .compatible = "fsl,imx7d-usb", + .data = &imx_data, }, { /* sentinel */ }, diff --git a/drivers/usb/imx/imx-usb-phy.c b/drivers/usb/imx/imx-usb-phy.c index 069dddc..c23a747 100644 --- a/drivers/usb/imx/imx-usb-phy.c +++ b/drivers/usb/imx/imx-usb-phy.c @@ -57,6 +57,7 @@ int ret; clk_enable(imxphy->clk); + mdelay(1); ret = stmp_reset_block(imxphy->base + HW_USBPHY_CTRL, false); if (ret) diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c index 2b233ed..6ebd97e 100644 --- a/drivers/watchdog/im28wd.c +++ b/drivers/watchdog/im28wd.c @@ -229,9 +229,18 @@ free(priv); } +static __maybe_unused struct of_device_id imx28_wdt_dt_ids[] = { + { + .compatible = "fsl,stmp3xxx-rtc", + }, { + /* sentinel */ + } +}; + static struct driver_d imx28_wd_driver = { .name = "im28wd", .probe = imx28_wd_probe, .remove = imx28_wd_remove, + .of_compatible = DRV_OF_COMPAT(imx28_wdt_dt_ids), }; device_platform_driver(imx28_wd_driver); diff --git a/include/filetype.h b/include/filetype.h index c3a5bdf..3019dda 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -51,6 +51,7 @@ filetype_ubootvar, filetype_stm32_image_v1, filetype_zynq_image, + filetype_mxs_sd_image, filetype_max, }; diff --git a/include/usb/chipidea-imx.h b/include/usb/chipidea-imx.h index 5ea5fcc..dfd84a9 100644 --- a/include/usb/chipidea-imx.h +++ b/include/usb/chipidea-imx.h @@ -43,7 +43,20 @@ enum usb_dr_mode mode; }; +#ifdef CONFIG_USB_IMX_CHIPIDEA_USBMISC int imx_usbmisc_port_init(struct device_d *dev, int port, unsigned flags); int imx_usbmisc_port_post_init(struct device_d *dev, int port, unsigned flags); +#else +static inline int imx_usbmisc_port_init(struct device_d *dev, int port, + unsigned flags) +{ + return 0; +} +static inline int imx_usbmisc_port_post_init(struct device_d *dev, int port, + unsigned flags) +{ + return 0; +} +#endif #endif /* __USB_CHIPIDEA_IMX_H */