Skip to content

Commit

Permalink
armv7: ls102xa: Add workaround for DDR erratum A-008850
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Alison Wang <[email protected]>
Reviewed-by: Prabhakar Kushwaha <[email protected]>
  • Loading branch information
alisonwh authored and Prabhakar Kushwaha committed Mar 15, 2019
1 parent ba7eadd commit 1580970
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 37 deletions.
6 changes: 6 additions & 0 deletions arch/arm/cpu/armv7/ls102xa/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
44 changes: 37 additions & 7 deletions arch/arm/cpu/armv7/ls102xa/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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)
{
}
Expand Down Expand Up @@ -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 */
Expand All @@ -191,6 +220,7 @@ int arch_soc_init(void)
out_be32(&scfg->eddrtqcfg, 0x63b20042);

/* Erratum */
erratum_a008850_early();
erratum_a009008();
erratum_a009798();
erratum_a008997();
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/include/asm/arch-ls102xa/ls102xa_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions board/freescale/ls1021aiot/ls1021aiot.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ int dram_init(void)
ddrmc_init();
#endif

erratum_a008850_post();

gd->ram_size = DDR_SIZE;
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions board/freescale/ls1021aqds/ddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ int fsl_initdram(void)
fsl_dp_resume();
#endif

erratum_a008850_post();

gd->ram_size = dram_size;

return 0;
Expand Down
3 changes: 3 additions & 0 deletions board/freescale/ls1021aqds/ddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 0 additions & 30 deletions board/freescale/ls1021aqds/ls1021aqds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions board/freescale/ls1021atwr/ls1021atwr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions include/configs/ls1021aiot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
2 changes: 2 additions & 0 deletions include/configs/ls1021atwr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 1580970

Please sign in to comment.