drm/i915: fixup pd vs pt confusion in gen6 ppgtt code
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / gpu / drm / i915 / i915_gem_gtt.c
index 926a1e2dd2349ea0aa5960bd4b0e089225631083..4cbae7bbb8338c483aa57a1602298ed84d1fbbd8 100644 (file)
@@ -83,7 +83,7 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt,
 {
        gtt_pte_t *pt_vaddr;
        gtt_pte_t scratch_pte;
-       unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES;
+       unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES;
        unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
        unsigned last_pte, i;
 
@@ -96,7 +96,7 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt,
                if (last_pte > I915_PPGTT_PT_ENTRIES)
                        last_pte = I915_PPGTT_PT_ENTRIES;
 
-               pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]);
+               pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pt]);
 
                for (i = first_pte; i < last_pte; i++)
                        pt_vaddr[i] = scratch_pte;
@@ -105,7 +105,7 @@ static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt,
 
                num_entries -= last_pte - first_pte;
                first_pte = 0;
-               act_pd++;
+               act_pt++;
        }
 }
 
@@ -115,42 +115,27 @@ static void gen6_ppgtt_insert_entries(struct i915_hw_ppgtt *ppgtt,
                                      enum i915_cache_level cache_level)
 {
        gtt_pte_t *pt_vaddr;
-       unsigned act_pd = first_entry / I915_PPGTT_PT_ENTRIES;
-       unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
-       unsigned i, j, m, segment_len;
-       dma_addr_t page_addr;
-       struct scatterlist *sg;
-
-       /* init sg walking */
-       sg = pages->sgl;
-       i = 0;
-       segment_len = sg_dma_len(sg) >> PAGE_SHIFT;
-       m = 0;
-
-       while (i < pages->nents) {
-               pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pd]);
-
-               for (j = first_pte; j < I915_PPGTT_PT_ENTRIES; j++) {
-                       page_addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
-                       pt_vaddr[j] = gen6_pte_encode(ppgtt->dev, page_addr,
-                                                     cache_level);
-
-                       /* grab the next page */
-                       if (++m == segment_len) {
-                               if (++i == pages->nents)
-                                       break;
-
-                               sg = sg_next(sg);
-                               segment_len = sg_dma_len(sg) >> PAGE_SHIFT;
-                               m = 0;
-                       }
-               }
-
-               kunmap_atomic(pt_vaddr);
+       unsigned act_pt = first_entry / I915_PPGTT_PT_ENTRIES;
+       unsigned act_pte = first_entry % I915_PPGTT_PT_ENTRIES;
+       struct sg_page_iter sg_iter;
+
+       pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pt]);
+       for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
+               dma_addr_t page_addr;
+
+               page_addr = sg_dma_address(sg_iter.sg) +
+                               (sg_iter.sg_pgoffset << PAGE_SHIFT);
+               pt_vaddr[act_pte] = gen6_pte_encode(ppgtt->dev, page_addr,
+                                                   cache_level);
+               if (++act_pte == I915_PPGTT_PT_ENTRIES) {
+                       kunmap_atomic(pt_vaddr);
+                       act_pt++;
+                       pt_vaddr = kmap_atomic(ppgtt->pt_pages[act_pt]);
+                       act_pte = 0;
 
-               first_pte = 0;
-               act_pd++;
+               }
        }
+       kunmap_atomic(pt_vaddr);
 }
 
 static void gen6_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
@@ -432,21 +417,17 @@ static void gen6_ggtt_insert_entries(struct drm_device *dev,
                                     enum i915_cache_level level)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct scatterlist *sg = st->sgl;
        gtt_pte_t __iomem *gtt_entries =
                (gtt_pte_t __iomem *)dev_priv->gtt.gsm + first_entry;
-       int unused, i = 0;
-       unsigned int len, m = 0;
+       int i = 0;
+       struct sg_page_iter sg_iter;
        dma_addr_t addr;
 
-       for_each_sg(st->sgl, sg, st->nents, unused) {
-               len = sg_dma_len(sg) >> PAGE_SHIFT;
-               for (m = 0; m < len; m++) {
-                       addr = sg_dma_address(sg) + (m << PAGE_SHIFT);
-                       iowrite32(gen6_pte_encode(dev, addr, level),
-                                 &gtt_entries[i]);
-                       i++;
-               }
+       for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
+               addr = sg_dma_address(sg_iter.sg) +
+                       (sg_iter.sg_pgoffset << PAGE_SHIFT);
+               iowrite32(gen6_pte_encode(dev, addr, level), &gtt_entries[i]);
+               i++;
        }
 
        /* XXX: This serves as a posting read to make sure that the PTE has
@@ -752,7 +733,7 @@ static int gen6_gmch_probe(struct drm_device *dev,
        pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
        gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
 
-       if (IS_GEN7(dev))
+       if (IS_GEN7(dev) && !IS_VALLEYVIEW(dev))
                *stolen = gen7_get_stolen_size(snb_gmch_ctl);
        else
                *stolen = gen6_get_stolen_size(snb_gmch_ctl);