From: Greg Kroah-Hartman Date: Fri, 6 Aug 2010 16:09:10 +0000 (-0700) Subject: .35 patches X-Git-Tag: v2.6.27.50~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f18ed98b6fff19f50c64594c3a7d46cdf2774705;p=thirdparty%2Fkernel%2Fstable-queue.git .35 patches --- diff --git a/queue-2.6.35/drm-i915-check-overlay-stride-errata-for-i830-and-i845.patch b/queue-2.6.35/drm-i915-check-overlay-stride-errata-for-i830-and-i845.patch new file mode 100644 index 00000000000..521f1ec6599 --- /dev/null +++ b/queue-2.6.35/drm-i915-check-overlay-stride-errata-for-i830-and-i845.patch @@ -0,0 +1,43 @@ +From a1efd14a99483a4fb9308902397ed86b69454c99 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Mon, 12 Jul 2010 19:35:38 +0100 +Subject: drm/i915: Check overlay stride errata for i830 and i845 + +From: Chris Wilson + +commit a1efd14a99483a4fb9308902397ed86b69454c99 upstream. + +Apparently i830 and i845 cannot handle any stride that is not a multiple +of 256, unlike their brethren which do support 64 byte aligned strides. + +Signed-off-by: Chris Wilson +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_overlay.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_overlay.c ++++ b/drivers/gpu/drm/i915/intel_overlay.c +@@ -958,7 +958,7 @@ static int check_overlay_src(struct drm_ + || rec->src_width < N_HORIZ_Y_TAPS*4) + return -EINVAL; + +- /* check alingment constrains */ ++ /* check alignment constraints */ + switch (rec->flags & I915_OVERLAY_TYPE_MASK) { + case I915_OVERLAY_RGB: + /* not implemented */ +@@ -990,7 +990,10 @@ static int check_overlay_src(struct drm_ + return -EINVAL; + + /* stride checking */ +- stride_mask = 63; ++ if (IS_I830(dev) || IS_845G(dev)) ++ stride_mask = 255; ++ else ++ stride_mask = 63; + + if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) + return -EINVAL; diff --git a/queue-2.6.35/drm-i915-unset-cursor-if-out-of-bounds-upon-mode-change-v4.patch b/queue-2.6.35/drm-i915-unset-cursor-if-out-of-bounds-upon-mode-change-v4.patch new file mode 100644 index 00000000000..36d992fd1f1 --- /dev/null +++ b/queue-2.6.35/drm-i915-unset-cursor-if-out-of-bounds-upon-mode-change-v4.patch @@ -0,0 +1,279 @@ +From cda4b7d3a5b1dcbc0d8e7bad52134347798e9047 Mon Sep 17 00:00:00 2001 +From: Chris Wilson +Date: Fri, 9 Jul 2010 08:45:04 +0100 +Subject: drm/i915: Unset cursor if out-of-bounds upon mode change (v4) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Chris Wilson + +commit cda4b7d3a5b1dcbc0d8e7bad52134347798e9047 upstream. + +The docs warn that to position the cursor such that no part of it is +visible on the pipe is an undefined operation. Avoid such circumstances +upon changing the mode, or at any other time, by unsetting the cursor if +it moves out of bounds. + +"For normal high resolution display modes, the cursor must have at least a +single pixel positioned over the active screen.” (p143, p148 of the hardware +registers docs). + +Fixes: + + Bug 24748 - [965G] Graphics crashes when resolution is changed with KMS + enabled + https://bugs.freedesktop.org/show_bug.cgi?id=24748 + +v2: Only update the cursor registers if they change. +v3: Fix the unsigned comparision of x,y against width,height. +v4: Always set CUR.BASE or else the cursor may become corrupt. + +Signed-off-by: Chris Wilson +Reported-by: Christian Eggers +Cc: Christopher James Halse Rogers +Signed-off-by: Eric Anholt +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_display.c | 144 ++++++++++++++++++++++------------- + drivers/gpu/drm/i915/intel_drv.h | 8 + + 2 files changed, 99 insertions(+), 53 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -42,6 +42,7 @@ + bool intel_pipe_has_type (struct drm_crtc *crtc, int type); + static void intel_update_watermarks(struct drm_device *dev); + static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); ++static void intel_crtc_update_cursor(struct drm_crtc *crtc); + + typedef struct { + /* given values */ +@@ -3403,6 +3404,9 @@ static int intel_crtc_mode_set(struct dr + return -EINVAL; + } + ++ /* Ensure that the cursor is valid for the new mode before changing... */ ++ intel_crtc_update_cursor(crtc); ++ + if (is_lvds && dev_priv->lvds_downclock_avail) { + has_reduced_clock = limit->find_pll(limit, crtc, + dev_priv->lvds_downclock, +@@ -3939,6 +3943,85 @@ void intel_crtc_load_lut(struct drm_crtc + } + } + ++/* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ ++static void intel_crtc_update_cursor(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int pipe = intel_crtc->pipe; ++ int x = intel_crtc->cursor_x; ++ int y = intel_crtc->cursor_y; ++ uint32_t base, pos; ++ bool visible; ++ ++ pos = 0; ++ ++ if (crtc->fb) { ++ base = intel_crtc->cursor_addr; ++ if (x > (int) crtc->fb->width) ++ base = 0; ++ ++ if (y > (int) crtc->fb->height) ++ base = 0; ++ } else ++ base = 0; ++ ++ if (x < 0) { ++ if (x + intel_crtc->cursor_width < 0) ++ base = 0; ++ ++ pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; ++ x = -x; ++ } ++ pos |= x << CURSOR_X_SHIFT; ++ ++ if (y < 0) { ++ if (y + intel_crtc->cursor_height < 0) ++ base = 0; ++ ++ pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; ++ y = -y; ++ } ++ pos |= y << CURSOR_Y_SHIFT; ++ ++ visible = base != 0; ++ if (!visible && !intel_crtc->cursor_visble) ++ return; ++ ++ I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); ++ if (intel_crtc->cursor_visble != visible) { ++ uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); ++ if (base) { ++ /* Hooray for CUR*CNTR differences */ ++ if (IS_MOBILE(dev) || IS_I9XX(dev)) { ++ cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); ++ cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; ++ cntl |= pipe << 28; /* Connect to correct pipe */ ++ } else { ++ cntl &= ~(CURSOR_FORMAT_MASK); ++ cntl |= CURSOR_ENABLE; ++ cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; ++ } ++ } else { ++ if (IS_MOBILE(dev) || IS_I9XX(dev)) { ++ cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); ++ cntl |= CURSOR_MODE_DISABLE; ++ } else { ++ cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); ++ } ++ } ++ I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); ++ ++ intel_crtc->cursor_visble = visible; ++ } ++ /* and commit changes on next vblank */ ++ I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); ++ ++ if (visible) ++ intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); ++} ++ + static int intel_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, +@@ -3949,11 +4032,7 @@ static int intel_crtc_cursor_set(struct + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_gem_object *bo; + struct drm_i915_gem_object *obj_priv; +- int pipe = intel_crtc->pipe; +- uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; +- uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; +- uint32_t temp = I915_READ(control); +- size_t addr; ++ uint32_t addr; + int ret; + + DRM_DEBUG_KMS("\n"); +@@ -3961,12 +4040,6 @@ static int intel_crtc_cursor_set(struct + /* if we want to turn off the cursor ignore width and height */ + if (!handle) { + DRM_DEBUG_KMS("cursor off\n"); +- if (IS_MOBILE(dev) || IS_I9XX(dev)) { +- temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); +- temp |= CURSOR_MODE_DISABLE; +- } else { +- temp &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); +- } + addr = 0; + bo = NULL; + mutex_lock(&dev->struct_mutex); +@@ -4008,7 +4081,8 @@ static int intel_crtc_cursor_set(struct + + addr = obj_priv->gtt_offset; + } else { +- ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); ++ ret = i915_gem_attach_phys_object(dev, bo, ++ (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); + if (ret) { + DRM_ERROR("failed to attach phys object\n"); + goto fail_locked; +@@ -4019,21 +4093,7 @@ static int intel_crtc_cursor_set(struct + if (!IS_I9XX(dev)) + I915_WRITE(CURSIZE, (height << 12) | width); + +- /* Hooray for CUR*CNTR differences */ +- if (IS_MOBILE(dev) || IS_I9XX(dev)) { +- temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); +- temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; +- temp |= (pipe << 28); /* Connect to correct pipe */ +- } else { +- temp &= ~(CURSOR_FORMAT_MASK); +- temp |= CURSOR_ENABLE; +- temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; +- } +- + finish: +- I915_WRITE(control, temp); +- I915_WRITE(base, addr); +- + if (intel_crtc->cursor_bo) { + if (dev_priv->info->cursor_needs_physical) { + if (intel_crtc->cursor_bo != bo) +@@ -4047,6 +4107,10 @@ static int intel_crtc_cursor_set(struct + + intel_crtc->cursor_addr = addr; + intel_crtc->cursor_bo = bo; ++ intel_crtc->cursor_width = width; ++ intel_crtc->cursor_height = height; ++ ++ intel_crtc_update_cursor(crtc); + + return 0; + fail_unpin: +@@ -4060,34 +4124,12 @@ fail: + + static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) + { +- struct drm_device *dev = crtc->dev; +- struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); +- struct intel_framebuffer *intel_fb; +- int pipe = intel_crtc->pipe; +- uint32_t temp = 0; +- uint32_t adder; +- +- if (crtc->fb) { +- intel_fb = to_intel_framebuffer(crtc->fb); +- intel_mark_busy(dev, intel_fb->obj); +- } +- +- if (x < 0) { +- temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; +- x = -x; +- } +- if (y < 0) { +- temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; +- y = -y; +- } + +- temp |= x << CURSOR_X_SHIFT; +- temp |= y << CURSOR_Y_SHIFT; ++ intel_crtc->cursor_x = x; ++ intel_crtc->cursor_y = y; + +- adder = intel_crtc->cursor_addr; +- I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); +- I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); ++ intel_crtc_update_cursor(crtc); + + return 0; + } +--- a/drivers/gpu/drm/i915/intel_drv.h ++++ b/drivers/gpu/drm/i915/intel_drv.h +@@ -143,8 +143,6 @@ struct intel_crtc { + struct drm_crtc base; + enum pipe pipe; + enum plane plane; +- struct drm_gem_object *cursor_bo; +- uint32_t cursor_addr; + u8 lut_r[256], lut_g[256], lut_b[256]; + int dpms_mode; + bool busy; /* is scanout buffer being updated frequently? */ +@@ -153,6 +151,12 @@ struct intel_crtc { + struct intel_overlay *overlay; + struct intel_unpin_work *unpin_work; + int fdi_lanes; ++ ++ struct drm_gem_object *cursor_bo; ++ uint32_t cursor_addr; ++ int16_t cursor_x, cursor_y; ++ int16_t cursor_width, cursor_height; ++ bool cursor_visble; + }; + + #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) diff --git a/queue-2.6.35/drm-radeon-add-new-pci-ids.patch b/queue-2.6.35/drm-radeon-add-new-pci-ids.patch new file mode 100644 index 00000000000..c49573c51b6 --- /dev/null +++ b/queue-2.6.35/drm-radeon-add-new-pci-ids.patch @@ -0,0 +1,70 @@ +From 1297c05a8dfb568c689f057d51a65eebe5ddc86f Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 4 Aug 2010 11:40:00 -0400 +Subject: drm/radeon: add new pci ids + +From: Alex Deucher + +commit 1297c05a8dfb568c689f057d51a65eebe5ddc86f upstream. + +New evergreen and r7xx ids. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + include/drm/drm_pciids.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -146,6 +146,8 @@ + {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6889, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x688A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x688C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x688D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6898, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6899, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x689c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_HEMLOCK|RADEON_NEW_MEMMAP}, \ +@@ -161,6 +163,7 @@ + {0x1002, 0x68be, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_JUNIPER|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x68c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_REDWOOD|RADEON_NEW_MEMMAP}, \ +@@ -174,6 +177,7 @@ + {0x1002, 0x68e8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68e9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x68f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ +@@ -314,6 +318,7 @@ + {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x945E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -324,6 +329,7 @@ + {0x1002, 0x9487, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9488, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9489, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x948A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x948F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9490, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9491, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -366,6 +372,7 @@ + {0x1002, 0x9553, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9555, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9557, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x955f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9581, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9583, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ diff --git a/queue-2.6.35/drm-radeon-fall-back-to-gtt-if-bo-creation-validation-in-vram-fails.patch b/queue-2.6.35/drm-radeon-fall-back-to-gtt-if-bo-creation-validation-in-vram-fails.patch new file mode 100644 index 00000000000..c4ea47eaa66 --- /dev/null +++ b/queue-2.6.35/drm-radeon-fall-back-to-gtt-if-bo-creation-validation-in-vram-fails.patch @@ -0,0 +1,87 @@ +From e376573f7267390f4e1bdc552564b6fb913bce76 Mon Sep 17 00:00:00 2001 +From: Michel Dänzer +Date: Thu, 8 Jul 2010 12:43:28 +1000 +Subject: drm/radeon: fall back to GTT if bo creation/validation in VRAM fails. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer + +commit e376573f7267390f4e1bdc552564b6fb913bce76 upstream. + +This fixes a problem where on low VRAM cards we'd run out of space for validation. + +[airlied: Tested on my M7, Thinkpad T42, compiz works with no problems.] + +Signed-off-by: Michel Dänzer +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_object.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_object.c ++++ b/drivers/gpu/drm/radeon/radeon_object.c +@@ -110,6 +110,7 @@ int radeon_bo_create(struct radeon_devic + bo->surface_reg = -1; + INIT_LIST_HEAD(&bo->list); + ++retry: + radeon_ttm_placement_from_domain(bo, domain); + /* Kernel allocation are uninterruptible */ + mutex_lock(&rdev->vram_mutex); +@@ -118,10 +119,15 @@ int radeon_bo_create(struct radeon_devic + &radeon_ttm_bo_destroy); + mutex_unlock(&rdev->vram_mutex); + if (unlikely(r != 0)) { +- if (r != -ERESTARTSYS) ++ if (r != -ERESTARTSYS) { ++ if (domain == RADEON_GEM_DOMAIN_VRAM) { ++ domain |= RADEON_GEM_DOMAIN_GTT; ++ goto retry; ++ } + dev_err(rdev->dev, + "object_init failed for (%lu, 0x%08X)\n", + size, domain); ++ } + return r; + } + *bo_ptr = bo; +@@ -321,6 +327,7 @@ int radeon_bo_list_validate(struct list_ + { + struct radeon_bo_list *lobj; + struct radeon_bo *bo; ++ u32 domain; + int r; + + list_for_each_entry(lobj, head, list) { +@@ -333,17 +340,19 @@ int radeon_bo_list_validate(struct list_ + list_for_each_entry(lobj, head, list) { + bo = lobj->bo; + if (!bo->pin_count) { +- if (lobj->wdomain) { +- radeon_ttm_placement_from_domain(bo, +- lobj->wdomain); +- } else { +- radeon_ttm_placement_from_domain(bo, +- lobj->rdomain); +- } ++ domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; ++ ++ retry: ++ radeon_ttm_placement_from_domain(bo, domain); + r = ttm_bo_validate(&bo->tbo, &bo->placement, + true, false, false); +- if (unlikely(r)) ++ if (unlikely(r)) { ++ if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { ++ domain |= RADEON_GEM_DOMAIN_GTT; ++ goto retry; ++ } + return r; ++ } + } + lobj->gpu_offset = radeon_bo_gpu_offset(bo); + lobj->tiling_flags = bo->tiling_flags; diff --git a/queue-2.6.35/drm-radeon-kms-handle-the-case-of-no-active-displays-properly-in-the-bandwidth-code.patch b/queue-2.6.35/drm-radeon-kms-handle-the-case-of-no-active-displays-properly-in-the-bandwidth-code.patch new file mode 100644 index 00000000000..23afd7db234 --- /dev/null +++ b/queue-2.6.35/drm-radeon-kms-handle-the-case-of-no-active-displays-properly-in-the-bandwidth-code.patch @@ -0,0 +1,146 @@ +From e06b14ee91a2ddefc9a67443a6cd8ee0fa800115 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 2 Aug 2010 12:13:46 -0400 +Subject: drm/radeon/kms: handle the case of no active displays properly in the bandwidth code + +From: Alex Deucher + +commit e06b14ee91a2ddefc9a67443a6cd8ee0fa800115 upstream. + +Logic was: +if (mode0 && mode1) +else if (mode0) +else + +Should be: +if (mode0 && mode1) +else if (mode0) +else if (mode1) + +Otherwise we may end up calculating the priority regs with +unitialized values. + +Fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=16492 + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/rs690.c | 27 +++++++++------------------ + drivers/gpu/drm/radeon/rv515.c | 23 +++++++++-------------- + 2 files changed, 18 insertions(+), 32 deletions(-) + +--- a/drivers/gpu/drm/radeon/rs690.c ++++ b/drivers/gpu/drm/radeon/rs690.c +@@ -398,7 +398,9 @@ void rs690_bandwidth_update(struct radeo + struct drm_display_mode *mode1 = NULL; + struct rs690_watermark wm0; + struct rs690_watermark wm1; +- u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; ++ u32 tmp; ++ u32 d1mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); ++ u32 d2mode_priority_a_cnt = S_006548_D1MODE_PRIORITY_A_OFF(1); + fixed20_12 priority_mark02, priority_mark12, fill_rate; + fixed20_12 a, b; + +@@ -495,10 +497,6 @@ void rs690_bandwidth_update(struct radeo + d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); + d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); + } +- WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +- WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +- WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +- WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } else if (mode0) { + if (dfixed_trunc(wm0.dbpp) > 64) + a.full = dfixed_mul(wm0.dbpp, wm0.num_line_pair); +@@ -528,13 +526,7 @@ void rs690_bandwidth_update(struct radeo + d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); + if (rdev->disp_priority == 2) + d1mode_priority_a_cnt |= S_006548_D1MODE_PRIORITY_A_ALWAYS_ON(1); +- WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +- WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +- WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, +- S_006D48_D2MODE_PRIORITY_A_OFF(1)); +- WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, +- S_006D4C_D2MODE_PRIORITY_B_OFF(1)); +- } else { ++ } else if (mode1) { + if (dfixed_trunc(wm1.dbpp) > 64) + a.full = dfixed_mul(wm1.dbpp, wm1.num_line_pair); + else +@@ -563,13 +555,12 @@ void rs690_bandwidth_update(struct radeo + d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + if (rdev->disp_priority == 2) + d2mode_priority_a_cnt |= S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(1); +- WREG32(R_006548_D1MODE_PRIORITY_A_CNT, +- S_006548_D1MODE_PRIORITY_A_OFF(1)); +- WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, +- S_00654C_D1MODE_PRIORITY_B_OFF(1)); +- WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +- WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } ++ ++ WREG32(R_006548_D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); ++ WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); ++ WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); ++ WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } + + uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) +--- a/drivers/gpu/drm/radeon/rv515.c ++++ b/drivers/gpu/drm/radeon/rv515.c +@@ -925,7 +925,9 @@ void rv515_bandwidth_avivo_update(struct + struct drm_display_mode *mode1 = NULL; + struct rv515_watermark wm0; + struct rv515_watermark wm1; +- u32 tmp, d1mode_priority_a_cnt, d2mode_priority_a_cnt; ++ u32 tmp; ++ u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; ++ u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; + fixed20_12 priority_mark02, priority_mark12, fill_rate; + fixed20_12 a, b; + +@@ -999,10 +1001,6 @@ void rv515_bandwidth_avivo_update(struct + d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; + d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; + } +- WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +- WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +- WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +- WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } else if (mode0) { + if (dfixed_trunc(wm0.dbpp) > 64) + a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); +@@ -1032,11 +1030,7 @@ void rv515_bandwidth_avivo_update(struct + d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); + if (rdev->disp_priority == 2) + d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; +- WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); +- WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); +- WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); +- WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); +- } else { ++ } else if (mode1) { + if (dfixed_trunc(wm1.dbpp) > 64) + a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); + else +@@ -1065,11 +1059,12 @@ void rv515_bandwidth_avivo_update(struct + d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); + if (rdev->disp_priority == 2) + d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; +- WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); +- WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); +- WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); +- WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } ++ ++ WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); ++ WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); ++ WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); ++ WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); + } + + void rv515_bandwidth_update(struct radeon_device *rdev) diff --git a/queue-2.6.35/drm-radeon-kms-r7xx-add-workaround-for-hw-issue-with-hdp-flush.patch b/queue-2.6.35/drm-radeon-kms-r7xx-add-workaround-for-hw-issue-with-hdp-flush.patch new file mode 100644 index 00000000000..a2f161bda0f --- /dev/null +++ b/queue-2.6.35/drm-radeon-kms-r7xx-add-workaround-for-hw-issue-with-hdp-flush.patch @@ -0,0 +1,95 @@ +From 812d046915f48236657f02c06d7dc47140e9ceda Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 26 Jul 2010 18:51:53 -0400 +Subject: drm/radeon/kms/r7xx: add workaround for hw issue with HDP flush + +From: Alex Deucher + +commit 812d046915f48236657f02c06d7dc47140e9ceda upstream. + +Use of HDP_*_COHERENCY_FLUSH_CNTL can cause a hang in certain +situations. Add workaround. + +Signed-off-by: Alex Deucher +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/r600.c | 24 ++++++++++++++++++++++-- + drivers/gpu/drm/radeon/r600d.h | 1 + + drivers/gpu/drm/radeon/rv770.c | 5 ++++- + drivers/gpu/drm/radeon/rv770d.h | 1 + + 4 files changed, 28 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -869,7 +869,17 @@ void r600_pcie_gart_tlb_flush(struct rad + u32 tmp; + + /* flush hdp cache so updates hit vram */ +- WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); ++ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { ++ void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; ++ u32 tmp; ++ ++ /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read ++ * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL ++ */ ++ WREG32(HDP_DEBUG1, 0); ++ tmp = readl((void __iomem *)ptr); ++ } else ++ WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + + WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); + WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); +@@ -3512,5 +3522,15 @@ int r600_debugfs_mc_info_init(struct rad + */ + void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) + { +- WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); ++ /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read ++ * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL ++ */ ++ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { ++ void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; ++ u32 tmp; ++ ++ WREG32(HDP_DEBUG1, 0); ++ tmp = readl((void __iomem *)ptr); ++ } else ++ WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + } +--- a/drivers/gpu/drm/radeon/r600d.h ++++ b/drivers/gpu/drm/radeon/r600d.h +@@ -245,6 +245,7 @@ + #define HDP_NONSURFACE_SIZE 0x2C0C + #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 + #define HDP_TILING_CONFIG 0x2F3C ++#define HDP_DEBUG1 0x2F34 + + #define MC_VM_AGP_TOP 0x2184 + #define MC_VM_AGP_BOT 0x2188 +--- a/drivers/gpu/drm/radeon/rv770.c ++++ b/drivers/gpu/drm/radeon/rv770.c +@@ -189,7 +189,10 @@ static void rv770_mc_program(struct rade + WREG32((0x2c20 + j), 0x00000000); + WREG32((0x2c24 + j), 0x00000000); + } +- WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); ++ /* r7xx hw bug. Read from HDP_DEBUG1 rather ++ * than writing to HDP_REG_COHERENCY_FLUSH_CNTL ++ */ ++ tmp = RREG32(HDP_DEBUG1); + + rv515_mc_stop(rdev, &save); + if (r600_mc_wait_for_idle(rdev)) { +--- a/drivers/gpu/drm/radeon/rv770d.h ++++ b/drivers/gpu/drm/radeon/rv770d.h +@@ -128,6 +128,7 @@ + #define HDP_NONSURFACE_SIZE 0x2C0C + #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 + #define HDP_TILING_CONFIG 0x2F3C ++#define HDP_DEBUG1 0x2F34 + + #define MC_SHARED_CHMAP 0x2004 + #define NOOFCHAN_SHIFT 12 diff --git a/queue-2.6.35/series b/queue-2.6.35/series index 3414e0f4029..3f9526b0267 100644 --- a/queue-2.6.35/series +++ b/queue-2.6.35/series @@ -30,3 +30,9 @@ mac80211-avoid-scheduling-while-atomic-in-mesh_rx_plink_frame.patch cred-fix-rcu-warning-due-to-previous-patch-fixing-__task_cred-s-checks.patch scsi-enclosure-fix-error-path-actually-return-err_ptr-on-error.patch xen-drop-xen_sched_clock-in-favour-of-using-plain-wallclock-time.patch +drm-radeon-add-new-pci-ids.patch +drm-radeon-fall-back-to-gtt-if-bo-creation-validation-in-vram-fails.patch +drm-radeon-kms-r7xx-add-workaround-for-hw-issue-with-hdp-flush.patch +drm-radeon-kms-handle-the-case-of-no-active-displays-properly-in-the-bandwidth-code.patch +drm-i915-unset-cursor-if-out-of-bounds-upon-mode-change-v4.patch +drm-i915-check-overlay-stride-errata-for-i830-and-i845.patch