mpc83xx: Add the support of MPC837x SoC

The MPC837x SoC including e300c4 core and new IP blocks,
such as SDHC, PCI Express and SATA controller.

Signed-off-by: Dave Liu <daveliu@freescale.com>
diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c
index cba57fa..23dfb30 100644
--- a/cpu/mpc83xx/speed.c
+++ b/cpu/mpc83xx/speed.c
@@ -2,7 +2,7 @@
  * (C) Copyright 2000-2002
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
- * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -100,7 +100,7 @@
 	u32 lcrr;
 
 	u32 csb_clk;
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
 	u32 tsec1_clk;
 	u32 tsec2_clk;
 	u32 usbdr_clk;
@@ -113,6 +113,9 @@
 #if !defined(CONFIG_MPC832X)
 	u32 i2c2_clk;
 #endif
+#if defined(CONFIG_MPC837X)
+	u32 sdhc_clk;
+#endif
 	u32 enc_clk;
 	u32 lbiu_clk;
 	u32 lclk_clk;
@@ -126,6 +129,11 @@
 	u32 qe_clk;
 	u32 brg_clk;
 #endif
+#if defined(CONFIG_MPC837X)
+	u32 pciexp1_clk;
+	u32 pciexp2_clk;
+	u32 sata_clk;
+#endif
 
 	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
 		return -1;
@@ -151,7 +159,7 @@
 
 	sccr = im->clk.sccr;
 
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
 	switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
 	case 0:
 		tsec1_clk = 0;
@@ -167,7 +175,7 @@
 		break;
 	default:
 		/* unkown SCCR_TSEC1CM value */
-		return -4;
+		return -2;
 	}
 
 	switch ((sccr & SCCR_USBDRCM) >> SCCR_USBDRCM_SHIFT) {
@@ -185,11 +193,11 @@
 		break;
 	default:
 		/* unkown SCCR_USBDRCM value */
-		return -8;
+		return -3;
 	}
 #endif
 
-#if defined(CONFIG_MPC834X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC837X)
 	switch ((sccr & SCCR_TSEC2CM) >> SCCR_TSEC2CM_SHIFT) {
 	case 0:
 		tsec2_clk = 0;
@@ -205,11 +213,18 @@
 		break;
 	default:
 		/* unkown SCCR_TSEC2CM value */
-		return -5;
+		return -4;
 	}
+#elif defined(CONFIG_MPC831X)
+	tsec2_clk = tsec1_clk;
 
-	i2c1_clk = tsec2_clk;
+	if (!(sccr & SCCR_TSEC1ON))
+		tsec1_clk = 0;
+	if (!(sccr & SCCR_TSEC2ON))
+		tsec2_clk = 0;
+#endif
 
+#if defined(CONFIG_MPC834X)
 	switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
 	case 0:
 		usbmph_clk = 0;
@@ -225,7 +240,7 @@
 		break;
 	default:
 		/* unkown SCCR_USBMPHCM value */
-		return -7;
+		return -5;
 	}
 
 	if (usbmph_clk != 0 && usbdr_clk != 0 && usbmph_clk != usbdr_clk) {
@@ -233,24 +248,9 @@
 		 * USB DR clock is not disabled then
 		 * USB MPH & USB DR must have the same rate
 		 */
-		return -9;
+		return -6;
 	}
-#elif defined(CONFIG_MPC831X)
-	tsec2_clk = tsec1_clk;
-
-	if (!(sccr & SCCR_TSEC1ON))
-		tsec1_clk = 0;
-	if (!(sccr & SCCR_TSEC2ON))
-		tsec2_clk = 0;
 #endif
-
-#if !defined(CONFIG_MPC834X)
-	i2c1_clk = csb_clk;
-#endif
-#if !defined(CONFIG_MPC832X)
-	i2c2_clk = csb_clk;	/* i2c-2 clk is equal to csb clk */
-#endif
-
 	switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
 	case 0:
 		enc_clk = 0;
@@ -266,9 +266,102 @@
 		break;
 	default:
 		/* unkown SCCR_ENCCM value */
-		return -6;
+		return -7;
 	}
 
+#if defined(CONFIG_MPC837X)
+	switch ((sccr & SCCR_SDHCCM) >> SCCR_SDHCCM_SHIFT) {
+	case 0:
+		sdhc_clk = 0;
+		break;
+	case 1:
+		sdhc_clk = csb_clk;
+		break;
+	case 2:
+		sdhc_clk = csb_clk / 2;
+		break;
+	case 3:
+		sdhc_clk = csb_clk / 3;
+		break;
+	default:
+		/* unkown SCCR_SDHCCM value */
+		return -8;
+	}
+#endif
+
+#if defined(CONFIG_MPC834X)
+	i2c1_clk = tsec2_clk;
+#elif defined(CONFIG_MPC8360)
+	i2c1_clk = csb_clk;
+#elif defined(CONFIG_MPC832X)
+	i2c1_clk = enc_clk;
+#elif defined(CONFIG_MPC831X)
+	i2c1_clk = enc_clk;
+#elif defined(CONFIG_MPC837X)
+	i2c1_clk = sdhc_clk;
+#endif
+#if !defined(CONFIG_MPC832X)
+	i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
+#endif
+
+#if defined(CONFIG_MPC837X)
+	switch ((sccr & SCCR_PCIEXP1CM) >> SCCR_PCIEXP1CM_SHIFT) {
+	case 0:
+		pciexp1_clk = 0;
+		break;
+	case 1:
+		pciexp1_clk = csb_clk;
+		break;
+	case 2:
+		pciexp1_clk = csb_clk / 2;
+		break;
+	case 3:
+		pciexp1_clk = csb_clk / 3;
+		break;
+	default:
+		/* unkown SCCR_PCIEXP1CM value */
+		return -9;
+	}
+
+	switch ((sccr & SCCR_PCIEXP2CM) >> SCCR_PCIEXP2CM_SHIFT) {
+	case 0:
+		pciexp2_clk = 0;
+		break;
+	case 1:
+		pciexp2_clk = csb_clk;
+		break;
+	case 2:
+		pciexp2_clk = csb_clk / 2;
+		break;
+	case 3:
+		pciexp2_clk = csb_clk / 3;
+		break;
+	default:
+		/* unkown SCCR_PCIEXP2CM value */
+		return -10;
+	}
+#endif
+
+#if defined(CONFIG_MPC837X)
+	switch ((sccr & SCCR_SATA1CM) >> SCCR_SATA1CM_SHIFT) {
+	case 0:
+		sata_clk = 0;
+		break;
+	case 1:
+		sata_clk = csb_clk;
+		break;
+	case 2:
+		sata_clk = csb_clk / 2;
+		break;
+	case 3:
+		sata_clk = csb_clk / 3;
+		break;
+	default:
+		/* unkown SCCR_SATA1CM value */
+		return -11;
+	}
+#endif
+
 	lbiu_clk = csb_clk *
 	           (1 + ((im->reset.rcwl & HRCWL_LBIUCM) >> HRCWL_LBIUCM_SHIFT));
 	lcrr = (im->lbus.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT;
@@ -280,7 +373,7 @@
 		break;
 	default:
 		/* unknown lcrr */
-		return -10;
+		return -12;
 	}
 
 	ddr_clk = csb_clk *
@@ -316,7 +409,7 @@
 		break;
 	default:
 		/* unkown core to csb ratio */
-		return -12;
+		return -13;
 	}
 
 #if defined(CONFIG_MPC8360) || defined(CONFIG_MPC832X)
@@ -327,7 +420,7 @@
 #endif
 
 	gd->csb_clk = csb_clk;
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
 	gd->tsec1_clk = tsec1_clk;
 	gd->tsec2_clk = tsec2_clk;
 	gd->usbdr_clk = usbdr_clk;
@@ -335,6 +428,9 @@
 #if defined(CONFIG_MPC834X)
 	gd->usbmph_clk = usbmph_clk;
 #endif
+#if defined(CONFIG_MPC837X)
+	gd->sdhc_clk = sdhc_clk;
+#endif
 	gd->core_clk = core_clk;
 	gd->i2c1_clk = i2c1_clk;
 #if !defined(CONFIG_MPC832X)
@@ -351,6 +447,11 @@
 	gd->qe_clk = qe_clk;
 	gd->brg_clk = brg_clk;
 #endif
+#if defined(CONFIG_MPC837X)
+	gd->pciexp1_clk = pciexp1_clk;
+	gd->pciexp2_clk = pciexp2_clk;
+	gd->sata_clk = sata_clk;
+#endif
 	gd->pci_clk = pci_sync_in;
 	gd->cpu_clk = gd->core_clk;
 	gd->bus_clk = gd->csb_clk;
@@ -387,7 +488,10 @@
 #if !defined(CONFIG_MPC832X)
 	printf("  I2C2:                %4d MHz\n", gd->i2c2_clk / 1000000);
 #endif
-#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X)
+#if defined(CONFIG_MPC837X)
+	printf("  SDHC:                %4d MHz\n", gd->sdhc_clk / 1000000);
+#endif
+#if defined(CONFIG_MPC834X) || defined(CONFIG_MPC831X) || defined(CONFIG_MPC837X)
 	printf("  TSEC1:               %4d MHz\n", gd->tsec1_clk / 1000000);
 	printf("  TSEC2:               %4d MHz\n", gd->tsec2_clk / 1000000);
 	printf("  USB DR:              %4d MHz\n", gd->usbdr_clk / 1000000);
@@ -395,6 +499,11 @@
 #if defined(CONFIG_MPC834X)
 	printf("  USB MPH:             %4d MHz\n", gd->usbmph_clk / 1000000);
 #endif
+#if defined(CONFIG_MPC837X)
+	printf("  PCIEXP1:             %4d MHz\n", gd->pciexp1_clk / 1000000);
+	printf("  PCIEXP2:             %4d MHz\n", gd->pciexp2_clk / 1000000);
+	printf("  SATA:                %4d MHz\n", gd->sata_clk / 1000000);
+#endif
 	return 0;
 }