diff options
author | Alan Cox <alan@linux.intel.com> | 2011-07-05 14:34:28 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-07-05 15:20:37 (GMT) |
commit | 3cc76c1c69d6520837e2c6f21f4653df91c6cb77 (patch) | |
tree | 0cd9559edd7c932590996bcdedd68a1520771ec3 /drivers/staging/gma500/psb_intel_display.c | |
parent | daab23f1f52bba4701f58b79855f1ad0cf523dca (diff) | |
download | linux-fsl-qoriq-3cc76c1c69d6520837e2c6f21f4653df91c6cb77.tar.xz |
gma500: Do sane FB cleanup
If we get a user frame buffer destroyed which is being displayed then clean
up the mess nicely. We can now run a slightly modified modetest including setting
modes, and handling crashes.
Modetest still blows up but this is because libdrm 2.4.25 is busted.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/gma500/psb_intel_display.c')
-rw-r--r-- | drivers/staging/gma500/psb_intel_display.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index a99271d..c7c55b1 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -352,15 +352,15 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, PSB_DEBUG_ENTRY("\n"); + if (!gma_power_begin(dev, true)) + return 0; + /* no fb bound */ if (!crtc->fb) { DRM_DEBUG("No FB bound\n"); - return 0; + goto psb_intel_pipe_cleaner; } - if (!gma_power_begin(dev, true)) - return 0; - /* We are displaying this buffer, make sure it is actually loaded into the GTT */ ret = psb_gtt_pin(psbfb->gtt); @@ -409,6 +409,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, REG_READ(dspbase); } +psb_intel_pipe_cleaner: /* If there was a previous display we can now unpin it */ if (old_fb) psb_gtt_unpin(to_psb_fb(old_fb)->gtt); @@ -588,6 +589,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; int pipe = psb_intel_crtc->pipe; int fp_reg = (pipe == 0) ? FPA0 : FPB0; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; @@ -610,6 +612,12 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; + /* No scan out no play */ + if (crtc->fb == NULL) { + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + return 0; + } + list_for_each_entry(connector, &mode_config->connector_list, head) { struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector); @@ -786,11 +794,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, REG_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } + crtc_funcs->mode_set_base(crtc, x, y, old_fb); psb_intel_wait_for_vblank(dev); |