Commit 029baf14 authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Russell King

ARM: 7683/1: pci: add a align_resource hook

The PCI specifications says that an I/O region must be aligned on a 4
KB boundary, and a memory region aligned on a 1 MB boundary.

However, the Marvell PCIe interfaces rely on address decoding windows
(which allow to associate a range of physical addresses with a given
device). For PCIe memory windows, those windows are defined with a 1
MB granularity (which matches the PCI specs), but PCIe I/O windows can
only be defined with a 64 KB granularity, so they have to be 64 KB
aligned. We therefore need to tell the PCI core about this special
alignement requirement.

The PCI core already calls pcibios_align_resource() in the ARM PCI
core, specifically for such purposes. So this patch extends the ARM
PCI core so that it calls a ->align_resource() hook registered by the
PCI driver, exactly like the existing ->map_irq() and ->swizzle()
hooks.

A particular PCI driver can register a align_resource() hook, and do
its own specific alignement, depending on the specific constraints of
the underlying hardware.
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 01223f36
...@@ -30,6 +30,11 @@ struct hw_pci { ...@@ -30,6 +30,11 @@ struct hw_pci {
void (*postinit)(void); void (*postinit)(void);
u8 (*swizzle)(struct pci_dev *dev, u8 *pin); u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
resource_size_t (*align_resource)(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
resource_size_t size,
resource_size_t align);
}; };
/* /*
...@@ -51,6 +56,12 @@ struct pci_sys_data { ...@@ -51,6 +56,12 @@ struct pci_sys_data {
u8 (*swizzle)(struct pci_dev *, u8 *); u8 (*swizzle)(struct pci_dev *, u8 *);
/* IRQ mapping */ /* IRQ mapping */
int (*map_irq)(const struct pci_dev *, u8, u8); int (*map_irq)(const struct pci_dev *, u8, u8);
/* Resource alignement requirements */
resource_size_t (*align_resource)(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
resource_size_t size,
resource_size_t align);
void *private_data; /* platform controller private data */ void *private_data; /* platform controller private data */
}; };
......
...@@ -462,6 +462,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head) ...@@ -462,6 +462,7 @@ static void pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
sys->busnr = busnr; sys->busnr = busnr;
sys->swizzle = hw->swizzle; sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq; sys->map_irq = hw->map_irq;
sys->align_resource = hw->align_resource;
INIT_LIST_HEAD(&sys->resources); INIT_LIST_HEAD(&sys->resources);
if (hw->private_data) if (hw->private_data)
...@@ -574,6 +575,8 @@ char * __init pcibios_setup(char *str) ...@@ -574,6 +575,8 @@ char * __init pcibios_setup(char *str)
resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t pcibios_align_resource(void *data, const struct resource *res,
resource_size_t size, resource_size_t align) resource_size_t size, resource_size_t align)
{ {
struct pci_dev *dev = data;
struct pci_sys_data *sys = dev->sysdata;
resource_size_t start = res->start; resource_size_t start = res->start;
if (res->flags & IORESOURCE_IO && start & 0x300) if (res->flags & IORESOURCE_IO && start & 0x300)
...@@ -581,6 +584,9 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, ...@@ -581,6 +584,9 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
start = (start + align - 1) & ~(align - 1); start = (start + align - 1) & ~(align - 1);
if (sys->align_resource)
return sys->align_resource(dev, res, start, size, align);
return start; return start;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment