Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bed030a4 authored by Sean Paul's avatar Sean Paul
Browse files

drm/rockchip: Don't fully disable vop on self refresh

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
Changes in v5:
- None

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



Cc: Zain Wang <wzz@rock-chips.com>
Cc: Tomasz Figa <tfiga@chromium.org>
Cc: Kristian H. Kristensen <hoegsberg@chromium.org>
Tested-by: default avatarHeiko Stuebner <heiko@sntech.de>
Reviewed-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190611160844.257498-11-sean@poorly.run
parent 2b60e11d
Loading
Loading
Loading
Loading
+36 −5
Original line number Original line Diff line number Diff line
@@ -127,6 +127,7 @@ struct vop {
	bool is_enabled;
	bool is_enabled;


	struct completion dsp_hold_completion;
	struct completion dsp_hold_completion;
	unsigned int win_enabled;


	/* protected by dev->event_lock */
	/* protected by dev->event_lock */
	struct drm_pending_vblank_event *event;
	struct drm_pending_vblank_event *event;
@@ -543,6 +544,7 @@ static void vop_win_disable(struct vop *vop, const struct vop_win *vop_win)
	}
	}


	VOP_WIN_SET(vop, win, enable, 0);
	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)
static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
@@ -625,6 +627,25 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
	return ret;
	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,
static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
				    struct drm_crtc_state *old_state)
				    struct drm_crtc_state *old_state)
{
{
@@ -632,15 +653,16 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,


	WARN_ON(vop->event);
	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_lock(&vop->vop_lock);
		mutex_unlock(&vop->vop_lock);
		return;
	}


	drm_crtc_vblank_off(crtc);
	drm_crtc_vblank_off(crtc);


	if (crtc->state->self_refresh_active)
		goto out;

	/*
	/*
	 * Vop standby will take effect at end of current frame,
	 * Vop standby will take effect at end of current frame,
	 * if dsp hold valid irq happen, it means standby complete.
	 * if dsp hold valid irq happen, it means standby complete.
@@ -671,6 +693,8 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
	clk_disable(vop->dclk);
	clk_disable(vop->dclk);
	vop_core_clks_disable(vop);
	vop_core_clks_disable(vop);
	pm_runtime_put(vop->dev);
	pm_runtime_put(vop->dev);

out:
	mutex_unlock(&vop->vop_lock);
	mutex_unlock(&vop->vop_lock);


	if (crtc->state->event && !crtc->state->active) {
	if (crtc->state->event && !crtc->state->active) {
@@ -888,6 +912,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
	}
	}


	VOP_WIN_SET(vop, win, enable, 1);
	VOP_WIN_SET(vop, win, enable, 1);
	vop->win_enabled |= BIT(win_index);
	spin_unlock(&vop->reg_lock);
	spin_unlock(&vop->reg_lock);
}
}


@@ -1046,6 +1071,12 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
	int dither_bpc = s->output_bpc ? s->output_bpc : 10;
	int dither_bpc = s->output_bpc ? s->output_bpc : 10;
	int ret;
	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);
	mutex_lock(&vop->vop_lock);


	WARN_ON(vop->event);
	WARN_ON(vop->event);