[U-Boot] [PATCH] armv7: ls102xa: Add workaround for DDR erratum A-008850

Alison Wang alison.wang at nxp.com
Wed Mar 6 06:49:14 UTC 2019


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 at nxp.com>
Signed-off-by: Alison Wang <alison.wang at nxp.com>
---
 arch/arm/cpu/armv7/ls102xa/Kconfig            |  6 +++
 arch/arm/cpu/armv7/ls102xa/soc.c              | 44 ++++++++++++++++---
 .../include/asm/arch-ls102xa/ls102xa_soc.h    |  2 +
 board/freescale/ls1021aiot/ls1021aiot.c       |  2 +
 board/freescale/ls1021aqds/ddr.c              |  2 +
 board/freescale/ls1021aqds/ddr.h              |  3 ++
 board/freescale/ls1021aqds/ls1021aqds.c       | 30 -------------
 board/freescale/ls1021atwr/ls1021atwr.c       |  2 +
 include/configs/ls1021aiot.h                  |  2 +
 include/configs/ls1021atwr.h                  |  2 +
 10 files changed, 58 insertions(+), 37 deletions(-)

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 <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();
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 10dc0c6843..5c4650b254 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 1a833e22dd..ba41000957 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
-- 
2.17.1



More information about the U-Boot mailing list