1/* 2 * arch/arm/mach-ixp23xx/pci.c 3 * 4 * PCI routines for IXP23XX based systems 5 * 6 * Copyright (c) 2005 MontaVista Software, Inc. 7 * 8 * based on original code: 9 * 10 * Author: Naeem Afzal <naeem.m.afzal@intel.com> 11 * Copyright 2002-2005 Intel Corp. 12 * 13 * This program is free software; you can redistribute it and/or modify it 14 * under the terms of the GNU General Public License as published by the 15 * Free Software Foundation; either version 2 of the License, or (at your 16 * option) any later version. 17 */ 18 19#include <linux/sched.h> 20#include <linux/kernel.h> 21#include <linux/pci.h> 22#include <linux/interrupt.h> 23#include <linux/mm.h> 24#include <linux/init.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/sizes.h> 31#include <asm/system.h> 32#include <asm/mach/pci.h> 33#include <mach/hardware.h> 34 35extern int (*external_fault) (unsigned long, struct pt_regs *); 36 37static volatile int pci_master_aborts = 0; 38 39#ifdef DEBUG 40#define DBG(x...) printk(x) 41#else 42#define DBG(x...) 43#endif 44 45int clear_master_aborts(void); 46 47static u32 48*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) 49{ 50 u32 *paddress; 51 52 /* 53 * Must be dword aligned 54 */ 55 where &= ~3; 56 57 /* 58 * For top bus, generate type 0, else type 1 59 */ 60 if (!bus_nr) { 61 if (PCI_SLOT(devfn) >= 8) 62 return 0; 63 64 paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT 65 | (1 << (PCI_SLOT(devfn) + 16)) 66 | (PCI_FUNC(devfn) << 8) | where); 67 } else { 68 paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT 69 | (bus_nr << 16) 70 | (PCI_SLOT(devfn) << 11) 71 | (PCI_FUNC(devfn) << 8) | where); 72 } 73 74 return paddress; 75} 76 77/* 78 * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. 79 * 0 and 3 are not valid indexes... 80 */ 81static u32 bytemask[] = { 82 /*0*/ 0, 83 /*1*/ 0xff, 84 /*2*/ 0xffff, 85 /*3*/ 0, 86 /*4*/ 0xffffffff, 87}; 88 89static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, 90 int where, int size, u32 *value) 91{ 92 u32 n; 93 u32 *addr; 94 95 n = where % 4; 96 97 DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where, 98 bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); 99 100 addr = ixp23xx_pci_config_addr(bus->number, devfn, where); 101 if (!addr) 102 return PCIBIOS_DEVICE_NOT_FOUND; 103 104 pci_master_aborts = 0; 105 *value = (*addr >> (8*n)) & bytemask[size]; 106 if (pci_master_aborts) { 107 pci_master_aborts = 0; 108 *value = 0xffffffff; 109 return PCIBIOS_DEVICE_NOT_FOUND; 110 } 111 112 return PCIBIOS_SUCCESSFUL; 113} 114 115/* 116 * We don't do error checking on the address for writes. 117 * It's assumed that the user checked for the device existing first 118 * by doing a read first. 119 */ 120static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, 121 int where, int size, u32 value) 122{ 123 u32 mask; 124 u32 *addr; 125 u32 temp; 126 127 mask = ~(bytemask[size] << ((where % 0x4) * 8)); 128 addr = ixp23xx_pci_config_addr(bus->number, devfn, where); 129 if (!addr) 130 return PCIBIOS_DEVICE_NOT_FOUND; 131 temp = (u32) (value) << ((where % 0x4) * 8); 132 *addr = (*addr & mask) | temp; 133 134 clear_master_aborts(); 135 136 return PCIBIOS_SUCCESSFUL; 137} 138 139struct pci_ops ixp23xx_pci_ops = { 140 .read = ixp23xx_pci_read_config, 141 .write = ixp23xx_pci_write_config, 142}; 143 144struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata) 145{ 146 return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata); 147} 148 149int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 150{ 151 volatile unsigned long temp; 152 unsigned long flags; 153 154 pci_master_aborts = 1; 155 156 local_irq_save(flags); 157 temp = *IXP23XX_PCI_CONTROL; 158 159 /* 160 * master abort and cmd tgt err 161 */ 162 if (temp & ((1 << 8) | (1 << 5))) 163 *IXP23XX_PCI_CONTROL = temp; 164 165 temp = *IXP23XX_PCI_CMDSTAT; 166 167 if (temp & (1 << 29)) 168 *IXP23XX_PCI_CMDSTAT = temp; 169 local_irq_restore(flags); 170 171 /* 172 * If it was an imprecise abort, then we need to correct the 173 * return address to be _after_ the instruction. 174 */ 175 if (fsr & (1 << 10)) 176 regs->ARM_pc += 4; 177 178 return 0; 179} 180 181int clear_master_aborts(void) 182{ 183 volatile u32 temp; 184 185 temp = *IXP23XX_PCI_CONTROL; 186 187 /* 188 * master abort and cmd tgt err 189 */ 190 if (temp & ((1 << 8) | (1 << 5))) 191 *IXP23XX_PCI_CONTROL = temp; 192 193 temp = *IXP23XX_PCI_CMDSTAT; 194 195 if (temp & (1 << 29)) 196 *IXP23XX_PCI_CMDSTAT = temp; 197 198 return 0; 199} 200 201static void __init ixp23xx_pci_common_init(void) 202{ 203#ifdef __ARMEB__ 204 *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */ 205#endif 206 /* 207 * ADDR_31 needs to be clear for PCI memory access to CPP memory 208 */ 209 *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31; 210 *IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF; 211 212 /* 213 * Select correct memory for PCI inbound transactions 214 */ 215 if (ixp23xx_cpp_boot()) { 216 *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1); 217 } else { 218 *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1); 219 220 /* 221 * Enable coherency on A2 silicon. 222 */ 223 if (arch_is_coherent()) 224 *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF; 225 } 226} 227 228void __init ixp23xx_pci_preinit(void) 229{ 230 ixp23xx_pci_common_init(); 231 232 hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0, 233 "PCI config cycle to non-existent device"); 234 235 *IXP23XX_PCI_ADDR_EXT = 0x0000e000; 236} 237 238/* 239 * Prevent PCI layer from seeing the inbound host-bridge resources 240 */ 241static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev) 242{ 243 int i; 244 245 dev->class &= 0xff; 246 dev->class |= PCI_CLASS_BRIDGE_HOST << 8; 247 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 248 dev->resource[i].start = 0; 249 dev->resource[i].end = 0; 250 dev->resource[i].flags = 0; 251 } 252} 253DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx); 254 255/* 256 * IXP2300 systems often have large resource requirements, so we just 257 * use our own resource space. 258 */ 259static struct resource ixp23xx_pci_mem_space = { 260 .start = IXP23XX_PCI_MEM_START, 261 .end = IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1, 262 .flags = IORESOURCE_MEM, 263 .name = "PCI Mem Space" 264}; 265 266static struct resource ixp23xx_pci_io_space = { 267 .start = 0x00000100, 268 .end = 0x01ffffff, 269 .flags = IORESOURCE_IO, 270 .name = "PCI I/O Space" 271}; 272 273int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) 274{ 275 if (nr >= 1) 276 return 0; 277 278 sys->resource[0] = &ixp23xx_pci_io_space; 279 sys->resource[1] = &ixp23xx_pci_mem_space; 280 sys->resource[2] = NULL; 281 282 return 1; 283} 284 285void __init ixp23xx_pci_slave_init(void) 286{ 287 ixp23xx_pci_common_init(); 288} 289