Fix memory detection and hcd compilation, thanks Gabor ! (closes #1813)

SVN-Revision: 7631
This commit is contained in:
Florian Fainelli 2007-06-14 11:59:31 +00:00
parent 816e40a9fe
commit 8ed6f00352
5 changed files with 153 additions and 55 deletions

View 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();

View file

@ -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 */

View 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);

View 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)

View file

@ -85,6 +85,19 @@
#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