/*
- * Copyright 2006 Freescale Semiconductor
+ * Copyright 2006,2009 Freescale Semiconductor, Inc.
* Jeff Brown
* Srikanth Srinivasan (srikanth.srinivasan@freescale.com)
*
#include <watchdog.h>
#include <command.h>
#include <asm/cache.h>
+#include <asm/mmu.h>
#include <mpc86xx.h>
#include <asm/fsl_law.h>
-#if defined(CONFIG_OF_FLAT_TREE)
-#include <ft_build.h>
-#endif
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Default board reset function
+ */
+static void
+__board_reset(void)
+{
+ /* Do nothing */
+}
+void board_reset(void) __attribute__((weak, alias("__board_reset")));
+
int
checkcpu(void)
uint pvr, svr;
uint ver;
uint major, minor;
- uint lcrr; /* local bus clock ratio register */
- uint clkdiv; /* clock divider portion of lcrr */
- volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ char buf1[32], buf2[32];
+ volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
volatile ccsr_gur_t *gur = &immap->im_gur;
-
- puts("Freescale PowerPC\n");
-
- pvr = get_pvr();
- ver = PVR_VER(pvr);
- major = PVR_MAJ(pvr);
- minor = PVR_MIN(pvr);
-
- puts("CPU:\n");
- puts(" Core: ");
-
- switch (ver) {
- case PVR_VER(PVR_86xx):
- {
- uint msscr0 = mfspr(MSSCR0);
- printf("E600 Core %d", (msscr0 & 0x20) ? 1 : 0 );
- if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
- puts("\n Core1Translation Enabled");
- debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
- }
- break;
- default:
- puts("Unknown");
- break;
- }
- printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
+ struct cpu_type *cpu;
+ uint msscr0 = mfspr(MSSCR0);
svr = get_svr();
- ver = SVR_VER(svr);
+ ver = SVR_SOC_VER(svr);
major = SVR_MAJ(svr);
minor = SVR_MIN(svr);
- puts(" System: ");
- switch (ver) {
- case SVR_8641:
- if (SVR_SUBVER(svr) == 1) {
- puts("8641D");
- } else {
- puts("8641");
- }
- break;
- case SVR_8610:
- puts("8610");
- break;
- default:
- puts("Unknown");
- break;
- }
- printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+ puts("CPU: ");
- get_sys_info(&sysinfo);
-
- puts(" Clocks: ");
- printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
- printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
- printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
-
-#if defined(CFG_LBC_LCRR)
- lcrr = CFG_LBC_LCRR;
-#else
- {
- volatile immap_t *immap = (immap_t *) CFG_IMMR;
- volatile ccsr_lbc_t *lbc = &immap->im_lbc;
-
- lcrr = lbc->lcrr;
- }
-#endif
- clkdiv = lcrr & 0x0f;
- if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
- printf("LBC:%4lu MHz\n",
- sysinfo.freqSystemBus / 1000000 / clkdiv);
- } else {
- printf(" LBC: unknown (lcrr: 0x%08x)\n", lcrr);
- }
+ cpu = gd->cpu;
- puts(" L2: ");
- if (get_l2cr() & 0x80000000)
- puts("Enabled\n");
+ if (cpu->name)
+ puts(cpu->name);
else
- puts("Disabled\n");
+ puts("Unknown");
- return 0;
-}
+ printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+ puts("Core: ");
+ pvr = get_pvr();
+ ver = PVR_E600_VER(pvr);
+ major = PVR_E600_MAJ(pvr);
+ minor = PVR_E600_MIN(pvr);
-static inline void
-soft_restart(unsigned long addr)
-{
-#if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
+ printf("E600 Core %d", (msscr0 & 0x20) ? 1 : 0 );
+ if (gur->pordevsr & MPC86xx_PORDEVSR_CORE1TE)
+ puts("\n Core1Translation Enabled");
+ debug(" (MSSCR0=%x, PORDEVSR=%x)", msscr0, gur->pordevsr);
- /*
- * SRR0 has system reset vector, SRR1 has default MSR value
- * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
- */
+ printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
- __asm__ __volatile__ ("mtspr 26, %0" :: "r" (addr));
- __asm__ __volatile__ ("li 4, (1 << 6)" ::: "r4");
- __asm__ __volatile__ ("mtspr 27, 4");
- __asm__ __volatile__ ("rfi");
+ get_sys_info(&sysinfo);
-#else /* CONFIG_MPC8641HPCN */
+ puts("Clock Configuration:\n");
+ printf(" CPU:%-4s MHz, ", strmhz(buf1, sysinfo.freqProcessor));
+ printf("MPX:%-4s MHz\n", strmhz(buf1, sysinfo.freqSystemBus));
+ printf(" DDR:%-4s MHz (%s MT/s data rate), ",
+ strmhz(buf1, sysinfo.freqSystemBus / 2),
+ strmhz(buf2, sysinfo.freqSystemBus));
- out8(PIXIS_BASE + PIXIS_RST, 0);
+ 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);
+ }
-#endif /* !CONFIG_MPC8641HPCN */
+ puts("L1: D-cache 32 KB enabled\n");
+ puts(" I-cache 32 KB enabled\n");
- while (1) ; /* not reached */
+ puts("L2: ");
+ if (get_l2cr() & 0x80000000) {
+#if defined(CONFIG_MPC8610)
+ puts("256");
+#elif defined(CONFIG_MPC8641)
+ puts("512");
+#endif
+ puts(" KB enabled\n");
+ } else {
+ puts("Disabled\n");
+ }
+
+ return 0;
}
-/*
- * No generic way to do board reset. Simply call soft_reset.
- */
void
do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
-#if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
-
-#ifdef CFG_RESET_ADDRESS
- ulong addr = CFG_RESET_ADDRESS;
-#else
- /*
- * note: when CFG_MONITOR_BASE points to a RAM address,
- * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
- * address. Better pick an address known to be invalid on your
- * system and assign it to CFG_RESET_ADDRESS.
- */
- ulong addr = CFG_MONITOR_BASE - sizeof(ulong);
-#endif
-
- /* flush and disable I/D cache */
- __asm__ __volatile__ ("mfspr 3, 1008" ::: "r3");
- __asm__ __volatile__ ("ori 5, 5, 0xcc00" ::: "r5");
- __asm__ __volatile__ ("ori 4, 3, 0xc00" ::: "r4");
- __asm__ __volatile__ ("andc 5, 3, 5" ::: "r5");
- __asm__ __volatile__ ("sync");
- __asm__ __volatile__ ("mtspr 1008, 4");
- __asm__ __volatile__ ("isync");
- __asm__ __volatile__ ("sync");
- __asm__ __volatile__ ("mtspr 1008, 5");
- __asm__ __volatile__ ("isync");
- __asm__ __volatile__ ("sync");
-
- soft_restart(addr);
-
-#else /* CONFIG_MPC8641HPCN */
+ volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
- out8(PIXIS_BASE + PIXIS_RST, 0);
+ /* Attempt board-specific reset */
+ board_reset();
-#endif /* !CONFIG_MPC8641HPCN */
+ /* Next try asserting HRESET_REQ */
+ out_be32(&gur->rstcr, MPC86xx_RSTCR_HRST_REQ);
- while (1) ; /* not reached */
+ while (1)
+ ;
}
void
watchdog_reset(void)
{
-}
-#endif /* CONFIG_WATCHDOG */
-
-
-#if defined(CONFIG_DDR_ECC)
-void
-dma_init(void)
-{
- volatile immap_t *immap = (immap_t *) CFG_IMMR;
- volatile ccsr_dma_t *dma = &immap->im_dma;
-
- dma->satr0 = 0x00040000;
- dma->datr0 = 0x00040000;
- asm("sync; isync");
-}
-
-uint
-dma_check(void)
-{
- volatile immap_t *immap = (immap_t *) CFG_IMMR;
- volatile ccsr_dma_t *dma = &immap->im_dma;
- volatile uint status = dma->sr0;
-
- /* While the channel is busy, spin */
- while ((status & 4) == 4) {
- status = dma->sr0;
- }
+#if defined(CONFIG_MPC8610)
+ /*
+ * This actually feed the hard enabled watchdog.
+ */
+ volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
+ volatile ccsr_wdt_t *wdt = &immap->im_wdt;
+ volatile ccsr_gur_t *gur = &immap->im_gur;
+ u32 tmp = gur->pordevsr;
- if (status != 0) {
- printf("DMA Error: status = %x\n", status);
+ if (tmp & 0x4000) {
+ wdt->swsrr = 0x556c;
+ wdt->swsrr = 0xaa39;
}
- return status;
-}
-
-int
-dma_xfer(void *dest, uint count, void *src)
-{
- volatile immap_t *immap = (immap_t *) CFG_IMMR;
- volatile ccsr_dma_t *dma = &immap->im_dma;
-
- dma->dar0 = (uint) dest;
- dma->sar0 = (uint) src;
- dma->bcr0 = count;
- dma->mr0 = 0xf000004;
- asm("sync;isync");
- dma->mr0 = 0xf000005;
- asm("sync;isync");
- return dma_check();
-}
-
-#endif /* CONFIG_DDR_ECC */
-
-
-#ifdef CONFIG_OF_FLAT_TREE
-void
-ft_cpu_setup(void *blob, bd_t *bd)
-{
- u32 *p;
- ulong clock;
- int len;
-
- clock = bd->bi_busfreq;
- p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
- p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
- p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
- if (p != NULL)
- *p = cpu_to_be32(clock);
-
-#if defined(CONFIG_TSEC1)
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enetaddr, 6);
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len);
- if (p)
- memcpy(p, bd->bi_enetaddr, 6);
-#endif
-
-#if defined(CONFIG_TSEC2)
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet1addr, 6);
-#endif
-
-#if defined(CONFIG_TSEC3)
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet2addr, 6);
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@26000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet2addr, 6);
-#endif
-
-#if defined(CONFIG_TSEC4)
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet3addr, 6);
- p = ft_get_prop(blob, "/" OF_SOC "/ethernet@27000/local-mac-address", &len);
- if (p != NULL)
- memcpy(p, bd->bi_enet3addr, 6);
#endif
-#endif /* CONFIG_OF_FLAT_TREE */
+}
+#endif /* CONFIG_WATCHDOG */
/*
* Print out the state of various machine registers.
- * Currently prints out LAWs and BR0/OR0
+ * Currently prints out LAWs, BR0/OR0, and BATs
*/
void mpc86xx_reginfo(void)
{
- immap_t *immap = (immap_t *)CFG_IMMR;
+ immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
ccsr_lbc_t *lbc = &immap->im_lbc;
+ print_bats();
print_laws();
printf ("Local Bus Controller Registers\n"