diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx')
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cmd_errata.c | 4 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu_init.c | 3 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/cpu_init_early.c | 4 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c | 7 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/start.S | 84 | ||||
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/tlb.c | 17 |
6 files changed, 105 insertions, 14 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index a09eb91406..253bf08b6a 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -103,6 +103,10 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_LBC103 puts("Work-around for Erratum NMG_LBC103 enabled\n"); #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 + if ((SVR_MAJ(svr) == 1) || IS_SVR_REV(svr, 2, 0)) + puts("Work-around for Erratum NMG ETSEC129 enabled\n"); +#endif return 0; } diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index 0a4ce538f3..b9a8193759 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -317,7 +317,6 @@ int cpu_init_r(void) volatile ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; volatile uint cache_ctl; uint svr, ver; - uint l2srbar; u32 l2siz_field; svr = get_svr(); @@ -385,8 +384,8 @@ int cpu_init_r(void) if (l2cache->l2ctl & MPC85xx_L2CTL_L2E) { puts("already enabled"); - l2srbar = l2cache->l2srbar0; #if defined(CONFIG_SYS_INIT_L2_ADDR) && defined(CONFIG_SYS_FLASH_BASE) + u32 l2srbar = l2cache->l2srbar0; if (l2cache->l2ctl & MPC85xx_L2CTL_L2SRAM_ENTIRE && l2srbar >= CONFIG_SYS_FLASH_BASE) { l2srbar = CONFIG_SYS_INIT_L2_ADDR; diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c index 4ef3c9a8a5..091af7c95a 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c @@ -71,7 +71,7 @@ void cpu_init_early_f(void) #endif #if defined(CONFIG_SYS_FSL_ERRATUM_IFC_A003399) && !defined(CONFIG_SYS_RAMBOOT) ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR; - u32 *l2srbar, *dst, *src; + u32 *dst, *src; void (*setup_ifc_sram)(void); #endif @@ -137,7 +137,7 @@ void cpu_init_early_f(void) dst = (u32 *) SRAM_BASE_ADDR; src = (u32 *) setup_ifc; for (i = 0; i < 1024; i++) - *l2srbar++ = *src++; + *dst++ = *src++; setup_ifc_sram(); diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 89ed5b47fc..4b52dad56c 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -495,7 +495,6 @@ void fsl_serdes_init(void) int cfg; serdes_corenet_t *srds_regs; int lane, bank, idx; - enum srds_prtcl lane_prtcl; int have_bank[SRDS_MAX_BANK] = {}; #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 u32 serdes8_devdisr = 0; @@ -507,6 +506,7 @@ void fsl_serdes_init(void) #ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001 int need_serdes_a001; /* TRUE == need work-around for SERDES A001 */ #endif +#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8 char buffer[HWCONFIG_BUFFER_SIZE]; char *buf = NULL; @@ -516,6 +516,7 @@ void fsl_serdes_init(void) */ if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0) buf = buffer; +#endif /* Is serdes enabled at all? */ if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN)) @@ -617,7 +618,10 @@ void fsl_serdes_init(void) } } +#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8) || defined (CONFIG_SYS_P4080_ERRATUM_SERDES9) for (lane = 0; lane < SRDS_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl; + idx = serdes_get_lane_idx(lane); lane_prtcl = serdes_get_prtcl(cfg, lane); @@ -729,6 +733,7 @@ void fsl_serdes_init(void) #endif } +#endif #ifdef DEBUG puts("\n"); diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S index 5e0d78d006..7bd5cc0b0f 100644 --- a/arch/powerpc/cpu/mpc85xx/start.S +++ b/arch/powerpc/cpu/mpc85xx/start.S @@ -319,6 +319,55 @@ l2_disabled: #endif /* CONFIG_MPC8569 */ /* + * Search for the TLB that covers the code we're executing, and shrink it + * so that it covers only this 4K page. That will ensure that any other + * TLB we create won't interfere with it. We assume that the TLB exists, + * which is why we don't check the Valid bit of MAS1. + * + * This is necessary, for example, when booting from the on-chip ROM, + * which (oddly) creates a single 4GB TLB that covers CCSR and DDR. + * If we don't shrink this TLB now, then we'll accidentally delete it + * in "purge_old_ccsr_tlb" below. + */ + bl nexti /* Find our address */ +nexti: mflr r1 /* R1 = our PC */ + li r2, 0 + mtspr MAS6, r2 /* Assume the current PID and AS are 0 */ + isync + msync + tlbsx 0, r1 /* This must succeed */ + + /* Set the size of the TLB to 4KB */ + mfspr r3, MAS1 + li r2, 0xF00 + andc r3, r3, r2 /* Clear the TSIZE bits */ + ori r3, r3, MAS1_TSIZE(BOOKE_PAGESZ_4K)@l + mtspr MAS1, r3 + + /* + * Set the base address of the TLB to our PC. We assume that + * virtual == physical. We also assume that MAS2_EPN == MAS3_RPN. + */ + lis r3, MAS2_EPN@h + ori r3, r3, MAS2_EPN@l /* R3 = MAS2_EPN */ + + and r1, r1, r3 /* Our PC, rounded down to the nearest page */ + + mfspr r2, MAS2 + andc r2, r2, r3 + or r2, r2, r1 + mtspr MAS2, r2 /* Set the EPN to our PC base address */ + + mfspr r2, MAS3 + andc r2, r2, r3 + or r2, r2, r1 + mtspr MAS3, r2 /* Set the RPN to our PC base address */ + + isync + msync + tlbwe + +/* * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default * location is not where we want it. This typically happens on a 36-bit * system, where we want to move CCSR to near the top of 36-bit address space. @@ -352,6 +401,8 @@ purge_old_ccsr_tlb: li r1, 0 mtspr MAS6, r1 /* Search the current address space and PID */ + isync + msync tlbsx 0, r8 mfspr r1, MAS1 andis. r2, r1, MAS1_VALID@h /* Check for the Valid bit */ @@ -359,6 +410,8 @@ purge_old_ccsr_tlb: rlwinm r1, r1, 0, 1, 31 /* Clear Valid bit */ mtspr MAS1, r1 + isync + msync tlbwe 1: @@ -387,7 +440,7 @@ create_ccsr_new_tlb: tlbwe /* - * Create a TLB for the old location of CCSR. Register R9 is reserved + * Create a TLB for the current location of CCSR. Register R9 is reserved * for the virtual address of this TLB (CONFIG_SYS_CCSRBAR + 0x1000). */ create_ccsr_old_tlb: @@ -407,6 +460,33 @@ create_ccsr_old_tlb: msync tlbwe + /* + * We have a TLB for what we think is the current (old) CCSR. Let's + * verify that, otherwise we won't be able to move it. + * CONFIG_SYS_CCSRBAR_DEFAULT is always a 32-bit number, so we only + * need to compare the lower 32 bits of CCSRBAR on CoreNet systems. + */ +verify_old_ccsr: + lis r0, CONFIG_SYS_CCSRBAR_DEFAULT@h + ori r0, r0, CONFIG_SYS_CCSRBAR_DEFAULT@l +#ifdef CONFIG_FSL_CORENET + lwz r1, 4(r9) /* CCSRBARL */ +#else + lwz r1, 0(r9) /* CCSRBAR, shifted right by 12 */ + slwi r1, r1, 12 +#endif + + cmpl 0, r0, r1 + + /* + * If the value we read from CCSRBARL is not what we expect, then + * enter an infinite loop. This will at least allow a debugger to + * halt execution and examine TLBs, etc. There's no point in going + * on. + */ +infinite_debug_loop: + bne infinite_debug_loop + #ifdef CONFIG_FSL_CORENET #define CCSR_LAWBARH0 (CONFIG_SYS_CCSRBAR + 0x1000) @@ -446,7 +526,7 @@ create_temp_law: */ read_old_ccsrbar: lwz r0, 0(r9) /* CCSRBARH */ - lwz r0, 4(r9) /* CCSRBARH */ + lwz r0, 4(r9) /* CCSRBARL */ isync /* diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index 01a3561fa0..929f6a607e 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -172,7 +172,7 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn, void disable_tlb(u8 esel) { - u32 _mas0, _mas1, _mas2, _mas3, _mas7; + u32 _mas0, _mas1, _mas2, _mas3; free_tlb_cam(esel); @@ -180,14 +180,13 @@ void disable_tlb(u8 esel) _mas1 = 0; _mas2 = 0; _mas3 = 0; - _mas7 = 0; mtspr(MAS0, _mas0); mtspr(MAS1, _mas1); mtspr(MAS2, _mas2); mtspr(MAS3, _mas3); #ifdef CONFIG_ENABLE_36BIT_PHYS - mtspr(MAS7, _mas7); + mtspr(MAS7, 0); #endif asm volatile("isync;msync;tlbwe;isync"); @@ -252,16 +251,20 @@ setup_ddr_tlbs_phys(phys_addr_t p_addr, unsigned int memsize_in_meg) unsigned int tlb_size; unsigned int wimge = 0; unsigned int ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE; - unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xf; + unsigned int max_cam; u64 size, memsize = (u64)memsize_in_meg << 20; #ifdef CONFIG_SYS_PPC_DDR_WIMGE wimge = CONFIG_SYS_PPC_DDR_WIMGE; #endif size = min(memsize, CONFIG_MAX_MEM_MAPPED); - - /* Convert (4^max) kB to (2^max) bytes */ - max_cam = max_cam * 2 + 10; + if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1) { + /* Convert (4^max) kB to (2^max) bytes */ + max_cam = ((mfspr(SPRN_TLB1CFG) >> 16) & 0xf) * 2 + 10; + } else { + /* Convert (2^max) kB to (2^max) bytes */ + max_cam = __ilog2(mfspr(SPRN_TLB1PS)) + 10; + } for (i = 0; size && i < 8; i++) { int ram_tlb_index = find_free_tlbcam(); |