diff options
| author | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 11:52:34 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2018-07-30 11:52:34 +0100 | 
| commit | 34e25ed60ae2cdf91b953dd3772ae48a6bffbd4c (patch) | |
| tree | 0f189cdd71e7ae4d166ee706bd092bcd2ec9235d /drivers/gpu/drm/armada | |
| parent | a0f75d2468fe4510bb8d0d6c4e1a5fd5e262e7b5 (diff) | |
| download | linux-34e25ed60ae2cdf91b953dd3772ae48a6bffbd4c.tar.bz2 | |
drm/armada: implement atomic_enable()/atomic_disable() methods
Implement the atomic_enable()/atomic_disable() methods used by the
atomic modeset helpers.  atomic_disable() will need some transitional
code during conversion to ensure proper ordering is maintained.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'drivers/gpu/drm/armada')
| -rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 71 | 
1 files changed, 71 insertions, 0 deletions
| diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 554135062d93..e93097d3aa06 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -581,6 +581,75 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc,  		armada_drm_crtc_queue_state_event(crtc);  } +static void armada_drm_crtc_atomic_disable(struct drm_crtc *crtc, +					   struct drm_crtc_state *old_state) +{ +	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); +	struct drm_pending_vblank_event *event; +	struct drm_plane *plane; + +	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); + +	/* +	 * For transition only - we must wait for completion of our +	 * untransitioned paths before changing anything. +	 */ +	plane = dcrtc->plane; +	if (plane) +		WARN_ON(!armada_drm_plane_work_wait(drm_to_armada_plane(plane), +						    HZ)); +	armada_drm_plane_work_wait(drm_to_armada_plane(dcrtc->crtc.primary), +				   MAX_SCHEDULE_TIMEOUT); + +	dcrtc->dpms = DRM_MODE_DPMS_OFF; +	drm_crtc_vblank_off(crtc); +	armada_drm_crtc_update(dcrtc, false); + +	if (!crtc->state->active) { +		/* +		 * This modeset will be leaving the CRTC disabled, so +		 * call the backend to disable upstream clocks etc. +		 */ +		if (dcrtc->variant->disable) +			dcrtc->variant->disable(dcrtc); + +		/* +		 * We will not receive any further vblank events. +		 * Send the flip_done event manually. +		 */ +		event = crtc->state->event; +		crtc->state->event = NULL; +		if (event) { +			spin_lock_irq(&crtc->dev->event_lock); +			drm_crtc_send_vblank_event(crtc, event); +			spin_unlock_irq(&crtc->dev->event_lock); +		} +	} +} + +static void armada_drm_crtc_atomic_enable(struct drm_crtc *crtc, +					  struct drm_crtc_state *old_state) +{ +	struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); + +	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); + +	dcrtc->dpms = DRM_MODE_DPMS_ON; +	if (!old_state->active) { +		/* +		 * This modeset is enabling the CRTC after it having +		 * been disabled.  Reverse the call to ->disable in +		 * the atomic_disable(). +		 */ +		if (dcrtc->variant->enable) +			dcrtc->variant->enable(dcrtc, &crtc->state->adjusted_mode); +	} +	armada_drm_crtc_update(dcrtc, true); +	drm_crtc_vblank_on(crtc); + +	armada_drm_crtc_queue_state_event(crtc); +} +  static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {  	.dpms		= armada_drm_crtc_dpms,  	.prepare	= armada_drm_crtc_prepare, @@ -592,6 +661,8 @@ static const struct drm_crtc_helper_funcs armada_crtc_helper_funcs = {  	.disable	= armada_drm_crtc_disable,  	.atomic_begin	= armada_drm_crtc_atomic_begin,  	.atomic_flush	= armada_drm_crtc_atomic_flush, +	.atomic_disable	= armada_drm_crtc_atomic_disable, +	.atomic_enable	= armada_drm_crtc_atomic_enable,  };  static void armada_load_cursor_argb(void __iomem *base, uint32_t *pix, |