diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-11-04 15:07:57 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-23 15:14:42 -0500 |
commit | 625dd9d331d8a1ce5ee4e9924a22f3e55b7ac615 (patch) | |
tree | bad37f7ecc7ef90134ea4eb9e51e788a946a654f /drivers | |
parent | 24a6b387af7cd5d1e0e5d15b15104644a5105de7 (diff) |
intel-gtt: switch i81x to the write_entry helpers
Initialization is still done with the old code with a few
added things sprinkled in to make the intel_fake_agp helper
functions work.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 152 |
1 files changed, 60 insertions, 92 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 2470040023d3..9d17a6d51640 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -101,6 +101,9 @@ static struct _intel_private { | |||
101 | dma_addr_t scratch_page_dma; | 101 | dma_addr_t scratch_page_dma; |
102 | } intel_private; | 102 | } intel_private; |
103 | 103 | ||
104 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, | ||
105 | off_t pg_start, int type); | ||
106 | |||
104 | #define INTEL_GTT_GEN intel_private.driver->gen | 107 | #define INTEL_GTT_GEN intel_private.driver->gen |
105 | #define IS_G33 intel_private.driver->is_g33 | 108 | #define IS_G33 intel_private.driver->is_g33 |
106 | #define IS_PINEVIEW intel_private.driver->is_pineview | 109 | #define IS_PINEVIEW intel_private.driver->is_pineview |
@@ -176,10 +179,12 @@ static int intel_i810_fetch_size(void) | |||
176 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { | 179 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { |
177 | agp_bridge->current_size = (void *) (values + 1); | 180 | agp_bridge->current_size = (void *) (values + 1); |
178 | agp_bridge->aperture_size_idx = 1; | 181 | agp_bridge->aperture_size_idx = 1; |
182 | intel_private.base.gtt_total_entries = KB(32) / 4; | ||
179 | return values[1].size; | 183 | return values[1].size; |
180 | } else { | 184 | } else { |
181 | agp_bridge->current_size = (void *) (values); | 185 | agp_bridge->current_size = (void *) (values); |
182 | agp_bridge->aperture_size_idx = 0; | 186 | agp_bridge->aperture_size_idx = 0; |
187 | intel_private.base.gtt_total_entries = KB(64) / 4; | ||
183 | return values[0].size; | 188 | return values[0].size; |
184 | } | 189 | } |
185 | 190 | ||
@@ -206,6 +211,9 @@ static int intel_i810_configure(void) | |||
206 | } | 211 | } |
207 | } | 212 | } |
208 | 213 | ||
214 | intel_private.gtt = intel_private.registers + I810_PTE_BASE; | ||
215 | intel_private.scratch_page_dma = agp_bridge->scratch_page & PAGE_MASK; | ||
216 | |||
209 | if ((readl(intel_private.registers+I810_DRAM_CTL) | 217 | if ((readl(intel_private.registers+I810_DRAM_CTL) |
210 | & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { | 218 | & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { |
211 | /* This will need to be dynamically assigned */ | 219 | /* This will need to be dynamically assigned */ |
@@ -273,79 +281,27 @@ static void i8xx_destroy_pages(struct page *page) | |||
273 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | 281 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, |
274 | int type) | 282 | int type) |
275 | { | 283 | { |
276 | int i, j, num_entries; | 284 | int i; |
277 | void *temp; | ||
278 | int ret = -EINVAL; | ||
279 | int mask_type; | ||
280 | |||
281 | if (mem->page_count == 0) | ||
282 | goto out; | ||
283 | |||
284 | temp = agp_bridge->current_size; | ||
285 | num_entries = A_SIZE_FIX(temp)->num_entries; | ||
286 | |||
287 | if ((pg_start + mem->page_count) > num_entries) | ||
288 | goto out_err; | ||
289 | |||
290 | |||
291 | for (j = pg_start; j < (pg_start + mem->page_count); j++) { | ||
292 | if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j))) { | ||
293 | ret = -EBUSY; | ||
294 | goto out_err; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | if (type != mem->type) | ||
299 | goto out_err; | ||
300 | 285 | ||
301 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 286 | if (type == AGP_DCACHE_MEMORY) { |
287 | if ((pg_start + mem->page_count) | ||
288 | > intel_private.num_dcache_entries) | ||
289 | return -EINVAL; | ||
302 | 290 | ||
303 | switch (mask_type) { | ||
304 | case AGP_DCACHE_MEMORY: | ||
305 | if (!mem->is_flushed) | 291 | if (!mem->is_flushed) |
306 | global_cache_flush(); | 292 | global_cache_flush(); |
293 | |||
307 | for (i = pg_start; i < (pg_start + mem->page_count); i++) { | 294 | for (i = pg_start; i < (pg_start + mem->page_count); i++) { |
308 | writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, | 295 | dma_addr_t addr = i << PAGE_SHIFT; |
309 | intel_private.registers+I810_PTE_BASE+(i*4)); | 296 | intel_private.driver->write_entry(addr, |
310 | } | 297 | i, type); |
311 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); | ||
312 | break; | ||
313 | case AGP_PHYS_MEMORY: | ||
314 | case AGP_NORMAL_MEMORY: | ||
315 | if (!mem->is_flushed) | ||
316 | global_cache_flush(); | ||
317 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | ||
318 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
319 | page_to_phys(mem->pages[i]), mask_type), | ||
320 | intel_private.registers+I810_PTE_BASE+(j*4)); | ||
321 | } | 298 | } |
322 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 299 | readl(intel_private.gtt+i-1); |
323 | break; | ||
324 | default: | ||
325 | goto out_err; | ||
326 | } | ||
327 | |||
328 | out: | ||
329 | ret = 0; | ||
330 | out_err: | ||
331 | mem->is_flushed = true; | ||
332 | return ret; | ||
333 | } | ||
334 | 300 | ||
335 | static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start, | ||
336 | int type) | ||
337 | { | ||
338 | int i; | ||
339 | |||
340 | if (mem->page_count == 0) | ||
341 | return 0; | 301 | return 0; |
342 | |||
343 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | ||
344 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | ||
345 | } | 302 | } |
346 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); | ||
347 | 303 | ||
348 | return 0; | 304 | return intel_fake_agp_insert_entries(mem, pg_start, type); |
349 | } | 305 | } |
350 | 306 | ||
351 | /* | 307 | /* |
@@ -390,29 +346,6 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) | |||
390 | return new; | 346 | return new; |
391 | } | 347 | } |
392 | 348 | ||
393 | static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) | ||
394 | { | ||
395 | struct agp_memory *new; | ||
396 | |||
397 | if (type == AGP_DCACHE_MEMORY) { | ||
398 | if (pg_count != intel_private.num_dcache_entries) | ||
399 | return NULL; | ||
400 | |||
401 | new = agp_create_memory(1); | ||
402 | if (new == NULL) | ||
403 | return NULL; | ||
404 | |||
405 | new->type = AGP_DCACHE_MEMORY; | ||
406 | new->page_count = pg_count; | ||
407 | new->num_scratch_pages = 0; | ||
408 | agp_free_page_array(new); | ||
409 | return new; | ||
410 | } | ||
411 | if (type == AGP_PHYS_MEMORY) | ||
412 | return alloc_agpphysmem_i8xx(pg_count, type); | ||
413 | return NULL; | ||
414 | } | ||
415 | |||
416 | static void intel_i810_free_by_type(struct agp_memory *curr) | 349 | static void intel_i810_free_by_type(struct agp_memory *curr) |
417 | { | 350 | { |
418 | agp_free_key(curr->key); | 351 | agp_free_key(curr->key); |
@@ -463,6 +396,23 @@ static int intel_gtt_setup_scratch_page(void) | |||
463 | return 0; | 396 | return 0; |
464 | } | 397 | } |
465 | 398 | ||
399 | static void i810_write_entry(dma_addr_t addr, unsigned int entry, | ||
400 | unsigned int flags) | ||
401 | { | ||
402 | u32 pte_flags = I810_PTE_VALID; | ||
403 | |||
404 | switch (flags) { | ||
405 | case AGP_DCACHE_MEMORY: | ||
406 | pte_flags |= I810_PTE_LOCAL; | ||
407 | break; | ||
408 | case AGP_USER_CACHED_MEMORY: | ||
409 | pte_flags |= I830_PTE_SYSTEM_CACHED; | ||
410 | break; | ||
411 | } | ||
412 | |||
413 | writel(addr | pte_flags, intel_private.gtt + entry); | ||
414 | } | ||
415 | |||
466 | static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { | 416 | static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { |
467 | {128, 32768, 5}, | 417 | {128, 32768, 5}, |
468 | /* The 64M mode still requires a 128k gatt */ | 418 | /* The 64M mode still requires a 128k gatt */ |
@@ -760,7 +710,7 @@ static void intel_gtt_cleanup(void) | |||
760 | 710 | ||
761 | iounmap(intel_private.gtt); | 711 | iounmap(intel_private.gtt); |
762 | iounmap(intel_private.registers); | 712 | iounmap(intel_private.registers); |
763 | 713 | ||
764 | intel_gtt_teardown_scratch_page(); | 714 | intel_gtt_teardown_scratch_page(); |
765 | } | 715 | } |
766 | 716 | ||
@@ -889,7 +839,7 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, | |||
889 | unsigned int flags) | 839 | unsigned int flags) |
890 | { | 840 | { |
891 | u32 pte_flags = I810_PTE_VALID; | 841 | u32 pte_flags = I810_PTE_VALID; |
892 | 842 | ||
893 | if (flags == AGP_USER_CACHED_MEMORY) | 843 | if (flags == AGP_USER_CACHED_MEMORY) |
894 | pte_flags |= I830_PTE_SYSTEM_CACHED; | 844 | pte_flags |= I830_PTE_SYSTEM_CACHED; |
895 | 845 | ||
@@ -1106,6 +1056,22 @@ static void intel_fake_agp_chipset_flush(struct agp_bridge_data *bridge) | |||
1106 | static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, | 1056 | static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, |
1107 | int type) | 1057 | int type) |
1108 | { | 1058 | { |
1059 | struct agp_memory *new; | ||
1060 | |||
1061 | if (type == AGP_DCACHE_MEMORY && INTEL_GTT_GEN == 1) { | ||
1062 | if (pg_count != intel_private.num_dcache_entries) | ||
1063 | return NULL; | ||
1064 | |||
1065 | new = agp_create_memory(1); | ||
1066 | if (new == NULL) | ||
1067 | return NULL; | ||
1068 | |||
1069 | new->type = AGP_DCACHE_MEMORY; | ||
1070 | new->page_count = pg_count; | ||
1071 | new->num_scratch_pages = 0; | ||
1072 | agp_free_page_array(new); | ||
1073 | return new; | ||
1074 | } | ||
1109 | if (type == AGP_PHYS_MEMORY) | 1075 | if (type == AGP_PHYS_MEMORY) |
1110 | return alloc_agpphysmem_i8xx(pg_count, type); | 1076 | return alloc_agpphysmem_i8xx(pg_count, type); |
1111 | /* always return NULL for other allocation types for now */ | 1077 | /* always return NULL for other allocation types for now */ |
@@ -1316,8 +1282,8 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1316 | .create_gatt_table = agp_generic_create_gatt_table, | 1282 | .create_gatt_table = agp_generic_create_gatt_table, |
1317 | .free_gatt_table = agp_generic_free_gatt_table, | 1283 | .free_gatt_table = agp_generic_free_gatt_table, |
1318 | .insert_memory = intel_i810_insert_entries, | 1284 | .insert_memory = intel_i810_insert_entries, |
1319 | .remove_memory = intel_i810_remove_entries, | 1285 | .remove_memory = intel_fake_agp_remove_entries, |
1320 | .alloc_by_type = intel_i810_alloc_by_type, | 1286 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1321 | .free_by_type = intel_i810_free_by_type, | 1287 | .free_by_type = intel_i810_free_by_type, |
1322 | .agp_alloc_page = agp_generic_alloc_page, | 1288 | .agp_alloc_page = agp_generic_alloc_page, |
1323 | .agp_alloc_pages = agp_generic_alloc_pages, | 1289 | .agp_alloc_pages = agp_generic_alloc_pages, |
@@ -1352,6 +1318,8 @@ static const struct agp_bridge_driver intel_fake_agp_driver = { | |||
1352 | static const struct intel_gtt_driver i81x_gtt_driver = { | 1318 | static const struct intel_gtt_driver i81x_gtt_driver = { |
1353 | .gen = 1, | 1319 | .gen = 1, |
1354 | .dma_mask_size = 32, | 1320 | .dma_mask_size = 32, |
1321 | .check_flags = i830_check_flags, | ||
1322 | .write_entry = i810_write_entry, | ||
1355 | }; | 1323 | }; |
1356 | static const struct intel_gtt_driver i8xx_gtt_driver = { | 1324 | static const struct intel_gtt_driver i8xx_gtt_driver = { |
1357 | .gen = 2, | 1325 | .gen = 2, |
@@ -1369,7 +1337,7 @@ static const struct intel_gtt_driver i915_gtt_driver = { | |||
1369 | .setup = i9xx_setup, | 1337 | .setup = i9xx_setup, |
1370 | .cleanup = i9xx_cleanup, | 1338 | .cleanup = i9xx_cleanup, |
1371 | /* i945 is the last gpu to need phys mem (for overlay and cursors). */ | 1339 | /* i945 is the last gpu to need phys mem (for overlay and cursors). */ |
1372 | .write_entry = i830_write_entry, | 1340 | .write_entry = i830_write_entry, |
1373 | .dma_mask_size = 32, | 1341 | .dma_mask_size = 32, |
1374 | .check_flags = i830_check_flags, | 1342 | .check_flags = i830_check_flags, |
1375 | .chipset_flush = i9xx_chipset_flush, | 1343 | .chipset_flush = i9xx_chipset_flush, |
@@ -1557,7 +1525,7 @@ int intel_gmch_probe(struct pci_dev *pdev, | |||
1557 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { | 1525 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { |
1558 | bridge->driver = | 1526 | bridge->driver = |
1559 | intel_gtt_chipsets[i].gmch_driver; | 1527 | intel_gtt_chipsets[i].gmch_driver; |
1560 | intel_private.driver = | 1528 | intel_private.driver = |
1561 | intel_gtt_chipsets[i].gtt_driver; | 1529 | intel_gtt_chipsets[i].gtt_driver; |
1562 | break; | 1530 | break; |
1563 | } | 1531 | } |