diff options
Diffstat (limited to 'drivers/char/agp/intel-gtt.c')
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 83 |
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 */ | ||
29 | int intel_max_stolen = 32 * 1024 * 1024; | ||
30 | EXPORT_SYMBOL(intel_max_stolen); | ||
31 | |||
28 | static const struct aper_size_info_fixed intel_i810_sizes[] = | 32 | static 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 | |||
125 | err: | ||
126 | sg_free_table(&st); | ||
127 | return -ENOMEM; | ||
121 | } | 128 | } |
122 | 129 | ||
123 | static void intel_agp_unmap_memory(struct agp_memory *mem) | 130 | static 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 | ||
1333 | static 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 | |||
1312 | static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | 1343 | static 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 | ||
1556 | static 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 | |||
1520 | static const struct agp_bridge_driver intel_g33_driver = { | 1589 | static 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, |