summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7/ls102xa/soc.c
diff options
context:
space:
mode:
authorAlison Wang <alison.wang@nxp.com>2019-03-06 14:49:14 +0800
committerPrabhakar Kushwaha <prabhakar.kushwaha@nxp.com>2019-03-15 11:52:01 +0530
commit158097052a6a528408e05d2345ff2ccdbb46036e (patch)
tree78453d3d716aef5368b91a620203c0487fe6f378 /arch/arm/cpu/armv7/ls102xa/soc.c
parentba7eadd8e107202ab90d0b2937044b6dcba4b7ae (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.c44
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();