1/* 2 * linux/arch/arm/mach-sa1100/pci-nanoengine.c 3 * 4 * PCI functions for BSE nanoEngine PCI 5 * 6 * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22#include <linux/kernel.h> 23#include <linux/irq.h> 24#include <linux/pci.h> 25 26#include <asm/mach/pci.h> 27#include <asm/mach-types.h> 28 29#include <mach/nanoengine.h> 30#include <mach/hardware.h> 31 32static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus, 33 unsigned int devfn, int where) 34{ 35 if (bus->number != 0 || (devfn >> 3) != 0) 36 return NULL; 37 38 return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT + 39 ((bus->number << 16) | (devfn << 8) | (where & ~3)); 40} 41 42static struct pci_ops pci_nano_ops = { 43 .map_bus = nanoengine_pci_map_bus, 44 .read = pci_generic_config_read32, 45 .write = pci_generic_config_write32, 46}; 47 48static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot, 49 u8 pin) 50{ 51 return NANOENGINE_IRQ_GPIO_PCI; 52} 53 54static struct resource pci_io_ports = 55 DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); 56 57static struct resource pci_non_prefetchable_memory = { 58 .name = "PCI non-prefetchable", 59 .start = NANO_PCI_MEM_RW_PHYS, 60 /* nanoEngine documentation says there is a 1 Megabyte window here, 61 * but PCI reports just 128 + 8 kbytes. */ 62 .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1, 63/* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/ 64 .flags = IORESOURCE_MEM, 65}; 66 67/* 68 * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it 69 * overlaps with previously defined memory. 70 * 71 * Here is what happens: 72 * 73# dmesg 74... 75pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 76pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] 77pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] 78pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] 79pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] 80pci 0000:00:00.0: supports D1 D2 81pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot 82pci 0000:00:00.0: PME# disabled 83PCI: bus0: Fast back to back transfers enabled 84pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000) 85pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] 86pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) 87pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] 88pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) 89pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] 90pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) 91 * 92 * On the other hand, if we do not request the prefetchable memory resource, 93 * linux will alloc it first and the two non-prefetchable memory areas that 94 * are our real interest will not be mapped. So we choose to map it to an 95 * unused area. It gets recognized as expansion ROM, but becomes disabled. 96 * 97 * Here is what happens then: 98 * 99# dmesg 100... 101pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 102pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] 103pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] 104pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] 105pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] 106pci 0000:00:00.0: supports D1 D2 107pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot 108pci 0000:00:00.0: PME# disabled 109PCI: bus0: Fast back to back transfers enabled 110pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref] 111pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] 112pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) 113pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] 114pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) 115pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] 116pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) 117 118# lspci -vv -s 0000:00:00.0 11900:00.0 Class 0200: Device 8086:1209 (rev 09) 120 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx- 121 Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx- 122 Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes 123 Interrupt: pin A routed to IRQ 0 124 Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K] 125 Region 1: I/O ports at 0400 [size=64] 126 Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K] 127 [virtual] Expansion ROM at 78000000 [disabled] [size=1M] 128 Capabilities: [dc] Power Management version 2 129 Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-) 130 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME- 131 Kernel driver in use: e100 132 Kernel modules: e100 133 * 134 */ 135static struct resource pci_prefetchable_memory = { 136 .name = "PCI prefetchable", 137 .start = 0x78000000, 138 .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1, 139 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, 140}; 141 142static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys) 143{ 144 if (request_resource(&ioport_resource, &pci_io_ports)) { 145 printk(KERN_ERR "PCI: unable to allocate io port region\n"); 146 return -EBUSY; 147 } 148 if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) { 149 release_resource(&pci_io_ports); 150 printk(KERN_ERR "PCI: unable to allocate non prefetchable\n"); 151 return -EBUSY; 152 } 153 if (request_resource(&iomem_resource, &pci_prefetchable_memory)) { 154 release_resource(&pci_io_ports); 155 release_resource(&pci_non_prefetchable_memory); 156 printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); 157 return -EBUSY; 158 } 159 pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset); 160 pci_add_resource_offset(&sys->resources, 161 &pci_non_prefetchable_memory, sys->mem_offset); 162 pci_add_resource_offset(&sys->resources, 163 &pci_prefetchable_memory, sys->mem_offset); 164 165 return 1; 166} 167 168int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) 169{ 170 int ret = 0; 171 172 pcibios_min_io = 0; 173 pcibios_min_mem = 0; 174 175 if (nr == 0) { 176 sys->mem_offset = NANO_PCI_MEM_RW_PHYS; 177 sys->io_offset = 0x400; 178 ret = pci_nanoengine_setup_resources(sys); 179 /* Enable alternate memory bus master mode, see 180 * "Intel StrongARM SA1110 Developer's Manual", 181 * section 10.8, "Alternate Memory Bus Master Mode". */ 182 GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; 183 GAFR |= GPIO_MBGNT | GPIO_MBREQ; 184 TUCR |= TUCR_MBGPIO; 185 } 186 187 return ret; 188} 189 190static struct hw_pci nanoengine_pci __initdata = { 191 .map_irq = pci_nanoengine_map_irq, 192 .nr_controllers = 1, 193 .ops = &pci_nano_ops, 194 .setup = pci_nanoengine_setup, 195}; 196 197static int __init nanoengine_pci_init(void) 198{ 199 if (machine_is_nanoengine()) 200 pci_common_init(&nanoengine_pci); 201 return 0; 202} 203 204subsys_initcall(nanoengine_pci_init); 205