Merge branch 'drm-intel-next' of git://people.freedesktop.org/~danvet/drm-intel into...
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / i915_gem.c
index 759daa491ab540fdf3bed97beee8095eeab26f43..b851bd34ca18376af5becaf346e1cbd960c0432a 100644 (file)
@@ -1397,16 +1397,19 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
        list_move_tail(&obj->ring_list, &ring->active_list);
 
        obj->last_rendering_seqno = seqno;
-       if (obj->fenced_gpu_access) {
-               struct drm_i915_fence_reg *reg;
-
-               BUG_ON(obj->fence_reg == I915_FENCE_REG_NONE);
 
+       if (obj->fenced_gpu_access) {
                obj->last_fenced_seqno = seqno;
                obj->last_fenced_ring = ring;
 
-               reg = &dev_priv->fence_regs[obj->fence_reg];
-               list_move_tail(&reg->lru_list, &dev_priv->mm.fence_list);
+               /* Bump MRU to take account of the delayed flush */
+               if (obj->fence_reg != I915_FENCE_REG_NONE) {
+                       struct drm_i915_fence_reg *reg;
+
+                       reg = &dev_priv->fence_regs[obj->fence_reg];
+                       list_move_tail(&reg->lru_list,
+                                      &dev_priv->mm.fence_list);
+               }
        }
 }
 
@@ -3580,12 +3583,32 @@ void i915_gem_init_ppgtt(struct drm_device *dev)
        drm_i915_private_t *dev_priv = dev->dev_private;
        uint32_t pd_offset;
        struct intel_ring_buffer *ring;
+       struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
+       uint32_t __iomem *pd_addr;
+       uint32_t pd_entry;
        int i;
 
        if (!dev_priv->mm.aliasing_ppgtt)
                return;
 
-       pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset;
+
+       pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t);
+       for (i = 0; i < ppgtt->num_pd_entries; i++) {
+               dma_addr_t pt_addr;
+
+               if (dev_priv->mm.gtt->needs_dmar)
+                       pt_addr = ppgtt->pt_dma_addr[i];
+               else
+                       pt_addr = page_to_phys(ppgtt->pt_pages[i]);
+
+               pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
+               pd_entry |= GEN6_PDE_VALID;
+
+               writel(pd_entry, pd_addr + i);
+       }
+       readl(pd_addr);
+
+       pd_offset = ppgtt->pd_offset;
        pd_offset /= 64; /* in cachelines, */
        pd_offset <<= 16;