From c944e6213c0a2cc4e7e0029846fb44e726ba0891 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 6 Dec 2012 10:14:23 -0800 Subject: [PATCH] 3.4-stable patches 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 --- ...ve-attempt-to-fix-pmu-rtc-interrupts.patch | 63 ++++ queue-3.4/dove-fix-irq_to_pmu.patch | 34 +++ ...-use-radeon_crtc-for-vblank-callback.patch | 61 ++++ ...le-mc_stop-mc_resume-on-evergreen-v2.patch | 271 ++++++++++++++++++ ...c-not_enabled-case-evergreen_mc_stop.patch | 30 ++ queue-3.4/series | 5 + 6 files changed, 464 insertions(+) create mode 100644 queue-3.4/dove-attempt-to-fix-pmu-rtc-interrupts.patch create mode 100644 queue-3.4/dove-fix-irq_to_pmu.patch create mode 100644 queue-3.4/drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch create mode 100644 queue-3.4/drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch create mode 100644 queue-3.4/drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch create mode 100644 queue-3.4/series 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 index 00000000000..60df3bf2063 --- /dev/null +++ b/queue-3.4/dove-attempt-to-fix-pmu-rtc-interrupts.patch @@ -0,0 +1,63 @@ +From 5d3df935426271016b895aecaa247101b4bfa35e Mon Sep 17 00:00:00 2001 +From: Russell King - ARM Linux +Date: Sun, 18 Nov 2012 16:29:44 +0000 +Subject: Dove: Attempt to fix PMU/RTC interrupts + +From: Russell King - ARM Linux + +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 +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..04b5b3f358c --- /dev/null +++ b/queue-3.4/dove-fix-irq_to_pmu.patch @@ -0,0 +1,34 @@ +From d356cf5a74afa32b40decca3c9dd88bc3cd63eb5 Mon Sep 17 00:00:00 2001 +From: Russell King - ARM Linux +Date: Sun, 18 Nov 2012 16:39:32 +0000 +Subject: Dove: Fix irq_to_pmu() + +From: Russell King - ARM Linux + +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 +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..07e43065f2d --- /dev/null +++ b/queue-3.4/drm-radeon-dce4-don-t-use-radeon_crtc-for-vblank-callback.patch @@ -0,0 +1,61 @@ +From 4a15903db02026728d0cf2755c6fabae16b8db6a Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 15 Aug 2012 17:13:53 -0400 +Subject: drm/radeon/dce4+: don't use radeon_crtc for vblank callback + +From: Alex Deucher + +commit 4a15903db02026728d0cf2755c6fabae16b8db6a upstream. + +This might be called before we've allocated the radeon_crtcs + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..946c575fffc --- /dev/null +++ b/queue-3.4/drm-radeon-properly-handle-mc_stop-mc_resume-on-evergreen-v2.patch @@ -0,0 +1,271 @@ +From 62444b7462a2b98bc78d68736c03a7c4e66ba7e2 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Wed, 15 Aug 2012 17:18:42 -0400 +Subject: drm/radeon: properly handle mc_stop/mc_resume on evergreen+ (v2) + +From: Alex Deucher + +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 +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..332d8f548fe --- /dev/null +++ b/queue-3.4/drm-radeon-properly-track-the-crtc-not_enabled-case-evergreen_mc_stop.patch @@ -0,0 +1,30 @@ +From 804cc4a0ad3a896ca295f771a28c6eb36ced7903 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5d7672d8439 --- /dev/null +++ b/queue-3.4/series @@ -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 -- 2.47.3