aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parisc/lba_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parisc/lba_pci.c')
-rw-r--r--drivers/parisc/lba_pci.c65
1 files changed, 61 insertions, 4 deletions
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 2ef7103270bb..19f6f70c67d3 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -613,6 +613,54 @@ truncate_pat_collision(struct resource *root, struct resource *new)
return 0; /* truncation successful */
}
+/*
+ * extend_lmmio_len: extend lmmio range to maximum length
+ *
+ * This is needed at least on C8000 systems to get the ATI FireGL card
+ * working. On other systems we will currently not extend the lmmio space.
+ */
+static unsigned long
+extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
+{
+ struct resource *tmp;
+
+ pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n",
+ end - start, lba_len);
+
+ lba_len = min(lba_len+1, 256UL*1024*1024); /* limit to 256 MB */
+
+ pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - original\n", start, end);
+
+ if (boot_cpu_data.cpu_type < mako) {
+ pr_info("LBA: Not a C8000 system - not extending LMMIO range.\n");
+ return end;
+ }
+
+ end += lba_len;
+ if (end < start) /* fix overflow */
+ end = -1ULL;
+
+ pr_debug("LBA: lmmio_space [0x%lx-0x%lx] - current\n", start, end);
+
+ /* first overlap */
+ for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
+ pr_debug("LBA: testing %pR\n", tmp);
+ if (tmp->start == start)
+ continue; /* ignore ourself */
+ if (tmp->end < start)
+ continue;
+ if (tmp->start > end)
+ continue;
+ if (end >= tmp->start)
+ end = tmp->start - 1;
+ }
+
+ pr_info("LBA: lmmio_space [0x%lx-0x%lx] - new\n", start, end);
+
+ /* return new end */
+ return end;
+}
+
#else
#define truncate_pat_collision(r,n) (0)
#endif
@@ -668,7 +716,7 @@ lba_fixup_bus(struct pci_bus *bus)
BUG();
}
- if (ldev->hba.elmmio_space.start) {
+ if (ldev->hba.elmmio_space.flags) {
err = request_resource(&iomem_resource,
&(ldev->hba.elmmio_space));
if (err < 0) {
@@ -993,7 +1041,15 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
case PAT_LMMIO:
/* used to fix up pre-initialized MEM BARs */
- if (!lba_dev->hba.lmmio_space.start) {
+ if (!lba_dev->hba.lmmio_space.flags) {
+ unsigned long lba_len;
+
+ lba_len = ~READ_REG32(lba_dev->hba.base_addr
+ + LBA_LMMIO_MASK);
+ if ((p->end - p->start) != lba_len)
+ p->end = extend_lmmio_len(p->start,
+ p->end, lba_len);
+
sprintf(lba_dev->hba.lmmio_name,
"PCI%02x LMMIO",
(int)lba_dev->hba.bus_num.start);
@@ -1001,7 +1057,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
io->start;
r = &lba_dev->hba.lmmio_space;
r->name = lba_dev->hba.lmmio_name;
- } else if (!lba_dev->hba.elmmio_space.start) {
+ } else if (!lba_dev->hba.elmmio_space.flags) {
sprintf(lba_dev->hba.elmmio_name,
"PCI%02x ELMMIO",
(int)lba_dev->hba.bus_num.start);
@@ -1096,6 +1152,7 @@ lba_legacy_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
r->name = "LBA PCI Busses";
r->start = lba_num & 0xff;
r->end = (lba_num>>8) & 0xff;
+ r->flags = IORESOURCE_BUS;
/* Set up local PCI Bus resources - we don't need them for
** Legacy boxes but it's nice to see in /proc/iomem.
@@ -1494,7 +1551,7 @@ lba_driver_probe(struct parisc_device *dev)
pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
HBA_PORT_BASE(lba_dev->hba.hba_num));
- if (lba_dev->hba.elmmio_space.start)
+ if (lba_dev->hba.elmmio_space.flags)
pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
lba_dev->hba.lmmio_space_offset);
if (lba_dev->hba.lmmio_space.flags)