Add the API to support set soft min or max clock.

Change-Id: Ia34381a721ef3c3d894d5a89d25afa757be46a79
Αυτή η υποβολή περιλαμβάνεται σε:
Bill(Shuzhou) Liu
2024-08-12 08:15:20 -05:00
υποβλήθηκε από Shuzhou Liu
γονέας 78373cb5f7
υποβολή 97e70d44cf
4 αρχεία άλλαξαν με 125 προσθήκες και 0 διαγραφές
@@ -1003,6 +1003,15 @@ typedef enum {
AMDSMI_GPU_BLOCK_RESERVED = 0x8000000000000000
} amdsmi_gpu_block_t;
/**
* @brief The clk limit type
*/
typedef enum {
CLK_LIMIT_MIN,
CLK_LIMIT_MAX
} amdsmi_clk_limit_type_t;
/**
* @brief The current ECC state
*/
@@ -3122,6 +3131,9 @@ amdsmi_status_t amdsmi_get_gpu_reg_table_info(
* @brief This function sets the clock range information. It is not supported on virtual
* machine guest
*
* @deprecated ::amdsmi_set_gpu_clk_limit() should be used, with an
* interface that set the min_value and then max_value.
*
* @platform{gpu_bm_linux}
*
* @details Given a processor handle @p processor_handle, a minimum clock value @p minclkvalue,
@@ -3145,6 +3157,31 @@ amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handl
uint64_t maxclkvalue,
amdsmi_clk_type_t clkType);
/**
* @brief This function sets the clock sets the clock min/max level
*
* @platform{gpu_bm_linux} @platform{guest_1vf}
*
* @details Given a processor handle @p processor_handle, a clock type @p clk_type,
* a value @p clk_value needs to be set, and the @p level indicates min or max
* clock you want to set, this function the clock limit.
*
* @param[in] processor_handle a processor handle
*
* @param[in] clk_type AMDSMI_CLK_TYPE_SYS, AMDSMI_CLK_TYPE_MEM and so on
*
* @param[in] limit_type AMDSMI_FREQ_IND_MIN|AMDSMI_FREQ_IND_MAX to set the
* minimum (0) or maximum (1) speed.
*
* @param[in] clk_value value to apply to. Frequency values are in MHz.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t amdsmi_set_gpu_clk_limit(amdsmi_processor_handle processor_handle,
amdsmi_clk_type_t clk_type,
amdsmi_clk_limit_type_t limit_type,
uint64_t clk_value);
/**
* @brief This function sets the clock frequency information. It is not supported on
* virtual machine guest
@@ -3033,6 +3033,32 @@ rsmi_status_t rsmi_dev_clk_range_set(uint32_t dv_ind, uint64_t minclkvalue,
uint64_t maxclkvalue,
rsmi_clk_type_t clkType);
/**
* @brief This function sets the clock min/max level
*
* @details Given a device index @p dv_ind, a clock value @p minclkvalue,
* a maximum clock value @p maxclkvalue and a clock type @p clkType this function
* will set the sclk|mclk range
*
* @param[in] dv_ind a device index
*
* @param[in] level RSMI_FREQ_IND_MIN|RSMI_FREQ_IND_MAX
*
* @param[in] clkvalue value to apply to the clock level. Frequency values
* are in MHz.
*
* @param[in] clkType RSMI_CLK_TYPE_SYS | RSMI_CLK_TYPE_MEM level type
*
* @retval ::RSMI_STATUS_SUCCESS call was successful
* @retval ::RSMI_STATUS_NOT_SUPPORTED installed software or hardware does not
* support this function with the given arguments
* @retval ::RSMI_STATUS_INVALID_ARGS the provided arguments are not valid
*/
rsmi_status_t rsmi_dev_clk_extremum_set(uint32_t dv_ind, rsmi_freq_ind_t level,
uint64_t clkvalue,
rsmi_clk_type_t clkType);
/**
* @brief This function sets the clock frequency information
*
@@ -1532,6 +1532,58 @@ static rsmi_status_t get_od_clk_volt_info(uint32_t dv_ind,
CATCH
}
rsmi_status_t rsmi_dev_clk_extremum_set(uint32_t dv_ind, rsmi_freq_ind_t level,
uint64_t clkvalue,
rsmi_clk_type_t clkType) {
TRY
rsmi_status_t ret;
std::ostringstream ss;
ss << __PRETTY_FUNCTION__ << "| ======= start =======";
LOG_TRACE(ss);
if (clkType != RSMI_CLK_TYPE_SYS && clkType != RSMI_CLK_TYPE_MEM) {
return RSMI_STATUS_INVALID_ARGS;
}
if (level != RSMI_FREQ_IND_MIN && level != RSMI_FREQ_IND_MAX) {
return RSMI_STATUS_INVALID_ARGS;
}
std::map<rsmi_clk_type_t, std::string> clk_char_map = {
{RSMI_CLK_TYPE_SYS, "s"},
{RSMI_CLK_TYPE_MEM, "m"},
};
DEVICE_MUTEX
// Set perf. level to manual so that we can then set the power profile
ret = rsmi_dev_perf_level_set_v1(dv_ind, RSMI_DEV_PERF_LEVEL_MANUAL);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
// For clock frequency setting, enter a new value by writing a string that
// contains "s/m index clock" to the file. The index should be 0 if to set
// minimum clock. And 1 if to set maximum clock. E.g., "s 0 500" will update
// minimum sclk to be 500 MHz. "m 1 800" will update maximum mclk to 800Mhz.
std::string sysvalue = clk_char_map[clkType];
sysvalue += ' ' + std::to_string(level);
sysvalue += ' ' + std::to_string(clkvalue);
sysvalue += '\n';
ret = set_dev_range(dv_ind, sysvalue);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
ret = set_dev_range(dv_ind, "c");
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
return RSMI_STATUS_SUCCESS;
CATCH
}
rsmi_status_t rsmi_dev_clk_range_set(uint32_t dv_ind, uint64_t minclkvalue,
uint64_t maxclkvalue,
rsmi_clk_type_t clkType) {
@@ -1552,6 +1552,16 @@ amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handl
static_cast<rsmi_clk_type_t>(clkType));
}
amdsmi_status_t amdsmi_set_gpu_clk_limit(amdsmi_processor_handle processor_handle,
amdsmi_clk_type_t clk_type,
amdsmi_clk_limit_type_t limit_type,
uint64_t clk_value) {
return rsmi_wrapper(rsmi_dev_clk_extremum_set, processor_handle,
static_cast<rsmi_freq_ind_t>(limit_type),
clk_value,
static_cast<rsmi_clk_type_t>(clk_type));
}
amdsmi_status_t amdsmi_reset_gpu(amdsmi_processor_handle processor_handle) {
return rsmi_wrapper(rsmi_dev_gpu_reset, processor_handle);
}