فهرست منبع

Merge branch 'drm-next-3.14-wip' of git://people.freedesktop.org/~agd5f/linux into drm-next

This is the drm-next pull for radeon for 3.14. Highlights include:
- dpm rework which fixes some issues and allows us to enable dpm by
default on CIK parts
- enable clockgating on CIK parts
- pci config reset.  This is a bus-level chip reset that can be more
reliable than soft reset in certain cases.  Disabled by default.  Enable
with the hard_reset module option.
- big endian rptr/wrptr update fixes
- lots of debugfs improvements
- some driver cleanup patches from Rashika Kheria
- bug fixes

* 'drm-next-3.14-wip' of git://people.freedesktop.org/~agd5f/linux: (50 commits)
  drm/radeon: implement pci config reset for CIK (v3)
  drm/radeon: implement pci config reset for SI (v2)
  drm/radeon: implement pci config reset for evergreen/cayman (v2)
  drm/radeon: implement pci config reset for r6xx/7xx (v3)
  drm/radeon: add pci config hard reset
  drm/radeon: add hard_reset module parameter
  drm/radeon: skip colorbuffer checking if COLOR_INFO.FORMAT is set to INVALID
  radeon/pm: Guard access to rdev->pm.power_state array
  drivers: gpu: Move prototype declarations to header file radeon_mode.h from radeon_atombios.c and radeon_combios.c
  drivers: gpu: Move prototype declaration to header file radeon_mode.h
  drm/radeon: move com/atombios scratch reg functions to radeon_mode.h
  drm/radeon/dpm: make some functions static for TN
  drm/radeon/dpm: make some functions static for sumo
  drm/radeon/dpm: make some functions static for CI
  drivers: gpu: Include appropriate header file in ci_smc.c
  drivers: gpu: Move prototype declaration to header file radeon_mode.h from atombios_i2c.c
  drivers: gpu: Include appropriate header file in si_smc.c and remove prototype declaration from header file sislands_smc.h
  drivers: gpu: Add static keyword to the definition of KMS_INVALID_IOCTL in radeon_kms.c
  drivers: gpu: Mark function as static in r600_hdmi.c
  drivers: gpu: Mark function as static in radeon_gem.c
  ...
Dave Airlie 11 سال پیش
والد
کامیت
e95d9f9550
66فایلهای تغییر یافته به همراه1572 افزوده شده و 614 حذف شده
  1. 0 2
      drivers/gpu/drm/radeon/atombios_i2c.c
  2. 5 15
      drivers/gpu/drm/radeon/btc_dpm.c
  3. 24 46
      drivers/gpu/drm/radeon/ci_dpm.c
  4. 1 0
      drivers/gpu/drm/radeon/ci_smc.c
  5. 230 38
      drivers/gpu/drm/radeon/cik.c
  6. 69 0
      drivers/gpu/drm/radeon/cik_sdma.c
  7. 11 0
      drivers/gpu/drm/radeon/cikd.h
  8. 0 15
      drivers/gpu/drm/radeon/cypress_dpm.c
  9. 76 19
      drivers/gpu/drm/radeon/evergreen.c
  10. 4 1
      drivers/gpu/drm/radeon/evergreen_cs.c
  11. 1 0
      drivers/gpu/drm/radeon/evergreen_reg.h
  12. 4 0
      drivers/gpu/drm/radeon/evergreend.h
  13. 15 33
      drivers/gpu/drm/radeon/kv_dpm.c
  14. 92 27
      drivers/gpu/drm/radeon/ni.c
  15. 69 0
      drivers/gpu/drm/radeon/ni_dma.c
  16. 6 15
      drivers/gpu/drm/radeon/ni_dpm.c
  17. 2 2
      drivers/gpu/drm/radeon/pptable.h
  18. 37 1
      drivers/gpu/drm/radeon/r100.c
  19. 7 0
      drivers/gpu/drm/radeon/r300.c
  20. 7 0
      drivers/gpu/drm/radeon/r420.c
  21. 5 0
      drivers/gpu/drm/radeon/r520.c
  22. 114 10
      drivers/gpu/drm/radeon/r600.c
  23. 4 1
      drivers/gpu/drm/radeon/r600_cs.c
  24. 10 3
      drivers/gpu/drm/radeon/r600_dma.c
  25. 18 2
      drivers/gpu/drm/radeon/r600_dpm.c
  26. 0 2
      drivers/gpu/drm/radeon/r600_dpm.h
  27. 1 1
      drivers/gpu/drm/radeon/r600_hdmi.c
  28. 7 0
      drivers/gpu/drm/radeon/r600d.h
  29. 14 3
      drivers/gpu/drm/radeon/radeon.h
  30. 48 37
      drivers/gpu/drm/radeon/radeon_asic.c
  31. 51 13
      drivers/gpu/drm/radeon/radeon_asic.h
  32. 0 17
      drivers/gpu/drm/radeon/radeon_atombios.c
  33. 0 16
      drivers/gpu/drm/radeon/radeon_combios.c
  34. 0 9
      drivers/gpu/drm/radeon/radeon_connectors.c
  35. 18 5
      drivers/gpu/drm/radeon/radeon_device.c
  36. 13 4
      drivers/gpu/drm/radeon/radeon_display.c
  37. 4 0
      drivers/gpu/drm/radeon/radeon_drv.c
  38. 2 0
      drivers/gpu/drm/radeon/radeon_fence.c
  39. 1 1
      drivers/gpu/drm/radeon/radeon_gem.c
  40. 3 0
      drivers/gpu/drm/radeon/radeon_i2c.c
  41. 3 2
      drivers/gpu/drm/radeon/radeon_kms.c
  42. 34 0
      drivers/gpu/drm/radeon/radeon_mode.h
  43. 1 1
      drivers/gpu/drm/radeon/radeon_object.c
  44. 82 64
      drivers/gpu/drm/radeon/radeon_pm.c
  45. 39 53
      drivers/gpu/drm/radeon/radeon_ring.c
  46. 4 2
      drivers/gpu/drm/radeon/radeon_sa.c
  47. 160 35
      drivers/gpu/drm/radeon/radeon_ttm.c
  48. 7 0
      drivers/gpu/drm/radeon/rs400.c
  49. 7 0
      drivers/gpu/drm/radeon/rs600.c
  50. 7 0
      drivers/gpu/drm/radeon/rs690.c
  51. 0 8
      drivers/gpu/drm/radeon/rs780_dpm.c
  52. 7 0
      drivers/gpu/drm/radeon/rv515.c
  53. 0 10
      drivers/gpu/drm/radeon/rv6xx_dpm.c
  54. 44 11
      drivers/gpu/drm/radeon/rv770.c
  55. 11 4
      drivers/gpu/drm/radeon/rv770_dpm.c
  56. 0 4
      drivers/gpu/drm/radeon/rv770_dpm.h
  57. 7 0
      drivers/gpu/drm/radeon/rv770d.h
  58. 131 21
      drivers/gpu/drm/radeon/si.c
  59. 18 42
      drivers/gpu/drm/radeon/si_dpm.c
  60. 1 0
      drivers/gpu/drm/radeon/si_smc.c
  61. 7 0
      drivers/gpu/drm/radeon/sid.h
  62. 0 2
      drivers/gpu/drm/radeon/sislands_smc.h
  63. 14 7
      drivers/gpu/drm/radeon/sumo_dpm.c
  64. 0 1
      drivers/gpu/drm/radeon/sumo_smc.c
  65. 15 6
      drivers/gpu/drm/radeon/trinity_dpm.c
  66. 0 3
      drivers/gpu/drm/radeon/trinity_smc.c

+ 0 - 2
drivers/gpu/drm/radeon/atombios_i2c.c

@@ -27,8 +27,6 @@
 #include "radeon.h"
 #include "radeon.h"
 #include "atom.h"
 #include "atom.h"
 
 
-extern void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
-
 #define TARGET_HW_I2C_CLOCK 50
 #define TARGET_HW_I2C_CLOCK 50
 
 
 /* these are a limitation of ProcessI2cChannelTransaction not the hw */
 /* these are a limitation of ProcessI2cChannelTransaction not the hw */

+ 5 - 15
drivers/gpu/drm/radeon/btc_dpm.c

@@ -49,6 +49,7 @@ struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 
 
+extern int ni_mc_load_microcode(struct radeon_device *rdev);
 
 
 //********* BARTS **************//
 //********* BARTS **************//
 static const u32 barts_cgcg_cgls_default[] =
 static const u32 barts_cgcg_cgls_default[] =
@@ -2510,21 +2511,6 @@ int btc_dpm_enable(struct radeon_device *rdev)
 	if (eg_pi->ls_clock_gating)
 	if (eg_pi->ls_clock_gating)
 		btc_ls_clock_gating_enable(rdev, true);
 		btc_ls_clock_gating_enable(rdev, true);
 
 
-	if (rdev->irq.installed &&
-	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
-		PPSMC_Result result;
-
-		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-		if (ret)
-			return ret;
-		rdev->irq.dpm_thermal = true;
-		radeon_irq_set(rdev);
-		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
-
-		if (result != PPSMC_Result_OK)
-			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
-	}
-
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 
 
 	btc_init_stutter_mode(rdev);
 	btc_init_stutter_mode(rdev);
@@ -2576,7 +2562,11 @@ void btc_dpm_disable(struct radeon_device *rdev)
 void btc_dpm_setup_asic(struct radeon_device *rdev)
 void btc_dpm_setup_asic(struct radeon_device *rdev)
 {
 {
 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int r;
 
 
+	r = ni_mc_load_microcode(rdev);
+	if (r)
+		DRM_ERROR("Failed to load MC firmware!\n");
 	rv770_get_memory_type(rdev);
 	rv770_get_memory_type(rdev);
 	rv740_read_clock_registers(rdev);
 	rv740_read_clock_registers(rdev);
 	btc_read_arb_registers(rdev);
 	btc_read_arb_registers(rdev);

+ 24 - 46
drivers/gpu/drm/radeon/ci_dpm.c

@@ -171,8 +171,7 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
 						     struct atom_voltage_table *voltage_table);
 						     struct atom_voltage_table *voltage_table);
 extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
 extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
 extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
 extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
-extern void cik_update_cg(struct radeon_device *rdev,
-			  u32 block, bool enable);
+extern int ci_mc_load_microcode(struct radeon_device *rdev);
 
 
 static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev,
 static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev,
 					 struct atom_voltage_table_entry *voltage_table,
 					 struct atom_voltage_table_entry *voltage_table,
@@ -4503,8 +4502,8 @@ static void ci_get_memory_type(struct radeon_device *rdev)
 
 
 }
 }
 
 
-void ci_update_current_ps(struct radeon_device *rdev,
-			  struct radeon_ps *rps)
+static void ci_update_current_ps(struct radeon_device *rdev,
+				 struct radeon_ps *rps)
 {
 {
 	struct ci_ps *new_ps = ci_get_ps(rps);
 	struct ci_ps *new_ps = ci_get_ps(rps);
 	struct ci_power_info *pi = ci_get_pi(rdev);
 	struct ci_power_info *pi = ci_get_pi(rdev);
@@ -4514,8 +4513,8 @@ void ci_update_current_ps(struct radeon_device *rdev,
 	pi->current_rps.ps_priv = &pi->current_ps;
 	pi->current_rps.ps_priv = &pi->current_ps;
 }
 }
 
 
-void ci_update_requested_ps(struct radeon_device *rdev,
-			    struct radeon_ps *rps)
+static void ci_update_requested_ps(struct radeon_device *rdev,
+				   struct radeon_ps *rps)
 {
 {
 	struct ci_ps *new_ps = ci_get_ps(rps);
 	struct ci_ps *new_ps = ci_get_ps(rps);
 	struct ci_power_info *pi = ci_get_pi(rdev);
 	struct ci_power_info *pi = ci_get_pi(rdev);
@@ -4549,6 +4548,11 @@ void ci_dpm_post_set_power_state(struct radeon_device *rdev)
 
 
 void ci_dpm_setup_asic(struct radeon_device *rdev)
 void ci_dpm_setup_asic(struct radeon_device *rdev)
 {
 {
+	int r;
+
+	r = ci_mc_load_microcode(rdev);
+	if (r)
+		DRM_ERROR("Failed to load MC firmware!\n");
 	ci_read_clock_registers(rdev);
 	ci_read_clock_registers(rdev);
 	ci_get_memory_type(rdev);
 	ci_get_memory_type(rdev);
 	ci_enable_acpi_power_management(rdev);
 	ci_enable_acpi_power_management(rdev);
@@ -4561,13 +4565,6 @@ int ci_dpm_enable(struct radeon_device *rdev)
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	int ret;
 	int ret;
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_MC |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_UVD |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	if (ci_is_smc_running(rdev))
 	if (ci_is_smc_running(rdev))
 		return -EINVAL;
 		return -EINVAL;
 	if (pi->voltage_control != CISLANDS_VOLTAGE_CONTROL_NONE) {
 	if (pi->voltage_control != CISLANDS_VOLTAGE_CONTROL_NONE) {
@@ -4665,6 +4662,18 @@ int ci_dpm_enable(struct radeon_device *rdev)
 		DRM_ERROR("ci_enable_power_containment failed\n");
 		DRM_ERROR("ci_enable_power_containment failed\n");
 		return ret;
 		return ret;
 	}
 	}
+
+	ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	ci_update_current_ps(rdev, boot_ps);
+
+	return 0;
+}
+
+int ci_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 #if 0
 #if 0
@@ -4685,19 +4694,8 @@ int ci_dpm_enable(struct radeon_device *rdev)
 #endif
 #endif
 	}
 	}
 
 
-	ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
-
 	ci_dpm_powergate_uvd(rdev, true);
 	ci_dpm_powergate_uvd(rdev, true);
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_MC |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_UVD |
-			     RADEON_CG_BLOCK_HDP), true);
-
-	ci_update_current_ps(rdev, boot_ps);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -4706,12 +4704,6 @@ void ci_dpm_disable(struct radeon_device *rdev)
 	struct ci_power_info *pi = ci_get_pi(rdev);
 	struct ci_power_info *pi = ci_get_pi(rdev);
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_MC |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_UVD |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	ci_dpm_powergate_uvd(rdev, false);
 	ci_dpm_powergate_uvd(rdev, false);
 
 
 	if (!ci_is_smc_running(rdev))
 	if (!ci_is_smc_running(rdev))
@@ -4742,13 +4734,6 @@ int ci_dpm_set_power_state(struct radeon_device *rdev)
 	struct radeon_ps *old_ps = &pi->current_rps;
 	struct radeon_ps *old_ps = &pi->current_rps;
 	int ret;
 	int ret;
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_MC |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_UVD |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	ci_find_dpm_states_clocks_in_dpm_table(rdev, new_ps);
 	ci_find_dpm_states_clocks_in_dpm_table(rdev, new_ps);
 	if (pi->pcie_performance_request)
 	if (pi->pcie_performance_request)
 		ci_request_link_speed_change_before_state_change(rdev, new_ps, old_ps);
 		ci_request_link_speed_change_before_state_change(rdev, new_ps, old_ps);
@@ -4804,13 +4789,6 @@ int ci_dpm_set_power_state(struct radeon_device *rdev)
 	if (pi->pcie_performance_request)
 	if (pi->pcie_performance_request)
 		ci_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
 		ci_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_MC |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_UVD |
-			     RADEON_CG_BLOCK_HDP), true);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -5023,8 +5001,8 @@ static int ci_parse_power_table(struct radeon_device *rdev)
 	return 0;
 	return 0;
 }
 }
 
 
-int ci_get_vbios_boot_values(struct radeon_device *rdev,
-			     struct ci_vbios_boot_state *boot_state)
+static int ci_get_vbios_boot_values(struct radeon_device *rdev,
+				    struct ci_vbios_boot_state *boot_state)
 {
 {
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	struct radeon_mode_info *mode_info = &rdev->mode_info;
 	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
 	int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);

+ 1 - 0
drivers/gpu/drm/radeon/ci_smc.c

@@ -28,6 +28,7 @@
 #include "cikd.h"
 #include "cikd.h"
 #include "ppsmc.h"
 #include "ppsmc.h"
 #include "radeon_ucode.h"
 #include "radeon_ucode.h"
+#include "ci_dpm.h"
 
 
 static int ci_set_smc_sram_address(struct radeon_device *rdev,
 static int ci_set_smc_sram_address(struct radeon_device *rdev,
 				   u32 smc_address, u32 limit)
 				   u32 smc_address, u32 limit)

+ 230 - 38
drivers/gpu/drm/radeon/cik.c

@@ -1697,7 +1697,7 @@ static void cik_srbm_select(struct radeon_device *rdev,
  * Load the GDDR MC ucode into the hw (CIK).
  * Load the GDDR MC ucode into the hw (CIK).
  * Returns 0 on success, error on failure.
  * Returns 0 on success, error on failure.
  */
  */
-static int ci_mc_load_microcode(struct radeon_device *rdev)
+int ci_mc_load_microcode(struct radeon_device *rdev)
 {
 {
 	const __be32 *fw_data;
 	const __be32 *fw_data;
 	u32 running, blackout = 0;
 	u32 running, blackout = 0;
@@ -4015,15 +4015,43 @@ static int cik_cp_gfx_resume(struct radeon_device *rdev)
 	return 0;
 	return 0;
 }
 }
 
 
-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
-			      struct radeon_ring *ring)
+u32 cik_gfx_get_rptr(struct radeon_device *rdev,
+		     struct radeon_ring *ring)
 {
 {
 	u32 rptr;
 	u32 rptr;
 
 
+	if (rdev->wb.enabled)
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	else
+		rptr = RREG32(CP_RB0_RPTR);
 
 
+	return rptr;
+}
+
+u32 cik_gfx_get_wptr(struct radeon_device *rdev,
+		     struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	wptr = RREG32(CP_RB0_WPTR);
+
+	return wptr;
+}
+
+void cik_gfx_set_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring)
+{
+	WREG32(CP_RB0_WPTR, ring->wptr);
+	(void)RREG32(CP_RB0_WPTR);
+}
+
+u32 cik_compute_get_rptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring)
+{
+	u32 rptr;
 
 
 	if (rdev->wb.enabled) {
 	if (rdev->wb.enabled) {
-		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
 	} else {
 	} else {
 		mutex_lock(&rdev->srbm_mutex);
 		mutex_lock(&rdev->srbm_mutex);
 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4035,13 +4063,14 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
 	return rptr;
 	return rptr;
 }
 }
 
 
-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
-			      struct radeon_ring *ring)
+u32 cik_compute_get_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring)
 {
 {
 	u32 wptr;
 	u32 wptr;
 
 
 	if (rdev->wb.enabled) {
 	if (rdev->wb.enabled) {
-		wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
+		/* XXX check if swapping is necessary on BE */
+		wptr = rdev->wb.wb[ring->wptr_offs/4];
 	} else {
 	} else {
 		mutex_lock(&rdev->srbm_mutex);
 		mutex_lock(&rdev->srbm_mutex);
 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
 		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
@@ -4053,10 +4082,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
 	return wptr;
 	return wptr;
 }
 }
 
 
-void cik_compute_ring_set_wptr(struct radeon_device *rdev,
-			       struct radeon_ring *ring)
+void cik_compute_set_wptr(struct radeon_device *rdev,
+			  struct radeon_ring *ring)
 {
 {
-	rdev->wb.wb[ring->wptr_offs/4] = cpu_to_le32(ring->wptr);
+	/* XXX check if swapping is necessary on BE */
+	rdev->wb.wb[ring->wptr_offs/4] = ring->wptr;
 	WDOORBELL32(ring->doorbell_index, ring->wptr);
 	WDOORBELL32(ring->doorbell_index, ring->wptr);
 }
 }
 
 
@@ -4850,6 +4880,160 @@ static void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
 	cik_print_gpu_status_regs(rdev);
 	cik_print_gpu_status_regs(rdev);
 }
 }
 
 
+struct kv_reset_save_regs {
+	u32 gmcon_reng_execute;
+	u32 gmcon_misc;
+	u32 gmcon_misc3;
+};
+
+static void kv_save_regs_for_reset(struct radeon_device *rdev,
+				   struct kv_reset_save_regs *save)
+{
+	save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE);
+	save->gmcon_misc = RREG32(GMCON_MISC);
+	save->gmcon_misc3 = RREG32(GMCON_MISC3);
+
+	WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP);
+	WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE |
+						STCTRL_STUTTER_EN));
+}
+
+static void kv_restore_regs_for_reset(struct radeon_device *rdev,
+				      struct kv_reset_save_regs *save)
+{
+	int i;
+
+	WREG32(GMCON_PGFSM_WRITE, 0);
+	WREG32(GMCON_PGFSM_CONFIG, 0x200010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0);
+	WREG32(GMCON_PGFSM_CONFIG, 0x300010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x210000);
+	WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x21003);
+	WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x2b00);
+	WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0);
+	WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x420000);
+	WREG32(GMCON_PGFSM_CONFIG, 0x100010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x120202);
+	WREG32(GMCON_PGFSM_CONFIG, 0x500010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x3e3e36);
+	WREG32(GMCON_PGFSM_CONFIG, 0x600010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x373f3e);
+	WREG32(GMCON_PGFSM_CONFIG, 0x700010ff);
+
+	for (i = 0; i < 5; i++)
+		WREG32(GMCON_PGFSM_WRITE, 0);
+
+	WREG32(GMCON_PGFSM_WRITE, 0x3e1332);
+	WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff);
+
+	WREG32(GMCON_MISC3, save->gmcon_misc3);
+	WREG32(GMCON_MISC, save->gmcon_misc);
+	WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute);
+}
+
+static void cik_gpu_pci_config_reset(struct radeon_device *rdev)
+{
+	struct evergreen_mc_save save;
+	struct kv_reset_save_regs kv_save = { 0 };
+	u32 tmp, i;
+
+	dev_info(rdev->dev, "GPU pci config reset\n");
+
+	/* disable dpm? */
+
+	/* disable cg/pg */
+	cik_fini_pg(rdev);
+	cik_fini_cg(rdev);
+
+	/* Disable GFX parsing/prefetching */
+	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
+
+	/* Disable MEC parsing/prefetching */
+	WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT);
+
+	/* sdma0 */
+	tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET);
+	tmp |= SDMA_HALT;
+	WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp);
+	/* sdma1 */
+	tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET);
+	tmp |= SDMA_HALT;
+	WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp);
+	/* XXX other engines? */
+
+	/* halt the rlc, disable cp internal ints */
+	cik_rlc_stop(rdev);
+
+	udelay(50);
+
+	/* disable mem access */
+	evergreen_mc_stop(rdev, &save);
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
+	}
+
+	if (rdev->flags & RADEON_IS_IGP)
+		kv_save_regs_for_reset(rdev, &kv_save);
+
+	/* disable BM */
+	pci_clear_master(rdev->pdev);
+	/* reset */
+	radeon_pci_config_reset(rdev);
+
+	udelay(100);
+
+	/* wait for asic to come out of reset */
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
+			break;
+		udelay(1);
+	}
+
+	/* does asic init need to be run first??? */
+	if (rdev->flags & RADEON_IS_IGP)
+		kv_restore_regs_for_reset(rdev, &kv_save);
+}
+
 /**
 /**
  * cik_asic_reset - soft reset GPU
  * cik_asic_reset - soft reset GPU
  *
  *
@@ -4868,10 +5052,17 @@ int cik_asic_reset(struct radeon_device *rdev)
 	if (reset_mask)
 	if (reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, true);
 		r600_set_bios_scratch_engine_hung(rdev, true);
 
 
+	/* try soft reset */
 	cik_gpu_soft_reset(rdev, reset_mask);
 	cik_gpu_soft_reset(rdev, reset_mask);
 
 
 	reset_mask = cik_gpu_check_soft_reset(rdev);
 	reset_mask = cik_gpu_check_soft_reset(rdev);
 
 
+	/* try pci config reset */
+	if (reset_mask && radeon_hard_reset)
+		cik_gpu_pci_config_reset(rdev);
+
+	reset_mask = cik_gpu_check_soft_reset(rdev);
+
 	if (!reset_mask)
 	if (!reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, false);
 		r600_set_bios_scratch_engine_hung(rdev, false);
 
 
@@ -7501,26 +7692,7 @@ static int cik_startup(struct radeon_device *rdev)
 
 
 	cik_mc_program(rdev);
 	cik_mc_program(rdev);
 
 
-	if (rdev->flags & RADEON_IS_IGP) {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
-		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
-			r = cik_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
-	} else {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
-		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
-		    !rdev->mc_fw) {
-			r = cik_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
-
+	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
 		r = ci_mc_load_microcode(rdev);
 		r = ci_mc_load_microcode(rdev);
 		if (r) {
 		if (r) {
 			DRM_ERROR("Failed to load MC firmware!\n");
 			DRM_ERROR("Failed to load MC firmware!\n");
@@ -7625,7 +7797,6 @@ static int cik_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     CP_RB0_RPTR, CP_RB0_WPTR,
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -7634,7 +7805,6 @@ static int cik_startup(struct radeon_device *rdev)
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
-			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -7646,7 +7816,6 @@ static int cik_startup(struct radeon_device *rdev)
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	/* type-2 packets are deprecated on MEC, use type-3 instead */
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
-			     CP_HQD_PQ_RPTR, CP_HQD_PQ_WPTR,
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 			     PACKET3(PACKET3_NOP, 0x3FFF));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -7658,16 +7827,12 @@ static int cik_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET,
-			     SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET,
 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-			     SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET,
-			     SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET,
 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
 			     SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -7683,7 +7848,6 @@ static int cik_startup(struct radeon_device *rdev)
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	if (ring->ring_size) {
 	if (ring->ring_size) {
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
 				     RADEON_CP_PACKET2);
 				     RADEON_CP_PACKET2);
 		if (!r)
 		if (!r)
 			r = uvd_v1_0_init(rdev);
 			r = uvd_v1_0_init(rdev);
@@ -7729,6 +7893,8 @@ int cik_resume(struct radeon_device *rdev)
 	/* init golden registers */
 	/* init golden registers */
 	cik_init_golden_registers(rdev);
 	cik_init_golden_registers(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = cik_startup(rdev);
 	r = cik_startup(rdev);
 	if (r) {
 	if (r) {
@@ -7752,6 +7918,7 @@ int cik_resume(struct radeon_device *rdev)
  */
  */
 int cik_suspend(struct radeon_device *rdev)
 int cik_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	dce6_audio_fini(rdev);
 	dce6_audio_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	cik_cp_enable(rdev, false);
 	cik_cp_enable(rdev, false);
@@ -7833,6 +8000,30 @@ int cik_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (rdev->flags & RADEON_IS_IGP) {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
+			r = cik_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	} else {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw ||
+		    !rdev->mc_fw) {
+			r = cik_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring->ring_obj = NULL;
 	ring->ring_obj = NULL;
 	r600_ring_init(rdev, ring, 1024 * 1024);
 	r600_ring_init(rdev, ring, 1024 * 1024);
@@ -7913,6 +8104,7 @@ int cik_init(struct radeon_device *rdev)
  */
  */
 void cik_fini(struct radeon_device *rdev)
 void cik_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	cik_cp_fini(rdev);
 	cik_cp_fini(rdev);
 	cik_sdma_fini(rdev);
 	cik_sdma_fini(rdev);
 	cik_fini_pg(rdev);
 	cik_fini_pg(rdev);

+ 69 - 0
drivers/gpu/drm/radeon/cik_sdma.c

@@ -51,6 +51,75 @@ u32 cik_gpu_check_soft_reset(struct radeon_device *rdev);
  * buffers.
  * buffers.
  */
  */
 
 
+/**
+ * cik_sdma_get_rptr - get the current read pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current rptr from the hardware (CIK+).
+ */
+uint32_t cik_sdma_get_rptr(struct radeon_device *rdev,
+			   struct radeon_ring *ring)
+{
+	u32 rptr, reg;
+
+	if (rdev->wb.enabled) {
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	} else {
+		if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+			reg = SDMA0_GFX_RB_RPTR + SDMA0_REGISTER_OFFSET;
+		else
+			reg = SDMA0_GFX_RB_RPTR + SDMA1_REGISTER_OFFSET;
+
+		rptr = RREG32(reg);
+	}
+
+	return (rptr & 0x3fffc) >> 2;
+}
+
+/**
+ * cik_sdma_get_wptr - get the current write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current wptr from the hardware (CIK+).
+ */
+uint32_t cik_sdma_get_wptr(struct radeon_device *rdev,
+			   struct radeon_ring *ring)
+{
+	u32 reg;
+
+	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+		reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
+	else
+		reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
+
+	return (RREG32(reg) & 0x3fffc) >> 2;
+}
+
+/**
+ * cik_sdma_set_wptr - commit the write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Write the wptr back to the hardware (CIK+).
+ */
+void cik_sdma_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring)
+{
+	u32 reg;
+
+	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+		reg = SDMA0_GFX_RB_WPTR + SDMA0_REGISTER_OFFSET;
+	else
+		reg = SDMA0_GFX_RB_WPTR + SDMA1_REGISTER_OFFSET;
+
+	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+}
+
 /**
 /**
  * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
  * cik_sdma_ring_ib_execute - Schedule an IB on the DMA engine
  *
  *

+ 11 - 0
drivers/gpu/drm/radeon/cikd.h

@@ -724,6 +724,17 @@
 
 
 #define ATC_MISC_CG           				0x3350
 #define ATC_MISC_CG           				0x3350
 
 
+#define GMCON_RENG_EXECUTE				0x3508
+#define 	RENG_EXECUTE_ON_PWR_UP			(1 << 0)
+#define GMCON_MISC					0x350c
+#define 	RENG_EXECUTE_ON_REG_UPDATE		(1 << 11)
+#define 	STCTRL_STUTTER_EN			(1 << 16)
+
+#define GMCON_PGFSM_CONFIG				0x3538
+#define GMCON_PGFSM_WRITE				0x353c
+#define GMCON_PGFSM_READ				0x3540
+#define GMCON_MISC3					0x3544
+
 #define MC_SEQ_CNTL_3                                     0x3600
 #define MC_SEQ_CNTL_3                                     0x3600
 #       define CAC_EN                                     (1 << 31)
 #       define CAC_EN                                     (1 << 31)
 #define MC_SEQ_G5PDX_CTRL                                 0x3604
 #define MC_SEQ_G5PDX_CTRL                                 0x3604

+ 0 - 15
drivers/gpu/drm/radeon/cypress_dpm.c

@@ -1905,21 +1905,6 @@ int cypress_dpm_enable(struct radeon_device *rdev)
 	if (pi->mg_clock_gating)
 	if (pi->mg_clock_gating)
 		cypress_mg_clock_gating_enable(rdev, true);
 		cypress_mg_clock_gating_enable(rdev, true);
 
 
-	if (rdev->irq.installed &&
-	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
-		PPSMC_Result result;
-
-		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-		if (ret)
-			return ret;
-		rdev->irq.dpm_thermal = true;
-		radeon_irq_set(rdev);
-		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
-
-		if (result != PPSMC_Result_OK)
-			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
-	}
-
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 
 
 	return 0;
 	return 0;

+ 76 - 19
drivers/gpu/drm/radeon/evergreen.c

@@ -146,6 +146,7 @@ extern u32 si_get_csb_size(struct radeon_device *rdev);
 extern void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
 extern void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
 extern u32 cik_get_csb_size(struct radeon_device *rdev);
 extern u32 cik_get_csb_size(struct radeon_device *rdev);
 extern void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
 extern void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
+extern void rv770_set_clk_bypass_mode(struct radeon_device *rdev);
 
 
 static const u32 evergreen_golden_registers[] =
 static const u32 evergreen_golden_registers[] =
 {
 {
@@ -3867,6 +3868,48 @@ static void evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
 	evergreen_print_gpu_status_regs(rdev);
 	evergreen_print_gpu_status_regs(rdev);
 }
 }
 
 
+void evergreen_gpu_pci_config_reset(struct radeon_device *rdev)
+{
+	struct evergreen_mc_save save;
+	u32 tmp, i;
+
+	dev_info(rdev->dev, "GPU pci config reset\n");
+
+	/* disable dpm? */
+
+	/* Disable CP parsing/prefetching */
+	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
+	udelay(50);
+	/* Disable DMA */
+	tmp = RREG32(DMA_RB_CNTL);
+	tmp &= ~DMA_RB_ENABLE;
+	WREG32(DMA_RB_CNTL, tmp);
+	/* XXX other engines? */
+
+	/* halt the rlc */
+	r600_rlc_stop(rdev);
+
+	udelay(50);
+
+	/* set mclk/sclk to bypass */
+	rv770_set_clk_bypass_mode(rdev);
+	/* disable BM */
+	pci_clear_master(rdev->pdev);
+	/* disable mem access */
+	evergreen_mc_stop(rdev, &save);
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
+	}
+	/* reset */
+	radeon_pci_config_reset(rdev);
+	/* wait for asic to come out of reset */
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
+			break;
+		udelay(1);
+	}
+}
+
 int evergreen_asic_reset(struct radeon_device *rdev)
 int evergreen_asic_reset(struct radeon_device *rdev)
 {
 {
 	u32 reset_mask;
 	u32 reset_mask;
@@ -3876,10 +3919,17 @@ int evergreen_asic_reset(struct radeon_device *rdev)
 	if (reset_mask)
 	if (reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, true);
 		r600_set_bios_scratch_engine_hung(rdev, true);
 
 
+	/* try soft reset */
 	evergreen_gpu_soft_reset(rdev, reset_mask);
 	evergreen_gpu_soft_reset(rdev, reset_mask);
 
 
 	reset_mask = evergreen_gpu_check_soft_reset(rdev);
 	reset_mask = evergreen_gpu_check_soft_reset(rdev);
 
 
+	/* try pci config reset */
+	if (reset_mask && radeon_hard_reset)
+		evergreen_gpu_pci_config_reset(rdev);
+
+	reset_mask = evergreen_gpu_check_soft_reset(rdev);
+
 	if (!reset_mask)
 	if (!reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, false);
 		r600_set_bios_scratch_engine_hung(rdev, false);
 
 
@@ -5109,27 +5159,12 @@ static int evergreen_startup(struct radeon_device *rdev)
 
 
 	evergreen_mc_program(rdev);
 	evergreen_mc_program(rdev);
 
 
-	if (ASIC_IS_DCE5(rdev)) {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
-			r = ni_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
+	if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) {
 		r = ni_mc_load_microcode(rdev);
 		r = ni_mc_load_microcode(rdev);
 		if (r) {
 		if (r) {
 			DRM_ERROR("Failed to load MC firmware!\n");
 			DRM_ERROR("Failed to load MC firmware!\n");
 			return r;
 			return r;
 		}
 		}
-	} else {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
-			r = r600_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
 	}
 	}
 
 
 	if (rdev->flags & RADEON_IS_AGP) {
 	if (rdev->flags & RADEON_IS_AGP) {
@@ -5199,14 +5234,12 @@ static int evergreen_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     DMA_RB_RPTR, DMA_RB_WPTR,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -5224,7 +5257,6 @@ static int evergreen_startup(struct radeon_device *rdev)
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	if (ring->ring_size) {
 	if (ring->ring_size) {
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
 				     RADEON_CP_PACKET2);
 				     RADEON_CP_PACKET2);
 		if (!r)
 		if (!r)
 			r = uvd_v1_0_init(rdev);
 			r = uvd_v1_0_init(rdev);
@@ -5267,6 +5299,8 @@ int evergreen_resume(struct radeon_device *rdev)
 	/* init golden registers */
 	/* init golden registers */
 	evergreen_init_golden_registers(rdev);
 	evergreen_init_golden_registers(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = evergreen_startup(rdev);
 	r = evergreen_startup(rdev);
 	if (r) {
 	if (r) {
@@ -5281,6 +5315,7 @@ int evergreen_resume(struct radeon_device *rdev)
 
 
 int evergreen_suspend(struct radeon_device *rdev)
 int evergreen_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	uvd_v1_0_fini(rdev);
 	uvd_v1_0_fini(rdev);
 	radeon_uvd_suspend(rdev);
 	radeon_uvd_suspend(rdev);
@@ -5357,6 +5392,27 @@ int evergreen_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (ASIC_IS_DCE5(rdev)) {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
+			r = ni_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	} else {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+			r = r600_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
 
@@ -5409,6 +5465,7 @@ int evergreen_init(struct radeon_device *rdev)
 
 
 void evergreen_fini(struct radeon_device *rdev)
 void evergreen_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r700_cp_fini(rdev);
 	r700_cp_fini(rdev);
 	r600_dma_fini(rdev);
 	r600_dma_fini(rdev);

+ 4 - 1
drivers/gpu/drm/radeon/evergreen_cs.c

@@ -967,7 +967,10 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p)
 	if (track->cb_dirty) {
 	if (track->cb_dirty) {
 		tmp = track->cb_target_mask;
 		tmp = track->cb_target_mask;
 		for (i = 0; i < 8; i++) {
 		for (i = 0; i < 8; i++) {
-			if ((tmp >> (i * 4)) & 0xF) {
+			u32 format = G_028C70_FORMAT(track->cb_color_info[i]);
+
+			if (format != V_028C70_COLOR_INVALID &&
+			    (tmp >> (i * 4)) & 0xF) {
 				/* at least one component is enabled */
 				/* at least one component is enabled */
 				if (track->cb_color_bo[i] == NULL) {
 				if (track->cb_color_bo[i] == NULL) {
 					dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
 					dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",

+ 1 - 0
drivers/gpu/drm/radeon/evergreen_reg.h

@@ -33,6 +33,7 @@
 #define EVERGREEN_PIF_PHY0_DATA                         0xc
 #define EVERGREEN_PIF_PHY0_DATA                         0xc
 #define EVERGREEN_PIF_PHY1_INDEX                        0x10
 #define EVERGREEN_PIF_PHY1_INDEX                        0x10
 #define EVERGREEN_PIF_PHY1_DATA                         0x14
 #define EVERGREEN_PIF_PHY1_DATA                         0x14
+#define EVERGREEN_MM_INDEX_HI                           0x18
 
 
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS               0x310
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS               0x310
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH          0x324
 #define EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH          0x324

+ 4 - 0
drivers/gpu/drm/radeon/evergreend.h

@@ -82,12 +82,16 @@
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define		SCLK_MUX_UPDATE				(1 << 26)
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
 #define		SPLL_DITHEN				(1 << 28)
 #define		SPLL_DITHEN				(1 << 28)
+#define	CG_SPLL_STATUS					0x60c
+#define		SPLL_CHG_STATUS				(1 << 1)
 
 
 #define MPLL_CNTL_MODE                                  0x61c
 #define MPLL_CNTL_MODE                                  0x61c
+#       define MPLL_MCLK_SEL                            (1 << 11)
 #       define SS_SSEN                                  (1 << 24)
 #       define SS_SSEN                                  (1 << 24)
 #       define SS_DSMODE_EN                             (1 << 25)
 #       define SS_DSMODE_EN                             (1 << 25)
 
 

+ 15 - 33
drivers/gpu/drm/radeon/kv_dpm.c

@@ -1126,11 +1126,6 @@ int kv_dpm_enable(struct radeon_device *rdev)
 	struct kv_power_info *pi = kv_get_pi(rdev);
 	struct kv_power_info *pi = kv_get_pi(rdev);
 	int ret;
 	int ret;
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	ret = kv_process_firmware_header(rdev);
 	ret = kv_process_firmware_header(rdev);
 	if (ret) {
 	if (ret) {
 		DRM_ERROR("kv_process_firmware_header failed\n");
 		DRM_ERROR("kv_process_firmware_header failed\n");
@@ -1215,6 +1210,21 @@ int kv_dpm_enable(struct radeon_device *rdev)
 
 
 	kv_reset_acp_boot_level(rdev);
 	kv_reset_acp_boot_level(rdev);
 
 
+	ret = kv_smc_bapm_enable(rdev, false);
+	if (ret) {
+		DRM_ERROR("kv_smc_bapm_enable failed\n");
+		return ret;
+	}
+
+	kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return ret;
+}
+
+int kv_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 		ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
 		ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
@@ -1226,35 +1236,17 @@ int kv_dpm_enable(struct radeon_device *rdev)
 		radeon_irq_set(rdev);
 		radeon_irq_set(rdev);
 	}
 	}
 
 
-	ret = kv_smc_bapm_enable(rdev, false);
-	if (ret) {
-		DRM_ERROR("kv_smc_bapm_enable failed\n");
-		return ret;
-	}
-
 	/* powerdown unused blocks for now */
 	/* powerdown unused blocks for now */
 	kv_dpm_powergate_acp(rdev, true);
 	kv_dpm_powergate_acp(rdev, true);
 	kv_dpm_powergate_samu(rdev, true);
 	kv_dpm_powergate_samu(rdev, true);
 	kv_dpm_powergate_vce(rdev, true);
 	kv_dpm_powergate_vce(rdev, true);
 	kv_dpm_powergate_uvd(rdev, true);
 	kv_dpm_powergate_uvd(rdev, true);
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_HDP), true);
-
-	kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
-
 	return ret;
 	return ret;
 }
 }
 
 
 void kv_dpm_disable(struct radeon_device *rdev)
 void kv_dpm_disable(struct radeon_device *rdev)
 {
 {
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	kv_smc_bapm_enable(rdev, false);
 	kv_smc_bapm_enable(rdev, false);
 
 
 	/* powerup blocks */
 	/* powerup blocks */
@@ -1779,11 +1771,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
 	/*struct radeon_ps *old_ps = &pi->current_rps;*/
 	/*struct radeon_ps *old_ps = &pi->current_rps;*/
 	int ret;
 	int ret;
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_HDP), false);
-
 	if (pi->bapm_enable) {
 	if (pi->bapm_enable) {
 		ret = kv_smc_bapm_enable(rdev, rdev->pm.dpm.ac_power);
 		ret = kv_smc_bapm_enable(rdev, rdev->pm.dpm.ac_power);
 		if (ret) {
 		if (ret) {
@@ -1849,11 +1836,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev)
 		}
 		}
 	}
 	}
 
 
-	cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			     RADEON_CG_BLOCK_SDMA |
-			     RADEON_CG_BLOCK_BIF |
-			     RADEON_CG_BLOCK_HDP), true);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 92 - 27
drivers/gpu/drm/radeon/ni.c

@@ -174,6 +174,7 @@ extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
 extern void evergreen_program_aspm(struct radeon_device *rdev);
 extern void evergreen_program_aspm(struct radeon_device *rdev);
 extern void sumo_rlc_fini(struct radeon_device *rdev);
 extern void sumo_rlc_fini(struct radeon_device *rdev);
 extern int sumo_rlc_init(struct radeon_device *rdev);
 extern int sumo_rlc_init(struct radeon_device *rdev);
+extern void evergreen_gpu_pci_config_reset(struct radeon_device *rdev);
 
 
 /* Firmware Names */
 /* Firmware Names */
 MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
 MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
@@ -1386,6 +1387,55 @@ static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
 	}
 	}
 }
 }
 
 
+u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
+			struct radeon_ring *ring)
+{
+	u32 rptr;
+
+	if (rdev->wb.enabled)
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	else {
+		if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
+			rptr = RREG32(CP_RB0_RPTR);
+		else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
+			rptr = RREG32(CP_RB1_RPTR);
+		else
+			rptr = RREG32(CP_RB2_RPTR);
+	}
+
+	return rptr;
+}
+
+u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
+			struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
+		wptr = RREG32(CP_RB0_WPTR);
+	else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
+		wptr = RREG32(CP_RB1_WPTR);
+	else
+		wptr = RREG32(CP_RB2_WPTR);
+
+	return wptr;
+}
+
+void cayman_gfx_set_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring)
+{
+	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
+		WREG32(CP_RB0_WPTR, ring->wptr);
+		(void)RREG32(CP_RB0_WPTR);
+	} else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
+		WREG32(CP_RB1_WPTR, ring->wptr);
+		(void)RREG32(CP_RB1_WPTR);
+	} else {
+		WREG32(CP_RB2_WPTR, ring->wptr);
+		(void)RREG32(CP_RB2_WPTR);
+	}
+}
+
 static int cayman_cp_load_microcode(struct radeon_device *rdev)
 static int cayman_cp_load_microcode(struct radeon_device *rdev)
 {
 {
 	const __be32 *fw_data;
 	const __be32 *fw_data;
@@ -1514,6 +1564,16 @@ static int cayman_cp_resume(struct radeon_device *rdev)
 		CP_RB1_BASE,
 		CP_RB1_BASE,
 		CP_RB2_BASE
 		CP_RB2_BASE
 	};
 	};
+	static const unsigned cp_rb_rptr[] = {
+		CP_RB0_RPTR,
+		CP_RB1_RPTR,
+		CP_RB2_RPTR
+	};
+	static const unsigned cp_rb_wptr[] = {
+		CP_RB0_WPTR,
+		CP_RB1_WPTR,
+		CP_RB2_WPTR
+	};
 	struct radeon_ring *ring;
 	struct radeon_ring *ring;
 	int i, r;
 	int i, r;
 
 
@@ -1572,8 +1632,8 @@ static int cayman_cp_resume(struct radeon_device *rdev)
 		WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
 		WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
 
 
 		ring->rptr = ring->wptr = 0;
 		ring->rptr = ring->wptr = 0;
-		WREG32(ring->rptr_reg, ring->rptr);
-		WREG32(ring->wptr_reg, ring->wptr);
+		WREG32(cp_rb_rptr[i], ring->rptr);
+		WREG32(cp_rb_wptr[i], ring->wptr);
 
 
 		mdelay(1);
 		mdelay(1);
 		WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
 		WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
@@ -1819,8 +1879,10 @@ int cayman_asic_reset(struct radeon_device *rdev)
 
 
 	reset_mask = cayman_gpu_check_soft_reset(rdev);
 	reset_mask = cayman_gpu_check_soft_reset(rdev);
 
 
-	if (!reset_mask)
-		r600_set_bios_scratch_engine_hung(rdev, false);
+	if (reset_mask)
+		evergreen_gpu_pci_config_reset(rdev);
+
+	r600_set_bios_scratch_engine_hung(rdev, false);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -1866,23 +1928,7 @@ static int cayman_startup(struct radeon_device *rdev)
 
 
 	evergreen_mc_program(rdev);
 	evergreen_mc_program(rdev);
 
 
-	if (rdev->flags & RADEON_IS_IGP) {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
-			r = ni_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
-	} else {
-		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
-			r = ni_init_microcode(rdev);
-			if (r) {
-				DRM_ERROR("Failed to load firmware!\n");
-				return r;
-			}
-		}
-
+	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
 		r = ni_mc_load_microcode(rdev);
 		r = ni_mc_load_microcode(rdev);
 		if (r) {
 		if (r) {
 			DRM_ERROR("Failed to load MC firmware!\n");
 			DRM_ERROR("Failed to load MC firmware!\n");
@@ -1969,23 +2015,18 @@ static int cayman_startup(struct radeon_device *rdev)
 	evergreen_irq_set(rdev);
 	evergreen_irq_set(rdev);
 
 
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     CP_RB0_RPTR, CP_RB0_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
-			     DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-			     DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
-			     DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -2004,7 +2045,6 @@ static int cayman_startup(struct radeon_device *rdev)
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	if (ring->ring_size) {
 	if (ring->ring_size) {
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
 				     RADEON_CP_PACKET2);
 				     RADEON_CP_PACKET2);
 		if (!r)
 		if (!r)
 			r = uvd_v1_0_init(rdev);
 			r = uvd_v1_0_init(rdev);
@@ -2051,6 +2091,8 @@ int cayman_resume(struct radeon_device *rdev)
 	/* init golden registers */
 	/* init golden registers */
 	ni_init_golden_registers(rdev);
 	ni_init_golden_registers(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = cayman_startup(rdev);
 	r = cayman_startup(rdev);
 	if (r) {
 	if (r) {
@@ -2063,6 +2105,7 @@ int cayman_resume(struct radeon_device *rdev)
 
 
 int cayman_suspend(struct radeon_device *rdev)
 int cayman_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	if (ASIC_IS_DCE6(rdev))
 	if (ASIC_IS_DCE6(rdev))
 		dce6_audio_fini(rdev);
 		dce6_audio_fini(rdev);
 	else
 	else
@@ -2133,6 +2176,27 @@ int cayman_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (rdev->flags & RADEON_IS_IGP) {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+			r = ni_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	} else {
+		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
+			r = ni_init_microcode(rdev);
+			if (r) {
+				DRM_ERROR("Failed to load firmware!\n");
+				return r;
+			}
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	ring->ring_obj = NULL;
 	ring->ring_obj = NULL;
 	r600_ring_init(rdev, ring, 1024 * 1024);
 	r600_ring_init(rdev, ring, 1024 * 1024);
 
 
@@ -2192,6 +2256,7 @@ int cayman_init(struct radeon_device *rdev)
 
 
 void cayman_fini(struct radeon_device *rdev)
 void cayman_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	cayman_cp_fini(rdev);
 	cayman_cp_fini(rdev);
 	cayman_dma_fini(rdev);
 	cayman_dma_fini(rdev);
 	r600_irq_fini(rdev);
 	r600_irq_fini(rdev);

+ 69 - 0
drivers/gpu/drm/radeon/ni_dma.c

@@ -42,6 +42,75 @@ u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev);
  * Cayman and newer support two asynchronous DMA engines.
  * Cayman and newer support two asynchronous DMA engines.
  */
  */
 
 
+/**
+ * cayman_dma_get_rptr - get the current read pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current rptr from the hardware (cayman+).
+ */
+uint32_t cayman_dma_get_rptr(struct radeon_device *rdev,
+			     struct radeon_ring *ring)
+{
+	u32 rptr, reg;
+
+	if (rdev->wb.enabled) {
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	} else {
+		if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+			reg = DMA_RB_RPTR + DMA0_REGISTER_OFFSET;
+		else
+			reg = DMA_RB_RPTR + DMA1_REGISTER_OFFSET;
+
+		rptr = RREG32(reg);
+	}
+
+	return (rptr & 0x3fffc) >> 2;
+}
+
+/**
+ * cayman_dma_get_wptr - get the current write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Get the current wptr from the hardware (cayman+).
+ */
+uint32_t cayman_dma_get_wptr(struct radeon_device *rdev,
+			   struct radeon_ring *ring)
+{
+	u32 reg;
+
+	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+		reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
+	else
+		reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;
+
+	return (RREG32(reg) & 0x3fffc) >> 2;
+}
+
+/**
+ * cayman_dma_set_wptr - commit the write pointer
+ *
+ * @rdev: radeon_device pointer
+ * @ring: radeon ring pointer
+ *
+ * Write the wptr back to the hardware (cayman+).
+ */
+void cayman_dma_set_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring)
+{
+	u32 reg;
+
+	if (ring->idx == R600_RING_TYPE_DMA_INDEX)
+		reg = DMA_RB_WPTR + DMA0_REGISTER_OFFSET;
+	else
+		reg = DMA_RB_WPTR + DMA1_REGISTER_OFFSET;
+
+	WREG32(reg, (ring->wptr << 2) & 0x3fffc);
+}
+
 /**
 /**
  * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
  * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
  *
  *

+ 6 - 15
drivers/gpu/drm/radeon/ni_dpm.c

@@ -720,6 +720,8 @@ static const u32 cayman_sysls_enable[] =
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 
 
+extern int ni_mc_load_microcode(struct radeon_device *rdev);
+
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
 {
 {
         struct ni_power_info *pi = rdev->pm.dpm.priv;
         struct ni_power_info *pi = rdev->pm.dpm.priv;
@@ -3565,7 +3567,11 @@ void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
 void ni_dpm_setup_asic(struct radeon_device *rdev)
 void ni_dpm_setup_asic(struct radeon_device *rdev)
 {
 {
 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+	int r;
 
 
+	r = ni_mc_load_microcode(rdev);
+	if (r)
+		DRM_ERROR("Failed to load MC firmware!\n");
 	ni_read_clock_registers(rdev);
 	ni_read_clock_registers(rdev);
 	btc_read_arb_registers(rdev);
 	btc_read_arb_registers(rdev);
 	rv770_get_memory_type(rdev);
 	rv770_get_memory_type(rdev);
@@ -3710,21 +3716,6 @@ int ni_dpm_enable(struct radeon_device *rdev)
 	if (eg_pi->ls_clock_gating)
 	if (eg_pi->ls_clock_gating)
 		ni_ls_clockgating_enable(rdev, true);
 		ni_ls_clockgating_enable(rdev, true);
 
 
-	if (rdev->irq.installed &&
-	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
-		PPSMC_Result result;
-
-		ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, 0xff * 1000);
-		if (ret)
-			return ret;
-		rdev->irq.dpm_thermal = true;
-		radeon_irq_set(rdev);
-		result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
-
-		if (result != PPSMC_Result_OK)
-			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
-	}
-
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 
 
 	ni_update_current_ps(rdev, boot_ps);
 	ni_update_current_ps(rdev, boot_ps);

+ 2 - 2
drivers/gpu/drm/radeon/pptable.h

@@ -23,7 +23,7 @@
 #ifndef _PPTABLE_H
 #ifndef _PPTABLE_H
 #define _PPTABLE_H
 #define _PPTABLE_H
 
 
-#pragma pack(push, 1)
+#pragma pack(1)
 
 
 typedef struct _ATOM_PPLIB_THERMALCONTROLLER
 typedef struct _ATOM_PPLIB_THERMALCONTROLLER
 
 
@@ -677,6 +677,6 @@ typedef struct _ATOM_PPLIB_PPM_Table
       ULONG  ulTjmax;
       ULONG  ulTjmax;
 } ATOM_PPLIB_PPM_Table;
 } ATOM_PPLIB_PPM_Table;
 
 
-#pragma pack(pop)
+#pragma pack()
 
 
 #endif
 #endif

+ 37 - 1
drivers/gpu/drm/radeon/r100.c

@@ -1050,6 +1050,36 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
 	return err;
 	return err;
 }
 }
 
 
+u32 r100_gfx_get_rptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring)
+{
+	u32 rptr;
+
+	if (rdev->wb.enabled)
+		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
+	else
+		rptr = RREG32(RADEON_CP_RB_RPTR);
+
+	return rptr;
+}
+
+u32 r100_gfx_get_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	wptr = RREG32(RADEON_CP_RB_WPTR);
+
+	return wptr;
+}
+
+void r100_gfx_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring)
+{
+	WREG32(RADEON_CP_RB_WPTR, ring->wptr);
+	(void)RREG32(RADEON_CP_RB_WPTR);
+}
+
 static void r100_cp_load_microcode(struct radeon_device *rdev)
 static void r100_cp_load_microcode(struct radeon_device *rdev)
 {
 {
 	const __be32 *fw_data;
 	const __be32 *fw_data;
@@ -1102,7 +1132,6 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
 	ring_size = (1 << (rb_bufsz + 1)) * 4;
 	ring_size = (1 << (rb_bufsz + 1)) * 4;
 	r100_cp_load_microcode(rdev);
 	r100_cp_load_microcode(rdev);
 	r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r) {
 	if (r) {
 		return r;
 		return r;
@@ -3913,6 +3942,8 @@ int r100_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r100_startup(rdev);
 	r = r100_startup(rdev);
 	if (r) {
 	if (r) {
@@ -3923,6 +3954,7 @@ int r100_resume(struct radeon_device *rdev)
 
 
 int r100_suspend(struct radeon_device *rdev)
 int r100_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
 	r100_irq_disable(rdev);
 	r100_irq_disable(rdev);
@@ -3933,6 +3965,7 @@ int r100_suspend(struct radeon_device *rdev)
 
 
 void r100_fini(struct radeon_device *rdev)
 void r100_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_ib_pool_fini(rdev);
@@ -4039,6 +4072,9 @@ int r100_init(struct radeon_device *rdev)
 	}
 	}
 	r100_set_safe_registers(rdev);
 	r100_set_safe_registers(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r100_startup(rdev);
 	r = r100_startup(rdev);
 	if (r) {
 	if (r) {

+ 7 - 0
drivers/gpu/drm/radeon/r300.c

@@ -1430,6 +1430,8 @@ int r300_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r300_startup(rdev);
 	r = r300_startup(rdev);
 	if (r) {
 	if (r) {
@@ -1440,6 +1442,7 @@ int r300_resume(struct radeon_device *rdev)
 
 
 int r300_suspend(struct radeon_device *rdev)
 int r300_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
 	r100_irq_disable(rdev);
 	r100_irq_disable(rdev);
@@ -1452,6 +1455,7 @@ int r300_suspend(struct radeon_device *rdev)
 
 
 void r300_fini(struct radeon_device *rdev)
 void r300_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_ib_pool_fini(rdev);
@@ -1538,6 +1542,9 @@ int r300_init(struct radeon_device *rdev)
 	}
 	}
 	r300_set_reg_safe(rdev);
 	r300_set_reg_safe(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r300_startup(rdev);
 	r = r300_startup(rdev);
 	if (r) {
 	if (r) {

+ 7 - 0
drivers/gpu/drm/radeon/r420.c

@@ -325,6 +325,8 @@ int r420_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r420_startup(rdev);
 	r = r420_startup(rdev);
 	if (r) {
 	if (r) {
@@ -335,6 +337,7 @@ int r420_resume(struct radeon_device *rdev)
 
 
 int r420_suspend(struct radeon_device *rdev)
 int r420_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r420_cp_errata_fini(rdev);
 	r420_cp_errata_fini(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
@@ -348,6 +351,7 @@ int r420_suspend(struct radeon_device *rdev)
 
 
 void r420_fini(struct radeon_device *rdev)
 void r420_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_ib_pool_fini(rdev);
@@ -444,6 +448,9 @@ int r420_init(struct radeon_device *rdev)
 	}
 	}
 	r420_set_reg_safe(rdev);
 	r420_set_reg_safe(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r420_startup(rdev);
 	r = r420_startup(rdev);
 	if (r) {
 	if (r) {

+ 5 - 0
drivers/gpu/drm/radeon/r520.c

@@ -240,6 +240,8 @@ int r520_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r520_startup(rdev);
 	r = r520_startup(rdev);
 	if (r) {
 	if (r) {
@@ -312,6 +314,9 @@ int r520_init(struct radeon_device *rdev)
 		return r;
 		return r;
 	rv515_set_safe_registers(rdev);
 	rv515_set_safe_registers(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r520_startup(rdev);
 	r = r520_startup(rdev);
 	if (r) {
 	if (r) {

+ 114 - 10
drivers/gpu/drm/radeon/r600.c

@@ -105,6 +105,7 @@ void r600_fini(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
 void r600_irq_disable(struct radeon_device *rdev);
 static void r600_pcie_gen2_enable(struct radeon_device *rdev);
 static void r600_pcie_gen2_enable(struct radeon_device *rdev);
 extern int evergreen_rlc_resume(struct radeon_device *rdev);
 extern int evergreen_rlc_resume(struct radeon_device *rdev);
+extern void rv770_set_clk_bypass_mode(struct radeon_device *rdev);
 
 
 /**
 /**
  * r600_get_xclk - get the xclk
  * r600_get_xclk - get the xclk
@@ -1644,6 +1645,67 @@ static void r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
 	r600_print_gpu_status_regs(rdev);
 	r600_print_gpu_status_regs(rdev);
 }
 }
 
 
+static void r600_gpu_pci_config_reset(struct radeon_device *rdev)
+{
+	struct rv515_mc_save save;
+	u32 tmp, i;
+
+	dev_info(rdev->dev, "GPU pci config reset\n");
+
+	/* disable dpm? */
+
+	/* Disable CP parsing/prefetching */
+	if (rdev->family >= CHIP_RV770)
+		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1) | S_0086D8_CP_PFP_HALT(1));
+	else
+		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
+
+	/* disable the RLC */
+	WREG32(RLC_CNTL, 0);
+
+	/* Disable DMA */
+	tmp = RREG32(DMA_RB_CNTL);
+	tmp &= ~DMA_RB_ENABLE;
+	WREG32(DMA_RB_CNTL, tmp);
+
+	mdelay(50);
+
+	/* set mclk/sclk to bypass */
+	if (rdev->family >= CHIP_RV770)
+		rv770_set_clk_bypass_mode(rdev);
+	/* disable BM */
+	pci_clear_master(rdev->pdev);
+	/* disable mem access */
+	rv515_mc_stop(rdev, &save);
+	if (r600_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
+	}
+
+	/* BIF reset workaround.  Not sure if this is needed on 6xx */
+	tmp = RREG32(BUS_CNTL);
+	tmp |= VGA_COHE_SPEC_TIMER_DIS;
+	WREG32(BUS_CNTL, tmp);
+
+	tmp = RREG32(BIF_SCRATCH0);
+
+	/* reset */
+	radeon_pci_config_reset(rdev);
+	mdelay(1);
+
+	/* BIF reset workaround.  Not sure if this is needed on 6xx */
+	tmp = SOFT_RESET_BIF;
+	WREG32(SRBM_SOFT_RESET, tmp);
+	mdelay(1);
+	WREG32(SRBM_SOFT_RESET, 0);
+
+	/* wait for asic to come out of reset */
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
+			break;
+		udelay(1);
+	}
+}
+
 int r600_asic_reset(struct radeon_device *rdev)
 int r600_asic_reset(struct radeon_device *rdev)
 {
 {
 	u32 reset_mask;
 	u32 reset_mask;
@@ -1653,10 +1715,17 @@ int r600_asic_reset(struct radeon_device *rdev)
 	if (reset_mask)
 	if (reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, true);
 		r600_set_bios_scratch_engine_hung(rdev, true);
 
 
+	/* try soft reset */
 	r600_gpu_soft_reset(rdev, reset_mask);
 	r600_gpu_soft_reset(rdev, reset_mask);
 
 
 	reset_mask = r600_gpu_check_soft_reset(rdev);
 	reset_mask = r600_gpu_check_soft_reset(rdev);
 
 
+	/* try pci config reset */
+	if (reset_mask && radeon_hard_reset)
+		r600_gpu_pci_config_reset(rdev);
+
+	reset_mask = r600_gpu_check_soft_reset(rdev);
+
 	if (!reset_mask)
 	if (!reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, false);
 		r600_set_bios_scratch_engine_hung(rdev, false);
 
 
@@ -2382,6 +2451,36 @@ out:
 	return err;
 	return err;
 }
 }
 
 
+u32 r600_gfx_get_rptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring)
+{
+	u32 rptr;
+
+	if (rdev->wb.enabled)
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	else
+		rptr = RREG32(R600_CP_RB_RPTR);
+
+	return rptr;
+}
+
+u32 r600_gfx_get_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring)
+{
+	u32 wptr;
+
+	wptr = RREG32(R600_CP_RB_WPTR);
+
+	return wptr;
+}
+
+void r600_gfx_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring)
+{
+	WREG32(R600_CP_RB_WPTR, ring->wptr);
+	(void)RREG32(R600_CP_RB_WPTR);
+}
+
 static int r600_cp_load_microcode(struct radeon_device *rdev)
 static int r600_cp_load_microcode(struct radeon_device *rdev)
 {
 {
 	const __be32 *fw_data;
 	const __be32 *fw_data;
@@ -2775,14 +2874,6 @@ static int r600_startup(struct radeon_device *rdev)
 
 
 	r600_mc_program(rdev);
 	r600_mc_program(rdev);
 
 
-	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
-		r = r600_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
-
 	if (rdev->flags & RADEON_IS_AGP) {
 	if (rdev->flags & RADEON_IS_AGP) {
 		r600_agp_enable(rdev);
 		r600_agp_enable(rdev);
 	} else {
 	} else {
@@ -2826,14 +2917,12 @@ static int r600_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     DMA_RB_RPTR, DMA_RB_WPTR,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -2889,6 +2978,8 @@ int r600_resume(struct radeon_device *rdev)
 	/* post card */
 	/* post card */
 	atom_asic_init(rdev->mode_info.atom_context);
 	atom_asic_init(rdev->mode_info.atom_context);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = r600_startup(rdev);
 	r = r600_startup(rdev);
 	if (r) {
 	if (r) {
@@ -2902,6 +2993,7 @@ int r600_resume(struct radeon_device *rdev)
 
 
 int r600_suspend(struct radeon_device *rdev)
 int r600_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_cp_stop(rdev);
 	r600_cp_stop(rdev);
 	r600_dma_stop(rdev);
 	r600_dma_stop(rdev);
@@ -2970,6 +3062,17 @@ int r600_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
 
@@ -3002,6 +3105,7 @@ int r600_init(struct radeon_device *rdev)
 
 
 void r600_fini(struct radeon_device *rdev)
 void r600_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_cp_fini(rdev);
 	r600_cp_fini(rdev);
 	r600_dma_fini(rdev);
 	r600_dma_fini(rdev);

+ 4 - 1
drivers/gpu/drm/radeon/r600_cs.c

@@ -749,7 +749,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
 		}
 		}
 
 
 		for (i = 0; i < 8; i++) {
 		for (i = 0; i < 8; i++) {
-			if ((tmp >> (i * 4)) & 0xF) {
+			u32 format = G_0280A0_FORMAT(track->cb_color_info[i]);
+
+			if (format != V_0280A0_COLOR_INVALID &&
+			    (tmp >> (i * 4)) & 0xF) {
 				/* at least one component is enabled */
 				/* at least one component is enabled */
 				if (track->cb_color_bo[i] == NULL) {
 				if (track->cb_color_bo[i] == NULL) {
 					dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
 					dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",

+ 10 - 3
drivers/gpu/drm/radeon/r600_dma.c

@@ -51,7 +51,14 @@ u32 r600_gpu_check_soft_reset(struct radeon_device *rdev);
 uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
 uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
 			   struct radeon_ring *ring)
 			   struct radeon_ring *ring)
 {
 {
-	return (radeon_ring_generic_get_rptr(rdev, ring) & 0x3fffc) >> 2;
+	u32 rptr;
+
+	if (rdev->wb.enabled)
+		rptr = rdev->wb.wb[ring->rptr_offs/4];
+	else
+		rptr = RREG32(DMA_RB_RPTR);
+
+	return (rptr & 0x3fffc) >> 2;
 }
 }
 
 
 /**
 /**
@@ -65,7 +72,7 @@ uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
 uint32_t r600_dma_get_wptr(struct radeon_device *rdev,
 uint32_t r600_dma_get_wptr(struct radeon_device *rdev,
 			   struct radeon_ring *ring)
 			   struct radeon_ring *ring)
 {
 {
-	return (RREG32(ring->wptr_reg) & 0x3fffc) >> 2;
+	return (RREG32(DMA_RB_WPTR) & 0x3fffc) >> 2;
 }
 }
 
 
 /**
 /**
@@ -79,7 +86,7 @@ uint32_t r600_dma_get_wptr(struct radeon_device *rdev,
 void r600_dma_set_wptr(struct radeon_device *rdev,
 void r600_dma_set_wptr(struct radeon_device *rdev,
 		       struct radeon_ring *ring)
 		       struct radeon_ring *ring)
 {
 {
-	WREG32(ring->wptr_reg, (ring->wptr << 2) & 0x3fffc);
+	WREG32(DMA_RB_WPTR, (ring->wptr << 2) & 0x3fffc);
 }
 }
 
 
 /**
 /**

+ 18 - 2
drivers/gpu/drm/radeon/r600_dpm.c

@@ -729,8 +729,8 @@ bool r600_is_uvd_state(u32 class, u32 class2)
 	return false;
 	return false;
 }
 }
 
 
-int r600_set_thermal_temperature_range(struct radeon_device *rdev,
-				       int min_temp, int max_temp)
+static int r600_set_thermal_temperature_range(struct radeon_device *rdev,
+					      int min_temp, int max_temp)
 {
 {
 	int low_temp = 0 * 1000;
 	int low_temp = 0 * 1000;
 	int high_temp = 255 * 1000;
 	int high_temp = 255 * 1000;
@@ -777,6 +777,22 @@ bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor)
 	}
 	}
 }
 }
 
 
+int r600_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
+	if (rdev->irq.installed &&
+	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+		ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+		if (ret)
+			return ret;
+		rdev->irq.dpm_thermal = true;
+		radeon_irq_set(rdev);
+	}
+
+	return 0;
+}
+
 union power_info {
 union power_info {
 	struct _ATOM_POWERPLAY_INFO info;
 	struct _ATOM_POWERPLAY_INFO info;
 	struct _ATOM_POWERPLAY_INFO_V2 info_2;
 	struct _ATOM_POWERPLAY_INFO_V2 info_2;

+ 0 - 2
drivers/gpu/drm/radeon/r600_dpm.h

@@ -213,8 +213,6 @@ void r600_wait_for_power_level(struct radeon_device *rdev,
 void r600_start_dpm(struct radeon_device *rdev);
 void r600_start_dpm(struct radeon_device *rdev);
 void r600_stop_dpm(struct radeon_device *rdev);
 void r600_stop_dpm(struct radeon_device *rdev);
 
 
-int r600_set_thermal_temperature_range(struct radeon_device *rdev,
-				       int min_temp, int max_temp);
 bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor);
 bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor);
 
 
 int r600_parse_extended_power_table(struct radeon_device *rdev);
 int r600_parse_extended_power_table(struct radeon_device *rdev);

+ 1 - 1
drivers/gpu/drm/radeon/r600_hdmi.c

@@ -250,7 +250,7 @@ static void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
 		 value, ~HDMI0_AUDIO_TEST_EN);
 		 value, ~HDMI0_AUDIO_TEST_EN);
 }
 }
 
 
-void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
+static void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
 {
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_device *rdev = dev->dev_private;

+ 7 - 0
drivers/gpu/drm/radeon/r600d.h

@@ -701,11 +701,18 @@
 #define RLC_UCODE_DATA                                    0x3f30
 #define RLC_UCODE_DATA                                    0x3f30
 
 
 #define SRBM_SOFT_RESET                                   0xe60
 #define SRBM_SOFT_RESET                                   0xe60
+#       define SOFT_RESET_BIF                             (1 << 1)
 #       define SOFT_RESET_DMA                             (1 << 12)
 #       define SOFT_RESET_DMA                             (1 << 12)
 #       define SOFT_RESET_RLC                             (1 << 13)
 #       define SOFT_RESET_RLC                             (1 << 13)
 #       define SOFT_RESET_UVD                             (1 << 18)
 #       define SOFT_RESET_UVD                             (1 << 18)
 #       define RV770_SOFT_RESET_DMA                       (1 << 20)
 #       define RV770_SOFT_RESET_DMA                       (1 << 20)
 
 
+#define BIF_SCRATCH0                                      0x5438
+
+#define BUS_CNTL                                          0x5420
+#       define BIOS_ROM_DIS                               (1 << 1)
+#       define VGA_COHE_SPEC_TIMER_DIS                    (1 << 9)
+
 #define CP_INT_CNTL                                       0xc124
 #define CP_INT_CNTL                                       0xc124
 #       define CNTX_BUSY_INT_ENABLE                       (1 << 19)
 #       define CNTX_BUSY_INT_ENABLE                       (1 << 19)
 #       define CNTX_EMPTY_INT_ENABLE                      (1 << 20)
 #       define CNTX_EMPTY_INT_ENABLE                      (1 << 20)

+ 14 - 3
drivers/gpu/drm/radeon/radeon.h

@@ -99,6 +99,7 @@ extern int radeon_fastfb;
 extern int radeon_dpm;
 extern int radeon_dpm;
 extern int radeon_aspm;
 extern int radeon_aspm;
 extern int radeon_runtime_pm;
 extern int radeon_runtime_pm;
+extern int radeon_hard_reset;
 
 
 /*
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -139,6 +140,9 @@ extern int radeon_runtime_pm;
 #define RADEON_VA_RESERVED_SIZE			(8 << 20)
 #define RADEON_VA_RESERVED_SIZE			(8 << 20)
 #define RADEON_IB_VM_MAX_SIZE			(64 << 10)
 #define RADEON_IB_VM_MAX_SIZE			(64 << 10)
 
 
+/* hard reset data */
+#define RADEON_ASIC_RESET_DATA                  0x39d5e86b
+
 /* reset flags */
 /* reset flags */
 #define RADEON_RESET_GFX			(1 << 0)
 #define RADEON_RESET_GFX			(1 << 0)
 #define RADEON_RESET_COMPUTE			(1 << 1)
 #define RADEON_RESET_COMPUTE			(1 << 1)
@@ -252,6 +256,7 @@ struct radeon_clock {
  * Power management
  * Power management
  */
  */
 int radeon_pm_init(struct radeon_device *rdev);
 int radeon_pm_init(struct radeon_device *rdev);
+int radeon_pm_late_init(struct radeon_device *rdev);
 void radeon_pm_fini(struct radeon_device *rdev);
 void radeon_pm_fini(struct radeon_device *rdev);
 void radeon_pm_compute_clocks(struct radeon_device *rdev);
 void radeon_pm_compute_clocks(struct radeon_device *rdev);
 void radeon_pm_suspend(struct radeon_device *rdev);
 void radeon_pm_suspend(struct radeon_device *rdev);
@@ -413,6 +418,11 @@ struct radeon_mman {
 	struct ttm_bo_device		bdev;
 	struct ttm_bo_device		bdev;
 	bool				mem_global_referenced;
 	bool				mem_global_referenced;
 	bool				initialized;
 	bool				initialized;
+
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry			*vram;
+	struct dentry			*gtt;
+#endif
 };
 };
 
 
 /* bo virtual address in a specific vm */
 /* bo virtual address in a specific vm */
@@ -779,13 +789,11 @@ struct radeon_ring {
 	volatile uint32_t	*ring;
 	volatile uint32_t	*ring;
 	unsigned		rptr;
 	unsigned		rptr;
 	unsigned		rptr_offs;
 	unsigned		rptr_offs;
-	unsigned		rptr_reg;
 	unsigned		rptr_save_reg;
 	unsigned		rptr_save_reg;
 	u64			next_rptr_gpu_addr;
 	u64			next_rptr_gpu_addr;
 	volatile u32		*next_rptr_cpu_addr;
 	volatile u32		*next_rptr_cpu_addr;
 	unsigned		wptr;
 	unsigned		wptr;
 	unsigned		wptr_old;
 	unsigned		wptr_old;
-	unsigned		wptr_reg;
 	unsigned		ring_size;
 	unsigned		ring_size;
 	unsigned		ring_free_dw;
 	unsigned		ring_free_dw;
 	int			count_dw;
 	int			count_dw;
@@ -949,7 +957,7 @@ unsigned radeon_ring_backup(struct radeon_device *rdev, struct radeon_ring *ring
 int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
 int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
 			unsigned size, uint32_t *data);
 			unsigned size, uint32_t *data);
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size,
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size,
-		     unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop);
+		     unsigned rptr_offs, u32 nop);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
 void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp);
 
 
 
 
@@ -1775,6 +1783,7 @@ struct radeon_asic {
 		int (*init)(struct radeon_device *rdev);
 		int (*init)(struct radeon_device *rdev);
 		void (*setup_asic)(struct radeon_device *rdev);
 		void (*setup_asic)(struct radeon_device *rdev);
 		int (*enable)(struct radeon_device *rdev);
 		int (*enable)(struct radeon_device *rdev);
+		int (*late_enable)(struct radeon_device *rdev);
 		void (*disable)(struct radeon_device *rdev);
 		void (*disable)(struct radeon_device *rdev);
 		int (*pre_set_power_state)(struct radeon_device *rdev);
 		int (*pre_set_power_state)(struct radeon_device *rdev);
 		int (*set_power_state)(struct radeon_device *rdev);
 		int (*set_power_state)(struct radeon_device *rdev);
@@ -2650,6 +2659,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 #define radeon_dpm_init(rdev) rdev->asic->dpm.init((rdev))
 #define radeon_dpm_init(rdev) rdev->asic->dpm.init((rdev))
 #define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev))
 #define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev))
 #define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev))
 #define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev))
+#define radeon_dpm_late_enable(rdev) rdev->asic->dpm.late_enable((rdev))
 #define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev))
 #define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev))
 #define radeon_dpm_pre_set_power_state(rdev) rdev->asic->dpm.pre_set_power_state((rdev))
 #define radeon_dpm_pre_set_power_state(rdev) rdev->asic->dpm.pre_set_power_state((rdev))
 #define radeon_dpm_set_power_state(rdev) rdev->asic->dpm.set_power_state((rdev))
 #define radeon_dpm_set_power_state(rdev) rdev->asic->dpm.set_power_state((rdev))
@@ -2668,6 +2678,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
 /* Common functions */
 /* Common functions */
 /* AGP */
 /* AGP */
 extern int radeon_gpu_reset(struct radeon_device *rdev);
 extern int radeon_gpu_reset(struct radeon_device *rdev);
+extern void radeon_pci_config_reset(struct radeon_device *rdev);
 extern void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung);
 extern void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung);
 extern void radeon_agp_disable(struct radeon_device *rdev);
 extern void radeon_agp_disable(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);
 extern int radeon_modeset_init(struct radeon_device *rdev);

+ 48 - 37
drivers/gpu/drm/radeon/radeon_asic.c

@@ -182,9 +182,9 @@ static struct radeon_asic_ring r100_gfx_ring = {
 	.ring_test = &r100_ring_test,
 	.ring_test = &r100_ring_test,
 	.ib_test = &r100_ib_test,
 	.ib_test = &r100_ib_test,
 	.is_lockup = &r100_gpu_is_lockup,
 	.is_lockup = &r100_gpu_is_lockup,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &r100_gfx_get_rptr,
+	.get_wptr = &r100_gfx_get_wptr,
+	.set_wptr = &r100_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic r100_asic = {
 static struct radeon_asic r100_asic = {
@@ -330,9 +330,9 @@ static struct radeon_asic_ring r300_gfx_ring = {
 	.ring_test = &r100_ring_test,
 	.ring_test = &r100_ring_test,
 	.ib_test = &r100_ib_test,
 	.ib_test = &r100_ib_test,
 	.is_lockup = &r100_gpu_is_lockup,
 	.is_lockup = &r100_gpu_is_lockup,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &r100_gfx_get_rptr,
+	.get_wptr = &r100_gfx_get_wptr,
+	.set_wptr = &r100_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic r300_asic = {
 static struct radeon_asic r300_asic = {
@@ -883,9 +883,9 @@ static struct radeon_asic_ring r600_gfx_ring = {
 	.ring_test = &r600_ring_test,
 	.ring_test = &r600_ring_test,
 	.ib_test = &r600_ib_test,
 	.ib_test = &r600_ib_test,
 	.is_lockup = &r600_gfx_is_lockup,
 	.is_lockup = &r600_gfx_is_lockup,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &r600_gfx_get_rptr,
+	.get_wptr = &r600_gfx_get_wptr,
+	.set_wptr = &r600_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring r600_dma_ring = {
 static struct radeon_asic_ring r600_dma_ring = {
@@ -1045,6 +1045,7 @@ static struct radeon_asic rv6xx_asic = {
 		.init = &rv6xx_dpm_init,
 		.init = &rv6xx_dpm_init,
 		.setup_asic = &rv6xx_setup_asic,
 		.setup_asic = &rv6xx_setup_asic,
 		.enable = &rv6xx_dpm_enable,
 		.enable = &rv6xx_dpm_enable,
+		.late_enable = &r600_dpm_late_enable,
 		.disable = &rv6xx_dpm_disable,
 		.disable = &rv6xx_dpm_disable,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.set_power_state = &rv6xx_dpm_set_power_state,
 		.set_power_state = &rv6xx_dpm_set_power_state,
@@ -1135,6 +1136,7 @@ static struct radeon_asic rs780_asic = {
 		.init = &rs780_dpm_init,
 		.init = &rs780_dpm_init,
 		.setup_asic = &rs780_dpm_setup_asic,
 		.setup_asic = &rs780_dpm_setup_asic,
 		.enable = &rs780_dpm_enable,
 		.enable = &rs780_dpm_enable,
+		.late_enable = &r600_dpm_late_enable,
 		.disable = &rs780_dpm_disable,
 		.disable = &rs780_dpm_disable,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.set_power_state = &rs780_dpm_set_power_state,
 		.set_power_state = &rs780_dpm_set_power_state,
@@ -1239,6 +1241,7 @@ static struct radeon_asic rv770_asic = {
 		.init = &rv770_dpm_init,
 		.init = &rv770_dpm_init,
 		.setup_asic = &rv770_dpm_setup_asic,
 		.setup_asic = &rv770_dpm_setup_asic,
 		.enable = &rv770_dpm_enable,
 		.enable = &rv770_dpm_enable,
+		.late_enable = &rv770_dpm_late_enable,
 		.disable = &rv770_dpm_disable,
 		.disable = &rv770_dpm_disable,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.set_power_state = &rv770_dpm_set_power_state,
 		.set_power_state = &rv770_dpm_set_power_state,
@@ -1267,9 +1270,9 @@ static struct radeon_asic_ring evergreen_gfx_ring = {
 	.ring_test = &r600_ring_test,
 	.ring_test = &r600_ring_test,
 	.ib_test = &r600_ib_test,
 	.ib_test = &r600_ib_test,
 	.is_lockup = &evergreen_gfx_is_lockup,
 	.is_lockup = &evergreen_gfx_is_lockup,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &r600_gfx_get_rptr,
+	.get_wptr = &r600_gfx_get_wptr,
+	.set_wptr = &r600_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring evergreen_dma_ring = {
 static struct radeon_asic_ring evergreen_dma_ring = {
@@ -1357,6 +1360,7 @@ static struct radeon_asic evergreen_asic = {
 		.init = &cypress_dpm_init,
 		.init = &cypress_dpm_init,
 		.setup_asic = &cypress_dpm_setup_asic,
 		.setup_asic = &cypress_dpm_setup_asic,
 		.enable = &cypress_dpm_enable,
 		.enable = &cypress_dpm_enable,
+		.late_enable = &rv770_dpm_late_enable,
 		.disable = &cypress_dpm_disable,
 		.disable = &cypress_dpm_disable,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.pre_set_power_state = &r600_dpm_pre_set_power_state,
 		.set_power_state = &cypress_dpm_set_power_state,
 		.set_power_state = &cypress_dpm_set_power_state,
@@ -1449,6 +1453,7 @@ static struct radeon_asic sumo_asic = {
 		.init = &sumo_dpm_init,
 		.init = &sumo_dpm_init,
 		.setup_asic = &sumo_dpm_setup_asic,
 		.setup_asic = &sumo_dpm_setup_asic,
 		.enable = &sumo_dpm_enable,
 		.enable = &sumo_dpm_enable,
+		.late_enable = &sumo_dpm_late_enable,
 		.disable = &sumo_dpm_disable,
 		.disable = &sumo_dpm_disable,
 		.pre_set_power_state = &sumo_dpm_pre_set_power_state,
 		.pre_set_power_state = &sumo_dpm_pre_set_power_state,
 		.set_power_state = &sumo_dpm_set_power_state,
 		.set_power_state = &sumo_dpm_set_power_state,
@@ -1540,6 +1545,7 @@ static struct radeon_asic btc_asic = {
 		.init = &btc_dpm_init,
 		.init = &btc_dpm_init,
 		.setup_asic = &btc_dpm_setup_asic,
 		.setup_asic = &btc_dpm_setup_asic,
 		.enable = &btc_dpm_enable,
 		.enable = &btc_dpm_enable,
+		.late_enable = &rv770_dpm_late_enable,
 		.disable = &btc_dpm_disable,
 		.disable = &btc_dpm_disable,
 		.pre_set_power_state = &btc_dpm_pre_set_power_state,
 		.pre_set_power_state = &btc_dpm_pre_set_power_state,
 		.set_power_state = &btc_dpm_set_power_state,
 		.set_power_state = &btc_dpm_set_power_state,
@@ -1570,9 +1576,9 @@ static struct radeon_asic_ring cayman_gfx_ring = {
 	.ib_test = &r600_ib_test,
 	.ib_test = &r600_ib_test,
 	.is_lockup = &cayman_gfx_is_lockup,
 	.is_lockup = &cayman_gfx_is_lockup,
 	.vm_flush = &cayman_vm_flush,
 	.vm_flush = &cayman_vm_flush,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &cayman_gfx_get_rptr,
+	.get_wptr = &cayman_gfx_get_wptr,
+	.set_wptr = &cayman_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring cayman_dma_ring = {
 static struct radeon_asic_ring cayman_dma_ring = {
@@ -1585,9 +1591,9 @@ static struct radeon_asic_ring cayman_dma_ring = {
 	.ib_test = &r600_dma_ib_test,
 	.ib_test = &r600_dma_ib_test,
 	.is_lockup = &cayman_dma_is_lockup,
 	.is_lockup = &cayman_dma_is_lockup,
 	.vm_flush = &cayman_dma_vm_flush,
 	.vm_flush = &cayman_dma_vm_flush,
-	.get_rptr = &r600_dma_get_rptr,
-	.get_wptr = &r600_dma_get_wptr,
-	.set_wptr = &r600_dma_set_wptr
+	.get_rptr = &cayman_dma_get_rptr,
+	.get_wptr = &cayman_dma_get_wptr,
+	.set_wptr = &cayman_dma_set_wptr
 };
 };
 
 
 static struct radeon_asic_ring cayman_uvd_ring = {
 static struct radeon_asic_ring cayman_uvd_ring = {
@@ -1683,6 +1689,7 @@ static struct radeon_asic cayman_asic = {
 		.init = &ni_dpm_init,
 		.init = &ni_dpm_init,
 		.setup_asic = &ni_dpm_setup_asic,
 		.setup_asic = &ni_dpm_setup_asic,
 		.enable = &ni_dpm_enable,
 		.enable = &ni_dpm_enable,
+		.late_enable = &rv770_dpm_late_enable,
 		.disable = &ni_dpm_disable,
 		.disable = &ni_dpm_disable,
 		.pre_set_power_state = &ni_dpm_pre_set_power_state,
 		.pre_set_power_state = &ni_dpm_pre_set_power_state,
 		.set_power_state = &ni_dpm_set_power_state,
 		.set_power_state = &ni_dpm_set_power_state,
@@ -1783,6 +1790,7 @@ static struct radeon_asic trinity_asic = {
 		.init = &trinity_dpm_init,
 		.init = &trinity_dpm_init,
 		.setup_asic = &trinity_dpm_setup_asic,
 		.setup_asic = &trinity_dpm_setup_asic,
 		.enable = &trinity_dpm_enable,
 		.enable = &trinity_dpm_enable,
+		.late_enable = &trinity_dpm_late_enable,
 		.disable = &trinity_dpm_disable,
 		.disable = &trinity_dpm_disable,
 		.pre_set_power_state = &trinity_dpm_pre_set_power_state,
 		.pre_set_power_state = &trinity_dpm_pre_set_power_state,
 		.set_power_state = &trinity_dpm_set_power_state,
 		.set_power_state = &trinity_dpm_set_power_state,
@@ -1813,9 +1821,9 @@ static struct radeon_asic_ring si_gfx_ring = {
 	.ib_test = &r600_ib_test,
 	.ib_test = &r600_ib_test,
 	.is_lockup = &si_gfx_is_lockup,
 	.is_lockup = &si_gfx_is_lockup,
 	.vm_flush = &si_vm_flush,
 	.vm_flush = &si_vm_flush,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &cayman_gfx_get_rptr,
+	.get_wptr = &cayman_gfx_get_wptr,
+	.set_wptr = &cayman_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring si_dma_ring = {
 static struct radeon_asic_ring si_dma_ring = {
@@ -1828,9 +1836,9 @@ static struct radeon_asic_ring si_dma_ring = {
 	.ib_test = &r600_dma_ib_test,
 	.ib_test = &r600_dma_ib_test,
 	.is_lockup = &si_dma_is_lockup,
 	.is_lockup = &si_dma_is_lockup,
 	.vm_flush = &si_dma_vm_flush,
 	.vm_flush = &si_dma_vm_flush,
-	.get_rptr = &r600_dma_get_rptr,
-	.get_wptr = &r600_dma_get_wptr,
-	.set_wptr = &r600_dma_set_wptr,
+	.get_rptr = &cayman_dma_get_rptr,
+	.get_wptr = &cayman_dma_get_wptr,
+	.set_wptr = &cayman_dma_set_wptr,
 };
 };
 
 
 static struct radeon_asic si_asic = {
 static struct radeon_asic si_asic = {
@@ -1913,6 +1921,7 @@ static struct radeon_asic si_asic = {
 		.init = &si_dpm_init,
 		.init = &si_dpm_init,
 		.setup_asic = &si_dpm_setup_asic,
 		.setup_asic = &si_dpm_setup_asic,
 		.enable = &si_dpm_enable,
 		.enable = &si_dpm_enable,
+		.late_enable = &si_dpm_late_enable,
 		.disable = &si_dpm_disable,
 		.disable = &si_dpm_disable,
 		.pre_set_power_state = &si_dpm_pre_set_power_state,
 		.pre_set_power_state = &si_dpm_pre_set_power_state,
 		.set_power_state = &si_dpm_set_power_state,
 		.set_power_state = &si_dpm_set_power_state,
@@ -1943,9 +1952,9 @@ static struct radeon_asic_ring ci_gfx_ring = {
 	.ib_test = &cik_ib_test,
 	.ib_test = &cik_ib_test,
 	.is_lockup = &cik_gfx_is_lockup,
 	.is_lockup = &cik_gfx_is_lockup,
 	.vm_flush = &cik_vm_flush,
 	.vm_flush = &cik_vm_flush,
-	.get_rptr = &radeon_ring_generic_get_rptr,
-	.get_wptr = &radeon_ring_generic_get_wptr,
-	.set_wptr = &radeon_ring_generic_set_wptr,
+	.get_rptr = &cik_gfx_get_rptr,
+	.get_wptr = &cik_gfx_get_wptr,
+	.set_wptr = &cik_gfx_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring ci_cp_ring = {
 static struct radeon_asic_ring ci_cp_ring = {
@@ -1958,9 +1967,9 @@ static struct radeon_asic_ring ci_cp_ring = {
 	.ib_test = &cik_ib_test,
 	.ib_test = &cik_ib_test,
 	.is_lockup = &cik_gfx_is_lockup,
 	.is_lockup = &cik_gfx_is_lockup,
 	.vm_flush = &cik_vm_flush,
 	.vm_flush = &cik_vm_flush,
-	.get_rptr = &cik_compute_ring_get_rptr,
-	.get_wptr = &cik_compute_ring_get_wptr,
-	.set_wptr = &cik_compute_ring_set_wptr,
+	.get_rptr = &cik_compute_get_rptr,
+	.get_wptr = &cik_compute_get_wptr,
+	.set_wptr = &cik_compute_set_wptr,
 };
 };
 
 
 static struct radeon_asic_ring ci_dma_ring = {
 static struct radeon_asic_ring ci_dma_ring = {
@@ -1973,9 +1982,9 @@ static struct radeon_asic_ring ci_dma_ring = {
 	.ib_test = &cik_sdma_ib_test,
 	.ib_test = &cik_sdma_ib_test,
 	.is_lockup = &cik_sdma_is_lockup,
 	.is_lockup = &cik_sdma_is_lockup,
 	.vm_flush = &cik_dma_vm_flush,
 	.vm_flush = &cik_dma_vm_flush,
-	.get_rptr = &r600_dma_get_rptr,
-	.get_wptr = &r600_dma_get_wptr,
-	.set_wptr = &r600_dma_set_wptr,
+	.get_rptr = &cik_sdma_get_rptr,
+	.get_wptr = &cik_sdma_get_wptr,
+	.set_wptr = &cik_sdma_set_wptr,
 };
 };
 
 
 static struct radeon_asic ci_asic = {
 static struct radeon_asic ci_asic = {
@@ -2058,6 +2067,7 @@ static struct radeon_asic ci_asic = {
 		.init = &ci_dpm_init,
 		.init = &ci_dpm_init,
 		.setup_asic = &ci_dpm_setup_asic,
 		.setup_asic = &ci_dpm_setup_asic,
 		.enable = &ci_dpm_enable,
 		.enable = &ci_dpm_enable,
+		.late_enable = &ci_dpm_late_enable,
 		.disable = &ci_dpm_disable,
 		.disable = &ci_dpm_disable,
 		.pre_set_power_state = &ci_dpm_pre_set_power_state,
 		.pre_set_power_state = &ci_dpm_pre_set_power_state,
 		.set_power_state = &ci_dpm_set_power_state,
 		.set_power_state = &ci_dpm_set_power_state,
@@ -2159,6 +2169,7 @@ static struct radeon_asic kv_asic = {
 		.init = &kv_dpm_init,
 		.init = &kv_dpm_init,
 		.setup_asic = &kv_dpm_setup_asic,
 		.setup_asic = &kv_dpm_setup_asic,
 		.enable = &kv_dpm_enable,
 		.enable = &kv_dpm_enable,
+		.late_enable = &kv_dpm_late_enable,
 		.disable = &kv_dpm_disable,
 		.disable = &kv_dpm_disable,
 		.pre_set_power_state = &kv_dpm_pre_set_power_state,
 		.pre_set_power_state = &kv_dpm_pre_set_power_state,
 		.set_power_state = &kv_dpm_set_power_state,
 		.set_power_state = &kv_dpm_set_power_state,
@@ -2449,7 +2460,7 @@ int radeon_asic_init(struct radeon_device *rdev)
 			rdev->cg_flags =
 			rdev->cg_flags =
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGLS |
 				RADEON_CG_SUPPORT_GFX_MGLS |
-				/*RADEON_CG_SUPPORT_GFX_CGCG |*/
+				RADEON_CG_SUPPORT_GFX_CGCG |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |
@@ -2468,7 +2479,7 @@ int radeon_asic_init(struct radeon_device *rdev)
 			rdev->cg_flags =
 			rdev->cg_flags =
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGLS |
 				RADEON_CG_SUPPORT_GFX_MGLS |
-				/*RADEON_CG_SUPPORT_GFX_CGCG |*/
+				RADEON_CG_SUPPORT_GFX_CGCG |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CP_LS |
 				RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2493,7 +2504,7 @@ int radeon_asic_init(struct radeon_device *rdev)
 			rdev->cg_flags =
 			rdev->cg_flags =
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGLS |
 				RADEON_CG_SUPPORT_GFX_MGLS |
-				/*RADEON_CG_SUPPORT_GFX_CGCG |*/
+				RADEON_CG_SUPPORT_GFX_CGCG |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |
@@ -2521,7 +2532,7 @@ int radeon_asic_init(struct radeon_device *rdev)
 			rdev->cg_flags =
 			rdev->cg_flags =
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGCG |
 				RADEON_CG_SUPPORT_GFX_MGLS |
 				RADEON_CG_SUPPORT_GFX_MGLS |
-				/*RADEON_CG_SUPPORT_GFX_CGCG |*/
+				RADEON_CG_SUPPORT_GFX_CGCG |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGLS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |
 				RADEON_CG_SUPPORT_GFX_CGTS_LS |

+ 51 - 13
drivers/gpu/drm/radeon/radeon_asic.h

@@ -47,13 +47,6 @@ u8 atombios_get_backlight_level(struct radeon_encoder *radeon_encoder);
 void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
 void radeon_legacy_set_backlight_level(struct radeon_encoder *radeon_encoder, u8 level);
 u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
 u8 radeon_legacy_get_backlight_level(struct radeon_encoder *radeon_encoder);
 
 
-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
-				 struct radeon_ring *ring);
-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
-				 struct radeon_ring *ring);
-void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
-				  struct radeon_ring *ring);
-
 /*
 /*
  * r100,rv100,rs100,rv200,rs200
  * r100,rv100,rs100,rv200,rs200
  */
  */
@@ -148,6 +141,13 @@ extern void r100_post_page_flip(struct radeon_device *rdev, int crtc);
 extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc);
 extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
 extern int r100_mc_wait_for_idle(struct radeon_device *rdev);
 
 
+u32 r100_gfx_get_rptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+u32 r100_gfx_get_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+void r100_gfx_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring);
+
 /*
 /*
  * r200,rv250,rs300,rv280
  * r200,rv250,rs300,rv280
  */
  */
@@ -368,6 +368,12 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
 int r600_pcie_gart_init(struct radeon_device *rdev);
 int r600_pcie_gart_init(struct radeon_device *rdev);
 void r600_scratch_init(struct radeon_device *rdev);
 void r600_scratch_init(struct radeon_device *rdev);
 int r600_init_microcode(struct radeon_device *rdev);
 int r600_init_microcode(struct radeon_device *rdev);
+u32 r600_gfx_get_rptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+u32 r600_gfx_get_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+void r600_gfx_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring);
 /* r600 irq */
 /* r600 irq */
 int r600_irq_process(struct radeon_device *rdev);
 int r600_irq_process(struct radeon_device *rdev);
 int r600_irq_init(struct radeon_device *rdev);
 int r600_irq_init(struct radeon_device *rdev);
@@ -392,6 +398,7 @@ int rv6xx_get_temp(struct radeon_device *rdev);
 int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
 int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
 int r600_dpm_pre_set_power_state(struct radeon_device *rdev);
 int r600_dpm_pre_set_power_state(struct radeon_device *rdev);
 void r600_dpm_post_set_power_state(struct radeon_device *rdev);
 void r600_dpm_post_set_power_state(struct radeon_device *rdev);
+int r600_dpm_late_enable(struct radeon_device *rdev);
 /* r600 dma */
 /* r600 dma */
 uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
 uint32_t r600_dma_get_rptr(struct radeon_device *rdev,
 			   struct radeon_ring *ring);
 			   struct radeon_ring *ring);
@@ -454,6 +461,7 @@ int rv770_get_temp(struct radeon_device *rdev);
 /* rv7xx pm */
 /* rv7xx pm */
 int rv770_dpm_init(struct radeon_device *rdev);
 int rv770_dpm_init(struct radeon_device *rdev);
 int rv770_dpm_enable(struct radeon_device *rdev);
 int rv770_dpm_enable(struct radeon_device *rdev);
+int rv770_dpm_late_enable(struct radeon_device *rdev);
 void rv770_dpm_disable(struct radeon_device *rdev);
 void rv770_dpm_disable(struct radeon_device *rdev);
 int rv770_dpm_set_power_state(struct radeon_device *rdev);
 int rv770_dpm_set_power_state(struct radeon_device *rdev);
 void rv770_dpm_setup_asic(struct radeon_device *rdev);
 void rv770_dpm_setup_asic(struct radeon_device *rdev);
@@ -545,6 +553,7 @@ u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low);
 bool btc_dpm_vblank_too_short(struct radeon_device *rdev);
 bool btc_dpm_vblank_too_short(struct radeon_device *rdev);
 int sumo_dpm_init(struct radeon_device *rdev);
 int sumo_dpm_init(struct radeon_device *rdev);
 int sumo_dpm_enable(struct radeon_device *rdev);
 int sumo_dpm_enable(struct radeon_device *rdev);
+int sumo_dpm_late_enable(struct radeon_device *rdev);
 void sumo_dpm_disable(struct radeon_device *rdev);
 void sumo_dpm_disable(struct radeon_device *rdev);
 int sumo_dpm_pre_set_power_state(struct radeon_device *rdev);
 int sumo_dpm_pre_set_power_state(struct radeon_device *rdev);
 int sumo_dpm_set_power_state(struct radeon_device *rdev);
 int sumo_dpm_set_power_state(struct radeon_device *rdev);
@@ -591,6 +600,19 @@ void cayman_dma_vm_set_page(struct radeon_device *rdev,
 
 
 void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 
 
+u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
+			struct radeon_ring *ring);
+u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
+			struct radeon_ring *ring);
+void cayman_gfx_set_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring);
+uint32_t cayman_dma_get_rptr(struct radeon_device *rdev,
+			     struct radeon_ring *ring);
+uint32_t cayman_dma_get_wptr(struct radeon_device *rdev,
+			     struct radeon_ring *ring);
+void cayman_dma_set_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring);
+
 int ni_dpm_init(struct radeon_device *rdev);
 int ni_dpm_init(struct radeon_device *rdev);
 void ni_dpm_setup_asic(struct radeon_device *rdev);
 void ni_dpm_setup_asic(struct radeon_device *rdev);
 int ni_dpm_enable(struct radeon_device *rdev);
 int ni_dpm_enable(struct radeon_device *rdev);
@@ -610,6 +632,7 @@ int ni_dpm_force_performance_level(struct radeon_device *rdev,
 bool ni_dpm_vblank_too_short(struct radeon_device *rdev);
 bool ni_dpm_vblank_too_short(struct radeon_device *rdev);
 int trinity_dpm_init(struct radeon_device *rdev);
 int trinity_dpm_init(struct radeon_device *rdev);
 int trinity_dpm_enable(struct radeon_device *rdev);
 int trinity_dpm_enable(struct radeon_device *rdev);
+int trinity_dpm_late_enable(struct radeon_device *rdev);
 void trinity_dpm_disable(struct radeon_device *rdev);
 void trinity_dpm_disable(struct radeon_device *rdev);
 int trinity_dpm_pre_set_power_state(struct radeon_device *rdev);
 int trinity_dpm_pre_set_power_state(struct radeon_device *rdev);
 int trinity_dpm_set_power_state(struct radeon_device *rdev);
 int trinity_dpm_set_power_state(struct radeon_device *rdev);
@@ -669,6 +692,7 @@ int si_get_temp(struct radeon_device *rdev);
 int si_dpm_init(struct radeon_device *rdev);
 int si_dpm_init(struct radeon_device *rdev);
 void si_dpm_setup_asic(struct radeon_device *rdev);
 void si_dpm_setup_asic(struct radeon_device *rdev);
 int si_dpm_enable(struct radeon_device *rdev);
 int si_dpm_enable(struct radeon_device *rdev);
+int si_dpm_late_enable(struct radeon_device *rdev);
 void si_dpm_disable(struct radeon_device *rdev);
 void si_dpm_disable(struct radeon_device *rdev);
 int si_dpm_pre_set_power_state(struct radeon_device *rdev);
 int si_dpm_pre_set_power_state(struct radeon_device *rdev);
 int si_dpm_set_power_state(struct radeon_device *rdev);
 int si_dpm_set_power_state(struct radeon_device *rdev);
@@ -739,17 +763,30 @@ void cik_sdma_vm_set_page(struct radeon_device *rdev,
 			  uint32_t incr, uint32_t flags);
 			  uint32_t incr, uint32_t flags);
 void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 void cik_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
 int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
 int cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
-u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
-			      struct radeon_ring *ring);
-u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
-			      struct radeon_ring *ring);
-void cik_compute_ring_set_wptr(struct radeon_device *rdev,
-			       struct radeon_ring *ring);
+u32 cik_gfx_get_rptr(struct radeon_device *rdev,
+		     struct radeon_ring *ring);
+u32 cik_gfx_get_wptr(struct radeon_device *rdev,
+		     struct radeon_ring *ring);
+void cik_gfx_set_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+u32 cik_compute_get_rptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring);
+u32 cik_compute_get_wptr(struct radeon_device *rdev,
+			 struct radeon_ring *ring);
+void cik_compute_set_wptr(struct radeon_device *rdev,
+			  struct radeon_ring *ring);
+u32 cik_sdma_get_rptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+u32 cik_sdma_get_wptr(struct radeon_device *rdev,
+		      struct radeon_ring *ring);
+void cik_sdma_set_wptr(struct radeon_device *rdev,
+		       struct radeon_ring *ring);
 int ci_get_temp(struct radeon_device *rdev);
 int ci_get_temp(struct radeon_device *rdev);
 int kv_get_temp(struct radeon_device *rdev);
 int kv_get_temp(struct radeon_device *rdev);
 
 
 int ci_dpm_init(struct radeon_device *rdev);
 int ci_dpm_init(struct radeon_device *rdev);
 int ci_dpm_enable(struct radeon_device *rdev);
 int ci_dpm_enable(struct radeon_device *rdev);
+int ci_dpm_late_enable(struct radeon_device *rdev);
 void ci_dpm_disable(struct radeon_device *rdev);
 void ci_dpm_disable(struct radeon_device *rdev);
 int ci_dpm_pre_set_power_state(struct radeon_device *rdev);
 int ci_dpm_pre_set_power_state(struct radeon_device *rdev);
 int ci_dpm_set_power_state(struct radeon_device *rdev);
 int ci_dpm_set_power_state(struct radeon_device *rdev);
@@ -770,6 +807,7 @@ void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
 
 
 int kv_dpm_init(struct radeon_device *rdev);
 int kv_dpm_init(struct radeon_device *rdev);
 int kv_dpm_enable(struct radeon_device *rdev);
 int kv_dpm_enable(struct radeon_device *rdev);
+int kv_dpm_late_enable(struct radeon_device *rdev);
 void kv_dpm_disable(struct radeon_device *rdev);
 void kv_dpm_disable(struct radeon_device *rdev);
 int kv_dpm_pre_set_power_state(struct radeon_device *rdev);
 int kv_dpm_pre_set_power_state(struct radeon_device *rdev);
 int kv_dpm_set_power_state(struct radeon_device *rdev);
 int kv_dpm_set_power_state(struct radeon_device *rdev);

+ 0 - 17
drivers/gpu/drm/radeon/radeon_atombios.c

@@ -30,27 +30,10 @@
 #include "atom.h"
 #include "atom.h"
 #include "atom-bits.h"
 #include "atom-bits.h"
 
 
-/* from radeon_encoder.c */
-extern uint32_t
-radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
-			uint8_t dac);
-extern void radeon_link_encoder_connector(struct drm_device *dev);
 extern void
 extern void
 radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
 radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum,
 			uint32_t supported_device, u16 caps);
 			uint32_t supported_device, u16 caps);
 
 
-/* from radeon_connector.c */
-extern void
-radeon_add_atom_connector(struct drm_device *dev,
-			  uint32_t connector_id,
-			  uint32_t supported_device,
-			  int connector_type,
-			  struct radeon_i2c_bus_rec *i2c_bus,
-			  uint32_t igp_lane_info,
-			  uint16_t connector_object_id,
-			  struct radeon_hpd *hpd,
-			  struct radeon_router *router);
-
 /* from radeon_legacy_encoder.c */
 /* from radeon_legacy_encoder.c */
 extern void
 extern void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,

+ 0 - 16
drivers/gpu/drm/radeon/radeon_combios.c

@@ -37,22 +37,6 @@
 #include <asm/pci-bridge.h>
 #include <asm/pci-bridge.h>
 #endif /* CONFIG_PPC_PMAC */
 #endif /* CONFIG_PPC_PMAC */
 
 
-/* from radeon_encoder.c */
-extern uint32_t
-radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
-			uint8_t dac);
-extern void radeon_link_encoder_connector(struct drm_device *dev);
-
-/* from radeon_connector.c */
-extern void
-radeon_add_legacy_connector(struct drm_device *dev,
-			    uint32_t connector_id,
-			    uint32_t supported_device,
-			    int connector_type,
-			    struct radeon_i2c_bus_rec *i2c_bus,
-			    uint16_t connector_object_id,
-			    struct radeon_hpd *hpd);
-
 /* from radeon_legacy_encoder.c */
 /* from radeon_legacy_encoder.c */
 extern void
 extern void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum,

+ 0 - 9
drivers/gpu/drm/radeon/radeon_connectors.c

@@ -33,15 +33,6 @@
 
 
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 
 
-extern void
-radeon_combios_connected_scratch_regs(struct drm_connector *connector,
-				      struct drm_encoder *encoder,
-				      bool connected);
-extern void
-radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
-				       struct drm_encoder *encoder,
-				       bool connected);
-
 void radeon_connector_hotplug(struct drm_connector *connector)
 void radeon_connector_hotplug(struct drm_connector *connector)
 {
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_device *dev = connector->dev;

+ 18 - 5
drivers/gpu/drm/radeon/radeon_device.c

@@ -144,6 +144,11 @@ void radeon_program_register_sequence(struct radeon_device *rdev,
 	}
 	}
 }
 }
 
 
+void radeon_pci_config_reset(struct radeon_device *rdev)
+{
+	pci_write_config_dword(rdev->pdev, 0x7c, RADEON_ASIC_RESET_DATA);
+}
+
 /**
 /**
  * radeon_surface_init - Clear GPU surface registers.
  * radeon_surface_init - Clear GPU surface registers.
  *
  *
@@ -249,7 +254,7 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
  * Init doorbell driver information (CIK)
  * Init doorbell driver information (CIK)
  * Returns 0 on success, error on failure.
  * Returns 0 on success, error on failure.
  */
  */
-int radeon_doorbell_init(struct radeon_device *rdev)
+static int radeon_doorbell_init(struct radeon_device *rdev)
 {
 {
 	/* doorbell bar mapping */
 	/* doorbell bar mapping */
 	rdev->doorbell.base = pci_resource_start(rdev->pdev, 2);
 	rdev->doorbell.base = pci_resource_start(rdev->pdev, 2);
@@ -278,7 +283,7 @@ int radeon_doorbell_init(struct radeon_device *rdev)
  *
  *
  * Tear down doorbell driver information (CIK)
  * Tear down doorbell driver information (CIK)
  */
  */
-void radeon_doorbell_fini(struct radeon_device *rdev)
+static void radeon_doorbell_fini(struct radeon_device *rdev)
 {
 {
 	iounmap(rdev->doorbell.ptr);
 	iounmap(rdev->doorbell.ptr);
 	rdev->doorbell.ptr = NULL;
 	rdev->doorbell.ptr = NULL;
@@ -1330,6 +1335,7 @@ int radeon_device_init(struct radeon_device *rdev,
 		if (r)
 		if (r)
 			return r;
 			return r;
 	}
 	}
+
 	if ((radeon_testing & 1)) {
 	if ((radeon_testing & 1)) {
 		if (rdev->accel_working)
 		if (rdev->accel_working)
 			radeon_test_moves(rdev);
 			radeon_test_moves(rdev);
@@ -1455,7 +1461,6 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
 
 
 	radeon_save_bios_scratch_regs(rdev);
 	radeon_save_bios_scratch_regs(rdev);
 
 
-	radeon_pm_suspend(rdev);
 	radeon_suspend(rdev);
 	radeon_suspend(rdev);
 	radeon_hpd_fini(rdev);
 	radeon_hpd_fini(rdev);
 	/* evict remaining vram memory */
 	/* evict remaining vram memory */
@@ -1516,14 +1521,22 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon)
 	if (r)
 	if (r)
 		DRM_ERROR("ib ring test failed (%d).\n", r);
 		DRM_ERROR("ib ring test failed (%d).\n", r);
 
 
-	radeon_pm_resume(rdev);
+	if (rdev->pm.dpm_enabled) {
+		/* do dpm late init */
+		r = radeon_pm_late_init(rdev);
+		if (r) {
+			rdev->pm.dpm_enabled = false;
+			DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+		}
+	}
+
 	radeon_restore_bios_scratch_regs(rdev);
 	radeon_restore_bios_scratch_regs(rdev);
 
 
 	if (fbcon) {
 	if (fbcon) {
 		radeon_fbdev_set_suspend(rdev, 0);
 		radeon_fbdev_set_suspend(rdev, 0);
 		console_unlock();
 		console_unlock();
 	}
 	}
-       
+
 	/* init dig PHYs, disp eng pll */
 	/* init dig PHYs, disp eng pll */
 	if (rdev->is_atom_bios) {
 	if (rdev->is_atom_bios) {
 		radeon_atom_encoder_init(rdev);
 		radeon_atom_encoder_init(rdev);

+ 13 - 4
drivers/gpu/drm/radeon/radeon_display.c

@@ -1464,12 +1464,22 @@ int radeon_modeset_init(struct radeon_device *rdev)
 	/* setup afmt */
 	/* setup afmt */
 	radeon_afmt_init(rdev);
 	radeon_afmt_init(rdev);
 
 
-	/* Initialize power management */
-	radeon_pm_init(rdev);
-
 	radeon_fbdev_init(rdev);
 	radeon_fbdev_init(rdev);
 	drm_kms_helper_poll_init(rdev->ddev);
 	drm_kms_helper_poll_init(rdev->ddev);
 
 
+	if (rdev->pm.dpm_enabled) {
+		/* do dpm late init */
+		ret = radeon_pm_late_init(rdev);
+		if (ret) {
+			rdev->pm.dpm_enabled = false;
+			DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n");
+		}
+		/* set the dpm state for PX since there won't be
+		 * a modeset to call this.
+		 */
+		radeon_pm_compute_clocks(rdev);
+	}
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1477,7 +1487,6 @@ void radeon_modeset_fini(struct radeon_device *rdev)
 {
 {
 	radeon_fbdev_fini(rdev);
 	radeon_fbdev_fini(rdev);
 	kfree(rdev->mode_info.bios_hardcoded_edid);
 	kfree(rdev->mode_info.bios_hardcoded_edid);
-	radeon_pm_fini(rdev);
 
 
 	if (rdev->mode_info.mode_config_initialized) {
 	if (rdev->mode_info.mode_config_initialized) {
 		radeon_afmt_fini(rdev);
 		radeon_afmt_fini(rdev);

+ 4 - 0
drivers/gpu/drm/radeon/radeon_drv.c

@@ -167,6 +167,7 @@ int radeon_fastfb = 0;
 int radeon_dpm = -1;
 int radeon_dpm = -1;
 int radeon_aspm = -1;
 int radeon_aspm = -1;
 int radeon_runtime_pm = -1;
 int radeon_runtime_pm = -1;
+int radeon_hard_reset = 0;
 
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
 module_param_named(no_wb, radeon_no_wb, int, 0444);
@@ -231,6 +232,9 @@ module_param_named(aspm, radeon_aspm, int, 0444);
 MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)");
 MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)");
 module_param_named(runpm, radeon_runtime_pm, int, 0444);
 module_param_named(runpm, radeon_runtime_pm, int, 0444);
 
 
+MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))");
+module_param_named(hard_reset, radeon_hard_reset, int, 0444);
+
 static struct pci_device_id pciidlist[] = {
 static struct pci_device_id pciidlist[] = {
 	radeon_PCI_IDS
 	radeon_PCI_IDS
 };
 };

+ 2 - 0
drivers/gpu/drm/radeon/radeon_fence.c

@@ -841,6 +841,8 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
 		if (!rdev->fence_drv[i].initialized)
 		if (!rdev->fence_drv[i].initialized)
 			continue;
 			continue;
 
 
+		radeon_fence_process(rdev, i);
+
 		seq_printf(m, "--- ring %d ---\n", i);
 		seq_printf(m, "--- ring %d ---\n", i);
 		seq_printf(m, "Last signaled fence 0x%016llx\n",
 		seq_printf(m, "Last signaled fence 0x%016llx\n",
 			   (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq));
 			   (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq));

+ 1 - 1
drivers/gpu/drm/radeon/radeon_gem.c

@@ -86,7 +86,7 @@ retry:
 	return 0;
 	return 0;
 }
 }
 
 
-int radeon_gem_set_domain(struct drm_gem_object *gobj,
+static int radeon_gem_set_domain(struct drm_gem_object *gobj,
 			  uint32_t rdomain, uint32_t wdomain)
 			  uint32_t rdomain, uint32_t wdomain)
 {
 {
 	struct radeon_bo *robj;
 	struct radeon_bo *robj;

+ 3 - 0
drivers/gpu/drm/radeon/radeon_i2c.c

@@ -1020,6 +1020,9 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 /* Add the default buses */
 /* Add the default buses */
 void radeon_i2c_init(struct radeon_device *rdev)
 void radeon_i2c_init(struct radeon_device *rdev)
 {
 {
+	if (radeon_hw_i2c)
+		DRM_INFO("hw_i2c forced on, you may experience display detection problems!\n");
+
 	if (rdev->is_atom_bios)
 	if (rdev->is_atom_bios)
 		radeon_atombios_i2c_init(rdev);
 		radeon_atombios_i2c_init(rdev);
 	else
 	else

+ 3 - 2
drivers/gpu/drm/radeon/radeon_kms.c

@@ -191,7 +191,7 @@ static void radeon_set_filp_rights(struct drm_device *dev,
  * etc. (all asics).
  * etc. (all asics).
  * Returns 0 on success, -EINVAL on failure.
  * Returns 0 on success, -EINVAL on failure.
  */
  */
-int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_radeon_info *info = data;
 	struct drm_radeon_info *info = data;
@@ -707,7 +707,8 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
 }
 }
 
 
 #define KMS_INVALID_IOCTL(name)						\
 #define KMS_INVALID_IOCTL(name)						\
-int name(struct drm_device *dev, void *data, struct drm_file *file_priv)\
+static int name(struct drm_device *dev, void *data, struct drm_file	\
+		*file_priv)						\
 {									\
 {									\
 	DRM_ERROR("invalid ioctl with kms %s\n", __func__);		\
 	DRM_ERROR("invalid ioctl with kms %s\n", __func__);		\
 	return -EINVAL;							\
 	return -EINVAL;							\

+ 34 - 0
drivers/gpu/drm/radeon/radeon_mode.h

@@ -624,6 +624,30 @@ struct atom_voltage_table
 	struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
 	struct atom_voltage_table_entry entries[MAX_VOLTAGE_ENTRIES];
 };
 };
 
 
+
+extern void
+radeon_add_atom_connector(struct drm_device *dev,
+			  uint32_t connector_id,
+			  uint32_t supported_device,
+			  int connector_type,
+			  struct radeon_i2c_bus_rec *i2c_bus,
+			  uint32_t igp_lane_info,
+			  uint16_t connector_object_id,
+			  struct radeon_hpd *hpd,
+			  struct radeon_router *router);
+extern void
+radeon_add_legacy_connector(struct drm_device *dev,
+			    uint32_t connector_id,
+			    uint32_t supported_device,
+			    int connector_type,
+			    struct radeon_i2c_bus_rec *i2c_bus,
+			    uint16_t connector_object_id,
+			    struct radeon_hpd *hpd);
+extern uint32_t
+radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device,
+			uint8_t dac);
+extern void radeon_link_encoder_connector(struct drm_device *dev);
+
 extern enum radeon_tv_std
 extern enum radeon_tv_std
 radeon_combios_get_tv_info(struct radeon_device *rdev);
 radeon_combios_get_tv_info(struct radeon_device *rdev);
 extern enum radeon_tv_std
 extern enum radeon_tv_std
@@ -631,6 +655,15 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev);
 extern void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
 extern void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
 						 u16 *vddc, u16 *vddci, u16 *mvdd);
 						 u16 *vddc, u16 *vddci, u16 *mvdd);
 
 
+extern void
+radeon_combios_connected_scratch_regs(struct drm_connector *connector,
+				      struct drm_encoder *encoder,
+				      bool connected);
+extern void
+radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
+				       struct drm_encoder *encoder,
+				       bool connected);
+
 extern struct drm_connector *
 extern struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 extern struct drm_connector *
 extern struct drm_connector *
@@ -666,6 +699,7 @@ extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
 extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
 extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 				u8 write_byte, u8 *read_byte);
 				u8 write_byte, u8 *read_byte);
+void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
 
 
 extern void radeon_i2c_init(struct radeon_device *rdev);
 extern void radeon_i2c_init(struct radeon_device *rdev);
 extern void radeon_i2c_fini(struct radeon_device *rdev);
 extern void radeon_i2c_fini(struct radeon_device *rdev);

+ 1 - 1
drivers/gpu/drm/radeon/radeon_object.c

@@ -46,7 +46,7 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo);
  * function are calling it.
  * function are calling it.
  */
  */
 
 
-void radeon_bo_clear_va(struct radeon_bo *bo)
+static void radeon_bo_clear_va(struct radeon_bo *bo)
 {
 {
 	struct radeon_bo_va *bo_va, *tmp;
 	struct radeon_bo_va *bo_va, *tmp;
 
 

+ 82 - 64
drivers/gpu/drm/radeon/radeon_pm.c

@@ -1010,8 +1010,10 @@ static void radeon_pm_resume_old(struct radeon_device *rdev)
 	rdev->pm.current_clock_mode_index = 0;
 	rdev->pm.current_clock_mode_index = 0;
 	rdev->pm.current_sclk = rdev->pm.default_sclk;
 	rdev->pm.current_sclk = rdev->pm.default_sclk;
 	rdev->pm.current_mclk = rdev->pm.default_mclk;
 	rdev->pm.current_mclk = rdev->pm.default_mclk;
-	rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
-	rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci;
+	if (rdev->pm.power_state) {
+		rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
+		rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci;
+	}
 	if (rdev->pm.pm_method == PM_METHOD_DYNPM
 	if (rdev->pm.pm_method == PM_METHOD_DYNPM
 	    && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
 	    && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
 		rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
 		rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
@@ -1032,25 +1034,27 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev)
 	radeon_dpm_setup_asic(rdev);
 	radeon_dpm_setup_asic(rdev);
 	ret = radeon_dpm_enable(rdev);
 	ret = radeon_dpm_enable(rdev);
 	mutex_unlock(&rdev->pm.mutex);
 	mutex_unlock(&rdev->pm.mutex);
-	if (ret) {
-		DRM_ERROR("radeon: dpm resume failed\n");
-		if ((rdev->family >= CHIP_BARTS) &&
-		    (rdev->family <= CHIP_CAYMAN) &&
-		    rdev->mc_fw) {
-			if (rdev->pm.default_vddc)
-				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
-							SET_VOLTAGE_TYPE_ASIC_VDDC);
-			if (rdev->pm.default_vddci)
-				radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
-							SET_VOLTAGE_TYPE_ASIC_VDDCI);
-			if (rdev->pm.default_sclk)
-				radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-			if (rdev->pm.default_mclk)
-				radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
-		}
-	} else {
-		rdev->pm.dpm_enabled = true;
-		radeon_pm_compute_clocks(rdev);
+	if (ret)
+		goto dpm_resume_fail;
+	rdev->pm.dpm_enabled = true;
+	radeon_pm_compute_clocks(rdev);
+	return;
+
+dpm_resume_fail:
+	DRM_ERROR("radeon: dpm resume failed\n");
+	if ((rdev->family >= CHIP_BARTS) &&
+	    (rdev->family <= CHIP_CAYMAN) &&
+	    rdev->mc_fw) {
+		if (rdev->pm.default_vddc)
+			radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
+						SET_VOLTAGE_TYPE_ASIC_VDDC);
+		if (rdev->pm.default_vddci)
+			radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
+						SET_VOLTAGE_TYPE_ASIC_VDDCI);
+		if (rdev->pm.default_sclk)
+			radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+		if (rdev->pm.default_mclk)
+			radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
 	}
 	}
 }
 }
 
 
@@ -1170,51 +1174,50 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev)
 	radeon_dpm_setup_asic(rdev);
 	radeon_dpm_setup_asic(rdev);
 	ret = radeon_dpm_enable(rdev);
 	ret = radeon_dpm_enable(rdev);
 	mutex_unlock(&rdev->pm.mutex);
 	mutex_unlock(&rdev->pm.mutex);
-	if (ret) {
-		rdev->pm.dpm_enabled = false;
-		if ((rdev->family >= CHIP_BARTS) &&
-		    (rdev->family <= CHIP_CAYMAN) &&
-		    rdev->mc_fw) {
-			if (rdev->pm.default_vddc)
-				radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
-							SET_VOLTAGE_TYPE_ASIC_VDDC);
-			if (rdev->pm.default_vddci)
-				radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
-							SET_VOLTAGE_TYPE_ASIC_VDDCI);
-			if (rdev->pm.default_sclk)
-				radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
-			if (rdev->pm.default_mclk)
-				radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
-		}
-		DRM_ERROR("radeon: dpm initialization failed\n");
-		return ret;
-	}
+	if (ret)
+		goto dpm_failed;
 	rdev->pm.dpm_enabled = true;
 	rdev->pm.dpm_enabled = true;
-	radeon_pm_compute_clocks(rdev);
 
 
-	if (rdev->pm.num_power_states > 1) {
-		ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
-		if (ret)
-			DRM_ERROR("failed to create device file for dpm state\n");
-		ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
-		if (ret)
-			DRM_ERROR("failed to create device file for dpm state\n");
-		/* XXX: these are noops for dpm but are here for backwards compat */
-		ret = device_create_file(rdev->dev, &dev_attr_power_profile);
-		if (ret)
-			DRM_ERROR("failed to create device file for power profile\n");
-		ret = device_create_file(rdev->dev, &dev_attr_power_method);
-		if (ret)
-			DRM_ERROR("failed to create device file for power method\n");
-
-		if (radeon_debugfs_pm_init(rdev)) {
-			DRM_ERROR("Failed to register debugfs file for dpm!\n");
-		}
+	ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state);
+	if (ret)
+		DRM_ERROR("failed to create device file for dpm state\n");
+	ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level);
+	if (ret)
+		DRM_ERROR("failed to create device file for dpm state\n");
+	/* XXX: these are noops for dpm but are here for backwards compat */
+	ret = device_create_file(rdev->dev, &dev_attr_power_profile);
+	if (ret)
+		DRM_ERROR("failed to create device file for power profile\n");
+	ret = device_create_file(rdev->dev, &dev_attr_power_method);
+	if (ret)
+		DRM_ERROR("failed to create device file for power method\n");
 
 
-		DRM_INFO("radeon: dpm initialized\n");
+	if (radeon_debugfs_pm_init(rdev)) {
+		DRM_ERROR("Failed to register debugfs file for dpm!\n");
 	}
 	}
 
 
+	DRM_INFO("radeon: dpm initialized\n");
+
 	return 0;
 	return 0;
+
+dpm_failed:
+	rdev->pm.dpm_enabled = false;
+	if ((rdev->family >= CHIP_BARTS) &&
+	    (rdev->family <= CHIP_CAYMAN) &&
+	    rdev->mc_fw) {
+		if (rdev->pm.default_vddc)
+			radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
+						SET_VOLTAGE_TYPE_ASIC_VDDC);
+		if (rdev->pm.default_vddci)
+			radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
+						SET_VOLTAGE_TYPE_ASIC_VDDCI);
+		if (rdev->pm.default_sclk)
+			radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
+		if (rdev->pm.default_mclk)
+			radeon_set_memory_clock(rdev, rdev->pm.default_mclk);
+	}
+	DRM_ERROR("radeon: dpm initialization failed\n");
+	return ret;
 }
 }
 
 
 int radeon_pm_init(struct radeon_device *rdev)
 int radeon_pm_init(struct radeon_device *rdev)
@@ -1229,10 +1232,6 @@ int radeon_pm_init(struct radeon_device *rdev)
 	case CHIP_RS780:
 	case CHIP_RS780:
 	case CHIP_RS880:
 	case CHIP_RS880:
 	case CHIP_CAYMAN:
 	case CHIP_CAYMAN:
-	case CHIP_BONAIRE:
-	case CHIP_KABINI:
-	case CHIP_KAVERI:
-	case CHIP_HAWAII:
 		/* DPM requires the RLC, RV770+ dGPU requires SMC */
 		/* DPM requires the RLC, RV770+ dGPU requires SMC */
 		if (!rdev->rlc_fw)
 		if (!rdev->rlc_fw)
 			rdev->pm.pm_method = PM_METHOD_PROFILE;
 			rdev->pm.pm_method = PM_METHOD_PROFILE;
@@ -1266,6 +1265,10 @@ int radeon_pm_init(struct radeon_device *rdev)
 	case CHIP_VERDE:
 	case CHIP_VERDE:
 	case CHIP_OLAND:
 	case CHIP_OLAND:
 	case CHIP_HAINAN:
 	case CHIP_HAINAN:
+	case CHIP_BONAIRE:
+	case CHIP_KABINI:
+	case CHIP_KAVERI:
+	case CHIP_HAWAII:
 		/* DPM requires the RLC, RV770+ dGPU requires SMC */
 		/* DPM requires the RLC, RV770+ dGPU requires SMC */
 		if (!rdev->rlc_fw)
 		if (!rdev->rlc_fw)
 			rdev->pm.pm_method = PM_METHOD_PROFILE;
 			rdev->pm.pm_method = PM_METHOD_PROFILE;
@@ -1290,6 +1293,18 @@ int radeon_pm_init(struct radeon_device *rdev)
 		return radeon_pm_init_old(rdev);
 		return radeon_pm_init_old(rdev);
 }
 }
 
 
+int radeon_pm_late_init(struct radeon_device *rdev)
+{
+	int ret = 0;
+
+	if (rdev->pm.pm_method == PM_METHOD_DPM) {
+		mutex_lock(&rdev->pm.mutex);
+		ret = radeon_dpm_late_enable(rdev);
+		mutex_unlock(&rdev->pm.mutex);
+	}
+	return ret;
+}
+
 static void radeon_pm_fini_old(struct radeon_device *rdev)
 static void radeon_pm_fini_old(struct radeon_device *rdev)
 {
 {
 	if (rdev->pm.num_power_states > 1) {
 	if (rdev->pm.num_power_states > 1) {
@@ -1420,6 +1435,9 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
 	struct drm_crtc *crtc;
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	struct radeon_crtc *radeon_crtc;
 
 
+	if (!rdev->pm.dpm_enabled)
+		return;
+
 	mutex_lock(&rdev->pm.mutex);
 	mutex_lock(&rdev->pm.mutex);
 
 
 	/* update active crtc counts */
 	/* update active crtc counts */

+ 39 - 53
drivers/gpu/drm/radeon/radeon_ring.c

@@ -332,36 +332,6 @@ bool radeon_ring_supports_scratch_reg(struct radeon_device *rdev,
 	}
 	}
 }
 }
 
 
-u32 radeon_ring_generic_get_rptr(struct radeon_device *rdev,
-				 struct radeon_ring *ring)
-{
-	u32 rptr;
-
-	if (rdev->wb.enabled)
-		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
-	else
-		rptr = RREG32(ring->rptr_reg);
-
-	return rptr;
-}
-
-u32 radeon_ring_generic_get_wptr(struct radeon_device *rdev,
-				 struct radeon_ring *ring)
-{
-	u32 wptr;
-
-	wptr = RREG32(ring->wptr_reg);
-
-	return wptr;
-}
-
-void radeon_ring_generic_set_wptr(struct radeon_device *rdev,
-				  struct radeon_ring *ring)
-{
-	WREG32(ring->wptr_reg, ring->wptr);
-	(void)RREG32(ring->wptr_reg);
-}
-
 /**
 /**
  * radeon_ring_free_size - update the free size
  * radeon_ring_free_size - update the free size
  *
  *
@@ -689,22 +659,18 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring,
  * @ring: radeon_ring structure holding ring information
  * @ring: radeon_ring structure holding ring information
  * @ring_size: size of the ring
  * @ring_size: size of the ring
  * @rptr_offs: offset of the rptr writeback location in the WB buffer
  * @rptr_offs: offset of the rptr writeback location in the WB buffer
- * @rptr_reg: MMIO offset of the rptr register
- * @wptr_reg: MMIO offset of the wptr register
  * @nop: nop packet for this ring
  * @nop: nop packet for this ring
  *
  *
  * Initialize the driver information for the selected ring (all asics).
  * Initialize the driver information for the selected ring (all asics).
  * Returns 0 on success, error on failure.
  * Returns 0 on success, error on failure.
  */
  */
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
 int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size,
-		     unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 nop)
+		     unsigned rptr_offs, u32 nop)
 {
 {
 	int r;
 	int r;
 
 
 	ring->ring_size = ring_size;
 	ring->ring_size = ring_size;
 	ring->rptr_offs = rptr_offs;
 	ring->rptr_offs = rptr_offs;
-	ring->rptr_reg = rptr_reg;
-	ring->wptr_reg = wptr_reg;
 	ring->nop = nop;
 	ring->nop = nop;
 	/* Allocate ring buffer */
 	/* Allocate ring buffer */
 	if (ring->ring_obj == NULL) {
 	if (ring->ring_obj == NULL) {
@@ -790,34 +756,54 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data)
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_device *rdev = dev->dev_private;
 	int ridx = *(int*)node->info_ent->data;
 	int ridx = *(int*)node->info_ent->data;
 	struct radeon_ring *ring = &rdev->ring[ridx];
 	struct radeon_ring *ring = &rdev->ring[ridx];
+
+	uint32_t rptr, wptr, rptr_next;
 	unsigned count, i, j;
 	unsigned count, i, j;
-	u32 tmp;
 
 
 	radeon_ring_free_size(rdev, ring);
 	radeon_ring_free_size(rdev, ring);
 	count = (ring->ring_size / 4) - ring->ring_free_dw;
 	count = (ring->ring_size / 4) - ring->ring_free_dw;
-	tmp = radeon_ring_get_wptr(rdev, ring);
-	seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp);
-	tmp = radeon_ring_get_rptr(rdev, ring);
-	seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp);
+
+	wptr = radeon_ring_get_wptr(rdev, ring);
+	seq_printf(m, "wptr: 0x%08x [%5d]\n",
+		   wptr, wptr);
+
+	rptr = radeon_ring_get_rptr(rdev, ring);
+	seq_printf(m, "rptr: 0x%08x [%5d]\n",
+		   rptr, rptr);
+
 	if (ring->rptr_save_reg) {
 	if (ring->rptr_save_reg) {
-		seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg,
-			   RREG32(ring->rptr_save_reg));
-	}
-	seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr);
-	seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n", ring->rptr, ring->rptr);
-	seq_printf(m, "last semaphore signal addr : 0x%016llx\n", ring->last_semaphore_signal_addr);
-	seq_printf(m, "last semaphore wait addr   : 0x%016llx\n", ring->last_semaphore_wait_addr);
+		rptr_next = RREG32(ring->rptr_save_reg);
+		seq_printf(m, "rptr next(0x%04x): 0x%08x [%5d]\n",
+			   ring->rptr_save_reg, rptr_next, rptr_next);
+	} else
+		rptr_next = ~0;
+
+	seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n",
+		   ring->wptr, ring->wptr);
+	seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n",
+		   ring->rptr, ring->rptr);
+	seq_printf(m, "last semaphore signal addr : 0x%016llx\n",
+		   ring->last_semaphore_signal_addr);
+	seq_printf(m, "last semaphore wait addr   : 0x%016llx\n",
+		   ring->last_semaphore_wait_addr);
 	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
 	seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
 	seq_printf(m, "%u dwords in ring\n", count);
 	seq_printf(m, "%u dwords in ring\n", count);
+
+	if (!ring->ready)
+		return 0;
+
 	/* print 8 dw before current rptr as often it's the last executed
 	/* print 8 dw before current rptr as often it's the last executed
 	 * packet that is the root issue
 	 * packet that is the root issue
 	 */
 	 */
-	i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask;
-	if (ring->ready) {
-		for (j = 0; j <= (count + 32); j++) {
-			seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]);
-			i = (i + 1) & ring->ptr_mask;
-		}
+	i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask;
+	for (j = 0; j <= (count + 32); j++) {
+		seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]);
+		if (rptr == i)
+			seq_puts(m, " *");
+		if (rptr_next == i)
+			seq_puts(m, " #");
+		seq_puts(m, "\n");
+		i = (i + 1) & ring->ptr_mask;
 	}
 	}
 	return 0;
 	return 0;
 }
 }

+ 4 - 2
drivers/gpu/drm/radeon/radeon_sa.c

@@ -402,13 +402,15 @@ void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager,
 
 
 	spin_lock(&sa_manager->wq.lock);
 	spin_lock(&sa_manager->wq.lock);
 	list_for_each_entry(i, &sa_manager->olist, olist) {
 	list_for_each_entry(i, &sa_manager->olist, olist) {
+		uint64_t soffset = i->soffset + sa_manager->gpu_addr;
+		uint64_t eoffset = i->eoffset + sa_manager->gpu_addr;
 		if (&i->olist == sa_manager->hole) {
 		if (&i->olist == sa_manager->hole) {
 			seq_printf(m, ">");
 			seq_printf(m, ">");
 		} else {
 		} else {
 			seq_printf(m, " ");
 			seq_printf(m, " ");
 		}
 		}
-		seq_printf(m, "[0x%08x 0x%08x] size %8d",
-			   i->soffset, i->eoffset, i->eoffset - i->soffset);
+		seq_printf(m, "[0x%010llx 0x%010llx] size %8lld",
+			   soffset, eoffset, eoffset - soffset);
 		if (i->fence) {
 		if (i->fence) {
 			seq_printf(m, " protected by 0x%016llx on ring %d",
 			seq_printf(m, " protected by 0x%016llx on ring %d",
 				   i->fence->seq, i->fence->ring);
 				   i->fence->seq, i->fence->ring);

+ 160 - 35
drivers/gpu/drm/radeon/radeon_ttm.c

@@ -39,12 +39,14 @@
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/swiotlb.h>
 #include <linux/swiotlb.h>
+#include <linux/debugfs.h>
 #include "radeon_reg.h"
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "radeon.h"
 
 
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 
 
 static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
 static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev);
 
 
 static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 {
 {
@@ -753,6 +755,7 @@ void radeon_ttm_fini(struct radeon_device *rdev)
 
 
 	if (!rdev->mman.initialized)
 	if (!rdev->mman.initialized)
 		return;
 		return;
+	radeon_ttm_debugfs_fini(rdev);
 	if (rdev->stollen_vga_memory) {
 	if (rdev->stollen_vga_memory) {
 		r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
 		r = radeon_bo_reserve(rdev->stollen_vga_memory, false);
 		if (r == 0) {
 		if (r == 0) {
@@ -832,16 +835,15 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma)
 	return 0;
 	return 0;
 }
 }
 
 
-
-#define RADEON_DEBUGFS_MEM_TYPES 2
-
 #if defined(CONFIG_DEBUG_FS)
 #if defined(CONFIG_DEBUG_FS)
+
 static int radeon_mm_dump_table(struct seq_file *m, void *data)
 static int radeon_mm_dump_table(struct seq_file *m, void *data)
 {
 {
 	struct drm_info_node *node = (struct drm_info_node *)m->private;
 	struct drm_info_node *node = (struct drm_info_node *)m->private;
-	struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;
+	unsigned ttm_pl = *(int *)node->info_ent->data;
 	struct drm_device *dev = node->minor->dev;
 	struct drm_device *dev = node->minor->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_device *rdev = dev->dev_private;
+	struct drm_mm *mm = (struct drm_mm *)rdev->mman.bdev.man[ttm_pl].priv;
 	int ret;
 	int ret;
 	struct ttm_bo_global *glob = rdev->mman.bdev.glob;
 	struct ttm_bo_global *glob = rdev->mman.bdev.glob;
 
 
@@ -850,46 +852,169 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data)
 	spin_unlock(&glob->lru_lock);
 	spin_unlock(&glob->lru_lock);
 	return ret;
 	return ret;
 }
 }
+
+static int ttm_pl_vram = TTM_PL_VRAM;
+static int ttm_pl_tt = TTM_PL_TT;
+
+static struct drm_info_list radeon_ttm_debugfs_list[] = {
+	{"radeon_vram_mm", radeon_mm_dump_table, 0, &ttm_pl_vram},
+	{"radeon_gtt_mm", radeon_mm_dump_table, 0, &ttm_pl_tt},
+	{"ttm_page_pool", ttm_page_alloc_debugfs, 0, NULL},
+#ifdef CONFIG_SWIOTLB
+	{"ttm_dma_page_pool", ttm_dma_page_alloc_debugfs, 0, NULL}
 #endif
 #endif
+};
 
 
-static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
+static int radeon_ttm_vram_open(struct inode *inode, struct file *filep)
 {
 {
-#if defined(CONFIG_DEBUG_FS)
-	static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES+2];
-	static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES+2][32];
-	unsigned i;
+	struct radeon_device *rdev = inode->i_private;
+	i_size_write(inode, rdev->mc.mc_vram_size);
+	filep->private_data = inode->i_private;
+	return 0;
+}
 
 
-	for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) {
-		if (i == 0)
-			sprintf(radeon_mem_types_names[i], "radeon_vram_mm");
-		else
-			sprintf(radeon_mem_types_names[i], "radeon_gtt_mm");
-		radeon_mem_types_list[i].name = radeon_mem_types_names[i];
-		radeon_mem_types_list[i].show = &radeon_mm_dump_table;
-		radeon_mem_types_list[i].driver_features = 0;
-		if (i == 0)
-			radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv;
-		else
-			radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv;
+static ssize_t radeon_ttm_vram_read(struct file *f, char __user *buf,
+				    size_t size, loff_t *pos)
+{
+	struct radeon_device *rdev = f->private_data;
+	ssize_t result = 0;
+	int r;
 
 
+	if (size & 0x3 || *pos & 0x3)
+		return -EINVAL;
+
+	while (size) {
+		unsigned long flags;
+		uint32_t value;
+
+		if (*pos >= rdev->mc.mc_vram_size)
+			return result;
+
+		spin_lock_irqsave(&rdev->mmio_idx_lock, flags);
+		WREG32(RADEON_MM_INDEX, ((uint32_t)*pos) | 0x80000000);
+		if (rdev->family >= CHIP_CEDAR)
+			WREG32(EVERGREEN_MM_INDEX_HI, *pos >> 31);
+		value = RREG32(RADEON_MM_DATA);
+		spin_unlock_irqrestore(&rdev->mmio_idx_lock, flags);
+
+		r = put_user(value, (uint32_t *)buf);
+		if (r)
+			return r;
+
+		result += 4;
+		buf += 4;
+		*pos += 4;
+		size -= 4;
 	}
 	}
-	/* Add ttm page pool to debugfs */
-	sprintf(radeon_mem_types_names[i], "ttm_page_pool");
-	radeon_mem_types_list[i].name = radeon_mem_types_names[i];
-	radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs;
-	radeon_mem_types_list[i].driver_features = 0;
-	radeon_mem_types_list[i++].data = NULL;
-#ifdef CONFIG_SWIOTLB
-	if (swiotlb_nr_tbl()) {
-		sprintf(radeon_mem_types_names[i], "ttm_dma_page_pool");
-		radeon_mem_types_list[i].name = radeon_mem_types_names[i];
-		radeon_mem_types_list[i].show = &ttm_dma_page_alloc_debugfs;
-		radeon_mem_types_list[i].driver_features = 0;
-		radeon_mem_types_list[i++].data = NULL;
+
+	return result;
+}
+
+static const struct file_operations radeon_ttm_vram_fops = {
+	.owner = THIS_MODULE,
+	.open = radeon_ttm_vram_open,
+	.read = radeon_ttm_vram_read,
+	.llseek = default_llseek
+};
+
+static int radeon_ttm_gtt_open(struct inode *inode, struct file *filep)
+{
+	struct radeon_device *rdev = inode->i_private;
+	i_size_write(inode, rdev->mc.gtt_size);
+	filep->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t radeon_ttm_gtt_read(struct file *f, char __user *buf,
+				   size_t size, loff_t *pos)
+{
+	struct radeon_device *rdev = f->private_data;
+	ssize_t result = 0;
+	int r;
+
+	while (size) {
+		loff_t p = *pos / PAGE_SIZE;
+		unsigned off = *pos & ~PAGE_MASK;
+		ssize_t cur_size = min(size, PAGE_SIZE - off);
+		struct page *page;
+		void *ptr;
+
+		if (p >= rdev->gart.num_cpu_pages)
+			return result;
+
+		page = rdev->gart.pages[p];
+		if (page) {
+			ptr = kmap(page);
+			ptr += off;
+
+			r = copy_to_user(buf, ptr, cur_size);
+			kunmap(rdev->gart.pages[p]);
+		} else
+			r = clear_user(buf, cur_size);
+
+		if (r)
+			return -EFAULT;
+
+		result += cur_size;
+		buf += cur_size;
+		*pos += cur_size;
+		size -= cur_size;
 	}
 	}
+
+	return result;
+}
+
+static const struct file_operations radeon_ttm_gtt_fops = {
+	.owner = THIS_MODULE,
+	.open = radeon_ttm_gtt_open,
+	.read = radeon_ttm_gtt_read,
+	.llseek = default_llseek
+};
+
 #endif
 #endif
-	return radeon_debugfs_add_files(rdev, radeon_mem_types_list, i);
 
 
+static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+	unsigned count;
+
+	struct drm_minor *minor = rdev->ddev->primary;
+	struct dentry *ent, *root = minor->debugfs_root;
+
+	ent = debugfs_create_file("radeon_vram", S_IFREG | S_IRUGO, root,
+				  rdev, &radeon_ttm_vram_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+	rdev->mman.vram = ent;
+
+	ent = debugfs_create_file("radeon_gtt", S_IFREG | S_IRUGO, root,
+				  rdev, &radeon_ttm_gtt_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+	rdev->mman.gtt = ent;
+
+	count = ARRAY_SIZE(radeon_ttm_debugfs_list);
+
+#ifdef CONFIG_SWIOTLB
+	if (!swiotlb_nr_tbl())
+		--count;
 #endif
 #endif
+
+	return radeon_debugfs_add_files(rdev, radeon_ttm_debugfs_list, count);
+#else
+
 	return 0;
 	return 0;
+#endif
+}
+
+static void radeon_ttm_debugfs_fini(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+
+	debugfs_remove(rdev->mman.vram);
+	rdev->mman.vram = NULL;
+
+	debugfs_remove(rdev->mman.gtt);
+	rdev->mman.gtt = NULL;
+#endif
 }
 }

+ 7 - 0
drivers/gpu/drm/radeon/rs400.c

@@ -474,6 +474,8 @@ int rs400_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs400_startup(rdev);
 	r = rs400_startup(rdev);
 	if (r) {
 	if (r) {
@@ -484,6 +486,7 @@ int rs400_resume(struct radeon_device *rdev)
 
 
 int rs400_suspend(struct radeon_device *rdev)
 int rs400_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
 	r100_irq_disable(rdev);
 	r100_irq_disable(rdev);
@@ -493,6 +496,7 @@ int rs400_suspend(struct radeon_device *rdev)
 
 
 void rs400_fini(struct radeon_device *rdev)
 void rs400_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_ib_pool_fini(rdev);
@@ -560,6 +564,9 @@ int rs400_init(struct radeon_device *rdev)
 		return r;
 		return r;
 	r300_set_reg_safe(rdev);
 	r300_set_reg_safe(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs400_startup(rdev);
 	r = rs400_startup(rdev);
 	if (r) {
 	if (r) {

+ 7 - 0
drivers/gpu/drm/radeon/rs600.c

@@ -1048,6 +1048,8 @@ int rs600_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs600_startup(rdev);
 	r = rs600_startup(rdev);
 	if (r) {
 	if (r) {
@@ -1058,6 +1060,7 @@ int rs600_resume(struct radeon_device *rdev)
 
 
 int rs600_suspend(struct radeon_device *rdev)
 int rs600_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
@@ -1068,6 +1071,7 @@ int rs600_suspend(struct radeon_device *rdev)
 
 
 void rs600_fini(struct radeon_device *rdev)
 void rs600_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
@@ -1136,6 +1140,9 @@ int rs600_init(struct radeon_device *rdev)
 		return r;
 		return r;
 	rs600_set_safe_registers(rdev);
 	rs600_set_safe_registers(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs600_startup(rdev);
 	r = rs600_startup(rdev);
 	if (r) {
 	if (r) {

+ 7 - 0
drivers/gpu/drm/radeon/rs690.c

@@ -746,6 +746,8 @@ int rs690_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs690_startup(rdev);
 	r = rs690_startup(rdev);
 	if (r) {
 	if (r) {
@@ -756,6 +758,7 @@ int rs690_resume(struct radeon_device *rdev)
 
 
 int rs690_suspend(struct radeon_device *rdev)
 int rs690_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
@@ -766,6 +769,7 @@ int rs690_suspend(struct radeon_device *rdev)
 
 
 void rs690_fini(struct radeon_device *rdev)
 void rs690_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
@@ -835,6 +839,9 @@ int rs690_init(struct radeon_device *rdev)
 		return r;
 		return r;
 	rs600_set_safe_registers(rdev);
 	rs600_set_safe_registers(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rs690_startup(rdev);
 	r = rs690_startup(rdev);
 	if (r) {
 	if (r) {

+ 0 - 8
drivers/gpu/drm/radeon/rs780_dpm.c

@@ -623,14 +623,6 @@ int rs780_dpm_enable(struct radeon_device *rdev)
 	if (pi->gfx_clock_gating)
 	if (pi->gfx_clock_gating)
 		r600_gfx_clockgating_enable(rdev, true);
 		r600_gfx_clockgating_enable(rdev, true);
 
 
-	if (rdev->irq.installed && (rdev->pm.int_thermal_type == THERMAL_TYPE_RV6XX)) {
-		ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-		if (ret)
-			return ret;
-		rdev->irq.dpm_thermal = true;
-		radeon_irq_set(rdev);
-	}
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 7 - 0
drivers/gpu/drm/radeon/rv515.c

@@ -586,6 +586,8 @@ int rv515_resume(struct radeon_device *rdev)
 	/* Initialize surface registers */
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	radeon_surface_init(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r =  rv515_startup(rdev);
 	r =  rv515_startup(rdev);
 	if (r) {
 	if (r) {
@@ -596,6 +598,7 @@ int rv515_resume(struct radeon_device *rdev)
 
 
 int rv515_suspend(struct radeon_device *rdev)
 int rv515_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r100_cp_disable(rdev);
 	r100_cp_disable(rdev);
 	radeon_wb_disable(rdev);
 	radeon_wb_disable(rdev);
 	rs600_irq_disable(rdev);
 	rs600_irq_disable(rdev);
@@ -612,6 +615,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
 
 
 void rv515_fini(struct radeon_device *rdev)
 void rv515_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r100_cp_fini(rdev);
 	r100_cp_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_wb_fini(rdev);
 	radeon_ib_pool_fini(rdev);
 	radeon_ib_pool_fini(rdev);
@@ -685,6 +689,9 @@ int rv515_init(struct radeon_device *rdev)
 		return r;
 		return r;
 	rv515_set_safe_registers(rdev);
 	rv515_set_safe_registers(rdev);
 
 
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rv515_startup(rdev);
 	r = rv515_startup(rdev);
 	if (r) {
 	if (r) {

+ 0 - 10
drivers/gpu/drm/radeon/rv6xx_dpm.c

@@ -1546,7 +1546,6 @@ int rv6xx_dpm_enable(struct radeon_device *rdev)
 {
 {
 	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
 	struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
-	int ret;
 
 
 	if (r600_dynamicpm_enabled(rdev))
 	if (r600_dynamicpm_enabled(rdev))
 		return -EINVAL;
 		return -EINVAL;
@@ -1594,15 +1593,6 @@ int rv6xx_dpm_enable(struct radeon_device *rdev)
 	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
 	r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true);
 	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, true);
 	r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, true);
 
 
-	if (rdev->irq.installed &&
-	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
-		ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
-		if (ret)
-			return ret;
-		rdev->irq.dpm_thermal = true;
-		radeon_irq_set(rdev);
-	}
-
 	rv6xx_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 	rv6xx_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
 
 
 	r600_start_dpm(rdev);
 	r600_start_dpm(rdev);

+ 44 - 11
drivers/gpu/drm/radeon/rv770.c

@@ -1123,6 +1123,35 @@ void r700_cp_fini(struct radeon_device *rdev)
 	radeon_scratch_free(rdev, ring->rptr_save_reg);
 	radeon_scratch_free(rdev, ring->rptr_save_reg);
 }
 }
 
 
+void rv770_set_clk_bypass_mode(struct radeon_device *rdev)
+{
+	u32 tmp, i;
+
+	if (rdev->flags & RADEON_IS_IGP)
+		return;
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+	tmp &= SCLK_MUX_SEL_MASK;
+	tmp |= SCLK_MUX_SEL(1) | SCLK_MUX_UPDATE;
+	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CG_SPLL_STATUS) & SPLL_CHG_STATUS)
+			break;
+		udelay(1);
+	}
+
+	tmp &= ~SCLK_MUX_UPDATE;
+	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+	tmp = RREG32(MPLL_CNTL_MODE);
+	if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
+		tmp &= ~RV730_MPLL_MCLK_SEL;
+	else
+		tmp &= ~MPLL_MCLK_SEL;
+	WREG32(MPLL_CNTL_MODE, tmp);
+}
+
 /*
 /*
  * Core functions
  * Core functions
  */
  */
@@ -1665,14 +1694,6 @@ static int rv770_startup(struct radeon_device *rdev)
 
 
 	rv770_mc_program(rdev);
 	rv770_mc_program(rdev);
 
 
-	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
-		r = r600_init_microcode(rdev);
-		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
-			return r;
-		}
-	}
-
 	if (rdev->flags & RADEON_IS_AGP) {
 	if (rdev->flags & RADEON_IS_AGP) {
 		rv770_agp_enable(rdev);
 		rv770_agp_enable(rdev);
 	} else {
 	} else {
@@ -1728,14 +1749,12 @@ static int rv770_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     R600_CP_RB_RPTR, R600_CP_RB_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     DMA_RB_RPTR, DMA_RB_WPTR,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -1754,7 +1773,6 @@ static int rv770_startup(struct radeon_device *rdev)
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 	if (ring->ring_size) {
 	if (ring->ring_size) {
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
 		r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-				     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
 				     RADEON_CP_PACKET2);
 				     RADEON_CP_PACKET2);
 		if (!r)
 		if (!r)
 			r = uvd_v1_0_init(rdev);
 			r = uvd_v1_0_init(rdev);
@@ -1792,6 +1810,8 @@ int rv770_resume(struct radeon_device *rdev)
 	/* init golden registers */
 	/* init golden registers */
 	rv770_init_golden_registers(rdev);
 	rv770_init_golden_registers(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = rv770_startup(rdev);
 	r = rv770_startup(rdev);
 	if (r) {
 	if (r) {
@@ -1806,6 +1826,7 @@ int rv770_resume(struct radeon_device *rdev)
 
 
 int rv770_suspend(struct radeon_device *rdev)
 int rv770_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	r600_audio_fini(rdev);
 	r600_audio_fini(rdev);
 	uvd_v1_0_fini(rdev);
 	uvd_v1_0_fini(rdev);
 	radeon_uvd_suspend(rdev);
 	radeon_uvd_suspend(rdev);
@@ -1876,6 +1897,17 @@ int rv770_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
+		r = r600_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
 
 
@@ -1915,6 +1947,7 @@ int rv770_init(struct radeon_device *rdev)
 
 
 void rv770_fini(struct radeon_device *rdev)
 void rv770_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	r700_cp_fini(rdev);
 	r700_cp_fini(rdev);
 	r600_dma_fini(rdev);
 	r600_dma_fini(rdev);
 	r600_irq_fini(rdev);
 	r600_irq_fini(rdev);

+ 11 - 4
drivers/gpu/drm/radeon/rv770_dpm.c

@@ -1863,8 +1863,8 @@ void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
 	}
 	}
 }
 }
 
 
-int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
-					int min_temp, int max_temp)
+static int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
+					       int min_temp, int max_temp)
 {
 {
 	int low_temp = 0 * 1000;
 	int low_temp = 0 * 1000;
 	int high_temp = 255 * 1000;
 	int high_temp = 255 * 1000;
@@ -1966,6 +1966,15 @@ int rv770_dpm_enable(struct radeon_device *rdev)
 	if (pi->mg_clock_gating)
 	if (pi->mg_clock_gating)
 		rv770_mg_clock_gating_enable(rdev, true);
 		rv770_mg_clock_gating_enable(rdev, true);
 
 
+	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	return 0;
+}
+
+int rv770_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 		PPSMC_Result result;
 		PPSMC_Result result;
@@ -1981,8 +1990,6 @@ int rv770_dpm_enable(struct radeon_device *rdev)
 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
 	}
 	}
 
 
-	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 0 - 4
drivers/gpu/drm/radeon/rv770_dpm.h

@@ -283,8 +283,4 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev,
 int rv770_write_smc_soft_register(struct radeon_device *rdev,
 int rv770_write_smc_soft_register(struct radeon_device *rdev,
 				  u16 reg_offset, u32 value);
 				  u16 reg_offset, u32 value);
 
 
-/* thermal */
-int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
-					int min_temp, int max_temp);
-
 #endif
 #endif

+ 7 - 0
drivers/gpu/drm/radeon/rv770d.h

@@ -100,14 +100,21 @@
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define		SCLK_MUX_UPDATE				(1 << 26)
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
 #define		SPLL_DITHEN				(1 << 28)
 #define		SPLL_DITHEN				(1 << 28)
+#define	CG_SPLL_STATUS					0x60c
+#define		SPLL_CHG_STATUS				(1 << 1)
 
 
 #define	SPLL_CNTL_MODE					0x610
 #define	SPLL_CNTL_MODE					0x610
 #define		SPLL_DIV_SYNC				(1 << 5)
 #define		SPLL_DIV_SYNC				(1 << 5)
 
 
+#define MPLL_CNTL_MODE                                  0x61c
+#       define MPLL_MCLK_SEL                            (1 << 11)
+#       define RV730_MPLL_MCLK_SEL                      (1 << 25)
+
 #define	MPLL_AD_FUNC_CNTL				0x624
 #define	MPLL_AD_FUNC_CNTL				0x624
 #define		CLKF(x)					((x) << 0)
 #define		CLKF(x)					((x) << 0)
 #define		CLKF_MASK				(0x7f << 0)
 #define		CLKF_MASK				(0x7f << 0)

+ 131 - 21
drivers/gpu/drm/radeon/si.c

@@ -80,6 +80,8 @@ extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
 extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 extern bool evergreen_is_display_hung(struct radeon_device *rdev);
 static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
 static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
 					 bool enable);
 					 bool enable);
+static void si_init_pg(struct radeon_device *rdev);
+static void si_init_cg(struct radeon_device *rdev);
 static void si_fini_pg(struct radeon_device *rdev);
 static void si_fini_pg(struct radeon_device *rdev);
 static void si_fini_cg(struct radeon_device *rdev);
 static void si_fini_cg(struct radeon_device *rdev);
 static void si_rlc_stop(struct radeon_device *rdev);
 static void si_rlc_stop(struct radeon_device *rdev);
@@ -1460,7 +1462,7 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
 };
 };
 
 
 /* ucode loading */
 /* ucode loading */
-static int si_mc_load_microcode(struct radeon_device *rdev)
+int si_mc_load_microcode(struct radeon_device *rdev)
 {
 {
 	const __be32 *fw_data;
 	const __be32 *fw_data;
 	u32 running, blackout = 0;
 	u32 running, blackout = 0;
@@ -3722,6 +3724,106 @@ static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
 	evergreen_print_gpu_status_regs(rdev);
 	evergreen_print_gpu_status_regs(rdev);
 }
 }
 
 
+static void si_set_clk_bypass_mode(struct radeon_device *rdev)
+{
+	u32 tmp, i;
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL);
+	tmp |= SPLL_BYPASS_EN;
+	WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+	tmp |= SPLL_CTLREQ_CHG;
+	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
+			break;
+		udelay(1);
+	}
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
+	tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
+	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
+
+	tmp = RREG32(MPLL_CNTL_MODE);
+	tmp &= ~MPLL_MCLK_SEL;
+	WREG32(MPLL_CNTL_MODE, tmp);
+}
+
+static void si_spll_powerdown(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(SPLL_CNTL_MODE);
+	tmp |= SPLL_SW_DIR_CONTROL;
+	WREG32(SPLL_CNTL_MODE, tmp);
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL);
+	tmp |= SPLL_RESET;
+	WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+	tmp = RREG32(CG_SPLL_FUNC_CNTL);
+	tmp |= SPLL_SLEEP;
+	WREG32(CG_SPLL_FUNC_CNTL, tmp);
+
+	tmp = RREG32(SPLL_CNTL_MODE);
+	tmp &= ~SPLL_SW_DIR_CONTROL;
+	WREG32(SPLL_CNTL_MODE, tmp);
+}
+
+static void si_gpu_pci_config_reset(struct radeon_device *rdev)
+{
+	struct evergreen_mc_save save;
+	u32 tmp, i;
+
+	dev_info(rdev->dev, "GPU pci config reset\n");
+
+	/* disable dpm? */
+
+	/* disable cg/pg */
+	si_fini_pg(rdev);
+	si_fini_cg(rdev);
+
+	/* Disable CP parsing/prefetching */
+	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
+	/* dma0 */
+	tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
+	tmp &= ~DMA_RB_ENABLE;
+	WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
+	/* dma1 */
+	tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
+	tmp &= ~DMA_RB_ENABLE;
+	WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
+	/* XXX other engines? */
+
+	/* halt the rlc, disable cp internal ints */
+	si_rlc_stop(rdev);
+
+	udelay(50);
+
+	/* disable mem access */
+	evergreen_mc_stop(rdev, &save);
+	if (evergreen_mc_wait_for_idle(rdev)) {
+		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
+	}
+
+	/* set mclk/sclk to bypass */
+	si_set_clk_bypass_mode(rdev);
+	/* powerdown spll */
+	si_spll_powerdown(rdev);
+	/* disable BM */
+	pci_clear_master(rdev->pdev);
+	/* reset */
+	radeon_pci_config_reset(rdev);
+	/* wait for asic to come out of reset */
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
+			break;
+		udelay(1);
+	}
+}
+
 int si_asic_reset(struct radeon_device *rdev)
 int si_asic_reset(struct radeon_device *rdev)
 {
 {
 	u32 reset_mask;
 	u32 reset_mask;
@@ -3731,10 +3833,17 @@ int si_asic_reset(struct radeon_device *rdev)
 	if (reset_mask)
 	if (reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, true);
 		r600_set_bios_scratch_engine_hung(rdev, true);
 
 
+	/* try soft reset */
 	si_gpu_soft_reset(rdev, reset_mask);
 	si_gpu_soft_reset(rdev, reset_mask);
 
 
 	reset_mask = si_gpu_check_soft_reset(rdev);
 	reset_mask = si_gpu_check_soft_reset(rdev);
 
 
+	/* try pci config reset */
+	if (reset_mask && radeon_hard_reset)
+		si_gpu_pci_config_reset(rdev);
+
+	reset_mask = si_gpu_check_soft_reset(rdev);
+
 	if (!reset_mask)
 	if (!reset_mask)
 		r600_set_bios_scratch_engine_hung(rdev, false);
 		r600_set_bios_scratch_engine_hung(rdev, false);
 
 
@@ -5210,8 +5319,8 @@ static void si_enable_hdp_ls(struct radeon_device *rdev,
 		WREG32(HDP_MEM_POWER_LS, data);
 		WREG32(HDP_MEM_POWER_LS, data);
 }
 }
 
 
-void si_update_cg(struct radeon_device *rdev,
-		  u32 block, bool enable)
+static void si_update_cg(struct radeon_device *rdev,
+			 u32 block, bool enable)
 {
 {
 	if (block & RADEON_CG_BLOCK_GFX) {
 	if (block & RADEON_CG_BLOCK_GFX) {
 		si_enable_gui_idle_interrupt(rdev, false);
 		si_enable_gui_idle_interrupt(rdev, false);
@@ -6322,21 +6431,14 @@ static int si_startup(struct radeon_device *rdev)
 
 
 	si_mc_program(rdev);
 	si_mc_program(rdev);
 
 
-	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
-	    !rdev->rlc_fw || !rdev->mc_fw) {
-		r = si_init_microcode(rdev);
+	if (!rdev->pm.dpm_enabled) {
+		r = si_mc_load_microcode(rdev);
 		if (r) {
 		if (r) {
-			DRM_ERROR("Failed to load firmware!\n");
+			DRM_ERROR("Failed to load MC firmware!\n");
 			return r;
 			return r;
 		}
 		}
 	}
 	}
 
 
-	r = si_mc_load_microcode(rdev);
-	if (r) {
-		DRM_ERROR("Failed to load MC firmware!\n");
-		return r;
-	}
-
 	r = si_pcie_gart_enable(rdev);
 	r = si_pcie_gart_enable(rdev);
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -6419,37 +6521,30 @@ static int si_startup(struct radeon_device *rdev)
 
 
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
-			     CP_RB0_RPTR, CP_RB0_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
-			     CP_RB1_RPTR, CP_RB1_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
-			     CP_RB2_RPTR, CP_RB2_WPTR,
 			     RADEON_CP_PACKET2);
 			     RADEON_CP_PACKET2);
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
-			     DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
-			     DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
-			     DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
-			     DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
 	if (r)
 	if (r)
 		return r;
 		return r;
@@ -6469,7 +6564,6 @@ static int si_startup(struct radeon_device *rdev)
 		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
 		if (ring->ring_size) {
 		if (ring->ring_size) {
 			r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
 			r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
-					     UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
 					     RADEON_CP_PACKET2);
 					     RADEON_CP_PACKET2);
 			if (!r)
 			if (!r)
 				r = uvd_v1_0_init(rdev);
 				r = uvd_v1_0_init(rdev);
@@ -6511,6 +6605,8 @@ int si_resume(struct radeon_device *rdev)
 	/* init golden registers */
 	/* init golden registers */
 	si_init_golden_registers(rdev);
 	si_init_golden_registers(rdev);
 
 
+	radeon_pm_resume(rdev);
+
 	rdev->accel_working = true;
 	rdev->accel_working = true;
 	r = si_startup(rdev);
 	r = si_startup(rdev);
 	if (r) {
 	if (r) {
@@ -6525,6 +6621,7 @@ int si_resume(struct radeon_device *rdev)
 
 
 int si_suspend(struct radeon_device *rdev)
 int si_suspend(struct radeon_device *rdev)
 {
 {
+	radeon_pm_suspend(rdev);
 	dce6_audio_fini(rdev);
 	dce6_audio_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	radeon_vm_manager_fini(rdev);
 	si_cp_enable(rdev, false);
 	si_cp_enable(rdev, false);
@@ -6598,6 +6695,18 @@ int si_init(struct radeon_device *rdev)
 	if (r)
 	if (r)
 		return r;
 		return r;
 
 
+	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
+	    !rdev->rlc_fw || !rdev->mc_fw) {
+		r = si_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
+	/* Initialize power management */
+	radeon_pm_init(rdev);
+
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
 	ring->ring_obj = NULL;
 	ring->ring_obj = NULL;
 	r600_ring_init(rdev, ring, 1024 * 1024);
 	r600_ring_init(rdev, ring, 1024 * 1024);
@@ -6664,6 +6773,7 @@ int si_init(struct radeon_device *rdev)
 
 
 void si_fini(struct radeon_device *rdev)
 void si_fini(struct radeon_device *rdev)
 {
 {
+	radeon_pm_fini(rdev);
 	si_cp_fini(rdev);
 	si_cp_fini(rdev);
 	cayman_dma_fini(rdev);
 	cayman_dma_fini(rdev);
 	si_fini_pg(rdev);
 	si_fini_pg(rdev);

+ 18 - 42
drivers/gpu/drm/radeon/si_dpm.c

@@ -1738,6 +1738,8 @@ struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev);
 struct ni_power_info *ni_get_pi(struct radeon_device *rdev);
 struct ni_ps *ni_get_ps(struct radeon_ps *rps);
 struct ni_ps *ni_get_ps(struct radeon_ps *rps);
 
 
+extern int si_mc_load_microcode(struct radeon_device *rdev);
+
 static int si_populate_voltage_value(struct radeon_device *rdev,
 static int si_populate_voltage_value(struct radeon_device *rdev,
 				     const struct atom_voltage_table *table,
 				     const struct atom_voltage_table *table,
 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
@@ -1753,9 +1755,6 @@ static int si_calculate_sclk_params(struct radeon_device *rdev,
 				    u32 engine_clock,
 				    u32 engine_clock,
 				    SISLANDS_SMC_SCLK_VALUE *sclk);
 				    SISLANDS_SMC_SCLK_VALUE *sclk);
 
 
-extern void si_update_cg(struct radeon_device *rdev,
-			 u32 block, bool enable);
-
 static struct si_power_info *si_get_pi(struct radeon_device *rdev)
 static struct si_power_info *si_get_pi(struct radeon_device *rdev)
 {
 {
         struct si_power_info *pi = rdev->pm.dpm.priv;
         struct si_power_info *pi = rdev->pm.dpm.priv;
@@ -5754,6 +5753,11 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,
 
 
 void si_dpm_setup_asic(struct radeon_device *rdev)
 void si_dpm_setup_asic(struct radeon_device *rdev)
 {
 {
+	int r;
+
+	r = si_mc_load_microcode(rdev);
+	if (r)
+		DRM_ERROR("Failed to load MC firmware!\n");
 	rv770_get_memory_type(rdev);
 	rv770_get_memory_type(rdev);
 	si_read_clock_registers(rdev);
 	si_read_clock_registers(rdev);
 	si_enable_acpi_power_management(rdev);
 	si_enable_acpi_power_management(rdev);
@@ -5791,13 +5795,6 @@ int si_dpm_enable(struct radeon_device *rdev)
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	int ret;
 	int ret;
 
 
-	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			    RADEON_CG_BLOCK_MC |
-			    RADEON_CG_BLOCK_SDMA |
-			    RADEON_CG_BLOCK_BIF |
-			    RADEON_CG_BLOCK_UVD |
-			    RADEON_CG_BLOCK_HDP), false);
-
 	if (si_is_smc_running(rdev))
 	if (si_is_smc_running(rdev))
 		return -EINVAL;
 		return -EINVAL;
 	if (pi->voltage_control)
 	if (pi->voltage_control)
@@ -5900,6 +5897,17 @@ int si_dpm_enable(struct radeon_device *rdev)
 	si_enable_sclk_control(rdev, true);
 	si_enable_sclk_control(rdev, true);
 	si_start_dpm(rdev);
 	si_start_dpm(rdev);
 
 
+	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+	ni_update_current_ps(rdev, boot_ps);
+
+	return 0;
+}
+
+int si_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 		PPSMC_Result result;
 		PPSMC_Result result;
@@ -5915,17 +5923,6 @@ int si_dpm_enable(struct radeon_device *rdev)
 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
 	}
 	}
 
 
-	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
-
-	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			    RADEON_CG_BLOCK_MC |
-			    RADEON_CG_BLOCK_SDMA |
-			    RADEON_CG_BLOCK_BIF |
-			    RADEON_CG_BLOCK_UVD |
-			    RADEON_CG_BLOCK_HDP), true);
-
-	ni_update_current_ps(rdev, boot_ps);
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -5934,13 +5931,6 @@ void si_dpm_disable(struct radeon_device *rdev)
 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
 
 
-	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			    RADEON_CG_BLOCK_MC |
-			    RADEON_CG_BLOCK_SDMA |
-			    RADEON_CG_BLOCK_BIF |
-			    RADEON_CG_BLOCK_UVD |
-			    RADEON_CG_BLOCK_HDP), false);
-
 	if (!si_is_smc_running(rdev))
 	if (!si_is_smc_running(rdev))
 		return;
 		return;
 	si_disable_ulv(rdev);
 	si_disable_ulv(rdev);
@@ -6005,13 +5995,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev)
 	struct radeon_ps *old_ps = &eg_pi->current_rps;
 	struct radeon_ps *old_ps = &eg_pi->current_rps;
 	int ret;
 	int ret;
 
 
-	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			    RADEON_CG_BLOCK_MC |
-			    RADEON_CG_BLOCK_SDMA |
-			    RADEON_CG_BLOCK_BIF |
-			    RADEON_CG_BLOCK_UVD |
-			    RADEON_CG_BLOCK_HDP), false);
-
 	ret = si_disable_ulv(rdev);
 	ret = si_disable_ulv(rdev);
 	if (ret) {
 	if (ret) {
 		DRM_ERROR("si_disable_ulv failed\n");
 		DRM_ERROR("si_disable_ulv failed\n");
@@ -6104,13 +6087,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
-			    RADEON_CG_BLOCK_MC |
-			    RADEON_CG_BLOCK_SDMA |
-			    RADEON_CG_BLOCK_BIF |
-			    RADEON_CG_BLOCK_UVD |
-			    RADEON_CG_BLOCK_HDP), true);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
drivers/gpu/drm/radeon/si_smc.c

@@ -28,6 +28,7 @@
 #include "sid.h"
 #include "sid.h"
 #include "ppsmc.h"
 #include "ppsmc.h"
 #include "radeon_ucode.h"
 #include "radeon_ucode.h"
+#include "sislands_smc.h"
 
 
 static int si_set_smc_sram_address(struct radeon_device *rdev,
 static int si_set_smc_sram_address(struct radeon_device *rdev,
 				   u32 smc_address, u32 limit)
 				   u32 smc_address, u32 limit)

+ 7 - 0
drivers/gpu/drm/radeon/sid.h

@@ -94,6 +94,8 @@
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define	CG_SPLL_FUNC_CNTL_2				0x604
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL(x)				((x) << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
 #define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
+#define		SPLL_CTLREQ_CHG				(1 << 23)
+#define		SCLK_MUX_UPDATE				(1 << 26)
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define	CG_SPLL_FUNC_CNTL_3				0x608
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV(x)				((x) << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
 #define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
@@ -101,7 +103,10 @@
 #define		SPLL_DITHEN				(1 << 28)
 #define		SPLL_DITHEN				(1 << 28)
 #define	CG_SPLL_FUNC_CNTL_4				0x60c
 #define	CG_SPLL_FUNC_CNTL_4				0x60c
 
 
+#define	SPLL_STATUS					0x614
+#define		SPLL_CHG_STATUS				(1 << 1)
 #define	SPLL_CNTL_MODE					0x618
 #define	SPLL_CNTL_MODE					0x618
+#define		SPLL_SW_DIR_CONTROL			(1 << 0)
 #	define SPLL_REFCLK_SEL(x)			((x) << 8)
 #	define SPLL_REFCLK_SEL(x)			((x) << 8)
 #	define SPLL_REFCLK_SEL_MASK			0xFF00
 #	define SPLL_REFCLK_SEL_MASK			0xFF00
 
 
@@ -559,6 +564,8 @@
 #       define MRDCK0_BYPASS                            (1 << 24)
 #       define MRDCK0_BYPASS                            (1 << 24)
 #       define MRDCK1_BYPASS                            (1 << 25)
 #       define MRDCK1_BYPASS                            (1 << 25)
 
 
+#define	MPLL_CNTL_MODE					0x2bb0
+#       define MPLL_MCLK_SEL                            (1 << 11)
 #define	MPLL_FUNC_CNTL					0x2bb4
 #define	MPLL_FUNC_CNTL					0x2bb4
 #define		BWCTRL(x)				((x) << 20)
 #define		BWCTRL(x)				((x) << 20)
 #define		BWCTRL_MASK				(0xff << 20)
 #define		BWCTRL_MASK				(0xff << 20)

+ 0 - 2
drivers/gpu/drm/radeon/sislands_smc.h

@@ -374,8 +374,6 @@ typedef struct Smc_SIslands_DTE_Configuration Smc_SIslands_DTE_Configuration;
 
 
 #pragma pack(pop)
 #pragma pack(pop)
 
 
-int si_set_smc_sram_address(struct radeon_device *rdev,
-			    u32 smc_address, u32 limit);
 int si_copy_bytes_to_smc(struct radeon_device *rdev,
 int si_copy_bytes_to_smc(struct radeon_device *rdev,
 			 u32 smc_start_address,
 			 u32 smc_start_address,
 			 const u8 *src, u32 byte_count, u32 limit);
 			 const u8 *src, u32 byte_count, u32 limit);

+ 14 - 7
drivers/gpu/drm/radeon/sumo_dpm.c

@@ -71,7 +71,7 @@ static const u32 sumo_dtc[SUMO_PM_NUMBER_OF_TC] =
 	SUMO_DTC_DFLT_14,
 	SUMO_DTC_DFLT_14,
 };
 };
 
 
-struct sumo_ps *sumo_get_ps(struct radeon_ps *rps)
+static struct sumo_ps *sumo_get_ps(struct radeon_ps *rps)
 {
 {
 	struct sumo_ps *ps = rps->ps_priv;
 	struct sumo_ps *ps = rps->ps_priv;
 
 
@@ -1202,14 +1202,10 @@ static void sumo_update_requested_ps(struct radeon_device *rdev,
 int sumo_dpm_enable(struct radeon_device *rdev)
 int sumo_dpm_enable(struct radeon_device *rdev)
 {
 {
 	struct sumo_power_info *pi = sumo_get_pi(rdev);
 	struct sumo_power_info *pi = sumo_get_pi(rdev);
-	int ret;
 
 
 	if (sumo_dpm_enabled(rdev))
 	if (sumo_dpm_enabled(rdev))
 		return -EINVAL;
 		return -EINVAL;
 
 
-	ret = sumo_enable_clock_power_gating(rdev);
-	if (ret)
-		return ret;
 	sumo_program_bootup_state(rdev);
 	sumo_program_bootup_state(rdev);
 	sumo_init_bsp(rdev);
 	sumo_init_bsp(rdev);
 	sumo_reset_am(rdev);
 	sumo_reset_am(rdev);
@@ -1233,6 +1229,19 @@ int sumo_dpm_enable(struct radeon_device *rdev)
 	if (pi->enable_boost)
 	if (pi->enable_boost)
 		sumo_enable_boost_timer(rdev);
 		sumo_enable_boost_timer(rdev);
 
 
+	sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return 0;
+}
+
+int sumo_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
+	ret = sumo_enable_clock_power_gating(rdev);
+	if (ret)
+		return ret;
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 		ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
 		ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
@@ -1242,8 +1251,6 @@ int sumo_dpm_enable(struct radeon_device *rdev)
 		radeon_irq_set(rdev);
 		radeon_irq_set(rdev);
 	}
 	}
 
 
-	sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 0 - 1
drivers/gpu/drm/radeon/sumo_smc.c

@@ -31,7 +31,6 @@
 #define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY  27
 #define SUMO_SMU_SERVICE_ROUTINE_ALTVDDNB_NOTIFY  27
 #define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20  20
 #define SUMO_SMU_SERVICE_ROUTINE_GFX_SRV_ID_20  20
 
 
-struct sumo_ps *sumo_get_ps(struct radeon_ps *rps);
 struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev);
 struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev);
 
 
 static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id)
 static void sumo_send_msg_to_smu(struct radeon_device *rdev, u32 id)

+ 15 - 6
drivers/gpu/drm/radeon/trinity_dpm.c

@@ -342,14 +342,14 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
 					     struct radeon_ps *new_rps,
 					     struct radeon_ps *new_rps,
 					     struct radeon_ps *old_rps);
 					     struct radeon_ps *old_rps);
 
 
-struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
+static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
 {
 {
 	struct trinity_ps *ps = rps->ps_priv;
 	struct trinity_ps *ps = rps->ps_priv;
 
 
 	return ps;
 	return ps;
 }
 }
 
 
-struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
+static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
 {
 {
 	struct trinity_power_info *pi = rdev->pm.dpm.priv;
 	struct trinity_power_info *pi = rdev->pm.dpm.priv;
 
 
@@ -1082,7 +1082,6 @@ void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
 int trinity_dpm_enable(struct radeon_device *rdev)
 int trinity_dpm_enable(struct radeon_device *rdev)
 {
 {
 	struct trinity_power_info *pi = trinity_get_pi(rdev);
 	struct trinity_power_info *pi = trinity_get_pi(rdev);
-	int ret;
 
 
 	trinity_acquire_mutex(rdev);
 	trinity_acquire_mutex(rdev);
 
 
@@ -1091,7 +1090,6 @@ int trinity_dpm_enable(struct radeon_device *rdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	trinity_enable_clock_power_gating(rdev);
 	trinity_program_bootup_state(rdev);
 	trinity_program_bootup_state(rdev);
 	sumo_program_vc(rdev, 0x00C00033);
 	sumo_program_vc(rdev, 0x00C00033);
 	trinity_start_am(rdev);
 	trinity_start_am(rdev);
@@ -1105,6 +1103,18 @@ int trinity_dpm_enable(struct radeon_device *rdev)
 	trinity_dpm_bapm_enable(rdev, false);
 	trinity_dpm_bapm_enable(rdev, false);
 	trinity_release_mutex(rdev);
 	trinity_release_mutex(rdev);
 
 
+	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+	return 0;
+}
+
+int trinity_dpm_late_enable(struct radeon_device *rdev)
+{
+	int ret;
+
+	trinity_acquire_mutex(rdev);
+	trinity_enable_clock_power_gating(rdev);
+
 	if (rdev->irq.installed &&
 	if (rdev->irq.installed &&
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
 		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
@@ -1115,8 +1125,7 @@ int trinity_dpm_enable(struct radeon_device *rdev)
 		rdev->irq.dpm_thermal = true;
 		rdev->irq.dpm_thermal = true;
 		radeon_irq_set(rdev);
 		radeon_irq_set(rdev);
 	}
 	}
-
-	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+	trinity_release_mutex(rdev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 0 - 3
drivers/gpu/drm/radeon/trinity_smc.c

@@ -27,9 +27,6 @@
 #include "trinity_dpm.h"
 #include "trinity_dpm.h"
 #include "ppsmc.h"
 #include "ppsmc.h"
 
 
-struct trinity_ps *trinity_get_ps(struct radeon_ps *rps);
-struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev);
-
 static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
 static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
 {
 {
 	int i;
 	int i;