]> git.sur5r.net Git - u-boot/blobdiff - cpu/mpc86xx/cpu.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / cpu / mpc86xx / cpu.c
index e1b3c52dcdc5e485d9c9ff828de86bd38b6bce63..f7e012db573cc0f795291f32dd3b2b9fae0c89c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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)
@@ -40,162 +50,93 @@ 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;
+       if (cpu_numcores() > 1) {
+#ifndef CONFIG_MP
+               puts("Unicore software on multiprocessor system!!\n"
+                    "To enable mutlticore build define CONFIG_MP\n");
+#endif
        }
-       printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
-
-       get_sys_info(&sysinfo);
+       puts("CPU:   ");
 
-       puts("    Clocks: ");
-       printf("CPU:%4lu MHz, ", sysinfo.freqProcessor / 1000000);
-       printf("MPX:%4lu MHz, ", sysinfo.freqSystemBus / 1000000);
-       printf("DDR:%4lu MHz, ", sysinfo.freqSystemBus / 2000000);
+       cpu = gd->cpu;
 
-#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;
+       puts(cpu->name);
 
-               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);
-       }
-
-       puts("    L2: ");
-       if (get_l2cr() & 0x80000000)
-               puts("Enabled\n");
-       else
-               puts("Disabled\n");
+       printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
+       puts("Core:  ");
 
-       return 0;
-}
+       pvr = get_pvr();
+       ver = PVR_E600_VER(pvr);
+       major = PVR_E600_MAJ(pvr);
+       minor = PVR_E600_MIN(pvr);
 
+       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);
 
-static inline void
-soft_restart(unsigned long addr)
-{
-#if !defined(CONFIG_MPC8641HPCN) && !defined(CONFIG_MPC8610HPCD)
+       printf(", Version: %d.%d, (0x%08x)\n", major, minor, pvr);
 
-       /*
-        * SRR0 has system reset vector, SRR1 has default MSR value
-        * rfi restores MSR from SRR1 and sets the PC to the SRR0 value
-        */
+       get_sys_info(&sysinfo);
 
-       __asm__ __volatile__ ("mtspr    26, %0"         :: "r" (addr));
-       __asm__ __volatile__ ("li       4, (1 << 6)"    ::: "r4");
-       __asm__ __volatile__ ("mtspr    27, 4");
-       __asm__ __volatile__ ("rfi");
+       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));
 
-#else /* CONFIG_MPC8641HPCN */
+       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);
+       }
 
-       out8(PIXIS_BASE + PIXIS_RST, 0);
+       puts("L1:    D-cache 32 KB enabled\n");
+       puts("       I-cache 32 KB enabled\n");
 
-#endif /* !CONFIG_MPC8641HPCN */
+       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");
+       }
 
-       while (1) ;             /* not reached */
+       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)
+               ;
 }
 
 
@@ -216,126 +157,33 @@ get_tbclk(void)
 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"