diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/am33xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/emif-common.c | 53 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap5/dra7xx_iodelay.c | 11 |
3 files changed, 42 insertions, 23 deletions
diff --git a/arch/arm/mach-omap2/am33xx/Kconfig b/arch/arm/mach-omap2/am33xx/Kconfig index 7f6b344c82..39d9c2873b 100644 --- a/arch/arm/mach-omap2/am33xx/Kconfig +++ b/arch/arm/mach-omap2/am33xx/Kconfig @@ -89,6 +89,7 @@ config TARGET_AM335X_SHC config TARGET_AM335X_GUARDIAN bool "Support am335x based guardian board from bosch" + select BOARD_LATE_INIT select DM select DM_SERIAL select DM_GPIO diff --git a/arch/arm/mach-omap2/emif-common.c b/arch/arm/mach-omap2/emif-common.c index b384343a3f..290f9dcdb0 100644 --- a/arch/arm/mach-omap2/emif-common.c +++ b/arch/arm/mach-omap2/emif-common.c @@ -348,52 +348,63 @@ static void dra7_reset_ddr_data(u32 base, u32 size) static void dra7_enable_ecc(u32 base, const struct emif_regs *regs) { struct emif_reg_struct *emif = (struct emif_reg_struct *)base; - u32 rgn, size; + u32 rgn, rgn_start, size, ctrl_reg; /* ECC available only on dra76x EMIF1 */ if ((base != EMIF1_BASE) || !is_dra76x()) return; if (regs->emif_ecc_ctrl_reg & EMIF_ECC_CTRL_REG_ECC_EN_MASK) { + /* Disable high-order interleaving */ + clrbits_le32(MA_PRIORITY, MA_HIMEM_INTERLEAVE_UN_MASK); + +#ifdef CONFIG_DRA7XX + /* Clear the status flags and other history */ + writel(readl(&emif->emif_1b_ecc_err_cnt), + &emif->emif_1b_ecc_err_cnt); + writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1); + writel(0x2, &emif->emif_1b_ecc_err_addr_log); + writel(0x1, &emif->emif_2b_ecc_err_addr_log); + writel(EMIF_INT_WR_ECC_ERR_SYS_MASK | + EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK | + EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK, + &emif->emif_irqstatus_sys); +#endif writel(regs->emif_ecc_address_range_1, &emif->emif_ecc_address_range_1); writel(regs->emif_ecc_address_range_2, &emif->emif_ecc_address_range_2); - writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg); + + /* Disable RMW and ECC verification for read accesses */ + ctrl_reg = (regs->emif_ecc_ctrl_reg & + ~EMIF_ECC_REG_RMW_EN_MASK) | + EMIF_ECC_CTRL_REG_ECC_VERIFY_DIS_MASK; + writel(ctrl_reg, &emif->emif_ecc_ctrl_reg); /* Set region1 memory with 0 */ - rgn = ((regs->emif_ecc_address_range_1 & - EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) + - CONFIG_SYS_SDRAM_BASE; + rgn_start = (regs->emif_ecc_address_range_1 & + EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16; + rgn = rgn_start + CONFIG_SYS_SDRAM_BASE; size = (regs->emif_ecc_address_range_1 & - EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000; + EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start; if (regs->emif_ecc_ctrl_reg & EMIF_ECC_REG_ECC_ADDR_RGN_1_EN_MASK) dra7_reset_ddr_data(rgn, size); /* Set region2 memory with 0 */ - rgn = ((regs->emif_ecc_address_range_2 & - EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16) + - CONFIG_SYS_SDRAM_BASE; + rgn_start = (regs->emif_ecc_address_range_2 & + EMIF_ECC_REG_ECC_START_ADDR_MASK) << 16; + rgn = rgn_start + CONFIG_SYS_SDRAM_BASE; size = (regs->emif_ecc_address_range_2 & - EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000; + EMIF_ECC_REG_ECC_END_ADDR_MASK) + 0x10000 - rgn_start; if (regs->emif_ecc_ctrl_reg & EMIF_ECC_REG_ECC_ADDR_RGN_2_EN_MASK) dra7_reset_ddr_data(rgn, size); -#ifdef CONFIG_DRA7XX - /* Clear the status flags and other history */ - writel(readl(&emif->emif_1b_ecc_err_cnt), - &emif->emif_1b_ecc_err_cnt); - writel(0xffffffff, &emif->emif_1b_ecc_err_dist_1); - writel(0x1, &emif->emif_2b_ecc_err_addr_log); - writel(EMIF_INT_WR_ECC_ERR_SYS_MASK | - EMIF_INT_TWOBIT_ECC_ERR_SYS_MASK | - EMIF_INT_ONEBIT_ECC_ERR_SYS_MASK, - &emif->emif_irqstatus_sys); -#endif + /* Default value enables RMW and ECC verification */ + writel(regs->emif_ecc_ctrl_reg, &emif->emif_ecc_ctrl_reg); } } diff --git a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c index e2abb7d058..9eda57c450 100644 --- a/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c +++ b/arch/arm/mach-omap2/omap5/dra7xx_iodelay.c @@ -202,8 +202,9 @@ void __recalibrate_iodelay_end(int ret) return; } - if (!ret) - ret = isolate_io(DEISOLATE_IO); + /* Deisolate IO if it is already isolated */ + if (readl((*ctrl)->ctrl_core_sma_sw_0) & CTRL_ISOLATE_MASK) + isolate_io(DEISOLATE_IO); /* lock IODELAY CONFIG registers */ writel(CFG_IODELAY_LOCK_KEY, (*ctrl)->iodelay_config_base + @@ -240,6 +241,12 @@ void __recalibrate_iodelay_end(int ret) debug("IODELAY: IO delay recalibration successfully completed\n"); } + /* If there is an error during iodelay recalibration, SoC is in a bad + * state. Do not progress any further. + */ + if (ret) + hang(); + return; } |