1/* 2 * arch/arm/mach-ixp2000/pci.c 3 * 4 * PCI routines for IXDP2400/IXDP2800 boards 5 * 6 * Original Author: Naeem Afzal <naeem.m.afzal@intel.com> 7 * Maintained by: Deepak Saxena <dsaxena@plexity.net> 8 * 9 * Copyright 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 18#include <linux/sched.h> 19#include <linux/kernel.h> 20#include <linux/pci.h> 21#include <linux/interrupt.h> 22#include <linux/mm.h> 23#include <linux/init.h> 24#include <linux/ioport.h> 25#include <linux/slab.h> 26#include <linux/delay.h> 27 28#include <asm/io.h> 29#include <asm/irq.h> 30#include <asm/system.h> 31#include <asm/hardware.h> 32 33#include <asm/mach/pci.h> 34 35static volatile int pci_master_aborts = 0; 36 37static int clear_master_aborts(void); 38 39u32 * 40ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where) 41{ 42 u32 *paddress; 43 44 if (PCI_SLOT(devfn) > 7) 45 return 0; 46 47 /* Must be dword aligned */ 48 where &= ~3; 49 50 /* 51 * For top bus, generate type 0, else type 1 52 */ 53 if (!bus_nr) { 54 /* only bits[23:16] are used for IDSEL */ 55 paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE 56 | (1 << (PCI_SLOT(devfn) + 16)) 57 | (PCI_FUNC(devfn) << 8) | where); 58 } else { 59 paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE 60 | (bus_nr << 16) 61 | (PCI_SLOT(devfn) << 11) 62 | (PCI_FUNC(devfn) << 8) | where); 63 } 64 65 return paddress; 66} 67 68/* 69 * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes. 70 * 0 and 3 are not valid indexes... 71 */ 72static u32 bytemask[] = { 73 /*0*/ 0, 74 /*1*/ 0xff, 75 /*2*/ 0xffff, 76 /*3*/ 0, 77 /*4*/ 0xffffffff, 78}; 79 80 81int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, 82 int size, u32 *value) 83{ 84 u32 n; 85 u32 *addr; 86 87 n = where % 4; 88 89 addr = ixp2000_pci_config_addr(bus->number, devfn, where); 90 if (!addr) 91 return PCIBIOS_DEVICE_NOT_FOUND; 92 93 pci_master_aborts = 0; 94 *value = (*addr >> (8*n)) & bytemask[size]; 95 if (pci_master_aborts) { 96 pci_master_aborts = 0; 97 *value = 0xffffffff; 98 return PCIBIOS_DEVICE_NOT_FOUND; 99 } 100 101 return PCIBIOS_SUCCESSFUL; 102} 103 104/* 105 * We don't do error checks by calling clear_master_aborts() b/c the 106 * assumption is that the caller did a read first to make sure a device 107 * exists. 108 */ 109int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, 110 int size, u32 value) 111{ 112 u32 mask; 113 u32 *addr; 114 u32 temp; 115 116 mask = ~(bytemask[size] << ((where % 0x4) * 8)); 117 addr = ixp2000_pci_config_addr(bus->number, devfn, where); 118 if (!addr) 119 return PCIBIOS_DEVICE_NOT_FOUND; 120 temp = (u32) (value) << ((where % 0x4) * 8); 121 *addr = (*addr & mask) | temp; 122 123 clear_master_aborts(); 124 125 return PCIBIOS_SUCCESSFUL; 126} 127 128 129static struct pci_ops ixp2000_pci_ops = { 130 .read = ixp2000_pci_read_config, 131 .write = ixp2000_pci_write_config 132}; 133 134struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata) 135{ 136 return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata); 137} 138 139 140int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 141{ 142 143 volatile u32 temp; 144 unsigned long flags; 145 146 pci_master_aborts = 1; 147 148 local_irq_save(flags); 149 temp = *(IXP2000_PCI_CONTROL); 150 if (temp & ((1 << 8) | (1 << 5))) { 151 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); 152 } 153 154 temp = *(IXP2000_PCI_CMDSTAT); 155 if (temp & (1 << 29)) { 156 while (temp & (1 << 29)) { 157 ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); 158 temp = *(IXP2000_PCI_CMDSTAT); 159 } 160 } 161 local_irq_restore(flags); 162 163 /* 164 * If it was an imprecise abort, then we need to correct the 165 * return address to be _after_ the instruction. 166 */ 167 if (fsr & (1 << 10)) 168 regs->ARM_pc += 4; 169 170 return 0; 171} 172 173int 174clear_master_aborts(void) 175{ 176 volatile u32 temp; 177 unsigned long flags; 178 179 local_irq_save(flags); 180 temp = *(IXP2000_PCI_CONTROL); 181 if (temp & ((1 << 8) | (1 << 5))) { 182 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp); 183 } 184 185 temp = *(IXP2000_PCI_CMDSTAT); 186 if (temp & (1 << 29)) { 187 while (temp & (1 << 29)) { 188 ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp); 189 temp = *(IXP2000_PCI_CMDSTAT); 190 } 191 } 192 local_irq_restore(flags); 193 194 return 0; 195} 196 197void __init 198ixp2000_pci_preinit(void) 199{ 200#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO 201 /* 202 * Configure the PCI unit to properly byteswap I/O transactions, 203 * and verify that it worked. 204 */ 205 ixp2000_reg_write(IXP2000_PCI_CONTROL, 206 (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); 207 208 if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) 209 panic("IXP2000: PCI I/O is broken on this ixp model, and " 210 "the needed workaround has not been configured in"); 211#endif 212 213 hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 214 "PCI config cycle to non-existent device"); 215} 216 217 218/* 219 * IXP2000 systems often have large resource requirements, so we just 220 * use our own resource space. 221 */ 222static struct resource ixp2000_pci_mem_space = { 223 .start = 0xe0000000, 224 .end = 0xffffffff, 225 .flags = IORESOURCE_MEM, 226 .name = "PCI Mem Space" 227}; 228 229static struct resource ixp2000_pci_io_space = { 230 .start = 0x00010000, 231 .end = 0x0001ffff, 232 .flags = IORESOURCE_IO, 233 .name = "PCI I/O Space" 234}; 235 236int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) 237{ 238 if (nr >= 1) 239 return 0; 240 241 sys->resource[0] = &ixp2000_pci_io_space; 242 sys->resource[1] = &ixp2000_pci_mem_space; 243 sys->resource[2] = NULL; 244 245 return 1; 246} 247