+#if 1
+# define mem_dbg(f, ...) prom_printf("mem_detect: " f, ## __VA_ARGS__)
+extern void prom_printf(char *, ...);
+#else
+# define mem_dbg(f, ...)
+#endif
+
+static void __init adm5120_detect_memsize(void)
+{
+ u32 memctrl;
+ u32 size, maxsize;
+ volatile u8 *p,*r;
+ u8 t;
+
+ memctrl = SWITCH_READ(SWITCH_REG_MEMCTRL);
+ switch (memctrl & MEMCTRL_SDRS_MASK) {
+ case MEMCTRL_SDRS_4M:
+ maxsize = 4 << 20;
+ break;
+ case MEMCTRL_SDRS_8M:
+ maxsize = 8 << 20;
+ break;
+ case MEMCTRL_SDRS_16M:
+ maxsize = 16 << 20;
+ break;
+ default:
+ maxsize = 64 << 20;
+ break;
+ }
+
+ /* FIXME: need to disable buffers for both SDRAM bank? */
+
+ mem_dbg("checking for %ldMB chip\n",maxsize >> 20);
+
+ /* detect size of the 1st SDRAM bank */
+ p = (volatile u8 *)KSEG1ADDR(0);
+ t = *p;
+ for (size = 2<<20; size <= (maxsize >> 1); size <<= 1) {
+#if 1
+ r = (p+size);
+ *p = 0x55;
+ mem_dbg("1st pattern at 0x%lx is 0x%02x\n", size, *r);
+ if (*r == 0x55) {
+ *p = 0xAA;
+ mem_dbg("2nd pattern at 0x%lx is 0x%02x\n", size, *r);
+ if (*r == 0xAA) {
+ /* mirrored address */
+ mem_dbg("mirrored data found at 0x%lx\n", size);
+ break;
+ }
+ }
+#else
+ p[0] = 0x55;
+ mem_dbg("1st pattern at 0x%lx is 0x%02x\n", size, p[size]);
+ if (p[size] != 0x55)
+ continue;
+
+ p[0] = 0xAA;
+ mem_dbg("2nd pattern at 0x%lx is 0x%02x\n", size, p[size]);
+ if (p[size] != 0xAA)
+ continue;
+
+ /* mirrored address */
+ mem_dbg("mirrored data found at 0x%lx\n", size);
+ break;
+#endif
+ }
+ *p = t;
+
+ mem_dbg("%ldMB chip found\n", size >> 20);
+
+ if (size == (32 << 20))
+ /* if bank size is 32MB, 2nd bank is not supported */
+ goto out;
+
+ if ((memctrl & MEMCTRL_SDR1_ENABLE) == 0)
+ /* if 2nd bank is not enabled, we are done */
+ goto out;
+
+ /*
+ * some bootloaders enable 2nd bank, even if the 2nd SDRAM chip
+ * are missing.
+ */
+ mem_dbg("checking second bank\n");
+ p += (maxsize+size)-1;
+ t = *p;
+ *p = 0x55;
+ if (*p != 0x55)
+ goto out;
+
+ *p = 0xAA;
+ if (*p != 0xAA)
+ goto out;
+
+ *p = t;
+ if (maxsize != size) {
+ /* adjusting MECTRL register */
+ memctrl &= ~(MEMCTRL_SDRS_MASK);
+ switch (size>>20) {
+ case 4:
+ memctrl |= MEMCTRL_SDRS_4M;
+ break;
+ case 8:
+ memctrl |= MEMCTRL_SDRS_8M;
+ break;
+ case 16:
+ memctrl |= MEMCTRL_SDRS_16M;
+ break;
+ default:
+ memctrl |= MEMCTRL_SDRS_64M;
+ break;
+ }
+ SWITCH_WRITE(SWITCH_REG_MEMCTRL, memctrl);
+ }
+ size <<= 1;
+
+out:
+ adm5120_memsize = size;
+ mem_dbg("%ldMB memory found\n",size>>20);
+}
+