diff options
author | Tom Rini <trini@ti.com> | 2014-12-11 18:28:09 -0500 |
---|---|---|
committer | Tom Rini <trini@ti.com> | 2014-12-11 18:28:09 -0500 |
commit | 2c49323d5de38e119f102fa3f5fb291c4bc4e8a0 (patch) | |
tree | f64ddb2b5c393f6fac9a54dc98ea72c118922d70 /drivers | |
parent | 9b416a9f4ca7cf5ac4d5f7143d67edde7f7d7326 (diff) | |
parent | d0419f400af6f4bbe5c4ee5c97f6fbbdedec6cf3 (diff) | |
download | u-boot-imx-2c49323d5de38e119f102fa3f5fb291c4bc4e8a0.zip u-boot-imx-2c49323d5de38e119f102fa3f5fb291c4bc4e8a0.tar.gz u-boot-imx-2c49323d5de38e119f102fa3f5fb291c4bc4e8a0.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ddr/fsl/arm_ddr_gen3.c | 45 | ||||
-rw-r--r-- | drivers/ddr/fsl/fsl_ddr_gen4.c | 44 | ||||
-rw-r--r-- | drivers/ddr/fsl/mpc85xx_ddr_gen3.c | 67 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_spl.c | 10 | ||||
-rw-r--r-- | drivers/pci/Makefile | 1 | ||||
-rw-r--r-- | drivers/pci/pcie_layerscape.c | 51 | ||||
-rw-r--r-- | drivers/usb/host/ehci-fsl.c | 186 |
8 files changed, 352 insertions, 54 deletions
diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c index 59f2fd6..c139da6 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -92,7 +92,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0); ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1); ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2); - ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode); ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); @@ -105,9 +104,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); - ddr_out32(&ddr->init_addr, regs->ddr_init_addr); - ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); - ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4); ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5); ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl); @@ -128,7 +124,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2); ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1); - ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + ddr_out32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE); + ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA); + + /* DRAM VRef will not be trained */ + ddr_out32(&ddr->ddr_cdr2, + regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); + } else +#endif + { + ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); + ddr_out32(&ddr->init_addr, regs->ddr_init_addr); + ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); + ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); + } ddr_out32(&ddr->err_disable, regs->err_disable); ddr_out32(&ddr->err_int_en, regs->err_int_en); for (i = 0; i < 32; i++) { @@ -167,8 +180,20 @@ step2: udelay(500); asm volatile("dsb sy;isb"); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + /* enter self-refresh */ + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); + temp_sdram_cfg |= SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + /* do board specific memory setup */ + board_mem_sleep_setup(); + + temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); + } else +#endif + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; /* Let the controller go */ - temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); asm volatile("dsb sy;isb"); @@ -211,4 +236,12 @@ step2: if (timeout <= 0) printf("Waiting for D_INIT timeout. Memory may not work.\n"); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + /* exit self-refresh */ + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); + temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + } +#endif } diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index e024db9..a3c01e7 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -103,7 +103,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->dq_map_1, regs->dq_map_1); ddr_out32(&ddr->dq_map_2, regs->dq_map_2); ddr_out32(&ddr->dq_map_3, regs->dq_map_3); - ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); ddr_out32(&ddr->sdram_cfg_3, regs->ddr_sdram_cfg_3); ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode); ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); @@ -124,8 +123,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl); ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval); ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init); - ddr_out32(&ddr->init_addr, regs->ddr_init_addr); - ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl); #ifndef CONFIG_SYS_FSL_DDR_EMU /* @@ -147,7 +144,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, ddr_out32(&ddr->ddr_sdram_rcw_5, regs->ddr_sdram_rcw_5); ddr_out32(&ddr->ddr_sdram_rcw_6, regs->ddr_sdram_rcw_6); ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1); - ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + ddr_out32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + ddr_out32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE); + ddr_out32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA); + + /* DRAM VRef will not be trained */ + ddr_out32(&ddr->ddr_cdr2, + regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); + } else +#endif + { + ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); + ddr_out32(&ddr->init_addr, regs->ddr_init_addr); + ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); + ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2); + } ddr_out32(&ddr->err_disable, regs->err_disable); ddr_out32(&ddr->err_int_en, regs->err_int_en); for (i = 0; i < 32; i++) { @@ -187,8 +201,20 @@ step2: mb(); isb(); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + /* enter self-refresh */ + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); + temp_sdram_cfg |= SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + /* do board specific memory setup */ + board_mem_sleep_setup(); + + temp_sdram_cfg = (ddr_in32(&ddr->sdram_cfg) | SDRAM_CFG_BI); + } else +#endif + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; /* Let the controller go */ - temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI; ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); mb(); isb(); @@ -233,4 +259,12 @@ step2: if (timeout <= 0) printf("Waiting for D_INIT timeout. Memory may not work.\n"); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + /* exit self-refresh */ + temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg_2); + temp_sdram_cfg &= ~SDRAM_CFG2_FRC_SR; + ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg); + } +#endif } diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index 4d5572e..8f4d01a 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -15,8 +15,6 @@ #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL #endif -DECLARE_GLOBAL_DATA_PTR; - /* * regs has the to-be-set values for DDR controller registers * ctrl_num is the DDR controller number @@ -44,16 +42,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, u32 save1, save2; #endif -#ifdef CONFIG_DEEP_SLEEP - const ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); - bool sleep_flag = 0; -#endif - -#ifdef CONFIG_DEEP_SLEEP - if (in_be32(&gur->scrtsr[0]) & (1 << 3)) - sleep_flag = 1; -#endif - switch (ctrl_num) { case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; @@ -130,13 +118,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0); out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1); out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2); -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) - out_be32(&ddr->sdram_cfg_2, - regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); - else -#endif - out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode); out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2); out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3); @@ -149,17 +130,6 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval); out_be32(&ddr->sdram_data_init, regs->ddr_data_init); out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl); -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) { - out_be32(&ddr->init_addr, 0); - out_be32(&ddr->init_ext_addr, (1 << 31)); - } else -#endif - { - out_be32(&ddr->init_addr, regs->ddr_init_addr); - out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); - } - out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4); out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5); out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl); @@ -180,7 +150,24 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1); out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2); out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1); - out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2); +#ifdef CONFIG_DEEP_SLEEP + if (is_warm_boot()) { + out_be32(&ddr->sdram_cfg_2, + regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT); + out_be32(&ddr->init_addr, CONFIG_SYS_SDRAM_BASE); + out_be32(&ddr->init_ext_addr, DDR_INIT_ADDR_EXT_UIA); + + /* DRAM VRef will not be trained */ + out_be32(&ddr->ddr_cdr2, + regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN); + } else +#endif + { + out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2); + out_be32(&ddr->init_addr, regs->ddr_init_addr); + out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr); + out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2); + } out_be32(&ddr->err_disable, regs->err_disable); out_be32(&ddr->err_int_en, regs->err_int_en); for (i = 0; i < 32; i++) { @@ -400,21 +387,17 @@ step2: asm volatile("sync;isync"); #ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) { + if (is_warm_boot()) { /* enter self-refresh */ - setbits_be32(&ddr->sdram_cfg_2, (1 << 31)); + setbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); /* do board specific memory setup */ board_mem_sleep_setup(); - } -#endif - - /* Let the controller go */ -#ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) | SDRAM_CFG_BI); - else + } else #endif temp_sdram_cfg = (in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI); + + /* Let the controller go */ out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN); asm volatile("sync;isync"); @@ -566,8 +549,8 @@ step2: } #endif /* CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134 */ #ifdef CONFIG_DEEP_SLEEP - if (sleep_flag) + if (is_warm_boot()) /* exit self-refresh */ - clrbits_be32(&ddr->sdram_cfg_2, (1 << 31)); + clrbits_be32(&ddr->sdram_cfg_2, SDRAM_CFG2_FRC_SR); #endif } diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 81b5070..b283eae 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -292,7 +292,7 @@ static int fsl_ifc_run_command(struct mtd_info *mtd) struct fsl_ifc *ifc = ctrl->regs; u32 timeo = (CONFIG_SYS_HZ * 10) / 1000; u32 time_start; - u32 eccstat[4]; + u32 eccstat[4] = {0}; int i; /* set the chip select for NAND Transaction */ diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c index e336cb1..fb827c5 100644 --- a/drivers/mtd/nand/fsl_ifc_spl.c +++ b/drivers/mtd/nand/fsl_ifc_spl.c @@ -254,3 +254,13 @@ void nand_boot(void) uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; uboot(); } + +#ifndef CONFIG_SPL_NAND_INIT +void nand_init(void) +{ +} + +void nand_deselect(void) +{ +} +#endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 55d6a9b..85e82bd 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o obj-$(CONFIG_WINBOND_83C553) += w83c553f.o +obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c new file mode 100644 index 0000000..291c249 --- /dev/null +++ b/drivers/pci/pcie_layerscape.c @@ -0,0 +1,51 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Layerscape PCIe driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <pci.h> +#include <asm/io.h> +#include <asm/pcie_layerscape.h> + +#ifdef CONFIG_OF_BOARD_SETUP +#include <libfdt.h> +#include <fdt_support.h> + +static void ft_pcie_ls_setup(void *blob, const char *pci_compat, + unsigned long ctrl_addr, enum srds_prtcl dev) +{ + int off; + + off = fdt_node_offset_by_compat_reg(blob, pci_compat, + (phys_addr_t)ctrl_addr); + if (off < 0) + return; + + if (!is_serdes_configured(dev)) + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); +} + +void ft_pcie_setup(void *blob, bd_t *bd) +{ + #ifdef CONFIG_PCIE1 + ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE1_ADDR, PCIE1); + #endif + + #ifdef CONFIG_PCIE2 + ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2); + #endif +} + +#else +void ft_pcie_setup(void *blob, bd_t *bd) +{ +} +#endif + +void pci_init_board(void) +{ +} diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 8f55464..5d4288d 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -15,9 +15,14 @@ #include <usb/ehci-fsl.h> #include <hwconfig.h> #include <fsl_usb.h> +#include <fdt_support.h> #include "ehci.h" +#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT +#define CONFIG_USB_MAX_CONTROLLER_COUNT 1 +#endif + static void set_txfifothresh(struct usb_ehci *, u32); /* Check USB PHY clock valid */ @@ -158,3 +163,184 @@ static void set_txfifothresh(struct usb_ehci *ehci, u32 txfifo_thresh) cmd |= TXFIFO_THRESH(txfifo_thresh); ehci_writel(&ehci->txfilltuning, cmd); } + +#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB) +static int fdt_fixup_usb_mode_phy_type(void *blob, const char *mode, + const char *phy_type, int start_offset) +{ + const char *compat_dr = "fsl-usb2-dr"; + const char *compat_mph = "fsl-usb2-mph"; + const char *prop_mode = "dr_mode"; + const char *prop_type = "phy_type"; + const char *node_type = NULL; + int node_offset; + int err; + + node_offset = fdt_node_offset_by_compatible(blob, + start_offset, compat_mph); + if (node_offset < 0) { + node_offset = fdt_node_offset_by_compatible(blob, + start_offset, + compat_dr); + if (node_offset < 0) { + printf("WARNING: could not find compatible node: %s", + fdt_strerror(node_offset)); + return -1; + } + node_type = compat_dr; + } else { + node_type = compat_mph; + } + + if (mode) { + err = fdt_setprop(blob, node_offset, prop_mode, mode, + strlen(mode) + 1); + if (err < 0) + printf("WARNING: could not set %s for %s: %s.\n", + prop_mode, node_type, fdt_strerror(err)); + } + + if (phy_type) { + err = fdt_setprop(blob, node_offset, prop_type, phy_type, + strlen(phy_type) + 1); + if (err < 0) + printf("WARNING: could not set %s for %s: %s.\n", + prop_type, node_type, fdt_strerror(err)); + } + + return node_offset; +} + +static const char *fdt_usb_get_node_type(void *blob, int start_offset, + int *node_offset) +{ + const char *compat_dr = "fsl-usb2-dr"; + const char *compat_mph = "fsl-usb2-mph"; + const char *node_type = NULL; + + *node_offset = fdt_node_offset_by_compatible(blob, start_offset, + compat_mph); + if (*node_offset < 0) { + *node_offset = fdt_node_offset_by_compatible(blob, + start_offset, + compat_dr); + if (*node_offset < 0) { + printf("ERROR: could not find compatible node: %s\n", + fdt_strerror(*node_offset)); + } else { + node_type = compat_dr; + } + } else { + node_type = compat_mph; + } + + return node_type; +} + +static int fdt_fixup_usb_erratum(void *blob, const char *prop_erratum, + int start_offset) +{ + int node_offset, err; + const char *node_type = NULL; + + node_type = fdt_usb_get_node_type(blob, start_offset, &node_offset); + if (!node_type) + return -1; + + err = fdt_setprop(blob, node_offset, prop_erratum, NULL, 0); + if (err < 0) { + printf("ERROR: could not set %s for %s: %s.\n", + prop_erratum, node_type, fdt_strerror(err)); + } + + return node_offset; +} + +void fdt_fixup_dr_usb(void *blob, bd_t *bd) +{ + static const char * const modes[] = { "host", "peripheral", "otg" }; + static const char * const phys[] = { "ulpi", "utmi" }; + int usb_erratum_a006261_off = -1; + int usb_erratum_a007075_off = -1; + int usb_erratum_a007792_off = -1; + int usb_mode_off = -1; + int usb_phy_off = -1; + char str[5]; + int i, j; + + for (i = 1; i <= CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { + const char *dr_mode_type = NULL; + const char *dr_phy_type = NULL; + int mode_idx = -1, phy_idx = -1; + + snprintf(str, 5, "%s%d", "usb", i); + if (hwconfig(str)) { + for (j = 0; j < ARRAY_SIZE(modes); j++) { + if (hwconfig_subarg_cmp(str, "dr_mode", + modes[j])) { + mode_idx = j; + break; + } + } + + for (j = 0; j < ARRAY_SIZE(phys); j++) { + if (hwconfig_subarg_cmp(str, "phy_type", + phys[j])) { + phy_idx = j; + break; + } + } + + if (mode_idx < 0 && phy_idx < 0) { + printf("WARNING: invalid phy or mode\n"); + return; + } + + if (mode_idx > -1) + dr_mode_type = modes[mode_idx]; + + if (phy_idx > -1) + dr_phy_type = phys[phy_idx]; + } + + usb_mode_off = fdt_fixup_usb_mode_phy_type(blob, + dr_mode_type, NULL, + usb_mode_off); + + if (usb_mode_off < 0) + return; + + usb_phy_off = fdt_fixup_usb_mode_phy_type(blob, + NULL, dr_phy_type, + usb_phy_off); + + if (usb_phy_off < 0) + return; + + if (has_erratum_a006261()) { + usb_erratum_a006261_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a006261", + usb_erratum_a006261_off); + if (usb_erratum_a006261_off < 0) + return; + } + if (has_erratum_a007075()) { + usb_erratum_a007075_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a007075", + usb_erratum_a007075_off); + if (usb_erratum_a007075_off < 0) + return; + } + if (has_erratum_a007792()) { + usb_erratum_a007792_off = fdt_fixup_usb_erratum + (blob, + "fsl,usb-erratum-a007792", + usb_erratum_a007792_off); + if (usb_erratum_a007792_off < 0) + return; + } + } +} +#endif |