summaryrefslogtreecommitdiff
path: root/cpu/mpc85xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/mpc85xx')
-rw-r--r--cpu/mpc85xx/Makefile3
-rw-r--r--cpu/mpc85xx/cpu.c102
-rw-r--r--cpu/mpc85xx/cpu_init.c10
-rw-r--r--cpu/mpc85xx/fdt.c52
-rw-r--r--cpu/mpc85xx/mp.c210
-rw-r--r--cpu/mpc85xx/mp.h20
-rw-r--r--cpu/mpc85xx/release.S182
-rw-r--r--cpu/mpc85xx/speed.c21
8 files changed, 536 insertions, 64 deletions
diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile
index 2205dca..adbc585 100644
--- a/cpu/mpc85xx/Makefile
+++ b/cpu/mpc85xx/Makefile
@@ -29,6 +29,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START = start.o resetvec.o
+SOBJS-$(CONFIG_MP) += release.o
+SOBJS = $(SOBJS-y)
+COBJS-$(CONFIG_MP) += mp.o
COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \
pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \
diff --git a/cpu/mpc85xx/cpu.c b/cpu/mpc85xx/cpu.c
index ac8b018..dcd8817 100644
--- a/cpu/mpc85xx/cpu.c
+++ b/cpu/mpc85xx/cpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004,2007 Freescale Semiconductor, Inc.
+ * Copyright 2004,2007,2008 Freescale Semiconductor, Inc.
* (C) Copyright 2002, 2003 Motorola Inc.
* Xianghua Xiao (X.Xiao@motorola.com)
*
@@ -30,6 +30,41 @@
#include <command.h>
#include <asm/cache.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+struct cpu_type {
+ char name[15];
+ u32 soc_ver;
+};
+
+#define CPU_TYPE_ENTRY(x) {#x, SVR_##x}
+
+struct cpu_type cpu_type_list [] = {
+ CPU_TYPE_ENTRY(8533),
+ CPU_TYPE_ENTRY(8533_E),
+ CPU_TYPE_ENTRY(8540),
+ CPU_TYPE_ENTRY(8541),
+ CPU_TYPE_ENTRY(8541_E),
+ CPU_TYPE_ENTRY(8543),
+ CPU_TYPE_ENTRY(8543_E),
+ CPU_TYPE_ENTRY(8544),
+ CPU_TYPE_ENTRY(8544_E),
+ CPU_TYPE_ENTRY(8545),
+ CPU_TYPE_ENTRY(8545_E),
+ CPU_TYPE_ENTRY(8547_E),
+ CPU_TYPE_ENTRY(8548),
+ CPU_TYPE_ENTRY(8548_E),
+ CPU_TYPE_ENTRY(8555),
+ CPU_TYPE_ENTRY(8555_E),
+ CPU_TYPE_ENTRY(8560),
+ CPU_TYPE_ENTRY(8567),
+ CPU_TYPE_ENTRY(8567_E),
+ CPU_TYPE_ENTRY(8568),
+ CPU_TYPE_ENTRY(8568_E),
+ CPU_TYPE_ENTRY(8572),
+ CPU_TYPE_ENTRY(8572_E),
+};
+
int checkcpu (void)
{
sys_info_t sysinfo;
@@ -39,47 +74,26 @@ int checkcpu (void)
uint fam;
uint ver;
uint major, minor;
+ int i;
u32 ddr_ratio;
volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
svr = get_svr();
- ver = SVR_VER(svr);
+ ver = SVR_SOC_VER(svr);
major = SVR_MAJ(svr);
minor = SVR_MIN(svr);
puts("CPU: ");
- switch (ver) {
- case SVR_8540:
- puts("8540");
- break;
- case SVR_8541:
- puts("8541");
- break;
- case SVR_8555:
- puts("8555");
- break;
- case SVR_8560:
- puts("8560");
- break;
- case SVR_8548:
- puts("8548");
- break;
- case SVR_8548_E:
- puts("8548_E");
- break;
- case SVR_8544:
- puts("8544");
- break;
- case SVR_8544_E:
- puts("8544_E");
- break;
- case SVR_8568_E:
- puts("8568_E");
- break;
- default:
+
+ for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
+ if (cpu_type_list[i].soc_ver == ver) {
+ puts(cpu_type_list[i].name);
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cpu_type_list))
puts("Unknown");
- break;
- }
+
printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
pvr = get_pvr();
@@ -108,13 +122,16 @@ int checkcpu (void)
ddr_ratio = ((gur->porpllsr) & 0x00003e00) >> 9;
switch (ddr_ratio) {
case 0x0:
- printf(" DDR:%4lu MHz, ", sysinfo.freqDDRBus / 2000000);
+ printf(" DDR:%4lu MHz (%lu MT/s data rate), ",
+ sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
break;
case 0x7:
- printf(" DDR:%4lu MHz (Synchronous), ", sysinfo.freqDDRBus / 2000000);
+ printf(" DDR:%4lu MHz (%lu MT/s data rate) (Synchronous), ",
+ sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
break;
default:
- printf(" DDR:%4lu MHz (Asynchronous), ", sysinfo.freqDDRBus / 2000000);
+ printf(" DDR:%4lu MHz (%lu MT/s data rate) (Asynchronous), ",
+ sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
break;
}
@@ -142,10 +159,9 @@ int checkcpu (void)
printf("LBC: unknown (lcrr: 0x%08x)\n", lcrr);
}
- if (ver == SVR_8560) {
- printf("CPM: %lu Mhz\n",
- sysinfo.freqSystemBus / 1000000);
- }
+#ifdef CONFIG_CPM2
+ printf("CPM: %lu Mhz\n", sysinfo.freqSystemBus / 1000000);
+#endif
puts("L1: D-cache 32 kB enabled\n I-cache 32 kB enabled\n");
@@ -190,11 +206,7 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
*/
unsigned long get_tbclk (void)
{
-
- sys_info_t sys_info;
-
- get_sys_info(&sys_info);
- return ((sys_info.freqSystemBus + 7L) / 8L);
+ return (gd->bus_clk + 4UL)/8UL;
}
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index c0ff1d5..fce0c48 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -33,6 +33,7 @@
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/fsl_law.h>
+#include "mp.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -127,12 +128,12 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm)
/* We run cpu_init_early_f in AS = 1 */
void cpu_init_early_f(void)
{
- set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR,
+ set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1, 0, BOOKE_PAGESZ_4K, 0);
/* set up CCSR if we want it moved */
-#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR_PHYS)
{
u32 temp;
@@ -141,7 +142,7 @@ void cpu_init_early_f(void)
1, 1, BOOKE_PAGESZ_4K, 0);
temp = in_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT);
- out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR >> 12);
+ out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR_PHYS >> 12);
temp = in_be32((volatile u32 *)CFG_CCSRBAR);
}
@@ -328,5 +329,8 @@ int cpu_init_r(void)
qe_reset();
#endif
+#if defined(CONFIG_MP)
+ setup_mp();
+#endif
return 0;
}
diff --git a/cpu/mpc85xx/fdt.c b/cpu/mpc85xx/fdt.c
index a6b014c..bde6d1e 100644
--- a/cpu/mpc85xx/fdt.c
+++ b/cpu/mpc85xx/fdt.c
@@ -28,6 +28,54 @@
#include <fdt_support.h>
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)
+{
+ int off;
+ ulong spin_tbl_addr = get_spin_addr();
+ u32 bootpg, id = get_my_id();
+
+ /* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+ if ((u64)gd->ram_size > 0xfffff000)
+ bootpg = 0xfffff000;
+ else
+ bootpg = gd->ram_size - 4096;
+
+ 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);
+
+ if (reg) {
+ if (*reg == id) {
+ fdt_setprop_string(blob, off, "status", "okay");
+ } else {
+ u32 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr;
+ val = cpu_to_fdt32(val);
+ fdt_setprop_string(blob, off, "status",
+ "disabled");
+ fdt_setprop_string(blob, off, "enable-method",
+ "spin-table");
+ fdt_setprop(blob, off, "cpu-release-addr",
+ &val, sizeof(val));
+ }
+ } else {
+ printf ("cpu NULL\n");
+ }
+ off = fdt_node_offset_by_prop_value(blob, off,
+ "device_type", "cpu", 4);
+ }
+
+ /* Reserve the boot page so OSes dont use it */
+ if ((u64)bootpg < memory_limit) {
+ off = fdt_add_mem_rsv(blob, bootpg, (u64)4096);
+ if (off < 0)
+ printf("%s: %s\n", __FUNCTION__, fdt_strerror(off));
+ }
+}
+#endif
void ft_cpu_setup(void *blob, bd_t *bd)
{
@@ -62,4 +110,8 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#endif
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
+
+#ifdef CONFIG_MP
+ ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize);
+#endif
}
diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c
new file mode 100644
index 0000000..7b10fba
--- /dev/null
+++ b/cpu/mpc85xx/mp.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2008 Freescale Semiconductor.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <ioports.h>
+#include <lmb.h>
+#include <asm/io.h>
+#include "mp.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 get_my_id()
+{
+ return mfspr(SPRN_PIR);
+}
+
+int cpu_reset(int nr)
+{
+ volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR);
+ out_be32(&pic->pir, 1 << nr);
+ (void)in_be32(&pic->pir);
+ out_be32(&pic->pir, 0x0);
+
+ return 0;
+}
+
+int cpu_status(int nr)
+{
+ u32 *table, id = get_my_id();
+
+ if (nr == id) {
+ table = (u32 *)get_spin_addr();
+ printf("table base @ 0x%08x\n", table);
+ } else {
+ table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+ printf("Running on cpu %d\n", id);
+ printf("\n");
+ printf("table @ 0x%08x:\n", table);
+ printf(" addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]);
+ printf(" pir - 0x%08x\n", table[BOOT_ENTRY_PIR]);
+ printf(" r3 - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]);
+ printf(" r6 - 0x%08x\n", table[BOOT_ENTRY_R6_LOWER]);
+ }
+
+ return 0;
+}
+
+static u8 boot_entry_map[4] = {
+ 0,
+ BOOT_ENTRY_PIR,
+ BOOT_ENTRY_R3_LOWER,
+ BOOT_ENTRY_R6_LOWER,
+};
+
+int cpu_release(int nr, int argc, char *argv[])
+{
+ u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+ u64 boot_addr;
+
+ if (nr == get_my_id()) {
+ printf("Invalid to release the boot core.\n\n");
+ return 1;
+ }
+
+ if (argc != 4) {
+ printf("Invalid number of arguments to release.\n\n");
+ return 1;
+ }
+
+#ifdef CFG_64BIT_STRTOUL
+ boot_addr = simple_strtoull(argv[0], NULL, 16);
+#else
+ boot_addr = simple_strtoul(argv[0], NULL, 16);
+#endif
+
+ /* handle pir, r3, r6 */
+ for (i = 1; i < 4; i++) {
+ if (argv[i][0] != '-') {
+ u8 entry = boot_entry_map[i];
+ val = simple_strtoul(argv[i], NULL, 16);
+ table[entry] = val;
+ }
+ }
+
+ table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);
+ table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff);
+
+ return 0;
+}
+
+ulong get_spin_addr(void)
+{
+ extern ulong __secondary_start_page;
+ extern ulong __spin_table;
+
+ ulong addr =
+ (ulong)&__spin_table - (ulong)&__secondary_start_page;
+ addr += 0xfffff000;
+
+ return addr;
+}
+
+static void pq3_mp_up(unsigned long bootpg)
+{
+ u32 up, cpu_up_mask, whoami;
+ u32 *table = (u32 *)get_spin_addr();
+ volatile u32 bpcr;
+ volatile ccsr_local_ecm_t *ecm = (void *)(CFG_MPC85xx_ECM_ADDR);
+ volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
+ volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR);
+ u32 devdisr;
+ int timeout = 10;
+
+ whoami = in_be32(&pic->whoami);
+ out_be32(&ecm->bptr, 0x80000000 | (bootpg >> 12));
+
+ /* disable time base at the platform */
+ devdisr = in_be32(&gur->devdisr);
+ if (whoami)
+ devdisr |= MPC85xx_DEVDISR_TB0;
+ else
+ devdisr |= MPC85xx_DEVDISR_TB1;
+ out_be32(&gur->devdisr, devdisr);
+
+ /* release the hounds */
+ up = ((1 << CONFIG_NR_CPUS) - 1);
+ bpcr = in_be32(&ecm->eebpcr);
+ bpcr |= (up << 24);
+ out_be32(&ecm->eebpcr, bpcr);
+ asm("sync; isync; msync");
+
+ cpu_up_mask = 1 << whoami;
+ /* wait for everyone */
+ while (timeout) {
+ int i;
+ for (i = 1; i < CONFIG_NR_CPUS; i++) {
+ if (table[i * NUM_BOOT_ENTRY])
+ cpu_up_mask |= (1 << i);
+ };
+
+ if ((cpu_up_mask & up) == up)
+ break;
+
+ udelay(100);
+ timeout--;
+ }
+
+ /* enable time base at the platform */
+ if (whoami)
+ devdisr |= MPC85xx_DEVDISR_TB1;
+ else
+ devdisr |= MPC85xx_DEVDISR_TB0;
+ out_be32(&gur->devdisr, devdisr);
+ mtspr(SPRN_TBWU, 0);
+ mtspr(SPRN_TBWL, 0);
+
+ devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1);
+ out_be32(&gur->devdisr, devdisr);
+}
+
+void cpu_mp_lmb_reserve(struct lmb *lmb)
+{
+ u32 bootpg;
+
+ /* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+ if ((u64)gd->ram_size > 0xfffff000)
+ bootpg = 0xfffff000;
+ else
+ bootpg = gd->ram_size - 4096;
+
+ lmb_reserve(lmb, bootpg, 4096);
+}
+
+void setup_mp(void)
+{
+ extern ulong __secondary_start_page;
+ ulong fixup = (ulong)&__secondary_start_page;
+ u32 bootpg;
+
+ /* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+ if ((u64)gd->ram_size > 0xfffff000)
+ bootpg = 0xfffff000;
+ else
+ bootpg = gd->ram_size - 4096;
+
+ memcpy((void *)bootpg, (void *)fixup, 4096);
+ flush_cache(bootpg, 4096);
+
+ pq3_mp_up(bootpg);
+}
diff --git a/cpu/mpc85xx/mp.h b/cpu/mpc85xx/mp.h
new file mode 100644
index 0000000..4329286
--- /dev/null
+++ b/cpu/mpc85xx/mp.h
@@ -0,0 +1,20 @@
+#ifndef __MPC85XX_MP_H_
+#define __MPC85XX_MP_H_
+
+ulong get_spin_addr(void);
+void setup_mp(void);
+u32 get_my_id(void);
+void cpu_mp_lmb_reserve(struct lmb *lmb);
+
+#define BOOT_ENTRY_ADDR_UPPER 0
+#define BOOT_ENTRY_ADDR_LOWER 1
+#define BOOT_ENTRY_R3_UPPER 2
+#define BOOT_ENTRY_R3_LOWER 3
+#define BOOT_ENTRY_RESV 4
+#define BOOT_ENTRY_PIR 5
+#define BOOT_ENTRY_R6_UPPER 6
+#define BOOT_ENTRY_R6_LOWER 7
+#define NUM_BOOT_ENTRY 8
+#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32))
+
+#endif
diff --git a/cpu/mpc85xx/release.S b/cpu/mpc85xx/release.S
new file mode 100644
index 0000000..3b7366f
--- /dev/null
+++ b/cpu/mpc85xx/release.S
@@ -0,0 +1,182 @@
+#include <config.h>
+#include <mpc85xx.h>
+#include <version.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+/* To boot secondary cpus, we need a place for them to start up.
+ * Normally, they start at 0xfffffffc, but that's usually the
+ * firmware, and we don't want to have to run the firmware again.
+ * Instead, the primary cpu will set the BPTR to point here to
+ * this page. We then set up the core, and head to
+ * start_secondary. Note that this means that the code below
+ * must never exceed 1023 instructions (the branch at the end
+ * would then be the 1024th).
+ */
+ .globl __secondary_start_page
+ .align 12
+__secondary_start_page:
+/* First do some preliminary setup */
+ lis r3, HID0_EMCP@h /* enable machine check */
+ ori r3,r3,HID0_TBEN@l /* enable Timebase */
+#ifdef CONFIG_PHYS_64BIT
+ ori r3,r3,HID0_ENMAS7@l /* enable MAS7 updates */
+#endif
+ mtspr SPRN_HID0,r3
+
+ li r3,(HID1_ASTME|HID1_ABE)@l /* Addr streaming & broadcast */
+ mtspr SPRN_HID1,r3
+
+ /* Enable branch prediction */
+ li r3,0x201
+ mtspr SPRN_BUCSR,r3
+
+ /* Enable/invalidate the I-Cache */
+ mfspr r0,SPRN_L1CSR1
+ ori r0,r0,(L1CSR1_ICFI|L1CSR1_ICE)
+ mtspr SPRN_L1CSR1,r0
+ isync
+
+ /* Enable/invalidate the D-Cache */
+ mfspr r0,SPRN_L1CSR0
+ ori r0,r0,(L1CSR0_DCFI|L1CSR0_DCE)
+ msync
+ isync
+ mtspr SPRN_L1CSR0,r0
+ isync
+
+#define toreset(x) (x - __secondary_start_page + 0xfffff000)
+
+ /* get our PIR to figure out our table entry */
+ lis r3,toreset(__spin_table)@h
+ ori r3,r3,toreset(__spin_table)@l
+
+ /* r10 has the base address for the entry */
+ mfspr r0,SPRN_PIR
+ mr r4,r0
+ slwi r8,r4,5
+ add r10,r3,r8
+
+#define EPAPR_MAGIC (0x45504150)
+#define ENTRY_ADDR_UPPER 0
+#define ENTRY_ADDR_LOWER 4
+#define ENTRY_R3_UPPER 8
+#define ENTRY_R3_LOWER 12
+#define ENTRY_RESV 16
+#define ENTRY_PIR 20
+#define ENTRY_R6_UPPER 24
+#define ENTRY_R6_LOWER 28
+#define ENTRY_SIZE 32
+
+ /* setup the entry */
+ li r3,0
+ li r8,1
+ stw r0,ENTRY_PIR(r10)
+ stw r3,ENTRY_ADDR_UPPER(r10)
+ stw r8,ENTRY_ADDR_LOWER(r10)
+ stw r3,ENTRY_R3_UPPER(r10)
+ stw r4,ENTRY_R3_LOWER(r10)
+ stw r3,ENTRY_R6_UPPER(r10)
+ stw r3,ENTRY_R6_LOWER(r10)
+
+ /* 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
+ 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
+ mtspr SPRN_MAS3,r11
+ tlbwe
+
+ bl 1f
+1: mflr r11
+ addi r11,r11,28
+ mfmsr r13
+ ori r12,r13,MSR_IS|MSR_DS@l
+
+ mtspr SPRN_SRR0,r11
+ mtspr SPRN_SRR1,r12
+ rfi
+
+ /* spin waiting for addr */
+2:
+ lwz r4,ENTRY_ADDR_LOWER(r10)
+ andi. r11,r4,1
+ bne 2b
+
+ /* get the upper bits of the addr */
+ lwz r11,ENTRY_ADDR_UPPER(r10)
+
+ /* setup branch addr */
+ mtspr SPRN_SRR0,r4
+
+ /* mark the entry as released */
+ li r8,3
+ stw r8,ENTRY_ADDR_LOWER(r10)
+
+ /* mask by ~64M to setup our tlb we will jump to */
+ rlwinm r12,r4,0,0,5
+
+ /* setup r3, r4, r5, r6, r7, r8, r9 */
+ lwz r3,ENTRY_R3_LOWER(r10)
+ li r4,0
+ li r5,0
+ lwz r6,ENTRY_R6_LOWER(r10)
+ lis r7,(64*1024*1024)@h
+ li r8,0
+ li r9,0
+
+ /* load up the pir */
+ lwz r0,ENTRY_PIR(r10)
+ mtspr SPRN_PIR,r0
+ mfspr r0,SPRN_PIR
+ stw r0,ENTRY_PIR(r10)
+
+/*
+ * Coming here, we know the cpu has one TLB mapping in TLB1[0]
+ * which maps 0xfffff000-0xffffffff one-to-one. We set up a
+ * second mapping that maps addr 1:1 for 64M, and then we jump to
+ * addr
+ */
+ lis r10,(MAS0_TLBSEL(1)|MAS0_ESEL(0))@h
+ mtspr SPRN_MAS0,r10
+ lis r10,(MAS1_VALID|MAS1_IPROT)@h
+ ori r10,r10,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
+ mtspr SPRN_MAS1,r10
+ /* WIMGE = 0b00000 for now */
+ mtspr SPRN_MAS2,r12
+ ori r12,r12,(MAS3_SX|MAS3_SW|MAS3_SR)
+ mtspr SPRN_MAS3,r12
+#ifdef CONFIG_ENABLE_36BIT_PHYS
+ mtspr SPRN_MAS7,r11
+#endif
+ tlbwe
+
+/* Now we have another mapping for this page, so we jump to that
+ * mapping
+ */
+ mtspr SPRN_SRR1,r13
+ rfi
+
+ .align 3
+ .globl __spin_table
+__spin_table:
+ .space CONFIG_NR_CPUS*ENTRY_SIZE
+
+ /* Fill in the empty space. The actual reset vector is
+ * the last word of the page */
+__secondary_start_code_end:
+ .space 4092 - (__secondary_start_code_end - __secondary_start_page)
+__secondary_reset_vector:
+ b __secondary_start_page
diff --git a/cpu/mpc85xx/speed.c b/cpu/mpc85xx/speed.c
index 952f30c..d90d397 100644
--- a/cpu/mpc85xx/speed.c
+++ b/cpu/mpc85xx/speed.c
@@ -48,6 +48,8 @@ void get_sys_info (sys_info_t * sysInfo)
* overflow for processor speeds above 2GHz */
half_freqSystemBus = sysInfo->freqSystemBus/2;
sysInfo->freqProcessor = e500_ratio*half_freqSystemBus;
+
+ /* Note: freqDDRBus is the MCLK frequency, not the data rate. */
sysInfo->freqDDRBus = sysInfo->freqSystemBus;
#ifdef CONFIG_DDR_CLK_FREQ
@@ -75,6 +77,7 @@ int get_clocks (void)
get_sys_info (&sys_info);
gd->cpu_clk = sys_info.freqProcessor;
gd->bus_clk = sys_info.freqSystemBus;
+ gd->mem_clk = sys_info.freqDDRBus;
gd->i2c1_clk = sys_info.freqSystemBus;
gd->i2c2_clk = sys_info.freqSystemBus;
@@ -96,14 +99,7 @@ int get_clocks (void)
*********************************************/
ulong get_bus_freq (ulong dummy)
{
- ulong val;
-
- sys_info_t sys_info;
-
- get_sys_info (&sys_info);
- val = sys_info.freqSystemBus;
-
- return val;
+ return gd->bus_clk;
}
/********************************************
@@ -112,12 +108,5 @@ ulong get_bus_freq (ulong dummy)
*********************************************/
ulong get_ddr_freq (ulong dummy)
{
- ulong val;
-
- sys_info_t sys_info;
-
- get_sys_info (&sys_info);
- val = sys_info.freqDDRBus;
-
- return val;
+ return gd->mem_clk;
}