diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 12:18:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-15 12:18:07 -0400 |
commit | 66a4fe0cb80a9fde8cb173289afb863fd279466a (patch) | |
tree | e1180ba7cbd123fb2f0bf510a955704725465776 /drivers/char/agp | |
parent | 18240904960a39e582ced8ba8ececb10b8c22dd3 (diff) | |
parent | 121264827656f5f06328b17983c796af17dc5949 (diff) |
Merge branch 'agp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6
* 'agp-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6:
agp/intel: remove restore in resume
agp: fix uninorth build
intel-agp: Set dma mask for i915
agp: kill phys_to_gart() and gart_to_phys()
intel-agp: fix sglist allocation to avoid vmalloc()
intel-agp: Move repeated sglist free into separate function
agp: Switch agp_{un,}map_page() to take struct page * argument
agp: tidy up handling of scratch pages w.r.t. DMA API
intel_agp: Use PCI DMA API correctly on chipsets new enough to have IOMMU
agp: Add generic support for graphics dma remapping
agp: Switch mask_memory() method to take address argument again, not page
Diffstat (limited to 'drivers/char/agp')
-rw-r--r-- | drivers/char/agp/agp.h | 15 | ||||
-rw-r--r-- | drivers/char/agp/ali-agp.c | 4 | ||||
-rw-r--r-- | drivers/char/agp/amd-k7-agp.c | 10 | ||||
-rw-r--r-- | drivers/char/agp/amd64-agp.c | 7 | ||||
-rw-r--r-- | drivers/char/agp/ati-agp.c | 7 | ||||
-rw-r--r-- | drivers/char/agp/backend.c | 32 | ||||
-rw-r--r-- | drivers/char/agp/efficeon-agp.c | 4 | ||||
-rw-r--r-- | drivers/char/agp/generic.c | 20 | ||||
-rw-r--r-- | drivers/char/agp/hp-agp.c | 8 | ||||
-rw-r--r-- | drivers/char/agp/i460-agp.c | 17 | ||||
-rw-r--r-- | drivers/char/agp/intel-agp.c | 182 | ||||
-rw-r--r-- | drivers/char/agp/nvidia-agp.c | 2 | ||||
-rw-r--r-- | drivers/char/agp/parisc-agp.c | 12 | ||||
-rw-r--r-- | drivers/char/agp/sgi-agp.c | 8 | ||||
-rw-r--r-- | drivers/char/agp/sworks-agp.c | 10 | ||||
-rw-r--r-- | drivers/char/agp/uninorth-agp.c | 4 |
16 files changed, 250 insertions, 92 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 178e2e9e9f09..d6f36c004d9b 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -107,7 +107,7 @@ struct agp_bridge_driver { | |||
107 | void (*agp_enable)(struct agp_bridge_data *, u32); | 107 | void (*agp_enable)(struct agp_bridge_data *, u32); |
108 | void (*cleanup)(void); | 108 | void (*cleanup)(void); |
109 | void (*tlb_flush)(struct agp_memory *); | 109 | void (*tlb_flush)(struct agp_memory *); |
110 | unsigned long (*mask_memory)(struct agp_bridge_data *, struct page *, int); | 110 | unsigned long (*mask_memory)(struct agp_bridge_data *, dma_addr_t, int); |
111 | void (*cache_flush)(void); | 111 | void (*cache_flush)(void); |
112 | int (*create_gatt_table)(struct agp_bridge_data *); | 112 | int (*create_gatt_table)(struct agp_bridge_data *); |
113 | int (*free_gatt_table)(struct agp_bridge_data *); | 113 | int (*free_gatt_table)(struct agp_bridge_data *); |
@@ -121,6 +121,11 @@ struct agp_bridge_driver { | |||
121 | void (*agp_destroy_pages)(struct agp_memory *); | 121 | void (*agp_destroy_pages)(struct agp_memory *); |
122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
123 | void (*chipset_flush)(struct agp_bridge_data *); | 123 | void (*chipset_flush)(struct agp_bridge_data *); |
124 | |||
125 | int (*agp_map_page)(struct page *page, dma_addr_t *ret); | ||
126 | void (*agp_unmap_page)(struct page *page, dma_addr_t dma); | ||
127 | int (*agp_map_memory)(struct agp_memory *mem); | ||
128 | void (*agp_unmap_memory)(struct agp_memory *mem); | ||
124 | }; | 129 | }; |
125 | 130 | ||
126 | struct agp_bridge_data { | 131 | struct agp_bridge_data { |
@@ -134,7 +139,8 @@ struct agp_bridge_data { | |||
134 | u32 __iomem *gatt_table; | 139 | u32 __iomem *gatt_table; |
135 | u32 *gatt_table_real; | 140 | u32 *gatt_table_real; |
136 | unsigned long scratch_page; | 141 | unsigned long scratch_page; |
137 | unsigned long scratch_page_real; | 142 | struct page *scratch_page_page; |
143 | dma_addr_t scratch_page_dma; | ||
138 | unsigned long gart_bus_addr; | 144 | unsigned long gart_bus_addr; |
139 | unsigned long gatt_bus_addr; | 145 | unsigned long gatt_bus_addr; |
140 | u32 mode; | 146 | u32 mode; |
@@ -291,7 +297,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge); | |||
291 | void global_cache_flush(void); | 297 | void global_cache_flush(void); |
292 | void get_agp_version(struct agp_bridge_data *bridge); | 298 | void get_agp_version(struct agp_bridge_data *bridge); |
293 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, | 299 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, |
294 | struct page *page, int type); | 300 | dma_addr_t phys, int type); |
295 | int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge, | 301 | int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge, |
296 | int type); | 302 | int type); |
297 | struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); | 303 | struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); |
@@ -312,9 +318,6 @@ void agp3_generic_cleanup(void); | |||
312 | #define AGP_GENERIC_SIZES_ENTRIES 11 | 318 | #define AGP_GENERIC_SIZES_ENTRIES 11 |
313 | extern const struct aper_size_info_16 agp3_generic_sizes[]; | 319 | extern const struct aper_size_info_16 agp3_generic_sizes[]; |
314 | 320 | ||
315 | #define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) | ||
316 | #define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) | ||
317 | |||
318 | extern int agp_off; | 321 | extern int agp_off; |
319 | extern int agp_try_unsupported_boot; | 322 | extern int agp_try_unsupported_boot; |
320 | 323 | ||
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 201ef3ffd484..d2ce68f27e4b 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -152,7 +152,7 @@ static struct page *m1541_alloc_page(struct agp_bridge_data *bridge) | |||
152 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 152 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
153 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 153 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
154 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 154 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
155 | phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN )); | 155 | page_to_phys(page)) | ALI_CACHE_FLUSH_EN )); |
156 | return page; | 156 | return page; |
157 | } | 157 | } |
158 | 158 | ||
@@ -180,7 +180,7 @@ static void m1541_destroy_page(struct page *page, int flags) | |||
180 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 180 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
181 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 181 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
182 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 182 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
183 | phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN)); | 183 | page_to_phys(page)) | ALI_CACHE_FLUSH_EN)); |
184 | } | 184 | } |
185 | agp_generic_destroy_page(page, flags); | 185 | agp_generic_destroy_page(page, flags); |
186 | } | 186 | } |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index ba9bde71eaaf..73dbf40c874d 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -44,7 +44,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) | |||
44 | #ifndef CONFIG_X86 | 44 | #ifndef CONFIG_X86 |
45 | SetPageReserved(virt_to_page(page_map->real)); | 45 | SetPageReserved(virt_to_page(page_map->real)); |
46 | global_cache_flush(); | 46 | global_cache_flush(); |
47 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), | 47 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), |
48 | PAGE_SIZE); | 48 | PAGE_SIZE); |
49 | if (page_map->remapped == NULL) { | 49 | if (page_map->remapped == NULL) { |
50 | ClearPageReserved(virt_to_page(page_map->real)); | 50 | ClearPageReserved(virt_to_page(page_map->real)); |
@@ -160,7 +160,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
160 | 160 | ||
161 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 161 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
162 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; | 162 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; |
163 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); | 163 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); |
164 | 164 | ||
165 | /* Get the address for the gart region. | 165 | /* Get the address for the gart region. |
166 | * This is a bus address even on the alpha, b/c its | 166 | * This is a bus address even on the alpha, b/c its |
@@ -173,7 +173,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
173 | 173 | ||
174 | /* Calculate the agp offset */ | 174 | /* Calculate the agp offset */ |
175 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 175 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
176 | writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, | 176 | writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, |
177 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 177 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
178 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 178 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
179 | } | 179 | } |
@@ -325,7 +325,9 @@ static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
325 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 325 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
326 | cur_gatt = GET_GATT(addr); | 326 | cur_gatt = GET_GATT(addr); |
327 | writel(agp_generic_mask_memory(agp_bridge, | 327 | writel(agp_generic_mask_memory(agp_bridge, |
328 | mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); | 328 | page_to_phys(mem->pages[i]), |
329 | mem->type), | ||
330 | cur_gatt+GET_GATT_OFF(addr)); | ||
329 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ | 331 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ |
330 | } | 332 | } |
331 | amd_irongate_tlbflush(mem); | 333 | amd_irongate_tlbflush(mem); |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 3bf5dda90f4a..2fb2e6cc322a 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -79,7 +79,8 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
79 | 79 | ||
80 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 80 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
81 | tmp = agp_bridge->driver->mask_memory(agp_bridge, | 81 | tmp = agp_bridge->driver->mask_memory(agp_bridge, |
82 | mem->pages[i], mask_type); | 82 | page_to_phys(mem->pages[i]), |
83 | mask_type); | ||
83 | 84 | ||
84 | BUG_ON(tmp & 0xffffff0000000ffcULL); | 85 | BUG_ON(tmp & 0xffffff0000000ffcULL); |
85 | pte = (tmp & 0x000000ff00000000ULL) >> 28; | 86 | pte = (tmp & 0x000000ff00000000ULL) >> 28; |
@@ -177,7 +178,7 @@ static const struct aper_size_info_32 amd_8151_sizes[7] = | |||
177 | 178 | ||
178 | static int amd_8151_configure(void) | 179 | static int amd_8151_configure(void) |
179 | { | 180 | { |
180 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); | 181 | unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); |
181 | int i; | 182 | int i; |
182 | 183 | ||
183 | /* Configure AGP regs in each x86-64 host bridge. */ | 184 | /* Configure AGP regs in each x86-64 host bridge. */ |
@@ -557,7 +558,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) | |||
557 | { | 558 | { |
558 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 559 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
559 | 560 | ||
560 | release_mem_region(virt_to_gart(bridge->gatt_table_real), | 561 | release_mem_region(virt_to_phys(bridge->gatt_table_real), |
561 | amd64_aperture_sizes[bridge->aperture_size_idx].size); | 562 | amd64_aperture_sizes[bridge->aperture_size_idx].size); |
562 | agp_remove_bridge(bridge); | 563 | agp_remove_bridge(bridge); |
563 | agp_put_bridge(bridge); | 564 | agp_put_bridge(bridge); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 33656e144cc5..3b2ecbe86ebe 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -302,7 +302,8 @@ static int ati_insert_memory(struct agp_memory * mem, | |||
302 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 302 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
303 | cur_gatt = GET_GATT(addr); | 303 | cur_gatt = GET_GATT(addr); |
304 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 304 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
305 | mem->pages[i], mem->type), | 305 | page_to_phys(mem->pages[i]), |
306 | mem->type), | ||
306 | cur_gatt+GET_GATT_OFF(addr)); | 307 | cur_gatt+GET_GATT_OFF(addr)); |
307 | } | 308 | } |
308 | readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ | 309 | readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ |
@@ -359,7 +360,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
359 | 360 | ||
360 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 361 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
361 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; | 362 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; |
362 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); | 363 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); |
363 | 364 | ||
364 | /* Write out the size register */ | 365 | /* Write out the size register */ |
365 | current_size = A_SIZE_LVL2(agp_bridge->current_size); | 366 | current_size = A_SIZE_LVL2(agp_bridge->current_size); |
@@ -389,7 +390,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
389 | 390 | ||
390 | /* Calculate the agp offset */ | 391 | /* Calculate the agp offset */ |
391 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 392 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
392 | writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, | 393 | writel(virt_to_phys(ati_generic_private.gatt_pages[i]->real) | 1, |
393 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 394 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
394 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 395 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
395 | } | 396 | } |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index cfa5a649dfe7..ad87753f6de4 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -149,9 +149,21 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
149 | return -ENOMEM; | 149 | return -ENOMEM; |
150 | } | 150 | } |
151 | 151 | ||
152 | bridge->scratch_page_real = phys_to_gart(page_to_phys(page)); | 152 | bridge->scratch_page_page = page; |
153 | bridge->scratch_page = | 153 | if (bridge->driver->agp_map_page) { |
154 | bridge->driver->mask_memory(bridge, page, 0); | 154 | if (bridge->driver->agp_map_page(page, |
155 | &bridge->scratch_page_dma)) { | ||
156 | dev_err(&bridge->dev->dev, | ||
157 | "unable to dma-map scratch page\n"); | ||
158 | rc = -ENOMEM; | ||
159 | goto err_out_nounmap; | ||
160 | } | ||
161 | } else { | ||
162 | bridge->scratch_page_dma = page_to_phys(page); | ||
163 | } | ||
164 | |||
165 | bridge->scratch_page = bridge->driver->mask_memory(bridge, | ||
166 | bridge->scratch_page_dma, 0); | ||
155 | } | 167 | } |
156 | 168 | ||
157 | size_value = bridge->driver->fetch_size(); | 169 | size_value = bridge->driver->fetch_size(); |
@@ -191,8 +203,14 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
191 | return 0; | 203 | return 0; |
192 | 204 | ||
193 | err_out: | 205 | err_out: |
206 | if (bridge->driver->needs_scratch_page && | ||
207 | bridge->driver->agp_unmap_page) { | ||
208 | bridge->driver->agp_unmap_page(bridge->scratch_page_page, | ||
209 | bridge->scratch_page_dma); | ||
210 | } | ||
211 | err_out_nounmap: | ||
194 | if (bridge->driver->needs_scratch_page) { | 212 | if (bridge->driver->needs_scratch_page) { |
195 | void *va = gart_to_virt(bridge->scratch_page_real); | 213 | void *va = page_address(bridge->scratch_page_page); |
196 | 214 | ||
197 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); | 215 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); |
198 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); | 216 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); |
@@ -219,7 +237,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) | |||
219 | 237 | ||
220 | if (bridge->driver->agp_destroy_page && | 238 | if (bridge->driver->agp_destroy_page && |
221 | bridge->driver->needs_scratch_page) { | 239 | bridge->driver->needs_scratch_page) { |
222 | void *va = gart_to_virt(bridge->scratch_page_real); | 240 | void *va = page_address(bridge->scratch_page_page); |
241 | |||
242 | if (bridge->driver->agp_unmap_page) | ||
243 | bridge->driver->agp_unmap_page(bridge->scratch_page_page, | ||
244 | bridge->scratch_page_dma); | ||
223 | 245 | ||
224 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); | 246 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); |
225 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); | 247 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); |
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 35d50f2861b6..793f39ea9618 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
@@ -67,7 +67,7 @@ static const struct gatt_mask efficeon_generic_masks[] = | |||
67 | /* This function does the same thing as mask_memory() for this chipset... */ | 67 | /* This function does the same thing as mask_memory() for this chipset... */ |
68 | static inline unsigned long efficeon_mask_memory(struct page *page) | 68 | static inline unsigned long efficeon_mask_memory(struct page *page) |
69 | { | 69 | { |
70 | unsigned long addr = phys_to_gart(page_to_phys(page)); | 70 | unsigned long addr = page_to_phys(page); |
71 | return addr | 0x00000001; | 71 | return addr | 0x00000001; |
72 | } | 72 | } |
73 | 73 | ||
@@ -226,7 +226,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) | |||
226 | 226 | ||
227 | efficeon_private.l1_table[index] = page; | 227 | efficeon_private.l1_table[index] = page; |
228 | 228 | ||
229 | value = virt_to_gart((unsigned long *)page) | pati | present | index; | 229 | value = virt_to_phys((unsigned long *)page) | pati | present | index; |
230 | 230 | ||
231 | pci_write_config_dword(agp_bridge->dev, | 231 | pci_write_config_dword(agp_bridge->dev, |
232 | EFFICEON_ATTPAGE, value); | 232 | EFFICEON_ATTPAGE, value); |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 1e8b461b91f1..c50543966eb2 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -437,6 +437,12 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start) | |||
437 | curr->bridge->driver->cache_flush(); | 437 | curr->bridge->driver->cache_flush(); |
438 | curr->is_flushed = true; | 438 | curr->is_flushed = true; |
439 | } | 439 | } |
440 | |||
441 | if (curr->bridge->driver->agp_map_memory) { | ||
442 | ret_val = curr->bridge->driver->agp_map_memory(curr); | ||
443 | if (ret_val) | ||
444 | return ret_val; | ||
445 | } | ||
440 | ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); | 446 | ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); |
441 | 447 | ||
442 | if (ret_val != 0) | 448 | if (ret_val != 0) |
@@ -478,6 +484,9 @@ int agp_unbind_memory(struct agp_memory *curr) | |||
478 | if (ret_val != 0) | 484 | if (ret_val != 0) |
479 | return ret_val; | 485 | return ret_val; |
480 | 486 | ||
487 | if (curr->bridge->driver->agp_unmap_memory) | ||
488 | curr->bridge->driver->agp_unmap_memory(curr); | ||
489 | |||
481 | curr->is_bound = false; | 490 | curr->is_bound = false; |
482 | curr->pg_start = 0; | 491 | curr->pg_start = 0; |
483 | spin_lock(&curr->bridge->mapped_lock); | 492 | spin_lock(&curr->bridge->mapped_lock); |
@@ -979,7 +988,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
979 | set_memory_uc((unsigned long)table, 1 << page_order); | 988 | set_memory_uc((unsigned long)table, 1 << page_order); |
980 | bridge->gatt_table = (void *)table; | 989 | bridge->gatt_table = (void *)table; |
981 | #else | 990 | #else |
982 | bridge->gatt_table = ioremap_nocache(virt_to_gart(table), | 991 | bridge->gatt_table = ioremap_nocache(virt_to_phys(table), |
983 | (PAGE_SIZE * (1 << page_order))); | 992 | (PAGE_SIZE * (1 << page_order))); |
984 | bridge->driver->cache_flush(); | 993 | bridge->driver->cache_flush(); |
985 | #endif | 994 | #endif |
@@ -992,7 +1001,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
992 | 1001 | ||
993 | return -ENOMEM; | 1002 | return -ENOMEM; |
994 | } | 1003 | } |
995 | bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); | 1004 | bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); |
996 | 1005 | ||
997 | /* AK: bogus, should encode addresses > 4GB */ | 1006 | /* AK: bogus, should encode addresses > 4GB */ |
998 | for (i = 0; i < num_entries; i++) { | 1007 | for (i = 0; i < num_entries; i++) { |
@@ -1132,7 +1141,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) | |||
1132 | } | 1141 | } |
1133 | 1142 | ||
1134 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1143 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
1135 | writel(bridge->driver->mask_memory(bridge, mem->pages[i], mask_type), | 1144 | writel(bridge->driver->mask_memory(bridge, |
1145 | page_to_phys(mem->pages[i]), | ||
1146 | mask_type), | ||
1136 | bridge->gatt_table+j); | 1147 | bridge->gatt_table+j); |
1137 | } | 1148 | } |
1138 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ | 1149 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ |
@@ -1347,9 +1358,8 @@ void global_cache_flush(void) | |||
1347 | EXPORT_SYMBOL(global_cache_flush); | 1358 | EXPORT_SYMBOL(global_cache_flush); |
1348 | 1359 | ||
1349 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, | 1360 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, |
1350 | struct page *page, int type) | 1361 | dma_addr_t addr, int type) |
1351 | { | 1362 | { |
1352 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
1353 | /* memory type is ignored in the generic routine */ | 1363 | /* memory type is ignored in the generic routine */ |
1354 | if (bridge->driver->masks) | 1364 | if (bridge->driver->masks) |
1355 | return addr | bridge->driver->masks[0].mask; | 1365 | return addr | bridge->driver->masks[0].mask; |
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 8f3d4c184914..501e293e5ad0 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
@@ -107,7 +107,7 @@ static int __init hp_zx1_ioc_shared(void) | |||
107 | hp->gart_size = HP_ZX1_GART_SIZE; | 107 | hp->gart_size = HP_ZX1_GART_SIZE; |
108 | hp->gatt_entries = hp->gart_size / hp->io_page_size; | 108 | hp->gatt_entries = hp->gart_size / hp->io_page_size; |
109 | 109 | ||
110 | hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); | 110 | hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); |
111 | hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; | 111 | hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; |
112 | 112 | ||
113 | if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { | 113 | if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { |
@@ -246,7 +246,7 @@ hp_zx1_configure (void) | |||
246 | agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); | 246 | agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); |
247 | 247 | ||
248 | if (hp->io_pdir_owner) { | 248 | if (hp->io_pdir_owner) { |
249 | writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); | 249 | writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); |
250 | readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); | 250 | readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); |
251 | writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); | 251 | writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); |
252 | readl(hp->ioc_regs+HP_ZX1_TCNFG); | 252 | readl(hp->ioc_regs+HP_ZX1_TCNFG); |
@@ -394,10 +394,8 @@ hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | static unsigned long | 396 | static unsigned long |
397 | hp_zx1_mask_memory (struct agp_bridge_data *bridge, | 397 | hp_zx1_mask_memory (struct agp_bridge_data *bridge, dma_addr_t addr, int type) |
398 | struct page *page, int type) | ||
399 | { | 398 | { |
400 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
401 | return HP_ZX1_PDIR_VALID_BIT | addr; | 399 | return HP_ZX1_PDIR_VALID_BIT | addr; |
402 | } | 400 | } |
403 | 401 | ||
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 60cc35bb5db7..e763d3312ce7 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #define WR_FLUSH_GATT(index) RD_GATT(index) | 61 | #define WR_FLUSH_GATT(index) RD_GATT(index) |
62 | 62 | ||
63 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, | 63 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, |
64 | unsigned long addr, int type); | 64 | dma_addr_t addr, int type); |
65 | 65 | ||
66 | static struct { | 66 | static struct { |
67 | void *gatt; /* ioremap'd GATT area */ | 67 | void *gatt; /* ioremap'd GATT area */ |
@@ -325,7 +325,7 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem, | |||
325 | 325 | ||
326 | io_page_size = 1UL << I460_IO_PAGE_SHIFT; | 326 | io_page_size = 1UL << I460_IO_PAGE_SHIFT; |
327 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { | 327 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { |
328 | paddr = phys_to_gart(page_to_phys(mem->pages[i])); | 328 | paddr = page_to_phys(mem->pages[i]); |
329 | for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) | 329 | for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) |
330 | WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type)); | 330 | WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type)); |
331 | } | 331 | } |
@@ -382,7 +382,7 @@ static int i460_alloc_large_page (struct lp_desc *lp) | |||
382 | return -ENOMEM; | 382 | return -ENOMEM; |
383 | } | 383 | } |
384 | 384 | ||
385 | lp->paddr = phys_to_gart(page_to_phys(lp->page)); | 385 | lp->paddr = page_to_phys(lp->page); |
386 | lp->refcount = 0; | 386 | lp->refcount = 0; |
387 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); | 387 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); |
388 | return 0; | 388 | return 0; |
@@ -546,20 +546,13 @@ static void i460_destroy_page (struct page *page, int flags) | |||
546 | #endif /* I460_LARGE_IO_PAGES */ | 546 | #endif /* I460_LARGE_IO_PAGES */ |
547 | 547 | ||
548 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, | 548 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, |
549 | unsigned long addr, int type) | 549 | dma_addr_t addr, int type) |
550 | { | 550 | { |
551 | /* Make sure the returned address is a valid GATT entry */ | 551 | /* Make sure the returned address is a valid GATT entry */ |
552 | return bridge->driver->masks[0].mask | 552 | return bridge->driver->masks[0].mask |
553 | | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12); | 553 | | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12); |
554 | } | 554 | } |
555 | 555 | ||
556 | static unsigned long i460_page_mask_memory(struct agp_bridge_data *bridge, | ||
557 | struct page *page, int type) | ||
558 | { | ||
559 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
560 | return i460_mask_memory(bridge, addr, type); | ||
561 | } | ||
562 | |||
563 | const struct agp_bridge_driver intel_i460_driver = { | 556 | const struct agp_bridge_driver intel_i460_driver = { |
564 | .owner = THIS_MODULE, | 557 | .owner = THIS_MODULE, |
565 | .aperture_sizes = i460_sizes, | 558 | .aperture_sizes = i460_sizes, |
@@ -569,7 +562,7 @@ const struct agp_bridge_driver intel_i460_driver = { | |||
569 | .fetch_size = i460_fetch_size, | 562 | .fetch_size = i460_fetch_size, |
570 | .cleanup = i460_cleanup, | 563 | .cleanup = i460_cleanup, |
571 | .tlb_flush = i460_tlb_flush, | 564 | .tlb_flush = i460_tlb_flush, |
572 | .mask_memory = i460_page_mask_memory, | 565 | .mask_memory = i460_mask_memory, |
573 | .masks = i460_masks, | 566 | .masks = i460_masks, |
574 | .agp_enable = agp_generic_enable, | 567 | .agp_enable = agp_generic_enable, |
575 | .cache_flush = global_cache_flush, | 568 | .cache_flush = global_cache_flush, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index c58557790585..1540e693d91e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -10,6 +10,16 @@ | |||
10 | #include <linux/agp_backend.h> | 10 | #include <linux/agp_backend.h> |
11 | #include "agp.h" | 11 | #include "agp.h" |
12 | 12 | ||
13 | /* | ||
14 | * If we have Intel graphics, we're not going to have anything other than | ||
15 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent | ||
16 | * on the Intel IOMMU support (CONFIG_DMAR). | ||
17 | * Only newer chipsets need to bother with this, of course. | ||
18 | */ | ||
19 | #ifdef CONFIG_DMAR | ||
20 | #define USE_PCI_DMA_API 1 | ||
21 | #endif | ||
22 | |||
13 | #define PCI_DEVICE_ID_INTEL_E7221_HB 0x2588 | 23 | #define PCI_DEVICE_ID_INTEL_E7221_HB 0x2588 |
14 | #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a | 24 | #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a |
15 | #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 | 25 | #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 |
@@ -172,6 +182,123 @@ static struct _intel_private { | |||
172 | int resource_valid; | 182 | int resource_valid; |
173 | } intel_private; | 183 | } intel_private; |
174 | 184 | ||
185 | #ifdef USE_PCI_DMA_API | ||
186 | static int intel_agp_map_page(struct page *page, dma_addr_t *ret) | ||
187 | { | ||
188 | *ret = pci_map_page(intel_private.pcidev, page, 0, | ||
189 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
190 | if (pci_dma_mapping_error(intel_private.pcidev, *ret)) | ||
191 | return -EINVAL; | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | static void intel_agp_unmap_page(struct page *page, dma_addr_t dma) | ||
196 | { | ||
197 | pci_unmap_page(intel_private.pcidev, dma, | ||
198 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
199 | } | ||
200 | |||
201 | static void intel_agp_free_sglist(struct agp_memory *mem) | ||
202 | { | ||
203 | struct sg_table st; | ||
204 | |||
205 | st.sgl = mem->sg_list; | ||
206 | st.orig_nents = st.nents = mem->page_count; | ||
207 | |||
208 | sg_free_table(&st); | ||
209 | |||
210 | mem->sg_list = NULL; | ||
211 | mem->num_sg = 0; | ||
212 | } | ||
213 | |||
214 | static int intel_agp_map_memory(struct agp_memory *mem) | ||
215 | { | ||
216 | struct sg_table st; | ||
217 | struct scatterlist *sg; | ||
218 | int i; | ||
219 | |||
220 | DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); | ||
221 | |||
222 | if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | mem->sg_list = sg = st.sgl; | ||
226 | |||
227 | for (i = 0 ; i < mem->page_count; i++, sg = sg_next(sg)) | ||
228 | sg_set_page(sg, mem->pages[i], PAGE_SIZE, 0); | ||
229 | |||
230 | mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list, | ||
231 | mem->page_count, PCI_DMA_BIDIRECTIONAL); | ||
232 | if (unlikely(!mem->num_sg)) { | ||
233 | intel_agp_free_sglist(mem); | ||
234 | return -ENOMEM; | ||
235 | } | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static void intel_agp_unmap_memory(struct agp_memory *mem) | ||
240 | { | ||
241 | DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); | ||
242 | |||
243 | pci_unmap_sg(intel_private.pcidev, mem->sg_list, | ||
244 | mem->page_count, PCI_DMA_BIDIRECTIONAL); | ||
245 | intel_agp_free_sglist(mem); | ||
246 | } | ||
247 | |||
248 | static void intel_agp_insert_sg_entries(struct agp_memory *mem, | ||
249 | off_t pg_start, int mask_type) | ||
250 | { | ||
251 | struct scatterlist *sg; | ||
252 | int i, j; | ||
253 | |||
254 | j = pg_start; | ||
255 | |||
256 | WARN_ON(!mem->num_sg); | ||
257 | |||
258 | if (mem->num_sg == mem->page_count) { | ||
259 | for_each_sg(mem->sg_list, sg, mem->page_count, i) { | ||
260 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
261 | sg_dma_address(sg), mask_type), | ||
262 | intel_private.gtt+j); | ||
263 | j++; | ||
264 | } | ||
265 | } else { | ||
266 | /* sg may merge pages, but we have to seperate | ||
267 | * per-page addr for GTT */ | ||
268 | unsigned int len, m; | ||
269 | |||
270 | for_each_sg(mem->sg_list, sg, mem->num_sg, i) { | ||
271 | len = sg_dma_len(sg) / PAGE_SIZE; | ||
272 | for (m = 0; m < len; m++) { | ||
273 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
274 | sg_dma_address(sg) + m * PAGE_SIZE, | ||
275 | mask_type), | ||
276 | intel_private.gtt+j); | ||
277 | j++; | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | readl(intel_private.gtt+j-1); | ||
282 | } | ||
283 | |||
284 | #else | ||
285 | |||
286 | static void intel_agp_insert_sg_entries(struct agp_memory *mem, | ||
287 | off_t pg_start, int mask_type) | ||
288 | { | ||
289 | int i, j; | ||
290 | |||
291 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | ||
292 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
293 | page_to_phys(mem->pages[i]), mask_type), | ||
294 | intel_private.gtt+j); | ||
295 | } | ||
296 | |||
297 | readl(intel_private.gtt+j-1); | ||
298 | } | ||
299 | |||
300 | #endif | ||
301 | |||
175 | static int intel_i810_fetch_size(void) | 302 | static int intel_i810_fetch_size(void) |
176 | { | 303 | { |
177 | u32 smram_miscc; | 304 | u32 smram_miscc; |
@@ -345,8 +472,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
345 | global_cache_flush(); | 472 | global_cache_flush(); |
346 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 473 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
347 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 474 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
348 | mem->pages[i], | 475 | page_to_phys(mem->pages[i]), mask_type), |
349 | mask_type), | ||
350 | intel_private.registers+I810_PTE_BASE+(j*4)); | 476 | intel_private.registers+I810_PTE_BASE+(j*4)); |
351 | } | 477 | } |
352 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 478 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); |
@@ -463,9 +589,8 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
463 | } | 589 | } |
464 | 590 | ||
465 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, | 591 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, |
466 | struct page *page, int type) | 592 | dma_addr_t addr, int type) |
467 | { | 593 | { |
468 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
469 | /* Type checking must be done elsewhere */ | 594 | /* Type checking must be done elsewhere */ |
470 | return addr | bridge->driver->masks[type].mask; | 595 | return addr | bridge->driver->masks[type].mask; |
471 | } | 596 | } |
@@ -853,7 +978,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
853 | 978 | ||
854 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 979 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
855 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 980 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
856 | mem->pages[i], mask_type), | 981 | page_to_phys(mem->pages[i]), mask_type), |
857 | intel_private.registers+I810_PTE_BASE+(j*4)); | 982 | intel_private.registers+I810_PTE_BASE+(j*4)); |
858 | } | 983 | } |
859 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 984 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); |
@@ -1017,6 +1142,12 @@ static int intel_i915_configure(void) | |||
1017 | 1142 | ||
1018 | intel_i9xx_setup_flush(); | 1143 | intel_i9xx_setup_flush(); |
1019 | 1144 | ||
1145 | #ifdef USE_PCI_DMA_API | ||
1146 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | ||
1147 | dev_err(&intel_private.pcidev->dev, | ||
1148 | "set gfx device dma mask 36bit failed!\n"); | ||
1149 | #endif | ||
1150 | |||
1020 | return 0; | 1151 | return 0; |
1021 | } | 1152 | } |
1022 | 1153 | ||
@@ -1041,7 +1172,7 @@ static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) | |||
1041 | static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | 1172 | static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, |
1042 | int type) | 1173 | int type) |
1043 | { | 1174 | { |
1044 | int i, j, num_entries; | 1175 | int num_entries; |
1045 | void *temp; | 1176 | void *temp; |
1046 | int ret = -EINVAL; | 1177 | int ret = -EINVAL; |
1047 | int mask_type; | 1178 | int mask_type; |
@@ -1065,7 +1196,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1065 | if ((pg_start + mem->page_count) > num_entries) | 1196 | if ((pg_start + mem->page_count) > num_entries) |
1066 | goto out_err; | 1197 | goto out_err; |
1067 | 1198 | ||
1068 | /* The i915 can't check the GTT for entries since its read only, | 1199 | /* The i915 can't check the GTT for entries since it's read only; |
1069 | * depend on the caller to make the correct offset decisions. | 1200 | * depend on the caller to make the correct offset decisions. |
1070 | */ | 1201 | */ |
1071 | 1202 | ||
@@ -1081,12 +1212,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1081 | if (!mem->is_flushed) | 1212 | if (!mem->is_flushed) |
1082 | global_cache_flush(); | 1213 | global_cache_flush(); |
1083 | 1214 | ||
1084 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1215 | intel_agp_insert_sg_entries(mem, pg_start, mask_type); |
1085 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
1086 | mem->pages[i], mask_type), intel_private.gtt+j); | ||
1087 | } | ||
1088 | |||
1089 | readl(intel_private.gtt+j-1); | ||
1090 | agp_bridge->driver->tlb_flush(mem); | 1216 | agp_bridge->driver->tlb_flush(mem); |
1091 | 1217 | ||
1092 | out: | 1218 | out: |
@@ -1198,9 +1324,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1198 | * this conditional. | 1324 | * this conditional. |
1199 | */ | 1325 | */ |
1200 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | 1326 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, |
1201 | struct page *page, int type) | 1327 | dma_addr_t addr, int type) |
1202 | { | 1328 | { |
1203 | dma_addr_t addr = phys_to_gart(page_to_phys(page)); | ||
1204 | /* Shift high bits down */ | 1329 | /* Shift high bits down */ |
1205 | addr |= (addr >> 28) & 0xf0; | 1330 | addr |= (addr >> 28) & 0xf0; |
1206 | 1331 | ||
@@ -2006,6 +2131,12 @@ static const struct agp_bridge_driver intel_915_driver = { | |||
2006 | .agp_destroy_pages = agp_generic_destroy_pages, | 2131 | .agp_destroy_pages = agp_generic_destroy_pages, |
2007 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2132 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2008 | .chipset_flush = intel_i915_chipset_flush, | 2133 | .chipset_flush = intel_i915_chipset_flush, |
2134 | #ifdef USE_PCI_DMA_API | ||
2135 | .agp_map_page = intel_agp_map_page, | ||
2136 | .agp_unmap_page = intel_agp_unmap_page, | ||
2137 | .agp_map_memory = intel_agp_map_memory, | ||
2138 | .agp_unmap_memory = intel_agp_unmap_memory, | ||
2139 | #endif | ||
2009 | }; | 2140 | }; |
2010 | 2141 | ||
2011 | static const struct agp_bridge_driver intel_i965_driver = { | 2142 | static const struct agp_bridge_driver intel_i965_driver = { |
@@ -2034,6 +2165,12 @@ static const struct agp_bridge_driver intel_i965_driver = { | |||
2034 | .agp_destroy_pages = agp_generic_destroy_pages, | 2165 | .agp_destroy_pages = agp_generic_destroy_pages, |
2035 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2166 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2036 | .chipset_flush = intel_i915_chipset_flush, | 2167 | .chipset_flush = intel_i915_chipset_flush, |
2168 | #ifdef USE_PCI_DMA_API | ||
2169 | .agp_map_page = intel_agp_map_page, | ||
2170 | .agp_unmap_page = intel_agp_unmap_page, | ||
2171 | .agp_map_memory = intel_agp_map_memory, | ||
2172 | .agp_unmap_memory = intel_agp_unmap_memory, | ||
2173 | #endif | ||
2037 | }; | 2174 | }; |
2038 | 2175 | ||
2039 | static const struct agp_bridge_driver intel_7505_driver = { | 2176 | static const struct agp_bridge_driver intel_7505_driver = { |
@@ -2088,6 +2225,12 @@ static const struct agp_bridge_driver intel_g33_driver = { | |||
2088 | .agp_destroy_pages = agp_generic_destroy_pages, | 2225 | .agp_destroy_pages = agp_generic_destroy_pages, |
2089 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 2226 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, |
2090 | .chipset_flush = intel_i915_chipset_flush, | 2227 | .chipset_flush = intel_i915_chipset_flush, |
2228 | #ifdef USE_PCI_DMA_API | ||
2229 | .agp_map_page = intel_agp_map_page, | ||
2230 | .agp_unmap_page = intel_agp_unmap_page, | ||
2231 | .agp_map_memory = intel_agp_map_memory, | ||
2232 | .agp_unmap_memory = intel_agp_unmap_memory, | ||
2233 | #endif | ||
2091 | }; | 2234 | }; |
2092 | 2235 | ||
2093 | static int find_gmch(u16 device) | 2236 | static int find_gmch(u16 device) |
@@ -2313,15 +2456,6 @@ static int agp_intel_resume(struct pci_dev *pdev) | |||
2313 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 2456 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
2314 | int ret_val; | 2457 | int ret_val; |
2315 | 2458 | ||
2316 | pci_restore_state(pdev); | ||
2317 | |||
2318 | /* We should restore our graphics device's config space, | ||
2319 | * as host bridge (00:00) resumes before graphics device (02:00), | ||
2320 | * then our access to its pci space can work right. | ||
2321 | */ | ||
2322 | if (intel_private.pcidev) | ||
2323 | pci_restore_state(intel_private.pcidev); | ||
2324 | |||
2325 | if (bridge->driver == &intel_generic_driver) | 2459 | if (bridge->driver == &intel_generic_driver) |
2326 | intel_configure(); | 2460 | intel_configure(); |
2327 | else if (bridge->driver == &intel_850_driver) | 2461 | else if (bridge->driver == &intel_850_driver) |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 263d71dd441c..7e36d2b4f9d4 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -225,7 +225,7 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type | |||
225 | } | 225 | } |
226 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 226 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
227 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 227 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
228 | mem->pages[i], mask_type), | 228 | page_to_phys(mem->pages[i]), mask_type), |
229 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); | 229 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); |
230 | } | 230 | } |
231 | 231 | ||
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index e077701ae3d9..60ab75104da9 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #define AGP8X_MODE (1 << AGP8X_MODE_BIT) | 32 | #define AGP8X_MODE (1 << AGP8X_MODE_BIT) |
33 | 33 | ||
34 | static unsigned long | 34 | static unsigned long |
35 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr, | 35 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, |
36 | int type); | 36 | int type); |
37 | 37 | ||
38 | static struct _parisc_agp_info { | 38 | static struct _parisc_agp_info { |
@@ -189,20 +189,12 @@ parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | static unsigned long | 191 | static unsigned long |
192 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr, | 192 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, |
193 | int type) | 193 | int type) |
194 | { | 194 | { |
195 | return SBA_PDIR_VALID_BIT | addr; | 195 | return SBA_PDIR_VALID_BIT | addr; |
196 | } | 196 | } |
197 | 197 | ||
198 | static unsigned long | ||
199 | parisc_agp_page_mask_memory(struct agp_bridge_data *bridge, struct page *page, | ||
200 | int type) | ||
201 | { | ||
202 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
203 | return SBA_PDIR_VALID_BIT | addr; | ||
204 | } | ||
205 | |||
206 | static void | 198 | static void |
207 | parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode) | 199 | parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode) |
208 | { | 200 | { |
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index d3ea2e4226b5..0d426ae39c85 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
@@ -70,10 +70,9 @@ static void sgi_tioca_tlbflush(struct agp_memory *mem) | |||
70 | * entry. | 70 | * entry. |
71 | */ | 71 | */ |
72 | static unsigned long | 72 | static unsigned long |
73 | sgi_tioca_mask_memory(struct agp_bridge_data *bridge, | 73 | sgi_tioca_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, |
74 | struct page *page, int type) | 74 | int type) |
75 | { | 75 | { |
76 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
77 | return tioca_physpage_to_gart(addr); | 76 | return tioca_physpage_to_gart(addr); |
78 | } | 77 | } |
79 | 78 | ||
@@ -190,7 +189,8 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
190 | 189 | ||
191 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 190 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
192 | table[j] = | 191 | table[j] = |
193 | bridge->driver->mask_memory(bridge, mem->pages[i], | 192 | bridge->driver->mask_memory(bridge, |
193 | page_to_phys(mem->pages[i]), | ||
194 | mem->type); | 194 | mem->type); |
195 | } | 195 | } |
196 | 196 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index b964a2199329..13acaaf64edb 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -155,7 +155,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
155 | /* Create a fake scratch directory */ | 155 | /* Create a fake scratch directory */ |
156 | for (i = 0; i < 1024; i++) { | 156 | for (i = 0; i < 1024; i++) { |
157 | writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); | 157 | writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); |
158 | writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); | 158 | writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); |
159 | } | 159 | } |
160 | 160 | ||
161 | retval = serverworks_create_gatt_pages(value->num_entries / 1024); | 161 | retval = serverworks_create_gatt_pages(value->num_entries / 1024); |
@@ -167,7 +167,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
167 | 167 | ||
168 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 168 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
169 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; | 169 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; |
170 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); | 170 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); |
171 | 171 | ||
172 | /* Get the address for the gart region. | 172 | /* Get the address for the gart region. |
173 | * This is a bus address even on the alpha, b/c its | 173 | * This is a bus address even on the alpha, b/c its |
@@ -179,7 +179,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
179 | 179 | ||
180 | /* Calculate the agp offset */ | 180 | /* Calculate the agp offset */ |
181 | for (i = 0; i < value->num_entries / 1024; i++) | 181 | for (i = 0; i < value->num_entries / 1024; i++) |
182 | writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); | 182 | writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); |
183 | 183 | ||
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
@@ -349,7 +349,9 @@ static int serverworks_insert_memory(struct agp_memory *mem, | |||
349 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 349 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
350 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 350 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
351 | cur_gatt = SVRWRKS_GET_GATT(addr); | 351 | cur_gatt = SVRWRKS_GET_GATT(addr); |
352 | writel(agp_bridge->driver->mask_memory(agp_bridge, mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); | 352 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
353 | page_to_phys(mem->pages[i]), mem->type), | ||
354 | cur_gatt+GET_GATT_OFF(addr)); | ||
353 | } | 355 | } |
354 | serverworks_tlbflush(mem); | 356 | serverworks_tlbflush(mem); |
355 | return 0; | 357 | return 0; |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index f192c3b9ad41..4317a5588daf 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -135,7 +135,7 @@ static int uninorth_configure(void) | |||
135 | if (is_u3) { | 135 | if (is_u3) { |
136 | pci_write_config_dword(agp_bridge->dev, | 136 | pci_write_config_dword(agp_bridge->dev, |
137 | UNI_N_CFG_GART_DUMMY_PAGE, | 137 | UNI_N_CFG_GART_DUMMY_PAGE, |
138 | agp_bridge->scratch_page_real >> 12); | 138 | page_to_phys(agp_bridge->scratch_page_page) >> 12); |
139 | } | 139 | } |
140 | 140 | ||
141 | return 0; | 141 | return 0; |
@@ -431,7 +431,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) | |||
431 | 431 | ||
432 | bridge->gatt_table_real = (u32 *) table; | 432 | bridge->gatt_table_real = (u32 *) table; |
433 | bridge->gatt_table = (u32 *)table; | 433 | bridge->gatt_table = (u32 *)table; |
434 | bridge->gatt_bus_addr = virt_to_gart(table); | 434 | bridge->gatt_bus_addr = virt_to_phys(table); |
435 | 435 | ||
436 | for (i = 0; i < num_entries; i++) | 436 | for (i = 0; i < num_entries; i++) |
437 | bridge->gatt_table[i] = 0; | 437 | bridge->gatt_table[i] = 0; |