aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem_gtt.c
diff options
context:
space:
mode:
authorAkash Goel <akash.goel@intel.com>2014-06-17 01:29:42 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-17 03:21:47 -0400
commit24f3a8cf7766e52a087904b4346794c7b410f957 (patch)
treeb3aae1632b0a7acfdac0e1c4272b19cd25c77a69 /drivers/gpu/drm/i915/i915_gem_gtt.c
parent5aa8a937730940b48b70b21e05cf03e4cea31058 (diff)
drm/i915: Added write-enable pte bit supportt
This adds support for a write-enable bit in the entry of GTT. This is handled via a read-only flag in the GEM buffer object which is then used to see how to set the bit when writing the GTT entries. Currently by default the Batch buffer & Ring buffers are marked as read only. v2: Moved the pte override code for read-only bit to 'byt_pte_encode'. (Chris) Fixed the issue of leaving 'gt_old_ro' as unused. (Chris) v3: Removed the 'gt_old_ro' field, now setting RO bit only for Ring Buffers(Daniel). v4: Added a new 'flags' parameter to all the pte(gen6) encode & insert_entries functions, in lieu of overloading the cache_level enum (Daniel). v5: Removed the superfluous VLV check & changed the definition location of PTE_READ_ONLY flag (Imre) Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Akash Goel <akash.goel@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6f5d5a1e7c32..743ddfcf2696 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -116,7 +116,7 @@ static inline gen8_ppgtt_pde_t gen8_pde_encode(struct drm_device *dev,
116 116
117static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr, 117static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
118 enum i915_cache_level level, 118 enum i915_cache_level level,
119 bool valid) 119 bool valid, u32 unused)
120{ 120{
121 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; 121 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
122 pte |= GEN6_PTE_ADDR_ENCODE(addr); 122 pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -138,7 +138,7 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
138 138
139static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr, 139static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
140 enum i915_cache_level level, 140 enum i915_cache_level level,
141 bool valid) 141 bool valid, u32 unused)
142{ 142{
143 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; 143 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
144 pte |= GEN6_PTE_ADDR_ENCODE(addr); 144 pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -162,7 +162,7 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
162 162
163static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr, 163static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
164 enum i915_cache_level level, 164 enum i915_cache_level level,
165 bool valid) 165 bool valid, u32 flags)
166{ 166{
167 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; 167 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
168 pte |= GEN6_PTE_ADDR_ENCODE(addr); 168 pte |= GEN6_PTE_ADDR_ENCODE(addr);
@@ -170,7 +170,8 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
170 /* Mark the page as writeable. Other platforms don't have a 170 /* Mark the page as writeable. Other platforms don't have a
171 * setting for read-only/writable, so this matches that behavior. 171 * setting for read-only/writable, so this matches that behavior.
172 */ 172 */
173 pte |= BYT_PTE_WRITEABLE; 173 if (!(flags & PTE_READ_ONLY))
174 pte |= BYT_PTE_WRITEABLE;
174 175
175 if (level != I915_CACHE_NONE) 176 if (level != I915_CACHE_NONE)
176 pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES; 177 pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
@@ -180,7 +181,7 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
180 181
181static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr, 182static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
182 enum i915_cache_level level, 183 enum i915_cache_level level,
183 bool valid) 184 bool valid, u32 unused)
184{ 185{
185 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; 186 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
186 pte |= HSW_PTE_ADDR_ENCODE(addr); 187 pte |= HSW_PTE_ADDR_ENCODE(addr);
@@ -193,7 +194,7 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
193 194
194static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr, 195static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
195 enum i915_cache_level level, 196 enum i915_cache_level level,
196 bool valid) 197 bool valid, u32 unused)
197{ 198{
198 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0; 199 gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
199 pte |= HSW_PTE_ADDR_ENCODE(addr); 200 pte |= HSW_PTE_ADDR_ENCODE(addr);
@@ -307,7 +308,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
307static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, 308static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
308 struct sg_table *pages, 309 struct sg_table *pages,
309 uint64_t start, 310 uint64_t start,
310 enum i915_cache_level cache_level) 311 enum i915_cache_level cache_level, u32 unused)
311{ 312{
312 struct i915_hw_ppgtt *ppgtt = 313 struct i915_hw_ppgtt *ppgtt =
313 container_of(vm, struct i915_hw_ppgtt, base); 314 container_of(vm, struct i915_hw_ppgtt, base);
@@ -645,7 +646,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
645 uint32_t pd_entry; 646 uint32_t pd_entry;
646 int pte, pde; 647 int pte, pde;
647 648
648 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true); 649 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
649 650
650 pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm + 651 pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
651 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t); 652 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
@@ -947,7 +948,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
947 unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES; 948 unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
948 unsigned last_pte, i; 949 unsigned last_pte, i;
949 950
950 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true); 951 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
951 952
952 while (num_entries) { 953 while (num_entries) {
953 last_pte = first_pte + num_entries; 954 last_pte = first_pte + num_entries;
@@ -970,7 +971,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
970static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, 971static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
971 struct sg_table *pages, 972 struct sg_table *pages,
972 uint64_t start, 973 uint64_t start,
973 enum i915_cache_level cache_level) 974 enum i915_cache_level cache_level, u32 flags)
974{ 975{
975 struct i915_hw_ppgtt *ppgtt = 976 struct i915_hw_ppgtt *ppgtt =
976 container_of(vm, struct i915_hw_ppgtt, base); 977 container_of(vm, struct i915_hw_ppgtt, base);
@@ -987,7 +988,8 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
987 988
988 pt_vaddr[act_pte] = 989 pt_vaddr[act_pte] =
989 vm->pte_encode(sg_page_iter_dma_address(&sg_iter), 990 vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
990 cache_level, true); 991 cache_level, true, flags);
992
991 if (++act_pte == I915_PPGTT_PT_ENTRIES) { 993 if (++act_pte == I915_PPGTT_PT_ENTRIES) {
992 kunmap_atomic(pt_vaddr); 994 kunmap_atomic(pt_vaddr);
993 pt_vaddr = NULL; 995 pt_vaddr = NULL;
@@ -1224,8 +1226,12 @@ ppgtt_bind_vma(struct i915_vma *vma,
1224 enum i915_cache_level cache_level, 1226 enum i915_cache_level cache_level,
1225 u32 flags) 1227 u32 flags)
1226{ 1228{
1229 /* Currently applicable only to VLV */
1230 if (vma->obj->gt_ro)
1231 flags |= PTE_READ_ONLY;
1232
1227 vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start, 1233 vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
1228 cache_level); 1234 cache_level, flags);
1229} 1235}
1230 1236
1231static void ppgtt_unbind_vma(struct i915_vma *vma) 1237static void ppgtt_unbind_vma(struct i915_vma *vma)
@@ -1400,7 +1406,7 @@ static inline void gen8_set_pte(void __iomem *addr, gen8_gtt_pte_t pte)
1400static void gen8_ggtt_insert_entries(struct i915_address_space *vm, 1406static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
1401 struct sg_table *st, 1407 struct sg_table *st,
1402 uint64_t start, 1408 uint64_t start,
1403 enum i915_cache_level level) 1409 enum i915_cache_level level, u32 unused)
1404{ 1410{
1405 struct drm_i915_private *dev_priv = vm->dev->dev_private; 1411 struct drm_i915_private *dev_priv = vm->dev->dev_private;
1406 unsigned first_entry = start >> PAGE_SHIFT; 1412 unsigned first_entry = start >> PAGE_SHIFT;
@@ -1446,7 +1452,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
1446static void gen6_ggtt_insert_entries(struct i915_address_space *vm, 1452static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
1447 struct sg_table *st, 1453 struct sg_table *st,
1448 uint64_t start, 1454 uint64_t start,
1449 enum i915_cache_level level) 1455 enum i915_cache_level level, u32 flags)
1450{ 1456{
1451 struct drm_i915_private *dev_priv = vm->dev->dev_private; 1457 struct drm_i915_private *dev_priv = vm->dev->dev_private;
1452 unsigned first_entry = start >> PAGE_SHIFT; 1458 unsigned first_entry = start >> PAGE_SHIFT;
@@ -1458,7 +1464,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
1458 1464
1459 for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) { 1465 for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
1460 addr = sg_page_iter_dma_address(&sg_iter); 1466 addr = sg_page_iter_dma_address(&sg_iter);
1461 iowrite32(vm->pte_encode(addr, level, true), &gtt_entries[i]); 1467 iowrite32(vm->pte_encode(addr, level, true, flags), &gtt_entries[i]);
1462 i++; 1468 i++;
1463 } 1469 }
1464 1470
@@ -1470,7 +1476,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
1470 */ 1476 */
1471 if (i != 0) 1477 if (i != 0)
1472 WARN_ON(readl(&gtt_entries[i-1]) != 1478 WARN_ON(readl(&gtt_entries[i-1]) !=
1473 vm->pte_encode(addr, level, true)); 1479 vm->pte_encode(addr, level, true, flags));
1474 1480
1475 /* This next bit makes the above posting read even more important. We 1481 /* This next bit makes the above posting read even more important. We
1476 * want to flush the TLBs only after we're certain all the PTE updates 1482 * want to flush the TLBs only after we're certain all the PTE updates
@@ -1524,7 +1530,7 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm,
1524 first_entry, num_entries, max_entries)) 1530 first_entry, num_entries, max_entries))
1525 num_entries = max_entries; 1531 num_entries = max_entries;
1526 1532
1527 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch); 1533 scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch, 0);
1528 1534
1529 for (i = 0; i < num_entries; i++) 1535 for (i = 0; i < num_entries; i++)
1530 iowrite32(scratch_pte, &gtt_base[i]); 1536 iowrite32(scratch_pte, &gtt_base[i]);
@@ -1573,6 +1579,10 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1573 struct drm_i915_private *dev_priv = dev->dev_private; 1579 struct drm_i915_private *dev_priv = dev->dev_private;
1574 struct drm_i915_gem_object *obj = vma->obj; 1580 struct drm_i915_gem_object *obj = vma->obj;
1575 1581
1582 /* Currently applicable only to VLV */
1583 if (obj->gt_ro)
1584 flags |= PTE_READ_ONLY;
1585
1576 /* If there is no aliasing PPGTT, or the caller needs a global mapping, 1586 /* If there is no aliasing PPGTT, or the caller needs a global mapping,
1577 * or we have a global mapping already but the cacheability flags have 1587 * or we have a global mapping already but the cacheability flags have
1578 * changed, set the global PTEs. 1588 * changed, set the global PTEs.
@@ -1589,7 +1599,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1589 (cache_level != obj->cache_level)) { 1599 (cache_level != obj->cache_level)) {
1590 vma->vm->insert_entries(vma->vm, obj->pages, 1600 vma->vm->insert_entries(vma->vm, obj->pages,
1591 vma->node.start, 1601 vma->node.start,
1592 cache_level); 1602 cache_level, flags);
1593 obj->has_global_gtt_mapping = 1; 1603 obj->has_global_gtt_mapping = 1;
1594 } 1604 }
1595 } 1605 }
@@ -1601,7 +1611,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
1601 appgtt->base.insert_entries(&appgtt->base, 1611 appgtt->base.insert_entries(&appgtt->base,
1602 vma->obj->pages, 1612 vma->obj->pages,
1603 vma->node.start, 1613 vma->node.start,
1604 cache_level); 1614 cache_level, flags);
1605 vma->obj->has_aliasing_ppgtt_mapping = 1; 1615 vma->obj->has_aliasing_ppgtt_mapping = 1;
1606 } 1616 }
1607} 1617}