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)
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)
......
......@@ -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_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,
const struct i915_ggtt_view *view,
u64 size,
......@@ -3279,12 +3279,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj,
bool write);
int __must_check
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,
u32 alignment,
const struct i915_ggtt_view *view);
void i915_gem_object_unpin_from_display_plane(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view);
void i915_gem_object_unpin_from_display_plane(struct i915_vma *vma);
int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj,
int align);
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,
struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
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 *
i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm);
struct i915_vma *
i915_gem_obj_to_ggtt_view(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view);
struct i915_address_space *vm,
const struct i915_ggtt_view *view);
struct i915_vma *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm);
struct i915_vma *
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);
struct i915_address_space *vm,
const struct i915_ggtt_view *view);
/* Some GGTT VM helpers */
static inline struct i915_hw_ppgtt *
i915_vm_to_ppgtt(struct i915_address_space *vm)
{
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
i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj);
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)
static inline unsigned long
i915_gem_object_ggtt_offset(struct drm_i915_gem_object *o,
const struct i915_ggtt_view *view)
{
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 */
......
This diff is collapsed.
......@@ -180,8 +180,8 @@ eb_lookup_vmas(struct eb_vmas *eb,
* from the (obj, vm) we don't run the risk of creating
* duplicated vmas for the same vm.
*/
vma = i915_gem_obj_lookup_or_create_vma(obj, vm);
if (IS_ERR(vma)) {
vma = i915_gem_obj_lookup_or_create_vma(obj, vm, NULL);
if (unlikely(IS_ERR(vma))) {
DRM_DEBUG("Failed to lookup VMA\n");
ret = PTR_ERR(vma);
goto err;
......@@ -349,30 +349,33 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
struct drm_i915_gem_relocation_entry *reloc,
uint64_t target_offset)
{
struct drm_device *dev = obj->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct i915_vma *vma;
uint64_t delta = relocation_target(reloc, target_offset);
uint64_t offset;
void __iomem *reloc_page;
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);
if (ret)
return ret;
goto unpin;
ret = i915_gem_object_put_fence(obj);
if (ret)
return ret;
goto unpin;
/* Map the page containing the relocation we're going to perform. */
offset = i915_gem_obj_ggtt_offset(obj);
offset += reloc->offset;
offset = vma->node.start + reloc->offset;
reloc_page = io_mapping_map_atomic_wc(ggtt->mappable,
offset & PAGE_MASK);
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);
if (offset_in_page(offset) == 0) {
......@@ -388,7 +391,9 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj,
io_mapping_unmap_atomic(reloc_page);
return 0;
unpin:
i915_vma_unpin(vma);
return ret;
}
static void
......@@ -1281,7 +1286,7 @@ i915_reset_gen7_sol_offsets(struct drm_i915_gem_request *req)
return 0;
}
static struct i915_vma*
static struct i915_vma *
i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
struct drm_i915_gem_exec_object2 *shadow_exec_entry,
struct drm_i915_gem_object *batch_obj,
......@@ -1305,31 +1310,28 @@ i915_gem_execbuffer_parse(struct intel_engine_cs *engine,
batch_start_offset,
batch_len,
is_master);
if (ret)
goto err;
ret = i915_gem_object_ggtt_pin(shadow_batch_obj, NULL, 0, 0, 0);
if (ret)
goto err;
if (ret) {
if (ret == -EACCES) /* unhandled chained batch */
vma = NULL;
else
vma = ERR_PTR(ret);
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));
vma = i915_gem_obj_to_ggtt(shadow_batch_obj);
vma->exec_entry = shadow_exec_entry;
vma->exec_entry->flags = __EXEC_OBJECT_HAS_PIN;
i915_gem_object_get(shadow_batch_obj);
list_add_tail(&vma->exec_list, &eb->vmas);
return vma;
err:
out:
i915_gem_object_unpin_pages(shadow_batch_obj);
if (ret == -EACCES) /* unhandled chained batch */
return NULL;
else
return ERR_PTR(ret);
return vma;
}
static int
......@@ -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. */
if (dispatch_flags & I915_DISPATCH_SECURE) {
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
......@@ -1688,11 +1691,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
* fitting due to fragmentation.
* So this is actually safe.
*/
ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
if (ret)
vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err;
}
params->batch = i915_gem_obj_to_ggtt(obj);
params->batch = vma;
}
/* Allocate a request for this batch buffer nice and early. */
......@@ -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
* 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);
if (ret)
......
......@@ -85,7 +85,7 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
POSTING_READ(fence_reg_lo);
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 stride = i915_gem_object_get_stride(obj);
u32 size = vma->node.size;
......@@ -120,7 +120,7 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
u32 val;
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 stride = i915_gem_object_get_stride(obj);
int pitch_val;
......@@ -161,7 +161,7 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
u32 val;
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 stride = i915_gem_object_get_stride(obj);
u32 pitch_val;
......@@ -432,13 +432,7 @@ bool
i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
{
if (obj->fence_reg != I915_FENCE_REG_NONE) {
struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
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++;
to_i915(obj->base.dev)->fence_regs[obj->fence_reg].pin_count++;
return true;
} else
return false;
......
......@@ -3341,23 +3341,19 @@ void i915_vma_close(struct i915_vma *vma)
}
static struct i915_vma *
__i915_gem_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
__i915_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{
struct i915_vma *vma;
int i;
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);
if (vma == NULL)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&vma->obj_link);
INIT_LIST_HEAD(&vma->exec_list);
for (i = 0; i < ARRAY_SIZE(vma->last_read); i++)
init_request_active(&vma->last_read[i], i915_vma_retire);
......@@ -3366,8 +3362,7 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
vma->obj = obj;
vma->size = obj->base.size;
if (i915_is_ggtt(vm)) {
vma->flags |= I915_VMA_GGTT;
if (view) {
vma->ggtt_view = *view;
if (view->type == I915_GGTT_VIEW_PARTIAL) {
vma->size = view->params.partial.size;
......@@ -3377,57 +3372,79 @@ __i915_gem_vma_create(struct drm_i915_gem_object *obj,
intel_rotation_info_size(&view->params.rotated);
vma->size <<= PAGE_SHIFT;
}
}
if (i915_is_ggtt(vm)) {
vma->flags |= I915_VMA_GGTT;
} else {
i915_ppgtt_get(i915_vm_to_ppgtt(vm));
}
list_add_tail(&vma->obj_link, &obj->vma_list);
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 *
i915_vma_create(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{
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 *
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm)
i915_gem_obj_to_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{
struct i915_vma *vma;
vma = i915_gem_obj_to_vma(obj, vm);
if (!vma)
vma = __i915_gem_vma_create(obj, vm,
i915_is_ggtt(vm) ? &i915_ggtt_view_normal : NULL);
list_for_each_entry_reverse(vma, &obj->vma_list, obj_link)
if (vma_matches(vma, vm, view))
return vma;
return vma;
return NULL;
}
struct i915_vma *
i915_gem_obj_lookup_or_create_ggtt_vma(struct drm_i915_gem_object *obj,
const struct i915_ggtt_view *view)
i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
struct i915_address_space *vm,
const struct i915_ggtt_view *view)
{
struct drm_device *dev = obj->base.dev;
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);
struct i915_vma *vma;
GEM_BUG_ON(!view);
GEM_BUG_ON(view && !i915_is_ggtt(vm));
vma = i915_gem_obj_to_vma(obj, vm, view);
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));
return vma;
}
static struct scatterlist *
......
......@@ -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);
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. */
#define PIN_NONBLOCK BIT(0)
#define PIN_MAPPABLE BIT(1)
......
......@@ -406,7 +406,7 @@ i915_gem_request_alloc(struct intel_engine_cs *engine,
/* No zalloc, must clear what we need by hand */
req->previous_context = NULL;
req->file_priv = NULL;
req->batch_obj = NULL;
req->batch = NULL;
req->pid = NULL;
req->elsp_submitted = 0;
......
......@@ -118,7 +118,7 @@ struct drm_i915_gem_request {
/** Batch buffer related to this request if any (used for
* error state dump only).
*/
struct drm_i915_gem_object *batch_obj;
struct i915_vma *batch;
struct list_head active_list;
/** Time at which this request was emitted, in jiffies. */
......
......@@ -696,7 +696,7 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
if (gtt_offset == I915_GTT_OFFSET_NONE)
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)) {
ret = PTR_ERR(vma);
goto err;
......
......@@ -130,7 +130,7 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, int tiling_mode)
if (INTEL_GEN(dev_priv) >= 4)
return 0;
vma = i915_gem_obj_to_ggtt(obj);
vma = i915_gem_object_to_ggtt(obj, NULL);
if (!vma)
return 0;
......
......@@ -653,46 +653,42 @@ static void i915_error_state_free(struct kref *error_ref)
static struct drm_i915_error_object *
i915_error_object_create(struct drm_i915_private *dev_priv,
struct drm_i915_gem_object *src,
struct i915_address_space *vm)
struct i915_vma *vma)
{
struct i915_ggtt *ggtt = &dev_priv->ggtt;
struct drm_i915_gem_object *src;
struct drm_i915_error_object *dst;
struct i915_vma *vma = NULL;
int num_pages;
bool use_ggtt;
int i = 0;
u64 reloc_offset;
if (src == NULL || src->pages == NULL)
if (!vma)
return NULL;
src = vma->obj;
if (!src->pages)
return NULL;
num_pages = src->base.size >> PAGE_SHIFT;
dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), GFP_ATOMIC);
if (dst == NULL)
if (!dst)
return NULL;
if (i915_gem_obj_bound(src, vm))
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);
reloc_offset = dst->gtt_offset = vma->node.start;
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);
/* Cannot access stolen address directly, try to use the aperture */
if (src->stolen) {
use_ggtt = true;
if (!(vma && vma->flags & I915_VMA_GLOBAL_BIND))
if (!(vma->flags & I915_VMA_GLOBAL_BIND))
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)
goto unwind;
}
......@@ -752,8 +748,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv,
kfree(dst);
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
* 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,
int i, count;
error->semaphore =
i915_error_ggtt_object_create(dev_priv,
dev_priv->semaphore->obj);
i915_error_object_create(dev_priv, dev_priv->semaphore);
for (i = 0; i < I915_NUM_ENGINES; 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,
*/
ee->batchbuffer =
i915_error_object_create(dev_priv,
request->batch_obj,
ee->vm);
request->batch);
if (HAS_BROKEN_CS_TLB(dev_priv))
ee->wa_batchbuffer =
i915_error_ggtt_object_create(dev_priv,
engine->scratch->obj);
i915_error_object_create(dev_priv,
engine->scratch);
if (request->ctx->engine[i].state) {
ee->ctx = i915_error_ggtt_object_create(dev_priv,
request->ctx->engine[i].state->obj);
}
ee->ctx =
i915_error_object_create(dev_priv,
request->ctx->engine[i].state);
if (request->pid) {
struct task_struct *task;
......@@ -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_tail = ring->tail;
ee->ringbuffer =
i915_error_ggtt_object_create(dev_priv,
ring->vma->obj);
i915_error_object_create(dev_priv, ring->vma);
}
ee->hws_page =
i915_error_ggtt_object_create(dev_priv,
engine->status_page.vma->obj);
i915_error_object_create(dev_priv,
engine->status_page.vma);
ee->wa_ctx = i915_error_ggtt_object_create(dev_priv,
engine->wa_ctx.vma->obj);
ee->wa_ctx =
i915_error_object_create(dev_priv, engine->wa_ctx.vma);
count = 0;
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
}
}
int
intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
unsigned int rotation)
struct i915_vma *
intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
{
struct drm_device *dev = fb->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view;
struct i915_vma *vma;
u32 alignment;
int ret;
......@@ -2213,10 +2213,11 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
*/
intel_runtime_pm_get(dev_priv);
ret = i915_gem_object_pin_to_display_plane(obj, alignment,
&view);
if (ret)
vma = i915_gem_object_pin_to_display_plane(obj, alignment, &view);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto err_pm;
}
/* Install a fence for tiled scan-out. Pre-i965 always needs a
* fence, whereas 965+ only requires a fence if using
......@@ -2243,19 +2244,20 @@ intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
}
intel_runtime_pm_put(dev_priv);
return 0;
return vma;
err_unpin:
i915_gem_object_unpin_from_display_plane(obj, &view);
i915_gem_object_unpin_from_display_plane(vma);
err_pm:
intel_runtime_pm_put(dev_priv);
return ret;
return ERR_PTR(ret);
}
void intel_unpin_fb_obj(struct drm_framebuffer *fb, unsigned int rotation)
{
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view;
struct i915_vma *vma;
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)
if (view.type == I915_GGTT_VIEW_NORMAL)
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,
......@@ -2796,7 +2799,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
continue;
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);
goto valid_fb;
}
......@@ -3115,7 +3118,7 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
I915_WRITE(DSPTILEOFF(plane), (y << 16) | x);
I915_WRITE(DSPLINOFF(plane), linear_offset);
} 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);
}
......@@ -3237,11 +3240,17 @@ u32 intel_fb_gtt_offset(struct drm_framebuffer *fb,
{
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_ggtt_view view;
struct i915_vma *vma;
u64 offset;
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));
......@@ -12032,6 +12041,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct intel_engine_cs *engine;
bool mmio_flip;
struct drm_i915_gem_request *request;
struct i915_vma *vma;
int ret;
/*
......@@ -12139,9 +12149,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
mmio_flip = use_mmio_flip(engine, obj);
ret = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
if (ret)
vma = intel_pin_and_fence_fb_obj(fb, primary->state->rotation);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto cleanup_pending;
}
work->gtt_offset = intel_fb_gtt_offset(fb, primary->state->rotation);
work->gtt_offset += intel_crtc->dspaddr_offset;
......@@ -14484,7 +14496,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
if (ret)
DRM_DEBUG_KMS("failed to attach phys object\n");
} 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) {
......@@ -14850,7 +14866,7 @@ intel_update_cursor_plane(struct drm_plane *plane,
if (!obj)
addr = 0;
else if (!INTEL_INFO(dev)->cursor_needs_physical)
addr = i915_gem_obj_ggtt_offset(obj);
addr = i915_gem_object_ggtt_offset(obj, NULL);
else
addr = obj->phys_handle->busaddr;
......@@ -16723,7 +16739,6 @@ void intel_modeset_gem_init(struct drm_device *dev)
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_crtc *c;
struct drm_i915_gem_object *obj;
int ret;
intel_init_gt_powersave(dev_priv);
......@@ -16737,15 +16752,17 @@ void intel_modeset_gem_init(struct drm_device *dev)
* for this.
*/
for_each_crtc(dev, c) {
struct i915_vma *vma;
obj = intel_fb_obj(c->primary->fb);
if (obj == NULL)
continue;
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);
mutex_unlock(&dev->struct_mutex);
if (ret) {
if (IS_ERR(vma)) {
DRM_ERROR("failed to pin boot fb on pipe %d\n",
to_intel_crtc(c)->pipe);
drm_framebuffer_unreference(c->primary->fb);
......
......@@ -193,6 +193,7 @@ struct intel_framebuffer {
struct intel_fbdev {
struct drm_fb_helper helper;
struct intel_framebuffer *fb;
struct i915_vma *vma;
async_cookie_t cookie;
int preferred_bpp;
};
......@@ -1239,8 +1240,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector,
void intel_release_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx);
int intel_pin_and_fence_fb_obj(struct drm_framebuffer *fb,
unsigned int rotation);
struct i915_vma *
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);
struct drm_framebuffer *
__intel_framebuffer_create(struct drm_device *dev,
......
......@@ -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
* platforms that need. */
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.stride = fb->pitches[0];
cache->fb.fence_reg = obj->fence_reg;
......
......@@ -187,7 +187,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct fb_info *info;
struct drm_framebuffer *fb;
struct i915_vma *vma;
struct drm_i915_gem_object *obj;
bool prealloc = false;
void __iomem *vaddr;
int ret;
......@@ -215,17 +214,17 @@ static int intelfb_create(struct drm_fb_helper *helper,
sizes->fb_height = intel_fb->base.height;
}
obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex);
/* Pin the GGTT vma for our access via info->screen_base.
* This also validates that any existing fb inherited from the
* BIOS is suitable for own access.
*/
ret = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
if (ret)
vma = intel_pin_and_fence_fb_obj(&ifbdev->fb->base, DRM_ROTATE_0);
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
goto out_unlock;
}
info = drm_fb_helper_alloc_fbi(helper);
if (IS_ERR(info)) {
......@@ -245,8 +244,6 @@ static int intelfb_create(struct drm_fb_helper *helper,
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &intelfb_ops;
vma = i915_gem_obj_to_ggtt(obj);
/* setup aperture base/size for vesafb takeover */
info->apertures->ranges[0].base = dev->mode_config.fb_base;
info->apertures->ranges[0].size = ggtt->mappable_end;
......@@ -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
* 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);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
fb->width, fb->height,
i915_gem_obj_ggtt_offset(obj), obj);
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx\n",
fb->width, fb->height, vma->node.start);
ifbdev->vma = vma;
mutex_unlock(&dev->struct_mutex);
vga_switcheroo_client_fb_set(dev->pdev, info);
......
......@@ -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
* 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 drm_i915_gem_object *fw_obj = guc_fw->guc_fw_obj;
unsigned long offset;
struct sg_table *sg = fw_obj->pages;
struct sg_table *sg = vma->pages;
u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
int i, ret = 0;
......@@ -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);
/* 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_HIGH, upper_32_bits(offset) & 0xFFFF);
......@@ -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 drm_device *dev = &dev_priv->drm;
struct i915_vma *vma;
int ret;
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)
return ret;
}
ret = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
if (ret) {
DRM_DEBUG_DRIVER("pin failed %d\n", ret);
return ret;
vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
if (IS_ERR(vma)) {
DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
return PTR_ERR(vma);
}
/* 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)
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);
......@@ -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
* 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;
}
......
......@@ -326,7 +326,7 @@ static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
i915_gem_track_fb(vma->obj, NULL,
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);
}
......@@ -342,7 +342,7 @@ static void intel_overlay_off_tail(struct i915_gem_active *active,
if (WARN_ON(!vma))
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);
overlay->crtc->overlay = NULL;
......@@ -755,12 +755,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret != 0)
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);
if (ret != 0)
return ret;
vma = i915_gem_obj_to_ggtt_view(new_bo, &i915_ggtt_view_normal);
if (IS_ERR(vma))
return PTR_ERR(vma);
ret = i915_gem_object_put_fence(new_bo);
if (ret)
......@@ -803,7 +801,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
swidth = params->src_w;
swidthsw = calc_swidthsw(dev_priv, params->offset_Y, tmp_width);
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;
if (params->format & I915_OVERLAY_YUV_PLANAR) {
......@@ -817,8 +815,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
params->src_w/uv_hscale);
swidthsw |= max_t(u32, tmp_U, tmp_V) << 16;
sheight |= (params->src_h/uv_vscale) << 16;
iowrite32(i915_gem_obj_ggtt_offset(new_bo) + 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_U, &regs->OBUF_0U);
iowrite32(vma->node.start + params->offset_V, &regs->OBUF_0V);
ostride |= params->stride_UV << 16;
}
......@@ -850,7 +848,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
return 0;
out_unpin:
i915_gem_object_ggtt_unpin(new_bo);
i915_gem_object_unpin_from_display_plane(vma);
return ret;
}
......@@ -1373,6 +1371,7 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
struct intel_overlay *overlay;
struct drm_i915_gem_object *reg_bo;
struct overlay_registers __iomem *regs;
struct i915_vma *vma = NULL;
int ret;
if (!HAS_OVERLAY(dev_priv))
......@@ -1406,13 +1405,14 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
}
overlay->flip_addr = reg_bo->phys_handle->busaddr;
} else {
ret = i915_gem_object_ggtt_pin(reg_bo, NULL,
vma = i915_gem_object_ggtt_pin(reg_bo, NULL,
0, PAGE_SIZE, PIN_MAPPABLE);
if (ret) {
if (IS_ERR(vma)) {
DRM_ERROR("failed to pin overlay register bo\n");
ret = PTR_ERR(vma);
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);
if (ret) {
......@@ -1444,8 +1444,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
return;
out_unpin_bo:
if (!OVERLAY_NEEDS_PHYSICAL(dev_priv))
i915_gem_object_ggtt_unpin(reg_bo);
if (vma)
i915_vma_unpin(vma);
out_free_bo:
i915_gem_object_put(reg_bo);
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