APM821xx: Add CPU support
authorTirumala Marri <tmarri@apm.com>
Tue, 28 Sep 2010 21:15:14 +0000 (14:15 -0700)
committerStefan Roese <sr@denx.de>
Mon, 4 Oct 2010 09:15:02 +0000 (11:15 +0200)
APM821XX is a new line of SoCs which are derivatives of
PPC44X family of processors. This patch adds support of CPU, cache,
tlb, 32k ocm, bootstraps, PLB and AHB bus.

Signed-off-by: Tirumala R Marri <tmarri@apm.com>
Signed-off-by: Stefan Roese <sr@denx.de>
arch/powerpc/cpu/ppc4xx/cpu.c
arch/powerpc/cpu/ppc4xx/cpu_init.c
arch/powerpc/cpu/ppc4xx/speed.c
arch/powerpc/cpu/ppc4xx/start.S
arch/powerpc/include/asm/apm821xx.h [new file with mode: 0644]
arch/powerpc/include/asm/ppc4xx-ebc.h
arch/powerpc/include/asm/ppc4xx-isram.h
arch/powerpc/include/asm/ppc4xx-sdram.h
arch/powerpc/include/asm/ppc4xx-uic.h
arch/powerpc/include/asm/ppc4xx.h
arch/powerpc/include/asm/processor.h

index 6009b0ce048089b0d7e06177eec77caee110833b..67f1fff7efe7613f6f7ce83632aa018028f7dca8 100644 (file)
@@ -250,6 +250,20 @@ static char *bootstrap_str[] = {
 };
 static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };
 #endif
+#if defined(CONFIG_APM821XX)
+#define SDR0_PINSTP_SHIFT       29
+static char *bootstrap_str[] = {
+       "RESERVED",
+       "RESERVED",
+       "RESERVED",
+       "NAND (8 bits)",
+       "NOR  (8 bits)",
+       "NOR  (8 bits) w/PLL Bypassed",
+       "I2C (Addr 0x54)",
+       "I2C (Addr 0x52)",
+};
+static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
+#endif
 
 #if defined(SDR0_PINSTP_SHIFT)
 static int bootstrap_option(void)
@@ -590,6 +604,11 @@ int checkcpu (void)
                strcpy(addstr, "No Security support");
                break;
 
+       case PVR_APM821XX_RA:
+               puts("APM821XX Rev. A");
+               strcpy(addstr, "Security support");
+               break;
+
        case PVR_VIRTEX5:
                puts("440x5 VIRTEX5");
                break;
index d54b30e26f099b5172a1c2ac589daaf9903835f1..2a727b1df38b94b96a27ba70dddd02a886c3a6a9 100644 (file)
@@ -237,7 +237,8 @@ cpu_init_f (void)
 
        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)
         */
@@ -393,7 +394,7 @@ 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
         */
index abd4e910d235f61f549959057a0769bcd0671885..09d6671d0d8a7ea0091e63a65b0a75e6e8148012 100644 (file)
@@ -189,7 +189,7 @@ ulong get_PCI_freq (void)
 #elif defined(CONFIG_440)
 
 #if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
-    defined(CONFIG_460SX)
+    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
 static u8 pll_fwdv_multi_bits[] = {
        /* values for:  1 - 16 */
        0x00, 0x01, 0x0f, 0x04, 0x09, 0x0a, 0x0d, 0x0e, 0x03, 0x0c,
@@ -250,6 +250,78 @@ u32 get_cpr0_fbdv(unsigned long cpr_reg_fbdv)
        return 0;
 }
 
+#if defined(CONFIG_APM821XX)
+
+void get_sys_info(sys_info_t *sysInfo)
+{
+       unsigned long plld;
+       unsigned long temp;
+       unsigned long mul;
+       unsigned long cpudv;
+       unsigned long plb2dv;
+       unsigned long ddr2dv;
+
+       /* Calculate Forward divisor A and Feeback divisor */
+       mfcpr(CPR0_PLLD, plld);
+
+       temp = CPR0_PLLD_FWDVA(plld);
+       sysInfo->pllFwdDivA = get_cpr0_fwdv(temp);
+
+       temp = CPR0_PLLD_FDV(plld);
+       sysInfo->pllFbkDiv = get_cpr0_fbdv(temp);
+
+       /* Calculate OPB clock divisor */
+       mfcpr(CPR0_OPBD, temp);
+       temp = CPR0_OPBD_OPBDV(temp);
+       sysInfo->pllOpbDiv = temp ? temp : 4;
+
+       /* Calculate Peripheral clock divisor */
+       mfcpr(CPR0_PERD, temp);
+       temp = CPR0_PERD_PERDV(temp);
+       sysInfo->pllExtBusDiv = temp ? temp : 4;
+
+       /* Calculate CPU clock divisor */
+       mfcpr(CPR0_CPUD, temp);
+       temp = CPR0_CPUD_CPUDV(temp);
+       cpudv = temp ? temp : 8;
+
+       /* Calculate PLB2 clock divisor */
+       mfcpr(CPR0_PLB2D, temp);
+       temp = CPR0_PLB2D_PLB2DV(temp);
+       plb2dv = temp ? temp : 4;
+
+       /* Calculate DDR2 clock divisor */
+       mfcpr(CPR0_DDR2D, temp);
+       temp = CPR0_DDR2D_DDR2DV(temp);
+       ddr2dv = temp ? temp : 4;
+
+       /* Calculate 'M' based on feedback source */
+       mfcpr(CPR0_PLLC, temp);
+       temp = CPR0_PLLC_SEL(temp);
+       if (temp == 0) {
+               /* PLL internal feedback */
+               mul = sysInfo->pllFbkDiv;
+       } else {
+               /* PLL PerClk feedback */
+               mul = sysInfo->pllFwdDivA * sysInfo->pllFbkDiv * cpudv
+                       * plb2dv * 2 * sysInfo->pllOpbDiv *
+                         sysInfo->pllExtBusDiv;
+       }
+
+       /* Now calculate the individual clocks */
+       sysInfo->freqVCOMhz = (mul * CONFIG_SYS_CLK_FREQ) + (mul >> 1);
+       sysInfo->freqProcessor = sysInfo->freqVCOMhz /
+               sysInfo->pllFwdDivA / cpudv;
+       sysInfo->freqPLB = sysInfo->freqVCOMhz /
+               sysInfo->pllFwdDivA / cpudv / plb2dv / 2;
+       sysInfo->freqOPB = sysInfo->freqPLB / sysInfo->pllOpbDiv;
+       sysInfo->freqEBC = sysInfo->freqOPB / sysInfo->pllExtBusDiv;
+       sysInfo->freqDDR = sysInfo->freqVCOMhz /
+               sysInfo->pllFwdDivA / cpudv / ddr2dv / 2;
+       sysInfo->freqUART = sysInfo->freqPLB;
+}
+
+#else
 /*
  * AMCC_TODO: verify this routine against latest EAS, cause stuff changed
  *            with latest EAS
@@ -307,6 +379,7 @@ void get_sys_info (sys_info_t * sysInfo)
 
        return;
 }
+#endif
 
 #elif defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
     defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
index 7a65d9fcc67f4164908f095f15547ccbd086612f..c2d52bfb9f173b86679302742d869087e7ca5c31 100644 (file)
@@ -703,7 +703,8 @@ _start:
     defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
     defined(CONFIG_460SX)
        mtdcr   L2_CACHE_CFG,r0         /* Ensure L2 Cache is off */
-#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+      defined(CONFIG_APM821XX)
        lis     r1, 0x0000
        ori     r1,r1,0x0008            /* Set L2_CACHE_CFG[RDBW]=1 */
        mtdcr   L2_CACHE_CFG,r1
@@ -731,7 +732,8 @@ _start:
        lis     r1, 0x8003
        ori     r1,r1, 0x0980           /* fourth 64k */
        mtdcr   ISRAM0_SB3CR,r1
-#elif defined(CONFIG_440SPE) || defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#elif defined(CONFIG_440SPE) || defined(CONFIG_460EX) || \
+      defined(CONFIG_460GT) || defined(CONFIG_APM821XX)
        lis     r1,0x0000               /* BAS = X_0000_0000 */
        ori     r1,r1,0x0984            /* first 64k */
        mtdcr   ISRAM0_SB0CR,r1
@@ -744,7 +746,8 @@ _start:
        lis     r1, 0x0003
        ori     r1,r1, 0x0984           /* fourth 64k */
        mtdcr   ISRAM0_SB3CR,r1
-#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_APM821XX)
        lis     r2,0x7fff
        ori     r2,r2,0xffff
        mfdcr   r1,ISRAM1_DPC
@@ -755,7 +758,7 @@ _start:
        mtdcr   ISRAM1_PMEG,r1
 
        lis     r1,0x0004               /* BAS = 4_0004_0000 */
-       ori     r1,r1,0x0984            /* 64k */
+       ori     r1,r1,ISRAM1_SIZE       /* ocm size */
        mtdcr   ISRAM1_SB0CR,r1
 #endif
 #elif defined(CONFIG_460SX)
diff --git a/arch/powerpc/include/asm/apm821xx.h b/arch/powerpc/include/asm/apm821xx.h
new file mode 100644 (file)
index 0000000..8841bc9
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010, Applied Micro Circuits Corporation
+ * Author: Tirumala R Marri <tmarri@apm.com>
+ *
+ * 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
+ */
+
+#ifndef _APM821XX_H_
+#define _APM821XX_H_
+
+#define CONFIG_SDRAM_PPC4xx_IBM_DDR2   /* IBM DDR(2) controller */
+
+/* Memory mapped registers */
+#define CONFIG_SYS_PERIPHERAL_BASE     0xEF600000
+#define CONFIG_SYS_NS16550_COM1        (CONFIG_SYS_PERIPHERAL_BASE + 0x0200)
+#define CONFIG_SYS_NS16550_COM2        (CONFIG_SYS_PERIPHERAL_BASE + 0x0300)
+
+#define GPIO0_BASE             (CONFIG_SYS_PERIPHERAL_BASE + 0x0700)
+
+#define SDR0_SRST0_DMC         0x00200000
+#define SDR0_SRST1_AHB         0x00000040      /* PLB4XAHB bridge */
+
+/* AHB config. */
+#define AHB_TOP                        0xA4
+#define AHB_BOT                        0xA5
+
+/* clk divisors */
+#define PLLSYS0_FWD_DIV_A_MASK 0x000000f0      /* Fwd Div A */
+#define PLLSYS0_FWD_DIV_B_MASK 0x0000000f      /* Fwd Div B */
+#define PLLSYS0_FB_DIV_MASK    0x0000ff00      /* Feedback divisor */
+#define PLLSYS0_OPB_DIV_MASK   0x0c000000      /* OPB Divisor */
+#define PLLSYS0_EPB_DIV_MASK   0x00000300      /* EPB divisor */
+#define PLLSYS0_EXTSL_MASK     0x00000080      /* PerClk feedback path */
+#define PLLSYS0_PLBEDV0_DIV_MASK       0xe0000000/* PLB Early Clk Div*/
+#define PLLSYS0_PERCLK_DIV_MASK        0x03000000      /* Peripheral Clk Divisor */
+#define PLLSYS0_SEL_MASK       0x18000000      /* 0 = PLL, 1 = PerClk */
+
+/*
+   + * Clocking Controller
+   + */
+#define CPR0_CLKUPD    0x0020
+#define CPR0_PLLC      0x0040
+#define CPR0_PLLC_SEL(pllc)            (((pllc) & 0x01000000) >> 24)
+#define CPR0_PLLD      0x0060
+#define CPR0_PLLD_FDV(plld)            (((plld) & 0xff000000) >> 24)
+#define CPR0_PLLD_FWDVA(plld)          (((plld) & 0x000f0000) >> 16)
+#define CPR0_CPUD      0x0080
+#define CPR0_CPUD_CPUDV(cpud)          (((cpud) & 0x07000000) >> 24)
+#define CPR0_PLB2D     0x00a0
+#define CPR0_PLB2D_PLB2DV(plb2d)       (((plb2d) & 0x06000000) >> 25)
+#define CPR0_OPBD      0x00c0
+#define CPR0_OPBD_OPBDV(opbd)          (((opbd) & 0x03000000) >> 24)
+#define CPR0_PERD      0x00e0
+#define CPR0_PERD_PERDV(perd)          (((perd) & 0x03000000) >> 24)
+#define CPR0_DDR2D     0x0100
+#define CPR0_DDR2D_DDR2DV(ddr2d)       (((ddr2d) & 0x06000000) >> 25)
+#define CLK_ICFG       0x0140
+
+#endif /* _APM821XX_H_ */
index 9c17e46252267c954612f327e1340989138d0e16..75af13000ec7a904bf01cdf60224dec8fa2856ae 100644 (file)
@@ -69,7 +69,8 @@
 #define EBC_NUM_BANKS  6
 #endif
 
-#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_APM821XX)
 #define EBC_NUM_BANKS  3
 #endif
 
index d6d17ac961bc18159f35571377326fb7826d88d6..32e1297d017b47c562f83d28ce2b2ee25ba77ea2 100644 (file)
@@ -25,7 +25,8 @@
 /*
  * Internal SRAM
  */
-#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_APM821XX)
 #define ISRAM0_DCR_BASE 0x380
 #else
 #define ISRAM0_DCR_BASE 0x020
@@ -42,7 +43,8 @@
 #define ISRAM0_REVID   (ISRAM0_DCR_BASE+0x09)  /* SRAM bus revision id reg */
 #define ISRAM0_DPC     (ISRAM0_DCR_BASE+0x0a)  /* SRAM data parity check reg */
 
-#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_APM821XX)
 #define ISRAM1_DCR_BASE 0x0B0
 #define ISRAM1_SB0CR   (ISRAM1_DCR_BASE+0x00)  /* SRAM1 bank config 0*/
 #define ISRAM1_BEAR    (ISRAM1_DCR_BASE+0x04)  /* SRAM1 bus error addr reg */
 #define ISRAM1_DPC     (ISRAM1_DCR_BASE+0x0a)  /* SRAM1 data parity check reg */
 #endif /* CONFIG_460EX || CONFIG_460GT */
 
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#define ISRAM1_SIZE 0x0984 /* OCM size 64k */
+#elif defined(CONFIG_APM821XX)
+#define ISRAM1_SIZE 0x0784 /* OCM size 32k */
+#endif
+
 /*
  * L2 Cache
  */
 #if defined (CONFIG_440GX) || \
     defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
-    defined(CONFIG_460SX)
+    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
 #define L2_CACHE_BASE  0x030
 #define L2_CACHE_CFG   (L2_CACHE_BASE+0x00)    /* L2 Cache Config      */
 #define L2_CACHE_CMD   (L2_CACHE_BASE+0x01)    /* L2 Cache Command     */
index ac150c268d8eef311a6ac57b78b4bff108662591..d570d7915e9bd86a2246e957055a2467539e919d 100644 (file)
  */
 #if defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
-    defined(CONFIG_460SX)
+    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
 #define SDRAM_RXBAS_SDBA_MASK          0xFFE00000      /* Base address */
 #define SDRAM_RXBAS_SDBA_ENCODE(n)     ((u32)(((phys_size_t)(n) >> 2) & 0xFFE00000))
 #define SDRAM_RXBAS_SDBA_DECODE(n)     ((((phys_size_t)(n)) & 0xFFE00000) << 2)
 /*
  * Memory controller registers
  */
-#ifdef CONFIG_405EX
+#if defined(CONFIG_405EX) || defined(CONFIG_APM821XX)
 #define SDRAM_BESR     0x00    /* PLB bus error status (read/clear)         */
 #define SDRAM_BESRT    0x01    /* PLB bus error status (test/set)           */
 #define SDRAM_BEARL    0x02    /* PLB bus error address low                 */
 #define SDRAM_PLBOPT   0x08    /* PLB slave options                         */
 #define SDRAM_PUABA    0x09    /* PLB upper address base                    */
 #define SDRAM_MCSTAT   0x1F    /* memory controller status                  */
-#else /* CONFIG_405EX */
+#else /* CONFIG_405EX || CONFIG_APM821XX */
 #define SDRAM_MCSTAT   0x14    /* memory controller status                  */
-#endif /* CONFIG_405EX */
+#endif /* CONFIG_405EX || CONFIG_APM821XX */
 #define SDRAM_MCOPT1   0x20    /* memory controller options 1               */
 #define SDRAM_MCOPT2   0x21    /* memory controller options 2               */
 #define SDRAM_MODT0    0x22    /* on die termination for bank 0             */
 #define SDRAM_MEMODE   0x89    /* memory extended mode                      */
 #define SDRAM_ECCES    0x98    /* ECC error status                          */
 #define SDRAM_CID      0xA4    /* core ID                                   */
-#ifndef CONFIG_405EX
+#if !defined(CONFIG_405EX) && !defined(CONFIG_APM821XX)
 #define SDRAM_RID      0xA8    /* revision ID                               */
 #endif
 #define SDRAM_FCSR     0xB0    /* feedback calibration status               */
 #define SDRAM_RTSR     0xB1    /* run time status tracking                  */
-#ifdef CONFIG_405EX
+#if  defined(CONFIG_405EX) || defined(CONFIG_APM821XX)
 #define SDRAM_RID      0xF8    /* revision ID                               */
 #endif
 
index 782d0454b7e5721eb4941af0120870513863bd27..3714a0a4f1c1e3e60049dec94370fcae706e28d5 100644 (file)
@@ -31,7 +31,7 @@
  */
 #if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
     defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
-    defined(CONFIG_460SX)
+    defined(CONFIG_460SX) || defined(CONFIG_APM821XX)
 #define UIC_MAX                4
 #elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
     defined(CONFIG_405EX)
 #define VECNUM_ETH0            (32 + 28)
 #endif /* CONFIG_440SPE */
 
-#if defined(CONFIG_460EX) || defined(CONFIG_460GT)
+#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \
+    defined(CONFIG_APM821XX)
 /* UIC 0 */
 #define VECNUM_UIC2NCI         10
 #define VECNUM_UIC2CI          11
index 87a16ec986b5da521649794ab852d56ee06f15a7..1b98f8b7b589d71bf29df240d3dc465397bccd4f 100644 (file)
 #include <asm/ppc460sx.h>
 #endif
 
+#if defined(CONFIG_APM821XX)
+#include <asm/apm821xx.h>
+#endif
+
 /*
  * Configure which SDRAM/DDR/DDR2 controller is equipped
  */
index 84a1e2ec0de7048a6f3b0193d55d6feffe1d568e..9cafe85f191697130cb218a4bcb0052f33bc4b8d 100644 (file)
 #define PVR_460SX_RA_V1 0x13541801 /* 460SX rev A Variant 1 Security disabled */
 #define PVR_460GX_RA    0x13541802 /* 460GX rev A                   */
 #define PVR_460GX_RA_V1 0x13541803 /* 460GX rev A Variant 1 Security disabled */
+#define PVR_APM821XX_RA 0x12C41C80 /* APM821XX rev A */
 #define PVR_601                0x00010000
 #define PVR_602                0x00050000
 #define PVR_603                0x00030000