aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp/intel-gtt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/agp/intel-gtt.c')
-rw-r--r--drivers/char/agp/intel-gtt.c96
1 files changed, 84 insertions, 12 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 9344216183a4..d22ffb811bf2 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -25,6 +25,10 @@
25#define USE_PCI_DMA_API 1 25#define USE_PCI_DMA_API 1
26#endif 26#endif
27 27
28/* Max amount of stolen space, anything above will be returned to Linux */
29int intel_max_stolen = 32 * 1024 * 1024;
30EXPORT_SYMBOL(intel_max_stolen);
31
28static const struct aper_size_info_fixed intel_i810_sizes[] = 32static const struct aper_size_info_fixed intel_i810_sizes[] =
29{ 33{
30 {64, 16384, 4}, 34 {64, 16384, 4},
@@ -104,7 +108,7 @@ static int intel_agp_map_memory(struct agp_memory *mem)
104 DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); 108 DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
105 109
106 if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) 110 if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
107 return -ENOMEM; 111 goto err;
108 112
109 mem->sg_list = sg = st.sgl; 113 mem->sg_list = sg = st.sgl;
110 114
@@ -113,11 +117,14 @@ static int intel_agp_map_memory(struct agp_memory *mem)
113 117
114 mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list, 118 mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list,
115 mem->page_count, PCI_DMA_BIDIRECTIONAL); 119 mem->page_count, PCI_DMA_BIDIRECTIONAL);
116 if (unlikely(!mem->num_sg)) { 120 if (unlikely(!mem->num_sg))
117 intel_agp_free_sglist(mem); 121 goto err;
118 return -ENOMEM; 122
119 }
120 return 0; 123 return 0;
124
125err:
126 sg_free_table(&st);
127 return -ENOMEM;
121} 128}
122 129
123static void intel_agp_unmap_memory(struct agp_memory *mem) 130static void intel_agp_unmap_memory(struct agp_memory *mem)
@@ -176,7 +183,7 @@ static void intel_agp_insert_sg_entries(struct agp_memory *mem,
176 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || 183 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB ||
177 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB) 184 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB)
178 { 185 {
179 cache_bits = I830_PTE_SYSTEM_CACHED; 186 cache_bits = GEN6_PTE_LLC_MLC;
180 } 187 }
181 188
182 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 189 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -710,7 +717,12 @@ static void intel_i830_init_gtt_entries(void)
710 break; 717 break;
711 } 718 }
712 } 719 }
713 if (gtt_entries > 0) { 720 if (!local && gtt_entries > intel_max_stolen) {
721 dev_info(&agp_bridge->dev->dev,
722 "detected %dK stolen memory, trimming to %dK\n",
723 gtt_entries / KB(1), intel_max_stolen / KB(1));
724 gtt_entries = intel_max_stolen / KB(4);
725 } else if (gtt_entries > 0) {
714 dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", 726 dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
715 gtt_entries / KB(1), local ? "local" : "stolen"); 727 gtt_entries / KB(1), local ? "local" : "stolen");
716 gtt_entries /= KB(4); 728 gtt_entries /= KB(4);
@@ -797,6 +809,10 @@ static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge)
797 809
798 /* we have to call this as early as possible after the MMIO base address is known */ 810 /* we have to call this as early as possible after the MMIO base address is known */
799 intel_i830_init_gtt_entries(); 811 intel_i830_init_gtt_entries();
812 if (intel_private.gtt_entries == 0) {
813 iounmap(intel_private.registers);
814 return -ENOMEM;
815 }
800 816
801 agp_bridge->gatt_table = NULL; 817 agp_bridge->gatt_table = NULL;
802 818
@@ -1216,17 +1232,20 @@ static int intel_i915_get_gtt_size(void)
1216 1232
1217 /* G33's GTT size defined in gmch_ctrl */ 1233 /* G33's GTT size defined in gmch_ctrl */
1218 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); 1234 pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl);
1219 switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { 1235 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
1220 case G33_PGETBL_SIZE_1M: 1236 case I830_GMCH_GMS_STOLEN_512:
1237 size = 512;
1238 break;
1239 case I830_GMCH_GMS_STOLEN_1024:
1221 size = 1024; 1240 size = 1024;
1222 break; 1241 break;
1223 case G33_PGETBL_SIZE_2M: 1242 case I830_GMCH_GMS_STOLEN_8192:
1224 size = 2048; 1243 size = 8*1024;
1225 break; 1244 break;
1226 default: 1245 default:
1227 dev_info(&agp_bridge->dev->dev, 1246 dev_info(&agp_bridge->dev->dev,
1228 "unknown page table size 0x%x, assuming 512KB\n", 1247 "unknown page table size 0x%x, assuming 512KB\n",
1229 (gmch_ctrl & G33_PGETBL_SIZE_MASK)); 1248 (gmch_ctrl & I830_GMCH_GMS_MASK));
1230 size = 512; 1249 size = 512;
1231 } 1250 }
1232 } else { 1251 } else {
@@ -1279,6 +1298,11 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1279 1298
1280 /* we have to call this as early as possible after the MMIO base address is known */ 1299 /* we have to call this as early as possible after the MMIO base address is known */
1281 intel_i830_init_gtt_entries(); 1300 intel_i830_init_gtt_entries();
1301 if (intel_private.gtt_entries == 0) {
1302 iounmap(intel_private.gtt);
1303 iounmap(intel_private.registers);
1304 return -ENOMEM;
1305 }
1282 1306
1283 agp_bridge->gatt_table = NULL; 1307 agp_bridge->gatt_table = NULL;
1284 1308
@@ -1306,6 +1330,16 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
1306 return addr | bridge->driver->masks[type].mask; 1330 return addr | bridge->driver->masks[type].mask;
1307} 1331}
1308 1332
1333static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge,
1334 dma_addr_t addr, int type)
1335{
1336 /* Shift high bits down */
1337 addr |= (addr >> 28) & 0xff;
1338
1339 /* Type checking must be done elsewhere */
1340 return addr | bridge->driver->masks[type].mask;
1341}
1342
1309static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) 1343static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
1310{ 1344{
1311 u16 snb_gmch_ctl; 1345 u16 snb_gmch_ctl;
@@ -1387,6 +1421,11 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
1387 1421
1388 /* we have to call this as early as possible after the MMIO base address is known */ 1422 /* we have to call this as early as possible after the MMIO base address is known */
1389 intel_i830_init_gtt_entries(); 1423 intel_i830_init_gtt_entries();
1424 if (intel_private.gtt_entries == 0) {
1425 iounmap(intel_private.gtt);
1426 iounmap(intel_private.registers);
1427 return -ENOMEM;
1428 }
1390 1429
1391 agp_bridge->gatt_table = NULL; 1430 agp_bridge->gatt_table = NULL;
1392 1431
@@ -1514,6 +1553,39 @@ static const struct agp_bridge_driver intel_i965_driver = {
1514#endif 1553#endif
1515}; 1554};
1516 1555
1556static const struct agp_bridge_driver intel_gen6_driver = {
1557 .owner = THIS_MODULE,
1558 .aperture_sizes = intel_i830_sizes,
1559 .size_type = FIXED_APER_SIZE,
1560 .num_aperture_sizes = 4,
1561 .needs_scratch_page = true,
1562 .configure = intel_i9xx_configure,
1563 .fetch_size = intel_i9xx_fetch_size,
1564 .cleanup = intel_i915_cleanup,
1565 .mask_memory = intel_gen6_mask_memory,
1566 .masks = intel_i810_masks,
1567 .agp_enable = intel_i810_agp_enable,
1568 .cache_flush = global_cache_flush,
1569 .create_gatt_table = intel_i965_create_gatt_table,
1570 .free_gatt_table = intel_i830_free_gatt_table,
1571 .insert_memory = intel_i915_insert_entries,
1572 .remove_memory = intel_i915_remove_entries,
1573 .alloc_by_type = intel_i830_alloc_by_type,
1574 .free_by_type = intel_i810_free_by_type,
1575 .agp_alloc_page = agp_generic_alloc_page,
1576 .agp_alloc_pages = agp_generic_alloc_pages,
1577 .agp_destroy_page = agp_generic_destroy_page,
1578 .agp_destroy_pages = agp_generic_destroy_pages,
1579 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1580 .chipset_flush = intel_i915_chipset_flush,
1581#ifdef USE_PCI_DMA_API
1582 .agp_map_page = intel_agp_map_page,
1583 .agp_unmap_page = intel_agp_unmap_page,
1584 .agp_map_memory = intel_agp_map_memory,
1585 .agp_unmap_memory = intel_agp_unmap_memory,
1586#endif
1587};
1588
1517static const struct agp_bridge_driver intel_g33_driver = { 1589static const struct agp_bridge_driver intel_g33_driver = {
1518 .owner = THIS_MODULE, 1590 .owner = THIS_MODULE,
1519 .aperture_sizes = intel_i830_sizes, 1591 .aperture_sizes = intel_i830_sizes,