mpc83xx: Add MPC8360EMDS basic board support

Add support for the Freescale MPC8360EMDS board.
Includes DDR, DUART, Local Bus, PCI.
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 4e82a8b..1de337b 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -43,28 +43,70 @@
 
 int checkcpu(void)
 {
+	volatile immap_t *immr;
 	ulong clock = gd->cpu_clk;
 	u32 pvr = get_pvr();
+	u32 spridr;
 	char buf[32];
 
+	immr = (immap_t *)CFG_IMMRBAR;
+
 	if ((pvr & 0xFFFF0000) != PVR_83xx) {
 		puts("Not MPC83xx Family!!!\n");
 		return -1;
 	}
 
-	puts("CPU:   MPC83xx, ");
-	switch(pvr) {
-	case PVR_8349_REV10:
+	spridr = immr->sysconf.spridr;
+	puts("CPU: ");
+	switch(spridr) {
+	case SPR_8349E_REV10:
+	case SPR_8349E_REV11:
+		puts("MPC8349E, ");
 		break;
-	case PVR_8349_REV11:
+	case SPR_8349_REV10:
+	case SPR_8349_REV11:
+		puts("MPC8349, ");
+		break;
+	case SPR_8347E_REV10_TBGA:
+	case SPR_8347E_REV11_TBGA:
+	case SPR_8347E_REV10_PBGA:
+	case SPR_8347E_REV11_PBGA:
+		puts("MPC8347E, ");
+		break;
+	case SPR_8347_REV10_TBGA:
+	case SPR_8347_REV11_TBGA:
+	case SPR_8347_REV10_PBGA:
+	case SPR_8347_REV11_PBGA:
+		puts("MPC8347, ");
+		break;
+	case SPR_8343E_REV10:
+	case SPR_8343E_REV11:
+		puts("MPC8343E, ");
+		break;
+	case SPR_8343_REV10:
+	case SPR_8343_REV11:
+		puts("MPC8343, ");
+		break;
+	case SPR_8360E_REV10:
+	case SPR_8360E_REV11:
+	case SPR_8360E_REV12:
+		puts("MPC8360E, ");
+		break;
+	case SPR_8360_REV10:
+	case SPR_8360_REV11:
+	case SPR_8360_REV12:
+		puts("MPC8360, ");
 		break;
 	default:
 		puts("Rev: Unknown\n");
 		return -1;	/* Not sure what this is */
 	}
-	printf("Rev: %d.%d at %s MHz\n", (pvr & 0xf0) >> 4,
-		(pvr & 0x0f), strmhz(buf, clock));
 
+#if defined(CONFIG_MPC8349)
+	printf("Rev: %02x at %s MHz\n", (spridr & 0x0000FFFF)>>4 |(spridr & 0x0000000F), strmhz(buf, clock));
+#else
+	printf("Rev: %02x at %s MHz\n", spridr & 0x0000FFFF, strmhz(buf, clock));
+#endif
 	return 0;
 }
 
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 3dfde8a..acc8c9e 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -4,7 +4,7 @@
  * (C) Copyright 2006
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
- * Copyright 2004 Freescale Semiconductor.
+ * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
  * (C) Copyright 2003 Motorola Inc.
  * Xianghua Xiao (X.Xiao@motorola.com)
  *
@@ -112,14 +112,10 @@
 
 long int spd_sdram()
 {
-#ifdef CONFIG_MPC834X
-	int caslat_83xx;  /* For Errata DDR6 */
-#endif
 	volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
 	volatile ddr83xx_t *ddr = &immap->ddr;
 	volatile law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
 	spd_eeprom_t spd;
-	unsigned int tmp, tmp1;
 	unsigned int memsize;
 	unsigned int law_size;
 	unsigned char caslat, caslat_ctrl;
@@ -131,28 +127,7 @@
 	unsigned sdram_cfg;
 	unsigned int ddrc_ecc_enable;
 
-
         /* Read SPD parameters with I2C */
-#ifdef CFG_83XX_DDR_USES_CS0
-	ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1;
-	ddr->cs_config[0] = ( 1 << 31
-			    | (spd.nrow_addr - 12) << 8
-			    | (spd.ncol_addr - 8) );
-	debug("\n");
-	debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds);
-	debug("cs0_config = 0x%08x\n",ddr->cs_config[0]);
-
-	if (spd.nrows == 2) {
-		ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8)
-				  | ((banksize(spd.row_dens) >> 23) - 1) );
-		ddr->cs_config[1] = ( 1<<31
-				    | (spd.nrow_addr-12) << 8
-				    | (spd.ncol_addr-8) );
-		debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds);
-		debug("cs1_config = 0x%08x\n",ddr->cs_config[1]);
-	}
-
-#else
 	CFG_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
 #ifdef SPD_DEBUG
 	spd_debug(&spd);
@@ -183,6 +158,26 @@
 		return 0;
 	}
         /* Setup DDR chip select register */
+#ifdef CFG_83XX_DDR_USES_CS0
+	ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1;
+	ddr->cs_config[0] = ( 1 << 31
+			    | (spd.nrow_addr - 12) << 8
+			    | (spd.ncol_addr - 8) );
+	debug("\n");
+	debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds);
+	debug("cs0_config = 0x%08x\n",ddr->cs_config[0]);
+
+	if (spd.nrows == 2) {
+		ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8)
+				  | ((banksize(spd.row_dens) >> 23) - 1) );
+		ddr->cs_config[1] = ( 1<<31
+				    | (spd.nrow_addr-12) << 8
+				    | (spd.ncol_addr-8) );
+		debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds);
+		debug("cs1_config = 0x%08x\n",ddr->cs_config[1]);
+	}
+
+#else
 	ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1;
 	ddr->cs_config[2] = ( 1 << 31
 			    | (spd.nrow_addr - 12) << 8
@@ -243,8 +238,9 @@
 	 */
 	caslat = __ilog2(spd.cas_lat);
 
-	if (caslat > 4 ) {
-		printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n", caslat);
+	if (caslat > 6 ) {
+		printf("DDR: Invalid SPD CAS Latency, caslat=%02X\n",
+			spd.cas_lat);
 		return 0;
 	}
 	max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10
@@ -256,89 +252,110 @@
 	ddrc_clk = get_ddr_clk(0) / 1000000;
 
 	if (max_data_rate >= 390) { /* it is DDR 400 */
-		printf("DDR: platform not support DDR 400\n");
-		return 0;
+		if (ddrc_clk <= 410 && ddrc_clk > 350) {
+			/* DDR controller clk at 350~410 */
+			effective_data_rate = 400; /* 5ns */
+			caslat = caslat;
+		} else if (ddrc_clk <= 350 && ddrc_clk > 280) {
+			/* DDR controller clk at 280~350 */
+			effective_data_rate = 333; /* 6ns */
+			if (spd.clk_cycle2 == 0x60) {
+				caslat = caslat - 1;
+			} else {
+				caslat = caslat;
+			}
+		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
+			/* DDR controller clk at 230~280 */
+			effective_data_rate = 266; /* 7.5ns */
+			if (spd.clk_cycle3 == 0x75) {
+				caslat = caslat - 2;
+			} else if (spd.clk_cycle2 == 0x60) {
+				caslat = caslat - 1;
+			} else {
+				caslat = caslat;
+			}
+		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
+			/* DDR controller clk at 90~230 */
+			effective_data_rate = 200; /* 10ns */
+			if (spd.clk_cycle3 == 0x75) {
+				caslat = caslat - 2;
+			} else if (spd.clk_cycle2 == 0x60) {
+				caslat = caslat - 1;
+			} else {
+				caslat = caslat;
+			}
+		}
 	} else if (max_data_rate >= 323) { /* it is DDR 333 */
 		if (ddrc_clk <= 350 && ddrc_clk > 280) {
-			/* DDRC clk at 280~350 */
+			/* DDR controller clk at 280~350 */
 			effective_data_rate = 333; /* 6ns */
 			caslat = caslat;
 		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
-			/* DDRC clk at 230~280 */
+			/* DDR controller clk at 230~280 */
+			effective_data_rate = 266; /* 7.5ns */
 			if (spd.clk_cycle2 == 0x75) {
-				effective_data_rate = 266; /* 7.5ns */
 				caslat = caslat - 1;
+			} else {
+				caslat = caslat;
 			}
 		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
-			/* DDRC clk at 90~230 */
+			/* DDR controller clk at 90~230 */
+			effective_data_rate = 200; /* 10ns */
 			if (spd.clk_cycle3 == 0xa0) {
-				effective_data_rate = 200; /* 10ns */
 				caslat = caslat - 2;
+			} else if (spd.clk_cycle2 == 0x75) {
+				caslat = caslat - 1;
+			} else {
+				caslat = caslat;
 			}
 		}
 	} else if (max_data_rate >= 256) { /* it is DDR 266 */
 		if (ddrc_clk <= 350 && ddrc_clk > 280) {
-			/* DDRC clk at 280~350 */
+			/* DDR controller clk at 280~350 */
 			printf("DDR: DDR controller freq is more than "
 				"max data rate of the module\n");
 			return 0;
 		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
-			/* DDRC clk at 230~280 */
+			/* DDR controller clk at 230~280 */
 			effective_data_rate = 266; /* 7.5ns */
 			caslat = caslat;
 		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
-			/* DDRC clk at 90~230 */
+			/* DDR controller clk at 90~230 */
+			effective_data_rate = 200; /* 10ns */
 			if (spd.clk_cycle2 == 0xa0) {
-				effective_data_rate = 200; /* 10ns */
 				caslat = caslat - 1;
 			}
 		}
 	} else if (max_data_rate >= 190) { /* it is DDR 200 */
 		if (ddrc_clk <= 350 && ddrc_clk > 230) {
-			/* DDRC clk at 230~350 */
+			/* DDR controller clk at 230~350 */
 			printf("DDR: DDR controller freq is more than "
 				"max data rate of the module\n");
 			return 0;
 		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
-			/* DDRC clk at 90~230 */
+			/* DDR controller clk at 90~230 */
 			effective_data_rate = 200; /* 10ns */
 			caslat = caslat;
 		}
 	}
 
-#ifdef CONFIG_MPC834X
-/* Errata DDR6
-   This errata affects all MPC8349E, MPC8343E and MPC8347E processors.
-*/
-	if ((tmp1 >= 280) && (tmp1 < 350)) /* CSB=333 */
-	{
-		if (spd.mid[0] == 0x2c) {
-			/* Micron memory running at 333 MHz */
-			/* Chances are, U-Boot will crash before we get here,
-			   but just in case, display a message and return error. */
-			printf("Micron DDR not supported at 333MHz CSB\n");
-			return 0;
-		} else if (spd.mid[0] == 0xad) {
-			printf("Hynix DDR does not require Errata DDR6\n");
-		} else {
-			/* enable 2 cycle Earlier for CL=2.5 or 3 */
-			ddr->debug_reg = 0x202c0000;
-			printf("Errata DDR6 (debug_reg=0x%x)\n", ddr->debug_reg);
-		}
-		caslat_83xx = caslat;
-	}
+	debug("DDR:Effective data rate is: %dMhz\n", effective_data_rate);
+	debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat);
 
-	if ((tmp1 >= 230) && (tmp1 < 280)) {  /* CSB=266 */
-		if (spd.mid[0] != 0x2c) /* non-Micron */
-			caslat_83xx = caslat - 1;
-
+	/*
+	 * Errata DDR6 work around: input enable 2 cycles earlier.
+	 * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
+	 */
+	if (caslat == 2) {
+		ddr->debug_reg = 0x201c0000; /* CL=2 */
+	} else if (caslat == 3) {
+		ddr->debug_reg = 0x202c0000; /* CL=2.5 */
+	} else if (caslat == 4) {
+		ddr->debug_reg = 0x202c0000; /* CL=3.0 */
 	}
+	__asm__ __volatile__ ("sync");
 
-	if ((tmp1 >= 90) && (tmp1 < 230)) {  /* CSB=200 */
-		caslat = 3;
-		caslat_83xx = 2;
-	}
-#endif
+	debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);
 
 	/*
 	 * note: caslat must also be programmed into ddr->sdram_mode
@@ -353,11 +370,7 @@
 	    (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |
 	     ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) |
 	     ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) |
-#ifdef CONFIG_MPC834x
-	     ((caslat_83xx & 0x07) << 16 ) |
-#else
 	     ((caslat_ctrl & 0x07) << 16 ) |
-#endif
 	     (((picos_to_clk(spd.trfc * 1000) - 8) & 0x0f) << 12 ) |
 	     ( 0x300 ) |
 	     ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1);
@@ -370,13 +383,10 @@
 	ddr->sdram_cfg = 0x42000000;
 
 	/* Check DIMM data bus width */
-	if (spd.dataw_lsb == 0x20)
-	{
+	if (spd.dataw_lsb == 0x20) {
 		burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
 		printf("\n   DDR DIMM: data bus width is 32 bit");
-	}
-	else
-	{
+	} else {
 		burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */
 		printf("\n   DDR DIMM: data bus width is 64 bit");
 	}
@@ -384,68 +394,67 @@
 	/* Is this an ECC DDR chip? */
 	if (spd.config == 0x02) {
 		printf(" with ECC\n");
-	}
-	else
+	} else {
 		printf(" without ECC\n");
+	}
 
 	/* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus,
 	   Burst type is sequential
 	 */
-	switch(caslat) {
-	case 1:
-		ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */
-		break;
-	case 2:
-		ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */
-		break;
-	case 3:
-		ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */
-		break;
-	case 4:
-		ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */
-		break;
-	default:
-		printf("DDR:only CAS Latency 1.5, 2.0, 2.5, 3.0 "
-					"is supported.\n");
-		return 0;
+	switch (caslat) {
+		case 1:
+			ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */
+			break;
+		case 2:
+			ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */
+			break;
+		case 3:
+			ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */
+			break;
+		case 4:
+			ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */
+			break;
+		default:
+			printf("DDR:only CL 1.5, 2.0, 2.5, 3.0 is supported\n");
+			return 0;
 	}
 	debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);
 
-	switch(spd.refresh) {
-	case 0x00:
-	case 0x80:
-		tmp = picos_to_clk(15625000);
-		break;
-	case 0x01:
-	case 0x81:
-		tmp = picos_to_clk(3900000);
-		break;
-	case 0x02:
-	case 0x82:
-		tmp = picos_to_clk(7800000);
-		break;
-	case 0x03:
-	case 0x83:
-		tmp = picos_to_clk(31300000);
-		break;
-	case 0x04:
-	case 0x84:
-		tmp = picos_to_clk(62500000);
-		break;
-	case 0x05:
-	case 0x85:
-		tmp = picos_to_clk(125000000);
-		break;
-	default:
-		tmp = 0x512;
-		break;
+	switch (spd.refresh) {
+		case 0x00:
+		case 0x80:
+			refresh_clk = picos_to_clk(15625000);
+			break;
+		case 0x01:
+		case 0x81:
+			refresh_clk = picos_to_clk(3900000);
+			break;
+		case 0x02:
+		case 0x82:
+			refresh_clk = picos_to_clk(7800000);
+			break;
+		case 0x03:
+		case 0x83:
+			refresh_clk = picos_to_clk(31300000);
+			break;
+		case 0x04:
+		case 0x84:
+			refresh_clk = picos_to_clk(62500000);
+			break;
+		case 0x05:
+		case 0x85:
+			refresh_clk = picos_to_clk(125000000);
+			break;
+		default:
+			refresh_clk = 0x512;
+			break;
 	}
 
 	/*
 	 * Set BSTOPRE to 0x100 for page mode
 	 * If auto-charge is used, set BSTOPRE = 0
 	 */
-	ddr->sdram_interval = ((tmp & 0x3fff) << 16) | 0x100;
+	ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100;
 	debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);
 
 	/* SS_EN = 0, source synchronous disable
@@ -459,8 +468,8 @@
 	udelay(600);
 
 	/*
-	 * Figure out the settings for the sdram_cfg register.  Build up
-	 * the entire register in 'tmp' before writing since the write into
+	 * Figure out the settings for the sdram_cfg register. Build up
+	 * the value in 'sdram_cfg' before writing since the write into
 	 * the register will actually enable the memory controller, and all
 	 * settings must be done before enabling.
 	 *
@@ -493,13 +502,13 @@
 		/* set single bit error threshold to maximum value,
 		 * reset counter to zero */
 		ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
-			(0 << ECC_ERROR_MAN_SBEC_SHIFT);
+				(0 << ECC_ERROR_MAN_SBEC_SHIFT);
 	}
 
 	debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
 	debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
 #endif
-	printf("   DDRC ECC mode: %s", ddrc_ecc_enable ? "ON":"OFF");
+	printf("   DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF");
 
 #if defined(CONFIG_DDR_2T_TIMING)
 	/*
@@ -517,7 +526,6 @@
 }
 #endif /* CONFIG_SPD_EEPROM */
 
-
 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
 /*
  * Use timebase counter, get_timer() is not availabe
@@ -602,26 +610,16 @@
 		}
 	}
 
-	/* 8K */
-	dma_xfer((uint *)0x2000, 0x2000, (uint *)0);
-	/* 16K */
-	dma_xfer((uint *)0x4000, 0x4000, (uint *)0);
-	/* 32K */
-	dma_xfer((uint *)0x8000, 0x8000, (uint *)0);
-	/* 64K */
-	dma_xfer((uint *)0x10000, 0x10000, (uint *)0);
-	/* 128k */
-	dma_xfer((uint *)0x20000, 0x20000, (uint *)0);
-	/* 256k */
-	dma_xfer((uint *)0x40000, 0x40000, (uint *)0);
-	/* 512k */
-	dma_xfer((uint *)0x80000, 0x80000, (uint *)0);
-	/* 1M */
-	dma_xfer((uint *)0x100000, 0x100000, (uint *)0);
-	/* 2M */
-	dma_xfer((uint *)0x200000, 0x200000, (uint *)0);
-	/* 4M */
-	dma_xfer((uint *)0x400000, 0x400000, (uint *)0);
+	dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */
+	dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */
+	dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */
+	dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */
+	dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */
+	dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */
+	dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */
+	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */
+	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */
+	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */
 
 	for (i = 1; i < dram_size / 0x800000; i++) {
 		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);
diff --git a/cpu/mpc83xx/speed.c b/cpu/mpc83xx/speed.c
index 412713f..31fcadd 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 2004 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -104,79 +104,52 @@
 	u32 lcrr;
 
 	u32 csb_clk;
+#if defined(CONFIG_MPC8349)
 	u32 tsec1_clk;
 	u32 tsec2_clk;
-	u32 core_clk;
 	u32 usbmph_clk;
 	u32 usbdr_clk;
-	u32 i2c_clk;
+#endif
+	u32 core_clk;
+	u32 i2c1_clk;
+	u32 i2c2_clk;
 	u32 enc_clk;
 	u32 lbiu_clk;
 	u32 lclk_clk;
 	u32 ddr_clk;
+#if defined (CONFIG_MPC8360)
+	u32 qepmf;
+	u32 qepdf;
+	u32 ddr_sec_clk;
+	u32 qe_clk;
+	u32 brg_clk;
+#endif
 
 	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
 		return -1;
 
-#ifndef CFG_HRCW_HIGH
-# error "CFG_HRCW_HIGH must be defined in board config file"
-#endif /* CFG_HCWD_HIGH */
-
-#if (CFG_HRCW_HIGH & HRCWH_PCI_HOST)
-
-# ifndef CONFIG_83XX_CLKIN
-#  error "In PCI Host Mode, CONFIG_83XX_CLKIN must be defined in board config file"
-# endif /* CONFIG_83XX_CLKIN */
-# ifdef CONFIG_83XX_PCICLK
-#  warning "In PCI Host Mode, CONFIG_83XX_PCICLK in board config file is igonred"
-# endif /* CONFIG_83XX_PCICLK */
-
-	/* PCI Host Mode */
-	if (!(im->reset.rcwh & RCWH_PCIHOST)) {
-		/* though RCWH_PCIHOST is defined in CFG_HRCW_HIGH
-		 * the im->reset.rcwhr PCI Host Mode is disabled
-		 * FIXME: findout if there is a way to issue some warning */
-		return -2;
-	}
-	if (im->clk.spmr & SPMR_CKID) {
-		/* PCI Clock is half CONFIG_83XX_CLKIN */
-		pci_sync_in = CONFIG_83XX_CLKIN / 2;
-	}
-	else {
-		pci_sync_in = CONFIG_83XX_CLKIN;
-	}
-
-#else /* (CFG_HRCW_HIGH & HRCWH_PCI_HOST) */
-
-# ifdef CONFIG_83XX_CLKIN
-#  warning "In PCI Agent Mode, CONFIG_83XX_CLKIN in board config file is igonred"
-# endif /* CONFIG_83XX_CLKIN */
-# ifndef CONFIG_83XX_PCICLK
-#  error "In PCI Agent Mode, CONFIG_83XX_PCICLK must be defined in board config file"
-# endif /* CONFIG_83XX_PCICLK */
-
-	/* PCI Agent Mode */
-	if (im->reset.rcwh & RCWH_PCIHOST) {
-		/* though RCWH_PCIHOST is not defined in CFG_HRCW_HIGH
-		 * the im->reset.rcwhr PCI Host Mode is enabled */
-		return -3;
-	}
-	pci_sync_in = CONFIG_83XX_PCICLK;
-
-#endif /* (CFG_HRCW_HIGH | RCWH_PCIHOST) */
-
-	/* we have up to date pci_sync_in */
-	spmf = ((im->reset.rcwl & RCWL_SPMF) >> RCWL_SPMF_SHIFT);
 	clkin_div = ((im->clk.spmr & SPMR_CKID) >> SPMR_CKID_SHIFT);
 
-	if ((im->reset.rcwl & RCWL_LBIUCM) || (im->reset.rcwl & RCWL_DDRCM)) {
-		csb_clk	= (pci_sync_in * spmf * (1 + clkin_div)) / 2;
-	}
-	else {
-		csb_clk = pci_sync_in * spmf * (1 + clkin_div);
+	if (im->reset.rcwh & HRCWH_PCI_HOST) {
+#if defined(CONFIG_83XX_CLKIN)
+		pci_sync_in = CONFIG_83XX_CLKIN / (1 + clkin_div);
+#else
+		pci_sync_in = 0xDEADBEEF;
+#endif
+	} else {
+#if defined(CONFIG_83XX_PCICLK)
+		pci_sync_in = CONFIG_83XX_PCICLK;
+#else
+		pci_sync_in = 0xDEADBEEF;
+#endif
 	}
 
+	spmf = ((im->reset.rcwl & RCWL_SPMF) >> RCWL_SPMF_SHIFT);
+	csb_clk = pci_sync_in * (1 + clkin_div) * spmf;
+
 	sccr = im->clk.sccr;
+
+#if defined(CONFIG_MPC8349)
 	switch ((sccr & SCCR_TSEC1CM) >> SCCR_TSEC1CM_SHIFT) {
 	case 0:
 		tsec1_clk = 0;
@@ -212,25 +185,8 @@
 		/* unkown SCCR_TSEC2CM value */
 		return -5;
 	}
-	i2c_clk = tsec2_clk;
 
-	switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
-	case 0:
-		enc_clk = 0;
-		break;
-	case 1:
-		enc_clk = csb_clk;
-		break;
-	case 2:
-		enc_clk = csb_clk / 2;
-		break;
-	case 3:
-		enc_clk = csb_clk / 3;
-		break;
-	default:
-		/* unkown SCCR_ENCCM value */
-		return -6;
-	}
+	i2c1_clk = tsec2_clk;
 
 	switch ((sccr & SCCR_USBMPHCM) >> SCCR_USBMPHCM_SHIFT) {
 	case 0:
@@ -274,8 +230,34 @@
 		/* if USB MPH clock is not disabled and USB DR clock is not disabled than USB MPH & USB DR must have the same rate */
 		return -9;
 	}
+#endif
+#if defined (CONFIG_MPC8360)
+	i2c1_clk = csb_clk;
+#endif
+	i2c2_clk = csb_clk; /* i2c-2 clk is equal to csb clk */
 
+	switch ((sccr & SCCR_ENCCM) >> SCCR_ENCCM_SHIFT) {
+	case 0:
+		enc_clk = 0;
+		break;
+	case 1:
+		enc_clk = csb_clk;
+		break;
+	case 2:
+		enc_clk = csb_clk / 2;
+		break;
+	case 3:
+		enc_clk = csb_clk / 3;
+		break;
+	default:
+		/* unkown SCCR_ENCCM value */
+		return -6;
+	}
+#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360)
 	lbiu_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT));
+#else
+#error Unknown MPC83xx chip
+#endif
 	lcrr = (im->lbus.lcrr & LCRR_CLKDIV) >> LCRR_CLKDIV_SHIFT;
 	switch (lcrr) {
 	case 2:
@@ -287,10 +269,16 @@
 		/* unknown lcrr */
 		return -10;
 	}
-
+#if defined(CONFIG_MPC8349) || defined(CONFIG_MPC8360)
 	ddr_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_DDRCM) >> RCWL_DDRCM_SHIFT));
-
 	corepll = (im->reset.rcwl & RCWL_COREPLL) >> RCWL_COREPLL_SHIFT;
+#if defined (CONFIG_MPC8360)
+	ddr_sec_clk = csb_clk * (1 + ((im->reset.rcwl & RCWL_LBIUCM) >> RCWL_LBIUCM_SHIFT));
+#endif
+#else
+#error Unknown MPC83xx chip
+#endif
+
 	corecnf_tab_index = ((corepll & 0x1F) << 2) | ((corepll & 0x60) >> 5);
 	if (corecnf_tab_index > (sizeof(corecnf_tab)/sizeof(corecnf_t)) ) {
 		/* corecnf_tab_index is too high, possibly worng value */
@@ -319,22 +307,36 @@
 		return -12;
 	}
 
-	gd->csb_clk    = csb_clk   ;
-	gd->tsec1_clk  = tsec1_clk ;
-	gd->tsec2_clk  = tsec2_clk ;
-	gd->core_clk   = core_clk  ;
-	gd->usbmph_clk = usbmph_clk;
-	gd->usbdr_clk  = usbdr_clk ;
-	gd->i2c_clk    = i2c_clk   ;
-	gd->enc_clk    = enc_clk   ;
-	gd->lbiu_clk   = lbiu_clk  ;
-	gd->lclk_clk   = lclk_clk  ;
-	gd->ddr_clk    = ddr_clk   ;
-	gd->pci_clk    = pci_sync_in;
+#if defined (CONFIG_MPC8360)
+	qepmf = (im->reset.rcwl & RCWL_CEPMF) >> RCWL_CEPMF_SHIFT;
+	qepdf = (im->reset.rcwl & RCWL_CEPDF) >> RCWL_CEPDF_SHIFT;
+	qe_clk = (pci_sync_in * qepmf)/(1+qepdf);
+	brg_clk = qe_clk / 2;
+#endif
 
-	gd->cpu_clk = gd->core_clk;
-	gd->bus_clk = gd->lbiu_clk;
+	gd->csb_clk     = csb_clk;
+#if defined(CONFIG_MPC8349)
+	gd->tsec1_clk   = tsec1_clk;
+	gd->tsec2_clk   = tsec2_clk;
+	gd->usbmph_clk  = usbmph_clk;
+	gd->usbdr_clk   = usbdr_clk;
+#endif
+	gd->core_clk    = core_clk;
+	gd->i2c1_clk    = i2c1_clk;
+	gd->i2c2_clk    = i2c2_clk;
+	gd->enc_clk     = enc_clk;
+	gd->lbiu_clk    = lbiu_clk;
+	gd->lclk_clk    = lclk_clk;
+	gd->ddr_clk     = ddr_clk;
+#if defined (CONFIG_MPC8360)
+	gd->ddr_sec_clk = ddr_sec_clk;
+	gd->qe_clk      = qe_clk;
+	gd->brg_clk     = brg_clk;
+#endif
+	gd->cpu_clk     = gd->core_clk;
+	gd->bus_clk     = gd->csb_clk;
 	return 0;
+
 }
 
 ulong get_ddr_clk(ulong dummy)
@@ -357,14 +359,23 @@
 	printf("Clock configuration:\n");
 	printf("  Coherent System Bus: %4d MHz\n",gd->csb_clk/1000000);
 	printf("  Core:                %4d MHz\n",gd->core_clk/1000000);
-	debug("  Local Bus Controller:%4d MHz\n",gd->lbiu_clk/1000000);
+#if defined (CONFIG_MPC8360)
+	printf("  QE:                  %4d MHz\n",gd->qe_clk/1000000);
+#endif
+	printf("  Local Bus Controller:%4d MHz\n",gd->lbiu_clk/1000000);
 	printf("  Local Bus:           %4d MHz\n",gd->lclk_clk/1000000);
-	debug("  DDR:                 %4d MHz\n",gd->ddr_clk/1000000);
-	debug("  I2C:                 %4d MHz\n",gd->i2c_clk/1000000);
-	debug("  TSEC1:               %4d MHz\n",gd->tsec1_clk/1000000);
-	debug("  TSEC2:               %4d MHz\n",gd->tsec2_clk/1000000);
-	debug("  USB MPH:             %4d MHz\n",gd->usbmph_clk/1000000);
-	debug("  USB DR:              %4d MHz\n",gd->usbdr_clk/1000000);
-
+	printf("  DDR:                 %4d MHz\n",gd->ddr_clk/1000000);
+#if defined (CONFIG_MPC8360)
+	printf("  DDR Secondary:       %4d MHz\n",gd->ddr_sec_clk/1000000);
+#endif
+	printf("  SEC:                 %4d MHz\n",gd->enc_clk/1000000);
+	printf("  I2C1:                %4d MHz\n",gd->i2c1_clk/1000000);
+	printf("  I2C2:                %4d MHz\n",gd->i2c2_clk/1000000);
+#if defined(CONFIG_MPC8349)
+	printf("  TSEC1:               %4d MHz\n",gd->tsec1_clk/1000000);
+	printf("  TSEC2:               %4d MHz\n",gd->tsec2_clk/1000000);
+	printf("  USB MPH:             %4d MHz\n",gd->usbmph_clk/1000000);
+	printf("  USB DR:              %4d MHz\n",gd->usbdr_clk/1000000);
+#endif
 	return 0;
 }