Path: blob/master/arch/arm/mach-ixp4xx/goramo_mlr.c
10817 views
/*1* Goramo MultiLink router platform code2* Copyright (C) 2006-2009 Krzysztof Halasa <[email protected]>3*/45#include <linux/delay.h>6#include <linux/hdlc.h>7#include <linux/i2c-gpio.h>8#include <linux/io.h>9#include <linux/irq.h>10#include <linux/kernel.h>11#include <linux/pci.h>12#include <linux/serial_8250.h>13#include <asm/mach-types.h>14#include <asm/system.h>15#include <asm/mach/arch.h>16#include <asm/mach/flash.h>17#include <asm/mach/pci.h>1819#define SLOT_ETHA 0x0B /* IDSEL = AD21 */20#define SLOT_ETHB 0x0C /* IDSEL = AD20 */21#define SLOT_MPCI 0x0D /* IDSEL = AD19 */22#define SLOT_NEC 0x0E /* IDSEL = AD18 */2324/* GPIO lines */25#define GPIO_SCL 026#define GPIO_SDA 127#define GPIO_STR 228#define GPIO_IRQ_NEC 329#define GPIO_IRQ_ETHA 430#define GPIO_IRQ_ETHB 531#define GPIO_HSS0_DCD_N 632#define GPIO_HSS1_DCD_N 733#define GPIO_UART0_DCD 834#define GPIO_UART1_DCD 935#define GPIO_HSS0_CTS_N 1036#define GPIO_HSS1_CTS_N 1137#define GPIO_IRQ_MPCI 1238#define GPIO_HSS1_RTS_N 1339#define GPIO_HSS0_RTS_N 1440/* GPIO15 is not connected */4142/* Control outputs from 74HC4094 */43#define CONTROL_HSS0_CLK_INT 044#define CONTROL_HSS1_CLK_INT 145#define CONTROL_HSS0_DTR_N 246#define CONTROL_HSS1_DTR_N 347#define CONTROL_EXT 448#define CONTROL_AUTO_RESET 549#define CONTROL_PCI_RESET_N 650#define CONTROL_EEPROM_WC_N 75152/* offsets from start of flash ROM = 0x50000000 */53#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */54#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */55#define CFG_REV 0x4C /* u32 */56#define CFG_SDRAM_SIZE 0x50 /* u32 */57#define CFG_SDRAM_CONF 0x54 /* u32 */58#define CFG_SDRAM_MODE 0x58 /* u32 */59#define CFG_SDRAM_REFRESH 0x5C /* u32 */6061#define CFG_HW_BITS 0x60 /* u32 */62#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */63#define CFG_HW_HAS_PCI_SLOT 0x0000000864#define CFG_HW_HAS_ETH0 0x0000001065#define CFG_HW_HAS_ETH1 0x0000002066#define CFG_HW_HAS_HSS0 0x0000004067#define CFG_HW_HAS_HSS1 0x0000008068#define CFG_HW_HAS_UART0 0x0000010069#define CFG_HW_HAS_UART1 0x0000020070#define CFG_HW_HAS_EEPROM 0x000004007172#define FLASH_CMD_READ_ARRAY 0xFF73#define FLASH_CMD_READ_ID 0x9074#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */7576static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;77static u8 control_value;7879static void set_scl(u8 value)80{81gpio_line_set(GPIO_SCL, !!value);82udelay(3);83}8485static void set_sda(u8 value)86{87gpio_line_set(GPIO_SDA, !!value);88udelay(3);89}9091static void set_str(u8 value)92{93gpio_line_set(GPIO_STR, !!value);94udelay(3);95}9697static inline void set_control(int line, int value)98{99if (value)100control_value |= (1 << line);101else102control_value &= ~(1 << line);103}104105106static void output_control(void)107{108int i;109110gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);111gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);112113for (i = 0; i < 8; i++) {114set_scl(0);115set_sda(control_value & (0x80 >> i)); /* MSB first */116set_scl(1); /* active edge */117}118119set_str(1);120set_str(0);121122set_scl(0);123set_sda(1); /* Be ready for START */124set_scl(1);125}126127128static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);129130static int hss_set_clock(int port, unsigned int clock_type)131{132int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;133134switch (clock_type) {135case CLOCK_DEFAULT:136case CLOCK_EXT:137set_control(ctrl_int, 0);138output_control();139return CLOCK_EXT;140141case CLOCK_INT:142set_control(ctrl_int, 1);143output_control();144return CLOCK_INT;145146default:147return -EINVAL;148}149}150151static irqreturn_t hss_dcd_irq(int irq, void *pdev)152{153int i, port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));154gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);155set_carrier_cb_tab[port](pdev, !i);156return IRQ_HANDLED;157}158159160static int hss_open(int port, void *pdev,161void (*set_carrier_cb)(void *pdev, int carrier))162{163int i, irq;164165if (!port)166irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);167else168irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);169170gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);171set_carrier_cb(pdev, !i);172173set_carrier_cb_tab[!!port] = set_carrier_cb;174175if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {176printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",177irq, i);178return i;179}180181set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);182output_control();183gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);184return 0;185}186187static void hss_close(int port, void *pdev)188{189free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :190IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);191set_carrier_cb_tab[!!port] = NULL; /* catch bugs */192193set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);194output_control();195gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);196}197198199/* Flash memory */200static struct flash_platform_data flash_data = {201.map_name = "cfi_probe",202.width = 2,203};204205static struct resource flash_resource = {206.flags = IORESOURCE_MEM,207};208209static struct platform_device device_flash = {210.name = "IXP4XX-Flash",211.id = 0,212.dev = { .platform_data = &flash_data },213.num_resources = 1,214.resource = &flash_resource,215};216217218/* I^2C interface */219static struct i2c_gpio_platform_data i2c_data = {220.sda_pin = GPIO_SDA,221.scl_pin = GPIO_SCL,222};223224static struct platform_device device_i2c = {225.name = "i2c-gpio",226.id = 0,227.dev = { .platform_data = &i2c_data },228};229230231/* IXP425 2 UART ports */232static struct resource uart_resources[] = {233{234.start = IXP4XX_UART1_BASE_PHYS,235.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,236.flags = IORESOURCE_MEM,237},238{239.start = IXP4XX_UART2_BASE_PHYS,240.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,241.flags = IORESOURCE_MEM,242}243};244245static struct plat_serial8250_port uart_data[] = {246{247.mapbase = IXP4XX_UART1_BASE_PHYS,248.membase = (char __iomem *)IXP4XX_UART1_BASE_VIRT +249REG_OFFSET,250.irq = IRQ_IXP4XX_UART1,251.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,252.iotype = UPIO_MEM,253.regshift = 2,254.uartclk = IXP4XX_UART_XTAL,255},256{257.mapbase = IXP4XX_UART2_BASE_PHYS,258.membase = (char __iomem *)IXP4XX_UART2_BASE_VIRT +259REG_OFFSET,260.irq = IRQ_IXP4XX_UART2,261.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,262.iotype = UPIO_MEM,263.regshift = 2,264.uartclk = IXP4XX_UART_XTAL,265},266{ },267};268269static struct platform_device device_uarts = {270.name = "serial8250",271.id = PLAT8250_DEV_PLATFORM,272.dev.platform_data = uart_data,273.num_resources = 2,274.resource = uart_resources,275};276277278/* Built-in 10/100 Ethernet MAC interfaces */279static struct eth_plat_info eth_plat[] = {280{281.phy = 0,282.rxq = 3,283.txreadyq = 32,284}, {285.phy = 1,286.rxq = 4,287.txreadyq = 33,288}289};290291static struct platform_device device_eth_tab[] = {292{293.name = "ixp4xx_eth",294.id = IXP4XX_ETH_NPEB,295.dev.platform_data = eth_plat,296}, {297.name = "ixp4xx_eth",298.id = IXP4XX_ETH_NPEC,299.dev.platform_data = eth_plat + 1,300}301};302303304/* IXP425 2 synchronous serial ports */305static struct hss_plat_info hss_plat[] = {306{307.set_clock = hss_set_clock,308.open = hss_open,309.close = hss_close,310.txreadyq = 34,311}, {312.set_clock = hss_set_clock,313.open = hss_open,314.close = hss_close,315.txreadyq = 35,316}317};318319static struct platform_device device_hss_tab[] = {320{321.name = "ixp4xx_hss",322.id = 0,323.dev.platform_data = hss_plat,324}, {325.name = "ixp4xx_hss",326.id = 1,327.dev.platform_data = hss_plat + 1,328}329};330331332static struct platform_device *device_tab[6] __initdata = {333&device_flash, /* index 0 */334};335336static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)337{338#ifdef __ARMEB__339return __raw_readb(flash + addr);340#else341return __raw_readb(flash + (addr ^ 3));342#endif343}344345static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)346{347#ifdef __ARMEB__348return __raw_readw(flash + addr);349#else350return __raw_readw(flash + (addr ^ 2));351#endif352}353354static void __init gmlr_init(void)355{356u8 __iomem *flash;357int i, devices = 1; /* flash */358359ixp4xx_sys_init();360361if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)362printk(KERN_ERR "goramo-mlr: unable to access system"363" configuration data\n");364else {365system_rev = __raw_readl(flash + CFG_REV);366hw_bits = __raw_readl(flash + CFG_HW_BITS);367368for (i = 0; i < ETH_ALEN; i++) {369eth_plat[0].hwaddr[i] =370flash_readb(flash, CFG_ETH0_ADDRESS + i);371eth_plat[1].hwaddr[i] =372flash_readb(flash, CFG_ETH1_ADDRESS + i);373}374375__raw_writew(FLASH_CMD_READ_ID, flash);376system_serial_high = flash_readw(flash, FLASH_SER_OFF);377system_serial_high <<= 16;378system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);379system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);380system_serial_low <<= 16;381system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);382__raw_writew(FLASH_CMD_READ_ARRAY, flash);383384iounmap(flash);385}386387switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {388case CFG_HW_HAS_UART0:389memset(&uart_data[1], 0, sizeof(uart_data[1]));390device_uarts.num_resources = 1;391break;392393case CFG_HW_HAS_UART1:394device_uarts.dev.platform_data = &uart_data[1];395device_uarts.resource = &uart_resources[1];396device_uarts.num_resources = 1;397break;398}399if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))400device_tab[devices++] = &device_uarts; /* max index 1 */401402if (hw_bits & CFG_HW_HAS_ETH0)403device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */404if (hw_bits & CFG_HW_HAS_ETH1)405device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */406407if (hw_bits & CFG_HW_HAS_HSS0)408device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */409if (hw_bits & CFG_HW_HAS_HSS1)410device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */411412if (hw_bits & CFG_HW_HAS_EEPROM)413device_tab[devices++] = &device_i2c; /* max index 6 */414415gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);416gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);417gpio_line_config(GPIO_STR, IXP4XX_GPIO_OUT);418gpio_line_config(GPIO_HSS0_RTS_N, IXP4XX_GPIO_OUT);419gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);420gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);421gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);422irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);423irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);424425set_control(CONTROL_HSS0_DTR_N, 1);426set_control(CONTROL_HSS1_DTR_N, 1);427set_control(CONTROL_EEPROM_WC_N, 1);428set_control(CONTROL_PCI_RESET_N, 1);429output_control();430431msleep(1); /* Wait for PCI devices to initialize */432433flash_resource.start = IXP4XX_EXP_BUS_BASE(0);434flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;435436platform_add_devices(device_tab, devices);437}438439440#ifdef CONFIG_PCI441static void __init gmlr_pci_preinit(void)442{443irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);444irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);445irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);446irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);447ixp4xx_pci_preinit();448}449450static void __init gmlr_pci_postinit(void)451{452if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&453(hw_bits & CFG_HW_USB_PORTS) < 5) {454/* need to adjust number of USB ports on NEC chip */455u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;456if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {457value &= ~7;458value |= (hw_bits & CFG_HW_USB_PORTS);459ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);460}461}462}463464static int __init gmlr_map_irq(struct pci_dev *dev, u8 slot, u8 pin)465{466switch(slot) {467case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);468case SLOT_ETHB: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);469case SLOT_NEC: return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);470default: return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);471}472}473474static struct hw_pci gmlr_hw_pci __initdata = {475.nr_controllers = 1,476.preinit = gmlr_pci_preinit,477.postinit = gmlr_pci_postinit,478.swizzle = pci_std_swizzle,479.setup = ixp4xx_setup,480.scan = ixp4xx_scan_bus,481.map_irq = gmlr_map_irq,482};483484static int __init gmlr_pci_init(void)485{486if (machine_is_goramo_mlr() &&487(hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))488pci_common_init(&gmlr_hw_pci);489return 0;490}491492subsys_initcall(gmlr_pci_init);493#endif /* CONFIG_PCI */494495496MACHINE_START(GORAMO_MLR, "MultiLink")497/* Maintainer: Krzysztof Halasa */498.map_io = ixp4xx_map_io,499.init_irq = ixp4xx_init_irq,500.timer = &ixp4xx_timer,501.boot_params = 0x0100,502.init_machine = gmlr_init,503MACHINE_END504505506