diff options
author | Alison Wang <alison.wang@nxp.com> | 2019-03-06 14:49:14 +0800 |
---|---|---|
committer | Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> | 2019-03-15 11:52:01 +0530 |
commit | 158097052a6a528408e05d2345ff2ccdbb46036e (patch) | |
tree | 78453d3d716aef5368b91a620203c0487fe6f378 /arch/arm/cpu/armv7/ls102xa/soc.c | |
parent | ba7eadd8e107202ab90d0b2937044b6dcba4b7ae (diff) |
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 <Shengzhou.Liu@nxp.com>
Signed-off-by: Alison Wang <alison.wang@nxp.com>
Reviewed-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Diffstat (limited to 'arch/arm/cpu/armv7/ls102xa/soc.c')
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/soc.c | 44 |
1 files changed, 37 insertions, 7 deletions
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 <asm/arch/ls102xa_soc.h> #include <asm/arch/ls102xa_stream_id.h> #include <fsl_csu.h> +#include <fsl_ddr_sdram.h> 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(); |