diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/powerpc/cpu/ppc4xx/cpu_init.c | 64 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/ppc405ex.h | 5 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/processor.h | 31 | 
3 files changed, 100 insertions, 0 deletions
| diff --git a/arch/powerpc/cpu/ppc4xx/cpu_init.c b/arch/powerpc/cpu/ppc4xx/cpu_init.c index bf208adfe..970a8c1e2 100644 --- a/arch/powerpc/cpu/ppc4xx/cpu_init.c +++ b/arch/powerpc/cpu/ppc4xx/cpu_init.c @@ -221,6 +221,66 @@ void reconfigure_pll(u32 new_cpu_freq)  #endif  } +#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA +void +chip_21_errata(void) +{ +	/* +	 * See rev 1.09 of the 405EX/405EXr errata.  CHIP_21 says that +	 * sometimes reading the PVR and/or SDR0_ECID results in incorrect +	 * values.  Since the rev-D chip uses the SDR0_ECID bits to control +	 * internal features, that means the second PCIe or ethernet of an EX +	 * variant could fail to work.  Also, security features of both EX and +	 * EXr might be incorrectly disabled. +	 * +	 * The suggested workaround is as follows (covering rev-C and rev-D): +	 * +	 * 1.Read the PVR and SDR0_ECID3. +	 * +	 * 2.If the PVR matches an expected Revision C PVR value AND if +	 * SDR0_ECID3[12:15] is different from PVR[28:31], then processor is +	 * Revision C: continue executing the initialization code (no reset +	 * required).  else go to step 3. +	 * +	 * 3.If the PVR matches an expected Revision D PVR value AND if +	 * SDR0_ECID3[10:11] matches its expected value, then continue +	 * executing initialization code, no reset required.  else write +	 * DBCR0[RST] = 0b11 to generate a SysReset. +	 */ + +	u32 pvr; +	u32 pvr_28_31; +	u32 ecid3; +	u32 ecid3_10_11; +	u32 ecid3_12_15; + +	/* Step 1: */ +	pvr = get_pvr(); +	mfsdr(SDR0_ECID3, ecid3); + +	/* Step 2: */ +	pvr_28_31 = pvr & 0xf; +	ecid3_10_11 = (ecid3 >> 20) & 0x3; +	ecid3_12_15 = (ecid3 >> 16) & 0xf; +	if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_C) && +			(pvr_28_31 != ecid3_12_15)) { +		/* No reset required. */ +		return; +	} + +	/* Step 3: */ +	if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_D) && +			(ecid3_10_11 == CONFIG_405EX_CHIP21_ECID3_REV_D)) { +		/* No reset required. */ +		return; +	} + +	/* Reset required. */ +	__asm__ __volatile__ ("sync; isync"); +	mtspr(SPRN_DBCR0, 0x30000000); +} +#endif +  /*   * Breath some life into the CPU...   * @@ -235,6 +295,10 @@ cpu_init_f (void)  	u32 val;  #endif +#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA +	chip_21_errata(); +#endif +  	reconfigure_pll(CONFIG_SYS_PLL_RECONFIG);  #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && \ diff --git a/arch/powerpc/include/asm/ppc405ex.h b/arch/powerpc/include/asm/ppc405ex.h index 36d3149b8..807038581 100644 --- a/arch/powerpc/include/asm/ppc405ex.h +++ b/arch/powerpc/include/asm/ppc405ex.h @@ -43,6 +43,11 @@  #define SDR0_PFC1		0x4101  #define SDR0_MFR		0x4300	/* SDR0_MFR reg */ +#define SDR0_ECID0		0x0080 +#define SDR0_ECID1		0x0081 +#define SDR0_ECID2		0x0082 +#define SDR0_ECID3		0x0083 +  #define SDR0_SDCS_SDD		(0x80000000 >> 31)  #define SDR0_SRST_DMC		(0x80000000 >> 10) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index f5bf4dd4f..c5b03b499 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -974,6 +974,37 @@  #define PVR_5200B	0x80822014  /* + * 405EX/EXr CHIP_21 Errata + */ +#ifdef CONFIG_SYS_4xx_CHIP_21_405EX_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C	PVR_405EX1_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D	PVR_405EX1_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D	0x0 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EX_NO_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C	PVR_405EX2_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D	PVR_405EX2_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D	0x1 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EXr_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C	PVR_405EXR1_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D	PVR_405EXR1_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D	0x2 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EXr_NO_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C	PVR_405EXR2_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D	PVR_405EXR2_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D	0x3 +#endif + +/*   * System Version Register   */ |