1/* 2 * arch/arm/mach-ixp2000/ixdp2400.c 3 * 4 * IXDP2400 platform support 5 * 6 * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> 7 * Maintainer: Deepak Saxena <dsaxena@plexity.net> 8 * 9 * Copyright (C) 2002 Intel Corp. 10 * Copyright (C) 2003-2004 MontaVista Software, Inc. 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the 14 * Free Software Foundation; either version 2 of the License, or (at your 15 * option) any later version. 16 */ 17#include <linux/kernel.h> 18#include <linux/init.h> 19#include <linux/mm.h> 20#include <linux/sched.h> 21#include <linux/interrupt.h> 22#include <linux/device.h> 23#include <linux/bitops.h> 24#include <linux/pci.h> 25#include <linux/ioport.h> 26#include <linux/delay.h> 27#include <linux/io.h> 28 29#include <asm/irq.h> 30#include <asm/pgtable.h> 31#include <asm/page.h> 32#include <asm/system.h> 33#include <mach/hardware.h> 34#include <asm/mach-types.h> 35 36#include <asm/mach/pci.h> 37#include <asm/mach/map.h> 38#include <asm/mach/irq.h> 39#include <asm/mach/time.h> 40#include <asm/mach/flash.h> 41#include <asm/mach/arch.h> 42 43/************************************************************************* 44 * IXDP2400 timer tick 45 *************************************************************************/ 46static void __init ixdp2400_timer_init(void) 47{ 48 int numerator, denominator; 49 int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8}; 50 51 numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2; 52 denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)]; 53 54 ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2); 55} 56 57static struct sys_timer ixdp2400_timer = { 58 .init = ixdp2400_timer_init, 59 .offset = ixp2000_gettimeoffset, 60}; 61 62/************************************************************************* 63 * IXDP2400 PCI 64 *************************************************************************/ 65void __init ixdp2400_pci_preinit(void) 66{ 67 ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); 68 ixp2000_pci_preinit(); 69 pcibios_setup("firmware"); 70} 71 72int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) 73{ 74 sys->mem_offset = 0xe0000000; 75 76 ixp2000_pci_setup(nr, sys); 77 78 return 1; 79} 80 81static int __init ixdp2400_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 82{ 83 if (ixdp2x00_master_npu()) { 84 85 /* 86 * Root bus devices. Slave NPU is only one with interrupt. 87 * Everything else, we just return -1 b/c nothing else 88 * on the root bus has interrupts. 89 */ 90 if(!dev->bus->self) { 91 if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN ) 92 return IRQ_IXDP2400_INGRESS_NPU; 93 94 return -1; 95 } 96 97 /* 98 * Bridge behind the PMC slot. 99 * NOTE: Only INTA from the PMC slot is routed. VERY BAD. 100 */ 101 if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN && 102 dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN && 103 !dev->bus->parent->self->bus->parent) 104 return IRQ_IXDP2400_PMC; 105 106 /* 107 * Device behind the first bridge 108 */ 109 if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) { 110 switch(dev->devfn) { 111 case IXDP2400_MASTER_ENET_DEVFN: 112 return IRQ_IXDP2400_ENET; 113 114 case IXDP2400_MEDIA_DEVFN: 115 return IRQ_IXDP2400_MEDIA_PCI; 116 117 case IXDP2400_SWITCH_FABRIC_DEVFN: 118 return IRQ_IXDP2400_SF_PCI; 119 120 case IXDP2X00_PMC_DEVFN: 121 return IRQ_IXDP2400_PMC; 122 } 123 } 124 125 return -1; 126 } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */ 127} 128 129 130static void ixdp2400_pci_postinit(void) 131{ 132 struct pci_dev *dev; 133 134 if (ixdp2x00_master_npu()) { 135 dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); 136 pci_remove_bus_device(dev); 137 pci_dev_put(dev); 138 } else { 139 dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); 140 pci_remove_bus_device(dev); 141 pci_dev_put(dev); 142 143 ixdp2x00_slave_pci_postinit(); 144 } 145} 146 147static struct hw_pci ixdp2400_pci __initdata = { 148 .nr_controllers = 1, 149 .setup = ixdp2400_pci_setup, 150 .preinit = ixdp2400_pci_preinit, 151 .postinit = ixdp2400_pci_postinit, 152 .scan = ixp2000_pci_scan_bus, 153 .map_irq = ixdp2400_pci_map_irq, 154}; 155 156int __init ixdp2400_pci_init(void) 157{ 158 if (machine_is_ixdp2400()) 159 pci_common_init(&ixdp2400_pci); 160 161 return 0; 162} 163 164subsys_initcall(ixdp2400_pci_init); 165 166void __init ixdp2400_init_irq(void) 167{ 168 ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS); 169} 170 171MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") 172 /* Maintainer: MontaVista Software, Inc. */ 173 .phys_io = IXP2000_UART_PHYS_BASE, 174 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, 175 .boot_params = 0x00000100, 176 .map_io = ixdp2x00_map_io, 177 .init_irq = ixdp2400_init_irq, 178 .timer = &ixdp2400_timer, 179 .init_machine = ixdp2x00_init_machine, 180MACHINE_END 181