summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/sumo_dpm.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-04-13 00:40:41 +0400
committerAlex Deucher <alexander.deucher@amd.com>2013-06-28 03:15:45 +0400
commitd70229f704474b2932e03367a528773e336f6205 (patch)
tree8e56480f4073505457f212706f7f3f81b89583bc /drivers/gpu/drm/radeon/sumo_dpm.c
parent80ea2c129c76a4159a93efeaef4385b6c964dfac (diff)
downloadlinux-d70229f704474b2932e03367a528773e336f6205.tar.xz
drm/radeon/kms: add dpm support for trinity asics
This adds dpm support for trinity asics. This includes: - clockgating - powergating - dynamic engine clock scaling - dynamic voltage scaling set radeon.dpm=1 to enable it. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/sumo_dpm.c')
-rw-r--r--drivers/gpu/drm/radeon/sumo_dpm.c90
1 files changed, 47 insertions, 43 deletions
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c
index fa2a72e17d07..7ab60068396e 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -27,7 +27,6 @@
#include "r600_dpm.h"
#include "cypress_dpm.h"
#include "sumo_dpm.h"
-#include "atom.h"
#define SUMO_MAX_DEEPSLEEP_DIVIDER_ID 5
#define SUMO_MINIMUM_ENGINE_CLOCK 800
@@ -144,7 +143,7 @@ static void sumo_program_grsd(struct radeon_device *rdev)
WREG32(CG_GCOOR, PHC(grs) | SDC(p) | SU(u));
}
-static void sumo_gfx_clockgating_initialize(struct radeon_device *rdev)
+void sumo_gfx_clockgating_initialize(struct radeon_device *rdev)
{
sumo_program_git(rdev);
sumo_program_grsd(rdev);
@@ -452,17 +451,17 @@ static void sumo_program_tp(struct radeon_device *rdev)
WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
}
-static void sumo_program_vc(struct radeon_device *rdev)
+void sumo_program_vc(struct radeon_device *rdev, u32 vrc)
{
- WREG32(CG_FTV, SUMO_VRC_DFLT);
+ WREG32(CG_FTV, vrc);
}
-static void sumo_clear_vc(struct radeon_device *rdev)
+void sumo_clear_vc(struct radeon_device *rdev)
{
WREG32(CG_FTV, 0);
}
-static void sumo_program_sstp(struct radeon_device *rdev)
+void sumo_program_sstp(struct radeon_device *rdev)
{
u32 p, u;
u32 xclk = sumo_get_xclk(rdev);
@@ -812,7 +811,7 @@ static void sumo_program_bootup_state(struct radeon_device *rdev)
sumo_power_level_enable(rdev, i, false);
}
-static void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
+void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
{
u32 v = RREG32(DOUT_SCRATCH3);
@@ -933,14 +932,14 @@ static void sumo_force_nbp_state(struct radeon_device *rdev)
}
}
-static u32 sumo_get_sleep_divider_from_id(u32 id)
+u32 sumo_get_sleep_divider_from_id(u32 id)
{
return 1 << id;
}
-static u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
- u32 sclk,
- u32 min_sclk_in_sr)
+u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
+ u32 sclk,
+ u32 min_sclk_in_sr)
{
struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 i;
@@ -1136,7 +1135,7 @@ int sumo_dpm_enable(struct radeon_device *rdev)
sumo_program_power_level_enter_state(rdev);
sumo_enable_voltage_scaling(rdev, true);
sumo_program_sstp(rdev);
- sumo_program_vc(rdev);
+ sumo_program_vc(rdev, SUMO_VRC_DFLT);
sumo_override_cnb_thermal_events(rdev);
sumo_start_dpm(rdev);
sumo_wait_for_level_0(rdev);
@@ -1393,23 +1392,25 @@ static int sumo_parse_power_table(struct radeon_device *rdev)
return 0;
}
-static u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev, u32 vid_2bit)
+u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
+ struct sumo_vid_mapping_table *vid_mapping_table,
+ u32 vid_2bit)
{
- struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 i;
- for (i = 0; i < pi->sys_info.vid_mapping_table.num_entries; i++) {
- if (pi->sys_info.vid_mapping_table.entries[i].vid_2bit == vid_2bit)
- return pi->sys_info.vid_mapping_table.entries[i].vid_7bit;
+ for (i = 0; i < vid_mapping_table->num_entries; i++) {
+ if (vid_mapping_table->entries[i].vid_2bit == vid_2bit)
+ return vid_mapping_table->entries[i].vid_7bit;
}
- return pi->sys_info.vid_mapping_table.entries[pi->sys_info.vid_mapping_table.num_entries - 1].vid_7bit;
+ return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
}
static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev,
u32 vid_2bit)
{
- u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, vid_2bit);
+ struct sumo_power_info *pi = sumo_get_pi(rdev);
+ u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
if (vid_7bit > 0x7C)
return 0;
@@ -1418,71 +1419,71 @@ static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev,
}
static void sumo_construct_display_voltage_mapping_table(struct radeon_device *rdev,
+ struct sumo_disp_clock_voltage_mapping_table *disp_clk_voltage_mapping_table,
ATOM_CLK_VOLT_CAPABILITY *table)
{
- struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 i;
for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
if (table[i].ulMaximumSupportedCLK == 0)
break;
- pi->sys_info.disp_clk_voltage_mapping_table.display_clock_frequency[i] =
+ disp_clk_voltage_mapping_table->display_clock_frequency[i] =
table[i].ulMaximumSupportedCLK;
}
- pi->sys_info.disp_clk_voltage_mapping_table.num_max_voltage_levels = i;
+ disp_clk_voltage_mapping_table->num_max_voltage_levels = i;
- if (pi->sys_info.disp_clk_voltage_mapping_table.num_max_voltage_levels == 0) {
- pi->sys_info.disp_clk_voltage_mapping_table.display_clock_frequency[0] = 80000;
- pi->sys_info.disp_clk_voltage_mapping_table.num_max_voltage_levels = 1;
+ if (disp_clk_voltage_mapping_table->num_max_voltage_levels == 0) {
+ disp_clk_voltage_mapping_table->display_clock_frequency[0] = 80000;
+ disp_clk_voltage_mapping_table->num_max_voltage_levels = 1;
}
}
-static void sumo_construct_sclk_voltage_mapping_table(struct radeon_device *rdev,
- ATOM_AVAILABLE_SCLK_LIST *table)
+void sumo_construct_sclk_voltage_mapping_table(struct radeon_device *rdev,
+ struct sumo_sclk_voltage_mapping_table *sclk_voltage_mapping_table,
+ ATOM_AVAILABLE_SCLK_LIST *table)
{
- struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 i;
u32 n = 0;
u32 prev_sclk = 0;
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
if (table[i].ulSupportedSCLK > prev_sclk) {
- pi->sys_info.sclk_voltage_mapping_table.entries[n].sclk_frequency =
+ sclk_voltage_mapping_table->entries[n].sclk_frequency =
table[i].ulSupportedSCLK;
- pi->sys_info.sclk_voltage_mapping_table.entries[n].vid_2bit =
+ sclk_voltage_mapping_table->entries[n].vid_2bit =
table[i].usVoltageIndex;
prev_sclk = table[i].ulSupportedSCLK;
n++;
}
}
- pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries = n;
+ sclk_voltage_mapping_table->num_max_dpm_entries = n;
}
-static void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
- ATOM_AVAILABLE_SCLK_LIST *table)
+void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
+ struct sumo_vid_mapping_table *vid_mapping_table,
+ ATOM_AVAILABLE_SCLK_LIST *table)
{
- struct sumo_power_info *pi = sumo_get_pi(rdev);
u32 i, j;
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
if (table[i].ulSupportedSCLK != 0) {
- pi->sys_info.vid_mapping_table.entries[table[i].usVoltageIndex].vid_7bit =
+ vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
table[i].usVoltageID;
- pi->sys_info.vid_mapping_table.entries[table[i].usVoltageIndex].vid_2bit =
+ vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
table[i].usVoltageIndex;
}
}
for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
- if (pi->sys_info.vid_mapping_table.entries[i].vid_7bit == 0) {
+ if (vid_mapping_table->entries[i].vid_7bit == 0) {
for (j = i + 1; j < SUMO_MAX_NUMBER_VOLTAGES; j++) {
- if (pi->sys_info.vid_mapping_table.entries[j].vid_7bit != 0) {
- pi->sys_info.vid_mapping_table.entries[i] =
- pi->sys_info.vid_mapping_table.entries[j];
- pi->sys_info.vid_mapping_table.entries[j].vid_7bit = 0;
+ if (vid_mapping_table->entries[j].vid_7bit != 0) {
+ vid_mapping_table->entries[i] =
+ vid_mapping_table->entries[j];
+ vid_mapping_table->entries[j].vid_7bit = 0;
break;
}
}
@@ -1492,7 +1493,7 @@ static void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
}
}
- pi->sys_info.vid_mapping_table.num_entries = i;
+ vid_mapping_table->num_entries = i;
}
union igp_info {
@@ -1561,10 +1562,13 @@ static int sumo_parse_sys_info_table(struct radeon_device *rdev)
else
pi->sys_info.enable_boost = false;
sumo_construct_display_voltage_mapping_table(rdev,
+ &pi->sys_info.disp_clk_voltage_mapping_table,
igp_info->info_6.sDISPCLK_Voltage);
sumo_construct_sclk_voltage_mapping_table(rdev,
+ &pi->sys_info.sclk_voltage_mapping_table,
igp_info->info_6.sAvail_SCLK);
- sumo_construct_vid_mapping_table(rdev, igp_info->info_6.sAvail_SCLK);
+ sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
+ igp_info->info_6.sAvail_SCLK);
}
return 0;