Re: [PATCH v2] drm/amdgpu: Update driver if header for SMU V15.0.5

Mario Limonciello <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>

On 7/21/26 11:44, Kanala Ramalingeswara Reddy wrote:
> Update smu v15.0.0 driver if header to be v15.0.5 compatible.
> 
> Signed-off-by: Kanala Ramalingeswara Reddy <[email protected]>
> ---
>   .../inc/pmfw_if/smu15_driver_if_v15_0_0.h     |  38 +++
>   drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h  |   2 +-
>   .../drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c  | 220 +++++++++++++++++-
>   3 files changed, 253 insertions(+), 7 deletions(-)
> 
Reviewed-by: Mario Limonciello (AMD) <[email protected]>
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu15_driver_if_v15_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu15_driver_if_v15_0_0.h
> index 47ddf533b08f..a5d3e8d88860 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu15_driver_if_v15_0_0.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu15_driver_if_v15_0_0.h
> @@ -144,6 +144,44 @@ typedef struct {
>     uint32_t MaxGfxClk;
>   } DpmClocks_t;
>   
> +//Freq in MHz
> +//Voltage in milli volts with 2 fractional bits
> +typedef struct {
> +	uint32_t DcfClocks[NUM_DCFCLK_DPM_LEVELS];
> +	uint32_t DispClocks[NUM_DISPCLK_DPM_LEVELS];
> +	uint32_t DppClocks[NUM_DPPCLK_DPM_LEVELS];
> +	uint32_t SocClocks[NUM_SOCCLK_DPM_LEVELS];
> +
> +	uint32_t VPEClocks[NUM_VPE_DPM_LEVELS];
> +	uint32_t FclkClocks_Freq[NUM_FCLK_DPM_LEVELS];
> +	uint32_t FclkClocks_Voltage[NUM_FCLK_DPM_LEVELS];
> +	uint32_t SocVoltage[NUM_SOC_VOLTAGE_LEVELS];
> +	MemPstateTable_t MemPstateTable[NUM_MEM_PSTATE_LEVELS];
> +
> +	uint8_t  NumDcfClkLevelsEnabled;
> +	uint8_t  NumDispClkLevelsEnabled; //Applies to both Dispclk and Dppclk
> +	uint8_t  NumSocClkLevelsEnabled;
> +
> +	uint8_t  VpeClkLevelsEnabled;
> +
> +	uint8_t  NumMemPstatesEnabled;
> +	uint8_t  NumFclkLevelsEnabled;
> +	uint8_t  Spare1;
> +	uint8_t  Spare2;
> +
> +	uint8_t  Spare3;
> +	uint8_t  Spare4;
> +	uint8_t  Spare5[2];
> +
> +	uint32_t MinGfxClk;
> +	uint32_t MaxGfxClk;
> +
> +	uint32_t Spare6[8];
> +	uint32_t Spare7[8];
> +	uint32_t Spare8[8];
> +	uint32_t Spare9[8];
> +} DpmClocks_t_v15_0_5;
> +
>   typedef struct {
>     uint16_t CoreFrequency[16];          //Target core frequency [MHz]
>     uint16_t CorePower[16];              //CAC calculated core power [mW]
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
> index 13723d45a7de..38e625cda97d 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
> +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h
> @@ -26,7 +26,7 @@
>   #include "amdgpu_smu.h"
>   
>   #define SMU15_DRIVER_IF_VERSION_INV 0xFFFFFFFF
> -#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x7
> +#define SMU15_DRIVER_IF_VERSION_SMU_V15_0 0x9
>   
>   
>   #define FEATURE_MASK(feature) (1ULL << feature)
> diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
> index bb8d09e73c7d..faa7d661f3bf 100644
> --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
> +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c
> @@ -168,7 +168,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
>   
>   	SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
>   		PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
> -	SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
> +	SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t_v15_0_5),
>   		PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
>   	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
>   		PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
> @@ -178,7 +178,7 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu)
>   		goto err0_out;
>   	smu_table->metrics_time = 0;
>   
> -	smu_table->clocks_table = kzalloc_obj(DpmClocks_t);
> +	smu_table->clocks_table = kzalloc_obj(DpmClocks_t_v15_0_5);
>   	if (!smu_table->clocks_table)
>   		goto err1_out;
>   
> @@ -752,11 +752,48 @@ static int smu_v15_0_0_get_dpm_freq_by_index(struct smu_context *smu,
>   	return 0;
>   }
>   
> +static int smu_v15_0_5_get_dpm_freq_by_index(struct smu_context *smu,
> +						enum smu_clk_type clk_type,
> +						uint32_t dpm_level,
> +						uint32_t *freq)
> +{
> +	DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
> +
> +	if (!clk_table || clk_type >= SMU_CLK_COUNT)
> +		return -EINVAL;
> +
> +	switch (clk_type) {
> +	case SMU_SOCCLK:
> +		if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
> +			return -EINVAL;
> +		*freq = clk_table->SocClocks[dpm_level];
> +		break;
> +	case SMU_UCLK:
> +	case SMU_MCLK:
> +		if (dpm_level >= clk_table->NumMemPstatesEnabled)
> +			return -EINVAL;
> +		*freq = clk_table->MemPstateTable[dpm_level].MemClk;
> +		break;
> +	case SMU_FCLK:
> +		if (dpm_level >= clk_table->NumFclkLevelsEnabled)
> +			return -EINVAL;
> +		*freq = clk_table->FclkClocks_Freq[dpm_level];
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>   static int smu_v15_0_common_get_dpm_freq_by_index(struct smu_context *smu,
>   						enum smu_clk_type clk_type,
>   						uint32_t dpm_level,
>   						uint32_t *freq)
>   {
> +	if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
> +		smu_v15_0_5_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
> +	else
>   		smu_v15_0_0_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
>   
>   	return 0;
> @@ -907,12 +944,116 @@ static int smu_v15_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
>   	return ret;
>   }
>   
> +static int smu_v15_0_5_get_dpm_ultimate_freq(struct smu_context *smu,
> +							enum smu_clk_type clk_type,
> +							uint32_t *min,
> +							uint32_t *max)
> +{
> +	DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
> +	uint32_t clock_limit;
> +	uint32_t max_dpm_level, min_dpm_level;
> +	int ret = 0;
> +
> +	if (!smu_v15_0_0_clk_dpm_is_enabled(smu, clk_type)) {
> +		switch (clk_type) {
> +		case SMU_MCLK:
> +		case SMU_UCLK:
> +			clock_limit = smu->smu_table.boot_values.uclk;
> +			break;
> +		case SMU_FCLK:
> +			clock_limit = smu->smu_table.boot_values.fclk;
> +			break;
> +		case SMU_GFXCLK:
> +		case SMU_SCLK:
> +			clock_limit = smu->smu_table.boot_values.gfxclk;
> +			break;
> +		case SMU_SOCCLK:
> +			clock_limit = smu->smu_table.boot_values.socclk;
> +			break;
> +		default:
> +			clock_limit = 0;
> +			break;
> +		}
> +
> +		/* clock in Mhz unit */
> +		if (min)
> +			*min = clock_limit / 100;
> +		if (max)
> +			*max = clock_limit / 100;
> +
> +		return 0;
> +	}
> +
> +	if (max) {
> +		switch (clk_type) {
> +		case SMU_GFXCLK:
> +		case SMU_SCLK:
> +			*max = clk_table->MaxGfxClk;
> +			break;
> +		case SMU_MCLK:
> +		case SMU_UCLK:
> +			max_dpm_level = 0;
> +			break;
> +		case SMU_FCLK:
> +			max_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
> +			break;
> +		case SMU_SOCCLK:
> +			max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			goto failed;
> +		}
> +
> +		if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
> +			ret = smu_v15_0_common_get_dpm_freq_by_index(smu, clk_type,
> +				max_dpm_level, max);
> +			if (ret)
> +				goto failed;
> +		}
> +	}
> +
> +	if (min) {
> +		switch (clk_type) {
> +		case SMU_GFXCLK:
> +		case SMU_SCLK:
> +			*min = clk_table->MinGfxClk;
> +			break;
> +		case SMU_MCLK:
> +		case SMU_UCLK:
> +			min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
> +			break;
> +		case SMU_FCLK:
> +			min_dpm_level = 0;
> +			break;
> +		case SMU_SOCCLK:
> +			min_dpm_level = 0;
> +			break;
> +		default:
> +			ret = -EINVAL;
> +			goto failed;
> +		}
> +
> +		if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
> +			ret = smu_v15_0_common_get_dpm_freq_by_index(smu, clk_type,
> +				min_dpm_level, min);
> +			if (ret)
> +				goto failed;
> +		}
> +	}
> +
> +failed:
> +	return ret;
> +}
> +
>   static int smu_v15_0_common_get_dpm_ultimate_freq(struct smu_context *smu,
>   							enum smu_clk_type clk_type,
>   							uint32_t *min,
>   							uint32_t *max)
>   {
> -	if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
> +	if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
> +		smu_v15_0_5_get_dpm_ultimate_freq(smu, clk_type, min, max);
> +	else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
>   		smu_v15_0_0_get_dpm_ultimate_freq(smu, clk_type, min, max);
>   
>   	return 0;
> @@ -986,11 +1127,36 @@ static int smu_v15_0_0_get_dpm_level_count(struct smu_context *smu,
>   	return 0;
>   }
>   
> +static int smu_v15_0_5_get_dpm_level_count(struct smu_context *smu,
> +					   enum smu_clk_type clk_type,
> +					   uint32_t *count)
> +{
> +	DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
> +
> +	switch (clk_type) {
> +	case SMU_SOCCLK:
> +		*count = clk_table->NumSocClkLevelsEnabled;
> +		break;
> +	case SMU_MCLK:
> +		*count = clk_table->NumMemPstatesEnabled;
> +		break;
> +	case SMU_FCLK:
> +		*count = clk_table->NumFclkLevelsEnabled;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>   static int smu_v15_0_common_get_dpm_level_count(struct smu_context *smu,
>   					   enum smu_clk_type clk_type,
>   					   uint32_t *count)
>   {
> -	if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
> +	if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
> +		smu_v15_0_5_get_dpm_level_count(smu, clk_type, count);
> +	else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
>   		smu_v15_0_0_get_dpm_level_count(smu, clk_type, count);
>   
>   	return 0;
> @@ -1363,9 +1529,24 @@ static int smu_v15_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *sm
>   	return 0;
>   }
>   
> +static int smu_v15_0_5_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
> +{
> +	DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
> +
> +	smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
> +	smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
> +	smu->gfx_actual_hard_min_freq = 0;
> +	smu->gfx_actual_soft_max_freq = 0;
> +
> +	return 0;
> +}
> +
>   static int smu_v15_0_common_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
>   {
> -	smu_v15_0_0_set_fine_grain_gfx_freq_parameters(smu);
> +	if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
> +		smu_v15_0_5_set_fine_grain_gfx_freq_parameters(smu);
> +	else
> +		smu_v15_0_0_set_fine_grain_gfx_freq_parameters(smu);
>   
>   	return 0;
>   }
> @@ -1405,9 +1586,36 @@ static int smu_v15_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks
>   	return 0;
>   }
>   
> +static int smu_v15_0_5_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
> +{
> +	DpmClocks_t_v15_0_5 *clk_table = smu->smu_table.clocks_table;
> +	uint8_t idx;
> +
> +	/*
> +	 * Only the Clock information of SOC and
> +	 * VPE is copied to provide VPE DPM settings for use.
> +	 */
> +	for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
> +		clock_table->SocClocks[idx].Freq =
> +			(idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
> +		clock_table->SocClocks[idx].Vol = 0;
> +	}
> +
> +	for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
> +		clock_table->VPEClocks[idx].Freq =
> +			(idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
> +		clock_table->VPEClocks[idx].Vol = 0;
> +	}
> +
> +	return 0;
> +}
> +
>   static int smu_v15_0_common_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
>   {
> -	smu_v15_0_0_get_dpm_table(smu, clock_table);
> +	if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(15, 0, 5))
> +		smu_v15_0_5_get_dpm_table(smu, clock_table);
> +	else
> +		smu_v15_0_0_get_dpm_table(smu, clock_table);
>   
>   	return 0;
>   }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.