diff options
author | Wolfgang Denk <wd@denx.de> | 2009-10-27 20:56:31 +0100 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2009-10-27 20:56:31 +0100 |
commit | 98cecb610f3fa53aa7d825a634d35ef9cf6c5487 (patch) | |
tree | f9a153be5ec31919981e4d53e5ee274cffa3d15b /cpu | |
parent | a747a7f31059b9069e97c78bba5496409c33aa05 (diff) | |
parent | 3fca80375981fe83d4674a0267183b469a1ea7ff (diff) | |
download | u-boot-imx-98cecb610f3fa53aa7d825a634d35ef9cf6c5487.zip u-boot-imx-98cecb610f3fa53aa7d825a634d35ef9cf6c5487.tar.gz u-boot-imx-98cecb610f3fa53aa7d825a634d35ef9cf6c5487.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/mpc85xx/config.mk | 5 | ||||
-rw-r--r-- | cpu/mpc85xx/cpu_init.c | 5 | ||||
-rw-r--r-- | cpu/mpc85xx/fdt.c | 2 | ||||
-rw-r--r-- | cpu/mpc85xx/mp.c | 70 | ||||
-rw-r--r-- | cpu/mpc85xx/mp.h | 3 | ||||
-rw-r--r-- | cpu/mpc85xx/release.S | 34 | ||||
-rw-r--r-- | cpu/mpc85xx/speed.c | 4 |
7 files changed, 91 insertions, 32 deletions
diff --git a/cpu/mpc85xx/config.mk b/cpu/mpc85xx/config.mk index beb3514..84651b8 100644 --- a/cpu/mpc85xx/config.mk +++ b/cpu/mpc85xx/config.mk @@ -24,6 +24,11 @@ PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi PLATFORM_CPPFLAGS += -ffixed-r2 -Wa,-me500 -msoft-float -mno-string + +# -mspe=yes is needed to have -mno-spe accepted by a buggy GCC; +# see "[PATCH,rs6000] make -mno-spe work as expected" on +# http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00311.html +PLATFORM_CPPFLAGS +=$(call cc-option,-mspe=yes) PLATFORM_CPPFLAGS +=$(call cc-option,-mno-spe) # Use default linker script. Board port can override in board/*/config.mk diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 5336934..0041a60 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -360,8 +360,11 @@ int cpu_init_r(void) /* enable the cache */ mtspr(SPRN_L2CSR0, CONFIG_SYS_INIT_L2CSR0); - if (CONFIG_SYS_INIT_L2CSR0 & L2CSR0_L2E) + if (CONFIG_SYS_INIT_L2CSR0 & L2CSR0_L2E) { + while (!(mfspr(SPRN_L2CSR0) & L2CSR0_L2E)) + ; printf("%d KB enabled\n", (l2cfg0 & 0x3fff) * 64); + } #else puts("disabled\n"); #endif diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c index efb6518..de2dcac 100644 --- a/cpu/mpc85xx/fdt.c +++ b/cpu/mpc85xx/fdt.c @@ -43,7 +43,7 @@ extern void ft_fixup_num_cores(void *blob); void ft_fixup_cpu(void *blob, u64 memory_limit) { int off; - ulong spin_tbl_addr = get_spin_addr(); + ulong spin_tbl_addr = get_spin_phys_addr(); u32 bootpg = determine_mp_bootpg(); u32 id = get_my_id(); diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c index b5c6020..00b6450 100644 --- a/cpu/mpc85xx/mp.c +++ b/cpu/mpc85xx/mp.c @@ -52,10 +52,10 @@ int cpu_status(int nr) u32 *table, id = get_my_id(); if (nr == id) { - table = (u32 *)get_spin_addr(); + table = (u32 *)get_spin_virt_addr(); printf("table base @ 0x%p\n", table); } else { - table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY; + table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY; printf("Running on cpu %d\n", id); printf("\n"); printf("table @ 0x%p\n", table); @@ -77,7 +77,7 @@ static u8 boot_entry_map[4] = { int cpu_release(int nr, int argc, char *argv[]) { - u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY; + u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY; u64 boot_addr; if (nr == get_my_id()) { @@ -124,23 +124,29 @@ u32 determine_mp_bootpg(void) return (gd->ram_size - 4096); } -ulong get_spin_addr(void) +ulong get_spin_phys_addr(void) { extern ulong __secondary_start_page; extern ulong __spin_table; - ulong addr = - (ulong)&__spin_table - (ulong)&__secondary_start_page; - addr += 0xfffff000; + return (determine_mp_bootpg() + + (ulong)&__spin_table - (ulong)&__secondary_start_page); +} + +ulong get_spin_virt_addr(void) +{ + extern ulong __secondary_start_page; + extern ulong __spin_table; - return addr; + return (CONFIG_BPTR_VIRT_ADDR + + (ulong)&__spin_table - (ulong)&__secondary_start_page); } #ifdef CONFIG_FSL_CORENET static void plat_mp_up(unsigned long bootpg) { u32 up, cpu_up_mask, whoami; - u32 *table = (u32 *)get_spin_addr(); + u32 *table = (u32 *)get_spin_virt_addr(); volatile ccsr_gur_t *gur; volatile ccsr_local_t *ccm; volatile ccsr_rcpm_t *rcpm; @@ -194,12 +200,23 @@ static void plat_mp_up(unsigned long bootpg) mtspr(SPRN_TBWU, 0); mtspr(SPRN_TBWL, 0); out_be32(&rcpm->ctbenrl, (1 << nr_cpus) - 1); + +#ifdef CONFIG_MPC8xxx_DISABLE_BPTR + /* + * Disabling Boot Page Translation allows the memory region 0xfffff000 + * to 0xffffffff to be used normally. Leaving Boot Page Translation + * enabled remaps 0xfffff000 to SDRAM which makes that memory region + * unusable for normal operation but it does allow OSes to easily + * reset a processor core to put it back into U-Boot's spinloop. + */ + clrbits_be32(&ecm->bptr, 0x80000000); +#endif } #else static void plat_mp_up(unsigned long bootpg) { u32 up, cpu_up_mask, whoami; - u32 *table = (u32 *)get_spin_addr(); + u32 *table = (u32 *)get_spin_virt_addr(); volatile u32 bpcr; volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -256,6 +273,17 @@ static void plat_mp_up(unsigned long bootpg) devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1); out_be32(&gur->devdisr, devdisr); + +#ifdef CONFIG_MPC8xxx_DISABLE_BPTR + /* + * Disabling Boot Page Translation allows the memory region 0xfffff000 + * to 0xffffffff to be used normally. Leaving Boot Page Translation + * enabled remaps 0xfffff000 to SDRAM which makes that memory region + * unusable for normal operation but it does allow OSes to easily + * reset a processor core to put it back into U-Boot's spinloop. + */ + clrbits_be32(&ecm->bptr, 0x80000000); +#endif } #endif @@ -269,33 +297,27 @@ void cpu_mp_lmb_reserve(struct lmb *lmb) void setup_mp(void) { extern ulong __secondary_start_page; + extern ulong __bootpg_addr; ulong fixup = (ulong)&__secondary_start_page; u32 bootpg = determine_mp_bootpg(); + /* Store the bootpg's SDRAM address for use by secondary CPU cores */ + __bootpg_addr = bootpg; + /* look for the tlb covering the reset page, there better be one */ - int i = find_tlb_idx((void *)0xfffff000, 1); + int i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1); /* we found a match */ if (i != -1) { /* map reset page to bootpg so we can copy code there */ disable_tlb(i); - set_tlb(1, 0xfffff000, bootpg, /* tlb, epn, rpn */ - MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M, /* perms, wimge */ - 0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */ - - memcpy((void *)0xfffff000, (void *)fixup, 4096); - flush_cache(0xfffff000, 4096); - - disable_tlb(i); - - /* setup reset page back to 1:1, we'll use HW boot translation - * to map this where we want - */ - set_tlb(1, 0xfffff000, 0xfffff000, /* tlb, epn, rpn */ + set_tlb(1, CONFIG_BPTR_VIRT_ADDR, bootpg, /* tlb, epn, rpn */ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I, /* perms, wimge */ 0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */ + memcpy((void *)CONFIG_BPTR_VIRT_ADDR, (void *)fixup, 4096); + plat_mp_up(bootpg); } else { puts("WARNING: No reset page TLB. " diff --git a/cpu/mpc85xx/mp.h b/cpu/mpc85xx/mp.h index 2c2929e..3422cc1 100644 --- a/cpu/mpc85xx/mp.h +++ b/cpu/mpc85xx/mp.h @@ -3,7 +3,8 @@ #include <asm/mp.h> -ulong get_spin_addr(void); +ulong get_spin_phys_addr(void); +ulong get_spin_virt_addr(void); u32 get_my_id(void); #define BOOT_ENTRY_ADDR_UPPER 0 diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S index ecbd0d5..a1ae78a 100644 --- a/cpu/mpc85xx/release.S +++ b/cpu/mpc85xx/release.S @@ -138,23 +138,38 @@ __secondary_start_page: stw r3,ENTRY_R6_UPPER(r10) stw r3,ENTRY_R6_LOWER(r10) + /* load r13 with the address of the 'bootpg' in SDRAM */ + lis r13,toreset(__bootpg_addr)@h + ori r13,r13,toreset(__bootpg_addr)@l + lwz r13,0(r13) + /* setup mapping for AS = 1, and jump there */ lis r11,(MAS0_TLBSEL(1)|MAS0_ESEL(1))@h mtspr SPRN_MAS0,r11 lis r11,(MAS1_VALID|MAS1_IPROT)@h ori r11,r11,(MAS1_TS|MAS1_TSIZE(BOOKE_PAGESZ_4K))@l mtspr SPRN_MAS1,r11 - lis r11,(0xfffff000|MAS2_I)@h - ori r11,r11,(0xfffff000|MAS2_I)@l + oris r11,r13,(MAS2_I)@h + ori r11,r13,(MAS2_I)@l mtspr SPRN_MAS2,r11 - lis r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@h - ori r11,r11,(0xfffff000|MAS3_SX|MAS3_SW|MAS3_SR)@l + oris r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@h + ori r11,r13,(MAS3_SX|MAS3_SW|MAS3_SR)@l mtspr SPRN_MAS3,r11 tlbwe bl 1f 1: mflr r11 - addi r11,r11,28 + /* + * OR in 0xfff to create a mask of the bootpg SDRAM address. We use + * this mask to fixup the cpu spin table and the address that we want + * to jump to, eg change them from 0xfffffxxx to 0x7ffffxxx if the + * bootpg is at 0x7ffff000 in SDRAM. + */ + ori r13,r13,0xfff + and r11, r11, r13 + and r10, r10, r13 + + addi r11,r11,(2f-1b) mfmsr r13 ori r12,r13,MSR_IS|MSR_DS@l @@ -227,6 +242,15 @@ __secondary_start_page: mtspr SPRN_SRR1,r13 rfi + /* + * Allocate some space for the SDRAM address of the bootpg. + * This variable has to be in the boot page so that it can + * be accessed by secondary cores when they come out of reset. + */ + .globl __bootpg_addr +__bootpg_addr: + .long 0 + .align L1_CACHE_SHIFT .globl __spin_table __spin_table: diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index 0244b5c..7959082 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -240,8 +240,12 @@ int get_clocks (void) gd->i2c2_clk = gd->i2c1_clk; #if defined(CONFIG_FSL_ESDHC) +#ifdef CONFIG_MPC8569 + gd->sdhc_clk = gd->bus_clk; +#else gd->sdhc_clk = gd->bus_clk / 2; #endif +#endif /* defined(CONFIG_FSL_ESDHC) */ #if defined(CONFIG_CPM2) gd->vco_out = 2*sys_info.freqSystemBus; |