Partially restore the handling of the GPU load history. Accumulate the
busy_time and and total_time measured in active state during the polling
period. This results in slightly smoother picture of the GPU frequencies
(measured on the a530/msm8996, using kmscube in different resolutions).

A call to msm_devfreq_get_dev_status() from msm_devfreq_active() was
removed in 69f06a5d854f ("drm/msm: remove explicit devfreq status
reset"), because dev_pm_qos_update_request() triggered that internally.
As the commit fadcc3ab1302 ("drm/msm/gpu: Bypass PM QoS constraint for
idle clamp") removed the calls to dev_pm_qos_update_request(), this
removal was also reverted.

The code doesn't take the frequency into account while accumulating the
data to keep the code simple for the RFC.

Cc: Chia-I Wu <olva...@gmail.com>
Signed-off-by: Dmitry Baryshkov <dmitry.barysh...@linaro.org>
---
 drivers/gpu/drm/msm/msm_gpu.h         |  3 +++
 drivers/gpu/drm/msm/msm_gpu_devfreq.c | 30 ++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index fc1c0d8611a8..9d1783375dcc 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -156,6 +156,9 @@ struct msm_gpu_devfreq {
 
        /** suspended: tracks if we're suspended */
        bool suspended;
+
+       /* stats for the current period */
+       struct devfreq_dev_status status;
 };
 
 struct msm_gpu {
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c 
b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
index e27dbf12b5e8..92cb022c8628 100644
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -74,7 +74,7 @@ static unsigned long get_freq(struct msm_gpu *gpu)
        return clk_get_rate(gpu->core_clk);
 }
 
-static int msm_devfreq_get_dev_status(struct device *dev,
+static int msm_devfreq_get_dev_status_int(struct device *dev,
                struct devfreq_dev_status *status)
 {
        struct msm_gpu *gpu = dev_to_gpu(dev);
@@ -112,6 +112,22 @@ static int msm_devfreq_get_dev_status(struct device *dev,
        return 0;
 }
 
+static int msm_devfreq_get_dev_status(struct device *dev,
+               struct devfreq_dev_status *status)
+{
+       struct msm_gpu *gpu = dev_to_gpu(dev);
+       struct msm_gpu_devfreq *df = &gpu->devfreq;
+
+       msm_devfreq_get_dev_status_int(&gpu->pdev->dev, status);
+       status->busy_time += df->status.busy_time;
+       status->total_time += df->status.total_time;
+
+       df->status.busy_time = 0;
+       df->status.total_time = 0;
+
+       return 0;
+}
+
 static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
 {
        *freq = get_freq(dev_to_gpu(dev));
@@ -290,6 +306,7 @@ void msm_devfreq_active(struct msm_gpu *gpu)
        struct msm_gpu_devfreq *df = &gpu->devfreq;
        unsigned int idle_time;
        unsigned long target_freq;
+       struct devfreq_dev_status status;
 
        if (!has_devfreq(gpu))
                return;
@@ -319,6 +336,12 @@ void msm_devfreq_active(struct msm_gpu *gpu)
        if (target_freq)
                msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
 
+       /*
+        * Reset the polling interval so we aren't inconsistent
+        * about freq vs busy/total cycles
+        */
+       msm_devfreq_get_dev_status_int(&gpu->pdev->dev, &status);
+
        mutex_unlock(&df->devfreq->lock);
 
        /*
@@ -339,6 +362,7 @@ static void msm_devfreq_idle_work(struct kthread_work *work)
        struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
        struct msm_drm_private *priv = gpu->dev->dev_private;
        unsigned long idle_freq, target_freq = 0;
+       struct devfreq_dev_status status;
 
        /*
         * Hold devfreq lock to synchronize with get_dev_status()/
@@ -346,6 +370,10 @@ static void msm_devfreq_idle_work(struct kthread_work 
*work)
         */
        mutex_lock(&df->devfreq->lock);
 
+       msm_devfreq_get_dev_status_int(&gpu->pdev->dev, &status);
+       df->status.busy_time += status.busy_time;
+       df->status.total_time += status.total_time;
+
        idle_freq = get_freq(gpu);
 
        if (priv->gpu_clamp_to_idle)
-- 
2.30.2

Reply via email to