Message ID | 20180228191906.185417-12-seanpaul@chromium.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 2018-02-28 11:19, Sean Paul wrote: > These are already provided by drm atomic core. > > In conjunction with the output fences removed earlier, this obsoletes > dpu_fence, and it can be entirely removed as well. > > Change-Id: Ida4924a09c455d7a84bfee569bd0d2fb436418de > Signed-off-by: Sean Paul <seanpaul@chromium.org> Reviewed-by: Jeykumar Sankaran <jsanka@codeaurora.org> > --- > drivers/gpu/drm/msm/Makefile | 1 - > drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 84 ----- > drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c | 404 ---------------------- > drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h | 190 ---------- > drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ------ > drivers/gpu/drm/msm/msm_drv.h | 4 +- > 6 files changed, 1 insertion(+), 786 deletions(-) > delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c > delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h > > diff --git a/drivers/gpu/drm/msm/Makefile > b/drivers/gpu/drm/msm/Makefile > index 2fb9ba11df19..b47ef5267e19 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -55,7 +55,6 @@ msm-y := \ > disp/dpu1/dpu_encoder.o \ > disp/dpu1/dpu_encoder_phys_cmd.o \ > disp/dpu1/dpu_encoder_phys_vid.o \ > - disp/dpu1/dpu_fence.o \ > disp/dpu1/dpu_formats.o \ > disp/dpu1/dpu_hw_ad4.o \ > disp/dpu1/dpu_hw_blk.o \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > index 2d44989ade7a..8dd986e476bd 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c > @@ -64,16 +64,6 @@ static struct dpu_crtc_custom_events custom_events[] > = > { > {DRM_EVENT_IDLE_NOTIFY, dpu_crtc_idle_interrupt_handler} > }; > > -/* default input fence timeout, in ms */ > -#define DPU_CRTC_INPUT_FENCE_TIMEOUT 10000 > - > -/* > - * The default input fence timeout is 2 seconds while max allowed > - * range is 10 seconds. Any value above 10 seconds adds glitches > beyond > - * tolerance limit. > - */ > -#define DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT 10000 > - > /* layer mixer index on dpu_crtc */ > #define LEFT_MIXER 0 > #define RIGHT_MIXER 1 > @@ -1946,21 +1936,6 @@ static void _dpu_crtc_set_idle_timeout(struct > drm_crtc *crtc, u64 val) > } > } > > -/** > - * _dpu_crtc_set_input_fence_timeout - update ns version of in fence > timeout > - * @cstate: Pointer to dpu crtc state > - */ > -static void _dpu_crtc_set_input_fence_timeout(struct dpu_crtc_state > *cstate) > -{ > - if (!cstate) { > - DPU_ERROR("invalid cstate\n"); > - return; > - } > - cstate->input_fence_timeout_ns = > - dpu_crtc_get_property(cstate, > CRTC_PROP_INPUT_FENCE_TIMEOUT); > - cstate->input_fence_timeout_ns *= NSEC_PER_MSEC; > -} > - > /** > * _dpu_crtc_set_dim_layer_v1 - copy dim layer settings from userspace > * @cstate: Pointer to dpu crtc state > @@ -2385,53 +2360,6 @@ static int > _dpu_crtc_check_dest_scaler_data(struct > drm_crtc *crtc, > return ret; > } > > -/** > - * _dpu_crtc_wait_for_fences - wait for incoming framebuffer sync > fences > - * @crtc: Pointer to CRTC object > - */ > -static void _dpu_crtc_wait_for_fences(struct drm_crtc *crtc) > -{ > - struct drm_plane *plane = NULL; > - uint32_t wait_ms = 1; > - ktime_t kt_end, kt_wait; > - int rc = 0; > - > - DPU_DEBUG("\n"); > - > - if (!crtc || !crtc->state) { > - DPU_ERROR("invalid crtc/state %pK\n", crtc); > - return; > - } > - > - /* use monotonic timer to limit total fence wait time */ > - kt_end = ktime_add_ns(ktime_get(), > - to_dpu_crtc_state(crtc->state)->input_fence_timeout_ns); > - > - /* > - * Wait for fences sequentially, as all of them need to be > signalled > - * before we can proceed. > - * > - * Limit total wait time to INPUT_FENCE_TIMEOUT, but still call > - * dpu_plane_wait_input_fence with wait_ms == 0 after the timeout > so > - * that each plane can check its fence status and react > appropriately > - * if its fence has timed out. Call input fence wait multiple > times if > - * fence wait is interrupted due to interrupt call. > - */ > - DPU_ATRACE_BEGIN("plane_wait_input_fence"); > - drm_atomic_crtc_for_each_plane(plane, crtc) { > - do { > - kt_wait = ktime_sub(kt_end, ktime_get()); > - if (ktime_compare(kt_wait, ktime_set(0, 0)) >= 0) > - wait_ms = ktime_to_ms(kt_wait); > - else > - wait_ms = 0; > - > - rc = dpu_plane_wait_input_fence(plane, wait_ms); > - } while (wait_ms && rc == -ERESTARTSYS); > - } > - DPU_ATRACE_END("plane_wait_input_fence"); > -} > - > static void _dpu_crtc_setup_mixer_for_encoder( > struct drm_crtc *crtc, > struct drm_encoder *enc) > @@ -2716,9 +2644,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc > *crtc, > drm_atomic_crtc_for_each_plane(plane, crtc) > dpu_plane_restore(plane); > > - /* wait for acquire fences before anything else is done */ > - _dpu_crtc_wait_for_fences(crtc); > - > if (!cstate->rsc_update) { > drm_for_each_encoder(encoder, dev) { > if (encoder->crtc != crtc) > @@ -3178,8 +3103,6 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) > &cstate->property_state, > cstate->property_values); > > - _dpu_crtc_set_input_fence_timeout(cstate); > - > _dpu_crtc_rp_reset(&cstate->rp, &dpu_crtc->rp_lock, > &dpu_crtc->rp_head); > > @@ -3929,10 +3852,6 @@ static void dpu_crtc_install_properties(struct > drm_crtc *crtc, > } > > /* range properties */ > - msm_property_install_range(&dpu_crtc->property_info, > - "input_fence_timeout", 0x0, 0, > DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT, > - DPU_CRTC_INPUT_FENCE_TIMEOUT, > CRTC_PROP_INPUT_FENCE_TIMEOUT); > - > msm_property_install_range(&dpu_crtc->property_info, > "core_clk", 0x0, 0, U64_MAX, > dpu_kms->perf.max_core_clk_rate, > @@ -4121,9 +4040,6 @@ static int dpu_crtc_atomic_set_property(struct > drm_crtc *crtc, > idx = msm_property_index(&dpu_crtc->property_info, > property); > switch (idx) { > - case CRTC_PROP_INPUT_FENCE_TIMEOUT: > - _dpu_crtc_set_input_fence_timeout(cstate); > - break; > case CRTC_PROP_DIM_LAYER_V1: > _dpu_crtc_set_dim_layer_v1(cstate, > (void __user > *)val); > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c > deleted file mode 100644 > index 49ffd7138eba..000000000000 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c > +++ /dev/null > @@ -1,404 +0,0 @@ > -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. > - * > - * This program is free software; you can redistribute it and/or > modify > - * it under the terms of the GNU General Public License version 2 and > - * only version 2 as published by the Free Software Foundation. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - */ > - > -#include <linux/sync_file.h> > -#include <linux/dma-fence.h> > -#include "msm_drv.h" > -#include "dpu_kms.h" > -#include "dpu_fence.h" > - > -#define TIMELINE_VAL_LENGTH 128 > - > -void *dpu_sync_get(uint64_t fd) > -{ > - /* force signed compare, fdget accepts an int argument */ > - return (signed int)fd >= 0 ? sync_file_get_fence(fd) : NULL; > -} > - > -void dpu_sync_put(void *fence) > -{ > - if (fence) > - dma_fence_put(fence); > -} > - > -signed long dpu_sync_wait(void *fnc, long timeout_ms) > -{ > - struct dma_fence *fence = fnc; > - int rc; > - char timeline_str[TIMELINE_VAL_LENGTH]; > - > - if (!fence) > - return -EINVAL; > - else if (dma_fence_is_signaled(fence)) > - return timeout_ms ? msecs_to_jiffies(timeout_ms) : 1; > - > - rc = dma_fence_wait_timeout(fence, true, > - msecs_to_jiffies(timeout_ms)); > - if (!rc || (rc == -EINVAL)) { > - if (fence->ops->timeline_value_str) > - fence->ops->timeline_value_str(fence, > - timeline_str, > TIMELINE_VAL_LENGTH); > - > - DPU_ERROR( > - "fence driver name:%s timeline name:%s seqno:0x%x > timeline:%s signaled:0x%x\n", > - fence->ops->get_driver_name(fence), > - fence->ops->get_timeline_name(fence), > - fence->seqno, timeline_str, > - fence->ops->signaled ? > - fence->ops->signaled(fence) : 0xffffffff); > - } > - > - return rc; > -} > - > -uint32_t dpu_sync_get_name_prefix(void *fence) > -{ > - const char *name; > - uint32_t i, prefix; > - struct dma_fence *f = fence; > - > - if (!fence) > - return 0; > - > - name = f->ops->get_driver_name(f); > - if (!name) > - return 0; > - > - prefix = 0x0; > - for (i = 0; i < sizeof(uint32_t) && name[i]; ++i) > - prefix = (prefix << CHAR_BIT) | name[i]; > - > - return prefix; > -} > - > -/** > - * struct dpu_fence - release/retire fence structure > - * @fence: base fence structure > - * @name: name of each fence- it is fence timeline + commit_count > - * @fence_list: list to associated this fence on timeline/context > - * @fd: fd attached to this fence - debugging purpose. > - */ > -struct dpu_fence { > - struct dma_fence base; > - struct dpu_fence_context *ctx; > - char name[DPU_FENCE_NAME_SIZE]; > - struct list_head fence_list; > - int fd; > -}; > - > -static void dpu_fence_destroy(struct kref *kref) > -{ > -} > - > -static inline struct dpu_fence *to_dpu_fence(struct dma_fence *fence) > -{ > - return container_of(fence, struct dpu_fence, base); > -} > - > -static const char *dpu_fence_get_driver_name(struct dma_fence *fence) > -{ > - struct dpu_fence *f = to_dpu_fence(fence); > - > - return f->name; > -} > - > -static const char *dpu_fence_get_timeline_name(struct dma_fence > *fence) > -{ > - struct dpu_fence *f = to_dpu_fence(fence); > - > - return f->ctx->name; > -} > - > -static bool dpu_fence_enable_signaling(struct dma_fence *fence) > -{ > - return true; > -} > - > -static bool dpu_fence_signaled(struct dma_fence *fence) > -{ > - struct dpu_fence *f = to_dpu_fence(fence); > - bool status; > - > - status = (int)(fence->seqno - f->ctx->done_count) <= 0 ? true : > false; > - DPU_DEBUG("status:%d fence seq:%d and timeline:%d\n", > - status, fence->seqno, f->ctx->done_count); > - return status; > -} > - > -static void dpu_fence_release(struct dma_fence *fence) > -{ > - struct dpu_fence *f; > - > - if (fence) { > - f = to_dpu_fence(fence); > - kfree(f); > - } > -} > - > -static void dpu_fence_value_str(struct dma_fence *fence, char *str, > int > size) > -{ > - if (!fence || !str) > - return; > - > - snprintf(str, size, "%d", fence->seqno); > -} > - > -static void dpu_fence_timeline_value_str(struct dma_fence *fence, char > *str, > - int size) > -{ > - struct dpu_fence *f = to_dpu_fence(fence); > - > - if (!fence || !f->ctx || !str) > - return; > - > - snprintf(str, size, "%d", f->ctx->done_count); > -} > - > -static struct dma_fence_ops dpu_fence_ops = { > - .get_driver_name = dpu_fence_get_driver_name, > - .get_timeline_name = dpu_fence_get_timeline_name, > - .enable_signaling = dpu_fence_enable_signaling, > - .signaled = dpu_fence_signaled, > - .wait = dma_fence_default_wait, > - .release = dpu_fence_release, > - .fence_value_str = dpu_fence_value_str, > - .timeline_value_str = dpu_fence_timeline_value_str, > -}; > - > -/** > - * _dpu_fence_create_fd - create fence object and return an fd for it > - * This function is NOT thread-safe. > - * @timeline: Timeline to associate with fence > - * @val: Timeline value at which to signal the fence > - * Return: File descriptor on success, or error code on error > - */ > -static int _dpu_fence_create_fd(void *fence_ctx, uint32_t val) > -{ > - struct dpu_fence *dpu_fence; > - struct sync_file *sync_file; > - signed int fd = -EINVAL; > - struct dpu_fence_context *ctx = fence_ctx; > - > - if (!ctx) { > - DPU_ERROR("invalid context\n"); > - goto exit; > - } > - > - dpu_fence = kzalloc(sizeof(*dpu_fence), GFP_KERNEL); > - if (!dpu_fence) > - return -ENOMEM; > - > - dpu_fence->ctx = fence_ctx; > - snprintf(dpu_fence->name, DPU_FENCE_NAME_SIZE, "dpu_fence:%s:%u", > - dpu_fence->ctx->name, > val); > - dma_fence_init(&dpu_fence->base, &dpu_fence_ops, &ctx->lock, > - ctx->context, val); > - > - /* create fd */ > - fd = get_unused_fd_flags(0); > - if (fd < 0) { > - dma_fence_put(&dpu_fence->base); > - DPU_ERROR("failed to get_unused_fd_flags(), %s\n", > - dpu_fence->name); > - goto exit; > - } > - > - /* create fence */ > - sync_file = sync_file_create(&dpu_fence->base); > - if (sync_file == NULL) { > - put_unused_fd(fd); > - fd = -EINVAL; > - dma_fence_put(&dpu_fence->base); > - DPU_ERROR("couldn't create fence, %s\n", dpu_fence->name); > - goto exit; > - } > - > - fd_install(fd, sync_file->file); > - dpu_fence->fd = fd; > - kref_get(&ctx->kref); > - > - spin_lock(&ctx->list_lock); > - list_add_tail(&dpu_fence->fence_list, &ctx->fence_list_head); > - spin_unlock(&ctx->list_lock); > - > -exit: > - return fd; > -} > - > -int dpu_fence_init(struct dpu_fence_context *ctx, > - const char *name, uint32_t drm_id) > -{ > - if (!ctx || !name) { > - DPU_ERROR("invalid argument(s)\n"); > - return -EINVAL; > - } > - memset(ctx, 0, sizeof(*ctx)); > - > - strlcpy(ctx->name, name, ARRAY_SIZE(ctx->name)); > - ctx->drm_id = drm_id; > - kref_init(&ctx->kref); > - ctx->context = dma_fence_context_alloc(1); > - > - spin_lock_init(&ctx->lock); > - spin_lock_init(&ctx->list_lock); > - INIT_LIST_HEAD(&ctx->fence_list_head); > - > - return 0; > -} > - > -void dpu_fence_deinit(struct dpu_fence_context *ctx) > -{ > - if (!ctx) { > - DPU_ERROR("invalid fence\n"); > - return; > - } > - > - kref_put(&ctx->kref, dpu_fence_destroy); > -} > - > -void dpu_fence_prepare(struct dpu_fence_context *ctx) > -{ > - unsigned long flags; > - > - if (!ctx) { > - DPU_ERROR("invalid argument(s), fence %pK\n", ctx); > - } else { > - spin_lock_irqsave(&ctx->lock, flags); > - ++ctx->commit_count; > - spin_unlock_irqrestore(&ctx->lock, flags); > - } > -} > - > -static void _dpu_fence_trigger(struct dpu_fence_context *ctx, ktime_t > ts) > -{ > - unsigned long flags; > - struct dpu_fence *fc, *next; > - bool is_signaled = false; > - struct list_head local_list_head; > - > - INIT_LIST_HEAD(&local_list_head); > - > - spin_lock(&ctx->list_lock); > - if (list_empty(&ctx->fence_list_head)) { > - DPU_DEBUG("nothing to trigger!\n"); > - spin_unlock(&ctx->list_lock); > - return; > - } > - > - list_for_each_entry_safe(fc, next, &ctx->fence_list_head, > fence_list) > - list_move(&fc->fence_list, &local_list_head); > - spin_unlock(&ctx->list_lock); > - > - list_for_each_entry_safe(fc, next, &local_list_head, fence_list) { > - spin_lock_irqsave(&ctx->lock, flags); > - fc->base.timestamp = ts; > - is_signaled = dma_fence_is_signaled_locked(&fc->base); > - spin_unlock_irqrestore(&ctx->lock, flags); > - > - if (is_signaled) { > - list_del_init(&fc->fence_list); > - dma_fence_put(&fc->base); > - kref_put(&ctx->kref, dpu_fence_destroy); > - } else { > - spin_lock(&ctx->list_lock); > - list_move(&fc->fence_list, &ctx->fence_list_head); > - spin_unlock(&ctx->list_lock); > - } > - } > -} > - > -int dpu_fence_create(struct dpu_fence_context *ctx, uint64_t *val, > - uint32_t offset) > -{ > - uint32_t trigger_value; > - int fd, rc = -EINVAL; > - unsigned long flags; > - > - if (!ctx || !val) { > - DPU_ERROR("invalid argument(s), fence %d, pval %d\n", > - ctx != NULL, val != NULL); > - return rc; > - } > - > - /* > - * Allow created fences to have a constant offset with respect > - * to the timeline. This allows us to delay the fence signalling > - * w.r.t. the commit completion (e.g., an offset of +1 would > - * cause fences returned during a particular commit to signal > - * after an additional delay of one commit, rather than at the > - * end of the current one. > - */ > - spin_lock_irqsave(&ctx->lock, flags); > - trigger_value = ctx->commit_count + offset; > - > - spin_unlock_irqrestore(&ctx->lock, flags); > - > - fd = _dpu_fence_create_fd(ctx, trigger_value); > - *val = fd; > - DPU_DEBUG("fence_create::fd:%d trigger:%d commit:%d offset:%d\n", > - fd, trigger_value, ctx->commit_count, > offset); > - > - DPU_EVT32(ctx->drm_id, trigger_value, fd); > - > - if (fd >= 0) { > - rc = 0; > - _dpu_fence_trigger(ctx, ktime_get()); > - } else { > - rc = fd; > - } > - > - return rc; > -} > - > -void dpu_fence_signal(struct dpu_fence_context *ctx, ktime_t ts, > - bool > reset_timeline) > -{ > - unsigned long flags; > - > - if (!ctx) { > - DPU_ERROR("invalid ctx, %pK\n", ctx); > - return; > - } > - > - spin_lock_irqsave(&ctx->lock, flags); > - if (reset_timeline) { > - if ((int)(ctx->done_count - ctx->commit_count) < 0) { > - DPU_ERROR( > - "timeline reset attempt! done count:%d > commit:%d\n", > - ctx->done_count, ctx->commit_count); > - ctx->done_count = ctx->commit_count; > - DPU_EVT32(ctx->drm_id, ctx->done_count, > - ctx->commit_count, ktime_to_us(ts), > - reset_timeline, DPU_EVTLOG_FATAL); > - } else { > - spin_unlock_irqrestore(&ctx->lock, flags); > - return; > - } > - } else if ((int)(ctx->done_count - ctx->commit_count) < 0) { > - ++ctx->done_count; > - DPU_DEBUG("fence_signal:done count:%d commit count:%d\n", > - ctx->done_count, > ctx->commit_count); > - } else { > - DPU_ERROR("extra signal attempt! done count:%d > commit:%d\n", > - ctx->done_count, > ctx->commit_count); > - DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, > - ktime_to_us(ts), reset_timeline, > DPU_EVTLOG_FATAL); > - spin_unlock_irqrestore(&ctx->lock, flags); > - return; > - } > - spin_unlock_irqrestore(&ctx->lock, flags); > - > - DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, > - ktime_to_us(ts)); > - > - _dpu_fence_trigger(ctx, ts); > -} > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h > deleted file mode 100644 > index f943046d96b8..000000000000 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h > +++ /dev/null > @@ -1,190 +0,0 @@ > -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. > - * > - * This program is free software; you can redistribute it and/or > modify > - * it under the terms of the GNU General Public License version 2 and > - * only version 2 as published by the Free Software Foundation. > - * > - * This program is distributed in the hope that it will be useful, > - * but WITHOUT ANY WARRANTY; without even the implied warranty of > - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > - * GNU General Public License for more details. > - */ > - > -#ifndef _DPU_FENCE_H_ > -#define _DPU_FENCE_H_ > - > -#include <linux/kernel.h> > -#include <linux/errno.h> > -#include <linux/mutex.h> > - > -#ifndef CHAR_BIT > -#define CHAR_BIT 8 /* define this if limits.h not available */ > -#endif > - > -#define DPU_FENCE_NAME_SIZE 24 > - > -/** > - * struct dpu_fence_context - release/retire fence context/timeline > structure > - * @commit_count: Number of detected commits since bootup > - * @done_count: Number of completed commits since bootup > - * @drm_id: ID number of owning DRM Object > - * @ref: kref counter on timeline > - * @lock: spinlock for fence counter protection > - * @list_lock: spinlock for timeline protection > - * @context: fence context > - * @list_head: fence list to hold all the fence created on this > context > - * @name: name of fence context/timeline > - */ > -struct dpu_fence_context { > - unsigned int commit_count; > - unsigned int done_count; > - uint32_t drm_id; > - struct kref kref; > - spinlock_t lock; > - spinlock_t list_lock; > - u64 context; > - struct list_head fence_list_head; > - char name[DPU_FENCE_NAME_SIZE]; > -}; > - > -#if IS_ENABLED(CONFIG_SYNC_FILE) > -/** > - * dpu_sync_get - Query sync fence object from a file handle > - * > - * On success, this function also increments the refcount of the sync > fence > - * > - * @fd: Integer sync fence handle > - * > - * Return: Pointer to sync fence object, or NULL > - */ > -void *dpu_sync_get(uint64_t fd); > - > -/** > - * dpu_sync_put - Releases a sync fence object acquired by > @dpu_sync_get > - * > - * This function decrements the sync fence's reference count; the > object > will > - * be released if the reference count goes to zero. > - * > - * @fence: Pointer to sync fence > - */ > -void dpu_sync_put(void *fence); > - > -/** > - * dpu_sync_wait - Query sync fence object from a file handle > - * > - * @fence: Pointer to sync fence > - * @timeout_ms: Time to wait, in milliseconds. Waits forever if > timeout_ms < 0 > - * > - * Return: > - * Zero if timed out > - * -ERESTARTSYS if wait interrupted > - * remaining jiffies in all other success cases. > - */ > -signed long dpu_sync_wait(void *fence, long timeout_ms); > - > -/** > - * dpu_sync_get_name_prefix - get integer representation of fence name > prefix > - * @fence: Pointer to opaque fence structure > - * > - * Return: 32-bit integer containing first 4 characters of fence name, > - * big-endian notation > - */ > -uint32_t dpu_sync_get_name_prefix(void *fence); > - > -/** > - * dpu_fence_init - initialize fence object > - * @fence: Pointer to crtc fence object > - * @drm_id: ID number of owning DRM Object > - * @name: Timeline name > - * Returns: Zero on success > - */ > -int dpu_fence_init(struct dpu_fence_context *fence, > - const char *name, > - uint32_t drm_id); > - > -/** > - * dpu_fence_deinit - deinit fence container > - * @fence: Pointer fence container > - */ > -void dpu_fence_deinit(struct dpu_fence_context *fence); > - > -/** > - * dpu_fence_prepare - prepare to return fences for current commit > - * @fence: Pointer fence container > - * Returns: Zero on success > - */ > -void dpu_fence_prepare(struct dpu_fence_context *fence); > -/** > - * dpu_fence_create - create output fence object > - * @fence: Pointer fence container > - * @val: Pointer to output value variable, fence fd will be placed > here > - * @offset: Fence signal commit offset, e.g., +1 to signal on next > commit > - * Returns: Zero on success > - */ > -int dpu_fence_create(struct dpu_fence_context *fence, uint64_t *val, > - uint32_t offset); > - > -/** > - * dpu_fence_signal - advance fence timeline to signal outstanding > fences > - * @fence: Pointer fence container > - * @ts: fence timestamp > - * @reset_timeline: reset the fence timeline to done count equal to > commit count > - */ > -void dpu_fence_signal(struct dpu_fence_context *fence, ktime_t ts, > - bool reset_timeline); > -#else > -static inline void *dpu_sync_get(uint64_t fd) > -{ > - return NULL; > -} > - > -static inline void dpu_sync_put(void *fence) > -{ > -} > - > -static inline signed long dpu_sync_wait(void *fence, long timeout_ms) > -{ > - return 0; > -} > - > -static inline uint32_t dpu_sync_get_name_prefix(void *fence) > -{ > - return 0x0; > -} > -static inline int dpu_fence_init(struct dpu_fence_context *fence, > - const char *name, > - uint32_t drm_id) > -{ > - /* do nothing */ > - return 0; > -} > - > -static inline void dpu_fence_deinit(struct dpu_fence_context *fence) > -{ > - /* do nothing */ > -} > - > -static inline int dpu_fence_get(struct dpu_fence_context *fence, > uint64_t > *val) > -{ > - return -EINVAL; > -} > - > -static inline void dpu_fence_signal(struct dpu_fence_context *fence, > - ktime_t ts, bool > reset_timeline) > -{ > - /* do nothing */ > -} > - > -static inline void dpu_fence_prepare(struct dpu_fence_context *fence) > -{ > - /* do nothing */ > -} > - > -static inline int dpu_fence_create(struct dpu_fence_context *fence, > - uint64_t *val, uint32_t > offset) > -{ > - return 0; > -} > -#endif /* IS_ENABLED(CONFIG_SW_SYNC) */ > - > -#endif /* _DPU_FENCE_H_ */ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > index 29e72b39fd72..610e616f2e74 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > @@ -27,7 +27,6 @@ > #include "msm_drv.h" > > #include "dpu_kms.h" > -#include "dpu_fence.h" > #include "dpu_formats.h" > #include "dpu_hw_sspp.h" > #include "dpu_hw_catalog_format.h" > @@ -676,26 +675,6 @@ static void _dpu_plane_set_ts_prefill(struct > drm_plane *plane, > pstate->multirect_index); > } > > -/* helper to update a state's input fence pointer from the property */ > -static void _dpu_plane_set_input_fence(struct dpu_plane *pdpu, > - struct dpu_plane_state *pstate, uint64_t fd) > -{ > - if (!pdpu || !pstate) { > - DPU_ERROR("invalid arg(s), plane %d state %d\n", > - pdpu != 0, pstate != 0); > - return; > - } > - > - /* clear previous reference */ > - if (pstate->input_fence) > - dpu_sync_put(pstate->input_fence); > - > - /* get fence pointer for later */ > - pstate->input_fence = dpu_sync_get(fd); > - > - DPU_DEBUG_PLANE(pdpu, "0x%llX\n", fd); > -} > - > /** > * _dpu_plane_inline_rot_set_ot_limit - set OT limit for the given > inline > * rotation xin client > @@ -780,64 +759,6 @@ static void > _dpu_plane_inline_rot_set_qos_remap(struct drm_plane *plane, > dpu_vbif_set_qos_remap(dpu_kms, &qos_params); > } > > -int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t > wait_ms) > -{ > - struct dpu_plane *pdpu; > - struct dpu_plane_state *pstate; > - uint32_t prefix; > - void *input_fence; > - int ret = -EINVAL; > - signed long rc; > - > - if (!plane) { > - DPU_ERROR("invalid plane\n"); > - } else if (!plane->state) { > - DPU_ERROR_PLANE(to_dpu_plane(plane), "invalid state\n"); > - } else { > - pdpu = to_dpu_plane(plane); > - pstate = to_dpu_plane_state(plane->state); > - input_fence = pstate->input_fence; > - > - if (input_fence) { > - pdpu->is_error = false; > - prefix = dpu_sync_get_name_prefix(input_fence); > - rc = dpu_sync_wait(input_fence, wait_ms); > - > - switch (rc) { > - case 0: > - DPU_ERROR_PLANE(pdpu, "%ums timeout on > %08X\n", > - wait_ms, prefix); > - pdpu->is_error = true; > - ret = -ETIMEDOUT; > - break; > - case -ERESTARTSYS: > - DPU_ERROR_PLANE(pdpu, > - "%ums wait interrupted on %08X\n", > - wait_ms, prefix); > - pdpu->is_error = true; > - ret = -ERESTARTSYS; > - break; > - case -EINVAL: > - DPU_ERROR_PLANE(pdpu, > - "invalid fence param for %08X\n", > - prefix); > - pdpu->is_error = true; > - ret = -EINVAL; > - break; > - default: > - DPU_DEBUG_PLANE(pdpu, "signaled\n"); > - ret = 0; > - break; > - } > - > - DPU_EVT32_VERBOSE(DRMID(plane), -ret, prefix); > - } else { > - ret = 0; > - } > - } > - return ret; > -} > - > /** > * _dpu_plane_get_aspace: gets the address space > */ > @@ -3332,7 +3253,6 @@ static int dpu_plane_sspp_atomic_update(struct > drm_plane *plane, > break; > case PLANE_PROP_INFO: > case PLANE_PROP_ALPHA: > - case PLANE_PROP_INPUT_FENCE: > case PLANE_PROP_BLEND_OP: > /* no special action required */ > break; > @@ -3703,10 +3623,6 @@ static void _dpu_plane_install_properties(struct > drm_plane *plane, > msm_property_install_range(&pdpu->property_info, "alpha", > 0x0, 0, 255, 255, PLANE_PROP_ALPHA); > > - /* linux default file descriptor range on each process */ > - msm_property_install_range(&pdpu->property_info, "input_fence", > - 0x0, 0, INR_OPEN_MAX, 0, PLANE_PROP_INPUT_FENCE); > - > if (!master_plane_id) { > if (pdpu->pipe_sblk->maxhdeciexp) { > msm_property_install_range(&pdpu->property_info, > @@ -4076,9 +3992,6 @@ static int dpu_plane_atomic_set_property(struct > drm_plane *plane, > idx = msm_property_index(&pdpu->property_info, > property); > switch (idx) { > - case PLANE_PROP_INPUT_FENCE: > - _dpu_plane_set_input_fence(pdpu, pstate, > val); > - break; > case PLANE_PROP_CSC_V1: > _dpu_plane_set_csc_v1(pdpu, (void *)val); > break; > @@ -4190,10 +4103,6 @@ static void dpu_plane_destroy_state(struct > drm_plane *plane, > if (state->fb) > drm_framebuffer_put(state->fb); > > - /* remove ref count for fence */ > - if (pstate->input_fence) > - dpu_sync_put(pstate->input_fence); > - > /* destroy value helper */ > msm_property_destroy_state(&pdpu->property_info, pstate, > &pstate->property_state); > @@ -4206,7 +4115,6 @@ dpu_plane_duplicate_state(struct drm_plane > *plane) > struct dpu_plane_state *pstate; > struct dpu_plane_state *old_state; > struct drm_property *drm_prop; > - uint64_t input_fence_default; > > if (!plane) { > DPU_ERROR("invalid plane\n"); > @@ -4230,18 +4138,6 @@ dpu_plane_duplicate_state(struct drm_plane > *plane) > msm_property_duplicate_state(&pdpu->property_info, old_state, > pstate, > &pstate->property_state, pstate->property_values); > > - /* clear out any input fence */ > - pstate->input_fence = 0; > - input_fence_default = msm_property_get_default( > - &pdpu->property_info, PLANE_PROP_INPUT_FENCE); > - drm_prop = msm_property_index_to_drm_property( > - &pdpu->property_info, > PLANE_PROP_INPUT_FENCE); > - if (msm_property_atomic_set(&pdpu->property_info, > - &pstate->property_state, drm_prop, > - input_fence_default)) > - DPU_DEBUG_PLANE(pdpu, > - "error clearing duplicated input > fence\n"); > - > pstate->dirty = 0x0; > pstate->pending = false; > > diff --git a/drivers/gpu/drm/msm/msm_drv.h > b/drivers/gpu/drm/msm/msm_drv.h > index 657ea052a1ee..75a24b81c89a 100644 > --- a/drivers/gpu/drm/msm/msm_drv.h > +++ b/drivers/gpu/drm/msm/msm_drv.h > @@ -99,7 +99,6 @@ enum msm_mdp_plane_property { > PLANE_PROP_COLOR_FILL, > PLANE_PROP_H_DECIMATE, > PLANE_PROP_V_DECIMATE, > - PLANE_PROP_INPUT_FENCE, > PLANE_PROP_HUE_ADJUST, > PLANE_PROP_SATURATION_ADJUST, > PLANE_PROP_VALUE_ADJUST, > @@ -131,8 +130,7 @@ enum msm_mdp_crtc_property { > CRTC_PROP_BLOBCOUNT, > > /* range properties */ > - CRTC_PROP_INPUT_FENCE_TIMEOUT = CRTC_PROP_BLOBCOUNT, > - CRTC_PROP_DIM_LAYER_V1, > + CRTC_PROP_DIM_LAYER_V1 = CRTC_PROP_BLOBCOUNT, > CRTC_PROP_CORE_CLK, > CRTC_PROP_CORE_AB, > CRTC_PROP_CORE_IB,
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 2fb9ba11df19..b47ef5267e19 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -55,7 +55,6 @@ msm-y := \ disp/dpu1/dpu_encoder.o \ disp/dpu1/dpu_encoder_phys_cmd.o \ disp/dpu1/dpu_encoder_phys_vid.o \ - disp/dpu1/dpu_fence.o \ disp/dpu1/dpu_formats.o \ disp/dpu1/dpu_hw_ad4.o \ disp/dpu1/dpu_hw_blk.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 2d44989ade7a..8dd986e476bd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -64,16 +64,6 @@ static struct dpu_crtc_custom_events custom_events[] = { {DRM_EVENT_IDLE_NOTIFY, dpu_crtc_idle_interrupt_handler} }; -/* default input fence timeout, in ms */ -#define DPU_CRTC_INPUT_FENCE_TIMEOUT 10000 - -/* - * The default input fence timeout is 2 seconds while max allowed - * range is 10 seconds. Any value above 10 seconds adds glitches beyond - * tolerance limit. - */ -#define DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT 10000 - /* layer mixer index on dpu_crtc */ #define LEFT_MIXER 0 #define RIGHT_MIXER 1 @@ -1946,21 +1936,6 @@ static void _dpu_crtc_set_idle_timeout(struct drm_crtc *crtc, u64 val) } } -/** - * _dpu_crtc_set_input_fence_timeout - update ns version of in fence timeout - * @cstate: Pointer to dpu crtc state - */ -static void _dpu_crtc_set_input_fence_timeout(struct dpu_crtc_state *cstate) -{ - if (!cstate) { - DPU_ERROR("invalid cstate\n"); - return; - } - cstate->input_fence_timeout_ns = - dpu_crtc_get_property(cstate, CRTC_PROP_INPUT_FENCE_TIMEOUT); - cstate->input_fence_timeout_ns *= NSEC_PER_MSEC; -} - /** * _dpu_crtc_set_dim_layer_v1 - copy dim layer settings from userspace * @cstate: Pointer to dpu crtc state @@ -2385,53 +2360,6 @@ static int _dpu_crtc_check_dest_scaler_data(struct drm_crtc *crtc, return ret; } -/** - * _dpu_crtc_wait_for_fences - wait for incoming framebuffer sync fences - * @crtc: Pointer to CRTC object - */ -static void _dpu_crtc_wait_for_fences(struct drm_crtc *crtc) -{ - struct drm_plane *plane = NULL; - uint32_t wait_ms = 1; - ktime_t kt_end, kt_wait; - int rc = 0; - - DPU_DEBUG("\n"); - - if (!crtc || !crtc->state) { - DPU_ERROR("invalid crtc/state %pK\n", crtc); - return; - } - - /* use monotonic timer to limit total fence wait time */ - kt_end = ktime_add_ns(ktime_get(), - to_dpu_crtc_state(crtc->state)->input_fence_timeout_ns); - - /* - * Wait for fences sequentially, as all of them need to be signalled - * before we can proceed. - * - * Limit total wait time to INPUT_FENCE_TIMEOUT, but still call - * dpu_plane_wait_input_fence with wait_ms == 0 after the timeout so - * that each plane can check its fence status and react appropriately - * if its fence has timed out. Call input fence wait multiple times if - * fence wait is interrupted due to interrupt call. - */ - DPU_ATRACE_BEGIN("plane_wait_input_fence"); - drm_atomic_crtc_for_each_plane(plane, crtc) { - do { - kt_wait = ktime_sub(kt_end, ktime_get()); - if (ktime_compare(kt_wait, ktime_set(0, 0)) >= 0) - wait_ms = ktime_to_ms(kt_wait); - else - wait_ms = 0; - - rc = dpu_plane_wait_input_fence(plane, wait_ms); - } while (wait_ms && rc == -ERESTARTSYS); - } - DPU_ATRACE_END("plane_wait_input_fence"); -} - static void _dpu_crtc_setup_mixer_for_encoder( struct drm_crtc *crtc, struct drm_encoder *enc) @@ -2716,9 +2644,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, drm_atomic_crtc_for_each_plane(plane, crtc) dpu_plane_restore(plane); - /* wait for acquire fences before anything else is done */ - _dpu_crtc_wait_for_fences(crtc); - if (!cstate->rsc_update) { drm_for_each_encoder(encoder, dev) { if (encoder->crtc != crtc) @@ -3178,8 +3103,6 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) &cstate->property_state, cstate->property_values); - _dpu_crtc_set_input_fence_timeout(cstate); - _dpu_crtc_rp_reset(&cstate->rp, &dpu_crtc->rp_lock, &dpu_crtc->rp_head); @@ -3929,10 +3852,6 @@ static void dpu_crtc_install_properties(struct drm_crtc *crtc, } /* range properties */ - msm_property_install_range(&dpu_crtc->property_info, - "input_fence_timeout", 0x0, 0, DPU_CRTC_MAX_INPUT_FENCE_TIMEOUT, - DPU_CRTC_INPUT_FENCE_TIMEOUT, CRTC_PROP_INPUT_FENCE_TIMEOUT); - msm_property_install_range(&dpu_crtc->property_info, "core_clk", 0x0, 0, U64_MAX, dpu_kms->perf.max_core_clk_rate, @@ -4121,9 +4040,6 @@ static int dpu_crtc_atomic_set_property(struct drm_crtc *crtc, idx = msm_property_index(&dpu_crtc->property_info, property); switch (idx) { - case CRTC_PROP_INPUT_FENCE_TIMEOUT: - _dpu_crtc_set_input_fence_timeout(cstate); - break; case CRTC_PROP_DIM_LAYER_V1: _dpu_crtc_set_dim_layer_v1(cstate, (void __user *)val); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c deleted file mode 100644 index 49ffd7138eba..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c +++ /dev/null @@ -1,404 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <linux/sync_file.h> -#include <linux/dma-fence.h> -#include "msm_drv.h" -#include "dpu_kms.h" -#include "dpu_fence.h" - -#define TIMELINE_VAL_LENGTH 128 - -void *dpu_sync_get(uint64_t fd) -{ - /* force signed compare, fdget accepts an int argument */ - return (signed int)fd >= 0 ? sync_file_get_fence(fd) : NULL; -} - -void dpu_sync_put(void *fence) -{ - if (fence) - dma_fence_put(fence); -} - -signed long dpu_sync_wait(void *fnc, long timeout_ms) -{ - struct dma_fence *fence = fnc; - int rc; - char timeline_str[TIMELINE_VAL_LENGTH]; - - if (!fence) - return -EINVAL; - else if (dma_fence_is_signaled(fence)) - return timeout_ms ? msecs_to_jiffies(timeout_ms) : 1; - - rc = dma_fence_wait_timeout(fence, true, - msecs_to_jiffies(timeout_ms)); - if (!rc || (rc == -EINVAL)) { - if (fence->ops->timeline_value_str) - fence->ops->timeline_value_str(fence, - timeline_str, TIMELINE_VAL_LENGTH); - - DPU_ERROR( - "fence driver name:%s timeline name:%s seqno:0x%x timeline:%s signaled:0x%x\n", - fence->ops->get_driver_name(fence), - fence->ops->get_timeline_name(fence), - fence->seqno, timeline_str, - fence->ops->signaled ? - fence->ops->signaled(fence) : 0xffffffff); - } - - return rc; -} - -uint32_t dpu_sync_get_name_prefix(void *fence) -{ - const char *name; - uint32_t i, prefix; - struct dma_fence *f = fence; - - if (!fence) - return 0; - - name = f->ops->get_driver_name(f); - if (!name) - return 0; - - prefix = 0x0; - for (i = 0; i < sizeof(uint32_t) && name[i]; ++i) - prefix = (prefix << CHAR_BIT) | name[i]; - - return prefix; -} - -/** - * struct dpu_fence - release/retire fence structure - * @fence: base fence structure - * @name: name of each fence- it is fence timeline + commit_count - * @fence_list: list to associated this fence on timeline/context - * @fd: fd attached to this fence - debugging purpose. - */ -struct dpu_fence { - struct dma_fence base; - struct dpu_fence_context *ctx; - char name[DPU_FENCE_NAME_SIZE]; - struct list_head fence_list; - int fd; -}; - -static void dpu_fence_destroy(struct kref *kref) -{ -} - -static inline struct dpu_fence *to_dpu_fence(struct dma_fence *fence) -{ - return container_of(fence, struct dpu_fence, base); -} - -static const char *dpu_fence_get_driver_name(struct dma_fence *fence) -{ - struct dpu_fence *f = to_dpu_fence(fence); - - return f->name; -} - -static const char *dpu_fence_get_timeline_name(struct dma_fence *fence) -{ - struct dpu_fence *f = to_dpu_fence(fence); - - return f->ctx->name; -} - -static bool dpu_fence_enable_signaling(struct dma_fence *fence) -{ - return true; -} - -static bool dpu_fence_signaled(struct dma_fence *fence) -{ - struct dpu_fence *f = to_dpu_fence(fence); - bool status; - - status = (int)(fence->seqno - f->ctx->done_count) <= 0 ? true : false; - DPU_DEBUG("status:%d fence seq:%d and timeline:%d\n", - status, fence->seqno, f->ctx->done_count); - return status; -} - -static void dpu_fence_release(struct dma_fence *fence) -{ - struct dpu_fence *f; - - if (fence) { - f = to_dpu_fence(fence); - kfree(f); - } -} - -static void dpu_fence_value_str(struct dma_fence *fence, char *str, int size) -{ - if (!fence || !str) - return; - - snprintf(str, size, "%d", fence->seqno); -} - -static void dpu_fence_timeline_value_str(struct dma_fence *fence, char *str, - int size) -{ - struct dpu_fence *f = to_dpu_fence(fence); - - if (!fence || !f->ctx || !str) - return; - - snprintf(str, size, "%d", f->ctx->done_count); -} - -static struct dma_fence_ops dpu_fence_ops = { - .get_driver_name = dpu_fence_get_driver_name, - .get_timeline_name = dpu_fence_get_timeline_name, - .enable_signaling = dpu_fence_enable_signaling, - .signaled = dpu_fence_signaled, - .wait = dma_fence_default_wait, - .release = dpu_fence_release, - .fence_value_str = dpu_fence_value_str, - .timeline_value_str = dpu_fence_timeline_value_str, -}; - -/** - * _dpu_fence_create_fd - create fence object and return an fd for it - * This function is NOT thread-safe. - * @timeline: Timeline to associate with fence - * @val: Timeline value at which to signal the fence - * Return: File descriptor on success, or error code on error - */ -static int _dpu_fence_create_fd(void *fence_ctx, uint32_t val) -{ - struct dpu_fence *dpu_fence; - struct sync_file *sync_file; - signed int fd = -EINVAL; - struct dpu_fence_context *ctx = fence_ctx; - - if (!ctx) { - DPU_ERROR("invalid context\n"); - goto exit; - } - - dpu_fence = kzalloc(sizeof(*dpu_fence), GFP_KERNEL); - if (!dpu_fence) - return -ENOMEM; - - dpu_fence->ctx = fence_ctx; - snprintf(dpu_fence->name, DPU_FENCE_NAME_SIZE, "dpu_fence:%s:%u", - dpu_fence->ctx->name, val); - dma_fence_init(&dpu_fence->base, &dpu_fence_ops, &ctx->lock, - ctx->context, val); - - /* create fd */ - fd = get_unused_fd_flags(0); - if (fd < 0) { - dma_fence_put(&dpu_fence->base); - DPU_ERROR("failed to get_unused_fd_flags(), %s\n", - dpu_fence->name); - goto exit; - } - - /* create fence */ - sync_file = sync_file_create(&dpu_fence->base); - if (sync_file == NULL) { - put_unused_fd(fd); - fd = -EINVAL; - dma_fence_put(&dpu_fence->base); - DPU_ERROR("couldn't create fence, %s\n", dpu_fence->name); - goto exit; - } - - fd_install(fd, sync_file->file); - dpu_fence->fd = fd; - kref_get(&ctx->kref); - - spin_lock(&ctx->list_lock); - list_add_tail(&dpu_fence->fence_list, &ctx->fence_list_head); - spin_unlock(&ctx->list_lock); - -exit: - return fd; -} - -int dpu_fence_init(struct dpu_fence_context *ctx, - const char *name, uint32_t drm_id) -{ - if (!ctx || !name) { - DPU_ERROR("invalid argument(s)\n"); - return -EINVAL; - } - memset(ctx, 0, sizeof(*ctx)); - - strlcpy(ctx->name, name, ARRAY_SIZE(ctx->name)); - ctx->drm_id = drm_id; - kref_init(&ctx->kref); - ctx->context = dma_fence_context_alloc(1); - - spin_lock_init(&ctx->lock); - spin_lock_init(&ctx->list_lock); - INIT_LIST_HEAD(&ctx->fence_list_head); - - return 0; -} - -void dpu_fence_deinit(struct dpu_fence_context *ctx) -{ - if (!ctx) { - DPU_ERROR("invalid fence\n"); - return; - } - - kref_put(&ctx->kref, dpu_fence_destroy); -} - -void dpu_fence_prepare(struct dpu_fence_context *ctx) -{ - unsigned long flags; - - if (!ctx) { - DPU_ERROR("invalid argument(s), fence %pK\n", ctx); - } else { - spin_lock_irqsave(&ctx->lock, flags); - ++ctx->commit_count; - spin_unlock_irqrestore(&ctx->lock, flags); - } -} - -static void _dpu_fence_trigger(struct dpu_fence_context *ctx, ktime_t ts) -{ - unsigned long flags; - struct dpu_fence *fc, *next; - bool is_signaled = false; - struct list_head local_list_head; - - INIT_LIST_HEAD(&local_list_head); - - spin_lock(&ctx->list_lock); - if (list_empty(&ctx->fence_list_head)) { - DPU_DEBUG("nothing to trigger!\n"); - spin_unlock(&ctx->list_lock); - return; - } - - list_for_each_entry_safe(fc, next, &ctx->fence_list_head, fence_list) - list_move(&fc->fence_list, &local_list_head); - spin_unlock(&ctx->list_lock); - - list_for_each_entry_safe(fc, next, &local_list_head, fence_list) { - spin_lock_irqsave(&ctx->lock, flags); - fc->base.timestamp = ts; - is_signaled = dma_fence_is_signaled_locked(&fc->base); - spin_unlock_irqrestore(&ctx->lock, flags); - - if (is_signaled) { - list_del_init(&fc->fence_list); - dma_fence_put(&fc->base); - kref_put(&ctx->kref, dpu_fence_destroy); - } else { - spin_lock(&ctx->list_lock); - list_move(&fc->fence_list, &ctx->fence_list_head); - spin_unlock(&ctx->list_lock); - } - } -} - -int dpu_fence_create(struct dpu_fence_context *ctx, uint64_t *val, - uint32_t offset) -{ - uint32_t trigger_value; - int fd, rc = -EINVAL; - unsigned long flags; - - if (!ctx || !val) { - DPU_ERROR("invalid argument(s), fence %d, pval %d\n", - ctx != NULL, val != NULL); - return rc; - } - - /* - * Allow created fences to have a constant offset with respect - * to the timeline. This allows us to delay the fence signalling - * w.r.t. the commit completion (e.g., an offset of +1 would - * cause fences returned during a particular commit to signal - * after an additional delay of one commit, rather than at the - * end of the current one. - */ - spin_lock_irqsave(&ctx->lock, flags); - trigger_value = ctx->commit_count + offset; - - spin_unlock_irqrestore(&ctx->lock, flags); - - fd = _dpu_fence_create_fd(ctx, trigger_value); - *val = fd; - DPU_DEBUG("fence_create::fd:%d trigger:%d commit:%d offset:%d\n", - fd, trigger_value, ctx->commit_count, offset); - - DPU_EVT32(ctx->drm_id, trigger_value, fd); - - if (fd >= 0) { - rc = 0; - _dpu_fence_trigger(ctx, ktime_get()); - } else { - rc = fd; - } - - return rc; -} - -void dpu_fence_signal(struct dpu_fence_context *ctx, ktime_t ts, - bool reset_timeline) -{ - unsigned long flags; - - if (!ctx) { - DPU_ERROR("invalid ctx, %pK\n", ctx); - return; - } - - spin_lock_irqsave(&ctx->lock, flags); - if (reset_timeline) { - if ((int)(ctx->done_count - ctx->commit_count) < 0) { - DPU_ERROR( - "timeline reset attempt! done count:%d commit:%d\n", - ctx->done_count, ctx->commit_count); - ctx->done_count = ctx->commit_count; - DPU_EVT32(ctx->drm_id, ctx->done_count, - ctx->commit_count, ktime_to_us(ts), - reset_timeline, DPU_EVTLOG_FATAL); - } else { - spin_unlock_irqrestore(&ctx->lock, flags); - return; - } - } else if ((int)(ctx->done_count - ctx->commit_count) < 0) { - ++ctx->done_count; - DPU_DEBUG("fence_signal:done count:%d commit count:%d\n", - ctx->done_count, ctx->commit_count); - } else { - DPU_ERROR("extra signal attempt! done count:%d commit:%d\n", - ctx->done_count, ctx->commit_count); - DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, - ktime_to_us(ts), reset_timeline, DPU_EVTLOG_FATAL); - spin_unlock_irqrestore(&ctx->lock, flags); - return; - } - spin_unlock_irqrestore(&ctx->lock, flags); - - DPU_EVT32(ctx->drm_id, ctx->done_count, ctx->commit_count, - ktime_to_us(ts)); - - _dpu_fence_trigger(ctx, ts); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h deleted file mode 100644 index f943046d96b8..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _DPU_FENCE_H_ -#define _DPU_FENCE_H_ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/mutex.h> - -#ifndef CHAR_BIT -#define CHAR_BIT 8 /* define this if limits.h not available */ -#endif - -#define DPU_FENCE_NAME_SIZE 24 - -/** - * struct dpu_fence_context - release/retire fence context/timeline structure - * @commit_count: Number of detected commits since bootup - * @done_count: Number of completed commits since bootup - * @drm_id: ID number of owning DRM Object - * @ref: kref counter on timeline - * @lock: spinlock for fence counter protection - * @list_lock: spinlock for timeline protection - * @context: fence context - * @list_head: fence list to hold all the fence created on this context - * @name: name of fence context/timeline - */ -struct dpu_fence_context { - unsigned int commit_count; - unsigned int done_count; - uint32_t drm_id; - struct kref kref; - spinlock_t lock; - spinlock_t list_lock; - u64 context; - struct list_head fence_list_head; - char name[DPU_FENCE_NAME_SIZE]; -}; - -#if IS_ENABLED(CONFIG_SYNC_FILE) -/** - * dpu_sync_get - Query sync fence object from a file handle - * - * On success, this function also increments the refcount of the sync fence - * - * @fd: Integer sync fence handle - * - * Return: Pointer to sync fence object, or NULL - */ -void *dpu_sync_get(uint64_t fd); - -/** - * dpu_sync_put - Releases a sync fence object acquired by @dpu_sync_get - * - * This function decrements the sync fence's reference count; the object will - * be released if the reference count goes to zero. - * - * @fence: Pointer to sync fence - */ -void dpu_sync_put(void *fence); - -/** - * dpu_sync_wait - Query sync fence object from a file handle - * - * @fence: Pointer to sync fence - * @timeout_ms: Time to wait, in milliseconds. Waits forever if timeout_ms < 0 - * - * Return: - * Zero if timed out - * -ERESTARTSYS if wait interrupted - * remaining jiffies in all other success cases. - */ -signed long dpu_sync_wait(void *fence, long timeout_ms); - -/** - * dpu_sync_get_name_prefix - get integer representation of fence name prefix - * @fence: Pointer to opaque fence structure - * - * Return: 32-bit integer containing first 4 characters of fence name, - * big-endian notation - */ -uint32_t dpu_sync_get_name_prefix(void *fence); - -/** - * dpu_fence_init - initialize fence object - * @fence: Pointer to crtc fence object - * @drm_id: ID number of owning DRM Object - * @name: Timeline name - * Returns: Zero on success - */ -int dpu_fence_init(struct dpu_fence_context *fence, - const char *name, - uint32_t drm_id); - -/** - * dpu_fence_deinit - deinit fence container - * @fence: Pointer fence container - */ -void dpu_fence_deinit(struct dpu_fence_context *fence); - -/** - * dpu_fence_prepare - prepare to return fences for current commit - * @fence: Pointer fence container - * Returns: Zero on success - */ -void dpu_fence_prepare(struct dpu_fence_context *fence); -/** - * dpu_fence_create - create output fence object - * @fence: Pointer fence container - * @val: Pointer to output value variable, fence fd will be placed here - * @offset: Fence signal commit offset, e.g., +1 to signal on next commit - * Returns: Zero on success - */ -int dpu_fence_create(struct dpu_fence_context *fence, uint64_t *val, - uint32_t offset); - -/** - * dpu_fence_signal - advance fence timeline to signal outstanding fences - * @fence: Pointer fence container - * @ts: fence timestamp - * @reset_timeline: reset the fence timeline to done count equal to commit count - */ -void dpu_fence_signal(struct dpu_fence_context *fence, ktime_t ts, - bool reset_timeline); -#else -static inline void *dpu_sync_get(uint64_t fd) -{ - return NULL; -} - -static inline void dpu_sync_put(void *fence) -{ -} - -static inline signed long dpu_sync_wait(void *fence, long timeout_ms) -{ - return 0; -} - -static inline uint32_t dpu_sync_get_name_prefix(void *fence) -{ - return 0x0; -} -static inline int dpu_fence_init(struct dpu_fence_context *fence, - const char *name, - uint32_t drm_id) -{ - /* do nothing */ - return 0; -} - -static inline void dpu_fence_deinit(struct dpu_fence_context *fence) -{ - /* do nothing */ -} - -static inline int dpu_fence_get(struct dpu_fence_context *fence, uint64_t *val) -{ - return -EINVAL; -} - -static inline void dpu_fence_signal(struct dpu_fence_context *fence, - ktime_t ts, bool reset_timeline) -{ - /* do nothing */ -} - -static inline void dpu_fence_prepare(struct dpu_fence_context *fence) -{ - /* do nothing */ -} - -static inline int dpu_fence_create(struct dpu_fence_context *fence, - uint64_t *val, uint32_t offset) -{ - return 0; -} -#endif /* IS_ENABLED(CONFIG_SW_SYNC) */ - -#endif /* _DPU_FENCE_H_ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 29e72b39fd72..610e616f2e74 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -27,7 +27,6 @@ #include "msm_drv.h" #include "dpu_kms.h" -#include "dpu_fence.h" #include "dpu_formats.h" #include "dpu_hw_sspp.h" #include "dpu_hw_catalog_format.h" @@ -676,26 +675,6 @@ static void _dpu_plane_set_ts_prefill(struct drm_plane *plane, pstate->multirect_index); } -/* helper to update a state's input fence pointer from the property */ -static void _dpu_plane_set_input_fence(struct dpu_plane *pdpu, - struct dpu_plane_state *pstate, uint64_t fd) -{ - if (!pdpu || !pstate) { - DPU_ERROR("invalid arg(s), plane %d state %d\n", - pdpu != 0, pstate != 0); - return; - } - - /* clear previous reference */ - if (pstate->input_fence) - dpu_sync_put(pstate->input_fence); - - /* get fence pointer for later */ - pstate->input_fence = dpu_sync_get(fd); - - DPU_DEBUG_PLANE(pdpu, "0x%llX\n", fd); -} - /** * _dpu_plane_inline_rot_set_ot_limit - set OT limit for the given inline * rotation xin client @@ -780,64 +759,6 @@ static void _dpu_plane_inline_rot_set_qos_remap(struct drm_plane *plane, dpu_vbif_set_qos_remap(dpu_kms, &qos_params); } -int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms) -{ - struct dpu_plane *pdpu; - struct dpu_plane_state *pstate; - uint32_t prefix; - void *input_fence; - int ret = -EINVAL; - signed long rc; - - if (!plane) { - DPU_ERROR("invalid plane\n"); - } else if (!plane->state) { - DPU_ERROR_PLANE(to_dpu_plane(plane), "invalid state\n"); - } else { - pdpu = to_dpu_plane(plane); - pstate = to_dpu_plane_state(plane->state); - input_fence = pstate->input_fence; - - if (input_fence) { - pdpu->is_error = false; - prefix = dpu_sync_get_name_prefix(input_fence); - rc = dpu_sync_wait(input_fence, wait_ms); - - switch (rc) { - case 0: - DPU_ERROR_PLANE(pdpu, "%ums timeout on %08X\n", - wait_ms, prefix); - pdpu->is_error = true; - ret = -ETIMEDOUT; - break; - case -ERESTARTSYS: - DPU_ERROR_PLANE(pdpu, - "%ums wait interrupted on %08X\n", - wait_ms, prefix); - pdpu->is_error = true; - ret = -ERESTARTSYS; - break; - case -EINVAL: - DPU_ERROR_PLANE(pdpu, - "invalid fence param for %08X\n", - prefix); - pdpu->is_error = true; - ret = -EINVAL; - break; - default: - DPU_DEBUG_PLANE(pdpu, "signaled\n"); - ret = 0; - break; - } - - DPU_EVT32_VERBOSE(DRMID(plane), -ret, prefix); - } else { - ret = 0; - } - } - return ret; -} - /** * _dpu_plane_get_aspace: gets the address space */ @@ -3332,7 +3253,6 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, break; case PLANE_PROP_INFO: case PLANE_PROP_ALPHA: - case PLANE_PROP_INPUT_FENCE: case PLANE_PROP_BLEND_OP: /* no special action required */ break; @@ -3703,10 +3623,6 @@ static void _dpu_plane_install_properties(struct drm_plane *plane, msm_property_install_range(&pdpu->property_info, "alpha", 0x0, 0, 255, 255, PLANE_PROP_ALPHA); - /* linux default file descriptor range on each process */ - msm_property_install_range(&pdpu->property_info, "input_fence", - 0x0, 0, INR_OPEN_MAX, 0, PLANE_PROP_INPUT_FENCE); - if (!master_plane_id) { if (pdpu->pipe_sblk->maxhdeciexp) { msm_property_install_range(&pdpu->property_info, @@ -4076,9 +3992,6 @@ static int dpu_plane_atomic_set_property(struct drm_plane *plane, idx = msm_property_index(&pdpu->property_info, property); switch (idx) { - case PLANE_PROP_INPUT_FENCE: - _dpu_plane_set_input_fence(pdpu, pstate, val); - break; case PLANE_PROP_CSC_V1: _dpu_plane_set_csc_v1(pdpu, (void *)val); break; @@ -4190,10 +4103,6 @@ static void dpu_plane_destroy_state(struct drm_plane *plane, if (state->fb) drm_framebuffer_put(state->fb); - /* remove ref count for fence */ - if (pstate->input_fence) - dpu_sync_put(pstate->input_fence); - /* destroy value helper */ msm_property_destroy_state(&pdpu->property_info, pstate, &pstate->property_state); @@ -4206,7 +4115,6 @@ dpu_plane_duplicate_state(struct drm_plane *plane) struct dpu_plane_state *pstate; struct dpu_plane_state *old_state; struct drm_property *drm_prop; - uint64_t input_fence_default; if (!plane) { DPU_ERROR("invalid plane\n"); @@ -4230,18 +4138,6 @@ dpu_plane_duplicate_state(struct drm_plane *plane) msm_property_duplicate_state(&pdpu->property_info, old_state, pstate, &pstate->property_state, pstate->property_values); - /* clear out any input fence */ - pstate->input_fence = 0; - input_fence_default = msm_property_get_default( - &pdpu->property_info, PLANE_PROP_INPUT_FENCE); - drm_prop = msm_property_index_to_drm_property( - &pdpu->property_info, PLANE_PROP_INPUT_FENCE); - if (msm_property_atomic_set(&pdpu->property_info, - &pstate->property_state, drm_prop, - input_fence_default)) - DPU_DEBUG_PLANE(pdpu, - "error clearing duplicated input fence\n"); - pstate->dirty = 0x0; pstate->pending = false; diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 657ea052a1ee..75a24b81c89a 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -99,7 +99,6 @@ enum msm_mdp_plane_property { PLANE_PROP_COLOR_FILL, PLANE_PROP_H_DECIMATE, PLANE_PROP_V_DECIMATE, - PLANE_PROP_INPUT_FENCE, PLANE_PROP_HUE_ADJUST, PLANE_PROP_SATURATION_ADJUST, PLANE_PROP_VALUE_ADJUST, @@ -131,8 +130,7 @@ enum msm_mdp_crtc_property { CRTC_PROP_BLOBCOUNT, /* range properties */ - CRTC_PROP_INPUT_FENCE_TIMEOUT = CRTC_PROP_BLOBCOUNT, - CRTC_PROP_DIM_LAYER_V1, + CRTC_PROP_DIM_LAYER_V1 = CRTC_PROP_BLOBCOUNT, CRTC_PROP_CORE_CLK, CRTC_PROP_CORE_AB, CRTC_PROP_CORE_IB,
These are already provided by drm atomic core. In conjunction with the output fences removed earlier, this obsoletes dpu_fence, and it can be entirely removed as well. Change-Id: Ida4924a09c455d7a84bfee569bd0d2fb436418de Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/msm/Makefile | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 84 ----- drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c | 404 ---------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h | 190 ---------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ------ drivers/gpu/drm/msm/msm_drv.h | 4 +- 6 files changed, 1 insertion(+), 786 deletions(-) delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.c delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_fence.h