diff options
| author | florian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-06-14 11:59:31 +0000 | 
|---|---|---|
| committer | florian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-06-14 11:59:31 +0000 | 
| commit | 5da973430ee902e017d204f59dbf1a983dc1a3e8 (patch) | |
| tree | e25963dcf01a84d5e6ec73f7cc32b073ff477f79 | |
| parent | eb12a445c6e6708f497b18efd8590e3ecd6f4bec (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
5 files changed, 153 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 fde86c8f8..ab96b0f6c 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 947b5b96a..190a0788f 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 */ diff --git a/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c index a9d0071df..87bfcc6c7 100644 --- a/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c +++ b/target/linux/adm5120-2.6/files/drivers/usb/host/adm5120-hcd.c @@ -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); diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h index c78c46b3b..b4730dc0f 100644 --- a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_info.h @@ -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) diff --git a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h index a0fc1e44e..f7664587d 100644 --- a/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h +++ b/target/linux/adm5120-2.6/files/include/asm-mips/mach-adm5120/adm5120_switch.h @@ -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 | 
