From 64bb34be977ed9a2dc244d54bdcc0a2f91c649bc Mon Sep 17 00:00:00 2001 From: "hyesoo.yu" Date: Fri, 18 Aug 2017 11:21:56 +0900 Subject: [PATCH] [COMMON] g2d: release performance lock If there is no further request from the user for 50ms, performance lock is released automatically. Change-Id: Id36220bbe6eecd45c716fd1c83f3e12f523c3f82 Signed-off-by: hyesoo.yu --- drivers/gpu/exynos/g2d/g2d.h | 3 ++- drivers/gpu/exynos/g2d/g2d_drv.c | 9 +++++++++ drivers/gpu/exynos/g2d/g2d_perf.c | 27 +++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/exynos/g2d/g2d.h b/drivers/gpu/exynos/g2d/g2d.h index f2ba826e0b04..afb69d2820ae 100644 --- a/drivers/gpu/exynos/g2d/g2d.h +++ b/drivers/gpu/exynos/g2d/g2d.h @@ -118,8 +118,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 f7da2d4481bf..6b03d1bd3e77 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 d18ae4e40153..b60ed1160bf0 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) -- 2.20.1