diff options
| -rw-r--r-- | arch/arm/Kconfig | 8 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/hardware.h | 8 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/nanoengine.h | 22 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/nanoengine.c | 13 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/pci-nanoengine.c | 284 |
7 files changed, 334 insertions, 4 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a19a5266d5fc..6af6c79ade2e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -1164,7 +1164,7 @@ config ISA_DMA_API | |||
| 1164 | bool | 1164 | bool |
| 1165 | 1165 | ||
| 1166 | config PCI | 1166 | config PCI |
| 1167 | bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX | 1167 | bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695 || MACH_ARMCORE || ARCH_CNS3XXX || SA1100_NANOENGINE |
| 1168 | help | 1168 | help |
| 1169 | Find out whether you have a PCI motherboard. PCI is the name of a | 1169 | Find out whether you have a PCI motherboard. PCI is the name of a |
| 1170 | bus system, i.e. the way the CPU talks to the other stuff inside | 1170 | bus system, i.e. the way the CPU talks to the other stuff inside |
| @@ -1175,6 +1175,12 @@ config PCI_DOMAINS | |||
| 1175 | bool | 1175 | bool |
| 1176 | depends on PCI | 1176 | depends on PCI |
| 1177 | 1177 | ||
| 1178 | config PCI_NANOENGINE | ||
| 1179 | bool "BSE nanoEngine PCI support" | ||
| 1180 | depends on SA1100_NANOENGINE | ||
| 1181 | help | ||
| 1182 | Enable PCI on the BSE nanoEngine board. | ||
| 1183 | |||
| 1178 | config PCI_SYSCALL | 1184 | config PCI_SYSCALL |
| 1179 | def_bool PCI | 1185 | def_bool PCI |
| 1180 | 1186 | ||
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index 3563d4637f6e..42625e4d949a 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig | |||
| @@ -121,6 +121,8 @@ config SA1100_LART | |||
| 121 | config SA1100_NANOENGINE | 121 | config SA1100_NANOENGINE |
| 122 | bool "nanoEngine" | 122 | bool "nanoEngine" |
| 123 | select CPU_FREQ_SA1110 | 123 | select CPU_FREQ_SA1110 |
| 124 | select PCI | ||
| 125 | select PCI_NANOENGINE | ||
| 124 | help | 126 | help |
| 125 | Say Y here if you are using the Bright Star Engineering nanoEngine. | 127 | Say Y here if you are using the Bright Star Engineering nanoEngine. |
| 126 | See <http://www.brightstareng.com/arm/nanoeng.htm> for information | 128 | See <http://www.brightstareng.com/arm/nanoeng.htm> for information |
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index 8029fe25bfcc..e697691eed28 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile | |||
| @@ -38,6 +38,7 @@ obj-$(CONFIG_SA1100_LART) += lart.o | |||
| 38 | led-$(CONFIG_SA1100_LART) += leds-lart.o | 38 | led-$(CONFIG_SA1100_LART) += leds-lart.o |
| 39 | 39 | ||
| 40 | obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o | 40 | obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o |
| 41 | obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o | ||
| 41 | 42 | ||
| 42 | obj-$(CONFIG_SA1100_PLEB) += pleb.o | 43 | obj-$(CONFIG_SA1100_PLEB) += pleb.o |
| 43 | 44 | ||
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h index 99f5856d8de4..967ae7684390 100644 --- a/arch/arm/mach-sa1100/include/mach/hardware.h +++ b/arch/arm/mach-sa1100/include/mach/hardware.h | |||
| @@ -76,4 +76,12 @@ static inline unsigned long get_clock_tick_rate(void) | |||
| 76 | #include "SA-1101.h" | 76 | #include "SA-1101.h" |
| 77 | #endif | 77 | #endif |
| 78 | 78 | ||
| 79 | #if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI) | ||
| 80 | #define PCIBIOS_MIN_IO 0 | ||
| 81 | #define PCIBIOS_MIN_MEM 0 | ||
| 82 | #define pcibios_assign_all_busses() 1 | ||
| 83 | #define HAVE_ARCH_PCI_SET_DMA_MASK 1 | ||
| 84 | #endif | ||
| 85 | |||
| 86 | |||
| 79 | #endif /* _ASM_ARCH_HARDWARE_H */ | 87 | #endif /* _ASM_ARCH_HARDWARE_H */ |
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h index 053776645526..14f8382d0665 100644 --- a/arch/arm/mach-sa1100/include/mach/nanoengine.h +++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #ifndef __ASM_ARCH_NANOENGINE_H | 14 | #ifndef __ASM_ARCH_NANOENGINE_H |
| 15 | #define __ASM_ARCH_NANOENGINE_H | 15 | #define __ASM_ARCH_NANOENGINE_H |
| 16 | 16 | ||
| 17 | #include <mach/irqs.h> | ||
| 18 | |||
| 17 | #define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ | 19 | #define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/ |
| 18 | #define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ | 20 | #define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */ |
| 19 | #define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ | 21 | #define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */ |
| @@ -21,10 +23,30 @@ | |||
| 21 | #define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ | 23 | #define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */ |
| 22 | #define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ | 24 | #define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */ |
| 23 | 25 | ||
| 26 | #define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0 | ||
| 24 | #define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 | 27 | #define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11 |
| 25 | #define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12 | 28 | #define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12 |
| 26 | #define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13 | 29 | #define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13 |
| 27 | #define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14 | 30 | #define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14 |
| 28 | 31 | ||
| 32 | /* | ||
| 33 | * nanoEngine Memory Map: | ||
| 34 | * | ||
| 35 | * 0000.0000 - 003F.0000 - 4 MB Flash | ||
| 36 | * C000.0000 - C1FF.FFFF - 32 MB SDRAM | ||
| 37 | * 1860.0000 - 186F.FFFF - 1 MB Internal PCI Memory Read/Write | ||
| 38 | * 18A1.0000 - 18A1.FFFF - 64 KB Internal PCI Config Space | ||
| 39 | * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode | ||
| 40 | * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode | ||
| 41 | * | ||
| 42 | */ | ||
| 43 | |||
| 44 | #define NANO_PCI_MEM_RW_PHYS 0x18600000 | ||
| 45 | #define NANO_PCI_MEM_RW_VIRT 0xf1000000 | ||
| 46 | #define NANO_PCI_MEM_RW_SIZE SZ_1M | ||
| 47 | #define NANO_PCI_CONFIG_SPACE_PHYS 0x18A10000 | ||
| 48 | #define NANO_PCI_CONFIG_SPACE_VIRT 0xf2000000 | ||
| 49 | #define NANO_PCI_CONFIG_SPACE_SIZE SZ_64K | ||
| 50 | |||
| 29 | #endif | 51 | #endif |
| 30 | 52 | ||
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c index 844ec61415a7..72087f0658b7 100644 --- a/arch/arm/mach-sa1100/nanoengine.c +++ b/arch/arm/mach-sa1100/nanoengine.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <asm/mach/serial_sa1100.h> | 26 | #include <asm/mach/serial_sa1100.h> |
| 27 | 27 | ||
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include <mach/nanoengine.h> | ||
| 29 | 30 | ||
| 30 | #include "generic.h" | 31 | #include "generic.h" |
| 31 | 32 | ||
| @@ -75,10 +76,16 @@ static struct map_desc nanoengine_io_desc[] __initdata = { | |||
| 75 | .length = 0x00100000, | 76 | .length = 0x00100000, |
| 76 | .type = MT_DEVICE | 77 | .type = MT_DEVICE |
| 77 | }, { | 78 | }, { |
| 79 | /* Internal PCI Memory Read/Write */ | ||
| 80 | .virtual = NANO_PCI_MEM_RW_VIRT, | ||
| 81 | .pfn = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS), | ||
| 82 | .length = NANO_PCI_MEM_RW_SIZE, | ||
| 83 | .type = MT_DEVICE | ||
| 84 | }, { | ||
| 78 | /* Internal PCI Config Space */ | 85 | /* Internal PCI Config Space */ |
| 79 | .virtual = 0xf1000000, | 86 | .virtual = NANO_PCI_CONFIG_SPACE_VIRT, |
| 80 | .pfn = __phys_to_pfn(0x18A00000), | 87 | .pfn = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS), |
| 81 | .length = 0x00100000, | 88 | .length = NANO_PCI_CONFIG_SPACE_SIZE, |
| 82 | .type = MT_DEVICE | 89 | .type = MT_DEVICE |
| 83 | } | 90 | } |
| 84 | }; | 91 | }; |
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c new file mode 100644 index 000000000000..fba7a913f12b --- /dev/null +++ b/arch/arm/mach-sa1100/pci-nanoengine.c | |||
| @@ -0,0 +1,284 @@ | |||
| 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 | #include <linux/spinlock.h> | ||
| 26 | |||
| 27 | #include <asm/mach/pci.h> | ||
| 28 | #include <asm/mach-types.h> | ||
| 29 | |||
| 30 | #include <mach/nanoengine.h> | ||
| 31 | |||
| 32 | static DEFINE_SPINLOCK(nano_lock); | ||
| 33 | |||
| 34 | static int nanoengine_get_pci_address(struct pci_bus *bus, | ||
| 35 | unsigned int devfn, int where, unsigned long *address) | ||
| 36 | { | ||
| 37 | int ret = PCIBIOS_DEVICE_NOT_FOUND; | ||
| 38 | unsigned int busnr = bus->number; | ||
| 39 | |||
| 40 | *address = NANO_PCI_CONFIG_SPACE_VIRT + | ||
| 41 | ((bus->number << 16) | (devfn << 8) | (where & ~3)); | ||
| 42 | |||
| 43 | ret = (busnr > 255 || devfn > 255 || where > 255) ? | ||
| 44 | PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | ||
| 45 | |||
| 46 | return ret; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 50 | int size, u32 *val) | ||
| 51 | { | ||
| 52 | int ret; | ||
| 53 | unsigned long address; | ||
| 54 | unsigned long flags; | ||
| 55 | u32 v; | ||
| 56 | |||
| 57 | /* nanoEngine PCI bridge does not return -1 for a non-existing | ||
| 58 | * device. We must fake the answer. We know that the only valid | ||
| 59 | * device is device zero at bus 0, which is the network chip. */ | ||
| 60 | if (bus->number != 0 || (devfn >> 3) != 0) { | ||
| 61 | v = -1; | ||
| 62 | nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 63 | goto exit_function; | ||
| 64 | } | ||
| 65 | |||
| 66 | spin_lock_irqsave(&nano_lock, flags); | ||
| 67 | |||
| 68 | ret = nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 69 | if (ret != PCIBIOS_SUCCESSFUL) | ||
| 70 | return ret; | ||
| 71 | v = __raw_readl(address); | ||
| 72 | |||
| 73 | spin_unlock_irqrestore(&nano_lock, flags); | ||
| 74 | |||
| 75 | v >>= ((where & 3) * 8); | ||
| 76 | v &= (unsigned long)(-1) >> ((4 - size) * 8); | ||
| 77 | |||
| 78 | exit_function: | ||
| 79 | *val = v; | ||
| 80 | return PCIBIOS_SUCCESSFUL; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 84 | int size, u32 val) | ||
| 85 | { | ||
| 86 | int ret; | ||
| 87 | unsigned long address; | ||
| 88 | unsigned long flags; | ||
| 89 | unsigned shift; | ||
| 90 | u32 v; | ||
| 91 | |||
| 92 | shift = (where & 3) * 8; | ||
| 93 | |||
| 94 | spin_lock_irqsave(&nano_lock, flags); | ||
| 95 | |||
| 96 | ret = nanoengine_get_pci_address(bus, devfn, where, &address); | ||
| 97 | if (ret != PCIBIOS_SUCCESSFUL) | ||
| 98 | return ret; | ||
| 99 | v = __raw_readl(address); | ||
| 100 | switch (size) { | ||
| 101 | case 1: | ||
| 102 | v &= ~(0xFF << shift); | ||
| 103 | v |= val << shift; | ||
| 104 | break; | ||
| 105 | case 2: | ||
| 106 | v &= ~(0xFFFF << shift); | ||
| 107 | v |= val << shift; | ||
| 108 | break; | ||
| 109 | case 4: | ||
| 110 | v = val; | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | __raw_writel(v, address); | ||
| 114 | |||
| 115 | spin_unlock_irqrestore(&nano_lock, flags); | ||
| 116 | |||
| 117 | return PCIBIOS_SUCCESSFUL; | ||
| 118 | } | ||
| 119 | |||
| 120 | static struct pci_ops pci_nano_ops = { | ||
| 121 | .read = nanoengine_read_config, | ||
| 122 | .write = nanoengine_write_config, | ||
| 123 | }; | ||
| 124 | |||
| 125 | static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | ||
| 126 | { | ||
| 127 | return NANOENGINE_IRQ_GPIO_PCI; | ||
| 128 | } | ||
| 129 | |||
| 130 | struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys) | ||
| 131 | { | ||
| 132 | return pci_scan_bus(sys->busnr, &pci_nano_ops, sys); | ||
| 133 | } | ||
| 134 | |||
| 135 | static struct resource pci_io_ports = { | ||
| 136 | .name = "PCI IO", | ||
| 137 | .start = 0x400, | ||
| 138 | .end = 0x7FF, | ||
| 139 | .flags = IORESOURCE_IO, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static struct resource pci_non_prefetchable_memory = { | ||
| 143 | .name = "PCI non-prefetchable", | ||
| 144 | .start = NANO_PCI_MEM_RW_PHYS, | ||
| 145 | /* nanoEngine documentation says there is a 1 Megabyte window here, | ||
| 146 | * but PCI reports just 128 + 8 kbytes. */ | ||
| 147 | .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1, | ||
| 148 | /* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/ | ||
| 149 | .flags = IORESOURCE_MEM, | ||
| 150 | }; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it | ||
| 154 | * overlaps with previously defined memory. | ||
| 155 | * | ||
| 156 | * Here is what happens: | ||
| 157 | * | ||
| 158 | # dmesg | ||
| 159 | ... | ||
| 160 | pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 | ||
| 161 | pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] | ||
| 162 | pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] | ||
| 163 | pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] | ||
| 164 | pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] | ||
| 165 | pci 0000:00:00.0: supports D1 D2 | ||
| 166 | pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot | ||
| 167 | pci 0000:00:00.0: PME# disabled | ||
| 168 | PCI: bus0: Fast back to back transfers enabled | ||
| 169 | pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000) | ||
| 170 | pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] | ||
| 171 | pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) | ||
| 172 | pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] | ||
| 173 | pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) | ||
| 174 | pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] | ||
| 175 | pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) | ||
| 176 | * | ||
| 177 | * On the other hand, if we do not request the prefetchable memory resource, | ||
| 178 | * linux will alloc it first and the two non-prefetchable memory areas that | ||
| 179 | * are our real interest will not be mapped. So we choose to map it to an | ||
| 180 | * unused area. It gets recognized as expansion ROM, but becomes disabled. | ||
| 181 | * | ||
| 182 | * Here is what happens then: | ||
| 183 | * | ||
| 184 | # dmesg | ||
| 185 | ... | ||
| 186 | pci 0000:00:00.0: [8086:1209] type 0 class 0x000200 | ||
| 187 | pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff] | ||
| 188 | pci 0000:00:00.0: reg 14: [io 0x0000-0x003f] | ||
| 189 | pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff] | ||
| 190 | pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref] | ||
| 191 | pci 0000:00:00.0: supports D1 D2 | ||
| 192 | pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot | ||
| 193 | pci 0000:00:00.0: PME# disabled | ||
| 194 | PCI: bus0: Fast back to back transfers enabled | ||
| 195 | pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref] | ||
| 196 | pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff] | ||
| 197 | pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff]) | ||
| 198 | pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff] | ||
| 199 | pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff]) | ||
| 200 | pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f] | ||
| 201 | pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f]) | ||
| 202 | |||
| 203 | # lspci -vv -s 0000:00:00.0 | ||
| 204 | 00:00.0 Class 0200: Device 8086:1209 (rev 09) | ||
| 205 | Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx- | ||
| 206 | Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx- | ||
| 207 | Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes | ||
| 208 | Interrupt: pin A routed to IRQ 0 | ||
| 209 | Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K] | ||
| 210 | Region 1: I/O ports at 0400 [size=64] | ||
| 211 | Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K] | ||
| 212 | [virtual] Expansion ROM at 78000000 [disabled] [size=1M] | ||
| 213 | Capabilities: [dc] Power Management version 2 | ||
| 214 | Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-) | ||
| 215 | Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME- | ||
| 216 | Kernel driver in use: e100 | ||
| 217 | Kernel modules: e100 | ||
| 218 | * | ||
| 219 | */ | ||
| 220 | static struct resource pci_prefetchable_memory = { | ||
| 221 | .name = "PCI prefetchable", | ||
| 222 | .start = 0x78000000, | ||
| 223 | .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1, | ||
| 224 | .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, | ||
| 225 | }; | ||
| 226 | |||
| 227 | static int __init pci_nanoengine_setup_resources(struct resource **resource) | ||
| 228 | { | ||
| 229 | if (request_resource(&ioport_resource, &pci_io_ports)) { | ||
| 230 | printk(KERN_ERR "PCI: unable to allocate io port region\n"); | ||
| 231 | return -EBUSY; | ||
| 232 | } | ||
| 233 | if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) { | ||
| 234 | release_resource(&pci_io_ports); | ||
| 235 | printk(KERN_ERR "PCI: unable to allocate non prefetchable\n"); | ||
| 236 | return -EBUSY; | ||
| 237 | } | ||
| 238 | if (request_resource(&iomem_resource, &pci_prefetchable_memory)) { | ||
| 239 | release_resource(&pci_io_ports); | ||
| 240 | release_resource(&pci_non_prefetchable_memory); | ||
| 241 | printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); | ||
| 242 | return -EBUSY; | ||
| 243 | } | ||
| 244 | resource[0] = &pci_io_ports; | ||
| 245 | resource[1] = &pci_non_prefetchable_memory; | ||
| 246 | resource[2] = &pci_prefetchable_memory; | ||
| 247 | |||
| 248 | return 1; | ||
| 249 | } | ||
| 250 | |||
| 251 | int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys) | ||
| 252 | { | ||
| 253 | int ret = 0; | ||
| 254 | |||
| 255 | if (nr == 0) { | ||
| 256 | sys->mem_offset = NANO_PCI_MEM_RW_PHYS; | ||
| 257 | sys->io_offset = 0x400; | ||
| 258 | ret = pci_nanoengine_setup_resources(sys->resource); | ||
| 259 | /* Enable alternate memory bus master mode, see | ||
| 260 | * "Intel StrongARM SA1110 Developer's Manual", | ||
| 261 | * section 10.8, "Alternate Memory Bus Master Mode". */ | ||
| 262 | GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; | ||
| 263 | GAFR |= GPIO_MBGNT | GPIO_MBREQ; | ||
| 264 | TUCR |= TUCR_MBGPIO; | ||
| 265 | } | ||
| 266 | |||
| 267 | return ret; | ||
| 268 | } | ||
| 269 | |||
| 270 | static struct hw_pci nanoengine_pci __initdata = { | ||
| 271 | .map_irq = pci_nanoengine_map_irq, | ||
| 272 | .nr_controllers = 1, | ||
| 273 | .scan = pci_nanoengine_scan_bus, | ||
| 274 | .setup = pci_nanoengine_setup, | ||
| 275 | }; | ||
| 276 | |||
| 277 | static int __init nanoengine_pci_init(void) | ||
| 278 | { | ||
| 279 | if (machine_is_nanoengine()) | ||
| 280 | pci_common_init(&nanoengine_pci); | ||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | subsys_initcall(nanoengine_pci_init); | ||
