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>
This commit is contained in:
@@ -19,7 +19,8 @@
|
||||
#include <linux/bug.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#define IO_SPACE_LIMIT 0xfffffffful
|
||||
/* Maximum PCI I/O space address supported. */
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
/*
|
||||
* 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,
|
||||
|
||||
#endif
|
||||
|
||||
#if CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO)
|
||||
|
||||
static inline u8 inb(unsigned long addr)
|
||||
{
|
||||
return readb((volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline u16 inw(unsigned long addr)
|
||||
{
|
||||
return readw((volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline u32 inl(unsigned long addr)
|
||||
{
|
||||
return readl((volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline void outb(u8 b, unsigned long addr)
|
||||
{
|
||||
writeb(b, (volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline void outw(u16 b, unsigned long addr)
|
||||
{
|
||||
writew(b, (volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline void outl(u32 b, unsigned long addr)
|
||||
{
|
||||
writel(b, (volatile void __iomem *) addr);
|
||||
}
|
||||
|
||||
static inline void insb(unsigned long addr, void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
u8 *buf = buffer;
|
||||
do {
|
||||
u8 x = inb(addr);
|
||||
*buf++ = x;
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void insw(unsigned long addr, void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
u16 *buf = buffer;
|
||||
do {
|
||||
u16 x = inw(addr);
|
||||
*buf++ = x;
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void insl(unsigned long addr, void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
u32 *buf = buffer;
|
||||
do {
|
||||
u32 x = inl(addr);
|
||||
*buf++ = x;
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void outsb(unsigned long addr, const void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
const u8 *buf = buffer;
|
||||
do {
|
||||
outb(*buf++, addr);
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void outsw(unsigned long addr, const void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
const u16 *buf = buffer;
|
||||
do {
|
||||
outw(*buf++, addr);
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void outsl(unsigned long addr, const void *buffer, int count)
|
||||
{
|
||||
if (count) {
|
||||
const u32 *buf = buffer;
|
||||
do {
|
||||
outl(*buf++, addr);
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
extern void __iomem *ioport_map(unsigned long port, unsigned int len);
|
||||
extern void ioport_unmap(void __iomem *addr);
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* The Tile architecture does not support IOPORT, even with PCI.
|
||||
* The TilePro architecture does not support IOPORT, even with PCI.
|
||||
* Unfortunately we can't yet simply not declare these methods,
|
||||
* since some generic code that compiles into the kernel, but
|
||||
* we never run, uses them unconditionally.
|
||||
@@ -290,7 +391,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
|
||||
|
||||
static inline long ioport_panic(void)
|
||||
{
|
||||
#ifdef __tilegx__
|
||||
panic("PCI IO space support is disabled. Configure the kernel with"
|
||||
" CONFIG_TILE_PCI_IO to enable it");
|
||||
#else
|
||||
panic("inb/outb and friends do not exist on tile");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -335,13 +441,6 @@ static inline void outl(u32 b, unsigned long addr)
|
||||
ioport_panic();
|
||||
}
|
||||
|
||||
#define inb_p(addr) inb(addr)
|
||||
#define inw_p(addr) inw(addr)
|
||||
#define inl_p(addr) inl(addr)
|
||||
#define outb_p(x, addr) outb((x), (addr))
|
||||
#define outw_p(x, addr) outw((x), (addr))
|
||||
#define outl_p(x, addr) outl((x), (addr))
|
||||
|
||||
static inline void insb(unsigned long addr, void *buffer, int count)
|
||||
{
|
||||
ioport_panic();
|
||||
@@ -372,6 +471,15 @@ static inline void outsl(unsigned long addr, const void *buffer, int count)
|
||||
ioport_panic();
|
||||
}
|
||||
|
||||
#endif /* CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) */
|
||||
|
||||
#define inb_p(addr) inb(addr)
|
||||
#define inw_p(addr) inw(addr)
|
||||
#define inl_p(addr) inl(addr)
|
||||
#define outb_p(x, addr) outb((x), (addr))
|
||||
#define outw_p(x, addr) outw((x), (addr))
|
||||
#define outl_p(x, addr) outl((x), (addr))
|
||||
|
||||
#define ioread16be(addr) be16_to_cpu(ioread16(addr))
|
||||
#define ioread32be(addr) be32_to_cpu(ioread32(addr))
|
||||
#define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr))
|
||||
|
||||
@@ -144,6 +144,10 @@ struct pci_controller {
|
||||
|
||||
int pio_mem_index; /* PIO region index for memory access */
|
||||
|
||||
#ifdef CONFIG_TILE_PCI_IO
|
||||
int pio_io_index; /* PIO region index for I/O space access */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mem-Map regions for all the memory controllers so that Linux can
|
||||
* map all of its physical memory space to the PCI bus.
|
||||
@@ -153,6 +157,10 @@ struct pci_controller {
|
||||
int index; /* PCI domain number */
|
||||
struct pci_bus *root_bus;
|
||||
|
||||
/* PCI I/O space resource for this controller. */
|
||||
struct resource io_space;
|
||||
char io_space_name[32];
|
||||
|
||||
/* PCI memory space resource for this controller. */
|
||||
struct resource mem_space;
|
||||
char mem_space_name[32];
|
||||
@@ -210,7 +218,8 @@ static inline int pcibios_assign_all_busses(void)
|
||||
}
|
||||
|
||||
#define PCIBIOS_MIN_MEM 0
|
||||
#define PCIBIOS_MIN_IO 0
|
||||
/* Minimum PCI I/O address, starting at the page boundary. */
|
||||
#define PCIBIOS_MIN_IO PAGE_SIZE
|
||||
|
||||
/* Use any cpu for PCI. */
|
||||
#define cpumask_of_pcibus(bus) cpu_online_mask
|
||||
|
||||
Reference in New Issue
Block a user