mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-31 03:21:32 +00:00
powerpc/mpc85xx: Add workaround for erratum A007212
Erratum A007212 for DDR is about a runaway condition for DDR PLL oscilliator. Please refer to erratum document for detail. For this workaround to work, DDR PLL needs to be disabled in RCW. However, u-boot needs to know the expected PLL ratio. We put the ratio in a reserved field RCW[18:23]. U-boot will skip this workaround if DDR PLL ratio is set, or the reserved field is not set. Workaround for erratum A007212 applies to selected versions of B4/T4 SoCs. It is safe to apply the workaround to all versions. It is helpful for upgrading SoC without changing u-boot. In case DDR PLL is disabled by RCW (part of the erratum workaround), we need this u-boot workround to bring up DDR clock. Signed-off-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
22cbf96434
commit
c3678b0937
5 changed files with 99 additions and 0 deletions
arch/powerpc
|
@ -113,6 +113,21 @@ static void check_erratum_a4580(uint32_t svr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
/*
|
||||
* This workaround can be implemented in PBI, or by u-boot.
|
||||
*/
|
||||
static void check_erratum_a007212(void)
|
||||
{
|
||||
u32 __iomem *plldgdcr = (void *)(CONFIG_SYS_DCSRBAR + 0x21c20);
|
||||
|
||||
if (in_be32(plldgdcr) & 0x1fe) {
|
||||
/* check if PLL ratio is set by workaround */
|
||||
puts("Work-around for Erratum A007212 enabled\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
|
||||
|
@ -281,6 +296,10 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||
if (has_erratum_a006261())
|
||||
puts("Work-around for Erratum A006261 enabled\n");
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
check_erratum_a007212();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -280,6 +280,71 @@ static void corenet_tb_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
void fsl_erratum_a007212_workaround(void)
|
||||
{
|
||||
ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
u32 ddr_pll_ratio;
|
||||
u32 __iomem *plldgdcr1 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c20);
|
||||
u32 __iomem *plldadcr1 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c28);
|
||||
u32 __iomem *dpdovrcr4 = (void *)(CONFIG_SYS_DCSRBAR + 0x21e80);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
|
||||
u32 __iomem *plldgdcr2 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c40);
|
||||
u32 __iomem *plldadcr2 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c48);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
|
||||
u32 __iomem *plldgdcr3 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c60);
|
||||
u32 __iomem *plldadcr3 = (void *)(CONFIG_SYS_DCSRBAR + 0x21c68);
|
||||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Even this workaround applies to selected version of SoCs, it is
|
||||
* safe to apply to all versions, with the limitation of odd ratios.
|
||||
* If RCW has disabled DDR PLL, we have to apply this workaround,
|
||||
* otherwise DDR will not work.
|
||||
*/
|
||||
ddr_pll_ratio = (in_be32(&gur->rcwsr[0]) >>
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT) &
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
/* check if RCW sets ratio to 0, required by this workaround */
|
||||
if (ddr_pll_ratio != 0)
|
||||
return;
|
||||
ddr_pll_ratio = (in_be32(&gur->rcwsr[0]) >>
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
/* check if reserved bits have the desired ratio */
|
||||
if (ddr_pll_ratio == 0) {
|
||||
printf("Error: Unknown DDR PLL ratio!\n");
|
||||
return;
|
||||
}
|
||||
ddr_pll_ratio >>= 1;
|
||||
|
||||
setbits_be32(plldadcr1, 0x02000001);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
|
||||
setbits_be32(plldadcr2, 0x02000001);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
|
||||
setbits_be32(plldadcr3, 0x02000001);
|
||||
#endif
|
||||
#endif
|
||||
setbits_be32(dpdovrcr4, 0xe0000000);
|
||||
out_be32(plldgdcr1, 0x08000001 | (ddr_pll_ratio << 1));
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
|
||||
out_be32(plldgdcr2, 0x08000001 | (ddr_pll_ratio << 1));
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
|
||||
out_be32(plldgdcr3, 0x08000001 | (ddr_pll_ratio << 1));
|
||||
#endif
|
||||
#endif
|
||||
udelay(100);
|
||||
clrbits_be32(plldadcr1, 0x02000001);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
|
||||
clrbits_be32(plldadcr2, 0x02000001);
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 3)
|
||||
clrbits_be32(plldadcr3, 0x02000001);
|
||||
#endif
|
||||
#endif
|
||||
clrbits_be32(dpdovrcr4, 0xe0000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
void cpu_init_f (void)
|
||||
{
|
||||
extern void m8560_cpm_reset (void);
|
||||
|
@ -349,6 +414,10 @@ void cpu_init_f (void)
|
|||
in_be32(&gur->dcsrcr);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
fsl_erratum_a007212_workaround();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Implement a dummy function for those platforms w/o SERDES */
|
||||
|
|
|
@ -107,6 +107,13 @@ void get_sys_info(sys_info_t *sys_info)
|
|||
mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)
|
||||
& FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
if (mem_pll_rat == 0) {
|
||||
mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
|
||||
FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
|
||||
}
|
||||
#endif
|
||||
/* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of
|
||||
* T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0
|
||||
* it uses 6.
|
||||
|
|
|
@ -679,6 +679,7 @@
|
|||
#define CONFIG_SYS_FSL_ERRATUM_A007075
|
||||
#define CONFIG_SYS_FSL_ERRATUM_A006475
|
||||
#define CONFIG_SYS_FSL_ERRATUM_A006384
|
||||
#define CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000
|
||||
|
||||
#ifdef CONFIG_PPC_B4860
|
||||
|
@ -792,6 +793,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
|
|||
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v3.0"
|
||||
#define CONFIG_SYS_FSL_USB_DUAL_PHY_ENABLE
|
||||
#define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
|
||||
#define CONFIG_SYS_FSL_ERRATUM_A007212
|
||||
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xfe000000
|
||||
#define CONFIG_SYS_FSL_SFP_VER_3_0
|
||||
#define CONFIG_SYS_FSL_ISBC_VER 2
|
||||
|
|
|
@ -1739,6 +1739,8 @@ typedef struct ccsr_gur {
|
|||
|
||||
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
|
||||
#define FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT 16
|
||||
/* use reserved bits 18~23 as scratch space to host DDR PLL ratio */
|
||||
#define FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT 8
|
||||
#define FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK 0x3f
|
||||
#if defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160)
|
||||
#define FSL_CORENET2_RCWSR4_SRDS1_PRTCL 0xfc000000
|
||||
|
|
Loading…
Add table
Reference in a new issue