336,6 → 336,7 |
0x00000204, 0x00000000, |
}; |
|
extern void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable); |
static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev, |
const u32 *seq, u32 count); |
static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev); |
985,6 → 986,21 |
trinity_setup_uvd_clocks(rdev, new_rps, old_rps); |
} |
|
static void trinity_set_vce_clock(struct radeon_device *rdev, |
struct radeon_ps *new_rps, |
struct radeon_ps *old_rps) |
{ |
if ((old_rps->evclk != new_rps->evclk) || |
(old_rps->ecclk != new_rps->ecclk)) { |
/* turn the clocks on when encoding, off otherwise */ |
if (new_rps->evclk || new_rps->ecclk) |
vce_v1_0_enable_mgcg(rdev, false); |
else |
vce_v1_0_enable_mgcg(rdev, true); |
radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk); |
} |
} |
|
static void trinity_program_ttt(struct radeon_device *rdev) |
{ |
struct trinity_power_info *pi = trinity_get_pi(rdev); |
1246,6 → 1262,7 |
trinity_force_level_0(rdev); |
trinity_unforce_levels(rdev); |
trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps); |
trinity_set_vce_clock(rdev, new_ps, old_ps); |
} |
trinity_release_mutex(rdev); |
|
1269,6 → 1286,7 |
trinity_release_mutex(rdev); |
} |
|
#if 0 |
void trinity_dpm_reset_asic(struct radeon_device *rdev) |
{ |
struct trinity_power_info *pi = trinity_get_pi(rdev); |
1284,6 → 1302,7 |
} |
trinity_release_mutex(rdev); |
} |
#endif |
|
static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev, |
u32 vid_2bit) |
1481,8 → 1500,36 |
} |
} |
|
static int trinity_get_vce_clock_voltage(struct radeon_device *rdev, |
u32 evclk, u32 ecclk, u16 *voltage) |
{ |
u32 i; |
int ret = -EINVAL; |
struct radeon_vce_clock_voltage_dependency_table *table = |
&rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; |
|
if (((evclk == 0) && (ecclk == 0)) || |
(table && (table->count == 0))) { |
*voltage = 0; |
return 0; |
} |
|
for (i = 0; i < table->count; i++) { |
if ((evclk <= table->entries[i].evclk) && |
(ecclk <= table->entries[i].ecclk)) { |
*voltage = table->entries[i].v; |
ret = 0; |
break; |
} |
} |
|
/* if no match return the highest voltage */ |
if (ret) |
*voltage = table->entries[table->count - 1].v; |
|
return ret; |
} |
|
static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, |
struct radeon_ps *new_rps, |
struct radeon_ps *old_rps) |
1494,6 → 1541,7 |
u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */ |
u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */ |
u32 i; |
u16 min_vce_voltage; |
bool force_high; |
u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count; |
|
1502,6 → 1550,14 |
|
trinity_adjust_uvd_state(rdev, new_rps); |
|
if (new_rps->vce_active) { |
new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk; |
new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk; |
} else { |
new_rps->evclk = 0; |
new_rps->ecclk = 0; |
} |
|
for (i = 0; i < ps->num_levels; i++) { |
if (ps->levels[i].vddc_index < min_voltage) |
ps->levels[i].vddc_index = min_voltage; |
1510,6 → 1566,17 |
ps->levels[i].sclk = |
trinity_get_valid_engine_clock(rdev, min_sclk); |
|
/* patch in vce limits */ |
if (new_rps->vce_active) { |
/* sclk */ |
if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk) |
ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk; |
/* vddc */ |
trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage); |
if (ps->levels[i].vddc_index < min_vce_voltage) |
ps->levels[i].vddc_index = min_vce_voltage; |
} |
|
ps->levels[i].ds_divider_index = |
sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr); |
|
1731,6 → 1798,19 |
power_state_offset += 2 + power_state->v2.ucNumDPMLevels; |
} |
rdev->pm.dpm.num_ps = state_array->ucNumEntries; |
|
/* fill in the vce power states */ |
for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { |
u32 sclk; |
clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx; |
clock_info = (union pplib_clock_info *) |
&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; |
sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); |
sclk |= clock_info->sumo.ucEngineClockHigh << 16; |
rdev->pm.dpm.vce_states[i].sclk = sclk; |
rdev->pm.dpm.vce_states[i].mclk = 0; |
} |
|
return 0; |
} |
|
1912,6 → 1992,10 |
if (ret) |
return ret; |
|
ret = r600_parse_extended_power_table(rdev); |
if (ret) |
return ret; |
|
ret = trinity_parse_power_table(rdev); |
if (ret) |
return ret; |
1962,6 → 2046,31 |
} |
} |
|
u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev) |
{ |
struct trinity_power_info *pi = trinity_get_pi(rdev); |
struct radeon_ps *rps = &pi->current_rps; |
struct trinity_ps *ps = trinity_get_ps(rps); |
struct trinity_pl *pl; |
u32 current_index = |
(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >> |
CURRENT_STATE_SHIFT; |
|
if (current_index >= ps->num_levels) { |
return 0; |
} else { |
pl = &ps->levels[current_index]; |
return pl->sclk; |
} |
} |
|
u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev) |
{ |
struct trinity_power_info *pi = trinity_get_pi(rdev); |
|
return pi->sys_info.bootup_uma_clk; |
} |
|
void trinity_dpm_fini(struct radeon_device *rdev) |
{ |
int i; |
1973,6 → 2082,7 |
} |
kfree(rdev->pm.dpm.ps); |
kfree(rdev->pm.dpm.priv); |
r600_free_extended_power_table(rdev); |
} |
|
u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low) |