diff options
Diffstat (limited to 'drivers/char/agp/intel-agp.c')
-rw-r--r-- | drivers/char/agp/intel-agp.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 7a748fa0dfce..8c9d50db5c3a 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -257,7 +257,7 @@ static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
257 | } | 257 | } |
258 | 258 | ||
259 | /* Exists to support ARGB cursors */ | 259 | /* Exists to support ARGB cursors */ |
260 | static void *i8xx_alloc_pages(void) | 260 | static struct page *i8xx_alloc_pages(void) |
261 | { | 261 | { |
262 | struct page *page; | 262 | struct page *page; |
263 | 263 | ||
@@ -272,17 +272,14 @@ static void *i8xx_alloc_pages(void) | |||
272 | } | 272 | } |
273 | get_page(page); | 273 | get_page(page); |
274 | atomic_inc(&agp_bridge->current_memory_agp); | 274 | atomic_inc(&agp_bridge->current_memory_agp); |
275 | return page_address(page); | 275 | return page; |
276 | } | 276 | } |
277 | 277 | ||
278 | static void i8xx_destroy_pages(void *addr) | 278 | static void i8xx_destroy_pages(struct page *page) |
279 | { | 279 | { |
280 | struct page *page; | 280 | if (page == NULL) |
281 | |||
282 | if (addr == NULL) | ||
283 | return; | 281 | return; |
284 | 282 | ||
285 | page = virt_to_page(addr); | ||
286 | set_pages_wb(page, 4); | 283 | set_pages_wb(page, 4); |
287 | put_page(page); | 284 | put_page(page); |
288 | __free_pages(page, 2); | 285 | __free_pages(page, 2); |
@@ -346,7 +343,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
346 | global_cache_flush(); | 343 | global_cache_flush(); |
347 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 344 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
348 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 345 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
349 | mem->memory[i], | 346 | mem->pages[i], |
350 | mask_type), | 347 | mask_type), |
351 | intel_private.registers+I810_PTE_BASE+(j*4)); | 348 | intel_private.registers+I810_PTE_BASE+(j*4)); |
352 | } | 349 | } |
@@ -389,37 +386,37 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
389 | static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) | 386 | static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) |
390 | { | 387 | { |
391 | struct agp_memory *new; | 388 | struct agp_memory *new; |
392 | void *addr; | 389 | struct page *page; |
393 | 390 | ||
394 | switch (pg_count) { | 391 | switch (pg_count) { |
395 | case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); | 392 | case 1: page = agp_bridge->driver->agp_alloc_page(agp_bridge); |
396 | break; | 393 | break; |
397 | case 4: | 394 | case 4: |
398 | /* kludge to get 4 physical pages for ARGB cursor */ | 395 | /* kludge to get 4 physical pages for ARGB cursor */ |
399 | addr = i8xx_alloc_pages(); | 396 | page = i8xx_alloc_pages(); |
400 | break; | 397 | break; |
401 | default: | 398 | default: |
402 | return NULL; | 399 | return NULL; |
403 | } | 400 | } |
404 | 401 | ||
405 | if (addr == NULL) | 402 | if (page == NULL) |
406 | return NULL; | 403 | return NULL; |
407 | 404 | ||
408 | new = agp_create_memory(pg_count); | 405 | new = agp_create_memory(pg_count); |
409 | if (new == NULL) | 406 | if (new == NULL) |
410 | return NULL; | 407 | return NULL; |
411 | 408 | ||
412 | new->memory[0] = virt_to_gart(addr); | 409 | new->pages[0] = page; |
413 | if (pg_count == 4) { | 410 | if (pg_count == 4) { |
414 | /* kludge to get 4 physical pages for ARGB cursor */ | 411 | /* kludge to get 4 physical pages for ARGB cursor */ |
415 | new->memory[1] = new->memory[0] + PAGE_SIZE; | 412 | new->pages[1] = new->pages[0] + 1; |
416 | new->memory[2] = new->memory[1] + PAGE_SIZE; | 413 | new->pages[2] = new->pages[1] + 1; |
417 | new->memory[3] = new->memory[2] + PAGE_SIZE; | 414 | new->pages[3] = new->pages[2] + 1; |
418 | } | 415 | } |
419 | new->page_count = pg_count; | 416 | new->page_count = pg_count; |
420 | new->num_scratch_pages = pg_count; | 417 | new->num_scratch_pages = pg_count; |
421 | new->type = AGP_PHYS_MEMORY; | 418 | new->type = AGP_PHYS_MEMORY; |
422 | new->physical = new->memory[0]; | 419 | new->physical = page_to_phys(new->pages[0]); |
423 | return new; | 420 | return new; |
424 | } | 421 | } |
425 | 422 | ||
@@ -451,13 +448,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
451 | agp_free_key(curr->key); | 448 | agp_free_key(curr->key); |
452 | if (curr->type == AGP_PHYS_MEMORY) { | 449 | if (curr->type == AGP_PHYS_MEMORY) { |
453 | if (curr->page_count == 4) | 450 | if (curr->page_count == 4) |
454 | i8xx_destroy_pages(gart_to_virt(curr->memory[0])); | 451 | i8xx_destroy_pages(curr->pages[0]); |
455 | else { | 452 | else { |
456 | void *va = gart_to_virt(curr->memory[0]); | 453 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
457 | |||
458 | agp_bridge->driver->agp_destroy_page(va, | ||
459 | AGP_PAGE_DESTROY_UNMAP); | 454 | AGP_PAGE_DESTROY_UNMAP); |
460 | agp_bridge->driver->agp_destroy_page(va, | 455 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
461 | AGP_PAGE_DESTROY_FREE); | 456 | AGP_PAGE_DESTROY_FREE); |
462 | } | 457 | } |
463 | agp_free_page_array(curr); | 458 | agp_free_page_array(curr); |
@@ -466,8 +461,9 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
466 | } | 461 | } |
467 | 462 | ||
468 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, | 463 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, |
469 | unsigned long addr, int type) | 464 | struct page *page, int type) |
470 | { | 465 | { |
466 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
471 | /* Type checking must be done elsewhere */ | 467 | /* Type checking must be done elsewhere */ |
472 | return addr | bridge->driver->masks[type].mask; | 468 | return addr | bridge->driver->masks[type].mask; |
473 | } | 469 | } |
@@ -855,7 +851,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
855 | 851 | ||
856 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 852 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
857 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 853 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
858 | mem->memory[i], mask_type), | 854 | mem->pages[i], mask_type), |
859 | intel_private.registers+I810_PTE_BASE+(j*4)); | 855 | intel_private.registers+I810_PTE_BASE+(j*4)); |
860 | } | 856 | } |
861 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 857 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); |
@@ -1085,7 +1081,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1085 | 1081 | ||
1086 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1082 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
1087 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 1083 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
1088 | mem->memory[i], mask_type), intel_private.gtt+j); | 1084 | mem->pages[i], mask_type), intel_private.gtt+j); |
1089 | } | 1085 | } |
1090 | 1086 | ||
1091 | readl(intel_private.gtt+j-1); | 1087 | readl(intel_private.gtt+j-1); |
@@ -1200,8 +1196,9 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
1200 | * this conditional. | 1196 | * this conditional. |
1201 | */ | 1197 | */ |
1202 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | 1198 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, |
1203 | unsigned long addr, int type) | 1199 | struct page *page, int type) |
1204 | { | 1200 | { |
1201 | dma_addr_t addr = phys_to_gart(page_to_phys(page)); | ||
1205 | /* Shift high bits down */ | 1202 | /* Shift high bits down */ |
1206 | addr |= (addr >> 28) & 0xf0; | 1203 | addr |= (addr >> 28) & 0xf0; |
1207 | 1204 | ||