Skip to content

Commit

Permalink
drm/i915/overlay: Pass interruptible to switch_off()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chris Wilson committed Sep 8, 2010
1 parent 106dada commit 5dcdbcb
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 35 deletions.
28 changes: 6 additions & 22 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct intel_overlay *overlay;
int ret;

if (!enable && intel_crtc->overlay) {
overlay = intel_crtc->overlay;
mutex_lock(&overlay->dev->struct_mutex);
for (;;) {
ret = intel_overlay_switch_off(overlay);
if (ret == 0)
break;
struct intel_overlay *overlay = intel_crtc->overlay;

ret = intel_overlay_recover_from_interrupt(overlay, 0);
if (ret != 0) {
/* overlay doesn't react anymore. Usually
* results in a black screen and an unkillable
* X server. */
BUG();
overlay->hw_wedged = HW_WEDGED;
break;
}
}
mutex_lock(&overlay->dev->struct_mutex);
(void) intel_overlay_switch_off(overlay, false);
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)
Expand Down
5 changes: 2 additions & 3 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,8 @@ 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_cleanup_overlay(struct drm_device *dev);
extern int intel_overlay_switch_off(struct intel_overlay *overlay);
extern int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
bool interruptible);
extern int intel_overlay_switch_off(struct intel_overlay *overlay,
bool interruptible);
extern int intel_overlay_put_image(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int intel_overlay_attrs(struct drm_device *dev, void *data,
Expand Down
23 changes: 13 additions & 10 deletions drivers/gpu/drm/i915/intel_overlay.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,8 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
}

/* 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;
u32 flip_addr = overlay->flip_addr;
Expand Down Expand Up @@ -394,7 +395,7 @@ static int intel_overlay_off(struct intel_overlay *overlay)
OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
ADVANCE_LP_RING();

return intel_overlay_do_wait_request(overlay, request, true,
return intel_overlay_do_wait_request(overlay, request, interruptible,
SWITCH_OFF);
}

Expand Down Expand Up @@ -427,8 +428,8 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)

/* recover from an interruption due to a signal
* We have to be careful not to repeat work forever an make forward progess. */
int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
bool interruptible)
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
bool interruptible)
{
struct drm_device *dev = overlay->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -855,17 +856,19 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
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 drm_device *dev = overlay->dev;
int ret;

BUG_ON(!mutex_is_locked(&dev->struct_mutex));
BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));

if (overlay->hw_wedged) {
ret = intel_overlay_recover_from_interrupt(overlay, 1);
ret = intel_overlay_recover_from_interrupt(overlay,
interruptible);
if (ret != 0)
return ret;
}
Expand All @@ -881,7 +884,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
regs->OCMD = 0;
intel_overlay_unmap_regs(overlay, regs);

ret = intel_overlay_off(overlay);
ret = intel_overlay_off(overlay, interruptible);
if (ret != 0)
return ret;

Expand Down Expand Up @@ -1097,7 +1100,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
mutex_lock(&dev->mode_config.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->mode_config.mutex);
Expand Down Expand Up @@ -1135,7 +1138,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,

if (overlay->crtc != crtc) {
struct drm_display_mode *mode = &crtc->base.mode;
ret = intel_overlay_switch_off(overlay);
ret = intel_overlay_switch_off(overlay, true);
if (ret != 0)
goto out_unlock;

Expand Down

0 comments on commit 5dcdbcb

Please sign in to comment.