aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Widawsky <ben@bwidawsk.net>2013-01-18 15:30:31 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-20 07:11:11 -0500
commita81cc00c11ab6816fbcb7dd99a60b50e71765d25 (patch)
tree506c92848c259bfa397e69d805508511e2024458
parentabedc077b45eff0b5a8630af8431ad5d59213582 (diff)
drm/i915: Cut out the infamous ILK w/a from AGP layer
And, move it to where the rest of the logic is. There is some slight functionality changes. There was extra paranoid checks in AGP code making sure we never do idle maps on gen2 parts. That was not duplicated as the simple PCI id check should do the right thing. v2: use IS_GEN5 && IS_MOBILE check instead. For now, this is the same as IS_IRONLAKE_M but is more future proof. The workaround docs hint that more than one platform may be effected, but we've never seen such a platform in the wild. (Rodrigo, Daniel) Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> (v1) Cc: Dave Airlie <airlied@redhat.com> Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/char/agp/intel-gtt.c27
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c24
-rw-r--r--include/drm/intel-gtt.h2
4 files changed, 23 insertions, 32 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index c8d9dcb15db0..12c31026eb56 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -840,9 +840,6 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
840{ 840{
841 int ret = -EINVAL; 841 int ret = -EINVAL;
842 842
843 if (intel_private.base.do_idle_maps)
844 return -ENODEV;
845
846 if (intel_private.clear_fake_agp) { 843 if (intel_private.clear_fake_agp) {
847 int start = intel_private.base.stolen_size / PAGE_SIZE; 844 int start = intel_private.base.stolen_size / PAGE_SIZE;
848 int end = intel_private.base.gtt_mappable_entries; 845 int end = intel_private.base.gtt_mappable_entries;
@@ -907,9 +904,6 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
907 if (mem->page_count == 0) 904 if (mem->page_count == 0)
908 return 0; 905 return 0;
909 906
910 if (intel_private.base.do_idle_maps)
911 return -ENODEV;
912
913 intel_gtt_clear_range(pg_start, mem->page_count); 907 intel_gtt_clear_range(pg_start, mem->page_count);
914 908
915 if (intel_private.base.needs_dmar) { 909 if (intel_private.base.needs_dmar) {
@@ -1069,24 +1063,6 @@ static void i965_write_entry(dma_addr_t addr,
1069 writel(addr | pte_flags, intel_private.gtt + entry); 1063 writel(addr | pte_flags, intel_private.gtt + entry);
1070} 1064}
1071 1065
1072/* Certain Gen5 chipsets require require idling the GPU before
1073 * unmapping anything from the GTT when VT-d is enabled.
1074 */
1075static inline int needs_idle_maps(void)
1076{
1077#ifdef CONFIG_INTEL_IOMMU
1078 const unsigned short gpu_devid = intel_private.pcidev->device;
1079
1080 /* Query intel_iommu to see if we need the workaround. Presumably that
1081 * was loaded first.
1082 */
1083 if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
1084 gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
1085 intel_iommu_gfx_mapped)
1086 return 1;
1087#endif
1088 return 0;
1089}
1090 1066
1091static int i9xx_setup(void) 1067static int i9xx_setup(void)
1092{ 1068{
@@ -1115,9 +1091,6 @@ static int i9xx_setup(void)
1115 break; 1091 break;
1116 } 1092 }
1117 1093
1118 if (needs_idle_maps())
1119 intel_private.base.do_idle_maps = 1;
1120
1121 intel_i9xx_setup_flush(); 1094 intel_i9xx_setup_flush();
1122 1095
1123 return 0; 1096 return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0a2a18b8a075..1fe802f4df13 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -381,6 +381,8 @@ struct i915_gtt {
381 381
382 /** "Graphics Stolen Memory" holds the global PTEs */ 382 /** "Graphics Stolen Memory" holds the global PTEs */
383 void __iomem *gsm; 383 void __iomem *gsm;
384
385 bool do_idle_maps;
384}; 386};
385 387
386#define I915_PPGTT_PD_ENTRIES 512 388#define I915_PPGTT_PD_ENTRIES 512
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 0f0db02c1e56..84c521fd11a2 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -338,11 +338,27 @@ void i915_gem_init_ppgtt(struct drm_device *dev)
338 } 338 }
339} 339}
340 340
341extern int intel_iommu_gfx_mapped;
342/* Certain Gen5 chipsets require require idling the GPU before
343 * unmapping anything from the GTT when VT-d is enabled.
344 */
345static inline bool needs_idle_maps(struct drm_device *dev)
346{
347#ifdef CONFIG_INTEL_IOMMU
348 /* Query intel_iommu to see if we need the workaround. Presumably that
349 * was loaded first.
350 */
351 if (IS_GEN5(dev) && IS_MOBILE(dev) && intel_iommu_gfx_mapped)
352 return true;
353#endif
354 return false;
355}
356
341static bool do_idling(struct drm_i915_private *dev_priv) 357static bool do_idling(struct drm_i915_private *dev_priv)
342{ 358{
343 bool ret = dev_priv->mm.interruptible; 359 bool ret = dev_priv->mm.interruptible;
344 360
345 if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { 361 if (unlikely(dev_priv->gtt.do_idle_maps)) {
346 dev_priv->mm.interruptible = false; 362 dev_priv->mm.interruptible = false;
347 if (i915_gpu_idle(dev_priv->dev)) { 363 if (i915_gpu_idle(dev_priv->dev)) {
348 DRM_ERROR("Couldn't idle GPU\n"); 364 DRM_ERROR("Couldn't idle GPU\n");
@@ -356,11 +372,10 @@ static bool do_idling(struct drm_i915_private *dev_priv)
356 372
357static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) 373static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
358{ 374{
359 if (unlikely(dev_priv->mm.gtt->do_idle_maps)) 375 if (unlikely(dev_priv->gtt.do_idle_maps))
360 dev_priv->mm.interruptible = interruptible; 376 dev_priv->mm.interruptible = interruptible;
361} 377}
362 378
363
364static void i915_ggtt_clear_range(struct drm_device *dev, 379static void i915_ggtt_clear_range(struct drm_device *dev,
365 unsigned first_entry, 380 unsigned first_entry,
366 unsigned num_entries) 381 unsigned num_entries)
@@ -709,6 +724,9 @@ int i915_gem_gtt_init(struct drm_device *dev)
709 intel_gmch_remove(); 724 intel_gmch_remove();
710 return -ENODEV; 725 return -ENODEV;
711 } 726 }
727
728 dev_priv->gtt.do_idle_maps = needs_idle_maps(dev);
729
712 return 0; 730 return 0;
713 } 731 }
714 732
diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h
index 3e3a166a2690..1747aa095f41 100644
--- a/include/drm/intel-gtt.h
+++ b/include/drm/intel-gtt.h
@@ -13,8 +13,6 @@ struct intel_gtt {
13 unsigned int gtt_mappable_entries; 13 unsigned int gtt_mappable_entries;
14 /* Whether i915 needs to use the dmar apis or not. */ 14 /* Whether i915 needs to use the dmar apis or not. */
15 unsigned int needs_dmar : 1; 15 unsigned int needs_dmar : 1;
16 /* Whether we idle the gpu before mapping/unmapping */
17 unsigned int do_idle_maps : 1;
18 /* Share the scratch page dma with ppgtts. */ 16 /* Share the scratch page dma with ppgtts. */
19 dma_addr_t scratch_page_dma; 17 dma_addr_t scratch_page_dma;
20 struct page *scratch_page; 18 struct page *scratch_page;