vserver 2.0 rc7
[linux-2.6.git] / arch / ppc / boot / simple / embed_config.c
index 3c3b31c..c342b47 100644 (file)
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/string.h>
+#include <asm/reg.h>
 #ifdef CONFIG_8xx
 #include <asm/mpc8xx.h>
 #endif
 #ifdef CONFIG_8260
 #include <asm/mpc8260.h>
-#include <asm/immap_8260.h>
+#include <asm/immap_cpm2.h>
 #endif
 #ifdef CONFIG_40x
 #include <asm/io.h>
@@ -96,7 +97,7 @@ embed_config(bd_t **bdp)
 #endif /* CONFIG_MBX */
 
 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \
-       defined(CONFIG_RPX6) || defined(CONFIG_EP405)
+       defined(CONFIG_RPX8260) || defined(CONFIG_EP405)
 /* Helper functions for Embedded Planet boards.
 */
 /* Because I didn't find anything that would do this.......
@@ -146,7 +147,7 @@ rpx_eth(bd_t *bd, u_char *cp)
        }
 }
 
-#ifdef CONFIG_RPX6
+#ifdef CONFIG_RPX8260
 static uint
 rpx_baseten(u_char *cp)
 {
@@ -402,17 +403,21 @@ embed_config(bd_t **bdp)
 
 #ifdef CONFIG_8260
 /* Compute 8260 clock values if the rom doesn't provide them.
- * We can't compute the internal core frequency (I don't know how to
- * do that).
  */
+static unsigned char bus2core_8260[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+       3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+       6,  5, 13,  2, 14,  4, 15,  2,  3, 11,  8, 10, 16, 12,  7,  2,
+};
+
 static void
 clk_8260(bd_t *bd)
 {
        uint    scmr, vco_out, clkin;
-       uint    plldf, pllmf, busdf, brgdf, cpmdf;
-       volatile immap_t        *ip;
+       uint    plldf, pllmf, corecnf;
+       volatile cpm2_map_t     *ip;
 
-       ip = (immap_t *)IMAP_ADDR;
+       ip = (cpm2_map_t *)CPM_MAP_ADDR;
        scmr = ip->im_clkrst.car_scmr;
 
        /* The clkin is always bus frequency.
@@ -423,8 +428,7 @@ clk_8260(bd_t *bd)
        */
        plldf = (scmr >> 12) & 1;
        pllmf = scmr & 0xfff;
-       cpmdf = (scmr >> 16) & 0x0f;
-       busdf = (scmr >> 20) & 0x0f;
+       corecnf = (scmr >> 24) &0x1f;
 
        /* This is arithmetic from the 8260 manual.
        */
@@ -433,6 +437,7 @@ clk_8260(bd_t *bd)
        bd->bi_vco = vco_out;           /* Save for later */
 
        bd->bi_cpmfreq = vco_out / 2;   /* CPM Freq, in MHz */
+       bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2;
 
        /* Set Baud rate divisor.  The power up default is divide by 16,
         * but we set it again here in case it was changed.
@@ -440,8 +445,79 @@ clk_8260(bd_t *bd)
        ip->im_clkrst.car_sccr = 1;     /* DIV 16 BRG */
        bd->bi_brgfreq = vco_out / 16;
 }
+
+static unsigned char bus2core_8280[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+       3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+       6,  5, 13,  2, 14,  2, 15,  2,  3,  2,  2,  2, 16,  2,  2,  2,
+};
+
+static void
+clk_8280(bd_t *bd)
+{
+       uint    scmr, main_clk, clkin;
+       uint    pllmf, corecnf;
+       volatile cpm2_map_t     *ip;
+
+       ip = (cpm2_map_t *)CPM_MAP_ADDR;
+       scmr = ip->im_clkrst.car_scmr;
+
+       /* The clkin is always bus frequency.
+       */
+       clkin = bd->bi_busfreq;
+
+       /* Collect the bits from the scmr.
+       */
+       pllmf = scmr & 0xf;
+       corecnf = (scmr >> 24) & 0x1f;
+
+       /* This is arithmetic from the 8280 manual.
+       */
+       main_clk = clkin * (pllmf + 1);
+
+       bd->bi_cpmfreq = main_clk / 2;  /* CPM Freq, in MHz */
+       bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2;
+
+       /* Set Baud rate divisor.  The power up default is divide by 16,
+        * but we set it again here in case it was changed.
+        */
+       ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1;
+       bd->bi_brgfreq = main_clk / 16;
+}
 #endif
 
+#ifdef CONFIG_SBC82xx
+void
+embed_config(bd_t **bdp)
+{
+       u_char  *cp;
+       int     i;
+       bd_t    *bd;
+       unsigned long pvr;
+
+       bd = *bdp;
+
+       bd = &bdinfo;
+       *bdp = bd;
+       bd->bi_baudrate = 9600;
+       bd->bi_memsize = 256 * 1024 * 1024;     /* just a guess */
+
+       cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1;
+       memcpy(bd->bi_enetaddr, cp, 6);
+
+       /* can busfreq be calculated? */
+       pvr = mfspr(SPRN_PVR);
+       if ((pvr & 0xffff0000) == 0x80820000) {
+               bd->bi_busfreq = 100000000;
+               clk_8280(bd);
+       } else {
+               bd->bi_busfreq = 66000000;
+               clk_8260(bd);
+       }
+
+}
+#endif /* SBC82xx */
+
 #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
 void
 embed_config(bd_t **bdp)
@@ -512,7 +588,7 @@ embed_config(bd_t **bdp)
 }
 #endif /* SBS8260 */
 
-#ifdef CONFIG_RPX6
+#ifdef CONFIG_RPX8260
 void
 embed_config(bd_t **bdp)
 {
@@ -673,25 +749,25 @@ embed_config(bd_t ** bdp)
        static const unsigned long line_size = 32;
        static const unsigned long congruence_classes = 256;
        unsigned long addr;
-       u_char *cp;
-       int i;
+       unsigned long dccr;
        bd_t *bd;
 
        /*
-        * At one point, we were getting machine checks.  Linux was not
-        * invalidating the data cache before it was enabled.  The
-        * following code was added to do that.  Soon after we had done
-        * that, we found the real reasons for the machine checks.  I've
-        * run the kernel a few times with the following code
-        * temporarily removed without any apparent problems.  However,
-        * I objdump'ed the kernel and boot code and found out that
-        * there were no other dccci's anywhere, so I put the code back
-        * in and have been reluctant to remove it.  It seems safer to
-        * just leave it here.
+        * Invalidate the data cache if the data cache is turned off.
+        * - The 405 core does not invalidate the data cache on power-up
+        *   or reset but does turn off the data cache. We cannot assume
+        *   that the cache contents are valid.
+        * - If the data cache is turned on this must have been done by
+        *   a bootloader and we assume that the cache contents are
+        *   valid.
         */
-       for (addr = 0;
-            addr < (congruence_classes * line_size); addr += line_size) {
-             __asm__("dccci 0,%0": :"b"(addr));
+       __asm__("mfdccr %0": "=r" (dccr));
+       if (dccr == 0) {
+               for (addr = 0;
+                    addr < (congruence_classes * line_size);
+                    addr += line_size) {
+                       __asm__("dccci 0,%0": :"b"(addr));
+               }
        }
 
        bd = &bdinfo;
@@ -699,13 +775,16 @@ embed_config(bd_t ** bdp)
        bd->bi_memsize = XPAR_DDR_0_SIZE;
        bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ;
        bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ;
+       bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ;
+       timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+       /* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */
 }
 #endif /* CONFIG_XILINX_ML300 */
 
 #ifdef CONFIG_IBM_OPENBIOS
 /* This could possibly work for all treeboot roms.
 */
-#if defined(CONFIG_ASH) || defined(CONFIG_BEECH)
+#if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA)
 #define BOARD_INFO_VECTOR       0xFFF80B50 /* openbios 1.19 moved this vector down  - armin */
 #else
 #define BOARD_INFO_VECTOR      0xFFFE0B50
@@ -742,7 +821,7 @@ embed_config(bd_t **bdp)
         */
        mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);     /* 1st reset MAL */
        while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */      
-       out_be32(EMAC0_BASE,0x20000000);        /* then reset EMAC */
+       out_be32((volatile u32*)EMAC0_BASE,0x20000000);        /* then reset EMAC */
 #endif
 
        bd = &bdinfo;