summaryrefslogtreecommitdiff
path: root/arch/powerpc/cpu/ppc4xx
diff options
context:
space:
mode:
authorTirumala Marri <tmarri@apm.com>2010-09-28 14:15:14 -0700
committerStefan Roese <sr@denx.de>2010-10-04 11:15:02 +0200
commit1b8fec1393e33d72d0e24f55ed597673b1c9e884 (patch)
tree4a4decf6305d3e96805ea9fcab3b61034e5c05c7 /arch/powerpc/cpu/ppc4xx
parentdd09985499ac95484974eb0f832fe47b33369952 (diff)
downloadu-boot-imx-1b8fec1393e33d72d0e24f55ed597673b1c9e884.zip
u-boot-imx-1b8fec1393e33d72d0e24f55ed597673b1c9e884.tar.gz
u-boot-imx-1b8fec1393e33d72d0e24f55ed597673b1c9e884.tar.bz2
APM821xx: Add CPU support
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>
Diffstat (limited to 'arch/powerpc/cpu/ppc4xx')
-rw-r--r--arch/powerpc/cpu/ppc4xx/cpu.c19
-rw-r--r--arch/powerpc/cpu/ppc4xx/cpu_init.c5
-rw-r--r--arch/powerpc/cpu/ppc4xx/speed.c75
-rw-r--r--arch/powerpc/cpu/ppc4xx/start.S11
4 files changed, 103 insertions, 7 deletions
diff --git a/arch/powerpc/cpu/ppc4xx/cpu.c b/arch/powerpc/cpu/ppc4xx/cpu.c
index 6009b0c..67f1fff 100644
--- a/arch/powerpc/cpu/ppc4xx/cpu.c
+++ b/arch/powerpc/cpu/ppc4xx/cpu.c
@@ -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;
diff --git a/arch/powerpc/cpu/ppc4xx/cpu_init.c b/arch/powerpc/cpu/ppc4xx/cpu_init.c
index d54b30e..2a727b1 100644
--- a/arch/powerpc/cpu/ppc4xx/cpu_init.c
+++ b/arch/powerpc/cpu/ppc4xx/cpu_init.c
@@ -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
*/
diff --git a/arch/powerpc/cpu/ppc4xx/speed.c b/arch/powerpc/cpu/ppc4xx/speed.c
index abd4e91..09d6671 100644
--- a/arch/powerpc/cpu/ppc4xx/speed.c
+++ b/arch/powerpc/cpu/ppc4xx/speed.c
@@ -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)
diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S
index 7a65d9f..c2d52bf 100644
--- a/arch/powerpc/cpu/ppc4xx/start.S
+++ b/arch/powerpc/cpu/ppc4xx/start.S
@@ -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)