#include <asm/bootinfo.h>
#include <asm/addrspace.h>
+#include <asm/byteorder.h>
#include <asm/mach-adm5120/adm5120_defs.h>
#include <asm/mach-adm5120/adm5120_switch.h>
#include <asm/mach-adm5120/routerboot.h>
#include <asm/mach-adm5120/zynos.h>
+extern char *prom_getenv(char *envname);
/*
* Globals
*/
unsigned int adm5120_package;
unsigned int adm5120_nand_boot;
unsigned long adm5120_speed;
+unsigned long adm5120_memsize;
/*
* Locals
};
static struct adm5120_board __initdata adm5120_boards[] = {
+ /* FIXME: some boards have invalid fields */
+ {
+ .name = "Cellvision CAS-630/630W",
+ .mach_type = MACH_ADM5120_CAS630,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision CAS-670/670W",
+ .mach_type = MACH_ADM5120_CAS670,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision CAS-700/700W",
+ .mach_type = MACH_ADM5120_CAS700,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision CAS-771/771W",
+ .mach_type = MACH_ADM5120_CAS771,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision CAS-790",
+ .mach_type = MACH_ADM5120_CAS790,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision CAS-861/861W",
+ .mach_type = MACH_ADM5120_CAS861,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision NFS-101U/101WU",
+ .mach_type = MACH_ADM5120_NFS101U,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "Cellvision NFS-202U/202WU",
+ .mach_type = MACH_ADM5120_NFS202U,
+ .has_usb = 0,
+ .iface_num = 1,
+ .flash0_size = 4*1024*1024,
+ },
{
.name = "Compex NetPassage 27G",
.mach_type = MACH_ADM5120_NP27G,
.flash0_size = 4*1024*1024,
},
{
- .name = "RouterBOARD RB-111",
+ .name = "Edimax BR-6104K",
+ .mach_type = MACH_ADM5120_BR6104K,
+ .has_usb = 0,
+ .iface_num = 5,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "Infineon EASY 5120",
+ .mach_type = MACH_ADM5120_EASY5120,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "Infineon EASY 5120-RT",
+ .mach_type = MACH_ADM5120_EASY5120RT,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "Infineon EASY 5120P-ATA",
+ .mach_type = MACH_ADM5120_EASY5120PATA,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 2*1024*1024,
+ },
+ {
+ .name = "Infineon EASY 83000",
+ .mach_type = MACH_ADM5120_EASY83000,
+ .has_usb = 0,
+ .iface_num = 6,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "RouterBOARD 111",
.mach_type = MACH_ADM5120_RB_111,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
- .name = "RouterBOARD RB-112",
+ .name = "RouterBOARD 112",
.mach_type = MACH_ADM5120_RB_112,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
- .name = "RouterBOARD RB-133",
+ .name = "RouterBOARD 133",
.mach_type = MACH_ADM5120_RB_133,
.has_usb = 0,
.iface_num = 3,
.flash0_size = 128*1024,
},
{
- .name = "RouterBOARD RB-133C",
+ .name = "RouterBOARD 133C",
.mach_type = MACH_ADM5120_RB_133C,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
- .name = "RouterBOARD RB-150",
+ .name = "RouterBOARD 150",
.mach_type = MACH_ADM5120_RB_150,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 128*1024,
},
{
- .name = "RouterBOARD RB-153",
+ .name = "RouterBOARD 153",
.mach_type = MACH_ADM5120_RB_153,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 128*1024,
},
+ {
+ .name = "ZyXEL ES-2024A",
+ .mach_type = MACH_ADM5120_ES2024A,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2024PWR",
+ .mach_type = MACH_ADM5120_ES2024PWR,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2108",
+ .mach_type = MACH_ADM5120_ES2108,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2108-F",
+ .mach_type = MACH_ADM5120_ES2108F,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2108-G",
+ .mach_type = MACH_ADM5120_ES2108G,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2108-LC",
+ .mach_type = MACH_ADM5120_ES2108LC,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
+ {
+ .name = "ZyXEL ES-2108-PWR",
+ .mach_type = MACH_ADM5120_ES2108PWR,
+ .has_usb = 0,
+ .iface_num = 0,
+ .flash0_size = 4*1024*1024,
+ },
{
.name = "ZyXEL HomeSafe 100/100W",
.mach_type = MACH_ADM5120_HS100,
.mach_type = MACH_ADM5120_UNKNOWN,
.has_usb = 1,
.iface_num = 5,
- .flash0_size = 0,
+ .flash0_size = 4*1024*1024,
}
};
+#define DUMMY_BOARD() {.mach_type = MACH_ADM5120_UNKNOWN}
+
struct mylo_board {
u16 vid;
u16 did;
unsigned long mach_type;
};
-#define DUMMY_BOARD() {.mach_type = MACH_ADM5120_UNKNOWN}
#define MYLO_BOARD(v,d,sv,sd,mt) { .vid = (v), .did = (d), .svid = (sv), \
.sdid = (sd), .mach_type = (mt) }
#define COMPEX_BOARD(d,mt) MYLO_BOARD(VENID_COMPEX,(d),VENID_COMPEX,(d),(mt))
-static struct mylo_board __initdata mylo_boards[] = {
+static struct mylo_board mylo_boards[] __initdata = {
COMPEX_BOARD(DEVID_COMPEX_NP27G, MACH_ADM5120_NP27G),
COMPEX_BOARD(DEVID_COMPEX_NP28G, MACH_ADM5120_NP28G),
COMPEX_BOARD(DEVID_COMPEX_NP28GHS, MACH_ADM5120_NP28GHS),
};
#define ROUTERBOARD(n, mt) { .name = (n), .mach_type = (mt) }
-static struct routerboard __initdata routerboards[] = {
+static struct routerboard routerboards[] __initdata = {
ROUTERBOARD("111", MACH_ADM5120_RB_111),
ROUTERBOARD("112", MACH_ADM5120_RB_112),
ROUTERBOARD("133", MACH_ADM5120_RB_133),
u16 board_id;
};
-#define ZYNOS_VENDOR_ID_INVALID 0
-#define ZYNOS_VENDOR_ID_ZYXEL 1
-#define ZYNOS_VENDOR_ID_DLINK 2
-#define ZYNOS_VENDOR_ID_LUCENT 3
-
#define ZYNOS_BOARD(vi, bi, mt) { .vendor_id = (vi), .board_id = (bi), \
.mach_type = (mt) }
#define DLINK_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_DLINK, bi, mt)
#define LUCENT_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_LUCENT, bi, mt)
-static struct zynos_board __initdata zynos_boards[] = {
+static struct zynos_board zynos_boards[] __initdata = {
ZYXEL_BOARD(ZYNOS_BOARD_HS100, MACH_ADM5120_HS100),
ZYXEL_BOARD(ZYNOS_BOARD_P334, MACH_ADM5120_P334),
ZYXEL_BOARD(ZYNOS_BOARD_P334U, MACH_ADM5120_P334U),
DUMMY_BOARD()
};
+struct common_board {
+ char *name;
+ unsigned long mach_type;
+};
+
+#define DEFBOARD(n, mt) { .name = (n), .mach_type = (mt) }
+static struct common_board common_boards[] __initdata = {
+ DEFBOARD("CAS-630", MACH_ADM5120_CAS630),
+ DEFBOARD("CAS-670", MACH_ADM5120_CAS670),
+ DEFBOARD("CAS-700", MACH_ADM5120_CAS700),
+ DEFBOARD("CAS-771", MACH_ADM5120_CAS771),
+ DEFBOARD("CAS-790", MACH_ADM5120_CAS790),
+ DEFBOARD("CAS-861", MACH_ADM5120_CAS861),
+ DEFBOARD("NFS-101U", MACH_ADM5120_NFS101U),
+ DEFBOARD("NFS-202U", MACH_ADM5120_NFS202U),
+ DEFBOARD("EASY 5120", MACH_ADM5120_EASY5120),
+ DEFBOARD("EASY 5120-RT", MACH_ADM5120_EASY5120RT),
+ DEFBOARD("EASY 5120P-ATA", MACH_ADM5120_EASY5120PATA),
+ DEFBOARD("EASY 83000", MACH_ADM5120_EASY83000),
+ DEFBOARD("BR-6104K", MACH_ADM5120_BR6104K),
+ DEFBOARD("WP54G-WRT", MACH_ADM5120_WP54G_WRT),
+ DEFBOARD("P-334WT", MACH_ADM5120_P334WT),
+ DEFBOARD("P-335", MACH_ADM5120_P335),
+};
+
/*
* Helper routines
*/
((u32)p[3] << 24));
}
+static inline u16 read_be16(void *buf)
+{
+ u8 *p;
+
+ p = buf;
+ return (((u16)p[0] << 8) + (u16)p[1]);
+}
+
+static inline u32 read_be32(void *buf)
+{
+ u8 *p;
+
+ p = buf;
+ return (((u32)p[0] << 24) + ((u32)p[1] << 16) + ((u32)p[2] << 8) +
+ ((u32)p[3]));
+}
+
/*
* CFE based boards
*/
return 0;
}
- /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 SoC
-*/
+ /* cfe_a1_val must be 0, because only one CPU present in the ADM5120 */
if (cfe_a1_val != 0) {
return 0;
}
/*
* RouterBOOT based boards
*/
-static int __init routerboot_find_tag(u8 *buf, u16 tagid, void **tagval,
- u16 *taglen)
+static int __init routerboot_load_hs(u8 *buf, u16 buflen,
+ struct rb_hard_settings *hs)
{
u16 id,len;
- int ret;
+ u8 *mac;
+ int i,j;
+
+ if (buflen < 4)
+ return -1;
- ret = -1;
- /* skip header */
- buf += 8;
- for (;;) {
+ if (read_le32(buf) != RB_MAGIC_HARD)
+ return -1;
+
+ /* skip magic value */
+ buf += 4;
+ buflen -= 4;
+
+ while (buflen > 2) {
id = read_le16(buf);
buf += 2;
- if (id == RB_ID_TERMINATOR)
+ buflen -= 2;
+ if (id == RB_ID_TERMINATOR || buflen < 2)
break;
len = read_le16(buf);
buf += 2;
- if (id == tagid) {
- *tagval = buf;
- *taglen = len;
- ret = 0;
+ buflen -= 2;
+
+ if (buflen < len)
+ break;
+
+ switch (id) {
+ case RB_ID_BIOS_VERSION:
+ hs->bios_ver = (char *)buf;
+ break;
+ case RB_ID_BOARD_NAME:
+ hs->name = (char *)buf;
+ break;
+ case RB_ID_MEMORY_SIZE:
+ hs->mem_size = read_le32(buf);
+ break;
+ case RB_ID_MAC_ADDRESS_COUNT:
+ hs->mac_count = read_le32(buf);
+ break;
+ case RB_ID_MAC_ADDRESS_PACK:
+ hs->mac_count = len/RB_MAC_SIZE;
+ if (hs->mac_count > RB_MAX_MAC_COUNT)
+ hs->mac_count = RB_MAX_MAC_COUNT;
+ mac = buf;
+ for (i=0; i < hs->mac_count; i++) {
+ for (j=0; j < RB_MAC_SIZE; j++)
+ hs->macs[i][j] = mac[j];
+ mac += RB_MAC_SIZE;
+ }
break;
}
buf += len;
+ buflen -= len;
+
}
- return ret;
+ return 0;
}
-#define RB_HS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x1000)
-#define RB_SS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x2000)
-#define RB_FW_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000)
+#define RB_BS_OFFS 0x14
+#define RB_OFFS_MAX (128*1024)
static unsigned long __init routerboot_detect_board(void)
{
struct routerboard *board;
- u32 magic;
- char *name;
- u16 namelen;
+ struct rb_hard_settings hs;
+ struct rb_bios_settings *bs;
+ u8 *base;
+ u32 off,len;
unsigned long ret;
ret = MACH_ADM5120_UNKNOWN;
- magic = le32_to_cpu(*(u32 *)RB_HS_ADDR);
- if (magic != RB_MAGIC_HARD)
- goto out;
+ base = (u8 *)KSEG1ADDR(ADM5120_SRAM0_BASE);
+ bs = (struct rb_bios_settings *)(base + RB_BS_OFFS);
- magic = le32_to_cpu(*(u32 *)RB_SS_ADDR);
- if ((magic != RB_MAGIC_SOFT) && (magic != RB_MAGIC_DAWN))
- goto out;
+ off = read_le32(&bs->hs_offs);
+ len = read_le32(&bs->hs_size);
+ if (off > RB_OFFS_MAX)
+ return ret;
- if (routerboot_find_tag((u8 *)RB_HS_ADDR, RB_ID_BOARD_NAME,
- (void *)&name, &namelen))
- goto out;
+ memset(&hs, 0, sizeof(hs));
+ if (routerboot_load_hs(base+off, len, &hs) != 0)
+ return ret;
+
+ /* assume RouterBOOT as the boot-loader */
+ adm5120_boot_loader = BOOT_LOADER_ROUTERBOOT;
+
+ if (hs.name == NULL)
+ return ret;
for (board = routerboards; board->mach_type != MACH_ADM5120_UNKNOWN;
board++) {
- if (strncmp(board->name, name, strlen(board->name)) == 0) {
+ if (strncmp(board->name, hs.name, strlen(board->name)) == 0) {
ret = board->mach_type;
break;
}
-
}
- /* assume RouterBOOT as the boot-loader */
- adm5120_boot_loader = BOOT_LOADER_ROUTERBOOT;
-
-out:
return ret;
}
/*
* ZyNOS based boards
*/
-#define CHECK_VENDOR(n) (strnicmp(vendor, ZYNOS_VENDOR_ZYXEL, \
- strlen(ZYNOS_VENDOR_ZYXEL)) == 0)
+static inline u32 zynos_dbgarea_present(u8 *data)
+{
+ u32 t;
+
+ t = read_be32(data+5);
+ if (t != ZYNOS_MAGIC_DBGAREA1)
+ return 0;
+
+ t = read_be32(data+9);
+ if (t != ZYNOS_MAGIC_DBGAREA2)
+ return 0;
+
+ return 1;
+}
-static unsigned int __init zynos_get_vendor_id(unsigned char *vendor)
+#define CHECK_VENDOR(n) (strnicmp(vendor,(n),strlen(n)) == 0)
+
+static inline unsigned int zynos_get_vendor_id(struct zynos_board_info *info)
{
- int ret;
+ unsigned char vendor[ZYNOS_NAME_LEN];
+ int i;
- ret = ZYNOS_VENDOR_ID_INVALID;
+ for (i=0; i<ZYNOS_NAME_LEN; i++)
+ vendor[i]=info->vendor[i];
if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL)
- ret = ZYNOS_VENDOR_ID_ZYXEL;
+ return ZYNOS_VENDOR_ID_ZYXEL;
#if 0
/* TODO: there are no known ADM5120 based boards from other vendors */
- else if CHECK_VENDOR(ZYNOS_VENDOR_DLINK)
- ret = ZYNOS_VENDOR_ID_DLINK;
- else if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT)
- ret = ZYNOS_VENDOR_ID_LUCENT;
+ if CHECK_VENDOR(ZYNOS_VENDOR_DLINK)
+ return ZYNOS_VENDOR_ID_DLINK;
+
+ if CHECK_VENDOR(ZYNOS_VENDOR_LUCENT)
+ return ZYNOS_VENDOR_ID_LUCENT;
+
+ if CHECK_VENDOR(ZYNOS_VENDOR_NETGEAR)
+ return ZYNOS_VENDOR_ID_NETGEAR;
#endif
- return ret;
+ return ZYNOS_VENDOR_ID_OTHER;
}
-#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90)
-#define BOOTEXT_ADDR_2M 0xBFC08000
-#define BOOTEXT_ADDR_4M 0xBFC10000
+static inline u16 zynos_get_board_id(struct zynos_board_info *info)
+{
+ return read_be16(&info->board_id);
+}
+
+static inline u32 zynos_get_bootext_addr(struct zynos_board_info *info)
+{
+ return read_be32(&info->bootext_addr);
+}
+
+
+#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90)
+#define ZYNOS_HDBG_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x4000)
+#define BOOTEXT_ADDR_MIN KSEG1ADDR(ADM5120_SRAM0_BASE)
+#define BOOTEXT_ADDR_MAX (BOOTEXT_ADDR_MIN + (2*1024*1024))
static unsigned long __init zynos_detect_board(void)
{
struct zynos_board_info *info;
struct zynos_board *board;
unsigned int vendor_id;
- u32 bootext_addr;
+ u16 board_id;
+ u32 t;
unsigned long ret;
ret = MACH_ADM5120_UNKNOWN;
+ /* check presence of the dbgarea */
+ if (zynos_dbgarea_present((u8 *)ZYNOS_HDBG_ADDR) == 0)
+ goto out;
info = (struct zynos_board_info *)(ZYNOS_INFO_ADDR);
- vendor_id = zynos_get_vendor_id(&info->vendor);
- if (vendor_id == ZYNOS_VENDOR_ID_INVALID)
- goto out;
- bootext_addr = be32_to_cpu(info->bootext_addr);
- if ((bootext_addr != BOOTEXT_ADDR_2M) ||
- (bootext_addr != BOOTEXT_ADDR_4M))
+ /* check for a valid BootExt address */
+ t = zynos_get_bootext_addr(info);
+ if ((t < BOOTEXT_ADDR_MIN) || (t > BOOTEXT_ADDR_MAX))
goto out;
+ vendor_id = zynos_get_vendor_id(info);
+ board_id = zynos_get_board_id(info);
+
for (board = zynos_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
board++) {
if ((board->vendor_id == vendor_id) &&
- (board->board_id == be16_to_cpu(info->board_id))) {
+ (board->board_id == board_id)) {
ret = board->mach_type;
break;
}
return MACH_ADM5120_UNKNOWN;
}
+/*
+ * Misc boards
+ */
+static unsigned long __init prom_detect_board(void)
+{
+ char *name;
+ unsigned long ret;
+ int i;
+
+ ret = MACH_ADM5120_UNKNOWN;
+ name = prom_getenv("board_name");
+ if (name == NULL)
+ goto out;
+
+ if (*name == '\0')
+ goto out;
+
+ for (i=0; i<ARRAY_SIZE(common_boards); i++) {
+ if (strcmp(common_boards[i].name, name) == 0) {
+ ret = common_boards[i].mach_type;
+ break;
+ }
+ }
+
+out:
+ return ret;
+}
+
static void __init adm5120_detect_board(void)
{
struct adm5120_board *board;
adm5120_boot_loader = BOOT_LOADER_UBOOT;
if (t == MACH_ADM5120_UNKNOWN)
t = uboot_detect_board();
+ } else {
+ if (t == MACH_ADM5120_UNKNOWN)
+ t = prom_detect_board();
}
for (board = adm5120_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
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
*/
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);
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 banks? */
+
+ 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 */
- printk("ADM%04X%s revision %d, running at %ldMHz\n",
+ printk(KERN_INFO "ADM%04X%s revision %d, running at %ldMHz\n",
adm5120_product_code,
(adm5120_package == ADM5120_PACKAGE_BGA) ? "" : "P",
adm5120_revision, (adm5120_speed / 1000000)
);
- 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(KERN_INFO "Boot loader is: %s\n", boot_loader_names[adm5120_boot_loader]);
+ printk(KERN_INFO "Booted from : %s flash\n", adm5120_nand_boot ? "NAND":"NOR");
+ printk(KERN_INFO "Board is : %s\n", adm5120_board_name());
+ printk(KERN_INFO "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();