drm/radeon/dpm: fetch vce states from the vbios

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Alex Deucher 2013-09-04 16:13:56 -04:00 committed by Christian König
parent b62d628bd6
commit 58bd2a88fa
2 changed files with 43 additions and 1 deletions

View File

@ -1063,7 +1063,15 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
(mode_info->atom_context->bios + data_offset + (mode_info->atom_context->bios + data_offset +
le16_to_cpu(ext_hdr->usVCETableOffset) + 1 + le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1 + array->ucNumEntries * sizeof(VCEClockInfo)); 1 + array->ucNumEntries * sizeof(VCEClockInfo));
ATOM_PPLIB_VCE_State_Table *states =
(ATOM_PPLIB_VCE_State_Table *)
(mode_info->atom_context->bios + data_offset +
le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry; ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
ATOM_PPLIB_VCE_State_Record *state_entry;
VCEClockInfo *vce_clk;
u32 size = limits->numEntries * u32 size = limits->numEntries *
sizeof(struct radeon_vce_clock_voltage_dependency_entry); sizeof(struct radeon_vce_clock_voltage_dependency_entry);
rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
@ -1075,8 +1083,9 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
limits->numEntries; limits->numEntries;
entry = &limits->entries[0]; entry = &limits->entries[0];
state_entry = &states->entries[0];
for (i = 0; i < limits->numEntries; i++) { for (i = 0; i < limits->numEntries; i++) {
VCEClockInfo *vce_clk = (VCEClockInfo *) vce_clk = (VCEClockInfo *)
((u8 *)&array->entries[0] + ((u8 *)&array->entries[0] +
(entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo))); (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk = rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
@ -1088,6 +1097,23 @@ int r600_parse_extended_power_table(struct radeon_device *rdev)
entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *) entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)); ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
} }
for (i = 0; i < states->numEntries; i++) {
if (i >= RADEON_MAX_VCE_LEVELS)
break;
vce_clk = (VCEClockInfo *)
((u8 *)&array->entries[0] +
(state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
rdev->pm.dpm.vce_states[i].evclk =
le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
rdev->pm.dpm.vce_states[i].ecclk =
le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
rdev->pm.dpm.vce_states[i].clk_idx =
state_entry->ucClockInfoIndex & 0x3f;
rdev->pm.dpm.vce_states[i].pstate =
(state_entry->ucClockInfoIndex & 0xc0) >> 6;
state_entry = (ATOM_PPLIB_VCE_State_Record *)
((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
}
} }
if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) && if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
ext_hdr->usUVDTableOffset) { ext_hdr->usUVDTableOffset) {

View File

@ -1259,6 +1259,8 @@ enum radeon_dpm_event_src {
RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4 RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
}; };
#define RADEON_MAX_VCE_LEVELS 6
enum radeon_vce_level { enum radeon_vce_level {
RADEON_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */ RADEON_VCE_LEVEL_AC_ALL = 0, /* AC, All cases */
RADEON_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */ RADEON_VCE_LEVEL_DC_EE = 1, /* DC, entropy encoding */
@ -1454,6 +1456,17 @@ enum radeon_dpm_forced_level {
RADEON_DPM_FORCED_LEVEL_HIGH = 2, RADEON_DPM_FORCED_LEVEL_HIGH = 2,
}; };
struct radeon_vce_state {
/* vce clocks */
u32 evclk;
u32 ecclk;
/* gpu clocks */
u32 sclk;
u32 mclk;
u8 clk_idx;
u8 pstate;
};
struct radeon_dpm { struct radeon_dpm {
struct radeon_ps *ps; struct radeon_ps *ps;
/* number of valid power states */ /* number of valid power states */
@ -1466,6 +1479,9 @@ struct radeon_dpm {
struct radeon_ps *boot_ps; struct radeon_ps *boot_ps;
/* default uvd power state */ /* default uvd power state */
struct radeon_ps *uvd_ps; struct radeon_ps *uvd_ps;
/* vce requirements */
struct radeon_vce_state vce_states[RADEON_MAX_VCE_LEVELS];
enum radeon_vce_level vce_level;
enum radeon_pm_state_type state; enum radeon_pm_state_type state;
enum radeon_pm_state_type user_state; enum radeon_pm_state_type user_state;
u32 platform_caps; u32 platform_caps;