]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 6 Dec 2012 18:14:23 +0000 (10:14 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 6 Dec 2012 18:14:23 +0000 (10:14 -0800)
added patches:
dove-attempt-to-fix-pmu-rtc-interrupts.patch
dove-fix-irq_to_pmu.patch
drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch
drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch
drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch

queue-3.4/dove-attempt-to-fix-pmu-rtc-interrupts.patch [new file with mode: 0644]
queue-3.4/dove-fix-irq_to_pmu.patch [new file with mode: 0644]
queue-3.4/drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch [new file with mode: 0644]
queue-3.4/drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch [new file with mode: 0644]
queue-3.4/drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

diff --git a/queue-3.4/dove-attempt-to-fix-pmu-rtc-interrupts.patch b/queue-3.4/dove-attempt-to-fix-pmu-rtc-interrupts.patch
new file mode 100644 (file)
index 0000000..60df3bf
--- /dev/null
@@ -0,0 +1,63 @@
+From 5d3df935426271016b895aecaa247101b4bfa35e Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Sun, 18 Nov 2012 16:29:44 +0000
+Subject: Dove: Attempt to fix PMU/RTC interrupts
+
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+
+commit 5d3df935426271016b895aecaa247101b4bfa35e upstream.
+
+Fix the acknowledgement of PMU interrupts on Dove: some Dove hardware
+has not been sensibly designed so that interrupts can be handled in a
+race free manner.  The PMU is one such instance.
+
+The pending (aka 'cause') register is a bunch of RW bits, meaning that
+these bits can be both cleared and set by software (confirmed on the
+Armada-510 on the cubox.)
+
+Hardware sets the appropriate bit when an interrupt is asserted, and
+software is required to clear the bits which are to be processed.  If
+we write ~(1 << bit), then we end up asserting every other interrupt
+except the one we're processing.  So, we need to do a read-modify-write
+cycle to clear the asserted bit.
+
+However, any interrupts which occur in the middle of this cycle will
+also be written back as zero, which will also clear the new interrupts.
+
+The upshot of this is: there is _no_ way to safely clear down interrupts
+in this register (and other similarly behaving interrupt pending
+registers on this device.)  The patch below at least stops us creating
+new interrupts.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-dove/irq.c |   14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-dove/irq.c
++++ b/arch/arm/mach-dove/irq.c
+@@ -61,8 +61,20 @@ static void pmu_irq_ack(struct irq_data
+       int pin = irq_to_pmu(d->irq);
+       u32 u;
++      /*
++       * The PMU mask register is not RW0C: it is RW.  This means that
++       * the bits take whatever value is written to them; if you write
++       * a '1', you will set the interrupt.
++       *
++       * Unfortunately this means there is NO race free way to clear
++       * these interrupts.
++       *
++       * So, let's structure the code so that the window is as small as
++       * possible.
++       */
+       u = ~(1 << (pin & 31));
+-      writel(u, PMU_INTERRUPT_CAUSE);
++      u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
++      writel_relaxed(u, PMU_INTERRUPT_CAUSE);
+ }
+ static struct irq_chip pmu_irq_chip = {
diff --git a/queue-3.4/dove-fix-irq_to_pmu.patch b/queue-3.4/dove-fix-irq_to_pmu.patch
new file mode 100644 (file)
index 0000000..04b5b3f
--- /dev/null
@@ -0,0 +1,34 @@
+From d356cf5a74afa32b40decca3c9dd88bc3cd63eb5 Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Sun, 18 Nov 2012 16:39:32 +0000
+Subject: Dove: Fix irq_to_pmu()
+
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+
+commit d356cf5a74afa32b40decca3c9dd88bc3cd63eb5 upstream.
+
+PMU interrupts start at IRQ_DOVE_PMU_START, not IRQ_DOVE_PMU_START + 1.
+Fix the condition.  (It may have been less likely to occur had the code
+been written "if (irq >= IRQ_DOVE_PMU_START" which imho is the easier
+to understand notation, and matches the normal way of thinking about
+these things.)
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-dove/include/mach/pm.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/mach-dove/include/mach/pm.h
++++ b/arch/arm/mach-dove/include/mach/pm.h
+@@ -45,7 +45,7 @@ static inline int pmu_to_irq(int pin)
+ static inline int irq_to_pmu(int irq)
+ {
+-      if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
++      if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
+               return irq - IRQ_DOVE_PMU_START;
+       return -EINVAL;
diff --git a/queue-3.4/drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch b/queue-3.4/drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch
new file mode 100644 (file)
index 0000000..07e4306
--- /dev/null
@@ -0,0 +1,61 @@
+From 4a15903db02026728d0cf2755c6fabae16b8db6a Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Wed, 15 Aug 2012 17:13:53 -0400
+Subject: drm/radeon/dce4+: don't use radeon_crtc for vblank callback
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 4a15903db02026728d0cf2755c6fabae16b8db6a upstream.
+
+This might be called before we've allocated the radeon_crtcs
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c |   20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -37,6 +37,16 @@
+ #define EVERGREEN_PFP_UCODE_SIZE 1120
+ #define EVERGREEN_PM4_UCODE_SIZE 1376
++static const u32 crtc_offsets[6] =
++{
++      EVERGREEN_CRTC0_REGISTER_OFFSET,
++      EVERGREEN_CRTC1_REGISTER_OFFSET,
++      EVERGREEN_CRTC2_REGISTER_OFFSET,
++      EVERGREEN_CRTC3_REGISTER_OFFSET,
++      EVERGREEN_CRTC4_REGISTER_OFFSET,
++      EVERGREEN_CRTC5_REGISTER_OFFSET
++};
++
+ static void evergreen_gpu_init(struct radeon_device *rdev);
+ void evergreen_fini(struct radeon_device *rdev);
+ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
+@@ -101,17 +111,19 @@ void evergreen_fix_pci_max_read_req_size
+ void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
+ {
+-      struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
+       int i;
+-      if (RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_MASTER_EN) {
++      if (crtc >= rdev->num_crtc)
++              return;
++
++      if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN) {
+               for (i = 0; i < rdev->usec_timeout; i++) {
+-                      if (!(RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK))
++                      if (!(RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK))
+                               break;
+                       udelay(1);
+               }
+               for (i = 0; i < rdev->usec_timeout; i++) {
+-                      if (RREG32(EVERGREEN_CRTC_STATUS + radeon_crtc->crtc_offset) & EVERGREEN_CRTC_V_BLANK)
++                      if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
+                               break;
+                       udelay(1);
+               }
diff --git a/queue-3.4/drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch b/queue-3.4/drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch
new file mode 100644 (file)
index 0000000..946c575
--- /dev/null
@@ -0,0 +1,271 @@
+From 62444b7462a2b98bc78d68736c03a7c4e66ba7e2 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Wed, 15 Aug 2012 17:18:42 -0400
+Subject: drm/radeon: properly handle mc_stop/mc_resume on evergreen+ (v2)
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 62444b7462a2b98bc78d68736c03a7c4e66ba7e2 upstream.
+
+- Stop the displays from accessing the FB
+- Block CPU access
+- Turn off MC client access
+
+This should fix issues some users have seen, especially
+with UEFI, when changing the MC FB location that result
+in hangs or display corruption.
+
+v2: fix crtc enabled check noticed by Luca Tettamanti
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/radeon/evergreen.c     |  173 +++++++++++++++------------------
+ drivers/gpu/drm/radeon/evergreen_reg.h |    2 
+ drivers/gpu/drm/radeon/evergreend.h    |    7 +
+ drivers/gpu/drm/radeon/radeon_asic.h   |    1 
+ 4 files changed, 90 insertions(+), 93 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -1129,116 +1129,103 @@ void evergreen_agp_enable(struct radeon_
+ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
+ {
++      u32 crtc_enabled, tmp, frame_count, blackout;
++      int i, j;
++
+       save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
+       save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+-      /* Stop all video */
++      /* disable VGA render */
+       WREG32(VGA_RENDER_CONTROL, 0);
+-      WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
+-      WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
+-      if (rdev->num_crtc >= 4) {
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+-      }
+-      if (rdev->num_crtc >= 6) {
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
+-      }
+-      WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+-      WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+-      if (rdev->num_crtc >= 4) {
+-              WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+-              WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+-      }
+-      if (rdev->num_crtc >= 6) {
+-              WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+-              WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+-      }
+-      WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
+-      WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
+-      if (rdev->num_crtc >= 4) {
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+-      }
+-      if (rdev->num_crtc >= 6) {
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+-              WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+-      }
+-
+-      WREG32(D1VGA_CONTROL, 0);
+-      WREG32(D2VGA_CONTROL, 0);
+-      if (rdev->num_crtc >= 4) {
+-              WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+-              WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+-      }
+-      if (rdev->num_crtc >= 6) {
+-              WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+-              WREG32(EVERGREEN_D6VGA_CONTROL, 0);
++      /* blank the display controllers */
++      for (i = 0; i < rdev->num_crtc; i++) {
++              crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
++              if (crtc_enabled) {
++                      save->crtc_enabled[i] = true;
++                      if (ASIC_IS_DCE6(rdev)) {
++                              tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
++                              if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
++                                      radeon_wait_for_vblank(rdev, i);
++                                      tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
++                                      WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
++                              }
++                      } else {
++                              tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
++                              if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
++                                      radeon_wait_for_vblank(rdev, i);
++                                      tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
++                                      WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
++                              }
++                      }
++                      /* wait for the next frame */
++                      frame_count = radeon_get_vblank_counter(rdev, i);
++                      for (j = 0; j < rdev->usec_timeout; j++) {
++                              if (radeon_get_vblank_counter(rdev, i) != frame_count)
++                                      break;
++                              udelay(1);
++                      }
++              }
++      }
++
++      radeon_mc_wait_for_idle(rdev);
++
++      blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
++      if ((blackout & BLACKOUT_MODE_MASK) != 1) {
++              /* Block CPU access */
++              WREG32(BIF_FB_EN, 0);
++              /* blackout the MC */
++              blackout &= ~BLACKOUT_MODE_MASK;
++              WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
+       }
+ }
+ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
+ {
+-      WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
+-             upper_32_bits(rdev->mc.vram_start));
+-      WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
+-             upper_32_bits(rdev->mc.vram_start));
+-      WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
+-             (u32)rdev->mc.vram_start);
+-      WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
+-             (u32)rdev->mc.vram_start);
+-
+-      WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
+-             upper_32_bits(rdev->mc.vram_start));
+-      WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
+-             upper_32_bits(rdev->mc.vram_start));
+-      WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
+-             (u32)rdev->mc.vram_start);
+-      WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
+-             (u32)rdev->mc.vram_start);
+-
+-      if (rdev->num_crtc >= 4) {
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
++      u32 tmp, frame_count;
++      int i, j;
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
++      /* update crtc base addresses */
++      for (i = 0; i < rdev->num_crtc; i++) {
++              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
+                      upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
++              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
+                      upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
++              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
+                      (u32)rdev->mc.vram_start);
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
++              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
+                      (u32)rdev->mc.vram_start);
+       }
+-      if (rdev->num_crtc >= 6) {
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
+-
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
+-                     upper_32_bits(rdev->mc.vram_start));
+-              WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
+-              WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
+-                     (u32)rdev->mc.vram_start);
+-      }
+-
+       WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
+       WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
+-      /* Unlock host access */
++
++      /* unblackout the MC */
++      tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
++      tmp &= ~BLACKOUT_MODE_MASK;
++      WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
++      /* allow CPU access */
++      WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
++
++      for (i = 0; i < rdev->num_crtc; i++) {
++              if (save->crtc_enabled) {
++                      if (ASIC_IS_DCE6(rdev)) {
++                              tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
++                              tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
++                              WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
++                      } else {
++                              tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
++                              tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
++                              WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
++                      }
++                      /* wait for the next frame */
++                      frame_count = radeon_get_vblank_counter(rdev, i);
++                      for (j = 0; j < rdev->usec_timeout; j++) {
++                              if (radeon_get_vblank_counter(rdev, i) != frame_count)
++                                      break;
++                              udelay(1);
++                      }
++              }
++      }
++      /* Unlock vga access */
+       WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
+       mdelay(1);
+       WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
+--- a/drivers/gpu/drm/radeon/evergreen_reg.h
++++ b/drivers/gpu/drm/radeon/evergreen_reg.h
+@@ -218,6 +218,8 @@
+ #define EVERGREEN_CRTC_CONTROL                          0x6e70
+ #       define EVERGREEN_CRTC_MASTER_EN                 (1 << 0)
+ #       define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24)
++#define EVERGREEN_CRTC_BLANK_CONTROL                    0x6e74
++#       define EVERGREEN_CRTC_BLANK_DATA_EN             (1 << 8)
+ #define EVERGREEN_CRTC_STATUS                           0x6e8c
+ #       define EVERGREEN_CRTC_V_BLANK                   (1 << 0)
+ #define EVERGREEN_CRTC_STATUS_POSITION                  0x6e90
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -77,6 +77,10 @@
+ #define       CONFIG_MEMSIZE                                  0x5428
++#define       BIF_FB_EN                                               0x5490
++#define               FB_READ_EN                                      (1 << 0)
++#define               FB_WRITE_EN                                     (1 << 1)
++
+ #define       CP_STRMOUT_CNTL                                 0x84FC
+ #define       CP_COHER_CNTL                                   0x85F0
+@@ -200,6 +204,9 @@
+ #define               NOOFCHAN_MASK                                   0x00003000
+ #define MC_SHARED_CHREMAP                                     0x2008
++#define MC_SHARED_BLACKOUT_CNTL                       0x20ac
++#define               BLACKOUT_MODE_MASK                      0x00000007
++
+ #define       MC_ARB_RAMCFG                                   0x2760
+ #define               NOOFBANK_SHIFT                                  0
+ #define               NOOFBANK_MASK                                   0x00000003
+--- a/drivers/gpu/drm/radeon/radeon_asic.h
++++ b/drivers/gpu/drm/radeon/radeon_asic.h
+@@ -400,6 +400,7 @@ void r700_cp_fini(struct radeon_device *
+ struct evergreen_mc_save {
+       u32 vga_render_control;
+       u32 vga_hdp_control;
++      bool crtc_enabled[RADEON_MAX_CRTCS];
+ };
+ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev);
diff --git a/queue-3.4/drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch b/queue-3.4/drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch
new file mode 100644 (file)
index 0000000..332d8f5
--- /dev/null
@@ -0,0 +1,30 @@
+From 804cc4a0ad3a896ca295f771a28c6eb36ced7903 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 19 Nov 2012 09:11:27 -0500
+Subject: drm/radeon: properly track the crtc not_enabled case evergreen_mc_stop()
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 804cc4a0ad3a896ca295f771a28c6eb36ced7903 upstream.
+
+The save struct is not initialized previously so explicitly
+mark the crtcs as not used when they are not in use.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -1164,6 +1164,8 @@ void evergreen_mc_stop(struct radeon_dev
+                                       break;
+                               udelay(1);
+                       }
++              } else {
++                      save->crtc_enabled[i] = false;
+               }
+       }
diff --git a/queue-3.4/series b/queue-3.4/series
new file mode 100644 (file)
index 0000000..5d7672d
--- /dev/null
@@ -0,0 +1,5 @@
+dove-attempt-to-fix-pmu-rtc-interrupts.patch
+dove-fix-irq_to_pmu.patch
+drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch
+drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch
+drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch