Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2012 19:58:30 +0000 (11:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Feb 2012 19:58:30 +0000 (11:58 -0800)
Intel, radeon, exynos fixes.

Intel: fixes a few Ivybridge hangs, along with fixing RC6 on SNB (still
not on, but at least allows for distros to patch it on easily).

radeon: oops reading some files in debugfs that weren't meant to appear,
a fix that touches a lot of files, so looks worse than it is, it fixes
an oops if a GPU reset fails and userspace keeps submitting more data,
along with a minor BIOS fix for newer boards.

exynos: a group of fixes for exynos, they've sent me a few more but
these were all I got through, and its no hw vanilla kernel users see a
lot off yet.

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/kms/atom: dpms bios scratch reg updates
  drm/radeon/kms: properly set accel working flag and bailout when false
  drm/radeon: Only create additional ring debugfs files on Cayman or newer.
  drm/exynos: added postclose to release resource.
  drm/exynos: removed exynos_drm_fbdev_recreate function.
  drm/exynos: fixed page flip issue.
  drm/exynos: added possible_clones setup function.
  drm/exynos: removed pageflip_event_list init code when closed.
  drm/exynos: changed priority of mixer layers.
  drm/exynos: Fix typo in exynos_mixer.c
  drm/i915: do not enable RC6p on Sandy Bridge
  drm/i915: gen7: Disable the RHWO optimization as it can cause GPU hangs.
  drm/i915: gen7: work around a system hang on IVB
  drm/i915: gen7: Implement an L3 caching workaround.
  drm/i915: gen7: implement rczunit workaround

25 files changed:
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/exynos/exynos_drm_encoder.c
drivers/gpu/drm/exynos/exynos_drm_encoder.h
drivers/gpu/drm/exynos/exynos_drm_fbdev.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_cs.c
drivers/gpu/drm/radeon/radeon_ring.c
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/drm/radeon/rv770.c

index 661a035..d08a558 100644 (file)
@@ -193,6 +193,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
                        return err;
                }
 
+               /* setup possible_clones. */
+               exynos_drm_encoder_setup(drm_dev);
+
                /*
                 * if any specific driver such as fimd or hdmi driver called
                 * exynos_drm_subdrv_register() later than drm_load(),
index e3861ac..de81883 100644 (file)
@@ -307,9 +307,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                 */
                event->pipe = exynos_crtc->pipe;
 
-               list_add_tail(&event->base.link,
-                               &dev_priv->pageflip_event_list);
-
                ret = drm_vblank_get(dev, exynos_crtc->pipe);
                if (ret) {
                        DRM_DEBUG("failed to acquire vblank counter\n");
@@ -318,6 +315,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
                        goto out;
                }
 
+               list_add_tail(&event->base.link,
+                               &dev_priv->pageflip_event_list);
+
                crtc->fb = fb;
                ret = exynos_drm_crtc_update(crtc);
                if (ret) {
index 35889ca..58820eb 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_crtc.h"
+#include "exynos_drm_encoder.h"
 #include "exynos_drm_fbdev.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_gem.h"
@@ -99,6 +100,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
        if (ret)
                goto err_vblank;
 
+       /* setup possible_clones. */
+       exynos_drm_encoder_setup(dev);
+
        /*
         * create and configure fb helper and also exynos specific
         * fbdev object.
@@ -141,16 +145,21 @@ static int exynos_drm_unload(struct drm_device *dev)
 }
 
 static void exynos_drm_preclose(struct drm_device *dev,
-                                       struct drm_file *file_priv)
+                                       struct drm_file *file)
 {
-       struct exynos_drm_private *dev_priv = dev->dev_private;
+       DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
-       /*
-        * drm framework frees all events at release time,
-        * so private event list should be cleared.
-        */
-       if (!list_empty(&dev_priv->pageflip_event_list))
-               INIT_LIST_HEAD(&dev_priv->pageflip_event_list);
+}
+
+static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+{
+       DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+       if (!file->driver_priv)
+               return;
+
+       kfree(file->driver_priv);
+       file->driver_priv = NULL;
 }
 
 static void exynos_drm_lastclose(struct drm_device *dev)
@@ -195,6 +204,7 @@ static struct drm_driver exynos_drm_driver = {
        .unload                 = exynos_drm_unload,
        .preclose               = exynos_drm_preclose,
        .lastclose              = exynos_drm_lastclose,
+       .postclose              = exynos_drm_postclose,
        .get_vblank_counter     = drm_vblank_count,
        .enable_vblank          = exynos_drm_crtc_enable_vblank,
        .disable_vblank         = exynos_drm_crtc_disable_vblank,
index 86b93dd..ef4754f 100644 (file)
@@ -195,6 +195,40 @@ static struct drm_encoder_funcs exynos_encoder_funcs = {
        .destroy = exynos_drm_encoder_destroy,
 };
 
+static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
+{
+       struct drm_encoder *clone;
+       struct drm_device *dev = encoder->dev;
+       struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
+       struct exynos_drm_display_ops *display_ops =
+                               exynos_encoder->manager->display_ops;
+       unsigned int clone_mask = 0;
+       int cnt = 0;
+
+       list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
+               switch (display_ops->type) {
+               case EXYNOS_DISPLAY_TYPE_LCD:
+               case EXYNOS_DISPLAY_TYPE_HDMI:
+                       clone_mask |= (1 << (cnt++));
+                       break;
+               default:
+                       continue;
+               }
+       }
+
+       return clone_mask;
+}
+
+void exynos_drm_encoder_setup(struct drm_device *dev)
+{
+       struct drm_encoder *encoder;
+
+       DRM_DEBUG_KMS("%s\n", __FILE__);
+
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+               encoder->possible_clones = exynos_drm_encoder_clones(encoder);
+}
+
 struct drm_encoder *
 exynos_drm_encoder_create(struct drm_device *dev,
                           struct exynos_drm_manager *manager,
index 97b087a..eb7d231 100644 (file)
@@ -30,6 +30,7 @@
 
 struct exynos_drm_manager;
 
+void exynos_drm_encoder_setup(struct drm_device *dev);
 struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
                                               struct exynos_drm_manager *mgr,
                                               unsigned int possible_crtcs);
index d7ae29d..3508700 100644 (file)
@@ -195,66 +195,6 @@ out:
        return ret;
 }
 
-static bool
-exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb,
-                           struct drm_fb_helper_surface_size *sizes)
-{
-       if (fb->width != sizes->surface_width)
-               return false;
-       if (fb->height != sizes->surface_height)
-               return false;
-       if (fb->bits_per_pixel != sizes->surface_bpp)
-               return false;
-       if (fb->depth != sizes->surface_depth)
-               return false;
-
-       return true;
-}
-
-static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
-                                     struct drm_fb_helper_surface_size *sizes)
-{
-       struct drm_device *dev = helper->dev;
-       struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
-       struct exynos_drm_gem_obj *exynos_gem_obj;
-       struct drm_framebuffer *fb = helper->fb;
-       struct drm_mode_fb_cmd2 mode_cmd = { 0 };
-       unsigned long size;
-
-       DRM_DEBUG_KMS("%s\n", __FILE__);
-
-       if (exynos_drm_fbdev_is_samefb(fb, sizes))
-               return 0;
-
-       mode_cmd.width = sizes->surface_width;
-       mode_cmd.height = sizes->surface_height;
-       mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3);
-       mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
-                                                         sizes->surface_depth);
-
-       if (exynos_fbdev->exynos_gem_obj)
-               exynos_drm_gem_destroy(exynos_fbdev->exynos_gem_obj);
-
-       if (fb->funcs->destroy)
-               fb->funcs->destroy(fb);
-
-       size = mode_cmd.pitches[0] * mode_cmd.height;
-       exynos_gem_obj = exynos_drm_gem_create(dev, size);
-       if (IS_ERR(exynos_gem_obj))
-               return PTR_ERR(exynos_gem_obj);
-
-       exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
-
-       helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd,
-                       &exynos_gem_obj->base);
-       if (IS_ERR_OR_NULL(helper->fb)) {
-               DRM_ERROR("failed to create drm framebuffer.\n");
-               return PTR_ERR(helper->fb);
-       }
-
-       return exynos_drm_fbdev_update(helper, helper->fb);
-}
-
 static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
                                   struct drm_fb_helper_surface_size *sizes)
 {
@@ -262,6 +202,10 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
+       /*
+        * with !helper->fb, it means that this funcion is called first time
+        * and after that, the helper->fb would be used as clone mode.
+        */
        if (!helper->fb) {
                ret = exynos_drm_fbdev_create(helper, sizes);
                if (ret < 0) {
@@ -274,12 +218,6 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
                 * because register_framebuffer() should be called.
                 */
                ret = 1;
-       } else {
-               ret = exynos_drm_fbdev_recreate(helper, sizes);
-               if (ret < 0) {
-                       DRM_ERROR("failed to reconfigure fbdev\n");
-                       return ret;
-               }
        }
 
        return ret;
index b6a737d..0dbb32b 100644 (file)
@@ -604,7 +604,12 @@ static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
        }
 
        if (is_checked) {
-               drm_vblank_put(drm_dev, crtc);
+               /*
+                * call drm_vblank_put only in case that drm_vblank_get was
+                * called.
+                */
+               if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+                       drm_vblank_put(drm_dev, crtc);
 
                /*
                 * don't off vblank if vblank_disable_allowed is 1,
index ac24cff..93846e8 100644 (file)
@@ -712,7 +712,12 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
        }
 
        if (is_checked)
-               drm_vblank_put(drm_dev, crtc);
+               /*
+                * call drm_vblank_put only in case that drm_vblank_get was
+                * called.
+                */
+               if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+                       drm_vblank_put(drm_dev, crtc);
 
        spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 }
@@ -779,15 +784,15 @@ static void mixer_win_reset(struct mixer_context *ctx)
        mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
                MXR_STATUS_BURST_MASK);
 
-       /* setting default layer priority: layer1 > video > layer0
+       /* setting default layer priority: layer1 > layer0 > video
         * because typical usage scenario would be
+        * layer1 - OSD
         * layer0 - framebuffer
         * video - video overlay
-        * layer1 - OSD
         */
-       val  = MXR_LAYER_CFG_GRP0_VAL(1);
-       val |= MXR_LAYER_CFG_VP_VAL(2);
-       val |= MXR_LAYER_CFG_GRP1_VAL(3);
+       val = MXR_LAYER_CFG_GRP1_VAL(3);
+       val |= MXR_LAYER_CFG_GRP0_VAL(2);
+       val |= MXR_LAYER_CFG_VP_VAL(1);
        mixer_reg_write(res, MXR_LAYER_CFG, val);
 
        /* setting background color */
@@ -1044,7 +1049,7 @@ static int mixer_remove(struct platform_device *pdev)
                                        platform_get_drvdata(pdev);
        struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
 
-       dev_info(dev, "remove sucessful\n");
+       dev_info(dev, "remove successful\n");
 
        mixer_resource_poweroff(ctx);
        mixer_resources_cleanup(ctx);
index c3afb78..03c53fc 100644 (file)
 #define  DISP_TILE_SURFACE_SWIZZLING   (1<<13)
 #define  DISP_FBC_WM_DIS               (1<<15)
 
+/* GEN7 chicken */
+#define GEN7_COMMON_SLICE_CHICKEN1             0x7010
+# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC     ((1<<10) | (1<<26))
+
+#define GEN7_L3CNTLREG1                                0xB01C
+#define  GEN7_WA_FOR_GEN7_L3_CONTROL                   0x3C4FFF8C
+
+#define GEN7_L3_CHICKEN_MODE_REGISTER          0xB030
+#define  GEN7_WA_L3_CHICKEN_MODE                               0x20000000
+
+/* WaCatErrorRejectionIssue */
+#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG         0x9030
+#define  GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB      (1<<11)
+
 /* PCH */
 
 /* south display engine interrupt */
 #define    GT_FIFO_NUM_RESERVED_ENTRIES                20
 
 #define GEN6_UCGCTL2                           0x9404
+# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE               (1 << 13)
 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE              (1 << 12)
 # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE               (1 << 11)
 
index 00fbff5..f425b23 100644 (file)
@@ -8184,8 +8184,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
        if (intel_enable_rc6(dev_priv->dev))
-               rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
-                       GEN6_RC_CTL_RC6_ENABLE;
+               rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
+                       (IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0;
 
        I915_WRITE(GEN6_RC_CONTROL,
                   rc6_mask |
@@ -8463,12 +8463,32 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        I915_WRITE(WM2_LP_ILK, 0);
        I915_WRITE(WM1_LP_ILK, 0);
 
+       /* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+        * This implements the WaDisableRCZUnitClockGating workaround.
+        */
+       I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
        I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
 
        I915_WRITE(IVB_CHICKEN3,
                   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
                   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
+       /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+       I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
+                  GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+       /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+       I915_WRITE(GEN7_L3CNTLREG1,
+                       GEN7_WA_FOR_GEN7_L3_CONTROL);
+       I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
+                       GEN7_WA_L3_CHICKEN_MODE);
+
+       /* This is required by WaCatErrorRejectionIssue */
+       I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+                       I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+                       GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
        for_each_pipe(pipe) {
                I915_WRITE(DSPCNTR(pipe),
                           I915_READ(DSPCNTR(pipe)) |
index 9be353b..f58254a 100644 (file)
@@ -3223,6 +3223,7 @@ int evergreen_resume(struct radeon_device *rdev)
        r = evergreen_startup(rdev);
        if (r) {
                DRM_ERROR("evergreen startup failed on resume\n");
+               rdev->accel_working = false;
                return r;
        }
 
index db09065..2509c50 100644 (file)
@@ -1547,6 +1547,7 @@ int cayman_resume(struct radeon_device *rdev)
        r = cayman_startup(rdev);
        if (r) {
                DRM_ERROR("cayman startup failed on resume\n");
+               rdev->accel_working = false;
                return r;
        }
        return r;
index 18cd84f..333cde9 100644 (file)
@@ -3928,6 +3928,8 @@ static int r100_startup(struct radeon_device *rdev)
 
 int r100_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        if (rdev->flags & RADEON_IS_PCI)
                r100_pci_gart_disable(rdev);
@@ -3947,7 +3949,11 @@ int r100_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return r100_startup(rdev);
+       r = r100_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int r100_suspend(struct radeon_device *rdev)
index 3fc0d29..6829638 100644 (file)
@@ -1431,6 +1431,8 @@ static int r300_startup(struct radeon_device *rdev)
 
 int r300_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        if (rdev->flags & RADEON_IS_PCIE)
                rv370_pcie_gart_disable(rdev);
@@ -1452,7 +1454,11 @@ int r300_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return r300_startup(rdev);
+       r = r300_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int r300_suspend(struct radeon_device *rdev)
index 666e28f..b143230 100644 (file)
@@ -291,6 +291,8 @@ static int r420_startup(struct radeon_device *rdev)
 
 int r420_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        if (rdev->flags & RADEON_IS_PCIE)
                rv370_pcie_gart_disable(rdev);
@@ -316,7 +318,11 @@ int r420_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return r420_startup(rdev);
+       r = r420_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int r420_suspend(struct radeon_device *rdev)
index 4ae1615..25084e8 100644 (file)
@@ -218,6 +218,8 @@ static int r520_startup(struct radeon_device *rdev)
 
 int r520_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        if (rdev->flags & RADEON_IS_PCIE)
                rv370_pcie_gart_disable(rdev);
@@ -237,7 +239,11 @@ int r520_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return r520_startup(rdev);
+       r = r520_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int r520_init(struct radeon_device *rdev)
index 4f08e5e..fbcd848 100644 (file)
@@ -2529,6 +2529,7 @@ int r600_resume(struct radeon_device *rdev)
        r = r600_startup(rdev);
        if (r) {
                DRM_ERROR("r600 startup failed on resume\n");
+               rdev->accel_working = false;
                return r;
        }
 
index 9e72dae..1f53ae7 100644 (file)
@@ -3020,6 +3020,9 @@ radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        uint32_t bios_2_scratch;
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (rdev->family >= CHIP_R600)
                bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
        else
index 435a3d9..e64bec4 100644 (file)
@@ -453,6 +453,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        int r;
 
        radeon_mutex_lock(&rdev->cs_mutex);
+       if (!rdev->accel_working) {
+               radeon_mutex_unlock(&rdev->cs_mutex);
+               return -EBUSY;
+       }
        /* initialize parser */
        memset(&parser, 0, sizeof(struct radeon_cs_parser));
        parser.filp = filp;
index 30a4c50..92c9ea4 100644 (file)
@@ -500,8 +500,11 @@ static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
 int radeon_debugfs_ring_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-       return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
-                                       ARRAY_SIZE(radeon_debugfs_ring_info_list));
+       if (rdev->family >= CHIP_CAYMAN)
+               return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
+                                               ARRAY_SIZE(radeon_debugfs_ring_info_list));
+       else
+               return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1);
 #else
        return 0;
 #endif
index b0ce84a..866a05b 100644 (file)
@@ -442,6 +442,8 @@ static int rs400_startup(struct radeon_device *rdev)
 
 int rs400_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        rs400_gart_disable(rdev);
        /* Resume clock before doing reset */
@@ -462,7 +464,11 @@ int rs400_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return rs400_startup(rdev);
+       r = rs400_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int rs400_suspend(struct radeon_device *rdev)
index c05865e..4fc7006 100644 (file)
@@ -876,6 +876,8 @@ static int rs600_startup(struct radeon_device *rdev)
 
 int rs600_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        rs600_gart_disable(rdev);
        /* Resume clock before doing reset */
@@ -894,7 +896,11 @@ int rs600_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return rs600_startup(rdev);
+       r = rs600_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int rs600_suspend(struct radeon_device *rdev)
index 4f24a0f..f68dff2 100644 (file)
@@ -659,6 +659,8 @@ static int rs690_startup(struct radeon_device *rdev)
 
 int rs690_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        rs400_gart_disable(rdev);
        /* Resume clock before doing reset */
@@ -677,7 +679,11 @@ int rs690_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return rs690_startup(rdev);
+       r = rs690_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int rs690_suspend(struct radeon_device *rdev)
index 880637f..959bf44 100644 (file)
@@ -424,6 +424,8 @@ static int rv515_startup(struct radeon_device *rdev)
 
 int rv515_resume(struct radeon_device *rdev)
 {
+       int r;
+
        /* Make sur GART are not working */
        if (rdev->flags & RADEON_IS_PCIE)
                rv370_pcie_gart_disable(rdev);
@@ -443,7 +445,11 @@ int rv515_resume(struct radeon_device *rdev)
        radeon_surface_init(rdev);
 
        rdev->accel_working = true;
-       return rv515_startup(rdev);
+       r =  rv515_startup(rdev);
+       if (r) {
+               rdev->accel_working = false;
+       }
+       return r;
 }
 
 int rv515_suspend(struct radeon_device *rdev)
index a1668b6..c049c0c 100644 (file)
@@ -1139,6 +1139,7 @@ int rv770_resume(struct radeon_device *rdev)
        r = rv770_startup(rdev);
        if (r) {
                DRM_ERROR("r600 startup failed on resume\n");
+               rdev->accel_working = false;
                return r;
        }