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