From: Sean Paul <seanp...@chromium.org>

Instead of fully disabling and re-enabling the vop on self refresh
transitions, only disable the active windows. This will speed up
self refresh exits substantially and is still a power-savings win.

This patch integrates portions of Zain's patch from here:
https://patchwork.kernel.org/patch/9615063/

Changes in v2:
- None
Changes in v3:
- None
Changes in v4:
- Adjust for preceding vop_win_disable changes

Link to v1: 
https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-5-s...@poorly.run
Link to v2: 
https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-4-s...@poorly.run
Link to v3: 
https://patchwork.freedesktop.org/patch/msgid/20190502194956.218441-10-s...@poorly.run

Cc: Zain Wang <w...@rock-chips.com>
Cc: Tomasz Figa <tf...@chromium.org>
Cc: Kristian H. Kristensen <hoegsb...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 41 ++++++++++++++++++---
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 15a5b44eb7e7..acdc86a9144b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -134,6 +134,7 @@ struct vop {
        bool is_enabled;
 
        struct completion dsp_hold_completion;
+       unsigned int win_enabled;
 
        /* protected by dev->event_lock */
        struct drm_pending_vblank_event *event;
@@ -555,6 +556,7 @@ static void vop_win_disable(struct vop *vop, const struct 
vop_win *vop_win)
        }
 
        VOP_WIN_SET(vop, win, enable, 0);
+       vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
 }
 
 static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
@@ -637,6 +639,25 @@ static int vop_enable(struct drm_crtc *crtc, struct 
drm_crtc_state *old_state)
        return ret;
 }
 
+static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
+{
+        struct vop *vop = to_vop(crtc);
+        int i;
+
+        spin_lock(&vop->reg_lock);
+
+        for (i = 0; i < vop->data->win_size; i++) {
+                struct vop_win *vop_win = &vop->win[i];
+                const struct vop_win_data *win = vop_win->data;
+
+                VOP_WIN_SET(vop, win, enable,
+                            enabled && (vop->win_enabled & BIT(i)));
+        }
+        vop_cfg_done(vop);
+
+        spin_unlock(&vop->reg_lock);
+}
+
 static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
                                    struct drm_crtc_state *old_state)
 {
@@ -644,15 +665,16 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
 
        WARN_ON(vop->event);
 
-       mutex_lock(&vop->vop_lock);
+       if (crtc->state->self_refresh_active)
+               rockchip_drm_set_win_enabled(crtc, false);
 
-       if (!vop->is_enabled) {
-               mutex_unlock(&vop->vop_lock);
-               return;
-       }
+       mutex_lock(&vop->vop_lock);
 
        drm_crtc_vblank_off(crtc);
 
+       if (crtc->state->self_refresh_active)
+               goto out;
+
        /*
         * Vop standby will take effect at end of current frame,
         * if dsp hold valid irq happen, it means standby complete.
@@ -683,6 +705,8 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
        clk_disable(vop->dclk);
        vop_core_clks_disable(vop);
        pm_runtime_put(vop->dev);
+
+out:
        mutex_unlock(&vop->vop_lock);
 
        if (crtc->state->event && !crtc->state->active) {
@@ -900,6 +924,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
        }
 
        VOP_WIN_SET(vop, win, enable, 1);
+       vop->win_enabled |= BIT(win_index);
        spin_unlock(&vop->reg_lock);
 }
 
@@ -1056,6 +1081,12 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
        int dither_bpc = s->output_bpc ? s->output_bpc : 10;
        int ret;
 
+       if (old_state && old_state->self_refresh_active) {
+               drm_crtc_vblank_on(crtc);
+               rockchip_drm_set_win_enabled(crtc, true);
+               return;
+       }
+
        mutex_lock(&vop->vop_lock);
 
        WARN_ON(vop->event);
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to