Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/arm/mach-integrator/pci_v3.c | |
3 | * | |
4 | * PCI functions for V3 host PCI bridge | |
5 | * | |
6 | * Copyright (C) 1999 ARM Limited | |
7 | * Copyright (C) 2000-2001 Deep Blue Solutions Ltd | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the License, or | |
12 | * (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | */ | |
1da177e4 LT |
23 | #include <linux/kernel.h> |
24 | #include <linux/pci.h> | |
1da177e4 LT |
25 | #include <linux/ioport.h> |
26 | #include <linux/interrupt.h> | |
27 | #include <linux/spinlock.h> | |
28 | #include <linux/init.h> | |
fced80c7 | 29 | #include <linux/io.h> |
86adc39f | 30 | #include <linux/platform_device.h> |
f55b2b56 LW |
31 | #include <linux/of.h> |
32 | #include <linux/of_address.h> | |
33 | #include <linux/of_irq.h> | |
34 | #include <linux/of_pci.h> | |
01ef3105 | 35 | #include <video/vga.h> |
1da177e4 | 36 | |
a09e64fb | 37 | #include <mach/hardware.h> |
a285edcf | 38 | #include <mach/platform.h> |
695436e3 LW |
39 | #include <mach/irqs.h> |
40 | ||
ae9daf2d | 41 | #include <asm/mach/map.h> |
d43c36dc | 42 | #include <asm/signal.h> |
1da177e4 | 43 | #include <asm/mach/pci.h> |
c6af66b9 | 44 | #include <asm/irq_regs.h> |
1da177e4 | 45 | |
ae9daf2d LW |
46 | #include "pci_v3.h" |
47 | ||
48 | /* | |
49 | * Where in the memory map does PCI live? | |
50 | * | |
51 | * This represents a fairly liberal usage of address space. Even though | |
52 | * the V3 only has two windows (therefore we need to map stuff on the fly), | |
53 | * we maintain the same addresses, even if they're not mapped. | |
54 | */ | |
1eb92b24 LW |
55 | #define PHYS_PCI_MEM_BASE 0x40000000 /* 256M */ |
56 | #define PHYS_PCI_PRE_BASE 0x50000000 /* 256M */ | |
ae9daf2d LW |
57 | #define PHYS_PCI_IO_BASE 0x60000000 /* 16M */ |
58 | #define PHYS_PCI_CONFIG_BASE 0x61000000 /* 16M */ | |
59 | #define PHYS_PCI_V3_BASE 0x62000000 /* 64K */ | |
60 | ||
61 | #define PCI_MEMORY_VADDR IOMEM(0xe8000000) | |
62 | #define PCI_CONFIG_VADDR IOMEM(0xec000000) | |
63 | ||
207bcf45 LW |
64 | /* |
65 | * V3 Local Bus to PCI Bridge definitions | |
66 | * | |
67 | * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04 | |
68 | * All V3 register names are prefaced by V3_ to avoid clashing with any other | |
69 | * PCI definitions. Their names match the user's manual. | |
70 | * | |
71 | * I'm assuming that I20 is disabled. | |
72 | * | |
73 | */ | |
74 | #define V3_PCI_VENDOR 0x00000000 | |
75 | #define V3_PCI_DEVICE 0x00000002 | |
76 | #define V3_PCI_CMD 0x00000004 | |
77 | #define V3_PCI_STAT 0x00000006 | |
78 | #define V3_PCI_CC_REV 0x00000008 | |
79 | #define V3_PCI_HDR_CFG 0x0000000C | |
80 | #define V3_PCI_IO_BASE 0x00000010 | |
81 | #define V3_PCI_BASE0 0x00000014 | |
82 | #define V3_PCI_BASE1 0x00000018 | |
83 | #define V3_PCI_SUB_VENDOR 0x0000002C | |
84 | #define V3_PCI_SUB_ID 0x0000002E | |
85 | #define V3_PCI_ROM 0x00000030 | |
86 | #define V3_PCI_BPARAM 0x0000003C | |
87 | #define V3_PCI_MAP0 0x00000040 | |
88 | #define V3_PCI_MAP1 0x00000044 | |
89 | #define V3_PCI_INT_STAT 0x00000048 | |
90 | #define V3_PCI_INT_CFG 0x0000004C | |
91 | #define V3_LB_BASE0 0x00000054 | |
92 | #define V3_LB_BASE1 0x00000058 | |
93 | #define V3_LB_MAP0 0x0000005E | |
94 | #define V3_LB_MAP1 0x00000062 | |
95 | #define V3_LB_BASE2 0x00000064 | |
96 | #define V3_LB_MAP2 0x00000066 | |
97 | #define V3_LB_SIZE 0x00000068 | |
98 | #define V3_LB_IO_BASE 0x0000006E | |
99 | #define V3_FIFO_CFG 0x00000070 | |
100 | #define V3_FIFO_PRIORITY 0x00000072 | |
101 | #define V3_FIFO_STAT 0x00000074 | |
102 | #define V3_LB_ISTAT 0x00000076 | |
103 | #define V3_LB_IMASK 0x00000077 | |
104 | #define V3_SYSTEM 0x00000078 | |
105 | #define V3_LB_CFG 0x0000007A | |
106 | #define V3_PCI_CFG 0x0000007C | |
107 | #define V3_DMA_PCI_ADR0 0x00000080 | |
108 | #define V3_DMA_PCI_ADR1 0x00000090 | |
109 | #define V3_DMA_LOCAL_ADR0 0x00000084 | |
110 | #define V3_DMA_LOCAL_ADR1 0x00000094 | |
111 | #define V3_DMA_LENGTH0 0x00000088 | |
112 | #define V3_DMA_LENGTH1 0x00000098 | |
113 | #define V3_DMA_CSR0 0x0000008B | |
114 | #define V3_DMA_CSR1 0x0000009B | |
115 | #define V3_DMA_CTLB_ADR0 0x0000008C | |
116 | #define V3_DMA_CTLB_ADR1 0x0000009C | |
117 | #define V3_DMA_DELAY 0x000000E0 | |
118 | #define V3_MAIL_DATA 0x000000C0 | |
119 | #define V3_PCI_MAIL_IEWR 0x000000D0 | |
120 | #define V3_PCI_MAIL_IERD 0x000000D2 | |
121 | #define V3_LB_MAIL_IEWR 0x000000D4 | |
122 | #define V3_LB_MAIL_IERD 0x000000D6 | |
123 | #define V3_MAIL_WR_STAT 0x000000D8 | |
124 | #define V3_MAIL_RD_STAT 0x000000DA | |
125 | #define V3_QBA_MAP 0x000000DC | |
126 | ||
127 | /* PCI COMMAND REGISTER bits | |
128 | */ | |
129 | #define V3_COMMAND_M_FBB_EN (1 << 9) | |
130 | #define V3_COMMAND_M_SERR_EN (1 << 8) | |
131 | #define V3_COMMAND_M_PAR_EN (1 << 6) | |
132 | #define V3_COMMAND_M_MASTER_EN (1 << 2) | |
133 | #define V3_COMMAND_M_MEM_EN (1 << 1) | |
134 | #define V3_COMMAND_M_IO_EN (1 << 0) | |
135 | ||
136 | /* SYSTEM REGISTER bits | |
137 | */ | |
138 | #define V3_SYSTEM_M_RST_OUT (1 << 15) | |
139 | #define V3_SYSTEM_M_LOCK (1 << 14) | |
140 | ||
141 | /* PCI_CFG bits | |
142 | */ | |
143 | #define V3_PCI_CFG_M_I2O_EN (1 << 15) | |
144 | #define V3_PCI_CFG_M_IO_REG_DIS (1 << 14) | |
145 | #define V3_PCI_CFG_M_IO_DIS (1 << 13) | |
146 | #define V3_PCI_CFG_M_EN3V (1 << 12) | |
147 | #define V3_PCI_CFG_M_RETRY_EN (1 << 10) | |
148 | #define V3_PCI_CFG_M_AD_LOW1 (1 << 9) | |
149 | #define V3_PCI_CFG_M_AD_LOW0 (1 << 8) | |
150 | ||
151 | /* PCI_BASE register bits (PCI -> Local Bus) | |
152 | */ | |
153 | #define V3_PCI_BASE_M_ADR_BASE 0xFFF00000 | |
154 | #define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00 | |
155 | #define V3_PCI_BASE_M_PREFETCH (1 << 3) | |
156 | #define V3_PCI_BASE_M_TYPE (3 << 1) | |
157 | #define V3_PCI_BASE_M_IO (1 << 0) | |
158 | ||
159 | /* PCI MAP register bits (PCI -> Local bus) | |
160 | */ | |
161 | #define V3_PCI_MAP_M_MAP_ADR 0xFFF00000 | |
162 | #define V3_PCI_MAP_M_RD_POST_INH (1 << 15) | |
163 | #define V3_PCI_MAP_M_ROM_SIZE (3 << 10) | |
164 | #define V3_PCI_MAP_M_SWAP (3 << 8) | |
165 | #define V3_PCI_MAP_M_ADR_SIZE 0x000000F0 | |
166 | #define V3_PCI_MAP_M_REG_EN (1 << 1) | |
167 | #define V3_PCI_MAP_M_ENABLE (1 << 0) | |
168 | ||
169 | /* | |
170 | * LB_BASE0,1 register bits (Local bus -> PCI) | |
171 | */ | |
172 | #define V3_LB_BASE_ADR_BASE 0xfff00000 | |
173 | #define V3_LB_BASE_SWAP (3 << 8) | |
174 | #define V3_LB_BASE_ADR_SIZE (15 << 4) | |
175 | #define V3_LB_BASE_PREFETCH (1 << 3) | |
176 | #define V3_LB_BASE_ENABLE (1 << 0) | |
177 | ||
178 | #define V3_LB_BASE_ADR_SIZE_1MB (0 << 4) | |
179 | #define V3_LB_BASE_ADR_SIZE_2MB (1 << 4) | |
180 | #define V3_LB_BASE_ADR_SIZE_4MB (2 << 4) | |
181 | #define V3_LB_BASE_ADR_SIZE_8MB (3 << 4) | |
182 | #define V3_LB_BASE_ADR_SIZE_16MB (4 << 4) | |
183 | #define V3_LB_BASE_ADR_SIZE_32MB (5 << 4) | |
184 | #define V3_LB_BASE_ADR_SIZE_64MB (6 << 4) | |
185 | #define V3_LB_BASE_ADR_SIZE_128MB (7 << 4) | |
186 | #define V3_LB_BASE_ADR_SIZE_256MB (8 << 4) | |
187 | #define V3_LB_BASE_ADR_SIZE_512MB (9 << 4) | |
188 | #define V3_LB_BASE_ADR_SIZE_1GB (10 << 4) | |
189 | #define V3_LB_BASE_ADR_SIZE_2GB (11 << 4) | |
190 | ||
191 | #define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE) | |
192 | ||
193 | /* | |
194 | * LB_MAP0,1 register bits (Local bus -> PCI) | |
195 | */ | |
196 | #define V3_LB_MAP_MAP_ADR 0xfff0 | |
197 | #define V3_LB_MAP_TYPE (7 << 1) | |
198 | #define V3_LB_MAP_AD_LOW_EN (1 << 0) | |
199 | ||
200 | #define V3_LB_MAP_TYPE_IACK (0 << 1) | |
201 | #define V3_LB_MAP_TYPE_IO (1 << 1) | |
202 | #define V3_LB_MAP_TYPE_MEM (3 << 1) | |
203 | #define V3_LB_MAP_TYPE_CONFIG (5 << 1) | |
204 | #define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1) | |
205 | ||
206 | #define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR) | |
207 | ||
208 | /* | |
209 | * LB_BASE2 register bits (Local bus -> PCI IO) | |
210 | */ | |
211 | #define V3_LB_BASE2_ADR_BASE 0xff00 | |
212 | #define V3_LB_BASE2_SWAP (3 << 6) | |
213 | #define V3_LB_BASE2_ENABLE (1 << 0) | |
214 | ||
215 | #define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE) | |
216 | ||
217 | /* | |
218 | * LB_MAP2 register bits (Local bus -> PCI IO) | |
219 | */ | |
220 | #define V3_LB_MAP2_MAP_ADR 0xff00 | |
221 | ||
222 | #define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR) | |
1da177e4 LT |
223 | |
224 | /* | |
225 | * The V3 PCI interface chip in Integrator provides several windows from | |
226 | * local bus memory into the PCI memory areas. Unfortunately, there | |
29d39604 | 227 | * are not really enough windows for our usage, therefore we reuse |
1da177e4 LT |
228 | * one of the windows for access to PCI configuration space. The |
229 | * memory map is as follows: | |
29d39604 | 230 | * |
1da177e4 | 231 | * Local Bus Memory Usage |
29d39604 | 232 | * |
1da177e4 LT |
233 | * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable |
234 | * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable | |
235 | * 60000000 - 60FFFFFF PCI IO. 16M | |
236 | * 61000000 - 61FFFFFF PCI Configuration. 16M | |
29d39604 | 237 | * |
1da177e4 LT |
238 | * There are three V3 windows, each described by a pair of V3 registers. |
239 | * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2. | |
240 | * Base0 and Base1 can be used for any type of PCI memory access. Base2 | |
241 | * can be used either for PCI I/O or for I20 accesses. By default, uHAL | |
242 | * uses this only for PCI IO space. | |
29d39604 | 243 | * |
1da177e4 | 244 | * Normally these spaces are mapped using the following base registers: |
29d39604 | 245 | * |
1da177e4 | 246 | * Usage Local Bus Memory Base/Map registers used |
29d39604 | 247 | * |
1da177e4 LT |
248 | * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 |
249 | * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1 | |
250 | * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 | |
251 | * Cfg 61000000 - 61FFFFFF | |
29d39604 | 252 | * |
1da177e4 | 253 | * This means that I20 and PCI configuration space accesses will fail. |
29d39604 | 254 | * When PCI configuration accesses are needed (via the uHAL PCI |
1da177e4 | 255 | * configuration space primitives) we must remap the spaces as follows: |
29d39604 | 256 | * |
1da177e4 | 257 | * Usage Local Bus Memory Base/Map registers used |
29d39604 | 258 | * |
1da177e4 LT |
259 | * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0 |
260 | * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0 | |
261 | * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2 | |
262 | * Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1 | |
29d39604 | 263 | * |
1da177e4 | 264 | * To make this work, the code depends on overlapping windows working. |
29d39604 | 265 | * The V3 chip translates an address by checking its range within |
1da177e4 LT |
266 | * each of the BASE/MAP pairs in turn (in ascending register number |
267 | * order). It will use the first matching pair. So, for example, | |
268 | * if the same address is mapped by both LB_BASE0/LB_MAP0 and | |
29d39604 | 269 | * LB_BASE1/LB_MAP1, the V3 will use the translation from |
1da177e4 | 270 | * LB_BASE0/LB_MAP0. |
29d39604 | 271 | * |
1da177e4 LT |
272 | * To allow PCI Configuration space access, the code enlarges the |
273 | * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes | |
274 | * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can | |
275 | * be remapped for use by configuration cycles. | |
29d39604 RH |
276 | * |
277 | * At the end of the PCI Configuration space accesses, | |
1da177e4 LT |
278 | * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window |
279 | * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to | |
280 | * reveal the now restored LB_BASE1/LB_MAP1 window. | |
29d39604 | 281 | * |
1da177e4 LT |
282 | * NOTE: We do not set up I2O mapping. I suspect that this is only |
283 | * for an intelligent (target) device. Using I2O disables most of | |
284 | * the mappings into PCI memory. | |
285 | */ | |
286 | ||
f55b2b56 | 287 | /* Filled in by probe */ |
a5ecbab7 | 288 | static void __iomem *pci_v3_base; |
1eb92b24 | 289 | /* CPU side memory ranges */ |
f55b2b56 LW |
290 | static struct resource conf_mem; /* FIXME: remap this instead of static map */ |
291 | static struct resource io_mem; | |
292 | static struct resource non_mem; | |
293 | static struct resource pre_mem; | |
1eb92b24 LW |
294 | /* PCI side memory ranges */ |
295 | static u64 non_mem_pci; | |
296 | static u64 non_mem_pci_sz; | |
297 | static u64 pre_mem_pci; | |
298 | static u64 pre_mem_pci_sz; | |
a5ecbab7 | 299 | |
1da177e4 | 300 | // V3 access routines |
a5ecbab7 LW |
301 | #define v3_writeb(o,v) __raw_writeb(v, pci_v3_base + (unsigned int)(o)) |
302 | #define v3_readb(o) (__raw_readb(pci_v3_base + (unsigned int)(o))) | |
1da177e4 | 303 | |
a5ecbab7 LW |
304 | #define v3_writew(o,v) __raw_writew(v, pci_v3_base + (unsigned int)(o)) |
305 | #define v3_readw(o) (__raw_readw(pci_v3_base + (unsigned int)(o))) | |
1da177e4 | 306 | |
a5ecbab7 LW |
307 | #define v3_writel(o,v) __raw_writel(v, pci_v3_base + (unsigned int)(o)) |
308 | #define v3_readl(o) (__raw_readl(pci_v3_base + (unsigned int)(o))) | |
1da177e4 LT |
309 | |
310 | /*============================================================================ | |
311 | * | |
312 | * routine: uHALir_PCIMakeConfigAddress() | |
313 | * | |
314 | * parameters: bus = which bus | |
315 | * device = which device | |
316 | * function = which function | |
317 | * offset = configuration space register we are interested in | |
318 | * | |
319 | * description: this routine will generate a platform dependent config | |
320 | * address. | |
321 | * | |
322 | * calls: none | |
323 | * | |
324 | * returns: configuration address to play on the PCI bus | |
325 | * | |
29d39604 RH |
326 | * To generate the appropriate PCI configuration cycles in the PCI |
327 | * configuration address space, you present the V3 with the following pattern | |
1da177e4 LT |
328 | * (which is very nearly a type 1 (except that the lower two bits are 00 and |
329 | * not 01). In order for this mapping to work you need to set up one of | |
330 | * the local to PCI aperatures to 16Mbytes in length translating to | |
331 | * PCI configuration space starting at 0x0000.0000. | |
332 | * | |
333 | * PCI configuration cycles look like this: | |
334 | * | |
335 | * Type 0: | |
336 | * | |
29d39604 | 337 | * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 |
1da177e4 LT |
338 | * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 |
339 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
340 | * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| | |
341 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
342 | * | |
343 | * 31:11 Device select bit. | |
344 | * 10:8 Function number | |
345 | * 7:2 Register number | |
346 | * | |
347 | * Type 1: | |
348 | * | |
29d39604 | 349 | * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 |
1da177e4 LT |
350 | * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 |
351 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
352 | * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| | |
353 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
354 | * | |
355 | * 31:24 reserved | |
356 | * 23:16 bus number (8 bits = 128 possible buses) | |
357 | * 15:11 Device number (5 bits) | |
358 | * 10:8 function number | |
359 | * 7:2 register number | |
29d39604 | 360 | * |
1da177e4 | 361 | */ |
bd31b859 | 362 | static DEFINE_RAW_SPINLOCK(v3_lock); |
1da177e4 | 363 | |
1da177e4 LT |
364 | #undef V3_LB_BASE_PREFETCH |
365 | #define V3_LB_BASE_PREFETCH 0 | |
366 | ||
b7a3f8db | 367 | static void __iomem *v3_open_config_window(struct pci_bus *bus, |
1da177e4 LT |
368 | unsigned int devfn, int offset) |
369 | { | |
370 | unsigned int address, mapaddress, busnr; | |
371 | ||
372 | busnr = bus->number; | |
373 | ||
374 | /* | |
375 | * Trap out illegal values | |
376 | */ | |
f7a9b365 SL |
377 | BUG_ON(offset > 255); |
378 | BUG_ON(busnr > 255); | |
379 | BUG_ON(devfn > 255); | |
1da177e4 LT |
380 | |
381 | if (busnr == 0) { | |
382 | int slot = PCI_SLOT(devfn); | |
383 | ||
384 | /* | |
385 | * local bus segment so need a type 0 config cycle | |
386 | * | |
387 | * build the PCI configuration "address" with one-hot in | |
388 | * A31-A11 | |
389 | * | |
390 | * mapaddress: | |
391 | * 3:1 = config cycle (101) | |
392 | * 0 = PCI A1 & A0 are 0 (0) | |
393 | */ | |
394 | address = PCI_FUNC(devfn) << 8; | |
395 | mapaddress = V3_LB_MAP_TYPE_CONFIG; | |
396 | ||
397 | if (slot > 12) | |
398 | /* | |
399 | * high order bits are handled by the MAP register | |
400 | */ | |
401 | mapaddress |= 1 << (slot - 5); | |
402 | else | |
403 | /* | |
404 | * low order bits handled directly in the address | |
405 | */ | |
406 | address |= 1 << (slot + 11); | |
407 | } else { | |
408 | /* | |
409 | * not the local bus segment so need a type 1 config cycle | |
410 | * | |
411 | * address: | |
412 | * 23:16 = bus number | |
413 | * 15:11 = slot number (7:3 of devfn) | |
414 | * 10:8 = func number (2:0 of devfn) | |
415 | * | |
416 | * mapaddress: | |
417 | * 3:1 = config cycle (101) | |
418 | * 0 = PCI A1 & A0 from host bus (1) | |
419 | */ | |
420 | mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN; | |
421 | address = (busnr << 16) | (devfn << 8); | |
422 | } | |
423 | ||
424 | /* | |
425 | * Set up base0 to see all 512Mbytes of memory space (not | |
426 | * prefetchable), this frees up base1 for re-use by | |
427 | * configuration memory | |
428 | */ | |
f55b2b56 | 429 | v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) | |
1da177e4 LT |
430 | V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE); |
431 | ||
432 | /* | |
433 | * Set up base1/map1 to point into configuration space. | |
434 | */ | |
f55b2b56 | 435 | v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(conf_mem.start) | |
1da177e4 LT |
436 | V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE); |
437 | v3_writew(V3_LB_MAP1, mapaddress); | |
438 | ||
439 | return PCI_CONFIG_VADDR + address + offset; | |
440 | } | |
441 | ||
442 | static void v3_close_config_window(void) | |
443 | { | |
444 | /* | |
445 | * Reassign base1 for use by prefetchable PCI memory | |
446 | */ | |
f55b2b56 | 447 | v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) | |
1da177e4 LT |
448 | V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH | |
449 | V3_LB_BASE_ENABLE); | |
1eb92b24 | 450 | v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) | |
1da177e4 LT |
451 | V3_LB_MAP_TYPE_MEM_MULTIPLE); |
452 | ||
453 | /* | |
454 | * And shrink base0 back to a 256M window (NOTE: MAP0 already correct) | |
455 | */ | |
f55b2b56 | 456 | v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) | |
1da177e4 LT |
457 | V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE); |
458 | } | |
459 | ||
460 | static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where, | |
461 | int size, u32 *val) | |
462 | { | |
b7a3f8db | 463 | void __iomem *addr; |
1da177e4 LT |
464 | unsigned long flags; |
465 | u32 v; | |
466 | ||
bd31b859 | 467 | raw_spin_lock_irqsave(&v3_lock, flags); |
1da177e4 LT |
468 | addr = v3_open_config_window(bus, devfn, where); |
469 | ||
470 | switch (size) { | |
471 | case 1: | |
472 | v = __raw_readb(addr); | |
473 | break; | |
474 | ||
475 | case 2: | |
476 | v = __raw_readw(addr); | |
477 | break; | |
478 | ||
479 | default: | |
480 | v = __raw_readl(addr); | |
481 | break; | |
482 | } | |
483 | ||
484 | v3_close_config_window(); | |
bd31b859 | 485 | raw_spin_unlock_irqrestore(&v3_lock, flags); |
1da177e4 LT |
486 | |
487 | *val = v; | |
488 | return PCIBIOS_SUCCESSFUL; | |
489 | } | |
490 | ||
491 | static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where, | |
492 | int size, u32 val) | |
493 | { | |
b7a3f8db | 494 | void __iomem *addr; |
1da177e4 LT |
495 | unsigned long flags; |
496 | ||
bd31b859 | 497 | raw_spin_lock_irqsave(&v3_lock, flags); |
1da177e4 LT |
498 | addr = v3_open_config_window(bus, devfn, where); |
499 | ||
500 | switch (size) { | |
501 | case 1: | |
502 | __raw_writeb((u8)val, addr); | |
503 | __raw_readb(addr); | |
504 | break; | |
505 | ||
506 | case 2: | |
507 | __raw_writew((u16)val, addr); | |
508 | __raw_readw(addr); | |
509 | break; | |
510 | ||
511 | case 4: | |
512 | __raw_writel(val, addr); | |
513 | __raw_readl(addr); | |
514 | break; | |
515 | } | |
516 | ||
517 | v3_close_config_window(); | |
bd31b859 | 518 | raw_spin_unlock_irqrestore(&v3_lock, flags); |
1da177e4 LT |
519 | |
520 | return PCIBIOS_SUCCESSFUL; | |
521 | } | |
522 | ||
f4bc4f0a | 523 | static struct pci_ops pci_v3_ops = { |
1da177e4 LT |
524 | .read = v3_read_config, |
525 | .write = v3_write_config, | |
526 | }; | |
527 | ||
37d15909 | 528 | static int __init pci_v3_setup_resources(struct pci_sys_data *sys) |
1da177e4 LT |
529 | { |
530 | if (request_resource(&iomem_resource, &non_mem)) { | |
531 | printk(KERN_ERR "PCI: unable to allocate non-prefetchable " | |
532 | "memory region\n"); | |
533 | return -EBUSY; | |
534 | } | |
535 | if (request_resource(&iomem_resource, &pre_mem)) { | |
536 | release_resource(&non_mem); | |
537 | printk(KERN_ERR "PCI: unable to allocate prefetchable " | |
538 | "memory region\n"); | |
539 | return -EBUSY; | |
540 | } | |
541 | ||
542 | /* | |
37d15909 BH |
543 | * the mem resource for this bus |
544 | * the prefetch mem resource for this bus | |
1da177e4 | 545 | */ |
9f786d03 BH |
546 | pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); |
547 | pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); | |
1da177e4 LT |
548 | |
549 | return 1; | |
550 | } | |
551 | ||
552 | /* | |
553 | * These don't seem to be implemented on the Integrator I have, which | |
554 | * means I can't get additional information on the reason for the pm2fb | |
555 | * problems. I suppose I'll just have to mind-meld with the machine. ;) | |
556 | */ | |
379df279 LW |
557 | static void __iomem *ap_syscon_base; |
558 | #define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18 | |
559 | #define INTEGRATOR_SC_LBFADDR_OFFSET 0x20 | |
560 | #define INTEGRATOR_SC_LBFCODE_OFFSET 0x24 | |
1da177e4 LT |
561 | |
562 | static int | |
563 | v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |
564 | { | |
565 | unsigned long pc = instruction_pointer(regs); | |
566 | unsigned long instr = *(unsigned long *)pc; | |
567 | #if 0 | |
568 | char buf[128]; | |
569 | ||
570 | sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n", | |
379df279 | 571 | addr, fsr, pc, instr, __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255, |
1da177e4 LT |
572 | v3_readb(V3_LB_ISTAT)); |
573 | printk(KERN_DEBUG "%s", buf); | |
1da177e4 LT |
574 | #endif |
575 | ||
576 | v3_writeb(V3_LB_ISTAT, 0); | |
379df279 | 577 | __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); |
1da177e4 LT |
578 | |
579 | /* | |
580 | * If the instruction being executed was a read, | |
581 | * make it look like it read all-ones. | |
582 | */ | |
583 | if ((instr & 0x0c100000) == 0x04100000) { | |
584 | int reg = (instr >> 12) & 15; | |
585 | unsigned long val; | |
586 | ||
587 | if (instr & 0x00400000) | |
588 | val = 255; | |
589 | else | |
590 | val = -1; | |
591 | ||
592 | regs->uregs[reg] = val; | |
593 | regs->ARM_pc += 4; | |
594 | return 0; | |
595 | } | |
596 | ||
597 | if ((instr & 0x0e100090) == 0x00100090) { | |
598 | int reg = (instr >> 12) & 15; | |
599 | ||
600 | regs->uregs[reg] = -1; | |
601 | regs->ARM_pc += 4; | |
602 | return 0; | |
603 | } | |
604 | ||
605 | return 1; | |
606 | } | |
607 | ||
e8f2af17 | 608 | static irqreturn_t v3_irq(int dummy, void *devid) |
1da177e4 LT |
609 | { |
610 | #ifdef CONFIG_DEBUG_LL | |
0cd61b68 | 611 | struct pt_regs *regs = get_irq_regs(); |
1da177e4 LT |
612 | unsigned long pc = instruction_pointer(regs); |
613 | unsigned long instr = *(unsigned long *)pc; | |
614 | char buf[128]; | |
7c28472a | 615 | extern void printascii(const char *); |
1da177e4 | 616 | |
e8f2af17 JG |
617 | sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x " |
618 | "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr, | |
379df279 LW |
619 | __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET), |
620 | __raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255, | |
1da177e4 LT |
621 | v3_readb(V3_LB_ISTAT)); |
622 | printascii(buf); | |
623 | #endif | |
624 | ||
625 | v3_writew(V3_PCI_STAT, 0xf000); | |
626 | v3_writeb(V3_LB_ISTAT, 0); | |
379df279 | 627 | __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); |
1da177e4 LT |
628 | |
629 | #ifdef CONFIG_DEBUG_LL | |
630 | /* | |
631 | * If the instruction being executed was a read, | |
632 | * make it look like it read all-ones. | |
633 | */ | |
634 | if ((instr & 0x0c100000) == 0x04100000) { | |
635 | int reg = (instr >> 16) & 15; | |
636 | sprintf(buf, " reg%d = %08lx\n", reg, regs->uregs[reg]); | |
637 | printascii(buf); | |
638 | } | |
639 | #endif | |
640 | return IRQ_HANDLED; | |
641 | } | |
642 | ||
f4bc4f0a | 643 | static int __init pci_v3_setup(int nr, struct pci_sys_data *sys) |
1da177e4 LT |
644 | { |
645 | int ret = 0; | |
646 | ||
67c6b2ef LW |
647 | if (!ap_syscon_base) |
648 | return -EINVAL; | |
649 | ||
1da177e4 | 650 | if (nr == 0) { |
f55b2b56 | 651 | sys->mem_offset = non_mem.start; |
37d15909 | 652 | ret = pci_v3_setup_resources(sys); |
1da177e4 LT |
653 | } |
654 | ||
655 | return ret; | |
656 | } | |
657 | ||
1da177e4 LT |
658 | /* |
659 | * V3_LB_BASE? - local bus address | |
660 | * V3_LB_MAP? - pci bus address | |
661 | */ | |
f4bc4f0a | 662 | static void __init pci_v3_preinit(void) |
1da177e4 LT |
663 | { |
664 | unsigned long flags; | |
665 | unsigned int temp; | |
1da177e4 | 666 | |
c9d95fbe RH |
667 | pcibios_min_mem = 0x00100000; |
668 | ||
1da177e4 LT |
669 | /* |
670 | * Hook in our fault handler for PCI errors | |
671 | */ | |
6338a6aa KS |
672 | hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch"); |
673 | hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch"); | |
674 | hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); | |
675 | hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch"); | |
1da177e4 | 676 | |
bd31b859 | 677 | raw_spin_lock_irqsave(&v3_lock, flags); |
1da177e4 LT |
678 | |
679 | /* | |
680 | * Unlock V3 registers, but only if they were previously locked. | |
681 | */ | |
682 | if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK) | |
683 | v3_writew(V3_SYSTEM, 0xa05f); | |
684 | ||
685 | /* | |
686 | * Setup window 0 - PCI non-prefetchable memory | |
687 | * Local: 0x40000000 Bus: 0x00000000 Size: 256MB | |
688 | */ | |
f55b2b56 | 689 | v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(non_mem.start) | |
1da177e4 | 690 | V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE); |
1eb92b24 | 691 | v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(non_mem_pci) | |
1da177e4 LT |
692 | V3_LB_MAP_TYPE_MEM); |
693 | ||
694 | /* | |
695 | * Setup window 1 - PCI prefetchable memory | |
696 | * Local: 0x50000000 Bus: 0x10000000 Size: 256MB | |
697 | */ | |
f55b2b56 | 698 | v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(pre_mem.start) | |
1da177e4 LT |
699 | V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH | |
700 | V3_LB_BASE_ENABLE); | |
1eb92b24 | 701 | v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(pre_mem_pci) | |
1da177e4 LT |
702 | V3_LB_MAP_TYPE_MEM_MULTIPLE); |
703 | ||
704 | /* | |
705 | * Setup window 2 - PCI IO | |
706 | */ | |
f55b2b56 | 707 | v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(io_mem.start) | |
1da177e4 LT |
708 | V3_LB_BASE_ENABLE); |
709 | v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0)); | |
710 | ||
711 | /* | |
712 | * Disable PCI to host IO cycles | |
713 | */ | |
714 | temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN; | |
715 | temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS; | |
716 | v3_writew(V3_PCI_CFG, temp); | |
717 | ||
718 | printk(KERN_DEBUG "FIFO_CFG: %04x FIFO_PRIO: %04x\n", | |
719 | v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY)); | |
720 | ||
721 | /* | |
722 | * Set the V3 FIFO such that writes have higher priority than | |
723 | * reads, and local bus write causes local bus read fifo flush. | |
724 | * Same for PCI. | |
725 | */ | |
726 | v3_writew(V3_FIFO_PRIORITY, 0x0a0a); | |
727 | ||
728 | /* | |
729 | * Re-lock the system register. | |
730 | */ | |
731 | temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK; | |
732 | v3_writew(V3_SYSTEM, temp); | |
733 | ||
734 | /* | |
735 | * Clear any error conditions, and enable write errors. | |
736 | */ | |
737 | v3_writeb(V3_LB_ISTAT, 0); | |
738 | v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10)); | |
739 | v3_writeb(V3_LB_IMASK, 0x28); | |
379df279 | 740 | __raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET); |
1da177e4 | 741 | |
bd31b859 | 742 | raw_spin_unlock_irqrestore(&v3_lock, flags); |
1da177e4 LT |
743 | } |
744 | ||
f4bc4f0a | 745 | static void __init pci_v3_postinit(void) |
1da177e4 LT |
746 | { |
747 | unsigned int pci_cmd; | |
748 | ||
749 | pci_cmd = PCI_COMMAND_MEMORY | | |
750 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE; | |
751 | ||
752 | v3_writew(V3_PCI_CMD, pci_cmd); | |
753 | ||
754 | v3_writeb(V3_LB_ISTAT, ~0x40); | |
755 | v3_writeb(V3_LB_IMASK, 0x68); | |
756 | ||
757 | #if 0 | |
758 | ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL); | |
759 | if (ret) | |
760 | printk(KERN_ERR "PCI: unable to grab local bus timeout " | |
761 | "interrupt: %d\n", ret); | |
762 | #endif | |
863dab45 | 763 | |
f55b2b56 | 764 | register_isa_ports(non_mem.start, io_mem.start, 0); |
1da177e4 | 765 | } |
f4bc4f0a LW |
766 | |
767 | /* | |
768 | * A small note about bridges and interrupts. The DECchip 21050 (and | |
769 | * later) adheres to the PCI-PCI bridge specification. This says that | |
770 | * the interrupts on the other side of a bridge are swizzled in the | |
771 | * following manner: | |
772 | * | |
773 | * Dev Interrupt Interrupt | |
774 | * Pin on Pin on | |
775 | * Device Connector | |
776 | * | |
777 | * 4 A A | |
778 | * B B | |
779 | * C C | |
780 | * D D | |
781 | * | |
782 | * 5 A B | |
783 | * B C | |
784 | * C D | |
785 | * D A | |
786 | * | |
787 | * 6 A C | |
788 | * B D | |
789 | * C A | |
790 | * D B | |
791 | * | |
792 | * 7 A D | |
793 | * B A | |
794 | * C B | |
795 | * D C | |
796 | * | |
797 | * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A. | |
798 | * Thus, each swizzle is ((pin-1) + (device#-4)) % 4 | |
799 | */ | |
800 | ||
801 | /* | |
802 | * This routine handles multiple bridges. | |
803 | */ | |
86adc39f | 804 | static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp) |
f4bc4f0a LW |
805 | { |
806 | if (*pinp == 0) | |
807 | *pinp = 1; | |
808 | ||
809 | return pci_common_swizzle(dev, pinp); | |
810 | } | |
811 | ||
812 | static int irq_tab[4] __initdata = { | |
813 | IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3 | |
814 | }; | |
815 | ||
816 | /* | |
817 | * map the specified device/slot/pin to an IRQ. This works out such | |
818 | * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1. | |
819 | */ | |
86adc39f | 820 | static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) |
f4bc4f0a LW |
821 | { |
822 | int intnr = ((slot - 9) + (pin - 1)) & 3; | |
823 | ||
824 | return irq_tab[intnr]; | |
825 | } | |
826 | ||
86adc39f LW |
827 | static struct hw_pci pci_v3 __initdata = { |
828 | .swizzle = pci_v3_swizzle, | |
f4bc4f0a LW |
829 | .setup = pci_v3_setup, |
830 | .nr_controllers = 1, | |
831 | .ops = &pci_v3_ops, | |
832 | .preinit = pci_v3_preinit, | |
833 | .postinit = pci_v3_postinit, | |
834 | }; | |
835 | ||
f55b2b56 LW |
836 | #ifdef CONFIG_OF |
837 | ||
838 | static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin) | |
839 | { | |
840 | struct of_irq oirq; | |
841 | int ret; | |
842 | ||
843 | ret = of_irq_map_pci(dev, &oirq); | |
844 | if (ret) { | |
845 | dev_err(&dev->dev, "of_irq_map_pci() %d\n", ret); | |
846 | /* Proper return code 0 == NO_IRQ */ | |
847 | return 0; | |
848 | } | |
849 | ||
850 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | |
851 | oirq.size); | |
852 | } | |
853 | ||
854 | static int __init pci_v3_dtprobe(struct platform_device *pdev, | |
855 | struct device_node *np) | |
856 | { | |
857 | struct of_pci_range_parser parser; | |
858 | struct of_pci_range range; | |
859 | struct resource *res; | |
860 | int irq, ret; | |
861 | ||
862 | if (of_pci_range_parser_init(&parser, np)) | |
863 | return -EINVAL; | |
864 | ||
865 | /* Get base for bridge registers */ | |
866 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
867 | if (!res) { | |
868 | dev_err(&pdev->dev, "unable to obtain PCIv3 base\n"); | |
869 | return -ENODEV; | |
870 | } | |
871 | pci_v3_base = devm_ioremap(&pdev->dev, res->start, | |
872 | resource_size(res)); | |
873 | if (!pci_v3_base) { | |
874 | dev_err(&pdev->dev, "unable to remap PCIv3 base\n"); | |
875 | return -ENODEV; | |
876 | } | |
877 | ||
878 | /* Get and request error IRQ resource */ | |
879 | irq = platform_get_irq(pdev, 0); | |
880 | if (irq <= 0) { | |
881 | dev_err(&pdev->dev, "unable to obtain PCIv3 error IRQ\n"); | |
882 | return -ENODEV; | |
883 | } | |
884 | ret = devm_request_irq(&pdev->dev, irq, v3_irq, 0, | |
885 | "PCIv3 error", NULL); | |
886 | if (ret < 0) { | |
887 | dev_err(&pdev->dev, "unable to request PCIv3 error IRQ %d (%d)\n", irq, ret); | |
888 | return ret; | |
889 | } | |
890 | ||
891 | for_each_of_pci_range(&parser, &range) { | |
892 | if (!range.flags) { | |
893 | of_pci_range_to_resource(&range, np, &conf_mem); | |
894 | conf_mem.name = "PCIv3 config"; | |
895 | } | |
896 | if (range.flags & IORESOURCE_IO) { | |
897 | of_pci_range_to_resource(&range, np, &io_mem); | |
898 | io_mem.name = "PCIv3 I/O"; | |
899 | } | |
900 | if ((range.flags & IORESOURCE_MEM) && | |
901 | !(range.flags & IORESOURCE_PREFETCH)) { | |
1eb92b24 LW |
902 | non_mem_pci = range.pci_addr; |
903 | non_mem_pci_sz = range.size; | |
f55b2b56 LW |
904 | of_pci_range_to_resource(&range, np, &non_mem); |
905 | non_mem.name = "PCIv3 non-prefetched mem"; | |
906 | } | |
907 | if ((range.flags & IORESOURCE_MEM) && | |
908 | (range.flags & IORESOURCE_PREFETCH)) { | |
1eb92b24 LW |
909 | pre_mem_pci = range.pci_addr; |
910 | pre_mem_pci_sz = range.size; | |
f55b2b56 LW |
911 | of_pci_range_to_resource(&range, np, &pre_mem); |
912 | pre_mem.name = "PCIv3 prefetched mem"; | |
913 | } | |
914 | } | |
915 | ||
916 | if (!conf_mem.start || !io_mem.start || | |
917 | !non_mem.start || !pre_mem.start) { | |
918 | dev_err(&pdev->dev, "missing ranges in device node\n"); | |
919 | return -EINVAL; | |
920 | } | |
921 | ||
922 | pci_v3.map_irq = pci_v3_map_irq_dt; | |
923 | pci_common_init_dev(&pdev->dev, &pci_v3); | |
924 | ||
925 | return 0; | |
926 | } | |
927 | ||
928 | #else | |
929 | ||
930 | static inline int pci_v3_dtprobe(struct platform_device *pdev, | |
931 | struct device_node *np) | |
932 | { | |
933 | return -EINVAL; | |
934 | } | |
935 | ||
936 | #endif | |
937 | ||
86adc39f | 938 | static int __init pci_v3_probe(struct platform_device *pdev) |
f4bc4f0a | 939 | { |
f55b2b56 | 940 | struct device_node *np = pdev->dev.of_node; |
5283456d LW |
941 | int ret; |
942 | ||
03884f4e LW |
943 | /* Remap the Integrator system controller */ |
944 | ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100); | |
945 | if (!ap_syscon_base) { | |
946 | dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n"); | |
947 | return -ENODEV; | |
948 | } | |
949 | ||
f55b2b56 LW |
950 | /* Device tree probe path */ |
951 | if (np) | |
952 | return pci_v3_dtprobe(pdev, np); | |
953 | ||
a5ecbab7 LW |
954 | pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K); |
955 | if (!pci_v3_base) { | |
956 | dev_err(&pdev->dev, "unable to remap PCIv3 base\n"); | |
957 | return -ENODEV; | |
958 | } | |
959 | ||
5283456d LW |
960 | ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL); |
961 | if (ret) { | |
962 | dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n", | |
963 | ret); | |
964 | return -ENODEV; | |
965 | } | |
966 | ||
f55b2b56 LW |
967 | conf_mem.name = "PCIv3 config"; |
968 | conf_mem.start = PHYS_PCI_CONFIG_BASE; | |
969 | conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1; | |
970 | conf_mem.flags = IORESOURCE_MEM; | |
971 | ||
972 | io_mem.name = "PCIv3 I/O"; | |
973 | io_mem.start = PHYS_PCI_IO_BASE; | |
974 | io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1; | |
975 | io_mem.flags = IORESOURCE_MEM; | |
976 | ||
1eb92b24 LW |
977 | non_mem_pci = 0x00000000; |
978 | non_mem_pci_sz = SZ_256M; | |
f55b2b56 | 979 | non_mem.name = "PCIv3 non-prefetched mem"; |
1eb92b24 LW |
980 | non_mem.start = PHYS_PCI_MEM_BASE; |
981 | non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1; | |
f55b2b56 LW |
982 | non_mem.flags = IORESOURCE_MEM; |
983 | ||
1eb92b24 LW |
984 | pre_mem_pci = 0x10000000; |
985 | pre_mem_pci_sz = SZ_256M; | |
f55b2b56 | 986 | pre_mem.name = "PCIv3 prefetched mem"; |
1eb92b24 LW |
987 | pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M; |
988 | pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1; | |
f55b2b56 LW |
989 | pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
990 | ||
991 | pci_v3.map_irq = pci_v3_map_irq; | |
992 | ||
993 | pci_common_init_dev(&pdev->dev, &pci_v3); | |
5283456d | 994 | |
f4bc4f0a LW |
995 | return 0; |
996 | } | |
997 | ||
f55b2b56 LW |
998 | static const struct of_device_id pci_ids[] = { |
999 | { .compatible = "v3,v360epc-pci", }, | |
1000 | {}, | |
1001 | }; | |
1002 | ||
86adc39f LW |
1003 | static struct platform_driver pci_v3_driver = { |
1004 | .driver = { | |
1005 | .name = "pci-v3", | |
f55b2b56 | 1006 | .of_match_table = pci_ids, |
86adc39f LW |
1007 | }, |
1008 | }; | |
1009 | ||
1010 | static int __init pci_v3_init(void) | |
1011 | { | |
1012 | return platform_driver_probe(&pci_v3_driver, pci_v3_probe); | |
1013 | } | |
1014 | ||
1015 | subsys_initcall(pci_v3_init); | |
ae9daf2d LW |
1016 | |
1017 | /* | |
1018 | * Static mappings for the PCIv3 bridge | |
1019 | * | |
1020 | * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) | |
1021 | * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M) | |
1022 | * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M) | |
1023 | */ | |
1024 | static struct map_desc pci_v3_io_desc[] __initdata __maybe_unused = { | |
1025 | { | |
1026 | .virtual = (unsigned long)PCI_MEMORY_VADDR, | |
1027 | .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE), | |
1028 | .length = SZ_16M, | |
1029 | .type = MT_DEVICE | |
1030 | }, { | |
1031 | .virtual = (unsigned long)PCI_CONFIG_VADDR, | |
1032 | .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE), | |
1033 | .length = SZ_16M, | |
1034 | .type = MT_DEVICE | |
1035 | } | |
1036 | }; | |
1037 | ||
1038 | int __init pci_v3_early_init(void) | |
1039 | { | |
1040 | iotable_init(pci_v3_io_desc, ARRAY_SIZE(pci_v3_io_desc)); | |
1041 | vga_base = (unsigned long)PCI_MEMORY_VADDR; | |
1042 | pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE)); | |
1043 | return 0; | |
1044 | } |