drm/i915/overlay: Pass interruptible to switch_off()
During DPMS we currently do not want the overlay code to be interruptible, so pass that information down and only take the uninterrruptible paths. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
106dadacbe
commit
5dcdbcb06b
|
@ -2223,33 +2223,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||||
|
|
||||||
static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
|
static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
|
||||||
{
|
{
|
||||||
struct intel_overlay *overlay;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!enable && intel_crtc->overlay) {
|
if (!enable && intel_crtc->overlay) {
|
||||||
overlay = intel_crtc->overlay;
|
struct intel_overlay *overlay = intel_crtc->overlay;
|
||||||
mutex_lock(&overlay->dev->struct_mutex);
|
|
||||||
for (;;) {
|
|
||||||
ret = intel_overlay_switch_off(overlay);
|
|
||||||
if (ret == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ret = intel_overlay_recover_from_interrupt(overlay, 0);
|
mutex_lock(&overlay->dev->struct_mutex);
|
||||||
if (ret != 0) {
|
(void) intel_overlay_switch_off(overlay, false);
|
||||||
/* overlay doesn't react anymore. Usually
|
|
||||||
* results in a black screen and an unkillable
|
|
||||||
* X server. */
|
|
||||||
BUG();
|
|
||||||
overlay->hw_wedged = HW_WEDGED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mutex_unlock(&overlay->dev->struct_mutex);
|
mutex_unlock(&overlay->dev->struct_mutex);
|
||||||
}
|
}
|
||||||
/* Let userspace switch the overlay on again. In most cases userspace
|
|
||||||
* has to recompute where to put it anyway. */
|
|
||||||
|
|
||||||
return;
|
/* Let userspace switch the overlay on again. In most cases userspace
|
||||||
|
* has to recompute where to put it anyway.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
|
static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
|
||||||
|
|
|
@ -287,8 +287,7 @@ extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
|
||||||
|
|
||||||
extern void intel_setup_overlay(struct drm_device *dev);
|
extern void intel_setup_overlay(struct drm_device *dev);
|
||||||
extern void intel_cleanup_overlay(struct drm_device *dev);
|
extern void intel_cleanup_overlay(struct drm_device *dev);
|
||||||
extern int intel_overlay_switch_off(struct intel_overlay *overlay);
|
extern int intel_overlay_switch_off(struct intel_overlay *overlay,
|
||||||
extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
|
|
||||||
bool interruptible);
|
bool interruptible);
|
||||||
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
|
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file_priv);
|
struct drm_file *file_priv);
|
||||||
|
|
|
@ -365,7 +365,8 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* overlay needs to be disabled in OCMD reg */
|
/* overlay needs to be disabled in OCMD reg */
|
||||||
static int intel_overlay_off(struct intel_overlay *overlay)
|
static int intel_overlay_off(struct intel_overlay *overlay,
|
||||||
|
bool interruptible)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = overlay->dev;
|
struct drm_device *dev = overlay->dev;
|
||||||
u32 flip_addr = overlay->flip_addr;
|
u32 flip_addr = overlay->flip_addr;
|
||||||
|
@ -394,7 +395,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
||||||
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
|
||||||
ADVANCE_LP_RING();
|
ADVANCE_LP_RING();
|
||||||
|
|
||||||
return intel_overlay_do_wait_request(overlay, request, true,
|
return intel_overlay_do_wait_request(overlay, request, interruptible,
|
||||||
SWITCH_OFF);
|
SWITCH_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +428,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
|
||||||
|
|
||||||
/* recover from an interruption due to a signal
|
/* recover from an interruption due to a signal
|
||||||
* We have to be careful not to repeat work forever an make forward progess. */
|
* We have to be careful not to repeat work forever an make forward progess. */
|
||||||
int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
|
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
|
||||||
bool interruptible)
|
bool interruptible)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = overlay->dev;
|
struct drm_device *dev = overlay->dev;
|
||||||
|
@ -855,17 +856,19 @@ out_unpin:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int intel_overlay_switch_off(struct intel_overlay *overlay)
|
int intel_overlay_switch_off(struct intel_overlay *overlay,
|
||||||
|
bool interruptible)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct overlay_registers *regs;
|
struct overlay_registers *regs;
|
||||||
struct drm_device *dev = overlay->dev;
|
struct drm_device *dev = overlay->dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
|
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
|
||||||
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
||||||
|
|
||||||
if (overlay->hw_wedged) {
|
if (overlay->hw_wedged) {
|
||||||
ret = intel_overlay_recover_from_interrupt(overlay, 1);
|
ret = intel_overlay_recover_from_interrupt(overlay,
|
||||||
|
interruptible);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -881,7 +884,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
|
||||||
regs->OCMD = 0;
|
regs->OCMD = 0;
|
||||||
intel_overlay_unmap_regs(overlay, regs);
|
intel_overlay_unmap_regs(overlay, regs);
|
||||||
|
|
||||||
ret = intel_overlay_off(overlay);
|
ret = intel_overlay_off(overlay, interruptible);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1097,7 +1100,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||||
mutex_lock(&dev->mode_config.mutex);
|
mutex_lock(&dev->mode_config.mutex);
|
||||||
mutex_lock(&dev->struct_mutex);
|
mutex_lock(&dev->struct_mutex);
|
||||||
|
|
||||||
ret = intel_overlay_switch_off(overlay);
|
ret = intel_overlay_switch_off(overlay, true);
|
||||||
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
mutex_unlock(&dev->mode_config.mutex);
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
@ -1135,7 +1138,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
|
||||||
|
|
||||||
if (overlay->crtc != crtc) {
|
if (overlay->crtc != crtc) {
|
||||||
struct drm_display_mode *mode = &crtc->base.mode;
|
struct drm_display_mode *mode = &crtc->base.mode;
|
||||||
ret = intel_overlay_switch_off(overlay);
|
ret = intel_overlay_switch_off(overlay, true);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue