diff options
author | Dave Airlie <airlied@redhat.com> | 2009-06-19 04:52:57 +0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-06-19 04:52:57 +0400 |
commit | a95fe463e73b8c7b2d97606ac86ce261f1270726 (patch) | |
tree | 8917b33b34e148dc4cce53374f15766f86975770 /drivers/char | |
parent | 95934f939c46ea2b37f3c91a4f8c82e003727761 (diff) | |
download | linux-a95fe463e73b8c7b2d97606ac86ce261f1270726.tar.xz |
agp: add user mapping support to ATI AGP bridge.
This should fix TTM/KMS on some of the original ATI IGP chipsets.
(rs100/rs200)
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/ati-agp.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 4d38baa209f5..33656e144cc5 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -269,12 +269,17 @@ static int ati_insert_memory(struct agp_memory * mem, int i, j, num_entries; unsigned long __iomem *cur_gatt; unsigned long addr; + int mask_type; num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; - if (type != 0 || mem->type != 0) + mask_type = agp_generic_type_to_mask_type(mem->bridge, type); + if (mask_type != 0 || type != mem->type) return -EINVAL; + if (mem->page_count == 0) + return 0; + if ((pg_start + mem->page_count) > num_entries) return -EINVAL; @@ -299,8 +304,8 @@ static int ati_insert_memory(struct agp_memory * mem, writel(agp_bridge->driver->mask_memory(agp_bridge, mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); - readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ } + readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ agp_bridge->driver->tlb_flush(mem); return 0; } @@ -311,17 +316,22 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, int i; unsigned long __iomem *cur_gatt; unsigned long addr; + int mask_type; - if (type != 0 || mem->type != 0) + mask_type = agp_generic_type_to_mask_type(mem->bridge, type); + if (mask_type != 0 || type != mem->type) return -EINVAL; + if (mem->page_count == 0) + return 0; + for (i = pg_start; i < (mem->page_count + pg_start); i++) { addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; cur_gatt = GET_GATT(addr); writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); - readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ } + readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ agp_bridge->driver->tlb_flush(mem); return 0; } |