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