1/* 2 * arch/arm/mach-ixp2000/enp2611.c 3 * 4 * Radisys ENP-2611 support. 5 * 6 * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The 7 * original version carries the following notices: 8 * 9 * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com> 10 * Maintainer: Deepak Saxena <dsaxena@plexity.net> 11 * 12 * Copyright (C) 2002-2003 Intel Corp. 13 * Copyright (C) 2003-2004 MontaVista Software, Inc. 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 */ 20 21#include <linux/kernel.h> 22#include <linux/init.h> 23#include <linux/mm.h> 24#include <linux/sched.h> 25#include <linux/interrupt.h> 26#include <linux/bitops.h> 27#include <linux/pci.h> 28#include <linux/ioport.h> 29#include <linux/delay.h> 30#include <linux/serial.h> 31#include <linux/tty.h> 32#include <linux/serial_core.h> 33#include <linux/platform_device.h> 34#include <linux/io.h> 35 36#include <asm/irq.h> 37#include <asm/pgtable.h> 38#include <asm/page.h> 39#include <asm/system.h> 40#include <mach/hardware.h> 41#include <asm/mach-types.h> 42 43#include <asm/mach/pci.h> 44#include <asm/mach/map.h> 45#include <asm/mach/irq.h> 46#include <asm/mach/time.h> 47#include <asm/mach/arch.h> 48#include <asm/mach/flash.h> 49 50/************************************************************************* 51 * ENP-2611 timer tick configuration 52 *************************************************************************/ 53static void __init enp2611_timer_init(void) 54{ 55 ixp2000_init_time(50 * 1000 * 1000); 56} 57 58static struct sys_timer enp2611_timer = { 59 .init = enp2611_timer_init, 60 .offset = ixp2000_gettimeoffset, 61}; 62 63 64/************************************************************************* 65 * ENP-2611 I/O 66 *************************************************************************/ 67static struct map_desc enp2611_io_desc[] __initdata = { 68 { 69 .virtual = ENP2611_CALEB_VIRT_BASE, 70 .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE), 71 .length = ENP2611_CALEB_SIZE, 72 .type = MT_DEVICE, 73 }, { 74 .virtual = ENP2611_PM3386_0_VIRT_BASE, 75 .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE), 76 .length = ENP2611_PM3386_0_SIZE, 77 .type = MT_DEVICE, 78 }, { 79 .virtual = ENP2611_PM3386_1_VIRT_BASE, 80 .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE), 81 .length = ENP2611_PM3386_1_SIZE, 82 .type = MT_DEVICE, 83 } 84}; 85 86void __init enp2611_map_io(void) 87{ 88 ixp2000_map_io(); 89 iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc)); 90} 91 92 93/************************************************************************* 94 * ENP-2611 PCI 95 *************************************************************************/ 96static int enp2611_pci_setup(int nr, struct pci_sys_data *sys) 97{ 98 sys->mem_offset = 0xe0000000; 99 ixp2000_pci_setup(nr, sys); 100 return 1; 101} 102 103static void __init enp2611_pci_preinit(void) 104{ 105 ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); 106 ixp2000_pci_preinit(); 107 pcibios_setup("firmware"); 108} 109 110static inline int enp2611_pci_valid_device(struct pci_bus *bus, 111 unsigned int devfn) 112{ 113 /* The 82559 ethernet controller appears at both PCI:1:0:0 and 114 * PCI:1:2:0, so let's pretend the second one isn't there. 115 */ 116 if (bus->number == 0x01 && devfn == 0x10) 117 return 0; 118 119 return 1; 120} 121 122static int enp2611_pci_read_config(struct pci_bus *bus, unsigned int devfn, 123 int where, int size, u32 *value) 124{ 125 if (enp2611_pci_valid_device(bus, devfn)) 126 return ixp2000_pci_read_config(bus, devfn, where, size, value); 127 128 return PCIBIOS_DEVICE_NOT_FOUND; 129} 130 131static int enp2611_pci_write_config(struct pci_bus *bus, unsigned int devfn, 132 int where, int size, u32 value) 133{ 134 if (enp2611_pci_valid_device(bus, devfn)) 135 return ixp2000_pci_write_config(bus, devfn, where, size, value); 136 137 return PCIBIOS_DEVICE_NOT_FOUND; 138} 139 140static struct pci_ops enp2611_pci_ops = { 141 .read = enp2611_pci_read_config, 142 .write = enp2611_pci_write_config 143}; 144 145static struct pci_bus * __init enp2611_pci_scan_bus(int nr, 146 struct pci_sys_data *sys) 147{ 148 return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys); 149} 150 151static int __init enp2611_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 152{ 153 int irq; 154 155 if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) { 156 /* IXP2400. */ 157 irq = IRQ_IXP2000_PCIA; 158 } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) { 159 /* 21555 non-transparent bridge. */ 160 irq = IRQ_IXP2000_PCIB; 161 } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) { 162 /* PCI2050B transparent bridge. */ 163 irq = -1; 164 } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) { 165 /* 82559 ethernet. */ 166 irq = IRQ_IXP2000_PCIA; 167 } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) { 168 /* SPI-3 option board. */ 169 irq = IRQ_IXP2000_PCIB; 170 } else { 171 printk(KERN_ERR "enp2611_pci_map_irq() called for unknown " 172 "device PCI:%d:%d:%d\n", dev->bus->number, 173 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 174 irq = -1; 175 } 176 177 return irq; 178} 179 180struct hw_pci enp2611_pci __initdata = { 181 .nr_controllers = 1, 182 .setup = enp2611_pci_setup, 183 .preinit = enp2611_pci_preinit, 184 .scan = enp2611_pci_scan_bus, 185 .map_irq = enp2611_pci_map_irq, 186}; 187 188int __init enp2611_pci_init(void) 189{ 190 if (machine_is_enp2611()) 191 pci_common_init(&enp2611_pci); 192 193 return 0; 194} 195 196subsys_initcall(enp2611_pci_init); 197 198 199/************************************************************************* 200 * ENP-2611 Machine Initialization 201 *************************************************************************/ 202static struct flash_platform_data enp2611_flash_platform_data = { 203 .map_name = "cfi_probe", 204 .width = 1, 205}; 206 207static struct ixp2000_flash_data enp2611_flash_data = { 208 .platform_data = &enp2611_flash_platform_data, 209 .nr_banks = 1 210}; 211 212static struct resource enp2611_flash_resource = { 213 .start = 0xc4000000, 214 .end = 0xc4000000 + 0x00ffffff, 215 .flags = IORESOURCE_MEM, 216}; 217 218static struct platform_device enp2611_flash = { 219 .name = "IXP2000-Flash", 220 .id = 0, 221 .dev = { 222 .platform_data = &enp2611_flash_data, 223 }, 224 .num_resources = 1, 225 .resource = &enp2611_flash_resource, 226}; 227 228static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = { 229 .sda_pin = ENP2611_GPIO_SDA, 230 .scl_pin = ENP2611_GPIO_SCL, 231}; 232 233static struct platform_device enp2611_i2c_controller = { 234 .name = "IXP2000-I2C", 235 .id = 0, 236 .dev = { 237 .platform_data = &enp2611_i2c_gpio_pins 238 }, 239 .num_resources = 0 240}; 241 242static struct platform_device *enp2611_devices[] __initdata = { 243 &enp2611_flash, 244 &enp2611_i2c_controller 245}; 246 247static void __init enp2611_init_machine(void) 248{ 249 platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices)); 250 ixp2000_uart_init(); 251} 252 253 254MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") 255 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ 256 .phys_io = IXP2000_UART_PHYS_BASE, 257 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, 258 .boot_params = 0x00000100, 259 .map_io = enp2611_map_io, 260 .init_irq = ixp2000_init_irq, 261 .timer = &enp2611_timer, 262 .init_machine = enp2611_init_machine, 263MACHINE_END 264