diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-02 16:45:22 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-06 12:55:32 -0400 |
commit | cf89c4262bd5fa70e67953126001c08ecea4f346 (patch) | |
tree | b968b7a7a2a9fb2140779948911e5c71b29585b1 /arch/tile/include/asm | |
parent | a3c4f2fb26974b5134861af8f7593040ae61a1f4 (diff) |
tile PCI RC: support I/O space access
To enable this functionality, configure CONFIG_TILE_PCI_IO. Without
this flag, the kernel still assigns I/O address ranges to the
devices, but no TRIO resource and mapping support is provided.
We assign disjoint I/O address ranges to separate PCIe domains.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/include/asm')
-rw-r--r-- | arch/tile/include/asm/io.h | 126 | ||||
-rw-r--r-- | arch/tile/include/asm/pci.h | 11 |
2 files changed, 127 insertions, 10 deletions
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index 31672918064c..73b319e39a3b 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h | |||
@@ -19,7 +19,8 @@ | |||
19 | #include <linux/bug.h> | 19 | #include <linux/bug.h> |
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | 21 | ||
22 | #define IO_SPACE_LIMIT 0xfffffffful | 22 | /* Maximum PCI I/O space address supported. */ |
23 | #define IO_SPACE_LIMIT 0xffffffff | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | 26 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem |
@@ -281,8 +282,108 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
281 | 282 | ||
282 | #endif | 283 | #endif |
283 | 284 | ||
285 | #if CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) | ||
286 | |||
287 | static inline u8 inb(unsigned long addr) | ||
288 | { | ||
289 | return readb((volatile void __iomem *) addr); | ||
290 | } | ||
291 | |||
292 | static inline u16 inw(unsigned long addr) | ||
293 | { | ||
294 | return readw((volatile void __iomem *) addr); | ||
295 | } | ||
296 | |||
297 | static inline u32 inl(unsigned long addr) | ||
298 | { | ||
299 | return readl((volatile void __iomem *) addr); | ||
300 | } | ||
301 | |||
302 | static inline void outb(u8 b, unsigned long addr) | ||
303 | { | ||
304 | writeb(b, (volatile void __iomem *) addr); | ||
305 | } | ||
306 | |||
307 | static inline void outw(u16 b, unsigned long addr) | ||
308 | { | ||
309 | writew(b, (volatile void __iomem *) addr); | ||
310 | } | ||
311 | |||
312 | static inline void outl(u32 b, unsigned long addr) | ||
313 | { | ||
314 | writel(b, (volatile void __iomem *) addr); | ||
315 | } | ||
316 | |||
317 | static inline void insb(unsigned long addr, void *buffer, int count) | ||
318 | { | ||
319 | if (count) { | ||
320 | u8 *buf = buffer; | ||
321 | do { | ||
322 | u8 x = inb(addr); | ||
323 | *buf++ = x; | ||
324 | } while (--count); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | static inline void insw(unsigned long addr, void *buffer, int count) | ||
329 | { | ||
330 | if (count) { | ||
331 | u16 *buf = buffer; | ||
332 | do { | ||
333 | u16 x = inw(addr); | ||
334 | *buf++ = x; | ||
335 | } while (--count); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static inline void insl(unsigned long addr, void *buffer, int count) | ||
340 | { | ||
341 | if (count) { | ||
342 | u32 *buf = buffer; | ||
343 | do { | ||
344 | u32 x = inl(addr); | ||
345 | *buf++ = x; | ||
346 | } while (--count); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | static inline void outsb(unsigned long addr, const void *buffer, int count) | ||
351 | { | ||
352 | if (count) { | ||
353 | const u8 *buf = buffer; | ||
354 | do { | ||
355 | outb(*buf++, addr); | ||
356 | } while (--count); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static inline void outsw(unsigned long addr, const void *buffer, int count) | ||
361 | { | ||
362 | if (count) { | ||
363 | const u16 *buf = buffer; | ||
364 | do { | ||
365 | outw(*buf++, addr); | ||
366 | } while (--count); | ||
367 | } | ||
368 | } | ||
369 | |||
370 | static inline void outsl(unsigned long addr, const void *buffer, int count) | ||
371 | { | ||
372 | if (count) { | ||
373 | const u32 *buf = buffer; | ||
374 | do { | ||
375 | outl(*buf++, addr); | ||
376 | } while (--count); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | extern void __iomem *ioport_map(unsigned long port, unsigned int len); | ||
381 | extern void ioport_unmap(void __iomem *addr); | ||
382 | |||
383 | #else | ||
384 | |||
284 | /* | 385 | /* |
285 | * The Tile architecture does not support IOPORT, even with PCI. | 386 | * The TilePro architecture does not support IOPORT, even with PCI. |
286 | * Unfortunately we can't yet simply not declare these methods, | 387 | * Unfortunately we can't yet simply not declare these methods, |
287 | * since some generic code that compiles into the kernel, but | 388 | * since some generic code that compiles into the kernel, but |
288 | * we never run, uses them unconditionally. | 389 | * we never run, uses them unconditionally. |
@@ -290,7 +391,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
290 | 391 | ||
291 | static inline long ioport_panic(void) | 392 | static inline long ioport_panic(void) |
292 | { | 393 | { |
394 | #ifdef __tilegx__ | ||
395 | panic("PCI IO space support is disabled. Configure the kernel with" | ||
396 | " CONFIG_TILE_PCI_IO to enable it"); | ||
397 | #else | ||
293 | panic("inb/outb and friends do not exist on tile"); | 398 | panic("inb/outb and friends do not exist on tile"); |
399 | #endif | ||
294 | return 0; | 400 | return 0; |
295 | } | 401 | } |
296 | 402 | ||
@@ -335,13 +441,6 @@ static inline void outl(u32 b, unsigned long addr) | |||
335 | ioport_panic(); | 441 | ioport_panic(); |
336 | } | 442 | } |
337 | 443 | ||
338 | #define inb_p(addr) inb(addr) | ||
339 | #define inw_p(addr) inw(addr) | ||
340 | #define inl_p(addr) inl(addr) | ||
341 | #define outb_p(x, addr) outb((x), (addr)) | ||
342 | #define outw_p(x, addr) outw((x), (addr)) | ||
343 | #define outl_p(x, addr) outl((x), (addr)) | ||
344 | |||
345 | static inline void insb(unsigned long addr, void *buffer, int count) | 444 | static inline void insb(unsigned long addr, void *buffer, int count) |
346 | { | 445 | { |
347 | ioport_panic(); | 446 | ioport_panic(); |
@@ -372,6 +471,15 @@ static inline void outsl(unsigned long addr, const void *buffer, int count) | |||
372 | ioport_panic(); | 471 | ioport_panic(); |
373 | } | 472 | } |
374 | 473 | ||
474 | #endif /* CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) */ | ||
475 | |||
476 | #define inb_p(addr) inb(addr) | ||
477 | #define inw_p(addr) inw(addr) | ||
478 | #define inl_p(addr) inl(addr) | ||
479 | #define outb_p(x, addr) outb((x), (addr)) | ||
480 | #define outw_p(x, addr) outw((x), (addr)) | ||
481 | #define outl_p(x, addr) outl((x), (addr)) | ||
482 | |||
375 | #define ioread16be(addr) be16_to_cpu(ioread16(addr)) | 483 | #define ioread16be(addr) be16_to_cpu(ioread16(addr)) |
376 | #define ioread32be(addr) be32_to_cpu(ioread32(addr)) | 484 | #define ioread32be(addr) be32_to_cpu(ioread32(addr)) |
377 | #define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr)) | 485 | #define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr)) |
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index cd10e654916e..9cf5308b1657 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h | |||
@@ -144,6 +144,10 @@ struct pci_controller { | |||
144 | 144 | ||
145 | int pio_mem_index; /* PIO region index for memory access */ | 145 | int pio_mem_index; /* PIO region index for memory access */ |
146 | 146 | ||
147 | #ifdef CONFIG_TILE_PCI_IO | ||
148 | int pio_io_index; /* PIO region index for I/O space access */ | ||
149 | #endif | ||
150 | |||
147 | /* | 151 | /* |
148 | * Mem-Map regions for all the memory controllers so that Linux can | 152 | * Mem-Map regions for all the memory controllers so that Linux can |
149 | * map all of its physical memory space to the PCI bus. | 153 | * map all of its physical memory space to the PCI bus. |
@@ -153,6 +157,10 @@ struct pci_controller { | |||
153 | int index; /* PCI domain number */ | 157 | int index; /* PCI domain number */ |
154 | struct pci_bus *root_bus; | 158 | struct pci_bus *root_bus; |
155 | 159 | ||
160 | /* PCI I/O space resource for this controller. */ | ||
161 | struct resource io_space; | ||
162 | char io_space_name[32]; | ||
163 | |||
156 | /* PCI memory space resource for this controller. */ | 164 | /* PCI memory space resource for this controller. */ |
157 | struct resource mem_space; | 165 | struct resource mem_space; |
158 | char mem_space_name[32]; | 166 | char mem_space_name[32]; |
@@ -210,7 +218,8 @@ static inline int pcibios_assign_all_busses(void) | |||
210 | } | 218 | } |
211 | 219 | ||
212 | #define PCIBIOS_MIN_MEM 0 | 220 | #define PCIBIOS_MIN_MEM 0 |
213 | #define PCIBIOS_MIN_IO 0 | 221 | /* Minimum PCI I/O address, starting at the page boundary. */ |
222 | #define PCIBIOS_MIN_IO PAGE_SIZE | ||
214 | 223 | ||
215 | /* Use any cpu for PCI. */ | 224 | /* Use any cpu for PCI. */ |
216 | #define cpumask_of_pcibus(bus) cpu_online_mask | 225 | #define cpumask_of_pcibus(bus) cpu_online_mask |