Fresh fixes from Gabor Juhos : detects RouterBoot, Bootbase, improve board specification

SVN-Revision: 6963
owl
Florian Fainelli 2007-04-16 09:55:30 +00:00
parent 0eb7f75195
commit 151babe684
10 changed files with 696 additions and 210 deletions

View File

@ -178,6 +178,7 @@ CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_PMC551 is not set # CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_RAM is not set # CONFIG_MTD_RAM is not set
# CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_MYLOADER_PARTS=y
# CONFIG_MTD_ROM is not set # CONFIG_MTD_ROM is not set
# CONFIG_MTD_SLRAM is not set # CONFIG_MTD_SLRAM is not set
CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_QUOTA=m

View File

@ -14,81 +14,339 @@
#include <linux/autoconf.h> #include <linux/autoconf.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <adm5120_info.h> #include <asm/mach-adm5120/adm5120_defs.h>
#include <adm5120_defs.h> #include <asm/mach-adm5120/adm5120_switch.h>
#include <adm5120_switch.h> #include <asm/mach-adm5120/adm5120_info.h>
#include <myloader.h> #include <asm/mach-adm5120/myloader.h>
#include <asm/mach-adm5120/routerboot.h>
#include <asm/mach-adm5120/zynos.h>
/* boot loaders specific definitions */ /*
#define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE from other bootloaders */ * Globals
*/
struct adm5120_board adm5120_board;
unsigned int adm5120_boot_loader;
struct adm5120_info adm5120_info = { unsigned int adm5120_product_code;
.cpu_speed = CPU_SPEED_175, unsigned int adm5120_revision;
.cpu_package = CPU_PACKAGE_PQFP, unsigned int adm5120_package;
.boot_loader = BOOT_LOADER_UNKNOWN, unsigned int adm5120_nand_boot;
.board_type = BOARD_TYPE_UNKNOWN unsigned long adm5120_speed;
};
/*
* Locals
*/
static char *boot_loader_names[BOOT_LOADER_LAST+1] = { static char *boot_loader_names[BOOT_LOADER_LAST+1] = {
[BOOT_LOADER_UNKNOWN] = "Unknown", [BOOT_LOADER_UNKNOWN] = "Unknown",
[BOOT_LOADER_CFE] = "CFE", [BOOT_LOADER_CFE] = "CFE",
[BOOT_LOADER_UBOOT] = "U-Boot", [BOOT_LOADER_UBOOT] = "U-Boot",
[BOOT_LOADER_MYLOADER] = "MyLoader", [BOOT_LOADER_MYLOADER] = "MyLoader",
[BOOT_LOADER_ROUTERBOOT]= "RouterBOOT" [BOOT_LOADER_ROUTERBOOT]= "RouterBOOT",
[BOOT_LOADER_BOOTBASE] = "Bootbase"
};
static struct adm5120_board __initdata adm5120_boards[] = {
{
.name = "Compex NetPassage 27G",
.mach_type = MACH_ADM5120_NP27G,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex NetPassage 28G",
.mach_type = MACH_ADM5120_NP28G,
.has_usb = 0,
.iface_num = 4,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex NP28G (HotSpot)",
.mach_type = MACH_ADM5120_NP28GHS,
.has_usb = 0,
.iface_num = 4,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex WP54AG",
.mach_type = MACH_ADM5120_WP54AG,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex WP54G",
.mach_type = MACH_ADM5120_WP54G,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex WP54G-WRT",
.mach_type = MACH_ADM5120_WP54G_WRT,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex WP54G v1C",
.mach_type = MACH_ADM5120_WP54Gv1C,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 2*1024*1024,
},
{
.name = "Compex WPP54AG",
.mach_type = MACH_ADM5120_WPP54AG,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 4*1024*1024,
},
{
.name = "Compex WPP54G",
.mach_type = MACH_ADM5120_WPP54G,
.has_usb = 0,
.iface_num = 2,
.flash0_size = 4*1024*1024,
},
{
.name = "RouterBOARD RB-111",
.mach_type = MACH_ADM5120_RB_111,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
.name = "RouterBOARD RB-112",
.mach_type = MACH_ADM5120_RB_112,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
.name = "RouterBOARD RB-133",
.mach_type = MACH_ADM5120_RB_133,
.has_usb = 0,
.iface_num = 3,
.flash0_size = 128*1024,
},
{
.name = "RouterBOARD RB-133C",
.mach_type = MACH_ADM5120_RB_133C,
.has_usb = 0,
.iface_num = 1,
.flash0_size = 128*1024,
},
{
.name = "RouterBOARD RB-150",
.mach_type = MACH_ADM5120_RB_150,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 128*1024,
},
{
.name = "RouterBOARD RB-153",
.mach_type = MACH_ADM5120_RB_153,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 128*1024,
},
{
.name = "ZyXEL HomeSafe 100/100W",
.mach_type = MACH_ADM5120_HS100,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 334",
.mach_type = MACH_ADM5120_P334,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 2*1024*1024,
},
{
.name = "ZyXEL Prestige 334U",
.mach_type = MACH_ADM5120_P334U,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 334W",
.mach_type = MACH_ADM5120_P334W,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 2*1024*1024,
},
{
.name = "ZyXEL Prestige 334WH",
.mach_type = MACH_ADM5120_P334WH,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 334WHD",
.mach_type = MACH_ADM5120_P334WHD,
.has_usb = 0,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 334WT",
.mach_type = MACH_ADM5120_P334WT,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 335/335WT",
.mach_type = MACH_ADM5120_P335,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 335Plus",
.mach_type = MACH_ADM5120_P335PLUS,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "ZyXEL Prestige 335U",
.mach_type = MACH_ADM5120_P335U,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 4*1024*1024,
},
{
.name = "Unknown ADM5120 board",
.mach_type = MACH_ADM5120_UNKNOWN,
.has_usb = 1,
.iface_num = 5,
.flash0_size = 0,
}
};
struct mylo_board {
u16 vid;
u16 did;
u16 svid;
u16 sdid;
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[] = {
COMPEX_BOARD(DEVID_COMPEX_NP27G, MACH_ADM5120_NP27G),
COMPEX_BOARD(DEVID_COMPEX_NP28G, MACH_ADM5120_NP28G),
COMPEX_BOARD(DEVID_COMPEX_NP28GHS, MACH_ADM5120_NP28GHS),
COMPEX_BOARD(DEVID_COMPEX_WP54G, MACH_ADM5120_WP54G),
COMPEX_BOARD(DEVID_COMPEX_WP54Gv1C, MACH_ADM5120_WP54Gv1C),
COMPEX_BOARD(DEVID_COMPEX_WP54AG, MACH_ADM5120_WP54AG),
COMPEX_BOARD(DEVID_COMPEX_WPP54G, MACH_ADM5120_WPP54G),
COMPEX_BOARD(DEVID_COMPEX_WPP54AG, MACH_ADM5120_WPP54AG),
DUMMY_BOARD()
};
#define ROUTERBOARD_NAME_LEN 16
struct routerboard {
unsigned long mach_type;
char name[ROUTERBOARD_NAME_LEN];
};
#define ROUTERBOARD(n, mt) { .name = (n), .mach_type = (mt) }
static struct routerboard __initdata routerboards[] = {
ROUTERBOARD("111", MACH_ADM5120_RB_111),
ROUTERBOARD("112", MACH_ADM5120_RB_112),
ROUTERBOARD("133", MACH_ADM5120_RB_133),
ROUTERBOARD("133C", MACH_ADM5120_RB_133C),
ROUTERBOARD("miniROUTER", MACH_ADM5120_RB_150),
ROUTERBOARD("153", MACH_ADM5120_RB_150),
DUMMY_BOARD()
};
struct zynos_board {
unsigned long mach_type;
unsigned int vendor_id;
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 ZYXEL_BOARD(bi, mt) ZYNOS_BOARD(ZYNOS_VENDOR_ID_ZYXEL, bi, 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[] = {
ZYXEL_BOARD(ZYNOS_BOARD_HS100, MACH_ADM5120_HS100),
ZYXEL_BOARD(ZYNOS_BOARD_P334, MACH_ADM5120_P334),
ZYXEL_BOARD(ZYNOS_BOARD_P334U, MACH_ADM5120_P334U),
ZYXEL_BOARD(ZYNOS_BOARD_P334W, MACH_ADM5120_P334W),
ZYXEL_BOARD(ZYNOS_BOARD_P334WH, MACH_ADM5120_P334WH),
ZYXEL_BOARD(ZYNOS_BOARD_P334WHD, MACH_ADM5120_P334WHD),
ZYXEL_BOARD(ZYNOS_BOARD_P334WT, MACH_ADM5120_P334WT),
ZYXEL_BOARD(ZYNOS_BOARD_P335, MACH_ADM5120_P335),
ZYXEL_BOARD(ZYNOS_BOARD_P335PLUS, MACH_ADM5120_P335PLUS),
ZYXEL_BOARD(ZYNOS_BOARD_P335U, MACH_ADM5120_P335U),
DUMMY_BOARD()
}; };
/* /*
* CPU settings detection * Helper routines
*/ */
#define CODE_GET_PC(c) ((c) & CODE_PC_MASK) static inline u16 read_le16(void *buf)
#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK)
#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK)
#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK)
#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0)
static void __init detect_cpu_info(void)
{ {
uint32_t *reg; u8 *p;
uint32_t code;
uint32_t clks;
reg = (uint32_t *)KSEG1ADDR(ADM5120_SWITCH_BASE+SWITCH_REG_CODE); p = buf;
code = *reg; return ((u16)p[0] + ((u16)p[1] << 8));
}
clks = CODE_GET_CLKS(code); static inline u32 read_le32(void *buf)
{
adm5120_info.product_code = CODE_GET_PC(code); u8 *p;
adm5120_info.revision = CODE_GET_REV(code);
adm5120_info.cpu_speed = CPU_SPEED_175;
if (clks & 1)
adm5120_info.cpu_speed += 25000000;
if (clks & 2)
adm5120_info.cpu_speed += 50000000;
adm5120_info.cpu_package = (CODE_GET_PK(code) == CODE_PK_BGA) ?
CPU_PACKAGE_BGA : CPU_PACKAGE_PQFP;
adm5120_info.nand_boot = CODE_GET_NAB(code);
p = buf;
return ((u32)p[0] + ((u32)p[1] << 8) + ((u32)p[2] << 16) +
((u32)p[3] << 24));
} }
/* /*
* Boot loader detection routines * CFE based boards
*/ */
static int __init detect_cfe(void) #define CFE_EPTSEAL 0x43464531 /* CFE1 is the magic number to recognize CFE
from other bootloaders */
static int __init cfe_present(void)
{ {
/* /*
* This method only works, when we are booted directly from the CFE. * This method only works, when we are booted directly from the CFE.
*/ */
uint32_t cfe_handle = (uint32_t) fw_arg0; u32 cfe_handle = (u32) fw_arg0;
uint32_t cfe_a1_val = (uint32_t) fw_arg1; u32 cfe_a1_val = (u32) fw_arg1;
uint32_t cfe_entry = (uint32_t) fw_arg2; u32 cfe_entry = (u32) fw_arg2;
uint32_t cfe_seal = (uint32_t) fw_arg3; u32 cfe_seal = (u32) fw_arg3;
/* Check for CFE by finding the CFE magic number */ /* Check for CFE by finding the CFE magic number */
if (cfe_seal != CFE_EPTSEAL) { if (cfe_seal != CFE_EPTSEAL) {
@ -96,7 +354,8 @@ static int __init detect_cfe(void)
return 0; 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 SoC
*/
if (cfe_a1_val != 0) { if (cfe_a1_val != 0) {
return 0; return 0;
} }
@ -109,88 +368,294 @@ static int __init detect_cfe(void)
return 1; return 1;
} }
static int __init detect_uboot(void) static unsigned long __init cfe_detect_board(void)
{ {
/* FIXME: not yet implemented */ return MACH_ADM5120_WP54G_WRT;
return 0;
} }
static int __init detect_myloader(void) /*
* MyLoader based boards
*/
#define SYS_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F000)
#define BOARD_PARAMS_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x0F800)
#define PART_TABLE_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x10000)
static unsigned long __init myloader_detect_board(void)
{ {
struct mylo_system_params *sysp; struct mylo_system_params *sysp;
struct mylo_board_params *boardp; struct mylo_board_params *boardp;
struct mylo_partition_table *parts; struct mylo_partition_table *parts;
struct mylo_board *board;
unsigned long ret;
sysp = (struct mylo_system_params *)(MYLO_MIPS_SYS_PARAMS); ret = MACH_ADM5120_UNKNOWN;
boardp = (struct mylo_board_params *)(MYLO_MIPS_BOARD_PARAMS);
parts = (struct mylo_partition_table *)(MYLO_MIPS_PARTITIONS); sysp = (struct mylo_system_params *)(SYS_PARAMS_ADDR);
boardp = (struct mylo_board_params *)(BOARD_PARAMS_ADDR);
parts = (struct mylo_partition_table *)(PART_TABLE_ADDR);
/* Check for some magic numbers */ /* Check for some magic numbers */
if ((sysp->magic != MYLO_MAGIC_SYS_PARAMS) || if ((le32_to_cpu(sysp->magic) != MYLO_MAGIC_SYS_PARAMS) ||
(boardp->magic != MYLO_MAGIC_BOARD_PARAMS) || (le32_to_cpu(boardp->magic) != MYLO_MAGIC_BOARD_PARAMS) ||
(parts->magic != MYLO_MAGIC_PARTITIONS)) (le32_to_cpu(parts->magic) != MYLO_MAGIC_PARTITIONS))
return 0; goto out;
return 1; for (board = mylo_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
board++) {
if ((le16_to_cpu(sysp->vid) == board->vid) &&
(le16_to_cpu(sysp->did) == board->did) &&
(le16_to_cpu(sysp->svid) == board->svid) &&
(le16_to_cpu(sysp->sdid) == board->sdid)) {
ret = board->mach_type;
break;
}
}
/* assume MyLoader as the boot-loader */
adm5120_boot_loader = BOOT_LOADER_MYLOADER;
out:
return ret;
} }
static int __init detect_routerboot(void) /*
* RouterBOOT based boards
*/
static int __init routerboot_find_tag(u8 *buf, u16 tagid, void **tagval,
u16 *taglen)
{
u16 id,len;
int ret;
ret = -1;
/* skip header */
buf += 8;
for (;;) {
id = read_le16(buf);
buf += 2;
if (id == RB_ID_TERMINATOR)
break;
len = read_le16(buf);
buf += 2;
if (id == tagid) {
*tagval = buf;
*taglen = len;
ret = 0;
break;
}
buf += len;
}
return ret;
}
#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)
static unsigned long __init routerboot_detect_board(void)
{
struct routerboard *board;
u32 magic;
char *name;
u16 namelen;
unsigned long ret;
ret = MACH_ADM5120_UNKNOWN;
magic = le32_to_cpu(*(u32 *)RB_HS_ADDR);
if (magic != RB_MAGIC_HARD)
goto out;
magic = le32_to_cpu(*(u32 *)RB_SS_ADDR);
if ((magic != RB_MAGIC_SOFT) && (magic != RB_MAGIC_DAWN))
goto out;
if (routerboot_find_tag((u8 *)RB_HS_ADDR, RB_ID_BOARD_NAME,
(void *)&name, &namelen))
goto out;
for (board = routerboards; board->mach_type != MACH_ADM5120_UNKNOWN;
board++) {
if (strncmp(board->name, 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 unsigned int __init zynos_get_vendor_id(unsigned char *vendor)
{
int ret;
ret = ZYNOS_VENDOR_ID_INVALID;
if CHECK_VENDOR(ZYNOS_VENDOR_ZYXEL)
ret = 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;
#endif
return ret;
}
#define ZYNOS_INFO_ADDR KSEG1ADDR(ADM5120_SRAM0_BASE+0x3F90)
#define BOOTEXT_ADDR_2M 0xBFC08000
#define BOOTEXT_ADDR_4M 0xBFC10000
static unsigned long __init zynos_detect_board(void)
{
struct zynos_board_info *info;
struct zynos_board *board;
unsigned int vendor_id;
u32 bootext_addr;
unsigned long ret;
ret = MACH_ADM5120_UNKNOWN;
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))
goto out;
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))) {
ret = board->mach_type;
break;
}
}
/* assume Bootbase as the boot-loader */
adm5120_boot_loader = BOOT_LOADER_BOOTBASE;
out:
return ret;
}
/*
* U-Boot based boards
*/
static int __init uboot_present(void)
{ {
/* FIXME: not yet implemented */ /* FIXME: not yet implemented */
return 0; return 0;
} }
static int __init detect_bootloader(void) static unsigned long __init uboot_detect_board(void)
{ {
if (detect_cfe()) /* FIXME: not yet implemented */
return BOOT_LOADER_CFE; return MACH_ADM5120_UNKNOWN;
}
if (detect_uboot()) static void __init adm5120_detect_board(void)
return BOOT_LOADER_UBOOT; {
struct adm5120_board *board;
unsigned long t;
if (detect_myloader()) adm5120_boot_loader = BOOT_LOADER_UNKNOWN;
return BOOT_LOADER_MYLOADER;
if (detect_routerboot()) /* Try to detect board type without bootloader */
return BOOT_LOADER_ROUTERBOOT; t = routerboot_detect_board();
return BOOT_LOADER_UNKNOWN; if (t == MACH_ADM5120_UNKNOWN)
t = zynos_detect_board();
if (t == MACH_ADM5120_UNKNOWN)
t = myloader_detect_board();
/* Try to detect bootloader type */
if (cfe_present()) {
adm5120_boot_loader = BOOT_LOADER_CFE;
if (t == MACH_ADM5120_UNKNOWN)
t = cfe_detect_board();
} else if (uboot_present()) {
adm5120_boot_loader = BOOT_LOADER_UBOOT;
if (t == MACH_ADM5120_UNKNOWN)
t = uboot_detect_board();
}
for (board = adm5120_boards; board->mach_type != MACH_ADM5120_UNKNOWN;
board++) {
if (board->mach_type == t)
break;
}
memcpy(&adm5120_board, board, sizeof(adm5120_board));
} }
/* /*
* Board detection * CPU settings detection
*/ */
static void __init detect_board_type(void) #define CODE_GET_PC(c) ((c) & CODE_PC_MASK)
#define CODE_GET_REV(c) (((c) >> CODE_REV_SHIFT) & CODE_REV_MASK)
#define CODE_GET_PK(c) (((c) >> CODE_PK_SHIFT) & CODE_PK_MASK)
#define CODE_GET_CLKS(c) (((c) >> CODE_CLKS_SHIFT) & CODE_CLKS_MASK)
#define CODE_GET_NAB(c) (((c) & CODE_NAB) != 0)
static void __init adm5120_detect_cpuinfo(void)
{ {
switch(adm5120_info.boot_loader) { u32 code;
case BOOT_LOADER_CFE: u32 clks;
adm5120_info.board_type = BOARD_TYPE_WP54G_WRT;
adm5120_info.iface_num = 2; code = *(u32 *)KSEG1ADDR(ADM5120_SWITCH_BASE+SWITCH_REG_CODE);
adm5120_info.has_usb = 0;
printk("Board is a Compex WP54G-WRT\n"); adm5120_product_code = CODE_GET_PC(code);
default: adm5120_revision = CODE_GET_REV(code);
adm5120_info.board_type = BOARD_TYPE_UNKNOWN; adm5120_package = (CODE_GET_PK(code) == CODE_PK_BGA) ?
printk("Board type is unknown\n"); ADM5120_PACKAGE_BGA : ADM5120_PACKAGE_PQFP;
} adm5120_nand_boot = CODE_GET_NAB(code);
clks = CODE_GET_CLKS(code);
adm5120_speed = ADM5120_SPEED_175;
if (clks & 1)
adm5120_speed += 25000000;
if (clks & 2)
adm5120_speed += 50000000;
} }
void __init adm5120_info_show(void) void __init adm5120_info_show(void)
{ {
/* FIXME: move this somewhere else */
printk("ADM%04X%s revision %d, running at %ldMHz\n", printk("ADM%04X%s revision %d, running at %ldMHz\n",
adm5120_info.product_code, adm5120_product_code,
(adm5120_info.cpu_package == CPU_PACKAGE_BGA) ? "" : "P", (adm5120_package == ADM5120_PACKAGE_BGA) ? "" : "P",
adm5120_info.revision, adm5120_revision, (adm5120_speed / 1000000)
(adm5120_info.cpu_speed / 1000000)
); );
printk("Boot loader is: %s\n", boot_loader_names[adm5120_info.boot_loader]); printk("Boot loader is: %s\n", boot_loader_names[adm5120_boot_loader]);
printk("Booted from : %s flash\n", adm5120_info.nand_boot ? "NAND" : "NOR"); printk("Booted from : %s flash\n", adm5120_nand_boot ? "NAND":"NOR");
printk("Board is : %s\n", adm5120_board_name());
} }
void __init adm5120_info_init(void) void __init adm5120_info_init(void)
{ {
detect_cpu_info(); adm5120_detect_cpuinfo();
adm5120_info.boot_loader = detect_bootloader(); adm5120_detect_board();
detect_board_type();
adm5120_info_show(); adm5120_info_show();
} }

View File

@ -3,6 +3,7 @@
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
* Copyright (C) 2003 ADMtek Incorporated. * Copyright (C) 2003 ADMtek Incorporated.
* daniell@admtek.com.tw * daniell@admtek.com.tw
* Copyright (C) 2007 OpenWrt.org
* *
* This program is free software; you can distribute it and/or modify it * This program is free software; you can distribute it and/or modify it
* under the terms of the GNU General Public License (Version 2) as * under the terms of the GNU General Public License (Version 2) as
@ -29,7 +30,7 @@
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include <adm5120_info.h> #include <asm/mach-adm5120/adm5120_info.h>
void setup_prom_printf(int); void setup_prom_printf(int);
void prom_printf(char *, ...); void prom_printf(char *, ...);
@ -98,18 +99,18 @@ char *prom_getenv(char *envname)
return(NULL); return(NULL);
} }
/* /*
* initialize the prom module. * initialize the prom module.
*/ */
void __init prom_init(void) void __init prom_init(void)
{ {
/* you should these macros defined in include/asm/bootinfo.h */
mips_machgroup = MACH_GROUP_ADM_GW;
mips_machtype = MACH_ADM_GW_5120;
adm5120_info_init(); adm5120_info_init();
/* you should these macros defined in include/asm/bootinfo.h */
mips_machgroup = MACH_GROUP_ADM5120;
mips_machtype = adm5120_board.mach_type;
/* init command line, register a default kernel command line */ /* init command line, register a default kernel command line */
strcpy(&(arcs_cmdline[0]), CONFIG_CMDLINE); strcpy(&(arcs_cmdline[0]), CONFIG_CMDLINE);

View File

@ -3,6 +3,7 @@
* Creator : daniell@admtek.com.tw * Creator : daniell@admtek.com.tw
* Copyright 1999, 2000 MIPS Technologies, Inc. * Copyright 1999, 2000 MIPS Technologies, Inc.
* Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
* Copyright (C) 2007 OpenWrt.org
*/ */
#include <linux/autoconf.h> #include <linux/autoconf.h>
@ -44,7 +45,7 @@ void adm5120_power_off(void)
void __init adm5120_time_init(void) void __init adm5120_time_init(void)
{ {
mips_counter_frequency = adm5120_info.cpu_speed >> 1; mips_counter_frequency = adm5120_speed >> 1;
} }
void __init plat_timer_setup(struct irqaction *irq) void __init plat_timer_setup(struct irqaction *irq)
@ -71,7 +72,7 @@ void __init plat_mem_setup(void)
const char *get_system_type(void) const char *get_system_type(void)
{ {
return "ADM5120 Board"; return adm5120_board_name();
} }
static struct resource adm5120_hcd_resources[] = { static struct resource adm5120_hcd_resources[] = {

View File

@ -3,7 +3,7 @@
* Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org> * Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
* Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
* *
* original functions for finding root filesystem from Mike Baker * original functions for finding root filesystem from Mike Baker
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
@ -24,10 +24,10 @@
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA. * 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* Copyright 2001-2003, Broadcom Corporation * Copyright 2001-2003, Broadcom Corporation
* All Rights Reserved. * All Rights Reserved.
* *
* THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
* KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
* SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
@ -57,7 +57,7 @@ extern int parse_myloader_partitions(struct mtd_info *master,
struct mtd_partition **pparts, struct mtd_partition **pparts,
unsigned long origin); unsigned long origin);
/* Macros for switching flash bank /* Macros for switching flash bank
ADM5120 only support 2MB flash address space ADM5120 only support 2MB flash address space
so GPIO5 is used as A20 so GPIO5 is used as A20
*/ */
@ -69,7 +69,7 @@ extern int parse_myloader_partitions(struct mtd_info *master,
#define TRX_MAGIC 0x30524448 /* "HDR0" */ #define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_VERSION 1 #define TRX_VERSION 1
#define TRX_MAX_LEN 0x3A0000 #define TRX_MAX_LEN 0x3A0000
#define TRX_NO_HEADER 1 /* Do not write TRX header */ #define TRX_NO_HEADER 1 /* Do not write TRX header */
#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ #define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */
#define TRX_MAX_OFFSET 3 #define TRX_MAX_OFFSET 3
@ -150,7 +150,7 @@ static void adm5120_map_copy_from(struct map_info *map, void *to, unsigned long
flash_switch_bank(FLASH_BOUNDARY); flash_switch_bank(FLASH_BOUNDARY);
inline_map_copy_from(map, to, from, len); inline_map_copy_from(map, to, from, len);
} }
} }
static int __init static int __init
@ -172,7 +172,7 @@ find_cfe_size(struct mtd_info *mtd, size_t size)
memset(buf, 0xe5, sizeof(buf)); memset(buf, 0xe5, sizeof(buf));
/* /*
* Read into buffer * Read into buffer
*/ */
if (mtd->read(mtd, off, sizeof(buf), &len, buf) || if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
len != sizeof(buf)) len != sizeof(buf))
@ -199,7 +199,7 @@ find_cfe_size(struct mtd_info *mtd, size_t size)
* Copied from mtdblock.c * Copied from mtdblock.c
* *
* Cache stuff... * Cache stuff...
* *
* Since typical flash erasable sectors are much larger than what Linux's * Since typical flash erasable sectors are much larger than what Linux's
* buffer cache can handle, we must implement read-modify-write on flash * buffer cache can handle, we must implement read-modify-write on flash
* sectors for each block write requests. To avoid over-erasing flash sectors * sectors for each block write requests. To avoid over-erasing flash sectors
@ -213,7 +213,7 @@ static void erase_callback(struct erase_info *done)
wake_up(wait_q); wake_up(wait_q);
} }
static int erase_write (struct mtd_info *mtd, unsigned long pos, static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf) int len, const char *buf)
{ {
struct erase_info erase; struct erase_info erase;
@ -282,7 +282,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
memset(&trx, 0xe5, sizeof(trx)); memset(&trx, 0xe5, sizeof(trx));
/* /*
* Read into buffer * Read into buffer
*/ */
if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) || if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
len != sizeof(trx)) len != sizeof(trx))
@ -290,9 +290,9 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
/* found a TRX header */ /* found a TRX header */
if (le32_to_cpu(trx.magic) == TRX_MAGIC) { if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
part->offset = le32_to_cpu(trx.offsets[2]) ? : part->offset = le32_to_cpu(trx.offsets[2]) ? :
le32_to_cpu(trx.offsets[1]); le32_to_cpu(trx.offsets[1]);
part->size = le32_to_cpu(trx.len); part->size = le32_to_cpu(trx.len);
part->size -= part->offset; part->size -= part->offset;
part->offset += off; part->offset += off;
@ -309,7 +309,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
found: found:
if (part->size == 0) if (part->size == 0)
return 0; return 0;
if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf)) if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
return 0; return 0;
@ -335,7 +335,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
if (trx.len != part->offset + part->size - off) { if (trx.len != part->offset + part->size - off) {
/* Update the trx offsets and length */ /* Update the trx offsets and length */
trx.len = part->offset + part->size - off; trx.len = part->offset + part->size - off;
/* Update the trx crc32 */ /* Update the trx crc32 */
for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) { for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf)) if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
@ -351,7 +351,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
printk("Error accessing the first trx eraseblock\n"); printk("Error accessing the first trx eraseblock\n");
return 0; return 0;
} }
printk("Updating TRX offsets and length:\n"); printk("Updating TRX offsets and length:\n");
printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32); printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32); printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx.offsets[0], trx.offsets[1], trx.offsets[2], trx.len, trx.crc32);
@ -366,7 +366,7 @@ find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
kfree(block); kfree(block);
printk("Done\n"); printk("Done\n");
} }
return part->size; return part->size;
} }
@ -395,15 +395,15 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
/* linux (kernel and rootfs) */ /* linux (kernel and rootfs) */
if (cfe_size != 384 * 1024) { if (cfe_size != 384 * 1024) {
adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size; adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size;
adm5120_cfe_parts[1].size = adm5120_cfe_parts[3].offset - adm5120_cfe_parts[1].size = adm5120_cfe_parts[3].offset -
adm5120_cfe_parts[1].offset; adm5120_cfe_parts[1].offset;
} else { } else {
/* do not count the elf loader, which is on one block */ /* do not count the elf loader, which is on one block */
adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size + adm5120_cfe_parts[1].offset = adm5120_cfe_parts[0].size +
adm5120_cfe_parts[3].size + mtd->erasesize; adm5120_cfe_parts[3].size + mtd->erasesize;
adm5120_cfe_parts[1].size = size - adm5120_cfe_parts[1].size = size -
adm5120_cfe_parts[0].size - adm5120_cfe_parts[0].size -
(2*adm5120_cfe_parts[3].size) - (2*adm5120_cfe_parts[3].size) -
mtd->erasesize; mtd->erasesize;
} }
@ -411,28 +411,28 @@ init_mtd_partitions(struct mtd_info *mtd, size_t size)
if (find_root(mtd,size,&adm5120_cfe_parts[2])==0) { if (find_root(mtd,size,&adm5120_cfe_parts[2])==0) {
/* entirely jffs2 */ /* entirely jffs2 */
adm5120_cfe_parts[4].name = NULL; adm5120_cfe_parts[4].name = NULL;
adm5120_cfe_parts[2].size = size - adm5120_cfe_parts[2].offset - adm5120_cfe_parts[2].size = size - adm5120_cfe_parts[2].offset -
adm5120_cfe_parts[3].size; adm5120_cfe_parts[3].size;
} else { } else {
/* legacy setup */ /* legacy setup */
/* calculate leftover flash, and assign it to the jffs2 partition */ /* calculate leftover flash, and assign it to the jffs2 partition */
if (cfe_size != 384 * 1024) { if (cfe_size != 384 * 1024) {
adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset + adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
adm5120_cfe_parts[2].size; adm5120_cfe_parts[2].size;
if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) { if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) {
adm5120_cfe_parts[4].offset += mtd->erasesize - adm5120_cfe_parts[4].offset += mtd->erasesize -
(adm5120_cfe_parts[4].offset % mtd->erasesize); (adm5120_cfe_parts[4].offset % mtd->erasesize);
} }
adm5120_cfe_parts[4].size = adm5120_cfe_parts[3].offset - adm5120_cfe_parts[4].size = adm5120_cfe_parts[3].offset -
adm5120_cfe_parts[4].offset; adm5120_cfe_parts[4].offset;
} else { } else {
adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset + adm5120_cfe_parts[4].offset = adm5120_cfe_parts[2].offset +
adm5120_cfe_parts[2].size; adm5120_cfe_parts[2].size;
if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) { if ((adm5120_cfe_parts[4].offset % mtd->erasesize) > 0) {
adm5120_cfe_parts[4].offset += mtd->erasesize - adm5120_cfe_parts[4].offset += mtd->erasesize -
(adm5120_cfe_parts[4].offset % mtd->erasesize); (adm5120_cfe_parts[4].offset % mtd->erasesize);
} }
adm5120_cfe_parts[4].size = size - adm5120_cfe_parts[3].size - adm5120_cfe_parts[4].size = size - adm5120_cfe_parts[3].size -
adm5120_cfe_parts[4].offset; adm5120_cfe_parts[4].offset;
} }
} }
@ -460,7 +460,7 @@ int __init init_adm5120_map(void)
adm5120_map.read = adm5120_map_read; adm5120_map.read = adm5120_map_read;
adm5120_map.write = adm5120_map_write; adm5120_map.write = adm5120_map_write;
adm5120_map.copy_from = adm5120_map_copy_from; adm5120_map.copy_from = adm5120_map_copy_from;
if (!(adm5120_mtd = do_map_probe("cfi_probe", &adm5120_map))) { if (!(adm5120_mtd = do_map_probe("cfi_probe", &adm5120_map))) {
printk("Failed to do_map_probe\n"); printk("Failed to do_map_probe\n");
iounmap((void *)adm5120_map.virt); iounmap((void *)adm5120_map.virt);
@ -475,14 +475,14 @@ int __init init_adm5120_map(void)
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
if (adm5120_info.boot_loader == BOOT_LOADER_CFE) if (adm5120_boot_loader == BOOT_LOADER_CFE)
{ {
printk(KERN_NOTICE "adm5120 : using CFE flash mapping\n"); printk(KERN_NOTICE "adm5120 : using CFE flash mapping\n");
parts = init_mtd_partitions(adm5120_mtd, size); parts = init_mtd_partitions(adm5120_mtd, size);
for (i = 0; parts[i].name; i++); for (i = 0; parts[i].name; i++);
ret = add_mtd_partitions(adm5120_mtd, parts, i); ret = add_mtd_partitions(adm5120_mtd, parts, i);
if (ret) { if (ret) {
printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
goto fail; goto fail;
@ -490,11 +490,11 @@ int __init init_adm5120_map(void)
} }
#endif #endif
#ifdef CONFIG_MTD_MYLOADER_PARTS #ifdef CONFIG_MTD_MYLOADER_PARTS
if (adm5120_info.boot_loader == BOOT_LOADER_MYLOADER) if (adm5120_boot_loader == BOOT_LOADER_MYLOADER)
{ {
printk(KERN_NOTICE "adm5120 : using MyLoader flash mapping\n"); printk(KERN_NOTICE "adm5120 : using MyLoader flash mapping\n");
char *part_type; char *part_type;
if (parsed_nr_parts == 0) { if (parsed_nr_parts == 0) {
ret = parse_myloader_partitions(adm5120_mtd, &parts, 0); ret = parse_myloader_partitions(adm5120_mtd, &parts, 0);

View File

@ -3,7 +3,7 @@
* *
* Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005 * Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2005
* *
* Inspiration for this driver came from the original ADMtek 2.4 * Inspiration for this driver came from the original ADMtek 2.4
* driver, Copyright ADMtek Inc. * driver, Copyright ADMtek Inc.
*/ */
#include <linux/autoconf.h> #include <linux/autoconf.h>
@ -20,7 +20,7 @@
#include <asm/io.h> #include <asm/io.h>
#include "adm5120sw.h" #include "adm5120sw.h"
#include "adm5120_info.h" #include <asm/mach-adm5120/adm5120_info.h>
MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)"); MODULE_AUTHOR("Jeroen Vreeken (pe1rxq@amsat.org)");
MODULE_DESCRIPTION("ADM5120 ethernet switch driver"); MODULE_DESCRIPTION("ADM5120 ethernet switch driver");
@ -29,7 +29,7 @@ MODULE_LICENSE("GPL");
/* /*
* The ADM5120 uses an internal matrix to determine which ports * The ADM5120 uses an internal matrix to determine which ports
* belong to which VLAN. * belong to which VLAN.
* The default generates a VLAN (and device) for each port * The default generates a VLAN (and device) for each port
* (including MII port) and the CPU port is part of all of them. * (including MII port) and the CPU port is part of all of them.
* *
* Another example, one big switch and everything mapped to eth0: * Another example, one big switch and everything mapped to eth0:
@ -42,7 +42,7 @@ static unsigned char vlan_matrix[SW_DEVS] = {
static int adm5120_nrdevs; static int adm5120_nrdevs;
static struct net_device *adm5120_devs[SW_DEVS]; static struct net_device *adm5120_devs[SW_DEVS];
static struct adm5120_dma static struct adm5120_dma
adm5120_dma_txh_v[ADM5120_DMA_TXH] __attribute__((aligned(16))), adm5120_dma_txh_v[ADM5120_DMA_TXH] __attribute__((aligned(16))),
adm5120_dma_txl_v[ADM5120_DMA_TXL] __attribute__((aligned(16))), adm5120_dma_txl_v[ADM5120_DMA_TXL] __attribute__((aligned(16))),
adm5120_dma_rxh_v[ADM5120_DMA_RXH] __attribute__((aligned(16))), adm5120_dma_rxh_v[ADM5120_DMA_RXH] __attribute__((aligned(16))),
@ -389,14 +389,9 @@ static int __init adm5120_sw_init(void)
if (err) if (err)
goto out; goto out;
/* MII port? */ adm5120_nrdevs = adm5120_board.iface_num;
if (adm5120_get_reg(ADM5120_CODE) & ADM5120_CODE_PQFP) if (adm5120_nrdevs > 5 && !adm5120_has_gmii())
adm5120_nrdevs = 5; adm5120_nrdevs = 5;
/* CFE based devices only have two enet ports */
else if (adm5120_info.boot_loader == BOOT_LOADER_CFE)
adm5120_nrdevs = 2;
else
adm5120_nrdevs = 6;
adm5120_set_reg(ADM5120_CPUP_CONF, adm5120_set_reg(ADM5120_CPUP_CONF,
ADM5120_DISCCPUPORT | ADM5120_CRC_PADDING | ADM5120_DISCCPUPORT | ADM5120_CRC_PADDING |
@ -426,14 +421,14 @@ static int __init adm5120_sw_init(void)
adm5120_set_reg(ADM5120_RECEIVE_LBADDR, KSEG1ADDR(adm5120_dma_rxl)); adm5120_set_reg(ADM5120_RECEIVE_LBADDR, KSEG1ADDR(adm5120_dma_rxl));
adm5120_set_vlan(vlan_matrix); adm5120_set_vlan(vlan_matrix);
for (i=0; i<adm5120_nrdevs; i++) { for (i=0; i<adm5120_nrdevs; i++) {
adm5120_devs[i] = alloc_etherdev(sizeof(struct adm5120_sw)); adm5120_devs[i] = alloc_etherdev(sizeof(struct adm5120_sw));
if (!adm5120_devs[i]) { if (!adm5120_devs[i]) {
err = -ENOMEM; err = -ENOMEM;
goto out_int; goto out_int;
} }
dev = adm5120_devs[i]; dev = adm5120_devs[i];
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
memset(netdev_priv(dev), 0, sizeof(struct adm5120_sw)); memset(netdev_priv(dev), 0, sizeof(struct adm5120_sw));
@ -456,7 +451,7 @@ static int __init adm5120_sw_init(void)
memcpy(dev->dev_addr, "\x00\x50\xfc\x11\x22\x01", 6); memcpy(dev->dev_addr, "\x00\x50\xfc\x11\x22\x01", 6);
dev->dev_addr[5] += i; dev->dev_addr[5] += i;
adm5120_write_mac(dev); adm5120_write_mac(dev);
if ((err = register_netdev(dev))) { if ((err = register_netdev(dev))) {
free_netdev(dev); free_netdev(dev);
goto out_int; goto out_int;

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org) * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org)
* *
* Based on the ADMtek 2.4 driver * Based on the ADMtek 2.4 driver
* (C) Copyright 2003 Junius Chen <juniusc@admtek.com.tw> * (C) Copyright 2003 Junius Chen <juniusc@admtek.com.tw>
* Which again was based on the ohci and uhci drivers. * Which again was based on the ohci and uhci drivers.
*/ */
@ -146,7 +146,7 @@ static int admhcd_td_err[16] = {
struct admhcd { struct admhcd {
spinlock_t lock; spinlock_t lock;
void __iomem *addr_reg; void __iomem *addr_reg;
void __iomem *data_reg; void __iomem *data_reg;
/* Root hub registers */ /* Root hub registers */
@ -160,7 +160,7 @@ struct admhcd {
u32 base; u32 base;
u32 dma_en; u32 dma_en;
unsigned long flags; unsigned long flags;
}; };
static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd) static inline struct admhcd *hcd_to_admhcd(struct usb_hcd *hcd)
@ -213,7 +213,7 @@ static struct admhcd_td *admhcd_td_alloc(struct admhcd_ed *ed, struct urb *urb)
if (ed->cur == NULL) { if (ed->cur == NULL) {
ed->cur = tdn; ed->cur = tdn;
ed->head = tdn; ed->head = tdn;
ed->tail = tdn; ed->tail = tdn;
td = tdn; td = tdn;
} else { } else {
/* Supply back the old tail and link in new td as tail */ /* Supply back the old tail and link in new td as tail */
@ -345,7 +345,7 @@ static irqreturn_t adm5120hcd_irq(int irq, void *ptr, struct pt_regs *regs)
} }
if (intstatus & ADMHCD_INT_TD) { if (intstatus & ADMHCD_INT_TD) {
struct admhcd_ed *ed, *head; struct admhcd_ed *ed, *head;
admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_TD); admhcd_reg_set(ahcd, ADMHCD_REG_INTSTATUS, ADMHCD_INT_TD);
head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD); head = (struct admhcd_ed *)admhcd_reg_get(ahcd, ADMHCD_REG_HOSTHEAD);
@ -355,7 +355,7 @@ static irqreturn_t adm5120hcd_irq(int irq, void *ptr, struct pt_regs *regs)
if (ed->urb && !(ed->cur->control & ADMHCD_TD_OWN)) { if (ed->urb && !(ed->cur->control & ADMHCD_TD_OWN)) {
struct admhcd_td *td; struct admhcd_td *td;
int error; int error;
td = ed->cur; td = ed->cur;
error = (td->control & ADMHCD_TD_ERRMASK) >> error = (td->control & ADMHCD_TD_ERRMASK) >>
ADMHCD_TD_ERRSHIFT; ADMHCD_TD_ERRSHIFT;
@ -442,7 +442,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0, td = admhcd_td_fill(ADMHCD_TD_SETUP | ADMHCD_TD_DATA0,
td, (dma_addr_t)urb->setup_packet, 8); td, (dma_addr_t)urb->setup_packet, 8);
while (data_len > 0) { while (data_len > 0) {
td = admhcd_td_fill(ADMHCD_TD_DATA1 td = admhcd_td_fill(ADMHCD_TD_DATA1
| ADMHCD_TD_R | | ADMHCD_TD_R |
(usb_pipeout(pipe) ? (usb_pipeout(pipe) ?
ADMHCD_TD_OUT : ADMHCD_TD_IN), td, ADMHCD_TD_OUT : ADMHCD_TD_IN), td,
@ -459,7 +459,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
i = 0; i = 0;
while(data_len > 4096) { while(data_len > 4096) {
td = admhcd_td_fill((usb_pipeout(pipe) ? td = admhcd_td_fill((usb_pipeout(pipe) ?
ADMHCD_TD_OUT : ADMHCD_TD_OUT :
ADMHCD_TD_IN | ADMHCD_TD_R) | ADMHCD_TD_IN | ADMHCD_TD_R) |
(i ? ADMHCD_TD_TOGGLE : toggle), td, (i ? ADMHCD_TD_TOGGLE : toggle), td,
data, 4096); data, 4096);
@ -467,7 +467,7 @@ static int admhcd_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep,
data_len -= 4096; data_len -= 4096;
i++; i++;
} }
td = admhcd_td_fill((usb_pipeout(pipe) ? td = admhcd_td_fill((usb_pipeout(pipe) ?
ADMHCD_TD_OUT : ADMHCD_TD_IN) | ADMHCD_TD_OUT : ADMHCD_TD_IN) |
(i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len); (i ? ADMHCD_TD_TOGGLE : toggle), td, data, data_len);
i++; i++;
@ -616,7 +616,7 @@ static int admhcd_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_RESET: case USB_PORT_FEAT_RESET:
if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4) if (admhcd_reg_get(ahcd, ADMHCD_REG_PORTSTATUS0 + port*4)
& ADMHCD_CCS) { & ADMHCD_CCS) {
admhcd_reg_set(ahcd, admhcd_reg_set(ahcd,
ADMHCD_REG_PORTSTATUS0 + port*4, ADMHCD_REG_PORTSTATUS0 + port*4,
ADMHCD_PRS | ADMHCD_CSC); ADMHCD_PRS | ADMHCD_CSC);
mdelay(50); mdelay(50);
@ -707,7 +707,7 @@ static int __init adm5120hcd_probe(struct platform_device *pdev)
struct usb_device *udev; struct usb_device *udev;
struct resource *addr, *data; struct resource *addr, *data;
void __iomem *addr_reg; void __iomem *addr_reg;
void __iomem *data_reg; void __iomem *data_reg;
int irq, err = 0; int irq, err = 0;
if (pdev->num_resources < 3) { if (pdev->num_resources < 3) {
@ -748,7 +748,7 @@ static int __init adm5120hcd_probe(struct platform_device *pdev)
err = -ENOMEM; err = -ENOMEM;
goto out_mem; goto out_mem;
} }
hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id); hcd = usb_create_hcd(&adm5120_hc_driver, &pdev->dev, pdev->dev.bus_id);
if (!hcd) if (!hcd)
@ -826,7 +826,7 @@ static int __init adm5120hcd_init(void)
{ {
if (usb_disabled()) if (usb_disabled())
return -ENODEV; return -ENODEV;
if (!adm5120_info.has_usb) if (!adm5120_board.has_usb)
return -ENODEV; return -ENODEV;
return platform_driver_register(&adm5120hcd_driver); return platform_driver_register(&adm5120hcd_driver);

View File

@ -15,59 +15,56 @@
#include <linux/types.h> #include <linux/types.h>
struct adm5120_info { #define ADM5120_BOARD_NAMELEN 64
unsigned int product_code;
unsigned int revision; struct adm5120_board {
unsigned int cpu_package; char name[ADM5120_BOARD_NAMELEN];
unsigned int nand_boot; unsigned long mach_type;
unsigned long cpu_speed; unsigned int iface_num; /* Number of Ethernet interfaces */
unsigned int boot_loader; unsigned int has_usb; /* USB controller presence flag */
unsigned int board_type; u32 flash0_size; /* Flash 0 size */
unsigned int iface_num; /* Number of Ethernet interfaces */
unsigned int has_usb; /* USB controller presence flag */
u32 window_addr; /* Flash address */
u32 window_size; /* Flash size */
}; };
#define CPU_SPEED_175 175000000 extern struct adm5120_board adm5120_board;
#define CPU_SPEED_200 200000000
#define CPU_SPEED_225 225000000
#define CPU_SPEED_250 250000000
#define CPU_PACKAGE_PQFP 0
#define CPU_PACKAGE_BGA 1
extern unsigned int adm5120_boot_loader;
#define BOOT_LOADER_UNKNOWN 0 #define BOOT_LOADER_UNKNOWN 0
#define BOOT_LOADER_CFE 1 #define BOOT_LOADER_CFE 1
#define BOOT_LOADER_UBOOT 2 #define BOOT_LOADER_UBOOT 2
#define BOOT_LOADER_MYLOADER 3 #define BOOT_LOADER_MYLOADER 3
#define BOOT_LOADER_ROUTERBOOT 4 #define BOOT_LOADER_ROUTERBOOT 4
#define BOOT_LOADER_LAST 4 #define BOOT_LOADER_BOOTBASE 5
#define BOOT_LOADER_LAST 5
#define BOARD_TYPE_UNKNOWN 0 extern unsigned int adm5120_product_code;
#define BOARD_TYPE_WP54G_WRT 1 extern unsigned int adm5120_revision;
#define BOARD_TYPE_WP54G 2 extern unsigned int adm5120_nand_boot;
#define BOARD_TYPE_WP54AG 3
#define BOARD_TYPE_WPP54G 4 extern unsigned long adm5120_speed;
#define BOARD_TYPE_WPP54AG 5 #define ADM5120_SPEED_175 175000000
#define BOARD_TYPE_NP28G 6 #define ADM5120_SPEED_200 200000000
#define BOARD_TYPE_NP28GHS 7 #define ADM5120_SPEED_225 225000000
#define BOARD_TYPE_NP27G 8 #define ADM5120_SPEED_250 250000000
#define BOARD_TYPE_WP54Gv1C 9
#define BOARD_TYPE_RB_111 10 extern unsigned int adm5120_package;
#define BOARD_TYPE_RB_112 11 #define ADM5120_PACKAGE_PQFP 0
#define BOARD_TYPE_RB_133 12 #define ADM5120_PACKAGE_BGA 1
#define BOARD_TYPE_RB_133C 13
#define BOARD_TYPE_RB_150 14
#define BOARD_TYPE_RB_153 15
#define BOART_TYPE_LAST 15
extern struct adm5120_info adm5120_info;
extern void adm5120_info_init(void); extern void adm5120_info_init(void);
static inline int adm5120_has_pci(void) static inline int adm5120_has_pci(void)
{ {
return (adm5120_info.cpu_package == CPU_PACKAGE_BGA); return (adm5120_package == ADM5120_PACKAGE_BGA);
}
static inline int adm5120_has_gmii(void)
{
return (adm5120_package == ADM5120_PACKAGE_BGA);
}
static inline char *adm5120_board_name(void)
{
return adm5120_board.name;
} }
#endif /* _ADM5120_INFO_H */ #endif /* _ADM5120_INFO_H */

View File

@ -31,7 +31,7 @@ install:
ifneq ($(TARGET),) ifneq ($(TARGET),)
install: compile install: compile
$(CP) $(PKG_BUILD_DIR)/$(LOADER).gz $(PKG_BUILD_DIR)/$(LOADER).elf $(TARGET)/ $(CP) $(PKG_BUILD_DIR)/$(LOADER).gz $(PKG_BUILD_DIR)/$(LOADER).elf $(PKG_BUILD_DIR)/$(LOADER).bin $(TARGET)/
endif endif
clean: clean:

View File

@ -1,16 +1,17 @@
diff -urN linux-2.6.19.2/arch/mips/Kconfig linux-2.6.19.2.new/arch/mips/Kconfig diff -urN linux-2.6.19.2/arch/mips/Kconfig linux-2.6.19.2.new/arch/mips/Kconfig
--- linux-2.6.19.2/arch/mips/Kconfig 2007-01-10 20:10:37.000000000 +0100 --- linux-2.6.19.2/arch/mips/Kconfig 2007-01-10 20:10:37.000000000 +0100
+++ linux-2.6.19.2.new/arch/mips/Kconfig 2007-01-23 14:49:38.000000000 +0100 +++ linux-2.6.19.2.new/arch/mips/Kconfig 2007-01-23 14:49:38.000000000 +0100
@@ -12,6 +12,18 @@ @@ -12,6 +12,19 @@
prompt "System type" prompt "System type"
default SGI_IP22 default SGI_IP22
+config MIPS_ADM5120 +config MIPS_ADM5120
+ bool "Support for ADM5120 SoC" + bool "Support for ADM5120 SoC"
+ select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R1
+ select DMA_NONCOHERENT + select DMA_NONCOHERENT
+ select HW_HAS_PCI + select HW_HAS_PCI
+ select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_32BIT_KERNEL
+ +
+config PCI_ADM5120 +config PCI_ADM5120
@ -25,7 +26,7 @@ diff -urN linux-2.6.19.2/arch/mips/Makefile linux-2.6.19.2.new/arch/mips/Makefil
+++ linux-2.6.19.2.new/arch/mips/Makefile 2007-01-23 14:49:39.000000000 +0100 +++ linux-2.6.19.2.new/arch/mips/Makefile 2007-01-23 14:49:39.000000000 +0100
@@ -165,6 +165,14 @@ @@ -165,6 +165,14 @@
load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000 load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
# #
+# ADMtek 5120 +# ADMtek 5120
+# +#
@ -49,16 +50,41 @@ diff -urN linux-2.6.19.2/arch/mips/pci/Makefile linux-2.6.19.2.new/arch/mips/pci
diff -urN linux-2.6.19.2/include/asm-mips/bootinfo.h linux-2.6.19.2.new/include/asm-mips/bootinfo.h diff -urN linux-2.6.19.2/include/asm-mips/bootinfo.h linux-2.6.19.2.new/include/asm-mips/bootinfo.h
--- linux-2.6.19.2/include/asm-mips/bootinfo.h 2007-01-10 20:10:37.000000000 +0100 --- linux-2.6.19.2/include/asm-mips/bootinfo.h 2007-01-10 20:10:37.000000000 +0100
+++ linux-2.6.19.2.new/include/asm-mips/bootinfo.h 2007-01-23 14:49:40.000000000 +0100 +++ linux-2.6.19.2.new/include/asm-mips/bootinfo.h 2007-01-23 14:49:40.000000000 +0100
@@ -212,6 +212,12 @@ @@ -212,6 +212,37 @@
#define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */ #define MACH_GROUP_NEC_EMMA2RH 25 /* NEC EMMA2RH (was 23) */
#define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */ #define MACH_NEC_MARKEINS 0 /* NEC EMMA2RH Mark-eins */
+/* +/*
+ * Valid machtype for group ADMtek + * Valid machtype for group ADMtek ADM5120
+ */ + */
+#define MACH_GROUP_ADM_GW 23 +#define MACH_GROUP_ADM5120 23
+#define MACH_ADM_GW_5120 0 +#define MACH_ADM5120_UNKNOWN 0 /* Unknown board */
+#define MACH_ADM5120_WP54G_WRT 1 /* Compex WP54G-WRT */
+#define MACH_ADM5120_WP54G 2 /* Compex WP54G */
+#define MACH_ADM5120_WP54AG 3 /* Compex WP54AG */
+#define MACH_ADM5120_WPP54G 4 /* Compex WPP54G */
+#define MACH_ADM5120_WPP54AG 5 /* Compex WPP54AG */
+#define MACH_ADM5120_NP28G 6 /* Compex NP28G */
+#define MACH_ADM5120_NP28GHS 7 /* Compex NP28G HotSpot */
+#define MACH_ADM5120_NP27G 8 /* Compex NP27G */
+#define MACH_ADM5120_WP54Gv1C 9 /* Compex WP54G version 1C */
+#define MACH_ADM5120_RB_111 10 /* Mikrotik RouterBOARD 111 */
+#define MACH_ADM5120_RB_112 11 /* Mikrotik RouterBOARD 112 */
+#define MACH_ADM5120_RB_133 12 /* Mikrotik RouterBOARD 133 */
+#define MACH_ADM5120_RB_133C 13 /* Mikrotik RouterBOARD 133c */
+#define MACH_ADM5120_RB_150 14 /* Mikrotik RouterBOARD 150 */
+#define MACH_ADM5120_RB_153 15 /* Mikrotik RouterBOARD 153 */
+#define MACH_ADM5120_HS100 16 /* ZyXEL HomeSafe 100/100W */
+#define MACH_ADM5120_P334 17 /* ZyXEL Prestige 334 */
+#define MACH_ADM5120_P334U 18 /* ZyXEL Prestige 334U */
+#define MACH_ADM5120_P334W 18 /* ZyXEL Prestige 334W */
+#define MACH_ADM5120_P334WH 19 /* ZyXEL Prestige 334WH */
+#define MACH_ADM5120_P334WHD 20 /* ZyXEL Prestige 334WHD */
+#define MACH_ADM5120_P334WT 21 /* ZyXEL Prestige 334WT */
+#define MACH_ADM5120_P335 22 /* ZyXEL Prestige 335/335WT */
+#define MACH_ADM5120_P335PLUS 23 /* ZyXEL Prestige 335Plus */
+#define MACH_ADM5120_P335U 24 /* ZyXEL Prestige 335U */
+ +
#define CL_SIZE COMMAND_LINE_SIZE #define CL_SIZE COMMAND_LINE_SIZE
const char *get_system_type(void); const char *get_system_type(void);