--- /dev/null
+From 695daf1a8e731a4b5b89de89a61f32a4d7ad7094 Mon Sep 17 00:00:00 2001
+From: Leo Liu <leo.liu@amd.com>
+Date: Mon, 28 Apr 2014 09:40:22 -0400
+Subject: drm/radeon: check buffer relocation offset
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Leo Liu <leo.liu@amd.com>
+
+commit 695daf1a8e731a4b5b89de89a61f32a4d7ad7094 upstream.
+
+Signed-off-by: Leo Liu <leo.liu@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_uvd.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_uvd.c
++++ b/drivers/gpu/drm/radeon/radeon_uvd.c
+@@ -465,6 +465,10 @@ static int radeon_uvd_cs_reloc(struct ra
+ cmd = radeon_get_ib_value(p, p->idx) >> 1;
+
+ if (cmd < 0x4) {
++ if (end <= start) {
++ DRM_ERROR("invalid reloc offset %X!\n", offset);
++ return -EINVAL;
++ }
+ if ((end - start) < buf_sizes[cmd]) {
+ DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd,
+ (unsigned)(end - start), buf_sizes[cmd]);
--- /dev/null
+From 76e6dcece841faebbee78895780e8209ff40d922 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Fri, 18 Apr 2014 09:08:11 -0400
+Subject: drm/radeon: disable dpm on rv770 by default
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit 76e6dcece841faebbee78895780e8209ff40d922 upstream.
+
+There seem to be stability issues on a number of cards.
+
+bugs:
+https://bugs.freedesktop.org/show_bug.cgi?id=76286
+https://bugzilla.redhat.com/show_bug.cgi?id=1085785
+https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=741619
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: matthias.graf@st.ovqu.de
+Cc: bp@alien8.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_pm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -1240,6 +1240,7 @@ int radeon_pm_init(struct radeon_device
+ case CHIP_RV670:
+ case CHIP_RS780:
+ case CHIP_RS880:
++ case CHIP_RV770:
+ case CHIP_BARTS:
+ case CHIP_TURKS:
+ case CHIP_CAICOS:
+@@ -1256,7 +1257,6 @@ int radeon_pm_init(struct radeon_device
+ else
+ rdev->pm.pm_method = PM_METHOD_PROFILE;
+ break;
+- case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
--- /dev/null
+From 73acacc7397fe854ed2ab75f1c940fa00faaf15e Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 15 Apr 2014 12:44:35 -0400
+Subject: drm/radeon: don't allow runpm=1 on systems with out ATPX
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit 73acacc7397fe854ed2ab75f1c940fa00faaf15e upstream.
+
+vgaswitcheroo and the ATPX ACPI methods are required to
+power down the dGPU.
+
+bug:
+https://bugzilla.kernel.org/show_bug.cgi?id=73901
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_kms.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_kms.c
+@@ -107,11 +107,9 @@ int radeon_driver_load_kms(struct drm_de
+ flags |= RADEON_IS_PCI;
+ }
+
+- if (radeon_runtime_pm == 1)
+- flags |= RADEON_IS_PX;
+- else if ((radeon_runtime_pm == -1) &&
+- radeon_has_atpx() &&
+- ((flags & RADEON_IS_IGP) == 0))
++ if ((radeon_runtime_pm != 0) &&
++ radeon_has_atpx() &&
++ ((flags & RADEON_IS_IGP) == 0))
+ flags |= RADEON_IS_PX;
+
+ /* radeon_device_init should report only fatal error
--- /dev/null
+From e9a4099a59cc598a44006059dd775c25e422b772 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 15 Apr 2014 12:44:34 -0400
+Subject: drm/radeon: fix ATPX detection on non-VGA GPUs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit e9a4099a59cc598a44006059dd775c25e422b772 upstream.
+
+Some newer PX laptops have the pci device class
+set to DISPLAY_OTHER rather than DISPLAY_VGA. This
+properly detects ATPX on those laptops.
+
+Based on a patch from: Pali Rohár <pali.rohar@gmail.com>
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: airlied@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_atpx_handler.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+@@ -528,6 +528,13 @@ static bool radeon_atpx_detect(void)
+ has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
+ }
+
++ /* some newer PX laptops mark the dGPU as a non-VGA display device */
++ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
++ vga_count++;
++
++ has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
++ }
++
+ if (has_atpx && vga_count == 2) {
+ acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer);
+ printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n",
--- /dev/null
+From 7e95cfb0b797678cd3493ca0322ef2675547a0bc Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 22 Apr 2014 08:17:18 -0400
+Subject: drm/radeon: fix count in cik_sdma_ring_test()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit 7e95cfb0b797678cd3493ca0322ef2675547a0bc upstream.
+
+Should be 5 rather than 4.
+
+Noticed-by: Mathias Fröhlich <Mathias.Froehlich@gmx.net>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/cik_sdma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/cik_sdma.c
++++ b/drivers/gpu/drm/radeon/cik_sdma.c
+@@ -599,7 +599,7 @@ int cik_sdma_ring_test(struct radeon_dev
+ tmp = 0xCAFEDEAD;
+ writel(tmp, ptr);
+
+- r = radeon_ring_lock(rdev, ring, 4);
++ r = radeon_ring_lock(rdev, ring, 5);
+ if (r) {
+ DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r);
+ return r;
--- /dev/null
+From 3ed9a335cfc64b2c83545f341cdddf2347b12b97 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 15 Apr 2014 12:44:33 -0400
+Subject: drm/radeon/pm: don't walk the crtc list before it has been initialized (v2)
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit 3ed9a335cfc64b2c83545f341cdddf2347b12b97 upstream.
+
+Avoids a crash in certain cases when thermal irqs are generated
+before the display structures have been initialized.
+
+v2: fix the vblank and vrefresh helpers as well
+
+bug:
+https://bugzilla.kernel.org/show_bug.cgi?id=73931
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/r600_dpm.c | 35 +++++++++++++++++++----------------
+ drivers/gpu/drm/radeon/radeon_pm.c | 28 ++++++++++++++++------------
+ 2 files changed, 35 insertions(+), 28 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/r600_dpm.c
++++ b/drivers/gpu/drm/radeon/r600_dpm.c
+@@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct rade
+ u32 line_time_us, vblank_lines;
+ u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
+
+- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+- radeon_crtc = to_radeon_crtc(crtc);
+- if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+- line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
+- radeon_crtc->hw_mode.clock;
+- vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
+- radeon_crtc->hw_mode.crtc_vdisplay +
+- (radeon_crtc->v_border * 2);
+- vblank_time_us = vblank_lines * line_time_us;
+- break;
++ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
++ radeon_crtc = to_radeon_crtc(crtc);
++ if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
++ line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
++ radeon_crtc->hw_mode.clock;
++ vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
++ radeon_crtc->hw_mode.crtc_vdisplay +
++ (radeon_crtc->v_border * 2);
++ vblank_time_us = vblank_lines * line_time_us;
++ break;
++ }
+ }
+ }
+
+@@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_
+ struct radeon_crtc *radeon_crtc;
+ u32 vrefresh = 0;
+
+- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+- radeon_crtc = to_radeon_crtc(crtc);
+- if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+- vrefresh = radeon_crtc->hw_mode.vrefresh;
+- break;
++ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
++ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
++ radeon_crtc = to_radeon_crtc(crtc);
++ if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
++ vrefresh = radeon_crtc->hw_mode.vrefresh;
++ break;
++ }
+ }
+ }
+-
+ return vrefresh;
+ }
+
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -1384,12 +1384,14 @@ static void radeon_pm_compute_clocks_old
+
+ rdev->pm.active_crtcs = 0;
+ rdev->pm.active_crtc_count = 0;
+- list_for_each_entry(crtc,
+- &ddev->mode_config.crtc_list, head) {
+- radeon_crtc = to_radeon_crtc(crtc);
+- if (radeon_crtc->enabled) {
+- rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
+- rdev->pm.active_crtc_count++;
++ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
++ list_for_each_entry(crtc,
++ &ddev->mode_config.crtc_list, head) {
++ radeon_crtc = to_radeon_crtc(crtc);
++ if (radeon_crtc->enabled) {
++ rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id);
++ rdev->pm.active_crtc_count++;
++ }
+ }
+ }
+
+@@ -1456,12 +1458,14 @@ static void radeon_pm_compute_clocks_dpm
+ /* update active crtc counts */
+ rdev->pm.dpm.new_active_crtcs = 0;
+ rdev->pm.dpm.new_active_crtc_count = 0;
+- list_for_each_entry(crtc,
+- &ddev->mode_config.crtc_list, head) {
+- radeon_crtc = to_radeon_crtc(crtc);
+- if (crtc->enabled) {
+- rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
+- rdev->pm.dpm.new_active_crtc_count++;
++ if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
++ list_for_each_entry(crtc,
++ &ddev->mode_config.crtc_list, head) {
++ radeon_crtc = to_radeon_crtc(crtc);
++ if (crtc->enabled) {
++ rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
++ rdev->pm.dpm.new_active_crtc_count++;
++ }
+ }
+ }
+
--- /dev/null
+From cb3e4e7c59e4b43ac378631f6101f5c8de3a27a5 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexdeucher@gmail.com>
+Date: Tue, 15 Apr 2014 12:44:32 -0400
+Subject: drm/radeon: properly unregister hwmon interface (v2)
+
+From: Alex Deucher <alexdeucher@gmail.com>
+
+commit cb3e4e7c59e4b43ac378631f6101f5c8de3a27a5 upstream.
+
+Need to properly unregister the hwmon device on driver
+unload.
+
+v2: minor clean up
+
+bug:
+https://bugzilla.kernel.org/show_bug.cgi?id=73931
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_pm.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -603,7 +603,6 @@ static const struct attribute_group *hwm
+ static int radeon_hwmon_init(struct radeon_device *rdev)
+ {
+ int err = 0;
+- struct device *hwmon_dev;
+
+ switch (rdev->pm.int_thermal_type) {
+ case THERMAL_TYPE_RV6XX:
+@@ -616,11 +615,11 @@ static int radeon_hwmon_init(struct rade
+ case THERMAL_TYPE_KV:
+ if (rdev->asic->pm.get_temperature == NULL)
+ return err;
+- hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
+- "radeon", rdev,
+- hwmon_groups);
+- if (IS_ERR(hwmon_dev)) {
+- err = PTR_ERR(hwmon_dev);
++ rdev->pm.int_hwmon_dev = hwmon_device_register_with_groups(rdev->dev,
++ "radeon", rdev,
++ hwmon_groups);
++ if (IS_ERR(rdev->pm.int_hwmon_dev)) {
++ err = PTR_ERR(rdev->pm.int_hwmon_dev);
+ dev_err(rdev->dev,
+ "Unable to register hwmon device: %d\n", err);
+ }
+@@ -632,6 +631,12 @@ static int radeon_hwmon_init(struct rade
+ return err;
+ }
+
++static void radeon_hwmon_fini(struct radeon_device *rdev)
++{
++ if (rdev->pm.int_hwmon_dev)
++ hwmon_device_unregister(rdev->pm.int_hwmon_dev);
++}
++
+ static void radeon_dpm_thermal_work_handler(struct work_struct *work)
+ {
+ struct radeon_device *rdev =
+@@ -1331,6 +1336,8 @@ static void radeon_pm_fini_old(struct ra
+ device_remove_file(rdev->dev, &dev_attr_power_method);
+ }
+
++ radeon_hwmon_fini(rdev);
++
+ if (rdev->pm.power_state)
+ kfree(rdev->pm.power_state);
+ }
+@@ -1350,6 +1357,8 @@ static void radeon_pm_fini_dpm(struct ra
+ }
+ radeon_dpm_fini(rdev);
+
++ radeon_hwmon_fini(rdev);
++
+ if (rdev->pm.power_state)
+ kfree(rdev->pm.power_state);
+ }
--- /dev/null
+From f5d636d2a74b755879feec35e14a259de52ccc07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 23 Apr 2014 20:46:06 +0200
+Subject: drm/radeon: use pflip irq on R600+ v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit f5d636d2a74b755879feec35e14a259de52ccc07 upstream.
+
+Testing the update pending bit directly after issuing an
+update is nonsense cause depending on the pixel clock the
+CRTC needs a bit of time to execute the flip even when we
+are in the VBLANK period.
+
+This is just a non invasive patch to solve the problem at
+hand, a more complete and cleaner solution should follow
+in the next merge window.
+
+Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=76564
+
+v2: fix source IDs for CRTC2-6
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/cik.c | 76 ++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/radeon/cikd.h | 9 +++
+ drivers/gpu/drm/radeon/evergreen.c | 28 ++++++++---
+ drivers/gpu/drm/radeon/r600.c | 13 ++++-
+ drivers/gpu/drm/radeon/radeon.h | 6 ++
+ drivers/gpu/drm/radeon/radeon_display.c | 4 +
+ drivers/gpu/drm/radeon/si.c | 28 ++++++++---
+ 7 files changed, 147 insertions(+), 17 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/cik.c
++++ b/drivers/gpu/drm/radeon/cik.c
+@@ -6672,6 +6672,19 @@ static void cik_disable_interrupt_state(
+ WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
+ WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
+ }
++ /* pflip */
++ if (rdev->num_crtc >= 2) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
++ }
++ if (rdev->num_crtc >= 4) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
++ }
++ if (rdev->num_crtc >= 6) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
++ }
+
+ /* dac hotplug */
+ WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
+@@ -7028,6 +7041,25 @@ int cik_irq_set(struct radeon_device *rd
+ WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
+ }
+
++ if (rdev->num_crtc >= 2) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ }
++ if (rdev->num_crtc >= 4) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ }
++ if (rdev->num_crtc >= 6) {
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ }
++
+ WREG32(DC_HPD1_INT_CONTROL, hpd1);
+ WREG32(DC_HPD2_INT_CONTROL, hpd2);
+ WREG32(DC_HPD3_INT_CONTROL, hpd3);
+@@ -7064,6 +7096,29 @@ static inline void cik_irq_ack(struct ra
+ rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
+ rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6);
+
++ rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC0_REGISTER_OFFSET);
++ rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC1_REGISTER_OFFSET);
++ if (rdev->num_crtc >= 4) {
++ rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC2_REGISTER_OFFSET);
++ rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC3_REGISTER_OFFSET);
++ }
++ if (rdev->num_crtc >= 6) {
++ rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC4_REGISTER_OFFSET);
++ rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS +
++ EVERGREEN_CRTC5_REGISTER_OFFSET);
++ }
++
++ if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
++ if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)
+ WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)
+@@ -7074,6 +7129,12 @@ static inline void cik_irq_ack(struct ra
+ WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
+
+ if (rdev->num_crtc >= 4) {
++ if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
++ if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+ WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+@@ -7085,6 +7146,12 @@ static inline void cik_irq_ack(struct ra
+ }
+
+ if (rdev->num_crtc >= 6) {
++ if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
++ if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
++ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+ WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+@@ -7436,6 +7503,15 @@ restart_ih:
+ break;
+ }
+ break;
++ case 8: /* D1 page flip */
++ case 10: /* D2 page flip */
++ case 12: /* D3 page flip */
++ case 14: /* D4 page flip */
++ case 16: /* D5 page flip */
++ case 18: /* D6 page flip */
++ DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
++ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
++ break;
+ case 42: /* HPD hotplug */
+ switch (src_data) {
+ case 0:
+--- a/drivers/gpu/drm/radeon/cikd.h
++++ b/drivers/gpu/drm/radeon/cikd.h
+@@ -882,6 +882,15 @@
+ # define DC_HPD6_RX_INTERRUPT (1 << 18)
+ #define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780
+
++/* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */
++#define GRPH_INT_STATUS 0x6858
++# define GRPH_PFLIP_INT_OCCURRED (1 << 0)
++# define GRPH_PFLIP_INT_CLEAR (1 << 8)
++/* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */
++#define GRPH_INT_CONTROL 0x685c
++# define GRPH_PFLIP_INT_MASK (1 << 0)
++# define GRPH_PFLIP_INT_TYPE (1 << 8)
++
+ #define DAC_AUTODETECT_INT_CONTROL 0x67c8
+
+ #define DC_HPD1_INT_STATUS 0x601c
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -4375,7 +4375,6 @@ int evergreen_irq_set(struct radeon_devi
+ u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
+ u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
+ u32 grbm_int_cntl = 0;
+- u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
+ u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0;
+ u32 dma_cntl, dma_cntl1 = 0;
+ u32 thermal_int = 0;
+@@ -4558,15 +4557,21 @@ int evergreen_irq_set(struct radeon_devi
+ WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
+ }
+
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ if (rdev->num_crtc >= 4) {
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ }
+ if (rdev->num_crtc >= 6) {
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ }
+
+ WREG32(DC_HPD1_INT_CONTROL, hpd1);
+@@ -4955,6 +4960,15 @@ restart_ih:
+ break;
+ }
+ break;
++ case 8: /* D1 page flip */
++ case 10: /* D2 page flip */
++ case 12: /* D3 page flip */
++ case 14: /* D4 page flip */
++ case 16: /* D5 page flip */
++ case 18: /* D6 page flip */
++ DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
++ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
++ break;
+ case 42: /* HPD hotplug */
+ switch (src_data) {
+ case 0:
+--- a/drivers/gpu/drm/radeon/r600.c
++++ b/drivers/gpu/drm/radeon/r600.c
+@@ -3509,7 +3509,6 @@ int r600_irq_set(struct radeon_device *r
+ u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
+ u32 grbm_int_cntl = 0;
+ u32 hdmi0, hdmi1;
+- u32 d1grph = 0, d2grph = 0;
+ u32 dma_cntl;
+ u32 thermal_int = 0;
+
+@@ -3618,8 +3617,8 @@ int r600_irq_set(struct radeon_device *r
+ WREG32(CP_INT_CNTL, cp_int_cntl);
+ WREG32(DMA_CNTL, dma_cntl);
+ WREG32(DxMODE_INT_MASK, mode_int);
+- WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph);
+- WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph);
++ WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
++ WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
+ WREG32(GRBM_INT_CNTL, grbm_int_cntl);
+ if (ASIC_IS_DCE3(rdev)) {
+ WREG32(DC_HPD1_INT_CONTROL, hpd1);
+@@ -3922,6 +3921,14 @@ restart_ih:
+ break;
+ }
+ break;
++ case 9: /* D1 pflip */
++ DRM_DEBUG("IH: D1 flip\n");
++ radeon_crtc_handle_flip(rdev, 0);
++ break;
++ case 11: /* D2 pflip */
++ DRM_DEBUG("IH: D2 flip\n");
++ radeon_crtc_handle_flip(rdev, 1);
++ break;
+ case 19: /* HPD/DAC hotplug */
+ switch (src_data) {
+ case 0:
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -733,6 +733,12 @@ struct cik_irq_stat_regs {
+ u32 disp_int_cont4;
+ u32 disp_int_cont5;
+ u32 disp_int_cont6;
++ u32 d1grph_int;
++ u32 d2grph_int;
++ u32 d3grph_int;
++ u32 d4grph_int;
++ u32 d5grph_int;
++ u32 d6grph_int;
+ };
+
+ union radeon_irq_stat_regs {
+--- a/drivers/gpu/drm/radeon/radeon_display.c
++++ b/drivers/gpu/drm/radeon/radeon_display.c
+@@ -282,6 +282,10 @@ void radeon_crtc_handle_flip(struct rade
+ u32 update_pending;
+ int vpos, hpos;
+
++ /* can happen during initialization */
++ if (radeon_crtc == NULL)
++ return;
++
+ spin_lock_irqsave(&rdev->ddev->event_lock, flags);
+ work = radeon_crtc->unpin_work;
+ if (work == NULL ||
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -5788,7 +5788,6 @@ int si_irq_set(struct radeon_device *rde
+ u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
+ u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0;
+ u32 grbm_int_cntl = 0;
+- u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
+ u32 dma_cntl, dma_cntl1;
+ u32 thermal_int = 0;
+
+@@ -5927,16 +5926,22 @@ int si_irq_set(struct radeon_device *rde
+ }
+
+ if (rdev->num_crtc >= 2) {
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ }
+ if (rdev->num_crtc >= 4) {
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ }
+ if (rdev->num_crtc >= 6) {
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
++ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET,
++ GRPH_PFLIP_INT_MASK);
+ }
+
+ if (!ASIC_IS_NODCE(rdev)) {
+@@ -6300,6 +6305,15 @@ restart_ih:
+ break;
+ }
+ break;
++ case 8: /* D1 page flip */
++ case 10: /* D2 page flip */
++ case 12: /* D3 page flip */
++ case 14: /* D4 page flip */
++ case 16: /* D5 page flip */
++ case 18: /* D6 page flip */
++ DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
++ radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
++ break;
+ case 42: /* HPD hotplug */
+ switch (src_data) {
+ case 0:
--- /dev/null
+From e45187620f9fc103edf68fa5ea78e73033e1668c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 10 Apr 2014 16:11:36 +0200
+Subject: drm/radeon/uvd: use lower clocks on old UVD to boot v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+
+commit e45187620f9fc103edf68fa5ea78e73033e1668c upstream.
+
+Some RV7xx generation hardware crashes after you
+raise the UVD clocks for the first time. Try to
+avoid this by using the lower clocks to boot these.
+
+Workaround for: https://bugzilla.kernel.org/show_bug.cgi?id=71891
+
+v2: lower clocks on IB test as well
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/uvd_v1_0.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/uvd_v1_0.c
++++ b/drivers/gpu/drm/radeon/uvd_v1_0.c
+@@ -83,7 +83,10 @@ int uvd_v1_0_init(struct radeon_device *
+ int r;
+
+ /* raise clocks while booting up the VCPU */
+- radeon_set_uvd_clocks(rdev, 53300, 40000);
++ if (rdev->family < CHIP_RV740)
++ radeon_set_uvd_clocks(rdev, 10000, 10000);
++ else
++ radeon_set_uvd_clocks(rdev, 53300, 40000);
+
+ r = uvd_v1_0_start(rdev);
+ if (r)
+@@ -407,7 +410,10 @@ int uvd_v1_0_ib_test(struct radeon_devic
+ struct radeon_fence *fence = NULL;
+ int r;
+
+- r = radeon_set_uvd_clocks(rdev, 53300, 40000);
++ if (rdev->family < CHIP_RV740)
++ r = radeon_set_uvd_clocks(rdev, 10000, 10000);
++ else
++ r = radeon_set_uvd_clocks(rdev, 53300, 40000);
+ if (r) {
+ DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
+ return r;
drm-radeon-re-enable-mclk-dpm-on-r7-260x-asics.patch
drm-radeon-si-make-sure-mc-ucode-is-loaded-before-checking-the-size.patch
drm-radeon-ci-make-sure-mc-ucode-is-loaded-before-checking-the-size.patch
+drm-radeon-properly-unregister-hwmon-interface-v2.patch
+drm-radeon-fix-atpx-detection-on-non-vga-gpus.patch
+drm-radeon-pm-don-t-walk-the-crtc-list-before-it-has-been-initialized-v2.patch
+drm-radeon-don-t-allow-runpm-1-on-systems-with-out-atpx.patch
+drm-radeon-disable-dpm-on-rv770-by-default.patch
+drm-radeon-fix-count-in-cik_sdma_ring_test.patch
+drm-radeon-uvd-use-lower-clocks-on-old-uvd-to-boot-v2.patch
+drm-radeon-use-pflip-irq-on-r600-v2.patch
+drm-radeon-check-buffer-relocation-offset.patch