Merge tag 'drm-misc-next-2018-12-06' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
Final changes to drm-misc-next for v4.21: UAPI Changes: Core Changes: - Add dma_fence_get_stub to dma-buf, and use it in drm/syncobj. - Add and use DRM_MODESET_LOCK_BEGIN/END helpers. - Small fixes to drm_atomic_helper_resume(), drm_mode_setcrtc() and drm_atomic_helper_commit_duplicated_state() - Fix drm_atomic_state_helper.[c] extraction. Driver Changes: - Small fixes to tinydrm, vkms, meson, rcar-du, virtio, vkms, v3d, and pl111. - vc4: Allow scaling and YUV formats on cursor planes. - v3d: Enable use of the Texture Formatting Unit, and fix prime imports of buffers from other drivers. - Add support for the AUO G101EVN010 panel. - sun4i: Enable support for the H6 display engine. Signed-off-by: Dave Airlie <airlied@redhat.com> [airlied: added drm/v3d: fix broken build to the merge commit] From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/321be9d3-ab75-5f92-8193-e5113662edef@linux.intel.com
This commit is contained in:
@@ -207,26 +207,26 @@ v3d_flush_caches(struct v3d_dev *v3d)
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_attach_object_fences(struct v3d_exec_info *exec)
|
||||
v3d_attach_object_fences(struct v3d_bo **bos, int bo_count,
|
||||
struct dma_fence *fence)
|
||||
{
|
||||
struct dma_fence *out_fence = exec->render_done_fence;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < exec->bo_count; i++) {
|
||||
for (i = 0; i < bo_count; i++) {
|
||||
/* XXX: Use shared fences for read-only objects. */
|
||||
reservation_object_add_excl_fence(exec->bo[i]->resv, out_fence);
|
||||
reservation_object_add_excl_fence(bos[i]->resv, fence);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_unlock_bo_reservations(struct drm_device *dev,
|
||||
struct v3d_exec_info *exec,
|
||||
v3d_unlock_bo_reservations(struct v3d_bo **bos,
|
||||
int bo_count,
|
||||
struct ww_acquire_ctx *acquire_ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < exec->bo_count; i++)
|
||||
ww_mutex_unlock(&exec->bo[i]->resv->lock);
|
||||
for (i = 0; i < bo_count; i++)
|
||||
ww_mutex_unlock(&bos[i]->resv->lock);
|
||||
|
||||
ww_acquire_fini(acquire_ctx);
|
||||
}
|
||||
@@ -239,8 +239,8 @@ v3d_unlock_bo_reservations(struct drm_device *dev,
|
||||
* to v3d, so we don't attach dma-buf fences to them.
|
||||
*/
|
||||
static int
|
||||
v3d_lock_bo_reservations(struct drm_device *dev,
|
||||
struct v3d_exec_info *exec,
|
||||
v3d_lock_bo_reservations(struct v3d_bo **bos,
|
||||
int bo_count,
|
||||
struct ww_acquire_ctx *acquire_ctx)
|
||||
{
|
||||
int contended_lock = -1;
|
||||
@@ -250,7 +250,7 @@ v3d_lock_bo_reservations(struct drm_device *dev,
|
||||
|
||||
retry:
|
||||
if (contended_lock != -1) {
|
||||
struct v3d_bo *bo = exec->bo[contended_lock];
|
||||
struct v3d_bo *bo = bos[contended_lock];
|
||||
|
||||
ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
|
||||
acquire_ctx);
|
||||
@@ -260,20 +260,20 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < exec->bo_count; i++) {
|
||||
for (i = 0; i < bo_count; i++) {
|
||||
if (i == contended_lock)
|
||||
continue;
|
||||
|
||||
ret = ww_mutex_lock_interruptible(&exec->bo[i]->resv->lock,
|
||||
ret = ww_mutex_lock_interruptible(&bos[i]->resv->lock,
|
||||
acquire_ctx);
|
||||
if (ret) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
ww_mutex_unlock(&exec->bo[j]->resv->lock);
|
||||
ww_mutex_unlock(&bos[j]->resv->lock);
|
||||
|
||||
if (contended_lock != -1 && contended_lock >= i) {
|
||||
struct v3d_bo *bo = exec->bo[contended_lock];
|
||||
struct v3d_bo *bo = bos[contended_lock];
|
||||
|
||||
ww_mutex_unlock(&bo->resv->lock);
|
||||
}
|
||||
@@ -293,10 +293,11 @@ retry:
|
||||
/* Reserve space for our shared (read-only) fence references,
|
||||
* before we commit the CL to the hardware.
|
||||
*/
|
||||
for (i = 0; i < exec->bo_count; i++) {
|
||||
ret = reservation_object_reserve_shared(exec->bo[i]->resv, 1);
|
||||
for (i = 0; i < bo_count; i++) {
|
||||
ret = reservation_object_reserve_shared(bos[i]->resv, 1);
|
||||
if (ret) {
|
||||
v3d_unlock_bo_reservations(dev, exec, acquire_ctx);
|
||||
v3d_unlock_bo_reservations(bos, bo_count,
|
||||
acquire_ctx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -419,6 +420,33 @@ void v3d_exec_put(struct v3d_exec_info *exec)
|
||||
kref_put(&exec->refcount, v3d_exec_cleanup);
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_tfu_job_cleanup(struct kref *ref)
|
||||
{
|
||||
struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job,
|
||||
refcount);
|
||||
struct v3d_dev *v3d = job->v3d;
|
||||
unsigned int i;
|
||||
|
||||
dma_fence_put(job->in_fence);
|
||||
dma_fence_put(job->done_fence);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(job->bo); i++) {
|
||||
if (job->bo[i])
|
||||
drm_gem_object_put_unlocked(&job->bo[i]->base);
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(v3d->dev);
|
||||
pm_runtime_put_autosuspend(v3d->dev);
|
||||
|
||||
kfree(job);
|
||||
}
|
||||
|
||||
void v3d_tfu_job_put(struct v3d_tfu_job *job)
|
||||
{
|
||||
kref_put(&job->refcount, v3d_tfu_job_cleanup);
|
||||
}
|
||||
|
||||
int
|
||||
v3d_wait_bo_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
@@ -493,6 +521,8 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_syncobj *sync_out;
|
||||
int ret = 0;
|
||||
|
||||
trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
|
||||
|
||||
if (args->pad != 0) {
|
||||
DRM_INFO("pad must be zero: %d\n", args->pad);
|
||||
return -EINVAL;
|
||||
@@ -536,7 +566,8 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = v3d_lock_bo_reservations(dev, exec, &acquire_ctx);
|
||||
ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count,
|
||||
&acquire_ctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
@@ -570,15 +601,15 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
&v3d_priv->sched_entity[V3D_RENDER]);
|
||||
mutex_unlock(&v3d->sched_lock);
|
||||
|
||||
v3d_attach_object_fences(exec);
|
||||
v3d_attach_object_fences(exec->bo, exec->bo_count,
|
||||
exec->render_done_fence);
|
||||
|
||||
v3d_unlock_bo_reservations(dev, exec, &acquire_ctx);
|
||||
v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
|
||||
|
||||
/* Update the return sync object for the */
|
||||
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
||||
if (sync_out) {
|
||||
drm_syncobj_replace_fence(sync_out, 0,
|
||||
exec->render_done_fence);
|
||||
drm_syncobj_replace_fence(sync_out, exec->render_done_fence);
|
||||
drm_syncobj_put(sync_out);
|
||||
}
|
||||
|
||||
@@ -588,13 +619,121 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
fail_unreserve:
|
||||
mutex_unlock(&v3d->sched_lock);
|
||||
v3d_unlock_bo_reservations(dev, exec, &acquire_ctx);
|
||||
v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
|
||||
fail:
|
||||
v3d_exec_put(exec);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* v3d_submit_tfu_ioctl() - Submits a TFU (texture formatting) job to the V3D.
|
||||
* @dev: DRM device
|
||||
* @data: ioctl argument
|
||||
* @file_priv: DRM file for this fd
|
||||
*
|
||||
* Userspace provides the register setup for the TFU, which we don't
|
||||
* need to validate since the TFU is behind the MMU.
|
||||
*/
|
||||
int
|
||||
v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct v3d_dev *v3d = to_v3d_dev(dev);
|
||||
struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
|
||||
struct drm_v3d_submit_tfu *args = data;
|
||||
struct v3d_tfu_job *job;
|
||||
struct ww_acquire_ctx acquire_ctx;
|
||||
struct drm_syncobj *sync_out;
|
||||
struct dma_fence *sched_done_fence;
|
||||
int ret = 0;
|
||||
int bo_count;
|
||||
|
||||
trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);
|
||||
|
||||
job = kcalloc(1, sizeof(*job), GFP_KERNEL);
|
||||
if (!job)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pm_runtime_get_sync(v3d->dev);
|
||||
if (ret < 0) {
|
||||
kfree(job);
|
||||
return ret;
|
||||
}
|
||||
|
||||
kref_init(&job->refcount);
|
||||
|
||||
ret = drm_syncobj_find_fence(file_priv, args->in_sync,
|
||||
0, 0, &job->in_fence);
|
||||
if (ret == -EINVAL)
|
||||
goto fail;
|
||||
|
||||
job->args = *args;
|
||||
job->v3d = v3d;
|
||||
|
||||
spin_lock(&file_priv->table_lock);
|
||||
for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) {
|
||||
struct drm_gem_object *bo;
|
||||
|
||||
if (!args->bo_handles[bo_count])
|
||||
break;
|
||||
|
||||
bo = idr_find(&file_priv->object_idr,
|
||||
args->bo_handles[bo_count]);
|
||||
if (!bo) {
|
||||
DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
|
||||
bo_count, args->bo_handles[bo_count]);
|
||||
ret = -ENOENT;
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
goto fail;
|
||||
}
|
||||
drm_gem_object_get(bo);
|
||||
job->bo[bo_count] = to_v3d_bo(bo);
|
||||
}
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
|
||||
ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
mutex_lock(&v3d->sched_lock);
|
||||
ret = drm_sched_job_init(&job->base,
|
||||
&v3d_priv->sched_entity[V3D_TFU],
|
||||
v3d_priv);
|
||||
if (ret)
|
||||
goto fail_unreserve;
|
||||
|
||||
sched_done_fence = dma_fence_get(&job->base.s_fence->finished);
|
||||
|
||||
kref_get(&job->refcount); /* put by scheduler job completion */
|
||||
drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]);
|
||||
mutex_unlock(&v3d->sched_lock);
|
||||
|
||||
v3d_attach_object_fences(job->bo, bo_count, sched_done_fence);
|
||||
|
||||
v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
||||
|
||||
/* Update the return sync object */
|
||||
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
||||
if (sync_out) {
|
||||
drm_syncobj_replace_fence(sync_out, sched_done_fence);
|
||||
drm_syncobj_put(sync_out);
|
||||
}
|
||||
dma_fence_put(sched_done_fence);
|
||||
|
||||
v3d_tfu_job_put(job);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unreserve:
|
||||
mutex_unlock(&v3d->sched_lock);
|
||||
v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
||||
fail:
|
||||
v3d_tfu_job_put(job);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
v3d_gem_init(struct drm_device *dev)
|
||||
{
|
||||
|
Reference in New Issue
Block a user