Fix memory detection and hcd compilation, thanks Gabor ! (closes #1813)
authorFlorian Fainelli <florian@openwrt.org>
Thu, 14 Jun 2007 11:59:31 +0000 (11:59 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Thu, 14 Jun 2007 11:59:31 +0000 (11:59 +0000)
SVN-Revision: 7631

target/linux/adm5120-2.6/files/arch/mips/adm5120/adm5120_info.c
target/linux/adm5120-2.6/files/arch/mips/adm5120/memory.c
target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c
target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h
target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h

index fde86c8..ab96b0f 100644 (file)
@@ -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();
index 947b5b9..190a078 100644 (file)
 #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 */
index a9d0071..87bfcc6 100644 (file)
@@ -833,6 +833,7 @@ static int __init adm5120hcd_init(void)
        if (!adm5120_board.has_usb) {
                printk(KERN_DEBUG PFX "this board does not have USB\n");
                return -ENODEV;
+       }
 
        printk(KERN_INFO PFX "registered\n");
        return platform_driver_register(&adm5120hcd_driver);
index c78c46b..b4730dc 100644 (file)
@@ -50,6 +50,8 @@ extern unsigned int adm5120_package;
 #define ADM5120_PACKAGE_PQFP   0
 #define ADM5120_PACKAGE_BGA    1
 
+extern unsigned long adm5120_memsize;
+
 extern void adm5120_info_init(void);
 
 static inline int adm5120_package_pqfp(void)
index a0fc1e4..f766458 100644 (file)
 #define CODE_PK_BGA            0               /* BGA package */
 #define CODE_PK_PQFP           1               /* PQFP package */
 
+/* MEMCTRL register bits */
+#define MEMCTRL_SDRS_MASK      BITMASK(3)      /* SDRAM bank size */
+#define MEMCTRL_SDRS_4M                0x01
+#define MEMCTRL_SDRS_8M                0x02
+#define MEMCTRL_SDRS_16M       0x03
+#define MEMCTRL_SDRS_64M       0x04
+#define MEMCTRL_SDRS_128M      0x05
+#define MEMCTRL_SDR1_ENABLE    ONEBIT(5)       /* enable SDRAM bank 1 */
+#define MEMCTRL_SR0S_MASK      BITMASK(3)      /* SRAM0 size */
+#define MEMCTRL_SR0S_SHIFT     8               
+#define MEMCTRL_SR1S_MASK      BITMAKS(3)      /* SRAM1 size */
+#define MEMCTRL_SR1S_SHIFT     16
+
 /* GPIO_CONF0 register bits */
 #define GPIO_CONF0_MASK                BITMASK(8)
 #define GPIO_CONF0_IM_SHIFT    0