|
@@ -116,7 +116,7 @@ static inline gen8_ppgtt_pde_t gen8_pde_encode(struct drm_device *dev,
|
|
|
|
|
|
|
|
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
|
|
static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
|
|
|
enum i915_cache_level level,
|
|
enum i915_cache_level level,
|
|
|
- bool valid)
|
|
|
|
|
|
|
+ bool valid, u32 unused)
|
|
|
{
|
|
{
|
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
@@ -138,7 +138,7 @@ static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
|
|
|
|
|
|
|
|
static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
|
|
static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
|
|
|
enum i915_cache_level level,
|
|
enum i915_cache_level level,
|
|
|
- bool valid)
|
|
|
|
|
|
|
+ bool valid, u32 unused)
|
|
|
{
|
|
{
|
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
@@ -162,7 +162,7 @@ static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
|
|
|
|
|
|
|
|
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
|
static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
|
|
enum i915_cache_level level,
|
|
enum i915_cache_level level,
|
|
|
- bool valid)
|
|
|
|
|
|
|
+ bool valid, u32 flags)
|
|
|
{
|
|
{
|
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
pte |= GEN6_PTE_ADDR_ENCODE(addr);
|
|
@@ -170,7 +170,8 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
|
|
/* Mark the page as writeable. Other platforms don't have a
|
|
/* Mark the page as writeable. Other platforms don't have a
|
|
|
* setting for read-only/writable, so this matches that behavior.
|
|
* setting for read-only/writable, so this matches that behavior.
|
|
|
*/
|
|
*/
|
|
|
- pte |= BYT_PTE_WRITEABLE;
|
|
|
|
|
|
|
+ if (!(flags & PTE_READ_ONLY))
|
|
|
|
|
+ pte |= BYT_PTE_WRITEABLE;
|
|
|
|
|
|
|
|
if (level != I915_CACHE_NONE)
|
|
if (level != I915_CACHE_NONE)
|
|
|
pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
|
|
pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
|
|
@@ -180,7 +181,7 @@ static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
|
|
|
|
|
|
|
|
static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
|
|
static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
|
|
|
enum i915_cache_level level,
|
|
enum i915_cache_level level,
|
|
|
- bool valid)
|
|
|
|
|
|
|
+ bool valid, u32 unused)
|
|
|
{
|
|
{
|
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
|
@@ -193,7 +194,7 @@ static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
|
|
|
|
|
|
|
|
static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
|
|
static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
|
|
|
enum i915_cache_level level,
|
|
enum i915_cache_level level,
|
|
|
- bool valid)
|
|
|
|
|
|
|
+ bool valid, u32 unused)
|
|
|
{
|
|
{
|
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
|
|
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
|
pte |= HSW_PTE_ADDR_ENCODE(addr);
|
|
@@ -307,7 +308,7 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
|
|
|
static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
|
|
static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
|
|
|
struct sg_table *pages,
|
|
struct sg_table *pages,
|
|
|
uint64_t start,
|
|
uint64_t start,
|
|
|
- enum i915_cache_level cache_level)
|
|
|
|
|
|
|
+ enum i915_cache_level cache_level, u32 unused)
|
|
|
{
|
|
{
|
|
|
struct i915_hw_ppgtt *ppgtt =
|
|
struct i915_hw_ppgtt *ppgtt =
|
|
|
container_of(vm, struct i915_hw_ppgtt, base);
|
|
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)
|
|
|
uint32_t pd_entry;
|
|
uint32_t pd_entry;
|
|
|
int pte, pde;
|
|
int pte, pde;
|
|
|
|
|
|
|
|
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
|
|
|
|
|
|
|
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
|
|
|
|
|
|
|
|
pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
|
|
pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
|
|
|
ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
|
|
ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
|
|
@@ -947,7 +948,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
|
|
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
|
|
unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
|
|
|
unsigned last_pte, i;
|
|
unsigned last_pte, i;
|
|
|
|
|
|
|
|
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
|
|
|
|
|
|
|
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true, 0);
|
|
|
|
|
|
|
|
while (num_entries) {
|
|
while (num_entries) {
|
|
|
last_pte = first_pte + num_entries;
|
|
last_pte = first_pte + num_entries;
|
|
@@ -970,7 +971,7 @@ static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
|
|
|
static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
|
static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
|
|
struct sg_table *pages,
|
|
struct sg_table *pages,
|
|
|
uint64_t start,
|
|
uint64_t start,
|
|
|
- enum i915_cache_level cache_level)
|
|
|
|
|
|
|
+ enum i915_cache_level cache_level, u32 flags)
|
|
|
{
|
|
{
|
|
|
struct i915_hw_ppgtt *ppgtt =
|
|
struct i915_hw_ppgtt *ppgtt =
|
|
|
container_of(vm, struct i915_hw_ppgtt, base);
|
|
container_of(vm, struct i915_hw_ppgtt, base);
|
|
@@ -987,7 +988,8 @@ static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
|
|
|
|
|
|
|
|
pt_vaddr[act_pte] =
|
|
pt_vaddr[act_pte] =
|
|
|
vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
|
|
vm->pte_encode(sg_page_iter_dma_address(&sg_iter),
|
|
|
- cache_level, true);
|
|
|
|
|
|
|
+ cache_level, true, flags);
|
|
|
|
|
+
|
|
|
if (++act_pte == I915_PPGTT_PT_ENTRIES) {
|
|
if (++act_pte == I915_PPGTT_PT_ENTRIES) {
|
|
|
kunmap_atomic(pt_vaddr);
|
|
kunmap_atomic(pt_vaddr);
|
|
|
pt_vaddr = NULL;
|
|
pt_vaddr = NULL;
|
|
@@ -1224,8 +1226,12 @@ ppgtt_bind_vma(struct i915_vma *vma,
|
|
|
enum i915_cache_level cache_level,
|
|
enum i915_cache_level cache_level,
|
|
|
u32 flags)
|
|
u32 flags)
|
|
|
{
|
|
{
|
|
|
|
|
+ /* Currently applicable only to VLV */
|
|
|
|
|
+ if (vma->obj->gt_ro)
|
|
|
|
|
+ flags |= PTE_READ_ONLY;
|
|
|
|
|
+
|
|
|
vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
|
|
vma->vm->insert_entries(vma->vm, vma->obj->pages, vma->node.start,
|
|
|
- cache_level);
|
|
|
|
|
|
|
+ cache_level, flags);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void ppgtt_unbind_vma(struct i915_vma *vma)
|
|
static 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)
|
|
|
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
|
|
static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
|
|
|
struct sg_table *st,
|
|
struct sg_table *st,
|
|
|
uint64_t start,
|
|
uint64_t start,
|
|
|
- enum i915_cache_level level)
|
|
|
|
|
|
|
+ enum i915_cache_level level, u32 unused)
|
|
|
{
|
|
{
|
|
|
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
|
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
|
|
unsigned first_entry = start >> PAGE_SHIFT;
|
|
unsigned first_entry = start >> PAGE_SHIFT;
|
|
@@ -1446,7 +1452,7 @@ static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
|
|
|
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|
static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|
|
struct sg_table *st,
|
|
struct sg_table *st,
|
|
|
uint64_t start,
|
|
uint64_t start,
|
|
|
- enum i915_cache_level level)
|
|
|
|
|
|
|
+ enum i915_cache_level level, u32 flags)
|
|
|
{
|
|
{
|
|
|
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
|
struct drm_i915_private *dev_priv = vm->dev->dev_private;
|
|
|
unsigned first_entry = start >> PAGE_SHIFT;
|
|
unsigned first_entry = start >> PAGE_SHIFT;
|
|
@@ -1458,7 +1464,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|
|
|
|
|
|
|
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
|
for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
|
|
|
addr = sg_page_iter_dma_address(&sg_iter);
|
|
addr = sg_page_iter_dma_address(&sg_iter);
|
|
|
- iowrite32(vm->pte_encode(addr, level, true), >t_entries[i]);
|
|
|
|
|
|
|
+ iowrite32(vm->pte_encode(addr, level, true, flags), >t_entries[i]);
|
|
|
i++;
|
|
i++;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1470,7 +1476,7 @@ static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
|
|
|
*/
|
|
*/
|
|
|
if (i != 0)
|
|
if (i != 0)
|
|
|
WARN_ON(readl(>t_entries[i-1]) !=
|
|
WARN_ON(readl(>t_entries[i-1]) !=
|
|
|
- vm->pte_encode(addr, level, true));
|
|
|
|
|
|
|
+ vm->pte_encode(addr, level, true, flags));
|
|
|
|
|
|
|
|
/* This next bit makes the above posting read even more important. We
|
|
/* This next bit makes the above posting read even more important. We
|
|
|
* want to flush the TLBs only after we're certain all the PTE updates
|
|
* 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,
|
|
|
first_entry, num_entries, max_entries))
|
|
first_entry, num_entries, max_entries))
|
|
|
num_entries = max_entries;
|
|
num_entries = max_entries;
|
|
|
|
|
|
|
|
- scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch);
|
|
|
|
|
|
|
+ scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch, 0);
|
|
|
|
|
|
|
|
for (i = 0; i < num_entries; i++)
|
|
for (i = 0; i < num_entries; i++)
|
|
|
iowrite32(scratch_pte, >t_base[i]);
|
|
iowrite32(scratch_pte, >t_base[i]);
|
|
@@ -1573,6 +1579,10 @@ static void ggtt_bind_vma(struct i915_vma *vma,
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct drm_i915_gem_object *obj = vma->obj;
|
|
struct drm_i915_gem_object *obj = vma->obj;
|
|
|
|
|
|
|
|
|
|
+ /* Currently applicable only to VLV */
|
|
|
|
|
+ if (obj->gt_ro)
|
|
|
|
|
+ flags |= PTE_READ_ONLY;
|
|
|
|
|
+
|
|
|
/* If there is no aliasing PPGTT, or the caller needs a global mapping,
|
|
/* If there is no aliasing PPGTT, or the caller needs a global mapping,
|
|
|
* or we have a global mapping already but the cacheability flags have
|
|
* or we have a global mapping already but the cacheability flags have
|
|
|
* changed, set the global PTEs.
|
|
* changed, set the global PTEs.
|
|
@@ -1589,7 +1599,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
|
|
|
(cache_level != obj->cache_level)) {
|
|
(cache_level != obj->cache_level)) {
|
|
|
vma->vm->insert_entries(vma->vm, obj->pages,
|
|
vma->vm->insert_entries(vma->vm, obj->pages,
|
|
|
vma->node.start,
|
|
vma->node.start,
|
|
|
- cache_level);
|
|
|
|
|
|
|
+ cache_level, flags);
|
|
|
obj->has_global_gtt_mapping = 1;
|
|
obj->has_global_gtt_mapping = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -1601,7 +1611,7 @@ static void ggtt_bind_vma(struct i915_vma *vma,
|
|
|
appgtt->base.insert_entries(&appgtt->base,
|
|
appgtt->base.insert_entries(&appgtt->base,
|
|
|
vma->obj->pages,
|
|
vma->obj->pages,
|
|
|
vma->node.start,
|
|
vma->node.start,
|
|
|
- cache_level);
|
|
|
|
|
|
|
+ cache_level, flags);
|
|
|
vma->obj->has_aliasing_ppgtt_mapping = 1;
|
|
vma->obj->has_aliasing_ppgtt_mapping = 1;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|