Commit a81cc00c authored by Ben Widawsky's avatar Ben Widawsky Committed by Daniel Vetter

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: default avatarBen Widawsky <ben@bwidawsk.net>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent abedc077
...@@ -840,9 +840,6 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, ...@@ -840,9 +840,6 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
{ {
int ret = -EINVAL; int ret = -EINVAL;
if (intel_private.base.do_idle_maps)
return -ENODEV;
if (intel_private.clear_fake_agp) { if (intel_private.clear_fake_agp) {
int start = intel_private.base.stolen_size / PAGE_SIZE; int start = intel_private.base.stolen_size / PAGE_SIZE;
int end = intel_private.base.gtt_mappable_entries; int end = intel_private.base.gtt_mappable_entries;
...@@ -907,9 +904,6 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem, ...@@ -907,9 +904,6 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem,
if (mem->page_count == 0) if (mem->page_count == 0)
return 0; return 0;
if (intel_private.base.do_idle_maps)
return -ENODEV;
intel_gtt_clear_range(pg_start, mem->page_count); intel_gtt_clear_range(pg_start, mem->page_count);
if (intel_private.base.needs_dmar) { if (intel_private.base.needs_dmar) {
...@@ -1069,24 +1063,6 @@ static void i965_write_entry(dma_addr_t addr, ...@@ -1069,24 +1063,6 @@ static void i965_write_entry(dma_addr_t addr,
writel(addr | pte_flags, intel_private.gtt + entry); writel(addr | pte_flags, intel_private.gtt + entry);
} }
/* Certain Gen5 chipsets require require idling the GPU before
* unmapping anything from the GTT when VT-d is enabled.
*/
static inline int needs_idle_maps(void)
{
#ifdef CONFIG_INTEL_IOMMU
const unsigned short gpu_devid = intel_private.pcidev->device;
/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
*/
if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
intel_iommu_gfx_mapped)
return 1;
#endif
return 0;
}
static int i9xx_setup(void) static int i9xx_setup(void)
{ {
...@@ -1115,9 +1091,6 @@ static int i9xx_setup(void) ...@@ -1115,9 +1091,6 @@ static int i9xx_setup(void)
break; break;
} }
if (needs_idle_maps())
intel_private.base.do_idle_maps = 1;
intel_i9xx_setup_flush(); intel_i9xx_setup_flush();
return 0; return 0;
......
...@@ -381,6 +381,8 @@ struct i915_gtt { ...@@ -381,6 +381,8 @@ struct i915_gtt {
/** "Graphics Stolen Memory" holds the global PTEs */ /** "Graphics Stolen Memory" holds the global PTEs */
void __iomem *gsm; void __iomem *gsm;
bool do_idle_maps;
}; };
#define I915_PPGTT_PD_ENTRIES 512 #define I915_PPGTT_PD_ENTRIES 512
......
...@@ -338,11 +338,27 @@ void i915_gem_init_ppgtt(struct drm_device *dev) ...@@ -338,11 +338,27 @@ void i915_gem_init_ppgtt(struct drm_device *dev)
} }
} }
extern int intel_iommu_gfx_mapped;
/* Certain Gen5 chipsets require require idling the GPU before
* unmapping anything from the GTT when VT-d is enabled.
*/
static inline bool needs_idle_maps(struct drm_device *dev)
{
#ifdef CONFIG_INTEL_IOMMU
/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
*/
if (IS_GEN5(dev) && IS_MOBILE(dev) && intel_iommu_gfx_mapped)
return true;
#endif
return false;
}
static bool do_idling(struct drm_i915_private *dev_priv) static bool do_idling(struct drm_i915_private *dev_priv)
{ {
bool ret = dev_priv->mm.interruptible; bool ret = dev_priv->mm.interruptible;
if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { if (unlikely(dev_priv->gtt.do_idle_maps)) {
dev_priv->mm.interruptible = false; dev_priv->mm.interruptible = false;
if (i915_gpu_idle(dev_priv->dev)) { if (i915_gpu_idle(dev_priv->dev)) {
DRM_ERROR("Couldn't idle GPU\n"); DRM_ERROR("Couldn't idle GPU\n");
...@@ -356,11 +372,10 @@ static bool do_idling(struct drm_i915_private *dev_priv) ...@@ -356,11 +372,10 @@ static bool do_idling(struct drm_i915_private *dev_priv)
static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible) static void undo_idling(struct drm_i915_private *dev_priv, bool interruptible)
{ {
if (unlikely(dev_priv->mm.gtt->do_idle_maps)) if (unlikely(dev_priv->gtt.do_idle_maps))
dev_priv->mm.interruptible = interruptible; dev_priv->mm.interruptible = interruptible;
} }
static void i915_ggtt_clear_range(struct drm_device *dev, static void i915_ggtt_clear_range(struct drm_device *dev,
unsigned first_entry, unsigned first_entry,
unsigned num_entries) unsigned num_entries)
...@@ -709,6 +724,9 @@ int i915_gem_gtt_init(struct drm_device *dev) ...@@ -709,6 +724,9 @@ int i915_gem_gtt_init(struct drm_device *dev)
intel_gmch_remove(); intel_gmch_remove();
return -ENODEV; return -ENODEV;
} }
dev_priv->gtt.do_idle_maps = needs_idle_maps(dev);
return 0; return 0;
} }
......
...@@ -13,8 +13,6 @@ struct intel_gtt { ...@@ -13,8 +13,6 @@ struct intel_gtt {
unsigned int gtt_mappable_entries; unsigned int gtt_mappable_entries;
/* Whether i915 needs to use the dmar apis or not. */ /* Whether i915 needs to use the dmar apis or not. */
unsigned int needs_dmar : 1; unsigned int needs_dmar : 1;
/* Whether we idle the gpu before mapping/unmapping */
unsigned int do_idle_maps : 1;
/* Share the scratch page dma with ppgtts. */ /* Share the scratch page dma with ppgtts. */
dma_addr_t scratch_page_dma; dma_addr_t scratch_page_dma;
struct page *scratch_page; struct page *scratch_page;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment