]> git.sur5r.net Git - u-boot/blobdiff - arch/powerpc/cpu/ppc4xx/cpu_init.c
serial: drop useless ctlr field
[u-boot] / arch / powerpc / cpu / ppc4xx / cpu_init.c
index c04eede90da87385000f622e68887ae451d8640d..970a8c1e2dc2c8e8bfc60184a1d1698ef3301d60 100644 (file)
 
 #include <common.h>
 #include <watchdog.h>
-#include <ppc4xx_enet.h>
+#include <asm/ppc4xx-emac.h>
 #include <asm/processor.h>
-#include <asm/gpio.h>
-#include <ppc4xx.h>
+#include <asm/ppc4xx-gpio.h>
+#include <asm/ppc4xx.h>
 
 #if defined(CONFIG_405GP)  || defined(CONFIG_405EP)
 DECLARE_GLOBAL_DATA_PTR;
@@ -142,22 +142,28 @@ void reconfigure_pll(u32 new_cpu_freq)
         * modify it.
         */
        if (temp == 1) {
-               mfcpr(CPR0_PLLD, reg);
-               /* Get current value of fbdv.  */
-               temp = (reg & PLLD_FBDV_MASK) >> 24;
-               fbdv = temp ? temp : 32;
-               /* Get current value of lfbdv. */
-               temp = (reg & PLLD_LFBDV_MASK);
-               lfbdv = temp ? temp : 64;
                /*
                 * Load register that contains current boot strapping option.
                 */
                mfcpr(CPR0_ICFG, reg);
-               /* Shift strapping option into low 3 bits.*/
-               reg = (reg >> 28);
+               /*
+                * Strapping option bits (ICS) are already in correct position,
+                * only masking needed.
+                */
+               reg &= CPR0_ICFG_ICS_MASK;
 
                if ((reg == BOOT_STRAP_OPTION_A) || (reg == BOOT_STRAP_OPTION_B) ||
                    (reg == BOOT_STRAP_OPTION_D) || (reg == BOOT_STRAP_OPTION_E)) {
+                       mfcpr(CPR0_PLLD, reg);
+
+                       /* Get current value of fbdv.  */
+                       temp = (reg & PLLD_FBDV_MASK) >> 24;
+                       fbdv = temp ? temp : 32;
+
+                       /* Get current value of lfbdv. */
+                       temp = (reg & PLLD_LFBDV_MASK);
+                       lfbdv = temp ? temp : 64;
+
                        /*
                         * Get current value of FWDVA. Assign current FWDVA to
                         * new FWDVB.
@@ -165,12 +171,14 @@ void reconfigure_pll(u32 new_cpu_freq)
                        mfcpr(CPR0_PLLD, reg);
                        target_fwdvb = (reg & PLLD_FWDVA_MASK) >> 16;
                        fwdvb = target_fwdvb ? target_fwdvb : 8;
+
                        /*
                         * Get current value of FWDVB. Assign current FWDVB to
                         * new FWDVA.
                         */
                        target_fwdva = (reg & PLLD_FWDVB_MASK) >> 8;
                        fwdva = target_fwdva ? target_fwdva : 16;
+
                        /*
                         * Update CPR0_PLLD with switched FWDVA and FWDVB.
                         */
@@ -181,6 +189,7 @@ void reconfigure_pll(u32 new_cpu_freq)
                                ((fbdv == 32 ? 0 : fbdv) << 24) |
                                (lfbdv == 64 ? 0 : lfbdv);
                        mtcpr(CPR0_PLLD, reg);
+
                        /* Acknowledge that a reset is required. */
                        reset_needed = 1;
                }
@@ -212,6 +221,66 @@ void reconfigure_pll(u32 new_cpu_freq)
 #endif
 }
 
+#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
+void
+chip_21_errata(void)
+{
+       /*
+        * See rev 1.09 of the 405EX/405EXr errata.  CHIP_21 says that
+        * sometimes reading the PVR and/or SDR0_ECID results in incorrect
+        * values.  Since the rev-D chip uses the SDR0_ECID bits to control
+        * internal features, that means the second PCIe or ethernet of an EX
+        * variant could fail to work.  Also, security features of both EX and
+        * EXr might be incorrectly disabled.
+        *
+        * The suggested workaround is as follows (covering rev-C and rev-D):
+        *
+        * 1.Read the PVR and SDR0_ECID3.
+        *
+        * 2.If the PVR matches an expected Revision C PVR value AND if
+        * SDR0_ECID3[12:15] is different from PVR[28:31], then processor is
+        * Revision C: continue executing the initialization code (no reset
+        * required).  else go to step 3.
+        *
+        * 3.If the PVR matches an expected Revision D PVR value AND if
+        * SDR0_ECID3[10:11] matches its expected value, then continue
+        * executing initialization code, no reset required.  else write
+        * DBCR0[RST] = 0b11 to generate a SysReset.
+        */
+
+       u32 pvr;
+       u32 pvr_28_31;
+       u32 ecid3;
+       u32 ecid3_10_11;
+       u32 ecid3_12_15;
+
+       /* Step 1: */
+       pvr = get_pvr();
+       mfsdr(SDR0_ECID3, ecid3);
+
+       /* Step 2: */
+       pvr_28_31 = pvr & 0xf;
+       ecid3_10_11 = (ecid3 >> 20) & 0x3;
+       ecid3_12_15 = (ecid3 >> 16) & 0xf;
+       if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_C) &&
+                       (pvr_28_31 != ecid3_12_15)) {
+               /* No reset required. */
+               return;
+       }
+
+       /* Step 3: */
+       if ((pvr == CONFIG_405EX_CHIP21_PVR_REV_D) &&
+                       (ecid3_10_11 == CONFIG_405EX_CHIP21_ECID3_REV_D)) {
+               /* No reset required. */
+               return;
+       }
+
+       /* Reset required. */
+       __asm__ __volatile__ ("sync; isync");
+       mtspr(SPRN_DBCR0, 0x30000000);
+}
+#endif
+
 /*
  * Breath some life into the CPU...
  *
@@ -226,9 +295,14 @@ cpu_init_f (void)
        u32 val;
 #endif
 
+#ifdef CONFIG_SYS_4xx_CHIP_21_ERRATA
+       chip_21_errata();
+#endif
+
        reconfigure_pll(CONFIG_SYS_PLL_RECONFIG);
 
-#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CONFIG_SYS_4xx_GPIO_TABLE)
+#if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && \
+    !defined(CONFIG_APM821XX) &&!defined(CONFIG_SYS_4xx_GPIO_TABLE)
        /*
         * GPIO0 setup (select GPIO or alternate function)
         */
@@ -257,7 +331,7 @@ cpu_init_f (void)
        /*
         * Set EMAC noise filter bits
         */
-       mtdcr(CPC0_EPCTL, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE);
+       mtdcr(CPC0_EPCTL, CPC0_EPCTL_E0NFE | CPC0_EPCTL_E1NFE);
 #endif /* CONFIG_405EP */
 
 #if defined(CONFIG_SYS_4xx_GPIO_TABLE)
@@ -332,7 +406,7 @@ cpu_init_f (void)
 #endif
 
 #if defined(CONFIG_WATCHDOG)
-       val = mfspr(tcr);
+       val = mfspr(SPRN_TCR);
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
        val |= 0xb8000000;      /* generate system reset after 1.34 seconds */
 #elif defined(CONFIG_440EPX)
@@ -344,11 +418,11 @@ cpu_init_f (void)
        val &= ~0x30000000;                     /* clear WRC bits */
        val |= CONFIG_SYS_4xx_RESET_TYPE << 28; /* set board specific WRC type */
 #endif
-       mtspr(tcr, val);
+       mtspr(SPRN_TCR, val);
 
-       val = mfspr(tsr);
+       val = mfspr(SPRN_TSR);
        val |= 0x80000000;      /* enable watchdog timer */
-       mtspr(tsr, val);
+       mtspr(SPRN_TSR, val);
 
        reset_4xx_watchdog();
 #endif /* CONFIG_WATCHDOG */
@@ -384,14 +458,14 @@ cpu_init_f (void)
 #if defined(CONFIG_405EX) || \
     defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT)  || \
-    defined(CONFIG_460SX)
+    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
        /*
         * Set PLB4 arbiter (Segment 0 and 1) to 4 deep pipeline read
         */
-       mtdcr(PLB0_ACR, (mfdcr(PLB0_ACR) & ~PLB0_ACR_RDP_MASK) |
-             PLB0_ACR_RDP_4DEEP);
-       mtdcr(PLB1_ACR, (mfdcr(PLB1_ACR) & ~PLB1_ACR_RDP_MASK) |
-             PLB1_ACR_RDP_4DEEP);
+       mtdcr(PLB4A0_ACR, (mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
+             PLB4Ax_ACR_RDP_4DEEP);
+       mtdcr(PLB4A1_ACR, (mfdcr(PLB4A1_ACR) & ~PLB4Ax_ACR_RDP_MASK) |
+             PLB4Ax_ACR_RDP_4DEEP);
 #endif /* CONFIG_440SP/SPE || CONFIG_460EX/GT || CONFIG_405EX */
 }