diff options
Diffstat (limited to 'cpu/mpc85xx')
-rw-r--r-- | cpu/mpc85xx/cpu.c | 38 | ||||
-rw-r--r-- | cpu/mpc85xx/fdt.c | 23 | ||||
-rw-r--r-- | cpu/mpc85xx/pci.c | 32 | ||||
-rw-r--r-- | cpu/mpc85xx/release.S | 1 | ||||
-rw-r--r-- | cpu/mpc85xx/speed.c | 37 | ||||
-rw-r--r-- | cpu/mpc85xx/start.S | 16 | ||||
-rw-r--r-- | cpu/mpc85xx/tlb.c | 40 |
7 files changed, 135 insertions, 52 deletions
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c index 943602f..a34e251 100644 --- a/cpu/mpc85xx/cpu.c +++ b/cpu/mpc85xx/cpu.c @@ -77,8 +77,6 @@ struct cpu_type *identify_cpu(u32 ver) int checkcpu (void) { sys_info_t sysinfo; - uint lcrr; /* local bus clock ratio register */ - uint clkdiv; /* clock divider portion of lcrr */ uint pvr, svr; uint fam; uint ver; @@ -92,6 +90,7 @@ int checkcpu (void) #else u32 ddr_ratio = 0; #endif + int i; svr = get_svr(); ver = SVR_SOC_VER(svr); @@ -143,8 +142,10 @@ int checkcpu (void) get_sys_info(&sysinfo); - puts("Clock Configuration:\n"); - printf(" CPU:%-4s MHz, ", strmhz(buf1, sysinfo.freqProcessor)); + puts("Clock Configuration:\n "); + for (i = 0; i < CONFIG_NUM_CPUS; i++) + printf("CPU%d:%-4s MHz, ", + i,strmhz(buf1, sysinfo.freqProcessor[i])); printf("CCB:%-4s MHz,\n", strmhz(buf1, sysinfo.freqSystemBus)); switch (ddr_ratio) { @@ -165,30 +166,11 @@ int checkcpu (void) break; } -#if defined(CONFIG_SYS_LBC_LCRR) - lcrr = CONFIG_SYS_LBC_LCRR; -#else - { - volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); - - lcrr = lbc->lcrr; - } -#endif - clkdiv = lcrr & 0x0f; - if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) { -#if defined(CONFIG_MPC8548) || defined(CONFIG_MPC8544) || \ - defined(CONFIG_MPC8572) || defined(CONFIG_MPC8536) - /* - * Yes, the entire PQ38 family use the same - * bit-representation for twice the clock divider values. - */ - clkdiv *= 2; -#endif - printf("LBC:%-4s MHz\n", - strmhz(buf1, sysinfo.freqSystemBus / clkdiv)); - } else { - printf("LBC: unknown (lcrr: 0x%08x)\n", lcrr); - } + if (sysinfo.freqLocalBus > LCRR_CLKDIV) + printf("LBC:%-4s MHz\n", strmhz(buf1, sysinfo.freqLocalBus)); + else + printf("LBC: unknown (LCRR[CLKDIV] = 0x%02lx)\n", + sysinfo.freqLocalBus); #ifdef CONFIG_CPM2 printf("CPM: %s MHz\n", strmhz(buf1, sysinfo.freqSystemBus)); diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c index 59aafb1..1fae47c 100644 --- a/cpu/mpc85xx/fdt.c +++ b/cpu/mpc85xx/fdt.c @@ -28,11 +28,12 @@ #include <fdt_support.h> #include <asm/processor.h> +DECLARE_GLOBAL_DATA_PTR; + extern void ft_qe_setup(void *blob); #ifdef CONFIG_MP #include "mp.h" -DECLARE_GLOBAL_DATA_PTR; void ft_fixup_cpu(void *blob, u64 memory_limit) { @@ -212,6 +213,10 @@ void fdt_add_enet_stashing(void *fdt) void ft_cpu_setup(void *blob, bd_t *bd) { + int off; + int val; + sys_info_t sysinfo; + /* delete crypto node if not on an E-processor */ if (!IS_E_PROCESSOR(get_svr())) fdt_fixup_crypto_node(blob, 0); @@ -227,10 +232,22 @@ void ft_cpu_setup(void *blob, bd_t *bd) "timebase-frequency", bd->bi_busfreq / 8, 1); do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, "bus-frequency", bd->bi_busfreq, 1); - do_fixup_by_prop_u32(blob, "device_type", "cpu", 4, - "clock-frequency", bd->bi_intfreq, 1); + get_sys_info(&sysinfo); + off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); + while (off != -FDT_ERR_NOTFOUND) { + u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0); + val = cpu_to_fdt32(sysinfo.freqProcessor[*reg]); + fdt_setprop(blob, off, "clock-frequency", &val, 4); + off = fdt_node_offset_by_prop_value(blob, off, "device_type", + "cpu", 4); + } do_fixup_by_prop_u32(blob, "device_type", "soc", 4, "bus-frequency", bd->bi_busfreq, 1); + + do_fixup_by_compat_u32(blob, "fsl,pq3-localbus", + "bus-frequency", gd->lbc_clk, 1); + do_fixup_by_compat_u32(blob, "fsl,elbc", + "bus-frequency", gd->lbc_clk, 1); #ifdef CONFIG_QE ft_qe_setup(blob); #endif diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c index 787c6eb..fedf1a5 100644 --- a/cpu/mpc85xx/pci.c +++ b/cpu/mpc85xx/pci.c @@ -31,6 +31,22 @@ #if defined(CONFIG_PCI) && !defined(CONFIG_FSL_PCI_INIT) +#ifndef CONFIG_SYS_PCI1_MEM_BUS +#define CONFIG_SYS_PCI1_MEM_BUS CONFIG_SYS_PCI1_MEM_BASE +#endif + +#ifndef CONFIG_SYS_PCI1_IO_BUS +#define CONFIG_SYS_PCI1_IO_BUS CONFIG_SYS_PCI1_IO_BASE +#endif + +#ifndef CONFIG_SYS_PCI2_MEM_BUS +#define CONFIG_SYS_PCI2_MEM_BUS CONFIG_SYS_PCI2_MEM_BASE +#endif + +#ifndef CONFIG_SYS_PCI2_IO_BUS +#define CONFIG_SYS_PCI2_IO_BUS CONFIG_SYS_PCI2_IO_BASE +#endif + static struct pci_controller *pci_hose; void @@ -80,14 +96,14 @@ pci_mpc85xx_init(struct pci_controller *board_hose) pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16); } - pcix->potar1 = (CONFIG_SYS_PCI1_MEM_BASE >> 12) & 0x000fffff; + pcix->potar1 = (CONFIG_SYS_PCI1_MEM_BUS >> 12) & 0x000fffff; pcix->potear1 = 0x00000000; pcix->powbar1 = (CONFIG_SYS_PCI1_MEM_PHYS >> 12) & 0x000fffff; pcix->powbear1 = 0x00000000; pcix->powar1 = (POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE | (__ilog2(CONFIG_SYS_PCI1_MEM_SIZE) - 1)); - pcix->potar2 = (CONFIG_SYS_PCI1_IO_BASE >> 12) & 0x000fffff; + pcix->potar2 = (CONFIG_SYS_PCI1_IO_BUS >> 12) & 0x000fffff; pcix->potear2 = 0x00000000; pcix->powbar2 = (CONFIG_SYS_PCI1_IO_PHYS >> 12) & 0x000fffff; pcix->powbear2 = 0x00000000; @@ -105,13 +121,13 @@ pci_mpc85xx_init(struct pci_controller *board_hose) pcix->piwar3 = 0; pci_set_region(hose->regions + 0, - CONFIG_SYS_PCI1_MEM_BASE, + CONFIG_SYS_PCI1_MEM_BUS, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_SIZE, PCI_REGION_MEM); pci_set_region(hose->regions + 1, - CONFIG_SYS_PCI1_IO_BASE, + CONFIG_SYS_PCI1_IO_BUS, CONFIG_SYS_PCI1_IO_PHYS, CONFIG_SYS_PCI1_IO_SIZE, PCI_REGION_IO); @@ -165,14 +181,14 @@ pci_mpc85xx_init(struct pci_controller *board_hose) */ pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); - pcix2->potar1 = (CONFIG_SYS_PCI2_MEM_BASE >> 12) & 0x000fffff; + pcix2->potar1 = (CONFIG_SYS_PCI2_MEM_BUS >> 12) & 0x000fffff; pcix2->potear1 = 0x00000000; pcix2->powbar1 = (CONFIG_SYS_PCI2_MEM_PHYS >> 12) & 0x000fffff; pcix2->powbear1 = 0x00000000; pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE | (__ilog2(CONFIG_SYS_PCI2_MEM_SIZE) - 1)); - pcix2->potar2 = (CONFIG_SYS_PCI2_IO_BASE >> 12) & 0x000fffff; + pcix2->potar2 = (CONFIG_SYS_PCI2_IO_BUS >> 12) & 0x000fffff; pcix2->potear2 = 0x00000000; pcix2->powbar2 = (CONFIG_SYS_PCI2_IO_PHYS >> 12) & 0x000fffff; pcix2->powbear2 = 0x00000000; @@ -190,13 +206,13 @@ pci_mpc85xx_init(struct pci_controller *board_hose) pcix2->piwar3 = 0; pci_set_region(hose->regions + 0, - CONFIG_SYS_PCI2_MEM_BASE, + CONFIG_SYS_PCI2_MEM_BUS, CONFIG_SYS_PCI2_MEM_PHYS, CONFIG_SYS_PCI2_MEM_SIZE, PCI_REGION_MEM); pci_set_region(hose->regions + 1, - CONFIG_SYS_PCI2_IO_BASE, + CONFIG_SYS_PCI2_IO_BUS, CONFIG_SYS_PCI2_IO_PHYS, CONFIG_SYS_PCI2_IO_SIZE, PCI_REGION_IO); diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S index 7c3e8a1..54c936c 100644 --- a/cpu/mpc85xx/release.S +++ b/cpu/mpc85xx/release.S @@ -157,6 +157,7 @@ __secondary_start_page: mfspr r0,SPRN_PIR stw r0,ENTRY_PIR(r10) + mtspr IVPR,r12 /* * Coming here, we know the cpu has one TLB mapping in TLB1[0] * which maps 0xfffff000-0xffffffff one-to-one. We set up a diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c index 1e0f483..b0f47e0 100644 --- a/cpu/mpc85xx/speed.c +++ b/cpu/mpc85xx/speed.c @@ -28,6 +28,7 @@ #include <common.h> #include <ppc_asm.tmpl> #include <asm/processor.h> +#include <asm/io.h> DECLARE_GLOBAL_DATA_PTR; @@ -37,17 +38,20 @@ void get_sys_info (sys_info_t * sysInfo) { volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); uint plat_ratio,e500_ratio,half_freqSystemBus; + uint lcrr_div; + int i; plat_ratio = (gur->porpllsr) & 0x0000003e; plat_ratio >>= 1; sysInfo->freqSystemBus = plat_ratio * CONFIG_SYS_CLK_FREQ; - e500_ratio = (gur->porpllsr) & 0x003f0000; - e500_ratio >>= 16; /* Divide before multiply to avoid integer * overflow for processor speeds above 2GHz */ half_freqSystemBus = sysInfo->freqSystemBus/2; - sysInfo->freqProcessor = e500_ratio*half_freqSystemBus; + for (i = 0; i < CONFIG_NUM_CPUS; i++) { + e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f; + sysInfo->freqProcessor[i] = e500_ratio * half_freqSystemBus; + } /* Note: freqDDRBus is the MCLK frequency, not the data rate. */ sysInfo->freqDDRBus = sysInfo->freqSystemBus; @@ -60,6 +64,30 @@ void get_sys_info (sys_info_t * sysInfo) sysInfo->freqDDRBus = ddr_ratio * CONFIG_DDR_CLK_FREQ; } #endif + +#if defined(CONFIG_SYS_LBC_LCRR) + /* We will program LCRR to this value later */ + lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV; +#else + { + volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR); + lcrr_div = in_be32(&lbc->lcrr) & LCRR_CLKDIV; + } +#endif + if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { +#if !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \ + !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560) + /* + * Yes, the entire PQ38 family use the same + * bit-representation for twice the clock divider values. + */ + lcrr_div *= 2; +#endif + sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; + } else { + /* In case anyone cares what the unknown value is */ + sysInfo->freqLocalBus = lcrr_div; + } } @@ -79,9 +107,10 @@ int get_clocks (void) dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT; #endif get_sys_info (&sys_info); - gd->cpu_clk = sys_info.freqProcessor; + gd->cpu_clk = sys_info.freqProcessor[0]; gd->bus_clk = sys_info.freqSystemBus; gd->mem_clk = sys_info.freqDDRBus; + gd->lbc_clk = sys_info.freqLocalBus; /* * The base clock for I2C depends on the actual SOC. Unfortunately, diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 8fa0ff7..80f9677 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -184,19 +184,19 @@ _start_e500: mtspr DBCR0,r0 #endif - /* create a temp mapping in AS=1 to the boot window */ + /* create a temp mapping in AS=1 to the 4M boot window */ lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l - lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@h - ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_16M)@l + lis r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@h + ori r7,r7,FSL_BOOKE_MAS1(1, 1, 0, 1, BOOKE_PAGESZ_4M)@l - /* Align the mapping to 16MB */ - lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@h - ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xff000000, (MAS2_I|MAS2_G))@l + lis r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@h + ori r8,r8,FSL_BOOKE_MAS2(TEXT_BASE & 0xffc00000, (MAS2_I|MAS2_G))@l - lis r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h - ori r9,r9,FSL_BOOKE_MAS3(0xff000000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l + /* The 85xx has the default boot window 0xff800000 - 0xffffffff */ + lis r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@h + ori r9,r9,FSL_BOOKE_MAS3(0xffc00000, 0, (MAS3_SX|MAS3_SW|MAS3_SR))@l mtspr MAS0,r6 mtspr MAS1,r7 diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c index a2d16ae..25fa9ee 100644 --- a/cpu/mpc85xx/tlb.c +++ b/cpu/mpc85xx/tlb.c @@ -26,6 +26,11 @@ #include <common.h> #include <asm/processor.h> #include <asm/mmu.h> +#ifdef CONFIG_ADDR_MAP +#include <addr_map.h> +#endif + +DECLARE_GLOBAL_DATA_PTR; void set_tlb(u8 tlb, u32 epn, u64 rpn, u8 perms, u8 wimge, @@ -47,6 +52,11 @@ void set_tlb(u8 tlb, u32 epn, u64 rpn, mtspr(MAS7, _mas7); #endif asm volatile("isync;msync;tlbwe;isync"); + +#ifdef CONFIG_ADDR_MAP + if ((tlb == 1) && (gd->flags & GD_FLG_RELOC)) + addrmap_set_entry(epn, rpn, (1UL << ((tsize * 2) + 10)), esel); +#endif } void disable_tlb(u8 esel) @@ -67,6 +77,11 @@ void disable_tlb(u8 esel) mtspr(MAS7, _mas7); #endif asm volatile("isync;msync;tlbwe;isync"); + +#ifdef CONFIG_ADDR_MAP + if (gd->flags & GD_FLG_RELOC) + addrmap_set_entry(0, 0, 0, esel); +#endif } void invalidate_tlb(u8 tlb) @@ -91,6 +106,29 @@ void init_tlbs(void) return ; } +#ifdef CONFIG_ADDR_MAP +void init_addr_map(void) +{ + int i; + + for (i = 0; i < num_tlb_entries; i++) { + if (tlb_table[i].tlb == 0) + continue; + + addrmap_set_entry(tlb_table[i].epn, + tlb_table[i].rpn, + (1UL << ((tlb_table[i].tsize * 2) + 10)), + tlb_table[i].esel); + } + + return ; +} +#endif + +#ifndef CONFIG_SYS_DDR_TLB_START +#define CONFIG_SYS_DDR_TLB_START 8 +#endif + unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) { unsigned int tlb_size; @@ -137,7 +175,7 @@ unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg) * Configure DDR TLB1 entries. * Starting at TLB1 8, use no more than 8 TLB1 entries. */ - ram_tlb_index = 8; + ram_tlb_index = CONFIG_SYS_DDR_TLB_START; ram_tlb_address = (unsigned int)CONFIG_SYS_DDR_SDRAM_BASE; while (ram_tlb_address < (memsize_in_meg * 1024 * 1024) && ram_tlb_index < 16) { |