Skip to content

Commit

Permalink
parisc: fix LMMIO mismatch between PAT length and MASK register
Browse files Browse the repository at this point in the history
The LMMIO length reported by PAT and the length given by the LBA MASK
register are not consistent. This leads e.g. to a not-working ATI FireGL
card with the radeon DRM driver since the memory can't be mapped.

Fix this by correctly adjusting the resource sizes.

Signed-off-by: Helge Deller <[email protected]>
Cc: <[email protected]> # 3.10
  • Loading branch information
hdeller committed Jul 9, 2013
1 parent d2b4a64 commit dac76f1
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions drivers/parisc/lba_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -994,6 +1042,14 @@ 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.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);
Expand Down

0 comments on commit dac76f1

Please sign in to comment.