From 93c34e70ebf464a9ee142d93b681c5df094ec654 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 22 Apr 2013 00:53:50 -0700 Subject: [PATCH] drm/i915: Fix page table entries for Bay Trail. On Bay Trail, bit 1 means "writeable by the GPU." Failing to set that means basically anything using the GPU will cause hangs. v2: Drop accidental inline keyword on byt_pte_encode. Signed-off-by: Kenneth Graunke Reviewed-by: Jani Nikula Tested-by: Daniel Leung [v1] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 92e147ff8665..62058dc760ac 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -73,6 +73,27 @@ static gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev, return pte; } +#define BYT_PTE_WRITEABLE (1 << 1) +#define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2) + +static gen6_gtt_pte_t byt_pte_encode(struct drm_device *dev, + dma_addr_t addr, + enum i915_cache_level level) +{ + gen6_gtt_pte_t pte = GEN6_PTE_VALID; + pte |= GEN6_PTE_ADDR_ENCODE(addr); + + /* Mark the page as writeable. Other platforms don't have a + * setting for read-only/writable, so this matches that behavior. + */ + pte |= BYT_PTE_WRITEABLE; + + if (level != I915_CACHE_NONE) + pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES; + + return pte; +} + static int gen6_ppgtt_enable(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -234,7 +255,11 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) first_pd_entry_in_global_pt = gtt_total_entries(dev_priv->gtt) - I915_PPGTT_PD_ENTRIES; - ppgtt->pte_encode = gen6_pte_encode; + if (IS_VALLEYVIEW(dev)) { + ppgtt->pte_encode = byt_pte_encode; + } else { + ppgtt->pte_encode = gen6_pte_encode; + } ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; ppgtt->enable = gen6_ppgtt_enable; ppgtt->clear_range = gen6_ppgtt_clear_range; @@ -824,7 +849,11 @@ int i915_gem_gtt_init(struct drm_device *dev) } else { dev_priv->gtt.gtt_probe = gen6_gmch_probe; dev_priv->gtt.gtt_remove = gen6_gmch_remove; - dev_priv->gtt.pte_encode = gen6_pte_encode; + if (IS_VALLEYVIEW(dev)) { + dev_priv->gtt.pte_encode = byt_pte_encode; + } else { + dev_priv->gtt.pte_encode = gen6_pte_encode; + } } ret = dev_priv->gtt.gtt_probe(dev, &dev_priv->gtt.total, -- 2.39.5