Commit e1e36485 authored by Rex Zhu's avatar Rex Zhu Committed by Alex Deucher
Browse files

drm/amd/pp: Implement update_smc_table for CI.



driver need to update uvd/vce smc table before enable
uvd/vce dpm.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarRex Zhu <Rex.Zhu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 600ae890
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -2846,6 +2846,89 @@ static int ci_update_dpm_settings(struct pp_hwmgr *hwmgr,
	return 0;
}

static int ci_update_uvd_smc_table(struct pp_hwmgr *hwmgr)
{
	struct amdgpu_device *adev = hwmgr->adev;
	struct smu7_hwmgr *data = hwmgr->backend;
	struct ci_smumgr *smu_data = hwmgr->smu_backend;
	struct phm_uvd_clock_voltage_dependency_table *uvd_table =
			hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
	uint32_t max_vddc = adev->pm.ac_power ? hwmgr->dyn_state.max_clock_voltage_on_ac.vddc :
						hwmgr->dyn_state.max_clock_voltage_on_dc.vddc;
	int32_t i;

	if (PP_CAP(PHM_PlatformCaps_UVDDPM) || uvd_table->count <= 0)
		smu_data->smc_state_table.UvdBootLevel = 0;
	else
		smu_data->smc_state_table.UvdBootLevel = uvd_table->count - 1;

	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, DPM_TABLE_475,
				UvdBootLevel, smu_data->smc_state_table.UvdBootLevel);

	data->dpm_level_enable_mask.uvd_dpm_enable_mask = 0;

	for (i = uvd_table->count - 1; i >= 0; i--) {
		if (uvd_table->entries[i].v <= max_vddc)
			data->dpm_level_enable_mask.uvd_dpm_enable_mask |= 1 << i;
		if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_UVDDPM))
			break;
	}
	ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_UVDDPM_SetEnabledMask,
				data->dpm_level_enable_mask.uvd_dpm_enable_mask);

	return 0;
}

static int ci_update_vce_smc_table(struct pp_hwmgr *hwmgr)
{
	struct amdgpu_device *adev = hwmgr->adev;
	struct smu7_hwmgr *data = hwmgr->backend;
	struct phm_vce_clock_voltage_dependency_table *vce_table =
			hwmgr->dyn_state.vce_clock_voltage_dependency_table;
	uint32_t profile_mode_mask = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD |
					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK |
					AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK |
					AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
	uint32_t max_vddc = adev->pm.ac_power ? hwmgr->dyn_state.max_clock_voltage_on_ac.vddc :
						hwmgr->dyn_state.max_clock_voltage_on_dc.vddc;
	int32_t i;

	PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, DPM_TABLE_475,
				VceBootLevel, 0); /* temp hard code to level 0, vce can set min evclk*/

	data->dpm_level_enable_mask.vce_dpm_enable_mask = 0;

	for (i = vce_table->count - 1; i >= 0; i--) {
		if (vce_table->entries[i].v <= max_vddc)
			data->dpm_level_enable_mask.vce_dpm_enable_mask |= 1 << i;
		if (hwmgr->dpm_level & profile_mode_mask || !PP_CAP(PHM_PlatformCaps_VCEDPM))
			break;
	}
	ci_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_VCEDPM_SetEnabledMask,
				data->dpm_level_enable_mask.vce_dpm_enable_mask);

	return 0;
}

static int ci_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type)
{
	switch (type) {
	case SMU_UVD_TABLE:
		ci_update_uvd_smc_table(hwmgr);
		break;
	case SMU_VCE_TABLE:
		ci_update_vce_smc_table(hwmgr);
		break;
	default:
		break;
	}
	return 0;
}

const struct pp_smumgr_func ci_smu_funcs = {
	.smu_init = ci_smu_init,
	.smu_fini = ci_smu_fini,
@@ -2868,4 +2951,5 @@ const struct pp_smumgr_func ci_smu_funcs = {
	.initialize_mc_reg_table = ci_initialize_mc_reg_table,
	.is_dpm_running = ci_is_dpm_running,
	.update_dpm_settings = ci_update_dpm_settings,
	.update_smc_table = ci_update_smc_table,
};