diff options
author | John Crispin <john@openwrt.org> | 2008-06-29 14:56:45 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2008-06-29 14:56:45 +0000 |
commit | 979fb5a23e515714462f880238af6c3c42b4eb05 (patch) | |
tree | 068a7ca1dd2b49318f19c34c393a16e09328b532 | |
parent | 76215afdec87bd6316029a4b148c51287239d682 (diff) | |
download | upstream-979fb5a23e515714462f880238af6c3c42b4eb05.tar.gz upstream-979fb5a23e515714462f880238af6c3c42b4eb05.tar.bz2 upstream-979fb5a23e515714462f880238af6c3c42b4eb05.zip |
fixes mdio, adds runtime board configuration for ifxmips
SVN-Revision: 11609
5 files changed, 192 insertions, 81 deletions
diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/board.c b/target/linux/ifxmips/files/arch/mips/ifxmips/board.c index b7e0387e30..0d932a2148 100644 --- a/target/linux/ifxmips/files/arch/mips/ifxmips/board.c +++ b/target/linux/ifxmips/files/arch/mips/ifxmips/board.c @@ -34,17 +34,31 @@ #include <asm/ifxmips/ifxmips.h> #include <asm/ifxmips/ifxmips_mii0.h> +#define MAX_BOARD_NAME_LEN 32 #define MAX_IFXMIPS_DEVS 9 -#define BOARD_DANUBE "Danube" -#define BOARD_DANUBE_CHIPID 0x10129083 +#define SYSTEM_DANUBE "Danube" +#define SYSTEM_DANUBE_CHIPID1 0x10129083 +#define SYSTEM_DANUBE_CHIPID2 0x3012B083 -#define BOARD_TWINPASS "Twinpass" -#define BOARD_TWINPASS_CHIPID 0x3012D083 +#define SYSTEM_TWINPASS "Twinpass" +#define SYSTEM_TWINPASS_CHIPID 0x3012D083 + +extern int ifxmips_pci_external_clock; static unsigned int chiprev; -static struct platform_device *ifxmips_devs[MAX_IFXMIPS_DEVS]; static int cmdline_mac = 0; +char board_name[MAX_BOARD_NAME_LEN + 1] = { 0 }; + +struct ifxmips_board { + char name[32]; + unsigned int system_type; + struct platform_device *devs[MAX_IFXMIPS_DEVS]; + struct resource reset_resource; + struct resource gpiodev_resource; + int pci_external_clock; + int num_devs; +}; spinlock_t ebu_lock = SPIN_LOCK_UNLOCKED; EXPORT_SYMBOL_GPL(ebu_lock); @@ -52,42 +66,35 @@ EXPORT_SYMBOL_GPL(ebu_lock); static struct ifxmips_mac ifxmips_mii_mac; static struct platform_device -ifxmips_led[] = +ifxmips_led = { - { - .id = 0, - .name = "ifxmips_led", - }, + .id = 0, + .name = "ifxmips_led", }; static struct platform_device -ifxmips_gpio[] = +ifxmips_gpio = { - { - .id = 0, - .name = "ifxmips_gpio", - }, + .id = 0, + .name = "ifxmips_gpio", + .num_resources = 1, }; static struct platform_device -ifxmips_mii[] = +ifxmips_mii = { - { - .id = 0, - .name = "ifxmips_mii0", - .dev = { - .platform_data = &ifxmips_mii_mac, - } - }, + .id = 0, + .name = "ifxmips_mii0", + .dev = { + .platform_data = &ifxmips_mii_mac, + } }; static struct platform_device -ifxmips_wdt[] = +ifxmips_wdt = { - { - .id = 0, - .name = "ifxmips_wdt", - }, + .id = 0, + .name = "ifxmips_wdt", }; static struct resource @@ -98,39 +105,20 @@ ifxmips_mtd_resource = { }; static struct platform_device -ifxmips_mtd[] = +ifxmips_mtd = { - { - .id = 0, - .name = "ifxmips_mtd", - .num_resources = 1, - .resource = &ifxmips_mtd_resource, - }, -}; - -#ifdef CONFIG_GPIO_DEVICE -static struct resource -ifxmips_gpio_dev_resources[] = { - { - .name = "gpio", - .flags = 0, - .start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | - (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), - .end = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | - (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), - }, + .id = 0, + .name = "ifxmips_mtd", + .num_resources = 1, + .resource = &ifxmips_mtd_resource, }; static struct platform_device -ifxmips_gpio_dev[] = { - { - .name = "GPIODEV", - .id = -1, - .num_resources = ARRAY_SIZE(ifxmips_gpio_dev_resources), - .resource = ifxmips_gpio_dev_resources, - } +ifxmips_gpio_dev = { + .name = "GPIODEV", + .id = -1, + .num_resources = 1, }; -#endif const char* get_system_type(void) @@ -138,17 +126,36 @@ get_system_type(void) chiprev = ifxmips_r32(IFXMIPS_MPS_CHIPID); switch(chiprev) { - case BOARD_DANUBE_CHIPID: - return BOARD_DANUBE; + case SYSTEM_DANUBE_CHIPID1: + case SYSTEM_DANUBE_CHIPID2: + return SYSTEM_DANUBE; - case BOARD_TWINPASS_CHIPID: - return BOARD_TWINPASS; + case SYSTEM_TWINPASS_CHIPID: + return SYSTEM_TWINPASS; } return BOARD_SYSTEM_TYPE; } -#define IS_HEX(x) (((x >='0' && x <= '9') || (x >='a' && x <= 'f') || (x >='A' && x <= 'F'))?(1):(0)) +static int __init +ifxmips_set_board_type(char *str) +{ + str = strchr(str, '='); + if(!str) + goto out; + str++; + if(strlen(str) > MAX_BOARD_NAME_LEN) + goto out; + strncpy(board_name, str, MAX_BOARD_NAME_LEN); + printk("bootloader told us, that this is a %s board\n", board_name); +out: + return 1; +} +__setup("ifxmips_board", ifxmips_set_board_type); + +#define IS_HEX(x) \ + (((x >='0' && x <= '9') || (x >='a' && x <= 'f') || (x >='A' && x <= 'F'))?(1):(0)) + static int __init ifxmips_set_mii0_mac(char *str) { @@ -174,23 +181,122 @@ out: } __setup("mii0_mac", ifxmips_set_mii0_mac); + +static struct ifxmips_board boards[] = +{ + { + .name = "EASY50712", + .system_type = SYSTEM_DANUBE_CHIPID1, + .devs = + { + &ifxmips_led, &ifxmips_gpio, &ifxmips_mii, + &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev, + }, + .reset_resource = + { + .name = "reset", + .start = 1, + .end = 15, + }, + .gpiodev_resource = + { + .name = "gpio", + .start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + .end = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + }, + .num_devs = 6, + }, { + .name = "EASY4010", + .system_type = SYSTEM_TWINPASS_CHIPID, + .devs = + { + &ifxmips_led, &ifxmips_gpio, &ifxmips_mii, + &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev, + }, + .reset_resource = + { + .name = "reset", + .start = 1, + .end = 15, + }, + .gpiodev_resource = + { + .name = "gpio", + .start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + .end = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + }, + .num_devs = 6, + }, { + .name = "ARV4519", + .system_type = SYSTEM_DANUBE_CHIPID2, + .devs = + { + &ifxmips_led, &ifxmips_gpio, &ifxmips_mii, + &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev, + }, + .reset_resource = + { + .name = "reset", + .start = 1, + .end = 12, + }, + .gpiodev_resource = + { + .name = "gpio", + .start = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + .end = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | + (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) | (1 << 12), + }, + .pci_external_clock = 1, + .num_devs = 6, + }, +}; + +struct ifxmips_board* ifxmips_find_board(void) +{ + int i; + if(!*board_name) + return 0; + for(i = 0; i < ARRAY_SIZE(boards); i++) + if((boards[i].system_type == chiprev) && (!strcmp(boards[i].name, board_name))) + return &boards[i]; + return 0; +} + int __init ifxmips_init_devices(void) { - int dev = 0; + struct ifxmips_board *board = ifxmips_find_board(); + + chiprev = ifxmips_r32(IFXMIPS_MPS_CHIPID); if(!cmdline_mac) random_ether_addr(ifxmips_mii_mac.mac); - ifxmips_devs[dev++] = ifxmips_led; - ifxmips_devs[dev++] = ifxmips_gpio; - ifxmips_devs[dev++] = ifxmips_mii; - ifxmips_devs[dev++] = ifxmips_mtd; - ifxmips_devs[dev++] = ifxmips_wdt; -#ifdef CONFIG_GPIO_DEVICE - ifxmips_devs[dev++] = ifxmips_gpio_dev; -#endif - return platform_add_devices(ifxmips_devs, dev); + if(!board) + { + switch(chiprev) + { + case SYSTEM_DANUBE_CHIPID1: + case SYSTEM_DANUBE_CHIPID2: + board = &boards[0]; + break; + case SYSTEM_TWINPASS_CHIPID: + board = &boards[1]; + break; + } + } + ifxmips_gpio.resource = &board->reset_resource; + ifxmips_gpio_dev.resource = &board->gpiodev_resource; + if(board->pci_external_clock) + ifxmips_pci_external_clock = 1; + printk("using board definition %s\n", board->name); + return platform_add_devices(board->devs, board->num_devs); } arch_initcall(ifxmips_init_devices); diff --git a/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c b/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c index 01212d1aef..cf64bda976 100644 --- a/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c +++ b/target/linux/ifxmips/files/arch/mips/ifxmips/gpio.c @@ -45,9 +45,9 @@ #define PINS_PER_PORT 16 #ifdef CONFIG_IFXMIPS_GPIO_RST_BTN -#define IFXMIPS_RST_PIN 15 -#define IFXMIPS_RST_PORT 1 +unsigned int rst_port = 1; +unsigned int rst_pin = 15; static struct timer_list rst_button_timer; extern struct sock *uevent_sock; @@ -306,7 +306,7 @@ reset_button_poll(unsigned long unused) rst_button_timer.expires = jiffies + (HZ / 4); add_timer(&rst_button_timer); - if (pressed != ifxmips_port_get_input(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN)) + if (pressed != ifxmips_port_get_input(rst_port, rst_pin)) { if(pressed) pressed = 0; @@ -333,10 +333,12 @@ ifxmips_gpio_probe(struct platform_device *dev) int retval = 0; #ifdef CONFIG_IFXMIPS_GPIO_RST_BTN - ifxmips_port_set_open_drain(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); - ifxmips_port_clear_altsel0(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); - ifxmips_port_clear_altsel1(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); - ifxmips_port_set_dir_in(IFXMIPS_RST_PORT, IFXMIPS_RST_PIN); + rst_port = dev->resource[0].start; + rst_pin = dev->resource[0].end; + ifxmips_port_set_open_drain(rst_port, rst_pin); + ifxmips_port_clear_altsel0(rst_port, rst_pin); + ifxmips_port_clear_altsel1(rst_port, rst_pin); + ifxmips_port_set_dir_in(rst_port, rst_pin); seen = jiffies; init_timer(&rst_button_timer); rst_button_timer.function = reset_button_poll; diff --git a/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c b/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c index bd500bdec0..97efa37dd1 100644 --- a/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c +++ b/target/linux/ifxmips/files/arch/mips/pci/pci-ifxmips.c @@ -50,7 +50,7 @@ static struct pci_controller ifxmips_pci_controller = }; u32 ifxmips_pci_mapped_cfg; -u32 ifxmips_pci_external_clock = 0; +int ifxmips_pci_external_clock = 0; static int __init ifxmips_pci_set_external_clk(char *str) diff --git a/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c b/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c index cd3075c1d6..cc3b9d46a7 100644 --- a/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c +++ b/target/linux/ifxmips/files/drivers/net/ifxmips_mii0.c @@ -54,6 +54,7 @@ ifxmips_write_mdio(u32 phy_addr, u32 phy_reg, u16 phy_data) while(ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_REQUEST); ifxmips_w32(val, IFXMIPS_PPE32_MDIO_ACC); } +EXPORT_SYMBOL(ifxmips_write_mdio); unsigned short ifxmips_read_mdio(u32 phy_addr, u32 phy_reg) @@ -67,6 +68,7 @@ ifxmips_read_mdio(u32 phy_addr, u32 phy_reg) val = ifxmips_r32(IFXMIPS_PPE32_MDIO_ACC) & MDIO_ACC_VAL_MASK; return val; } +EXPORT_SYMBOL(ifxmips_read_mdio); int ifxmips_ifxmips_mii_open(struct net_device *dev) @@ -346,6 +348,7 @@ ifxmips_mii_probe(struct platform_device *dev) ifxmips_mii0_dev->init = ifxmips_mii_dev_init; memcpy(mac_addr, mac->mac, 6); strcpy(ifxmips_mii0_dev->name, "eth%d"); + ifxmips_mii_chip_init(REV_MII_MODE); result = register_netdev(ifxmips_mii0_dev); if (result) { @@ -353,7 +356,6 @@ ifxmips_mii_probe(struct platform_device *dev) goto out; } - ifxmips_mii_chip_init(REV_MII_MODE); printk(KERN_INFO "ifxmips_mii0: driver loaded!\n"); out: diff --git a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h index 3a8c3f64fd..1c6c614329 100644 --- a/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h +++ b/target/linux/ifxmips/files/include/asm-mips/ifxmips/ifxmips.h @@ -182,7 +182,8 @@ #define REV_MII_MODE 2 /* mdio access */ -#define IFXMIPS_PPE32_MDIO_ACC ((u32*)(IFXMIPS_PPE32_MEM_MAP + 0x1804)) +#define IFXMIPS_PPE32_MDIO_CFG ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x11800)) +#define IFXMIPS_PPE32_MDIO_ACC ((u32*)(IFXMIPS_PPE32_BASE_ADDR + 0x11804)) #define MDIO_ACC_REQUEST 0x80000000 #define MDIO_ACC_READ 0x40000000 |