mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
ipq806x: Clear L2 error status register before linux boots.
Previous pending L2 cache errors are cleared during the cleanup phase before transferring the control to linux. Change-Id: I3a54c64049135e150c2b49b0d6de1667511b6a14
This commit is contained in:
parent
5a5d4fb198
commit
4b79b9c406
7 changed files with 106 additions and 2 deletions
|
|
@ -16,6 +16,33 @@
|
|||
#define ARMV7_DCACHE_CLEAN_INVAL_RANGE 4
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
|
||||
void set_l2_indirect_reg(u32 reg_addr, u32 val)
|
||||
{
|
||||
|
||||
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
|
||||
"isb\n\t"
|
||||
"mcr p15, 3, %[l2cpdr], c15, c0, 7\n\t"
|
||||
"isb\n\t"
|
||||
:
|
||||
: [l2cpselr]"r" (reg_addr), [l2cpdr]"r" (val)
|
||||
);
|
||||
}
|
||||
|
||||
u32 get_l2_indirect_reg(u32 reg_addr)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
asm volatile ("mcr p15, 3, %[l2cpselr], c15, c0, 6\n\t"
|
||||
"isb\n\t"
|
||||
"mrc p15, 3, %[l2cpdr], c15, c0, 7\n\t"
|
||||
: [l2cpdr]"=r" (val)
|
||||
: [l2cpselr]"r" (reg_addr)
|
||||
);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the level and type you want to Cache Size Selection Register(CSSELR)
|
||||
* to get size details from Current Cache Size ID Register(CCSIDR)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ int cleanup_before_linux_select(int flags)
|
|||
*/
|
||||
cpu_cache_initialization();
|
||||
|
||||
clear_l2cache_err();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,20 @@ int board_init(void)
|
|||
int ret;
|
||||
uint32_t start_blocks;
|
||||
uint32_t size_blocks;
|
||||
|
||||
#ifdef CONFIG_IPQ_REPORT_L2ERR
|
||||
u32 l2esr;
|
||||
|
||||
/* Record any kind of L2 errors caused during
|
||||
* the previous boot stages as we are clearing
|
||||
* the L2 errors before jumping to linux.
|
||||
* Refer to cleanup_before_linux() */
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
l2esr = get_l2_indirect_reg(L2ESR_IND_ADDR);
|
||||
#endif
|
||||
report_l2err(l2esr);
|
||||
#endif
|
||||
|
||||
qca_smem_flash_info_t *sfi = &qca_smem_flash_info;
|
||||
|
||||
gd->bd->bi_boot_params = QCA_BOOT_PARAMS_ADDR;
|
||||
|
|
@ -249,6 +263,35 @@ int dram_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPQ_REPORT_L2ERR
|
||||
void report_l2err(u32 l2esr)
|
||||
{
|
||||
if (l2esr & L2ESR_MPDCD)
|
||||
printf("L2 Master port decode error\n");
|
||||
|
||||
if (l2esr & L2ESR_MPSLV)
|
||||
printf("L2 master port slave error\n");
|
||||
|
||||
if (l2esr & L2ESR_TSESB)
|
||||
printf("L2 tag soft error, single-bit\n");
|
||||
|
||||
if (l2esr & L2ESR_TSEDB)
|
||||
printf("L2 tag soft error, double-bit\n");
|
||||
|
||||
if (l2esr & L2ESR_DSESB)
|
||||
printf("L2 data soft error, single-bit\n");
|
||||
|
||||
if (l2esr & L2ESR_DSEDB)
|
||||
printf("L2 data soft error, double-bit\n");
|
||||
|
||||
if (l2esr & L2ESR_MSE)
|
||||
printf("L2 modified soft error\n");
|
||||
|
||||
if (l2esr & L2ESR_MPLDREXNOK)
|
||||
printf("L2 master port LDREX received Normal OK response\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
icache_enable();
|
||||
|
|
@ -259,7 +302,7 @@ void disable_caches(void)
|
|||
icache_disable();
|
||||
}
|
||||
|
||||
void clear_l2cache_err(void)
|
||||
__weak void clear_l2cache_err(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -831,3 +831,19 @@ int ipq_get_tz_version(char *version_name, int buf_size)
|
|||
snprintf(version_name, buf_size, "%s\n", version_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear_l2cache_err(void)
|
||||
{
|
||||
unsigned int val;
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
val = get_l2_indirect_reg(L2ESR_IND_ADDR);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IPQ_REPORT_L2ERR
|
||||
report_l2err(val);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
set_l2_indirect_reg(L2ESR_IND_ADDR, val);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,18 @@
|
|||
*/
|
||||
#define RESET_WDT_BARK_TIME (5 * RESET_WDT_BITE_TIME)
|
||||
|
||||
#define L2ESR_IND_ADDR (0x204)
|
||||
|
||||
/* L2ESR bit fields */
|
||||
#define L2ESR_MPDCD BIT(0)
|
||||
#define L2ESR_MPSLV BIT(1)
|
||||
#define L2ESR_TSESB BIT(2)
|
||||
#define L2ESR_TSEDB BIT(3)
|
||||
#define L2ESR_DSESB BIT(4)
|
||||
#define L2ESR_DSEDB BIT(5)
|
||||
#define L2ESR_MSE BIT(6)
|
||||
#define L2ESR_MPLDREXNOK BIT(8)
|
||||
|
||||
#define CE1_REG_USAGE (0)
|
||||
#define CE1_ADM_USAGE (1)
|
||||
#define CE1_RESOURCE (1)
|
||||
|
|
|
|||
|
|
@ -778,6 +778,10 @@ void flush_dcache_range(unsigned long start, unsigned long stop);
|
|||
void invalidate_dcache_range(unsigned long start, unsigned long stop);
|
||||
void invalidate_dcache_all(void);
|
||||
void invalidate_icache_all(void);
|
||||
void set_l2_indirect_reg(u32 reg_addr, u32 val);
|
||||
void clear_l2cache_err(void);
|
||||
u32 get_l2_indirect_reg(u32 reg_addr);
|
||||
void report_l2err(u32 l2esr);
|
||||
|
||||
enum {
|
||||
/* Disable caches (else flush caches but leave them active) */
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ typedef struct {
|
|||
|
||||
/* Enabling this flag will report any L2 errors.
|
||||
* By default we are disabling it */
|
||||
/*#define CONFIG_IPQ_REPORT_L2ERR*/
|
||||
#define CONFIG_IPQ_REPORT_L2ERR
|
||||
|
||||
/*
|
||||
* Location in IMEM which contains the physical address of
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue