ddr: Rework errata A008109, A008378, 009942 workaround

Move errata A008109, A008378, 009942 workaround implementation from
compute_fsl_memctl_config_regs() to  fsl_ddr_set_memctl_regs()
and add register write after each workaround implementation.

Signed-off-by: Jaiprakash Singh <Jaiprakash.singh@nxp.com>
Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com>
diff --git a/arch/powerpc/cpu/mpc85xx/Kconfig b/arch/powerpc/cpu/mpc85xx/Kconfig
index 5bd69d5..285cc56 100644
--- a/arch/powerpc/cpu/mpc85xx/Kconfig
+++ b/arch/powerpc/cpu/mpc85xx/Kconfig
@@ -996,6 +996,7 @@
 	select FSL_LAW
 	select SYS_FSL_DDR_VER_50
 	select SYS_FSL_ERRATUM_A008378
+	select SYS_FSL_ERRATUM_A008109
 	select SYS_FSL_ERRATUM_A009663
 	select SYS_FSL_ERRATUM_A009942
 	select SYS_FSL_ERRATUM_ESDHC111
@@ -1016,6 +1017,7 @@
 	select FSL_LAW
 	select SYS_FSL_DDR_VER_50
 	select SYS_FSL_ERRATUM_A008378
+	select SYS_FSL_ERRATUM_A008109
 	select SYS_FSL_ERRATUM_A009663
 	select SYS_FSL_ERRATUM_A009942
 	select SYS_FSL_ERRATUM_ESDHC111
@@ -1091,6 +1093,7 @@
 	select SYS_FSL_ERRATUM_A007212
 	select SYS_FSL_ERRATUM_A007815
 	select SYS_FSL_ERRATUM_A007907
+	select SYS_FSL_ERRATUM_A008109
 	select SYS_FSL_ERRATUM_A009942
 	select SYS_FSL_ERRATUM_ESDHC111
 	select FSL_PCIE_RESET
@@ -1169,6 +1172,7 @@
 	select SYS_FSL_ERRATUM_A007798
 	select SYS_FSL_ERRATUM_A007815
 	select SYS_FSL_ERRATUM_A007907
+	select SYS_FSL_ERRATUM_A008109
 	select SYS_FSL_ERRATUM_A009942
 	select SYS_FSL_HAS_DDR3
 	select SYS_FSL_HAS_SEC
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 0e98ba4..c849ef3 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2008-2016 Freescale Semiconductor, Inc.
- * Copyright 2017-2018 NXP Semiconductor
+ * Copyright 2017-2020 NXP Semiconductor
  */
 
 /*
@@ -2363,38 +2363,6 @@
 	unsigned int ip_rev = 0;
 	unsigned int unq_mrs_en = 0;
 	int cs_en = 1;
-#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
-	unsigned int ddr_freq;
-#endif
-#if (defined(CONFIG_SYS_FSL_ERRATUM_A008378) && \
-	defined(CONFIG_SYS_FSL_DDRC_GEN4)) || \
-	defined(CONFIG_SYS_FSL_ERRATUM_A009942)
-	struct ccsr_ddr __iomem *ddrc;
-
-	switch (ctrl_num) {
-	case 0:
-		ddrc = (void *)CONFIG_SYS_FSL_DDR_ADDR;
-		break;
-#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
-	case 1:
-		ddrc = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
-		break;
-#endif
-#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
-	case 2:
-		ddrc = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
-		break;
-#endif
-#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
-	case 3:
-		ddrc = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
-		break;
-#endif
-	default:
-		printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
-		return 1;
-	}
-#endif
 
 	memset(ddr, 0, sizeof(fsl_ddr_cfg_regs_t));
 
@@ -2615,37 +2583,7 @@
 		ddr->debug[2] |= 0x00000200;	/* set bit 22 */
 #endif
 
-#if defined(CONFIG_SYS_FSL_ERRATUM_A008378) && defined(CONFIG_SYS_FSL_DDRC_GEN4)
-	/* Erratum applies when accumulated ECC is used, or DBI is enabled */
-#define IS_ACC_ECC_EN(v) ((v) & 0x4)
-#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2)
-	if (has_erratum_a008378()) {
-		if (IS_ACC_ECC_EN(ddr->ddr_sdram_cfg) ||
-		    IS_DBI(ddr->ddr_sdram_cfg_3)) {
-			ddr->debug[28] = ddr_in32(&ddrc->debug[28]);
-			ddr->debug[28] |= (0x9 << 20);
-		}
-	}
-#endif
-
-#ifdef CONFIG_SYS_FSL_ERRATUM_A008109
-	ddr->ddr_sdram_cfg_2 = ddr_in32(&ddr->ddr_sdram_cfg_2) | 0x800; /* DDR_SLOW */
-	ddr->debug[18] = ddr_in32(&ddrc->debug[18]) | 0x2;
-	ddr->debug[28] = 0x30000000;
-#endif
-
 #ifdef CONFIG_SYS_FSL_ERRATUM_A009942
-	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
-	ddr->debug[28] |= ddr_in32(&ddrc->debug[28]);
-	ddr->debug[28] &= 0xff0fff00;
-	if (ddr_freq <= 1333)
-		ddr->debug[28] |= 0x0080006a;
-	else if (ddr_freq <= 1600)
-		ddr->debug[28] |= 0x0070006f;
-	else if (ddr_freq <= 1867)
-		ddr->debug[28] |= 0x00700076;
-	else if (ddr_freq <= 2133)
-		ddr->debug[28] |= 0x0060007b;
 	if (popts->cpo_sample)
 		ddr->debug[28] = (ddr->debug[28] & 0xffffff00) |
 				  popts->cpo_sample;
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index eab5b82..e43c680 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * Copyright 2014-2015 Freescale Semiconductor, Inc.
+ * Copyright 2014-2020 Freescale Semiconductor, Inc.
  */
 
 #include <common.h>
@@ -73,6 +73,15 @@
 #ifdef CONFIG_FSL_DDR_BIST
 	char buffer[CONFIG_SYS_CBSIZE];
 #endif
+#if defined(CONFIG_SYS_FSL_ERRATUM_A009942) || \
+	(defined(CONFIG_SYS_FSL_ERRATUM_A008378) && \
+	defined(CONFIG_SYS_FSL_DDRC_GEN4)) || \
+	defined(CONFIG_SYS_FSL_ERRATUM_A008109)
+	u32 val32;
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
+	unsigned int ddr_freq;
+#endif
 	switch (ctrl_num) {
 	case 0:
 		ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
@@ -437,6 +446,49 @@
 	ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
 #endif
 
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008378) && defined(CONFIG_SYS_FSL_DDRC_GEN4)
+	/* Erratum applies when accumulated ECC is used, or DBI is enabled */
+#define IS_ACC_ECC_EN(v) ((v) & 0x4)
+#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2)
+	if (has_erratum_a008378()) {
+		if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) ||
+		    IS_DBI(regs->ddr_sdram_cfg_3)) {
+			val32 = ddr_in32(&ddr->debug[28]);
+			val32 |= (0x9 << 20);
+			ddr_out32(&ddr->debug[28], val32);
+		}
+		debug("Applied errata CONFIG_SYS_FSL_ERRATUM_A008378\n");
+	}
+#endif
+
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008109)
+	val32 = ddr_in32(&ddr->sdram_cfg_2) | 0x800; /* DDR_SLOW */
+	ddr_out32(&ddr->sdram_cfg_2, val32);
+
+	val32 = ddr_in32(&ddr->debug[18]) | 0x2;
+	ddr_out32(&ddr->debug[18], val32);
+
+	ddr_out32(&ddr->debug[28], 0x30000000);
+	debug("Applied errta CONFIG_SYS_FSL_ERRATUM_A008109\n");
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
+	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
+	val32 = ddr_in32(&ddr->debug[28]);
+	val32 &= 0xff0fff00;
+	if (ddr_freq <= 1333)
+		val32 |= 0x0080006a;
+	else if (ddr_freq <= 1600)
+		val32 |= 0x0070006f;
+	else if (ddr_freq <= 1867)
+		val32 |= 0x00700076;
+	else if (ddr_freq <= 2133)
+		val32 |= 0x0060007b;
+
+	ddr_out32(&ddr->debug[28], val32);
+	debug("Applied errata CONFIG_SYS_FSL_ERRATUM_A009942\n");
+#endif
+
 	total_gb_size_per_controller = 0;
 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
 		if (!(regs->cs[i].config & 0x80000000))
diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
index ab8d2de..1ed4d50 100644
--- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
+++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright 2008-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008-2020 Freescale Semiconductor, Inc.
  */
 
 #include <common.h>
@@ -40,6 +40,15 @@
 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR_A003
 	u32 save1, save2;
 #endif
+#if defined(CONFIG_SYS_FSL_ERRATUM_A009942) || \
+	(defined(CONFIG_SYS_FSL_ERRATUM_A008378) && \
+	defined(CONFIG_SYS_FSL_DDRC_GEN4)) || \
+	defined(CONFIG_SYS_FSL_ERRATUM_A008109)
+	u32 val32;
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
+	unsigned int ddr_freq;
+#endif
 
 	switch (ctrl_num) {
 	case 0:
@@ -338,6 +347,49 @@
 
 	}
 #endif
+
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008378) && defined(CONFIG_SYS_FSL_DDRC_GEN4)
+	/* Erratum applies when accumulated ECC is used, or DBI is enabled */
+#define IS_ACC_ECC_EN(v) ((v) & 0x4)
+#define IS_DBI(v) ((((v) >> 12) & 0x3) == 0x2)
+	if (has_erratum_a008378()) {
+		if (IS_ACC_ECC_EN(regs->ddr_sdram_cfg) ||
+		    IS_DBI(regs->ddr_sdram_cfg_3)) {
+			val32 = ddr_in32(&ddr->debug[28]);
+			val32 |= (0x9 << 20);
+			ddr_out32(&ddr->debug[28], val32);
+		}
+		debug("Applied errata CONFIG_SYS_FSL_ERRATUM_A008378\n");
+	}
+#endif
+
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008109)
+	val32 = in_be32(&ddr->sdram_cfg_2) | 0x800; /* DDR_SLOW */
+	out_be32(&ddr->sdram_cfg_2, val32);
+
+	val32 = in_be32(&ddr->debug[18]) | 0x2;
+	out_be32(&ddr->debug[18], val32);
+
+	out_be32(&ddr->debug[28], 0x30000000);
+	debug("Applied errta CONFIG_SYS_FSL_ERRATUM_A008109\n");
+#endif
+
+#ifdef CONFIG_SYS_FSL_ERRATUM_A009942
+	ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
+	val32 = in_be32(&ddr->debug[28]);
+	val32 &= 0xff0fff00;
+	if (ddr_freq <= 1333)
+		val32 |= 0x0080006a;
+	else if (ddr_freq <= 1600)
+		val32 |= 0x0070006f;
+	else if (ddr_freq <= 1867)
+		val32 |= 0x00700076;
+	else if (ddr_freq <= 2133)
+		val32 |= 0x0060007b;
+
+	out_be32(&ddr->debug[28], val32);
+	debug("Applied errata CONFIG_SYS_FSL_ERRATUM_A009942\n");
+#endif
 	/*
 	 * For 8572 DDR1 erratum - DDR controller may enter illegal state
 	 * when operatiing in 32-bit bus mode with 4-beat bursts,