summaryrefslogtreecommitdiff
path: root/target/linux/adm5120-2.6/files/arch/mips
diff options
context:
space:
mode:
authorflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2007-06-14 11:59:31 +0000
committerflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2007-06-14 11:59:31 +0000
commit5da973430ee902e017d204f59dbf1a983dc1a3e8 (patch)
treee25963dcf01a84d5e6ec73f7cc32b073ff477f79 /target/linux/adm5120-2.6/files/arch/mips
parenteb12a445c6e6708f497b18efd8590e3ecd6f4bec (diff)
Fix memory detection and hcd compilation, thanks Gabor ! (closes #1813)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7631 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/adm5120-2.6/files/arch/mips')
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c131
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c61
2 files changed, 137 insertions, 55 deletions
diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
index fde86c8f86..ab96b0f6c9 100644
--- a/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
+++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
@@ -37,6 +37,7 @@ unsigned int adm5120_revision;
unsigned int adm5120_package;
unsigned int adm5120_nand_boot;
unsigned long adm5120_speed;
+unsigned long adm5120_memsize;
/*
* Locals
@@ -266,7 +267,7 @@ static struct adm5120_board __initdata adm5120_boards[] = {
.mach_type = MACH_ADM5120_UNKNOWN,
.has_usb = 1,
.iface_num = 5,
- .flash0_size = 0,
+ .flash0_size = 4*1024*1024,
}
};
@@ -728,6 +729,9 @@ static void __init adm5120_detect_board(void)
memcpy(&adm5120_board, board, sizeof(adm5120_board));
}
+#define SWITCH_READ(r) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))
+#define SWITCH_WRITE(r,v) *(u32 *)(KSEG1ADDR(ADM5120_SWITCH_BASE)+(r))=(v)
+
/*
* CPU settings detection
*/
@@ -742,7 +746,7 @@ static void __init adm5120_detect_cpuinfo(void)
u32 code;
u32 clks;
- code = *(u32 *)KSEG1ADDR(ADM5120_SWITCH_BASE+SWITCH_REG_CODE);
+ code = SWITCH_READ(SWITCH_REG_CODE);
adm5120_product_code = CODE_GET_PC(code);
adm5120_revision = CODE_GET_REV(code);
@@ -758,6 +762,127 @@ static void __init adm5120_detect_cpuinfo(void)
adm5120_speed += 50000000;
}
+#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);
+}
+
void __init adm5120_info_show(void)
{
/* FIXME: move this somewhere else */
@@ -769,11 +894,13 @@ void __init adm5120_info_show(void)
printk("Boot loader is: %s\n", boot_loader_names[adm5120_boot_loader]);
printk("Booted from : %s flash\n", adm5120_nand_boot ? "NAND":"NOR");
printk("Board is : %s\n", adm5120_board_name());
+ printk("Memory size : %ldMB\n", adm5120_memsize >> 20);
}
void __init adm5120_info_init(void)
{
adm5120_detect_cpuinfo();
+ adm5120_detect_memsize();
adm5120_detect_board();
adm5120_info_show();
diff --git a/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c b/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c
index 947b5b96a8..190a0788fc 100644
--- a/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c
+++ b/target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c
@@ -35,49 +35,19 @@
#include <asm/page.h>
#include <asm/sections.h>
+#include <asm/mach-adm5120/adm5120_info.h>
#include <asm-mips/mips-boards/prom.h>
-extern char *prom_getenv(char *envname);
-void prom_printf(char *, ...);
-
#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
-#define ADM5120_MEMCTRL 0x1200001c
-#define ADM5120_MEMCTRL_SDRAM_MASK 0x7
-
-static const unsigned long adm_sdramsize[] __initdata = {
- 0x0, /* Reserved */
- 0x0400000, /* 4Mb */
- 0x0800000, /* 8Mb */
- 0x1000000, /* 16Mb */
- 0x4000000, /* 64Mb */
- 0x8000000, /* 128Mb */
-};
-
-/* determined physical memory size, not overridden by command line args */
-unsigned long physical_memsize = 0L;
-
struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
struct prom_pmemblock * __init prom_getmdesc(void)
{
- char *memsize_str;
unsigned int memsize;
char cmdline[CL_SIZE], *ptr;
- memsize_str = prom_getenv("memsize");
-
- if (!memsize_str)
- {
- prom_printf("memsize not set in boot prom, set to default (8Mb)\n");
- physical_memsize = 0x00800000;
- }
- else
-#ifdef DEBUG
- prom_printf("prom_memsize = %s\n", memsize_str);
-#endif
- physical_memsize = simple_strtol(memsize_str, NULL, 0);
-
+ memsize = adm5120_memsize;
/* Check the command line for a memsize directive that overrides
* the physical/default amount */
strcpy(cmdline, arcs_cmdline);
@@ -87,16 +57,13 @@ struct prom_pmemblock * __init prom_getmdesc(void)
if (ptr)
memsize = memparse(ptr + 8, &ptr);
- else
- memsize = physical_memsize;
+
+ memset(mdesc, 0, sizeof(mdesc));
+ mdesc[0].type = BOOT_MEM_RAM;
+ mdesc[0].base = CPHYSADDR(PFN_ALIGN(&_end));
+ mdesc[0].size = memsize - mdesc[0].base;
- memset(mdesc, 0, sizeof(mdesc));
-
- mdesc[0].type = BOOT_MEM_RAM;
- mdesc[0].base = CPHYSADDR(PFN_ALIGN(&_end));
- mdesc[0].size = memsize - mdesc[0].base;
-
- return &mdesc[0];
+ return &mdesc[0];
}
void __init prom_meminit(void)
@@ -117,18 +84,6 @@ void __init prom_meminit(void)
}
}
-#if 0
-void __init prom_meminit(void)
-{
- unsigned long base = CPHYSADDR(PFN_ALIGN(&_end));
- unsigned long size;
-
- u32 memctrl = *(u32*)KSEG1ADDR(ADM5120_MEMCTRL);
- size = adm_sdramsize[memctrl & ADM5120_MEMCTRL_SDRAM_MASK];
- add_memory_region(base, size-base, BOOT_MEM_RAM);
-}
-#endif
-
void __init prom_free_prom_memory(void)
{
/* We do not have to prom memory to free */