[PATCH 074/165] drm/radeon/kms: add common r600 dpm functions

alexdeucher at gmail.com alexdeucher at gmail.com
Wed Jun 26 06:22:34 PDT 2013


From: Alex Deucher <alexander.deucher at amd.com>

These are shared by rs780/rs880, rv6xx, and newer chips.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/Makefile   |    3 +-
 drivers/gpu/drm/radeon/r600_dpm.c |  678 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/r600_dpm.h |  210 ++++++++++++
 drivers/gpu/drm/radeon/r600d.h    |  213 ++++++++++++
 drivers/gpu/drm/radeon/radeon.h   |   13 +
 5 files changed, 1116 insertions(+), 1 deletions(-)
 create mode 100644 drivers/gpu/drm/radeon/r600_dpm.c
 create mode 100644 drivers/gpu/drm/radeon/r600_dpm.h

diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 292fd25..a131a13 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -76,7 +76,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
 	evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
 	evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
 	atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
-	si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o
+	si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
+	r600_dpm.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
new file mode 100644
index 0000000..91bc5ab
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_dpm.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include "drmP.h"
+#include "radeon.h"
+#include "r600d.h"
+#include "r600_dpm.h"
+#include "atom.h"
+
+const u32 r600_utc[R600_PM_NUMBER_OF_TC] =
+{
+	R600_UTC_DFLT_00,
+	R600_UTC_DFLT_01,
+	R600_UTC_DFLT_02,
+	R600_UTC_DFLT_03,
+	R600_UTC_DFLT_04,
+	R600_UTC_DFLT_05,
+	R600_UTC_DFLT_06,
+	R600_UTC_DFLT_07,
+	R600_UTC_DFLT_08,
+	R600_UTC_DFLT_09,
+	R600_UTC_DFLT_10,
+	R600_UTC_DFLT_11,
+	R600_UTC_DFLT_12,
+	R600_UTC_DFLT_13,
+	R600_UTC_DFLT_14,
+};
+
+const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =
+{
+	R600_DTC_DFLT_00,
+	R600_DTC_DFLT_01,
+	R600_DTC_DFLT_02,
+	R600_DTC_DFLT_03,
+	R600_DTC_DFLT_04,
+	R600_DTC_DFLT_05,
+	R600_DTC_DFLT_06,
+	R600_DTC_DFLT_07,
+	R600_DTC_DFLT_08,
+	R600_DTC_DFLT_09,
+	R600_DTC_DFLT_10,
+	R600_DTC_DFLT_11,
+	R600_DTC_DFLT_12,
+	R600_DTC_DFLT_13,
+	R600_DTC_DFLT_14,
+};
+
+void r600_dpm_print_class_info(u32 class, u32 class2)
+{
+	printk("\tui class: ");
+	switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
+	case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
+	default:
+		printk("none\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
+		printk("battery\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
+		printk("balanced\n");
+		break;
+	case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
+		printk("performance\n");
+		break;
+	}
+	printk("\tinternal class: ");
+	if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
+	    (class2 == 0))
+		printk("none");
+	else {
+		if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
+			printk("boot ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
+			printk("thermal ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
+			printk("limited_pwr ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_REST)
+			printk("rest ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
+			printk("forced ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
+			printk("3d_perf ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
+			printk("ovrdrv ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+			printk("uvd ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
+			printk("3d_low ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
+			printk("acpi ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+			printk("uvd_hd2 ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+			printk("uvd_hd ");
+		if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+			printk("uvd_sd ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
+			printk("limited_pwr2 ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
+			printk("ulv ");
+		if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+			printk("uvd_mvc ");
+	}
+	printk("\n");
+}
+
+void r600_dpm_print_cap_info(u32 caps)
+{
+	printk("\tcaps: ");
+	if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
+		printk("single_disp ");
+	if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
+		printk("video ");
+	if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
+		printk("no_dc ");
+	printk("\n");
+}
+
+void r600_dpm_print_ps_status(struct radeon_device *rdev,
+			      struct radeon_ps *rps)
+{
+	printk("\tstatus: ");
+	if (rps == rdev->pm.dpm.current_ps)
+		printk("c ");
+	if (rps == rdev->pm.dpm.requested_ps)
+		printk("r ");
+	if (rps == rdev->pm.dpm.boot_ps)
+		printk("b ");
+	printk("\n");
+}
+
+void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
+			    u32 *p, u32 *u)
+{
+	u32 b_c = 0;
+	u32 i_c;
+	u32 tmp;
+
+	i_c = (i * r_c) / 100;
+	tmp = i_c >> p_b;
+
+	while (tmp) {
+		b_c++;
+		tmp >>= 1;
+	}
+
+	*u = (b_c + 1) / 2;
+	*p = i_c / (1 << (2 * (*u)));
+}
+
+int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
+{
+	u32 k, a, ah, al;
+	u32 t1;
+
+	if ((fl == 0) || (fh == 0) || (fl > fh))
+		return -EINVAL;
+
+	k = (100 * fh) / fl;
+	t1 = (t * (k - 100));
+	a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
+	a = (a + 5) / 10;
+	ah = ((a * t) + 5000) / 10000;
+	al = a - ah;
+
+	*th = t - ah;
+	*tl = t + al;
+
+	return 0;
+}
+
+void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
+{
+	int i;
+
+	if (enable) {
+		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
+	} else {
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
+
+		WREG32(CG_RLC_REQ_AND_RSP, 0x2);
+
+		for (i = 0; i < rdev->usec_timeout; i++) {
+			if (((RREG32(CG_RLC_REQ_AND_RSP) & CG_RLC_RSP_TYPE_MASK) >> CG_RLC_RSP_TYPE_SHIFT) == 1)
+				break;
+			udelay(1);
+		}
+
+		WREG32(CG_RLC_REQ_AND_RSP, 0x0);
+
+		WREG32(GRBM_PWR_CNTL, 0x1);
+		RREG32(GRBM_PWR_CNTL);
+	}
+}
+
+void r600_dynamicpm_enable(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
+}
+
+void r600_enable_thermal_protection(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
+	else
+		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
+}
+
+void r600_enable_acpi_pm(struct radeon_device *rdev)
+{
+	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
+}
+
+void r600_enable_dynamic_pcie_gen2(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+	else
+		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+bool r600_dynamicpm_enabled(struct radeon_device *rdev)
+{
+	if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
+		return true;
+	else
+		return false;
+}
+
+void r600_enable_sclk_control(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(GENERAL_PWRMGT, 0, ~SCLK_PWRMGT_OFF);
+	else
+		WREG32_P(GENERAL_PWRMGT, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
+}
+
+void r600_enable_mclk_control(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
+	else
+		WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
+}
+
+void r600_enable_spll_bypass(struct radeon_device *rdev, bool enable)
+{
+	if (enable)
+		WREG32_P(CG_SPLL_FUNC_CNTL, SPLL_BYPASS_EN, ~SPLL_BYPASS_EN);
+	else
+		WREG32_P(CG_SPLL_FUNC_CNTL, 0, ~SPLL_BYPASS_EN);
+}
+
+void r600_wait_for_spll_change(struct radeon_device *rdev)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (RREG32(CG_SPLL_FUNC_CNTL) & SPLL_CHG_STATUS)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_set_bsp(struct radeon_device *rdev, u32 u, u32 p)
+{
+	WREG32(CG_BSP, BSP(p) | BSU(u));
+}
+
+void r600_set_at(struct radeon_device *rdev,
+		 u32 l_to_m, u32 m_to_h,
+		 u32 h_to_m, u32 m_to_l)
+{
+	WREG32(CG_RT, FLS(l_to_m) | FMS(m_to_h));
+	WREG32(CG_LT, FHS(h_to_m) | FMS(m_to_l));
+}
+
+void r600_set_tc(struct radeon_device *rdev,
+		 u32 index, u32 u_t, u32 d_t)
+{
+	WREG32(CG_FFCT_0 + (index * 4), UTC_0(u_t) | DTC_0(d_t));
+}
+
+void r600_select_td(struct radeon_device *rdev,
+		    enum r600_td td)
+{
+	if (td == R600_TD_AUTO)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
+	else
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
+	if (td == R600_TD_UP)
+		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
+	if (td == R600_TD_DOWN)
+		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
+}
+
+void r600_set_vrc(struct radeon_device *rdev, u32 vrv)
+{
+	WREG32(CG_FTV, vrv);
+}
+
+void r600_set_tpu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_TPC, TPU(u), ~TPU_MASK);
+}
+
+void r600_set_tpc(struct radeon_device *rdev, u32 c)
+{
+	WREG32_P(CG_TPC, TPCC(c), ~TPCC_MASK);
+}
+
+void r600_set_sstu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_SSP, CG_SSTU(u), ~CG_SSTU_MASK);
+}
+
+void r600_set_sst(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_SSP, CG_SST(t), ~CG_SST_MASK);
+}
+
+void r600_set_git(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_GIT, CG_GICST(t), ~CG_GICST_MASK);
+}
+
+void r600_set_fctu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_FC_T, FC_TU(u), ~FC_TU_MASK);
+}
+
+void r600_set_fct(struct radeon_device *rdev, u32 t)
+{
+	WREG32_P(CG_FC_T, FC_T(t), ~FC_T_MASK);
+}
+
+void r600_set_ctxcgtt3d_rphc(struct radeon_device *rdev, u32 p)
+{
+	WREG32_P(CG_CTX_CGTT3D_R, PHC(p), ~PHC_MASK);
+}
+
+void r600_set_ctxcgtt3d_rsdc(struct radeon_device *rdev, u32 s)
+{
+	WREG32_P(CG_CTX_CGTT3D_R, SDC(s), ~SDC_MASK);
+}
+
+void r600_set_vddc3d_oorsu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(CG_VDDC3D_OOR, SU(u), ~SU_MASK);
+}
+
+void r600_set_vddc3d_oorphc(struct radeon_device *rdev, u32 p)
+{
+	WREG32_P(CG_VDDC3D_OOR, PHC(p), ~PHC_MASK);
+}
+
+void r600_set_vddc3d_oorsdc(struct radeon_device *rdev, u32 s)
+{
+	WREG32_P(CG_VDDC3D_OOR, SDC(s), ~SDC_MASK);
+}
+
+void r600_set_mpll_lock_time(struct radeon_device *rdev, u32 lock_time)
+{
+	WREG32_P(MPLL_TIME, MPLL_LOCK_TIME(lock_time), ~MPLL_LOCK_TIME_MASK);
+}
+
+void r600_set_mpll_reset_time(struct radeon_device *rdev, u32 reset_time)
+{
+	WREG32_P(MPLL_TIME, MPLL_RESET_TIME(reset_time), ~MPLL_RESET_TIME_MASK);
+}
+
+void r600_engine_clock_entry_enable(struct radeon_device *rdev,
+				    u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_SPLL_ENTRY_VALID, ~STEP_0_SPLL_ENTRY_VALID);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_SPLL_ENTRY_VALID);
+}
+
+void r600_engine_clock_entry_enable_pulse_skipping(struct radeon_device *rdev,
+						   u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_SPLL_STEP_ENABLE, ~STEP_0_SPLL_STEP_ENABLE);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_SPLL_STEP_ENABLE);
+}
+
+void r600_engine_clock_entry_enable_post_divider(struct radeon_device *rdev,
+						 u32 index, bool enable)
+{
+	if (enable)
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 STEP_0_POST_DIV_EN, ~STEP_0_POST_DIV_EN);
+	else
+		WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
+			 0, ~STEP_0_POST_DIV_EN);
+}
+
+void r600_engine_clock_entry_set_post_divider(struct radeon_device *rdev,
+					      u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_POST_DIV(divider), ~STEP_0_SPLL_POST_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_reference_divider(struct radeon_device *rdev,
+						   u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_REF_DIV(divider), ~STEP_0_SPLL_REF_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_feedback_divider(struct radeon_device *rdev,
+						  u32 index, u32 divider)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_FB_DIV(divider), ~STEP_0_SPLL_FB_DIV_MASK);
+}
+
+void r600_engine_clock_entry_set_step_time(struct radeon_device *rdev,
+					   u32 index, u32 step_time)
+{
+	WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
+		 STEP_0_SPLL_STEP_TIME(step_time), ~STEP_0_SPLL_STEP_TIME_MASK);
+}
+
+void r600_vid_rt_set_ssu(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(VID_RT, SSTU(u), ~SSTU_MASK);
+}
+
+void r600_vid_rt_set_vru(struct radeon_device *rdev, u32 u)
+{
+	WREG32_P(VID_RT, VID_CRTU(u), ~VID_CRTU_MASK);
+}
+
+void r600_vid_rt_set_vrt(struct radeon_device *rdev, u32 rt)
+{
+	WREG32_P(VID_RT, VID_CRT(rt), ~VID_CRT_MASK);
+}
+
+void r600_voltage_control_enable_pins(struct radeon_device *rdev,
+				      u64 mask)
+{
+	WREG32(LOWER_GPIO_ENABLE, mask & 0xffffffff);
+	WREG32(UPPER_GPIO_ENABLE, upper_32_bits(mask));
+}
+
+
+void r600_voltage_control_program_voltages(struct radeon_device *rdev,
+					   enum r600_power_level index, u64 pins)
+{
+	u32 tmp, mask;
+	u32 ix = 3 - (3 & index);
+
+	WREG32(CTXSW_VID_LOWER_GPIO_CNTL + (ix * 4), pins & 0xffffffff);
+
+	mask = 7 << (3 * ix);
+	tmp = RREG32(VID_UPPER_GPIO_CNTL);
+	tmp = (tmp & ~mask) | ((pins >> (32 - (3 * ix))) & mask);
+	WREG32(VID_UPPER_GPIO_CNTL, tmp);
+}
+
+void r600_voltage_control_deactivate_static_control(struct radeon_device *rdev,
+						    u64 mask)
+{
+	u32 gpio;
+
+	gpio = RREG32(GPIOPAD_MASK);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_MASK, gpio);
+
+	gpio = RREG32(GPIOPAD_EN);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_EN, gpio);
+
+	gpio = RREG32(GPIOPAD_A);
+	gpio &= ~mask;
+	WREG32(GPIOPAD_A, gpio);
+}
+
+void r600_power_level_enable(struct radeon_device *rdev,
+			     enum r600_power_level index, bool enable)
+{
+	u32 ix = 3 - (3 & index);
+
+	if (enable)
+		WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), CTXSW_FREQ_STATE_ENABLE,
+			 ~CTXSW_FREQ_STATE_ENABLE);
+	else
+		WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), 0,
+			 ~CTXSW_FREQ_STATE_ENABLE);
+}
+
+void r600_power_level_set_voltage_index(struct radeon_device *rdev,
+					enum r600_power_level index, u32 voltage_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_VIDS_CFG_INDEX(voltage_index), ~CTXSW_FREQ_VIDS_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_mem_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 mem_clock_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_MCLK_CFG_INDEX(mem_clock_index), ~CTXSW_FREQ_MCLK_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_eng_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 eng_clock_index)
+{
+	u32 ix = 3 - (3 & index);
+
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
+		 CTXSW_FREQ_SCLK_CFG_INDEX(eng_clock_index), ~CTXSW_FREQ_SCLK_CFG_INDEX_MASK);
+}
+
+void r600_power_level_set_watermark_id(struct radeon_device *rdev,
+				       enum r600_power_level index,
+				       enum r600_display_watermark watermark_id)
+{
+	u32 ix = 3 - (3 & index);
+	u32 tmp = 0;
+
+	if (watermark_id == R600_DISPLAY_WATERMARK_HIGH)
+		tmp = CTXSW_FREQ_DISPLAY_WATERMARK;
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_DISPLAY_WATERMARK);
+}
+
+void r600_power_level_set_pcie_gen2(struct radeon_device *rdev,
+				    enum r600_power_level index, bool compatible)
+{
+	u32 ix = 3 - (3 & index);
+	u32 tmp = 0;
+
+	if (compatible)
+		tmp = CTXSW_FREQ_GEN2PCIE_VOLT;
+	WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_GEN2PCIE_VOLT);
+}
+
+enum r600_power_level r600_power_level_get_current_index(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK;
+	tmp >>= CURRENT_PROFILE_INDEX_SHIFT;
+	return tmp;
+}
+
+enum r600_power_level r600_power_level_get_target_index(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_PROFILE_INDEX_MASK;
+	tmp >>= TARGET_PROFILE_INDEX_SHIFT;
+	return tmp;
+}
+
+void r600_power_level_set_enter_index(struct radeon_device *rdev,
+				      enum r600_power_level index)
+{
+	WREG32_P(TARGET_AND_CURRENT_PROFILE_INDEX, DYN_PWR_ENTER_INDEX(index),
+		 ~DYN_PWR_ENTER_INDEX_MASK);
+}
+
+void r600_wait_for_power_level_unequal(struct radeon_device *rdev,
+				       enum r600_power_level index)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_target_index(rdev) != index)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_current_index(rdev) != index)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_wait_for_power_level(struct radeon_device *rdev,
+			       enum r600_power_level index)
+{
+	int i;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_target_index(rdev) == index)
+			break;
+		udelay(1);
+	}
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		if (r600_power_level_get_current_index(rdev) == index)
+			break;
+		udelay(1);
+	}
+}
+
+void r600_start_dpm(struct radeon_device *rdev)
+{
+	r600_enable_sclk_control(rdev, false);
+	r600_enable_mclk_control(rdev, false);
+
+	r600_dynamicpm_enable(rdev, true);
+
+	radeon_wait_for_vblank(rdev, 0);
+	radeon_wait_for_vblank(rdev, 1);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_spll_bypass(rdev, true);
+	r600_wait_for_spll_change(rdev);
+	r600_enable_spll_bypass(rdev, false);
+	r600_wait_for_spll_change(rdev);
+
+	r600_enable_sclk_control(rdev, true);
+	r600_enable_mclk_control(rdev, true);
+}
+
+void r600_stop_dpm(struct radeon_device *rdev)
+{
+	r600_dynamicpm_enable(rdev, false);
+}
+
+bool r600_is_uvd_state(u32 class, u32 class2)
+{
+	if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
+		return true;
+	if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
+		return true;
+	if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
+		return true;
+	return false;
+}
diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h
new file mode 100644
index 0000000..240a7ed
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_dpm.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef __R600_DPM_H__
+#define __R600_DPM_H__
+
+#define R600_ASI_DFLT                                10000
+#define R600_BSP_DFLT                                0x41EB
+#define R600_BSU_DFLT                                0x2
+#define R600_AH_DFLT                                 5
+#define R600_RLP_DFLT                                25
+#define R600_RMP_DFLT                                65
+#define R600_LHP_DFLT                                40
+#define R600_LMP_DFLT                                15
+#define R600_TD_DFLT                                 0
+#define R600_UTC_DFLT_00                             0x24
+#define R600_UTC_DFLT_01                             0x22
+#define R600_UTC_DFLT_02                             0x22
+#define R600_UTC_DFLT_03                             0x22
+#define R600_UTC_DFLT_04                             0x22
+#define R600_UTC_DFLT_05                             0x22
+#define R600_UTC_DFLT_06                             0x22
+#define R600_UTC_DFLT_07                             0x22
+#define R600_UTC_DFLT_08                             0x22
+#define R600_UTC_DFLT_09                             0x22
+#define R600_UTC_DFLT_10                             0x22
+#define R600_UTC_DFLT_11                             0x22
+#define R600_UTC_DFLT_12                             0x22
+#define R600_UTC_DFLT_13                             0x22
+#define R600_UTC_DFLT_14                             0x22
+#define R600_DTC_DFLT_00                             0x24
+#define R600_DTC_DFLT_01                             0x22
+#define R600_DTC_DFLT_02                             0x22
+#define R600_DTC_DFLT_03                             0x22
+#define R600_DTC_DFLT_04                             0x22
+#define R600_DTC_DFLT_05                             0x22
+#define R600_DTC_DFLT_06                             0x22
+#define R600_DTC_DFLT_07                             0x22
+#define R600_DTC_DFLT_08                             0x22
+#define R600_DTC_DFLT_09                             0x22
+#define R600_DTC_DFLT_10                             0x22
+#define R600_DTC_DFLT_11                             0x22
+#define R600_DTC_DFLT_12                             0x22
+#define R600_DTC_DFLT_13                             0x22
+#define R600_DTC_DFLT_14                             0x22
+#define R600_VRC_DFLT                                0x0000C003
+#define R600_VOLTAGERESPONSETIME_DFLT                1000
+#define R600_BACKBIASRESPONSETIME_DFLT               1000
+#define R600_VRU_DFLT                                0x3
+#define R600_SPLLSTEPTIME_DFLT                       0x1000
+#define R600_SPLLSTEPUNIT_DFLT                       0x3
+#define R600_TPU_DFLT                                0
+#define R600_TPC_DFLT                                0x200
+#define R600_SSTU_DFLT                               0
+#define R600_SST_DFLT                                0x00C8
+#define R600_GICST_DFLT                              0x200
+#define R600_FCT_DFLT                                0x0400
+#define R600_FCTU_DFLT                               0
+#define R600_CTXCGTT3DRPHC_DFLT                      0x20
+#define R600_CTXCGTT3DRSDC_DFLT                      0x40
+#define R600_VDDC3DOORPHC_DFLT                       0x100
+#define R600_VDDC3DOORSDC_DFLT                       0x7
+#define R600_VDDC3DOORSU_DFLT                        0
+#define R600_MPLLLOCKTIME_DFLT                       100
+#define R600_MPLLRESETTIME_DFLT                      150
+#define R600_VCOSTEPPCT_DFLT                          20
+#define R600_ENDINGVCOSTEPPCT_DFLT                    5
+#define R600_REFERENCEDIVIDER_DFLT                    4
+
+#define R600_PM_NUMBER_OF_TC 15
+#define R600_PM_NUMBER_OF_SCLKS 20
+#define R600_PM_NUMBER_OF_MCLKS 4
+#define R600_PM_NUMBER_OF_VOLTAGE_LEVELS 4
+#define R600_PM_NUMBER_OF_ACTIVITY_LEVELS 3
+
+enum r600_power_level {
+	R600_POWER_LEVEL_LOW = 0,
+	R600_POWER_LEVEL_MEDIUM = 1,
+	R600_POWER_LEVEL_HIGH = 2,
+	R600_POWER_LEVEL_CTXSW = 3,
+};
+
+enum r600_td {
+	R600_TD_AUTO,
+	R600_TD_UP,
+	R600_TD_DOWN,
+};
+
+enum r600_display_watermark {
+	R600_DISPLAY_WATERMARK_LOW = 0,
+	R600_DISPLAY_WATERMARK_HIGH = 1,
+};
+
+enum r600_display_gap
+{
+    R600_PM_DISPLAY_GAP_VBLANK_OR_WM = 0,
+    R600_PM_DISPLAY_GAP_VBLANK       = 1,
+    R600_PM_DISPLAY_GAP_WATERMARK    = 2,
+    R600_PM_DISPLAY_GAP_IGNORE       = 3,
+};
+
+extern const u32 r600_utc[R600_PM_NUMBER_OF_TC];
+extern const u32 r600_dtc[R600_PM_NUMBER_OF_TC];
+
+void r600_dpm_print_class_info(u32 class, u32 class2);
+void r600_dpm_print_cap_info(u32 caps);
+void r600_dpm_print_ps_status(struct radeon_device *rdev,
+			      struct radeon_ps *rps);
+bool r600_is_uvd_state(u32 class, u32 class2);
+void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
+			    u32 *p, u32 *u);
+int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th);
+void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable);
+void r600_dynamicpm_enable(struct radeon_device *rdev, bool enable);
+void r600_enable_thermal_protection(struct radeon_device *rdev, bool enable);
+void r600_enable_acpi_pm(struct radeon_device *rdev);
+void r600_enable_dynamic_pcie_gen2(struct radeon_device *rdev, bool enable);
+bool r600_dynamicpm_enabled(struct radeon_device *rdev);
+void r600_enable_sclk_control(struct radeon_device *rdev, bool enable);
+void r600_enable_mclk_control(struct radeon_device *rdev, bool enable);
+void r600_enable_spll_bypass(struct radeon_device *rdev, bool enable);
+void r600_wait_for_spll_change(struct radeon_device *rdev);
+void r600_set_bsp(struct radeon_device *rdev, u32 u, u32 p);
+void r600_set_at(struct radeon_device *rdev,
+		 u32 l_to_m, u32 m_to_h,
+		 u32 h_to_m, u32 m_to_l);
+void r600_set_tc(struct radeon_device *rdev, u32 index, u32 u_t, u32 d_t);
+void r600_select_td(struct radeon_device *rdev, enum r600_td td);
+void r600_set_vrc(struct radeon_device *rdev, u32 vrv);
+void r600_set_tpu(struct radeon_device *rdev, u32 u);
+void r600_set_tpc(struct radeon_device *rdev, u32 c);
+void r600_set_sstu(struct radeon_device *rdev, u32 u);
+void r600_set_sst(struct radeon_device *rdev, u32 t);
+void r600_set_git(struct radeon_device *rdev, u32 t);
+void r600_set_fctu(struct radeon_device *rdev, u32 u);
+void r600_set_fct(struct radeon_device *rdev, u32 t);
+void r600_set_ctxcgtt3d_rphc(struct radeon_device *rdev, u32 p);
+void r600_set_ctxcgtt3d_rsdc(struct radeon_device *rdev, u32 s);
+void r600_set_vddc3d_oorsu(struct radeon_device *rdev, u32 u);
+void r600_set_vddc3d_oorphc(struct radeon_device *rdev, u32 p);
+void r600_set_vddc3d_oorsdc(struct radeon_device *rdev, u32 s);
+void r600_set_mpll_lock_time(struct radeon_device *rdev, u32 lock_time);
+void r600_set_mpll_reset_time(struct radeon_device *rdev, u32 reset_time);
+void r600_engine_clock_entry_enable(struct radeon_device *rdev,
+				    u32 index, bool enable);
+void r600_engine_clock_entry_enable_pulse_skipping(struct radeon_device *rdev,
+						   u32 index, bool enable);
+void r600_engine_clock_entry_enable_post_divider(struct radeon_device *rdev,
+						 u32 index, bool enable);
+void r600_engine_clock_entry_set_post_divider(struct radeon_device *rdev,
+					      u32 index, u32 divider);
+void r600_engine_clock_entry_set_reference_divider(struct radeon_device *rdev,
+						   u32 index, u32 divider);
+void r600_engine_clock_entry_set_feedback_divider(struct radeon_device *rdev,
+						  u32 index, u32 divider);
+void r600_engine_clock_entry_set_step_time(struct radeon_device *rdev,
+					   u32 index, u32 step_time);
+void r600_vid_rt_set_ssu(struct radeon_device *rdev, u32 u);
+void r600_vid_rt_set_vru(struct radeon_device *rdev, u32 u);
+void r600_vid_rt_set_vrt(struct radeon_device *rdev, u32 rt);
+void r600_voltage_control_enable_pins(struct radeon_device *rdev,
+				      u64 mask);
+void r600_voltage_control_program_voltages(struct radeon_device *rdev,
+					   enum r600_power_level index, u64 pins);
+void r600_voltage_control_deactivate_static_control(struct radeon_device *rdev,
+						    u64 mask);
+void r600_power_level_enable(struct radeon_device *rdev,
+			     enum r600_power_level index, bool enable);
+void r600_power_level_set_voltage_index(struct radeon_device *rdev,
+					enum r600_power_level index, u32 voltage_index);
+void r600_power_level_set_mem_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 mem_clock_index);
+void r600_power_level_set_eng_clock_index(struct radeon_device *rdev,
+					  enum r600_power_level index, u32 eng_clock_index);
+void r600_power_level_set_watermark_id(struct radeon_device *rdev,
+				       enum r600_power_level index,
+				       enum r600_display_watermark watermark_id);
+void r600_power_level_set_pcie_gen2(struct radeon_device *rdev,
+				    enum r600_power_level index, bool compatible);
+enum r600_power_level r600_power_level_get_current_index(struct radeon_device *rdev);
+enum r600_power_level r600_power_level_get_target_index(struct radeon_device *rdev);
+void r600_power_level_set_enter_index(struct radeon_device *rdev,
+				      enum r600_power_level index);
+void r600_wait_for_power_level_unequal(struct radeon_device *rdev,
+				       enum r600_power_level index);
+void r600_wait_for_power_level(struct radeon_device *rdev,
+			       enum r600_power_level index);
+void r600_start_dpm(struct radeon_device *rdev);
+void r600_stop_dpm(struct radeon_device *rdev);
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index a3f926c..d6d385a 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -1144,6 +1144,219 @@
 #       define AFMT_AZ_FORMAT_WTRIG_ACK      (1 << 29)
 #       define AFMT_AZ_AUDIO_ENABLE_CHG_ACK  (1 << 30)
 
+/* Power management */
+#define CG_SPLL_FUNC_CNTL                                 0x600
+#       define SPLL_RESET                                (1 << 0)
+#       define SPLL_SLEEP                                (1 << 1)
+#       define SPLL_REF_DIV(x)                           ((x) << 2)
+#       define SPLL_REF_DIV_MASK                         (7 << 2)
+#       define SPLL_FB_DIV(x)                            ((x) << 5)
+#       define SPLL_FB_DIV_MASK                          (0xff << 5)
+#       define SPLL_PULSEEN                              (1 << 13)
+#       define SPLL_PULSENUM(x)                          ((x) << 14)
+#       define SPLL_PULSENUM_MASK                        (3 << 14)
+#       define SPLL_SW_HILEN(x)                          ((x) << 16)
+#       define SPLL_SW_HILEN_MASK                        (0xf << 16)
+#       define SPLL_SW_LOLEN(x)                          ((x) << 20)
+#       define SPLL_SW_LOLEN_MASK                        (0xf << 20)
+#       define SPLL_DIVEN                                (1 << 24)
+#       define SPLL_BYPASS_EN                            (1 << 25)
+#       define SPLL_CHG_STATUS                           (1 << 29)
+#       define SPLL_CTLREQ                               (1 << 30)
+#       define SPLL_CTLACK                               (1 << 31)
+
+#define GENERAL_PWRMGT                                    0x618
+#       define GLOBAL_PWRMGT_EN                           (1 << 0)
+#       define STATIC_PM_EN                               (1 << 1)
+#       define MOBILE_SU                                  (1 << 2)
+#       define THERMAL_PROTECTION_DIS                     (1 << 3)
+#       define THERMAL_PROTECTION_TYPE                    (1 << 4)
+#       define ENABLE_GEN2PCIE                            (1 << 5)
+#       define SW_GPIO_INDEX(x)                           ((x) << 6)
+#       define SW_GPIO_INDEX_MASK                         (3 << 6)
+#       define LOW_VOLT_D2_ACPI                           (1 << 8)
+#       define LOW_VOLT_D3_ACPI                           (1 << 9)
+#       define VOLT_PWRMGT_EN                             (1 << 10)
+#define CG_TPC                                            0x61c
+#       define TPCC(x)                                    ((x) << 0)
+#       define TPCC_MASK                                  (0x7fffff << 0)
+#       define TPU(x)                                     ((x) << 23)
+#       define TPU_MASK                                   (0x1f << 23)
+#define SCLK_PWRMGT_CNTL                                  0x620
+#       define SCLK_PWRMGT_OFF                            (1 << 0)
+#       define SCLK_TURNOFF                               (1 << 1)
+#       define SPLL_TURNOFF                               (1 << 2)
+#       define SU_SCLK_USE_BCLK                           (1 << 3)
+#       define DYNAMIC_GFX_ISLAND_PWR_DOWN                (1 << 4)
+#       define DYNAMIC_GFX_ISLAND_PWR_LP                  (1 << 5)
+#       define CLK_TURN_ON_STAGGER                        (1 << 6)
+#       define CLK_TURN_OFF_STAGGER                       (1 << 7)
+#       define FIR_FORCE_TREND_SEL                        (1 << 8)
+#       define FIR_TREND_MODE                             (1 << 9)
+#       define DYN_GFX_CLK_OFF_EN                         (1 << 10)
+#       define VDDC3D_TURNOFF_D1                          (1 << 11)
+#       define VDDC3D_TURNOFF_D2                          (1 << 12)
+#       define VDDC3D_TURNOFF_D3                          (1 << 13)
+#       define SPLL_TURNOFF_D2                            (1 << 14)
+#       define SCLK_LOW_D1                                (1 << 15)
+#       define DYN_GFX_CLK_OFF_MC_EN                      (1 << 16)
+#define MCLK_PWRMGT_CNTL                                  0x624
+#       define MPLL_PWRMGT_OFF                            (1 << 0)
+#       define YCLK_TURNOFF                               (1 << 1)
+#       define MPLL_TURNOFF                               (1 << 2)
+#       define SU_MCLK_USE_BCLK                           (1 << 3)
+#       define DLL_READY                                  (1 << 4)
+#       define MC_BUSY                                    (1 << 5)
+#       define MC_INT_CNTL                                (1 << 7)
+#       define MRDCKA_SLEEP                               (1 << 8)
+#       define MRDCKB_SLEEP                               (1 << 9)
+#       define MRDCKC_SLEEP                               (1 << 10)
+#       define MRDCKD_SLEEP                               (1 << 11)
+#       define MRDCKE_SLEEP                               (1 << 12)
+#       define MRDCKF_SLEEP                               (1 << 13)
+#       define MRDCKG_SLEEP                               (1 << 14)
+#       define MRDCKH_SLEEP                               (1 << 15)
+#       define MRDCKA_RESET                               (1 << 16)
+#       define MRDCKB_RESET                               (1 << 17)
+#       define MRDCKC_RESET                               (1 << 18)
+#       define MRDCKD_RESET                               (1 << 19)
+#       define MRDCKE_RESET                               (1 << 20)
+#       define MRDCKF_RESET                               (1 << 21)
+#       define MRDCKG_RESET                               (1 << 22)
+#       define MRDCKH_RESET                               (1 << 23)
+#       define DLL_READY_READ                             (1 << 24)
+#       define USE_DISPLAY_GAP                            (1 << 25)
+#       define USE_DISPLAY_URGENT_NORMAL                  (1 << 26)
+#       define USE_DISPLAY_GAP_CTXSW                      (1 << 27)
+#       define MPLL_TURNOFF_D2                            (1 << 28)
+#       define USE_DISPLAY_URGENT_CTXSW                   (1 << 29)
+
+#define MPLL_TIME                                         0x634
+#       define MPLL_LOCK_TIME(x)                          ((x) << 0)
+#       define MPLL_LOCK_TIME_MASK                        (0xffff << 0)
+#       define MPLL_RESET_TIME(x)                         ((x) << 16)
+#       define MPLL_RESET_TIME_MASK                       (0xffff << 16)
+
+#define SCLK_FREQ_SETTING_STEP_0_PART1                    0x648
+#       define STEP_0_SPLL_POST_DIV(x)                    ((x) << 0)
+#       define STEP_0_SPLL_POST_DIV_MASK                  (0xff << 0)
+#       define STEP_0_SPLL_FB_DIV(x)                      ((x) << 8)
+#       define STEP_0_SPLL_FB_DIV_MASK                    (0xff << 8)
+#       define STEP_0_SPLL_REF_DIV(x)                     ((x) << 16)
+#       define STEP_0_SPLL_REF_DIV_MASK                   (7 << 16)
+#       define STEP_0_SPLL_STEP_TIME(x)                   ((x) << 19)
+#       define STEP_0_SPLL_STEP_TIME_MASK                 (0x1fff << 19)
+#define SCLK_FREQ_SETTING_STEP_0_PART2                    0x64c
+#       define STEP_0_PULSE_HIGH_CNT(x)                   ((x) << 0)
+#       define STEP_0_PULSE_HIGH_CNT_MASK                 (0x1ff << 0)
+#       define STEP_0_POST_DIV_EN                         (1 << 9)
+#       define STEP_0_SPLL_STEP_ENABLE                    (1 << 30)
+#       define STEP_0_SPLL_ENTRY_VALID                    (1 << 31)
+
+#define VID_RT                                            0x6f8
+#       define VID_CRT(x)                                 ((x) << 0)
+#       define VID_CRT_MASK                               (0x1fff << 0)
+#       define VID_CRTU(x)                                ((x) << 13)
+#       define VID_CRTU_MASK                              (7 << 13)
+#       define SSTU(x)                                    ((x) << 16)
+#       define SSTU_MASK                                  (7 << 16)
+#define CTXSW_PROFILE_INDEX                               0x6fc
+#       define CTXSW_FREQ_VIDS_CFG_INDEX(x)               ((x) << 0)
+#       define CTXSW_FREQ_VIDS_CFG_INDEX_MASK             (3 << 0)
+#       define CTXSW_FREQ_VIDS_CFG_INDEX_SHIFT            0
+#       define CTXSW_FREQ_MCLK_CFG_INDEX(x)               ((x) << 2)
+#       define CTXSW_FREQ_MCLK_CFG_INDEX_MASK             (3 << 2)
+#       define CTXSW_FREQ_MCLK_CFG_INDEX_SHIFT            2
+#       define CTXSW_FREQ_SCLK_CFG_INDEX(x)               ((x) << 4)
+#       define CTXSW_FREQ_SCLK_CFG_INDEX_MASK             (0x1f << 4)
+#       define CTXSW_FREQ_SCLK_CFG_INDEX_SHIFT            4
+#       define CTXSW_FREQ_STATE_SPLL_RESET_EN             (1 << 9)
+#       define CTXSW_FREQ_STATE_ENABLE                    (1 << 10)
+#       define CTXSW_FREQ_DISPLAY_WATERMARK               (1 << 11)
+#       define CTXSW_FREQ_GEN2PCIE_VOLT                   (1 << 12)
+
+#define TARGET_AND_CURRENT_PROFILE_INDEX                  0x70c
+#       define TARGET_PROFILE_INDEX_MASK                  (3 << 0)
+#       define TARGET_PROFILE_INDEX_SHIFT                 0
+#       define CURRENT_PROFILE_INDEX_MASK                 (3 << 2)
+#       define CURRENT_PROFILE_INDEX_SHIFT                2
+#       define DYN_PWR_ENTER_INDEX(x)                     ((x) << 4)
+#       define DYN_PWR_ENTER_INDEX_MASK                   (3 << 4)
+#       define DYN_PWR_ENTER_INDEX_SHIFT                  4
+#       define CURR_MCLK_INDEX_MASK                       (3 << 6)
+#       define CURR_MCLK_INDEX_SHIFT                      6
+#       define CURR_SCLK_INDEX_MASK                       (0x1f << 8)
+#       define CURR_SCLK_INDEX_SHIFT                      8
+#       define CURR_VID_INDEX_MASK                        (3 << 13)
+#       define CURR_VID_INDEX_SHIFT                       13
+
+#define LOWER_GPIO_ENABLE                                 0x710
+#define UPPER_GPIO_ENABLE                                 0x714
+#define CTXSW_VID_LOWER_GPIO_CNTL                         0x718
+
+#define VID_UPPER_GPIO_CNTL                               0x740
+#define CG_CTX_CGTT3D_R                                   0x744
+#       define PHC(x)                                     ((x) << 0)
+#       define PHC_MASK                                   (0x1ff << 0)
+#       define SDC(x)                                     ((x) << 9)
+#       define SDC_MASK                                   (0x3fff << 9)
+#define CG_VDDC3D_OOR                                     0x748
+#       define SU(x)                                      ((x) << 23)
+#       define SU_MASK                                    (0xf << 23)
+#define CG_FTV                                            0x74c
+#define CG_FFCT_0                                         0x750
+#       define UTC_0(x)                                   ((x) << 0)
+#       define UTC_0_MASK                                 (0x3ff << 0)
+#       define DTC_0(x)                                   ((x) << 10)
+#       define DTC_0_MASK                                 (0x3ff << 10)
+
+#define CG_BSP                                            0x78c
+#       define BSP(x)                                     ((x) << 0)
+#       define BSP_MASK                                   (0xffff << 0)
+#       define BSU(x)                                     ((x) << 16)
+#       define BSU_MASK                                   (0xf << 16)
+#define CG_RT                                             0x790
+#       define FLS(x)                                     ((x) << 0)
+#       define FLS_MASK                                   (0xffff << 0)
+#       define FMS(x)                                     ((x) << 16)
+#       define FMS_MASK                                   (0xffff << 16)
+#define CG_LT                                             0x794
+#       define FHS(x)                                     ((x) << 0)
+#       define FHS_MASK                                   (0xffff << 0)
+#define CG_GIT                                            0x798
+#       define CG_GICST(x)                                ((x) << 0)
+#       define CG_GICST_MASK                              (0xffff << 0)
+#       define CG_GIPOT(x)                                ((x) << 16)
+#       define CG_GIPOT_MASK                              (0xffff << 16)
+
+#define CG_SSP                                            0x7a8
+#       define CG_SST(x)                                  ((x) << 0)
+#       define CG_SST_MASK                                (0xffff << 0)
+#       define CG_SSTU(x)                                 ((x) << 16)
+#       define CG_SSTU_MASK                               (0xf << 16)
+
+#define CG_RLC_REQ_AND_RSP                                0x7c4
+#       define RLC_CG_REQ_TYPE_MASK                       0xf
+#       define RLC_CG_REQ_TYPE_SHIFT                      0
+#       define CG_RLC_RSP_TYPE_MASK                       0xf0
+#       define CG_RLC_RSP_TYPE_SHIFT                      4
+
+#define CG_FC_T                                           0x7cc
+#       define FC_T(x)                                    ((x) << 0)
+#       define FC_T_MASK                                  (0xffff << 0)
+#       define FC_TU(x)                                   ((x) << 16)
+#       define FC_TU_MASK                                 (0x1f << 16)
+
+#define GPIOPAD_MASK                                      0x1798
+#define GPIOPAD_A                                         0x179c
+#define GPIOPAD_EN                                        0x17a0
+
+#define GRBM_PWR_CNTL                                     0x800c
+#       define REQ_TYPE_MASK                              0xf
+#       define REQ_TYPE_SHIFT                             0
+#       define RSP_TYPE_MASK                              0xf0
+#       define RSP_TYPE_SHIFT                             4
+
 /*
  * UVD
  */
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index c43673c..7adc7a1 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1184,6 +1184,19 @@ struct radeon_power_state {
  */
 #define RADEON_MODE_OVERCLOCK_MARGIN 500 /* 5 MHz */
 
+enum radeon_dpm_auto_throttle_src {
+	RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL,
+	RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL
+};
+
+enum radeon_dpm_event_src {
+	RADEON_DPM_EVENT_SRC_ANALOG = 0,
+	RADEON_DPM_EVENT_SRC_EXTERNAL = 1,
+	RADEON_DPM_EVENT_SRC_DIGITAL = 2,
+	RADEON_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
+	RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
+};
+
 struct radeon_ps {
 	u32 caps; /* vbios flags */
 	u32 class; /* vbios flags */
-- 
1.7.7.5



More information about the dri-devel mailing list