Loading drivers/gpu/drm/radeon/trinity_dpm.c +76 −0 Original line number Diff line number Diff line Loading @@ -985,6 +985,15 @@ static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev 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)) 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); Loading Loading @@ -1246,6 +1255,7 @@ int trinity_dpm_set_power_state(struct radeon_device *rdev) 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); Loading Loading @@ -1483,7 +1493,35 @@ static void trinity_adjust_uvd_state(struct radeon_device *rdev, } } 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, Loading @@ -1496,6 +1534,7 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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; Loading @@ -1504,6 +1543,14 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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; Loading @@ -1512,6 +1559,17 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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); Loading Loading @@ -1733,6 +1791,19 @@ static int trinity_parse_power_table(struct radeon_device *rdev) 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; } Loading Loading @@ -1914,6 +1985,10 @@ int trinity_dpm_init(struct radeon_device *rdev) 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; Loading Loading @@ -2000,6 +2075,7 @@ void trinity_dpm_fini(struct radeon_device *rdev) } 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) Loading Loading
drivers/gpu/drm/radeon/trinity_dpm.c +76 −0 Original line number Diff line number Diff line Loading @@ -985,6 +985,15 @@ static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev 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)) 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); Loading Loading @@ -1246,6 +1255,7 @@ int trinity_dpm_set_power_state(struct radeon_device *rdev) 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); Loading Loading @@ -1483,7 +1493,35 @@ static void trinity_adjust_uvd_state(struct radeon_device *rdev, } } 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, Loading @@ -1496,6 +1534,7 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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; Loading @@ -1504,6 +1543,14 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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; Loading @@ -1512,6 +1559,17 @@ static void trinity_apply_state_adjust_rules(struct radeon_device *rdev, 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); Loading Loading @@ -1733,6 +1791,19 @@ static int trinity_parse_power_table(struct radeon_device *rdev) 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; } Loading Loading @@ -1914,6 +1985,10 @@ int trinity_dpm_init(struct radeon_device *rdev) 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; Loading Loading @@ -2000,6 +2075,7 @@ void trinity_dpm_fini(struct radeon_device *rdev) } 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) Loading