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.c83
1 files changed, 76 insertions, 7 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index a7547150a705..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
@@ -1282,6 +1298,11 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
1282 1298
1283 /* 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 */
1284 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 }
1285 1306
1286 agp_bridge->gatt_table = NULL; 1307 agp_bridge->gatt_table = NULL;
1287 1308
@@ -1309,6 +1330,16 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
1309 return addr | bridge->driver->masks[type].mask; 1330 return addr | bridge->driver->masks[type].mask;
1310} 1331}
1311 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
1312static 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)
1313{ 1344{
1314 u16 snb_gmch_ctl; 1345 u16 snb_gmch_ctl;
@@ -1390,6 +1421,11 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
1390 1421
1391 /* 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 */
1392 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 }
1393 1429
1394 agp_bridge->gatt_table = NULL; 1430 agp_bridge->gatt_table = NULL;
1395 1431
@@ -1517,6 +1553,39 @@ static const struct agp_bridge_driver intel_i965_driver = {
1517#endif 1553#endif
1518}; 1554};
1519 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
1520static const struct agp_bridge_driver intel_g33_driver = { 1589static const struct agp_bridge_driver intel_g33_driver = {
1521 .owner = THIS_MODULE, 1590 .owner = THIS_MODULE,
1522 .aperture_sizes = intel_i830_sizes, 1591 .aperture_sizes = intel_i830_sizes,