summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/rv770_dpm.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-06-26 00:33:35 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:15:22 -0400
commitdc50ba7f9a6d9a920409892c7f30bce266067345 (patch)
tree17e9dc618117ceacf39c2f2e29907792cdedc598 /drivers/gpu/drm/radeon/rv770_dpm.c
parent66229b200598a3b66b839d1759ff3f5b17ac5639 (diff)
drm/radeon/kms: add dpm support for evergreen (v4)
This adds dpm support for evergreen asics. This includes: - clockgating - dynamic engine clock scaling - dynamic memory clock scaling - dynamic voltage scaling - dynamic pcie gen1/gen2 switching (requires additional acpi support) Set radeon.dpm=1 to enable. v2: reduce stack usage, rename ulv struct v3: fix thermal interrupt check notices by Jerome v4: fix state enable Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770_dpm.c')
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
index 232b2fdf57eb..d15e7157a4bf 100644
--- a/drivers/gpu/drm/radeon/rv770_dpm.c
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -27,6 +27,7 @@
#include "rv770d.h"
#include "r600_dpm.h"
#include "rv770_dpm.h"
+#include "cypress_dpm.h"
#include "atom.h"
#define MC_CG_ARB_FREQ_F0 0x0a
@@ -56,6 +57,13 @@ struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev)
return pi;
}
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev)
+{
+ struct evergreen_power_info *pi = rdev->pm.dpm.priv;
+
+ return pi;
+}
+
static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
bool enable)
{
@@ -1806,8 +1814,8 @@ void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
}
}
-static int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
- int min_temp, int max_temp)
+int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
+ int min_temp, int max_temp)
{
int low_temp = 0 * 1000;
int high_temp = 255 * 1000;
@@ -2057,6 +2065,7 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
union pplib_clock_info *clock_info)
{
struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+ struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
struct rv7xx_ps *ps = rv770_get_ps(rps);
u32 sclk, mclk;
u16 vddc;
@@ -2075,13 +2084,24 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
break;
}
- sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
- sclk |= clock_info->r600.ucEngineClockHigh << 16;
- mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
- mclk |= clock_info->r600.ucMemoryClockHigh << 16;
+ if (rdev->family >= CHIP_CEDAR) {
+ sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
+ sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
+ mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
+ mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
+
+ pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
+ pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
+ pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
+ } else {
+ sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
+ sclk |= clock_info->r600.ucEngineClockHigh << 16;
+ mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
+ mclk |= clock_info->r600.ucMemoryClockHigh << 16;
- pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
- pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
+ pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
+ pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
+ }
pl->mclk = mclk;
pl->sclk = sclk;
@@ -2094,12 +2114,21 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
pi->acpi_vddc = pl->vddc;
+ if (rdev->family >= CHIP_CEDAR)
+ eg_pi->acpi_vddci = pl->vddci;
if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
pi->acpi_pcie_gen2 = true;
else
pi->acpi_pcie_gen2 = false;
}
+ if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
+ if (rdev->family >= CHIP_BARTS) {
+ eg_pi->ulv.supported = true;
+ eg_pi->ulv.pl = pl;
+ }
+ }
+
if (pi->min_vddc_in_table > pl->vddc)
pi->min_vddc_in_table = pl->vddc;