mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	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: Heiko Stuebner <heiko@sntech.de> Reviewed-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190611160844.257498-11-sean@poorly.run
This commit is contained in:
		
							parent
							
								
									2b60e11d0b
								
							
						
					
					
						commit
						bed030a49f
					
				
					 1 changed files with 36 additions and 5 deletions
				
			
		|  | @ -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); | ||||||
| 
 | 
 | ||||||
|  | 	if (crtc->state->self_refresh_active) | ||||||
|  | 		rockchip_drm_set_win_enabled(crtc, false); | ||||||
|  | 
 | ||||||
| 	mutex_lock(&vop->vop_lock); | 	mutex_lock(&vop->vop_lock); | ||||||
| 
 | 
 | ||||||
| 	if (!vop->is_enabled) { |  | ||||||
| 		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); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Sean Paul
						Sean Paul