Commit 058d88c4 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Track pinned VMA

Treat the VMA as the primary struct responsible for tracking bindings
into the GPU's VM. That is we want to treat the VMA returned after we
pin an object into the VM as the cookie we hold and eventually release
when unpinning. Doing so eliminates the ambiguity in pinning the object
and then searching for the relevant pin later.

v2: Joonas' stylistic nitpicks, a fun rebase.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1471254551-25805-27-git-send-email-chris@chris-wilson.co.uk
parent 19880c4a
...@@ -105,7 +105,7 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj) ...@@ -105,7 +105,7 @@ static char get_tiling_flag(struct drm_i915_gem_object *obj)
static char get_global_flag(struct drm_i915_gem_object *obj) static char get_global_flag(struct drm_i915_gem_object *obj)
{ {
return i915_gem_obj_to_ggtt(obj) ? 'g' : ' '; return i915_gem_object_to_ggtt(obj, NULL) ? 'g' : ' ';
} }
static char get_pin_mapped_flag(struct drm_i915_gem_object *obj) static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
......
...@@ -3075,7 +3075,7 @@ struct drm_i915_gem_object *i915_gem_object_create_from_data( ...@@ -3075,7 +3075,7 @@ struct drm_i915_gem_object *i915_gem_object_create_from_data(
void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file); void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *file);
void i915_gem_free_object(struct drm_gem_object *obj); void i915_gem_free_object(struct drm_gem_object *obj);
int __must_check struct i915_vma * __must_check
i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj, i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view, const struct i915_ggtt_view *view,
u64 size, u64 size,
...@@ -3279,12 +3279,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, ...@@ -3279,12 +3279,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
bool write); bool write);
int __must_check int __must_check
i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write); i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write);
int __must_check struct i915_vma * __must_check
i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj,
u32 alignment, u32 alignment,
const struct i915_ggtt_view *view); const struct i915_ggtt_view *view);
void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj, void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
const struct i915_ggtt_view *view);
int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
int align); int align);
int i915_gem_open(struct drm_device *dev, struct drm_file *file); int i915_gem_open(struct drm_device *dev, struct drm_file *file);
...@@ -3304,63 +3303,34 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev, ...@@ -3304,63 +3303,34 @@ struct drm_gem_object *i915_gem_prime_import(struct drm_device *dev,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev, struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *gem_obj, int flags); struct drm_gem_object *gem_obj, int flags);
u64 i915_gem_obj_ggtt_offset_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view);
u64 i915_gem_obj_offset(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
static inline u64
i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *o)
{
return i915_gem_obj_ggtt_offset_view(o, &i915_ggtt_view_normal);
}
bool i915_gem_obj_ggtt_bound_view(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view);
bool i915_gem_obj_bound(struct drm_i915_gem_object *o,
struct i915_address_space *vm);
struct i915_vma * struct i915_vma *
i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm); struct i915_address_space *vm,
struct i915_vma * const struct i915_ggtt_view *view);
i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view);
struct i915_vma * struct i915_vma *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm); struct i915_address_space *vm,
struct i915_vma * const struct i915_ggtt_view *view);
i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view);
static inline struct i915_vma *
i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj)
{
return i915_gem_obj_to_ggtt_view(obj, &i915_ggtt_view_normal);
}
bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj);
/* Some GGTT VM helpers */
static inline struct i915_hw_ppgtt * static inline struct i915_hw_ppgtt *
i915_vm_to_ppgtt(struct i915_address_space *vm) i915_vm_to_ppgtt(struct i915_address_space *vm)
{ {
return container_of(vm, struct i915_hw_ppgtt, base); return container_of(vm, struct i915_hw_ppgtt, base);
} }
static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) static inline struct i915_vma *
i915_gem_object_to_ggtt(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view)
{ {
return i915_gem_obj_ggtt_bound_view(obj, &i915_ggtt_view_normal); return i915_gem_obj_to_vma(obj, &to_i915(obj->base.dev)->ggtt.base, view);
} }
unsigned long static inline unsigned long
i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj); i915_gem_object_ggtt_offset(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view)
void i915_gem_object_ggtt_unpin_view(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view);
static inline void
i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj)
{ {
i915_gem_object_ggtt_unpin_view(obj, &i915_ggtt_view_normal); return i915_gem_object_to_ggtt(o, view)->node.start;
} }
/* i915_gem_fence.c */ /* i915_gem_fence.c */
......
This diff is collapsed.
...@@ -180,8 +180,8 @@ eb_lookup_vmas(struct eb_vmas *eb, ...@@ -180,8 +180,8 @@ eb_lookup_vmas(struct eb_vmas *eb,
* from the (obj, vm) we don't run the risk of creating * from the (obj, vm) we don't run the risk of creating
* duplicated vmas for the same vm. * duplicated vmas for the same vm.
*/ */
vma = i915_gem_obj_lookup_or_create_vma(obj, vm); vma = i915_gem_obj_lookup_or_create_vma(obj, vm, NULL);
if (IS_ERR(vma)) { if (unlikely(IS_ERR(vma))) {
DRM_DEBUG("Failed to lookup VMA\n"); DRM_DEBUG("Failed to lookup VMA\n");
ret = PTR_ERR(vma); ret = PTR_ERR(vma);
goto err; goto err;
...@@ -349,30 +349,33 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, ...@@ -349,30 +349,33 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
struct drm_i915_gem_relocation_entry *reloc, struct drm_i915_gem_relocation_entry *reloc,
uint64_t target_offset) uint64_t target_offset)
{ {
struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct i915_vma *vma;
uint64_t delta = relocation_target(reloc, target_offset); uint64_t delta = relocation_target(reloc, target_offset);
uint64_t offset; uint64_t offset;
void __iomem *reloc_page; void __iomem *reloc_page;
int ret; int ret;
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
if (IS_ERR(vma))
return PTR_ERR(vma);
ret = i915_gem_object_set_to_gtt_domain(obj, true); ret = i915_gem_object_set_to_gtt_domain(obj, true);
if (ret) if (ret)
return ret; goto unpin;
ret = i915_gem_object_put_fence(obj); ret = i915_gem_object_put_fence(obj);
if (ret) if (ret)
return ret; goto unpin;
/* Map the page containing the relocation we're going to perform. */ /* Map the page containing the relocation we're going to perform. */
offset = i915_gem_obj_ggtt_offset(obj); offset = vma->node.start + reloc->offset;
offset += reloc->offset;
reloc_page = io_mapping_map_atomic_wc(ggtt->mappable, reloc_page = io_mapping_map_atomic_wc(ggtt->mappable,
offset & PAGE_MASK); offset & PAGE_MASK);
iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset));
if (INTEL_INFO(dev)->gen >= 8) { if (INTEL_GEN(dev_priv) >= 8) {
offset += sizeof(uint32_t); offset += sizeof(uint32_t);
if (offset_in_page(offset) == 0) { if (offset_in_page(offset) == 0) {
...@@ -388,7 +391,9 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, ...@@ -388,7 +391,9 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
io_mapping_unmap_atomic(reloc_page); io_mapping_unmap_atomic(reloc_page);
return 0; unpin:
i915_vma_unpin(vma);
return ret;
} }
static void static void
...@@ -1281,7 +1286,7 @@ i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req) ...@@ -1281,7 +1286,7 @@ i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req)
return 0; return 0;
} }
static struct i915_vma* static struct i915_vma *
i915_gem_execbuffer_parse(struct intel_engine_cs *engine, i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
struct drm_i915_gem_exec_object2 *shadow_exec_entry, struct drm_i915_gem_exec_object2 *shadow_exec_entry,
struct drm_i915_gem_object *batch_obj, struct drm_i915_gem_object *batch_obj,
...@@ -1305,31 +1310,28 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine, ...@@ -1305,31 +1310,28 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
batch_start_offset, batch_start_offset,
batch_len, batch_len,
is_master); is_master);
if (ret) if (ret) {
goto err; if (ret == -EACCES) /* unhandled chained batch */
vma = NULL;
ret = i915_gem_object_ggtt_pin(shadow_batch_obj, NULL, 0, 0, 0); else
if (ret) vma = ERR_PTR(ret);
goto err; goto out;
}
i915_gem_object_unpin_pages(shadow_batch_obj); vma = i915_gem_object_ggtt_pin(shadow_batch_obj, NULL, 0, 0, 0);
if (IS_ERR(vma))
goto out;
memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry)); memset(shadow_exec_entry, 0, sizeof(*shadow_exec_entry));
vma = i915_gem_obj_to_ggtt(shadow_batch_obj);
vma->exec_entry = shadow_exec_entry; vma->exec_entry = shadow_exec_entry;
vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN; vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN;
i915_gem_object_get(shadow_batch_obj); i915_gem_object_get(shadow_batch_obj);
list_add_tail(&vma->exec_list, &eb->vmas); list_add_tail(&vma->exec_list, &eb->vmas);
return vma; out:
err:
i915_gem_object_unpin_pages(shadow_batch_obj); i915_gem_object_unpin_pages(shadow_batch_obj);
if (ret == -EACCES) /* unhandled chained batch */ return vma;
return NULL;
else
return ERR_PTR(ret);
} }
static int static int
...@@ -1677,6 +1679,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1677,6 +1679,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
* hsw should have this fixed, but bdw mucks it up again. */ * hsw should have this fixed, but bdw mucks it up again. */
if (dispatch_flags & I915_DISPATCH_SECURE) { if (dispatch_flags & I915_DISPATCH_SECURE) {
struct drm_i915_gem_object *obj = params->batch->obj; struct drm_i915_gem_object *obj = params->batch->obj;
struct i915_vma *vma;
/* /*
* So on first glance it looks freaky that we pin the batch here * So on first glance it looks freaky that we pin the batch here
...@@ -1688,11 +1691,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1688,11 +1691,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
* fitting due to fragmentation. * fitting due to fragmentation.
* So this is actually safe. * So this is actually safe.
*/ */
ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0); vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
if (ret) if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err; goto err;
}
params->batch = i915_gem_obj_to_ggtt(obj); params->batch = vma;
} }
/* Allocate a request for this batch buffer nice and early. */ /* Allocate a request for this batch buffer nice and early. */
...@@ -1708,7 +1713,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ...@@ -1708,7 +1713,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
* inactive_list and lose its active reference. Hence we do not need * inactive_list and lose its active reference. Hence we do not need
* to explicitly hold another reference here. * to explicitly hold another reference here.
*/ */
params->request->batch_obj = params->batch->obj; params->request->batch = params->batch;
ret = i915_gem_request_add_to_client(params->request, file); ret = i915_gem_request_add_to_client(params->request, file);
if (ret) if (ret)
......
...@@ -85,7 +85,7 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, ...@@ -85,7 +85,7 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
POSTING_READ(fence_reg_lo); POSTING_READ(fence_reg_lo);
if (obj) { if (obj) {
struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
unsigned int tiling = i915_gem_object_get_tiling(obj); unsigned int tiling = i915_gem_object_get_tiling(obj);
unsigned int stride = i915_gem_object_get_stride(obj); unsigned int stride = i915_gem_object_get_stride(obj);
u32 size = vma->node.size; u32 size = vma->node.size;
...@@ -120,7 +120,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg, ...@@ -120,7 +120,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
u32 val; u32 val;
if (obj) { if (obj) {
struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
unsigned int tiling = i915_gem_object_get_tiling(obj); unsigned int tiling = i915_gem_object_get_tiling(obj);
unsigned int stride = i915_gem_object_get_stride(obj); unsigned int stride = i915_gem_object_get_stride(obj);
int pitch_val; int pitch_val;
...@@ -161,7 +161,7 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg, ...@@ -161,7 +161,7 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
u32 val; u32 val;
if (obj) { if (obj) {
struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); struct i915_vma *vma = i915_gem_object_to_ggtt(obj, NULL);
unsigned int tiling = i915_gem_object_get_tiling(obj); unsigned int tiling = i915_gem_object_get_tiling(obj);
unsigned int stride = i915_gem_object_get_stride(obj); unsigned int stride = i915_gem_object_get_stride(obj);
u32 pitch_val; u32 pitch_val;
...@@ -432,13 +432,7 @@ bool ...@@ -432,13 +432,7 @@ bool
i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
{ {
if (obj->fence_reg != I915_FENCE_REG_NONE) { if (obj->fence_reg != I915_FENCE_REG_NONE) {
struct drm_i915_private *dev_priv = to_i915(obj->base.dev); to_i915(obj->base.dev)->fence_regs[obj->fence_reg].pin_count++;
struct i915_vma *ggtt_vma = i915_gem_obj_to_ggtt(obj);
WARN_ON(!ggtt_vma ||
dev_priv->fence_regs[obj->fence_reg].pin_count >
i915_vma_pin_count(ggtt_vma));
dev_priv->fence_regs[obj->fence_reg].pin_count++;
return true; return true;
} else } else
return false; return false;
......
...@@ -3341,23 +3341,19 @@ void i915_vma_close(struct i915_vma *vma) ...@@ -3341,23 +3341,19 @@ void i915_vma_close(struct i915_vma *vma)
} }
static struct i915_vma * static struct i915_vma *
__i915_gem_vma_create(struct drm_i915_gem_object *obj, __i915_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm, struct i915_address_space *vm,
const struct i915_ggtt_view *view) const struct i915_ggtt_view *view)
{ {
struct i915_vma *vma; struct i915_vma *vma;
int i; int i;
GEM_BUG_ON(vm->closed); GEM_BUG_ON(vm->closed);
if (WARN_ON(i915_is_ggtt(vm) != !!view))
return ERR_PTR(-EINVAL);
vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL); vma = kmem_cache_zalloc(to_i915(obj->base.dev)->vmas, GFP_KERNEL);
if (vma == NULL) if (vma == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&vma->obj_link);
INIT_LIST_HEAD(&vma->exec_list); INIT_LIST_HEAD(&vma->exec_list);
for (i = 0; i < ARRAY_SIZE(vma->last_read); i++) for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
init_request_active(&vma->last_read[i], i915_vma_retire); init_request_active(&vma->last_read[i], i915_vma_retire);
...@@ -3366,8 +3362,7 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj, ...@@ -3366,8 +3362,7 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
vma->obj = obj; vma->obj = obj;
vma->size = obj->base.size; vma->size = obj->base.size;
if (i915_is_ggtt(vm)) { if (view) {
vma->flags |= I915_VMA_GGTT;
vma->ggtt_view = *view; vma->ggtt_view = *view;
if (view->type == I915_GGTT_VIEW_PARTIAL) { if (view->type == I915_GGTT_VIEW_PARTIAL) {
vma->size = view->params.partial.size; vma->size = view->params.partial.size;
...@@ -3377,57 +3372,79 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj, ...@@ -3377,57 +3372,79 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
intel_rotation_info_size(&view->params.rotated); intel_rotation_info_size(&view->params.rotated);
vma->size <<= PAGE_SHIFT; vma->size <<= PAGE_SHIFT;
} }
}
if (i915_is_ggtt(vm)) {
vma->flags |= I915_VMA_GGTT;
} else { } else {
i915_ppgtt_get(i915_vm_to_ppgtt(vm)); i915_ppgtt_get(i915_vm_to_ppgtt(vm));
} }
list_add_tail(&vma->obj_link, &obj->vma_list); list_add_tail(&vma->obj_link, &obj->vma_list);
return vma; return vma;
} }
static inline bool vma_matches(struct i915_vma *vma,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{
if (vma->vm != vm)
return false;
if (!i915_vma_is_ggtt(vma))
return true;
if (!view)
return vma->ggtt_view.type == 0;
if (vma->ggtt_view.type != view->type)
return false;
return memcmp(&vma->ggtt_view.params,
&view->params,
sizeof(view->params)) == 0;
}
struct i915_vma * struct i915_vma *
i915_vma_create(struct drm_i915_gem_object *obj, i915_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm, struct i915_address_space *vm,
const struct i915_ggtt_view *view) const struct i915_ggtt_view *view)
{ {
GEM_BUG_ON(view && !i915_is_ggtt(vm)); GEM_BUG_ON(view && !i915_is_ggtt(vm));
GEM_BUG_ON(view ? i915_gem_obj_to_ggtt_view(obj, view) : i915_gem_obj_to_vma(obj, vm)); GEM_BUG_ON(i915_gem_obj_to_vma(obj, vm, view));
return __i915_gem_vma_create(obj, vm, view ?: &i915_ggtt_view_normal); return __i915_vma_create(obj, vm, view);
} }
struct i915_vma * struct i915_vma *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm) struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{ {
struct i915_vma *vma; struct i915_vma *vma;
vma = i915_gem_obj_to_vma(obj, vm); list_for_each_entry_reverse(vma, &obj->vma_list, obj_link)
if (!vma) if (vma_matches(vma, vm, view))
vma = __i915_gem_vma_create(obj, vm, return vma;
i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL);
return vma; return NULL;
} }
struct i915_vma * struct i915_vma *
i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj, i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view) struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{ {
struct drm_device *dev = obj->base.dev; struct i915_vma *vma;
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct i915_vma *vma = i915_gem_obj_to_ggtt_view(obj, view);
GEM_BUG_ON(!view); GEM_BUG_ON(view && !i915_is_ggtt(vm));
vma = i915_gem_obj_to_vma(obj, vm, view);
if (!vma) if (!vma)
vma = __i915_gem_vma_create(obj, &ggtt->base, view); vma = __i915_vma_create(obj, vm, view);
GEM_BUG_ON(i915_vma_is_closed(vma)); GEM_BUG_ON(i915_vma_is_closed(vma));
return vma; return vma;
} }
static struct scatterlist * static struct scatterlist *
......
...@@ -610,20 +610,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev); ...@@ -610,20 +610,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev);
int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj); int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_finish_object(struct drm_i915_gem_object *obj);
static inline bool
i915_ggtt_view_equal(const struct i915_ggtt_view *a,
const struct i915_ggtt_view *b)
{
if (WARN_ON(!a || !b))
return false;
if (a->type != b->type)
return false;
if (a->type != I915_GGTT_VIEW_NORMAL)
return !memcmp(&a->params, &b->params, sizeof(a->params));
return true;
}
/* Flags used by pin/bind&friends. */ /* Flags used by pin/bind&friends. */
#define PIN_NONBLOCK BIT(0) #define PIN_NONBLOCK BIT(0)
#define PIN_MAPPABLE BIT(1) #define PIN_MAPPABLE BIT(1)
......
...@@ -406,7 +406,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine, ...@@ -406,7 +406,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
/* No zalloc, must clear what we need by hand */ /* No zalloc, must clear what we need by hand */
req->previous_context = NULL; req->previous_context = NULL;
req->file_priv = NULL; req->file_priv = NULL;
req->batch_obj = NULL; req->batch = NULL;
req->pid = NULL; req->pid = NULL;
req->elsp_submitted = 0; req->elsp_submitted = 0;
......
...@@ -118,7 +118,7 @@ struct drm_i915_gem_request { ...@@ -118,7 +118,7 @@ struct drm_i915_gem_request {
/** Batch buffer related to this request if any (used for /** Batch buffer related to this request if any (used for
* error state dump only). * error state dump only).
*/ */
struct drm_i915_gem_object *batch_obj; struct i915_vma *batch;
struct list_head active_list; struct list_head active_list;
/** Time at which this request was emitted, in jiffies. */ /** Time at which this request was emitted, in jiffies. */
......
...@@ -696,7 +696,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, ...@@ -696,7 +696,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
if (gtt_offset == I915_GTT_OFFSET_NONE) if (gtt_offset == I915_GTT_OFFSET_NONE)
return obj; return obj;
vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base); vma = i915_gem_obj_lookup_or_create_vma(obj, &ggtt->base, NULL);
if (IS_ERR(vma)) { if (IS_ERR(vma)) {
ret = PTR_ERR(vma); ret = PTR_ERR(vma);
goto err; goto err;
......
...@@ -130,7 +130,7 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, int tiling_mode) ...@@ -130,7 +130,7 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, int tiling_mode)
if (INTEL_GEN(dev_priv) >= 4) if (INTEL_GEN(dev_priv) >= 4)
return 0; return 0;
vma = i915_gem_obj_to_ggtt(obj); vma = i915_gem_object_to_ggtt(obj, NULL);
if (!vma) if (!vma)
return 0; return 0;
......
...@@ -653,46 +653,42 @@ static void i915_error_state_free(struct kref *error_ref) ...@@ -653,46 +653,42 @@ static void i915_error_state_free(struct kref *error_ref)
static struct drm_i915_error_object * static struct drm_i915_error_object *
i915_error_object_create(struct drm_i915_private *dev_priv, i915_error_object_create(struct drm_i915_private *dev_priv,
struct drm_i915_gem_object *src, struct i915_vma *vma)
struct i915_address_space *vm)
{ {
struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct drm_i915_gem_object *src;
struct drm_i915_error_object *dst; struct drm_i915_error_object *dst;
struct i915_vma *vma = NULL;
int num_pages; int num_pages;
bool use_ggtt; bool use_ggtt;
int i = 0; int i = 0;
u64 reloc_offset; u64 reloc_offset;
if (src == NULL || src->pages == NULL) if (!vma)
return NULL;
src = vma->obj;
if (!src->pages)
return NULL; return NULL;
num_pages = src->base.size >> PAGE_SHIFT; num_pages = src->base.size >> PAGE_SHIFT;
dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC); dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC);
if (dst == NULL) if (!dst)
return NULL; return NULL;
if (i915_gem_obj_bound(src, vm)) reloc_offset = dst->gtt_offset = vma->node.start;
dst->gtt_offset = i915_gem_obj_offset(src, vm);
else
dst->gtt_offset = -1;
reloc_offset = dst->gtt_offset;
if (i915_is_ggtt(vm))
vma = i915_gem_obj_to_ggtt(src);
use_ggtt = (src->cache_level == I915_CACHE_NONE && use_ggtt = (src->cache_level == I915_CACHE_NONE &&
vma && (vma->flags & I915_VMA_GLOBAL_BIND) && (vma->flags & I915_VMA_GLOBAL_BIND) &&
reloc_offset + num_pages * PAGE_SIZE <= ggtt->mappable_end); reloc_offset + num_pages * PAGE_SIZE <= ggtt->mappable_end);
/* Cannot access stolen address directly, try to use the aperture */ /* Cannot access stolen address directly, try to use the aperture */
if (src->stolen) { if (src->stolen) {
use_ggtt = true; use_ggtt = true;
if (!(vma && vma->flags & I915_VMA_GLOBAL_BIND)) if (!(vma->flags & I915_VMA_GLOBAL_BIND))
goto unwind; goto unwind;
reloc_offset = i915_gem_obj_ggtt_offset(src); reloc_offset = vma->node.start;
if (reloc_offset + num_pages * PAGE_SIZE > ggtt->mappable_end) if (reloc_offset + num_pages * PAGE_SIZE > ggtt->mappable_end)
goto unwind; goto unwind;
} }
...@@ -752,8 +748,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv, ...@@ -752,8 +748,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
kfree(dst); kfree(dst);
return NULL; return NULL;
} }
#define i915_error_ggtt_object_create(dev_priv, src) \
i915_error_object_create((dev_priv), (src), &(dev_priv)->ggtt.base)
/* The error capture is special as tries to run underneath the normal /* The error capture is special as tries to run underneath the normal
* locking rules - so we use the raw version of the i915_gem_active lookup. * locking rules - so we use the raw version of the i915_gem_active lookup.
...@@ -1062,8 +1056,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, ...@@ -1062,8 +1056,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
int i, count; int i, count;
error->semaphore = error->semaphore =
i915_error_ggtt_object_create(dev_priv, i915_error_object_create(dev_priv, dev_priv->semaphore);
dev_priv->semaphore->obj);
for (i = 0; i < I915_NUM_ENGINES; i++) { for (i = 0; i < I915_NUM_ENGINES; i++) {
struct intel_engine_cs *engine = &dev_priv->engine[i]; struct intel_engine_cs *engine = &dev_priv->engine[i];
...@@ -1093,18 +1086,16 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, ...@@ -1093,18 +1086,16 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
*/ */
ee->batchbuffer = ee->batchbuffer =
i915_error_object_create(dev_priv, i915_error_object_create(dev_priv,
request->batch_obj, request->batch);
ee->vm);
if (HAS_BROKEN_CS_TLB(dev_priv)) if (HAS_BROKEN_CS_TLB(dev_priv))
ee->wa_batchbuffer = ee->wa_batchbuffer =
i915_error_ggtt_object_create(dev_priv, i915_error_object_create(dev_priv,
engine->scratch->obj); engine->scratch);
if (request->ctx->engine[i].state) { ee->ctx =
ee->ctx = i915_error_ggtt_object_create(dev_priv, i915_error_object_create(dev_priv,
request->ctx->engine[i].state->obj); request->ctx->engine[i].state);
}
if (request->pid) { if (request->pid) {
struct task_struct *task; struct task_struct *task;
...@@ -1125,16 +1116,15 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv, ...@@ -1125,16 +1116,15 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
ee->cpu_ring_head = ring->head; ee->cpu_ring_head = ring->head;
ee->cpu_ring_tail = ring->tail; ee->cpu_ring_tail = ring->tail;
ee->ringbuffer = ee->ringbuffer =
i915_error_ggtt_object_create(dev_priv, i915_error_object_create(dev_priv, ring->vma);
ring->vma->obj);
} }
ee->hws_page = ee->hws_page =
i915_error_ggtt_object_create(dev_priv, i915_error_object_create(dev_priv,
engine->status_page.vma->obj); engine->status_page.vma);
ee->wa_ctx = i915_error_ggtt_object_create(dev_priv, ee->wa_ctx =
engine->wa_ctx.vma->obj); i915_error_object_create(dev_priv, engine->wa_ctx.vma);
count = 0; count = 0;
list_for_each_entry(request, &engine->request_list, link) list_for_each_entry(request, &engine->request_list, link)
......
...@@ -2179,14 +2179,14 @@ static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv ...@@ -2179,14 +2179,14 @@ static unsigned int intel_surf_alignment(const struct drm_i915_private *dev_priv
} }
} }
int struct i915_vma *
intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
unsigned int rotation)
{ {
struct drm_device *dev = fb->dev; struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view; struct i915_ggtt_view view;
struct i915_vma *vma;
u32 alignment; u32 alignment;
int ret; int ret;
...@@ -2213,10 +2213,11 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, ...@@ -2213,10 +2213,11 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
*/ */
intel_runtime_pm_get(dev_priv); intel_runtime_pm_get(dev_priv);
ret = i915_gem_object_pin_to_display_plane(obj, alignment, vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
&view); if (IS_ERR(vma)) {
if (ret) ret = PTR_ERR(vma);
goto err_pm; goto err_pm;
}
/* Install a fence for tiled scan-out. Pre-i965 always needs a /* Install a fence for tiled scan-out. Pre-i965 always needs a
* fence, whereas 965+ only requires a fence if using * fence, whereas 965+ only requires a fence if using
...@@ -2243,19 +2244,20 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, ...@@ -2243,19 +2244,20 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
} }
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return 0; return vma;
err_unpin: err_unpin:
i915_gem_object_unpin_from_display_plane(obj, &view); i915_gem_object_unpin_from_display_plane(vma);
err_pm: err_pm:
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return ret; return ERR_PTR(ret);
} }
void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
{ {
struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view; struct i915_ggtt_view view;
struct i915_vma *vma;
WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex)); WARN_ON(!mutex_is_locked(&obj->base.dev->struct_mutex));
...@@ -2264,7 +2266,8 @@ void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation) ...@@ -2264,7 +2266,8 @@ void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
if (view.type == I915_GGTT_VIEW_NORMAL) if (view.type == I915_GGTT_VIEW_NORMAL)
i915_gem_object_unpin_fence(obj); i915_gem_object_unpin_fence(obj);
i915_gem_object_unpin_from_display_plane(obj, &view); vma = i915_gem_object_to_ggtt(obj, &view);
i915_gem_object_unpin_from_display_plane(vma);
} }
static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane, static int intel_fb_pitch(const struct drm_framebuffer *fb, int plane,
...@@ -2796,7 +2799,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, ...@@ -2796,7 +2799,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
continue; continue;
obj = intel_fb_obj(fb); obj = intel_fb_obj(fb);
if (i915_gem_obj_ggtt_offset(obj) == plane_config->base) { if (i915_gem_object_ggtt_offset(obj, NULL) == plane_config->base) {
drm_framebuffer_reference(fb); drm_framebuffer_reference(fb);
goto valid_fb; goto valid_fb;
} }
...@@ -3115,7 +3118,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary, ...@@ -3115,7 +3118,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPLINOFF(plane), linear_offset); I915_WRITE(DSPLINOFF(plane), linear_offset);
} else } else
I915_WRITE(DSPADDR(plane), i915_gem_obj_ggtt_offset(obj) + linear_offset); I915_WRITE(DSPADDR(plane), i915_gem_object_ggtt_offset(obj, NULL) + linear_offset);
POSTING_READ(reg); POSTING_READ(reg);
} }
...@@ -3237,11 +3240,17 @@ u32 intel_fb_gtt_offset(struct drm_framebuffer *fb, ...@@ -3237,11 +3240,17 @@ u32 intel_fb_gtt_offset(struct drm_framebuffer *fb,
{ {
struct drm_i915_gem_object *obj = intel_fb_obj(fb); struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view; struct i915_ggtt_view view;
struct i915_vma *vma;
u64 offset; u64 offset;
intel_fill_fb_ggtt_view(&view, fb, rotation); intel_fill_fb_ggtt_view(&view, fb, rotation);
offset = i915_gem_obj_ggtt_offset_view(obj, &view); vma = i915_gem_object_to_ggtt(obj, &view);
if (WARN(!vma, "ggtt vma for display object not found! (view=%u)\n",
view.type))
return -1;
offset = vma->node.start;
WARN_ON(upper_32_bits(offset)); WARN_ON(upper_32_bits(offset));
...@@ -12032,6 +12041,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -12032,6 +12041,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
bool mmio_flip; bool mmio_flip;
struct drm_i915_gem_request *request; struct drm_i915_gem_request *request;
struct i915_vma *vma;
int ret; int ret;
/* /*
...@@ -12139,9 +12149,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ...@@ -12139,9 +12149,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
mmio_flip = use_mmio_flip(engine, obj); mmio_flip = use_mmio_flip(engine, obj);
ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation); vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
if (ret) if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto cleanup_pending; goto cleanup_pending;
}
work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation); work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation);
work->gtt_offset += intel_crtc->dspaddr_offset; work->gtt_offset += intel_crtc->dspaddr_offset;
...@@ -14484,7 +14496,11 @@ intel_prepare_plane_fb(struct drm_plane *plane, ...@@ -14484,7 +14496,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (ret) if (ret)
DRM_DEBUG_KMS("failed to attach phys object\n"); DRM_DEBUG_KMS("failed to attach phys object\n");
} else { } else {
ret = intel_pin_and_fence_fb_obj(fb, new_state->rotation); struct i915_vma *vma;
vma = intel_pin_and_fence_fb_obj(fb, new_state->rotation);
if (IS_ERR(vma))
ret = PTR_ERR(vma);
} }
if (ret == 0) { if (ret == 0) {
...@@ -14850,7 +14866,7 @@ intel_update_cursor_plane(struct drm_plane *plane, ...@@ -14850,7 +14866,7 @@ intel_update_cursor_plane(struct drm_plane *plane,
if (!obj) if (!obj)
addr = 0; addr = 0;
else if (!INTEL_INFO(dev)->cursor_needs_physical) else if (!INTEL_INFO(dev)->cursor_needs_physical)
addr = i915_gem_obj_ggtt_offset(obj); addr = i915_gem_object_ggtt_offset(obj, NULL);
else else
addr = obj->phys_handle->busaddr; addr = obj->phys_handle->busaddr;
...@@ -16723,7 +16739,6 @@ void intel_modeset_gem_init(struct drm_device *dev) ...@@ -16723,7 +16739,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc *c; struct drm_crtc *c;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret;
intel_init_gt_powersave(dev_priv); intel_init_gt_powersave(dev_priv);
...@@ -16737,15 +16752,17 @@ void intel_modeset_gem_init(struct drm_device *dev) ...@@ -16737,15 +16752,17 @@ void intel_modeset_gem_init(struct drm_device *dev)
* for this. * for this.
*/ */
for_each_crtc(dev, c) { for_each_crtc(dev, c) {
struct i915_vma *vma;
obj = intel_fb_obj(c->primary->fb); obj = intel_fb_obj(c->primary->fb);
if (obj == NULL) if (obj == NULL)
continue; continue;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(c->primary->fb, vma = intel_pin_and_fence_fb_obj(c->primary->fb,
c->primary->state->rotation); c->primary->state->rotation);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
if (ret) { if (IS_ERR(vma)) {
DRM_ERROR("failed to pin boot fb on pipe %d\n", DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe); to_intel_crtc(c)->pipe);
drm_framebuffer_unreference(c->primary->fb); drm_framebuffer_unreference(c->primary->fb);
......
...@@ -193,6 +193,7 @@ struct intel_framebuffer { ...@@ -193,6 +193,7 @@ struct intel_framebuffer {
struct intel_fbdev { struct intel_fbdev {
struct drm_fb_helper helper; struct drm_fb_helper helper;
struct intel_framebuffer *fb; struct intel_framebuffer *fb;
struct i915_vma *vma;
async_cookie_t cookie; async_cookie_t cookie;
int preferred_bpp; int preferred_bpp;
}; };
...@@ -1239,8 +1240,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -1239,8 +1240,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
void intel_release_load_detect_pipe(struct drm_connector *connector, void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old, struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx); struct drm_modeset_acquire_ctx *ctx);
int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, struct i915_vma *
unsigned int rotation); intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation);
void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation); void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation);
struct drm_framebuffer * struct drm_framebuffer *
__intel_framebuffer_create(struct drm_device *dev, __intel_framebuffer_create(struct drm_device *dev,
......
...@@ -737,7 +737,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, ...@@ -737,7 +737,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
/* FIXME: We lack the proper locking here, so only run this on the /* FIXME: We lack the proper locking here, so only run this on the
* platforms that need. */ * platforms that need. */
if (IS_GEN(dev_priv, 5, 6)) if (IS_GEN(dev_priv, 5, 6))
cache->fb.ilk_ggtt_offset = i915_gem_obj_ggtt_offset(obj); cache->fb.ilk_ggtt_offset = i915_gem_object_ggtt_offset(obj, NULL);
cache->fb.pixel_format = fb->pixel_format; cache->fb.pixel_format = fb->pixel_format;
cache->fb.stride = fb->pitches[0]; cache->fb.stride = fb->pitches[0];
cache->fb.fence_reg = obj->fence_reg; cache->fb.fence_reg = obj->fence_reg;
......
...@@ -187,7 +187,6 @@ static int intelfb_create(struct drm_fb_helper *helper, ...@@ -187,7 +187,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct fb_info *info; struct fb_info *info;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
struct i915_vma *vma; struct i915_vma *vma;
struct drm_i915_gem_object *obj;
bool prealloc = false; bool prealloc = false;
void __iomem *vaddr; void __iomem *vaddr;
int ret; int ret;
...@@ -215,17 +214,17 @@ static int intelfb_create(struct drm_fb_helper *helper, ...@@ -215,17 +214,17 @@ static int intelfb_create(struct drm_fb_helper *helper,
sizes->fb_height = intel_fb->base.height; sizes->fb_height = intel_fb->base.height;
} }
obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/* Pin the GGTT vma for our access via info->screen_base. /* Pin the GGTT vma for our access via info->screen_base.
* This also validates that any existing fb inherited from the * This also validates that any existing fb inherited from the
* BIOS is suitable for own access. * BIOS is suitable for own access.
*/ */
ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0); vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
if (ret) if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto out_unlock; goto out_unlock;
}
info = drm_fb_helper_alloc_fbi(helper); info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) { if (IS_ERR(info)) {
...@@ -245,8 +244,6 @@ static int intelfb_create(struct drm_fb_helper *helper, ...@@ -245,8 +244,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &intelfb_ops; info->fbops = &intelfb_ops;
vma = i915_gem_obj_to_ggtt(obj);
/* setup aperture base/size for vesafb takeover */ /* setup aperture base/size for vesafb takeover */
info->apertures->ranges[0].base = dev->mode_config.fb_base; info->apertures->ranges[0].base = dev->mode_config.fb_base;
info->apertures->ranges[0].size = ggtt->mappable_end; info->apertures->ranges[0].size = ggtt->mappable_end;
...@@ -273,14 +270,14 @@ static int intelfb_create(struct drm_fb_helper *helper, ...@@ -273,14 +270,14 @@ static int intelfb_create(struct drm_fb_helper *helper,
* If the object is stolen however, it will be full of whatever * If the object is stolen however, it will be full of whatever
* garbage was left in there. * garbage was left in there.
*/ */
if (ifbdev->fb->obj->stolen && !prealloc) if (intel_fb->obj->stolen && !prealloc)
memset_io(info->screen_base, 0, info->screen_size); memset_io(info->screen_base, 0, info->screen_size);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n", DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx\n",
fb->width, fb->height, fb->width, fb->height, vma->node.start);
i915_gem_obj_ggtt_offset(obj), obj); ifbdev->vma = vma;
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
vga_switcheroo_client_fb_set(dev->pdev, info); vga_switcheroo_client_fb_set(dev->pdev, info);
......
...@@ -249,12 +249,12 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv, ...@@ -249,12 +249,12 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
* Note that GuC needs the CSS header plus uKernel code to be copied by the * Note that GuC needs the CSS header plus uKernel code to be copied by the
* DMA engine in one operation, whereas the RSA signature is loaded via MMIO. * DMA engine in one operation, whereas the RSA signature is loaded via MMIO.
*/ */
static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv) static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
struct i915_vma *vma)
{ {
struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
struct drm_i915_gem_object *fw_obj = guc_fw->guc_fw_obj;
unsigned long offset; unsigned long offset;
struct sg_table *sg = fw_obj->pages; struct sg_table *sg = vma->pages;
u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT]; u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
int i, ret = 0; int i, ret = 0;
...@@ -271,7 +271,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv) ...@@ -271,7 +271,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size); I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size);
/* Set the source address for the new blob */ /* Set the source address for the new blob */
offset = i915_gem_obj_ggtt_offset(fw_obj) + guc_fw->header_offset; offset = vma->node.start + guc_fw->header_offset;
I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset)); I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF); I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
...@@ -326,6 +326,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) ...@@ -326,6 +326,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
{ {
struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw; struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct i915_vma *vma;
int ret; int ret;
ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false); ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
...@@ -334,10 +335,10 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) ...@@ -334,10 +335,10 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
return ret; return ret;
} }
ret = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0); vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
if (ret) { if (IS_ERR(vma)) {
DRM_DEBUG_DRIVER("pin failed %d\n", ret); DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
return ret; return PTR_ERR(vma);
} }
/* Invalidate GuC TLB to let GuC take the latest updates to GTT. */ /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
...@@ -380,7 +381,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) ...@@ -380,7 +381,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
set_guc_init_params(dev_priv); set_guc_init_params(dev_priv);
ret = guc_ucode_xfer_dma(dev_priv); ret = guc_ucode_xfer_dma(dev_priv, vma);
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
...@@ -388,7 +389,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv) ...@@ -388,7 +389,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
* We keep the object pages for reuse during resume. But we can unpin it * We keep the object pages for reuse during resume. But we can unpin it
* now that DMA has completed, so it doesn't continue to take up space. * now that DMA has completed, so it doesn't continue to take up space.
*/ */
i915_gem_object_ggtt_unpin(guc_fw->guc_fw_obj); i915_vma_unpin(vma);
return ret; return ret;
} }
......
...@@ -326,7 +326,7 @@ static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active, ...@@ -326,7 +326,7 @@ static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
i915_gem_track_fb(vma->obj, NULL, i915_gem_track_fb(vma->obj, NULL,
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
i915_gem_object_unpin_from_display_plane(vma->obj, &i915_ggtt_view_normal); i915_gem_object_unpin_from_display_plane(vma);
i915_vma_put(vma); i915_vma_put(vma);
} }
...@@ -342,7 +342,7 @@ static void intel_overlay_off_tail(struct i915_gem_active *active, ...@@ -342,7 +342,7 @@ static void intel_overlay_off_tail(struct i915_gem_active *active,
if (WARN_ON(!vma)) if (WARN_ON(!vma))
return; return;
i915_gem_object_unpin_from_display_plane(vma->obj, &i915_ggtt_view_normal); i915_gem_object_unpin_from_display_plane(vma);
i915_vma_put(vma); i915_vma_put(vma);
overlay->crtc->overlay = NULL; overlay->crtc->overlay = NULL;
...@@ -755,12 +755,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, ...@@ -755,12 +755,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret != 0) if (ret != 0)
return ret; return ret;
ret = i915_gem_object_pin_to_display_plane(new_bo, 0, vma = i915_gem_object_pin_to_display_plane(new_bo, 0,
&i915_ggtt_view_normal); &i915_ggtt_view_normal);
if (ret != 0) if (IS_ERR(vma))
return ret; return PTR_ERR(vma);
vma = i915_gem_obj_to_ggtt_view(new_bo, &i915_ggtt_view_normal);
ret = i915_gem_object_put_fence(new_bo); ret = i915_gem_object_put_fence(new_bo);
if (ret) if (ret)
...@@ -803,7 +801,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, ...@@ -803,7 +801,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
swidth = params->src_w; swidth = params->src_w;
swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width); swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
sheight = params->src_h; sheight = params->src_h;
iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_Y, &regs->OBUF_0Y); iowrite32(vma->node.start + params->offset_Y, &regs->OBUF_0Y);
ostride = params->stride_Y; ostride = params->stride_Y;
if (params->format & I915_OVERLAY_YUV_PLANAR) { if (params->format & I915_OVERLAY_YUV_PLANAR) {
...@@ -817,8 +815,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, ...@@ -817,8 +815,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
params->src_w/uv_hscale); params->src_w/uv_hscale);
swidthsw |= max_t(u32, tmp_U, tmp_V) << 16; swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
sheight |= (params->src_h/uv_vscale) << 16; sheight |= (params->src_h/uv_vscale) << 16;
iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_U, &regs->OBUF_0U); iowrite32(vma->node.start + params->offset_U, &regs->OBUF_0U);
iowrite32(i915_gem_obj_ggtt_offset(new_bo) + params->offset_V, &regs->OBUF_0V); iowrite32(vma->node.start + params->offset_V, &regs->OBUF_0V);
ostride |= params->stride_UV << 16; ostride |= params->stride_UV << 16;
} }
...@@ -850,7 +848,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, ...@@ -850,7 +848,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
return 0; return 0;
out_unpin: out_unpin:
i915_gem_object_ggtt_unpin(new_bo); i915_gem_object_unpin_from_display_plane(vma);
return ret; return ret;
} }
...@@ -1373,6 +1371,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) ...@@ -1373,6 +1371,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
struct intel_overlay *overlay; struct intel_overlay *overlay;
struct drm_i915_gem_object *reg_bo; struct drm_i915_gem_object *reg_bo;
struct overlay_registers __iomem *regs; struct overlay_registers __iomem *regs;
struct i915_vma *vma = NULL;
int ret; int ret;
if (!HAS_OVERLAY(dev_priv)) if (!HAS_OVERLAY(dev_priv))
...@@ -1406,13 +1405,14 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) ...@@ -1406,13 +1405,14 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
} }
overlay->flip_addr = reg_bo->phys_handle->busaddr; overlay->flip_addr = reg_bo->phys_handle->busaddr;
} else { } else {
ret = i915_gem_object_ggtt_pin(reg_bo, NULL, vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
0, PAGE_SIZE, PIN_MAPPABLE); 0, PAGE_SIZE, PIN_MAPPABLE);
if (ret) { if (IS_ERR(vma)) {
DRM_ERROR("failed to pin overlay register bo\n"); DRM_ERROR("failed to pin overlay register bo\n");
ret = PTR_ERR(vma);
goto out_free_bo; goto out_free_bo;
} }
overlay->flip_addr = i915_gem_obj_ggtt_offset(reg_bo); overlay->flip_addr = vma->node.start;
ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
if (ret) { if (ret) {
...@@ -1444,8 +1444,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv) ...@@ -1444,8 +1444,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
return; return;
out_unpin_bo: out_unpin_bo:
if (!OVERLAY_NEEDS_PHYSICAL(dev_priv)) if (vma)
i915_gem_object_ggtt_unpin(reg_bo); i915_vma_unpin(vma);
out_free_bo: out_free_bo:
i915_gem_object_put(reg_bo); i915_gem_object_put(reg_bo);
out_free: out_free:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment