aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2010-09-11 16:12:11 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-21 06:36:38 -0400
commitfefaa70f0c7fa406492039e35b69b83fc13e163a (patch)
treec9f721ad19884c401774d926b65a6c4f8b08a037 /drivers
parent5cbecafce4ee8ab73c194911e01a77a7a07f034e (diff)
intel-gtt: generic (insert|remove)_entries for i915
Beef up the generic version to support dmar. Otherwise like for the i830. v2: Don't try to DMA remap on resume for already remapped pages. 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.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index c1b766dbef4d..f05c3648017d 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -124,7 +124,6 @@ static struct _intel_private {
124#define IS_PINEVIEW intel_private.driver->is_pineview 124#define IS_PINEVIEW intel_private.driver->is_pineview
125#define IS_IRONLAKE intel_private.driver->is_ironlake 125#define IS_IRONLAKE intel_private.driver->is_ironlake
126 126
127#if USE_PCI_DMA_API
128static void intel_agp_free_sglist(struct agp_memory *mem) 127static void intel_agp_free_sglist(struct agp_memory *mem)
129{ 128{
130 struct sg_table st; 129 struct sg_table st;
@@ -144,6 +143,9 @@ static int intel_agp_map_memory(struct agp_memory *mem)
144 struct scatterlist *sg; 143 struct scatterlist *sg;
145 int i; 144 int i;
146 145
146 if (mem->sg_list)
147 return 0; /* already mapped (for e.g. resume */
148
147 DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); 149 DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
148 150
149 if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) 151 if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
@@ -175,6 +177,7 @@ static void intel_agp_unmap_memory(struct agp_memory *mem)
175 intel_agp_free_sglist(mem); 177 intel_agp_free_sglist(mem);
176} 178}
177 179
180#if USE_PCI_DMA_API
178static void intel_agp_insert_sg_entries(struct agp_memory *mem, 181static void intel_agp_insert_sg_entries(struct agp_memory *mem,
179 off_t pg_start, int mask_type) 182 off_t pg_start, int mask_type)
180{ 183{
@@ -1051,6 +1054,31 @@ static bool i830_check_flags(unsigned int flags)
1051 return false; 1054 return false;
1052} 1055}
1053 1056
1057static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list,
1058 unsigned int sg_len,
1059 unsigned int pg_start,
1060 unsigned int flags)
1061{
1062 struct scatterlist *sg;
1063 unsigned int len, m;
1064 int i, j;
1065
1066 j = pg_start;
1067
1068 /* sg may merge pages, but we have to separate
1069 * per-page addr for GTT */
1070 for_each_sg(sg_list, sg, sg_len, i) {
1071 len = sg_dma_len(sg) >> PAGE_SHIFT;
1072 for (m = 0; m < len; m++) {
1073 dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
1074 intel_private.driver->write_entry(addr,
1075 j, flags);
1076 j++;
1077 }
1078 }
1079 readl(intel_private.gtt+j-1);
1080}
1081
1054static int intel_fake_agp_insert_entries(struct agp_memory *mem, 1082static int intel_fake_agp_insert_entries(struct agp_memory *mem,
1055 off_t pg_start, int type) 1083 off_t pg_start, int type)
1056{ 1084{
@@ -1082,11 +1110,21 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
1082 if (!mem->is_flushed) 1110 if (!mem->is_flushed)
1083 global_cache_flush(); 1111 global_cache_flush();
1084 1112
1085 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 1113 if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) {
1086 intel_private.driver->write_entry(page_to_phys(mem->pages[i]), 1114 ret = intel_agp_map_memory(mem);
1087 j, type); 1115 if (ret != 0)
1116 return ret;
1117
1118 intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg,
1119 pg_start, type);
1120 } else {
1121 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
1122 dma_addr_t addr = page_to_phys(mem->pages[i]);
1123 intel_private.driver->write_entry(addr,
1124 j, type);
1125 }
1126 readl(intel_private.gtt+j-1);
1088 } 1127 }
1089 readl(intel_private.gtt+j-1);
1090 1128
1091out: 1129out:
1092 ret = 0; 1130 ret = 0;
@@ -1109,6 +1147,9 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
1109 return -EINVAL; 1147 return -EINVAL;
1110 } 1148 }
1111 1149
1150 if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2)
1151 intel_agp_unmap_memory(mem);
1152
1112 for (i = pg_start; i < (mem->page_count + pg_start); i++) { 1153 for (i = pg_start; i < (mem->page_count + pg_start); i++) {
1113 intel_private.driver->write_entry(intel_private.scratch_page_dma, 1154 intel_private.driver->write_entry(intel_private.scratch_page_dma,
1114 i, 0); 1155 i, 0);
@@ -1469,8 +1510,8 @@ static const struct agp_bridge_driver intel_915_driver = {
1469 .cache_flush = global_cache_flush, 1510 .cache_flush = global_cache_flush,
1470 .create_gatt_table = intel_fake_agp_create_gatt_table, 1511 .create_gatt_table = intel_fake_agp_create_gatt_table,
1471 .free_gatt_table = intel_fake_agp_free_gatt_table, 1512 .free_gatt_table = intel_fake_agp_free_gatt_table,
1472 .insert_memory = intel_i915_insert_entries, 1513 .insert_memory = intel_fake_agp_insert_entries,
1473 .remove_memory = intel_i915_remove_entries, 1514 .remove_memory = intel_fake_agp_remove_entries,
1474 .alloc_by_type = intel_fake_agp_alloc_by_type, 1515 .alloc_by_type = intel_fake_agp_alloc_by_type,
1475 .free_by_type = intel_i810_free_by_type, 1516 .free_by_type = intel_i810_free_by_type,
1476 .agp_alloc_page = agp_generic_alloc_page, 1517 .agp_alloc_page = agp_generic_alloc_page,
@@ -1479,10 +1520,6 @@ static const struct agp_bridge_driver intel_915_driver = {
1479 .agp_destroy_pages = agp_generic_destroy_pages, 1520 .agp_destroy_pages = agp_generic_destroy_pages,
1480 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 1521 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1481 .chipset_flush = intel_i915_chipset_flush, 1522 .chipset_flush = intel_i915_chipset_flush,
1482#if USE_PCI_DMA_API
1483 .agp_map_memory = intel_agp_map_memory,
1484 .agp_unmap_memory = intel_agp_unmap_memory,
1485#endif
1486}; 1523};
1487 1524
1488static const struct agp_bridge_driver intel_i965_driver = { 1525static const struct agp_bridge_driver intel_i965_driver = {
@@ -1586,6 +1623,7 @@ static const struct intel_gtt_driver i915_gtt_driver = {
1586 .setup = i9xx_setup, 1623 .setup = i9xx_setup,
1587 /* i945 is the last gpu to need phys mem (for overlay and cursors). */ 1624 /* i945 is the last gpu to need phys mem (for overlay and cursors). */
1588 .write_entry = i830_write_entry, 1625 .write_entry = i830_write_entry,
1626 .check_flags = i830_check_flags,
1589}; 1627};
1590static const struct intel_gtt_driver g33_gtt_driver = { 1628static const struct intel_gtt_driver g33_gtt_driver = {
1591 .gen = 3, 1629 .gen = 3,