From: Alison Wang Date: Wed, 6 Mar 2019 06:49:14 +0000 (+0800) Subject: armv7: ls102xa: Add workaround for DDR erratum A-008850 X-Git-Url: http://git.dujemihanovic.xyz/img/static/git-favicon.png?a=commitdiff_plain;h=158097052a6a528408e05d2345ff2ccdbb46036e;p=u-boot.git armv7: ls102xa: Add workaround for DDR erratum A-008850 Barrier transactions from CCI400 need to be disabled till the DDR is configured, otherwise it may lead to system hang. The patch adds workaround to fix the erratum. Signed-off-by: Shengzhou Liu Signed-off-by: Alison Wang Reviewed-by: Prabhakar Kushwaha --- diff --git a/arch/arm/cpu/armv7/ls102xa/Kconfig b/arch/arm/cpu/armv7/ls102xa/Kconfig index 5d6a711c14..94fa68250d 100644 --- a/arch/arm/cpu/armv7/ls102xa/Kconfig +++ b/arch/arm/cpu/armv7/ls102xa/Kconfig @@ -4,6 +4,7 @@ config ARCH_LS1021A select SYS_FSL_DDR_VER_50 if SYS_FSL_DDR select SYS_FSL_ERRATUM_A008378 select SYS_FSL_ERRATUM_A008407 + select SYS_FSL_ERRATUM_A008850 select SYS_FSL_ERRATUM_A008997 select SYS_FSL_ERRATUM_A009007 select SYS_FSL_ERRATUM_A009008 @@ -63,6 +64,11 @@ config SYS_CCI400_OFFSET Offset for CCI400 base. CCI400 base addr = CCSRBAR + CCI400_OFFSET +config SYS_FSL_ERRATUM_A008850 + bool + help + Workaround for DDR erratum A008850 + config SYS_FSL_ERRATUM_A008997 bool help diff --git a/arch/arm/cpu/armv7/ls102xa/soc.c b/arch/arm/cpu/armv7/ls102xa/soc.c index 448d951c36..a779d33739 100644 --- a/arch/arm/cpu/armv7/ls102xa/soc.c +++ b/arch/arm/cpu/armv7/ls102xa/soc.c @@ -11,6 +11,7 @@ #include #include #include +#include struct liodn_id_table sec_liodn_tbl[] = { SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10), @@ -103,6 +104,41 @@ static void erratum_a009007(void) #endif /* CONFIG_SYS_FSL_ERRATUM_A009007 */ } +static void erratum_a008850_early(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008850 + /* part 1 of 2 */ + struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + + /* disables propagation of barrier transactions to DDRC from CCI400 */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + + /* disable the re-ordering in DDRC */ + out_be32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS); +#endif +} + +void erratum_a008850_post(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008850 + /* part 2 of 2 */ + struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + u32 tmp; + + /* enable propagation of barrier transactions to DDRC from CCI400 */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + + /* enable the re-ordering in DDRC */ + tmp = in_be32(&ddr->eor); + tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS); + out_be32(&ddr->eor, tmp); +#endif +} + void s_init(void) { } @@ -163,13 +199,6 @@ int arch_soc_init(void) */ out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); - - /* Workaround for the issue that DDR could not respond to - * barrier transaction which is generated by executing DSB/ISB - * instruction. Set CCI-400 control override register to - * terminate the barrier transaction. After DDR is initialized, - * allow barrier transaction to DDR again */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); } /* Enable all the snoop signal for various masters */ @@ -191,6 +220,7 @@ int arch_soc_init(void) out_be32(&scfg->eddrtqcfg, 0x63b20042); /* Erratum */ + erratum_a008850_early(); erratum_a009008(); erratum_a009798(); erratum_a008997(); diff --git a/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h b/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h index 05e8b49c2d..1fde8bce5d 100644 --- a/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h +++ b/arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h @@ -10,6 +10,8 @@ unsigned int get_soc_major_rev(void); int arch_soc_init(void); int ls102xa_smmu_stream_id_init(void); +void erratum_a008850_post(void); + #ifdef CONFIG_SYS_FSL_ERRATUM_A010315 void erratum_a010315(void); #endif diff --git a/board/freescale/ls1021aiot/ls1021aiot.c b/board/freescale/ls1021aiot/ls1021aiot.c index fb05b55b5c..70992a5ce4 100644 --- a/board/freescale/ls1021aiot/ls1021aiot.c +++ b/board/freescale/ls1021aiot/ls1021aiot.c @@ -97,6 +97,8 @@ int dram_init(void) ddrmc_init(); #endif + erratum_a008850_post(); + gd->ram_size = DDR_SIZE; return 0; } diff --git a/board/freescale/ls1021aqds/ddr.c b/board/freescale/ls1021aqds/ddr.c index 98faf9389e..d3e2e53321 100644 --- a/board/freescale/ls1021aqds/ddr.c +++ b/board/freescale/ls1021aqds/ddr.c @@ -179,6 +179,8 @@ int fsl_initdram(void) fsl_dp_resume(); #endif + erratum_a008850_post(); + gd->ram_size = dram_size; return 0; diff --git a/board/freescale/ls1021aqds/ddr.h b/board/freescale/ls1021aqds/ddr.h index ff1fe8e2ec..58a8838436 100644 --- a/board/freescale/ls1021aqds/ddr.h +++ b/board/freescale/ls1021aqds/ddr.h @@ -5,6 +5,9 @@ #ifndef __DDR_H__ #define __DDR_H__ + +void erratum_a008850_post(void); + struct board_specific_parameters { u32 n_ranks; u32 datarate_mhz_high; diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c index c08be1ee46..2ca2bd9909 100644 --- a/board/freescale/ls1021aqds/ls1021aqds.c +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -200,10 +200,6 @@ int board_early_init_f(void) #ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + - CONFIG_SYS_CCI400_OFFSET); - unsigned int major; - #ifdef CONFIG_NAND_BOOT struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; u32 porsr1, pinctl; @@ -240,10 +236,6 @@ void board_init_f(ulong dummy) i2c_init_all(); #endif - major = get_soc_major_rev(); - if (major == SOC_MAJOR_VER_1_0) - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); - timer_init(); dram_init(); @@ -420,22 +412,12 @@ int misc_init_r(void) int board_init(void) { - struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + - CONFIG_SYS_CCI400_OFFSET); - unsigned int major; - #ifdef CONFIG_SYS_FSL_ERRATUM_A010315 erratum_a010315(); #endif #ifdef CONFIG_SYS_FSL_ERRATUM_A009942 erratum_a009942_check_cpo(); #endif - major = get_soc_major_rev(); - if (major == SOC_MAJOR_VER_1_0) { - /* Set CCI-400 control override register to - * enable barrier transaction */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); - } select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); @@ -456,18 +438,6 @@ int board_init(void) #if defined(CONFIG_DEEP_SLEEP) void board_sleep_prepare(void) { - struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + - CONFIG_SYS_CCI400_OFFSET); - unsigned int major; - - major = get_soc_major_rev(); - if (major == SOC_MAJOR_VER_1_0) { - /* Set CCI-400 control override register to - * enable barrier transaction */ - out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); - } - - #ifdef CONFIG_LAYERSCAPE_NS_ACCESS enable_layerscape_ns_access(); #endif diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index beb82cebb6..01ba1bc962 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -222,6 +222,8 @@ int dram_init(void) ddrmc_init(); #endif + erratum_a008850_post(); + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); #if defined(CONFIG_DEEP_SLEEP) && !defined(CONFIG_SPL_BUILD) diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index 6be8df109b..4af3988886 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -85,6 +85,8 @@ #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL #define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 + /* * Serial Port */ diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 4b6760b600..da55bf2f43 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -104,6 +104,8 @@ #define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL #define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 + #if !defined(CONFIG_SD_BOOT) && !defined(CONFIG_NAND_BOOT) && \ !defined(CONFIG_QSPI_BOOT) #define CONFIG_SYS_QE_FMAN_FW_IN_NOR