From: hyesoo.yu Date: Fri, 18 Aug 2017 02:21:56 +0000 (+0900) Subject: [COMMON] g2d: release performance lock X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=05cbcbce918d136a6be42931c8c51b08909e31ae;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] g2d: release performance lock If there is no further request from the user for 50ms, performance lock is released automatically. Change-Id: If1548cf253d74fbf2ea5034077989d8072cbfd23 Signed-off-by: hyesoo.yu --- diff --git a/drivers/gpu/exynos/g2d/g2d.h b/drivers/gpu/exynos/g2d/g2d.h index 50bf4b2db70f..4bf2a1e3c98b 100644 --- a/drivers/gpu/exynos/g2d/g2d.h +++ b/drivers/gpu/exynos/g2d/g2d.h @@ -126,8 +126,9 @@ struct g2d_context { u32 priority; int authority; - struct pm_qos_request req; + struct delayed_work dwork; + struct pm_qos_request req; struct list_head qos_node; u64 r_bw; u64 w_bw; diff --git a/drivers/gpu/exynos/g2d/g2d_drv.c b/drivers/gpu/exynos/g2d/g2d_drv.c index 5ef0fabb5209..3921e3200d56 100644 --- a/drivers/gpu/exynos/g2d/g2d_drv.c +++ b/drivers/gpu/exynos/g2d/g2d_drv.c @@ -235,6 +235,14 @@ static __u32 get_hw_version(struct g2d_device *g2d_dev, __u32 *version) return ret; } +static void g2d_timeout_perf_work(struct work_struct *work) +{ + struct g2d_context *ctx = container_of(work, struct g2d_context, + dwork.work); + + g2d_put_performance(ctx); +} + static int g2d_open(struct inode *inode, struct file *filp) { struct g2d_device *g2d_dev; @@ -260,6 +268,7 @@ static int g2d_open(struct inode *inode, struct file *filp) atomic_inc(&g2d_dev->prior_stats[g2d_ctx->priority]); INIT_LIST_HEAD(&g2d_ctx->qos_node); + INIT_DELAYED_WORK(&(g2d_ctx->dwork), g2d_timeout_perf_work); return 0; } diff --git a/drivers/gpu/exynos/g2d/g2d_perf.c b/drivers/gpu/exynos/g2d/g2d_perf.c index 1d409afb8934..cd376fdea73d 100644 --- a/drivers/gpu/exynos/g2d/g2d_perf.c +++ b/drivers/gpu/exynos/g2d/g2d_perf.c @@ -20,6 +20,8 @@ #include "g2d_task.h" #include "g2d_uapi.h" +#include + #ifdef CONFIG_PM_DEVFREQ static void g2d_pm_qos_update_devfreq(struct pm_qos_request *req, u32 freq) { @@ -149,7 +151,7 @@ static void g2d_set_device_frequency(struct g2d_context *g2d_ctx, } } - if (!ip_clock && !g2d_still_need_perf(g2d_dev)) + if (!ip_clock) g2d_pm_qos_remove_devfreq(&g2d_ctx->req); else if (ip_clock) g2d_pm_qos_update_devfreq(&g2d_ctx->req, ip_clock); @@ -179,11 +181,6 @@ static void g2d_set_qos_frequency(struct g2d_context *g2d_ctx, if (list_empty(&g2d_ctx->qos_node) && !rbw && !wbw) return; - if (!rbw && !rbw && g2d_still_need_perf(g2d_dev)) - return; - - mutex_lock(&g2d_dev->lock_qos); - if (!list_empty(&g2d_dev->qos_contexts)) { struct g2d_context *ctx_qos; @@ -238,13 +235,12 @@ static void g2d_set_qos_frequency(struct g2d_context *g2d_ctx, * bts_update_bw(BTS_BW_G2D, bw); */ } - - mutex_unlock(&g2d_dev->lock_qos); } void g2d_set_performance(struct g2d_context *ctx, struct g2d_performance_data *data) { + struct g2d_device *g2d_dev = ctx->g2d_dev; int i; if (data->num_frame > G2D_PERF_MAX_FRAMES) @@ -255,8 +251,23 @@ void g2d_set_performance(struct g2d_context *ctx, return; } + mutex_lock(&g2d_dev->lock_qos); + + if (!data->num_frame) { + if (g2d_still_need_perf(g2d_dev)) { + mutex_unlock(&g2d_dev->lock_qos); + return; + } + cancel_delayed_work(&ctx->dwork); + } else { + mod_delayed_work(system_wq, &ctx->dwork, + msecs_to_jiffies(50)); + } + g2d_set_qos_frequency(ctx, data); g2d_set_device_frequency(ctx, data); + + mutex_unlock(&g2d_dev->lock_qos); } void g2d_put_performance(struct g2d_context *ctx)