Patch by Josef Wagner, 04 Jun 2004:
- DDR Ram support for PM520 (MPC5200)
- support for different flash types (PM520)
- USB / IDE / CF-Card / DiskOnChip support for PM520
- 8 bit boot rom support for PM520/CE520
- Add auto SDRAM module detection for MicroSys CPC45 board (MPC8245)
- I2C and RTC support for CPC45
- support of new flash type (28F160C3T) for CPC45
diff --git a/board/cpc45/cpc45.c b/board/cpc45/cpc45.c
index ad69245..92ccd42 100644
--- a/board/cpc45/cpc45.c
+++ b/board/cpc45/cpc45.c
@@ -25,6 +25,7 @@
 #include <mpc824x.h>
 #include <asm/processor.h>
 #include <pci.h>
+#include <i2c.h>
 
 int sysControlDisplay(int digit, uchar ascii_code);
 extern void Plx9030Init(void);
@@ -58,46 +59,134 @@
 	return 0;
 }
 
-long int initdram(int board_type)
+long int initdram (int board_type)
 {
-	long size;
-	long new_bank0_end;
-	long mear1;
-	long emear1;
+	int m, row, col, bank, i, ref;
+	unsigned long start, end;
+	uint32_t mccr1, mccr2;
+	uint32_t mear1 = 0, emear1 = 0, msar1 = 0, emsar1 = 0;
+	uint32_t mear2 = 0, emear2 = 0, msar2 = 0, emsar2 = 0;
+	uint8_t mber = 0;
+	unsigned int tmp;
 
-	size = get_ram_size(CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE);
+	i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
 
-	new_bank0_end = size - 1;
-	mear1 = mpc824x_mpc107_getreg(MEAR1);
-	emear1 = mpc824x_mpc107_getreg(EMEAR1);
-	mear1 = (mear1  & 0xFFFFFF00) |
-		((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT);
-	emear1 = (emear1 & 0xFFFFFF00) |
-		((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT);
-	mpc824x_mpc107_setreg(MEAR1, mear1);
-	mpc824x_mpc107_setreg(EMEAR1, emear1);
+	if (i2c_reg_read (0x50, 2) != 0x04)
+		return 0;	/* Memory type */
 
-	return (size);
+	m = i2c_reg_read (0x50, 5);	/* # of physical banks */
+	row = i2c_reg_read (0x50, 3);	/* # of rows */
+	col = i2c_reg_read (0x50, 4);	/* # of columns */
+	bank = i2c_reg_read (0x50, 17);	/* # of logical banks */
+	ref  = i2c_reg_read (0x50, 12);	/* refresh rate / type */
+
+	CONFIG_READ_WORD(MCCR1, mccr1);
+	mccr1 &= 0xffff0000;
+
+	CONFIG_READ_WORD(MCCR2, mccr2);
+	mccr2 &= 0xffff0000;
+
+	start = CFG_SDRAM_BASE;
+	end = start + (1 << (col + row + 3) ) * bank - 1;
+
+	for (i = 0; i < m; i++) {
+		mccr1 |= ((row == 13)? 2 : (bank == 4)? 0 : 3) << i * 2;
+		if (i < 4) {
+			msar1  |= ((start >> 20) & 0xff) << i * 8;
+			emsar1 |= ((start >> 28) & 0xff) << i * 8;
+			mear1  |= ((end >> 20) & 0xff) << i * 8;
+			emear1 |= ((end >> 28) & 0xff) << i * 8;
+		} else {
+			msar2  |= ((start >> 20) & 0xff) << (i-4) * 8;
+			emsar2 |= ((start >> 28) & 0xff) << (i-4) * 8;
+			mear2  |= ((end >> 20) & 0xff) << (i-4) * 8;
+			emear2 |= ((end >> 28) & 0xff) << (i-4) * 8;
+		}
+		mber |= 1 << i;
+		start += (1 << (col + row + 3) ) * bank;
+		end += (1 << (col + row + 3) ) * bank;
+	}
+	for (; i < 8; i++) {
+		if (i < 4) {
+			msar1  |= 0xff << i * 8;
+			emsar1 |= 0x30 << i * 8;
+			mear1  |= 0xff << i * 8;
+			emear1 |= 0x30 << i * 8;
+		} else {
+			msar2  |= 0xff << (i-4) * 8;
+			emsar2 |= 0x30 << (i-4) * 8;
+			mear2  |= 0xff << (i-4) * 8;
+			emear2 |= 0x30 << (i-4) * 8;
+		}
+	}
+
+	switch(ref) {
+		case 0x00:
+		case 0x80:
+			tmp = get_bus_freq(0) / 1000000 * 15625 / 1000 - 22;
+			break;
+		case 0x01:
+		case 0x81:
+			tmp = get_bus_freq(0) / 1000000 * 3900 / 1000 - 22;
+			break;
+		case 0x02:
+		case 0x82:
+			tmp = get_bus_freq(0) / 1000000 * 7800 / 1000 - 22;
+			break;
+		case 0x03:
+		case 0x83:
+			tmp = get_bus_freq(0) / 1000000 * 31300 / 1000 - 22;
+			break;
+		case 0x04:
+		case 0x84:
+			tmp = get_bus_freq(0) / 1000000 * 62500 / 1000 - 22;
+			break;
+		case 0x05:
+		case 0x85:
+			tmp = get_bus_freq(0) / 1000000 * 125000 / 1000 - 22;
+			break;
+		default:
+			tmp = 0x512;
+			break;
+	}
+
+	CONFIG_WRITE_WORD(MCCR1, mccr1);
+	CONFIG_WRITE_WORD(MCCR2, tmp << MCCR2_REFINT_SHIFT);
+	CONFIG_WRITE_WORD(MSAR1, msar1);
+	CONFIG_WRITE_WORD(EMSAR1, emsar1);
+	CONFIG_WRITE_WORD(MEAR1, mear1);
+	CONFIG_WRITE_WORD(EMEAR1, emear1);
+	CONFIG_WRITE_WORD(MSAR2, msar2);
+	CONFIG_WRITE_WORD(EMSAR2, emsar2);
+	CONFIG_WRITE_WORD(MEAR2, mear2);
+	CONFIG_WRITE_WORD(EMEAR2, emear2);
+	CONFIG_WRITE_BYTE(MBER, mber);
+
+	return (1 << (col + row + 3) ) * bank * m;
 }
 
+
 /*
  * Initialize PCI Devices, report devices found.
  */
-#ifndef CONFIG_PCI_PNP
 
-static struct pci_config_table pci_sandpoint_config_table[] = {
-	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID,
+static struct pci_config_table pci_cpc45_config_table[] = {
+#ifndef CONFIG_PCI_PNP
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0F, PCI_ANY_ID,
 	  pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
 				       PCI_ENET0_MEMADDR,
 				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0D, PCI_ANY_ID,
+	  pci_cfgfunc_config_device, { PCI_PLX9030_IOADDR,
+				       PCI_PLX9030_MEMADDR,
+				       PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+#endif /*CONFIG_PCI_PNP*/
 	{ }
 };
-#endif
-
 
 struct pci_controller hose = {
 #ifndef CONFIG_PCI_PNP
-	config_table: pci_sandpoint_config_table,
+	config_table: pci_cpc45_config_table,
 #endif
 };
 
@@ -108,6 +197,9 @@
 	/* init PCI_to_LOCAL Bus BRIDGE */
 	Plx9030Init();
 
+	/* Clear Display */
+	DISP_CWORD = 0x0;
+
 	sysControlDisplay(0,' ');
 	sysControlDisplay(1,'C');
 	sysControlDisplay(2,'P');
@@ -130,16 +222,14 @@
 * RETURNS: NA
 */
 
-int sysControlDisplay
-    (
-    int digit, 			/* number of digit 0..7 */
-    uchar ascii_code		/* ASCII code */
-    )
+int sysControlDisplay (int digit,	/* number of digit 0..7 */
+		       uchar ascii_code	/* ASCII code */
+		      )
 {
 	if ((digit < 0) || (digit > 7))
 		return (-1);
 
-	*((volatile uchar*)(DISP_CHR_RAM + digit)) = ascii_code;
+	*((volatile uchar *) (DISP_CHR_RAM + digit)) = ascii_code;
 
 	return (0);
 }