Adding setsrange, setmrange, setvc, setslevel and setmlevel functionality to rocm lib and cli
Signed-off-by: Divya Shikre <DivyaUday.Shikre@amd.com>
Change-Id: I5fd65ea7bcd5403aaf2e42d2aa28d837929da253
[ROCm/rocm_smi_lib commit: 54d4b9d500]
This commit is contained in:
committed by
Divya Uday Shikre
parent
e4aff0d37c
commit
31f3b6d33d
@@ -2006,6 +2006,56 @@ rsmi_status_t rsmi_dev_gpu_clk_freq_get(uint32_t dv_ind,
|
||||
rsmi_status_t rsmi_dev_od_volt_info_get(uint32_t dv_ind,
|
||||
rsmi_od_volt_freq_data_t *odv);
|
||||
|
||||
/**
|
||||
* @brief This function sets the clock frequency information
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a frequency level @p level,
|
||||
* a clock value @p clkvalue 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 to set the
|
||||
* minimum (0) or maximum (1) speed.
|
||||
*
|
||||
* @param[in] clkvalue value to apply to the clock range. Frequency values
|
||||
* are in MHz.
|
||||
*
|
||||
* @param[in] clkType RSMI_CLK_TYPE_SYS | RSMI_CLK_TYPE_MEM range 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_od_clk_info_set(uint32_t dv_ind, rsmi_freq_ind_t level,
|
||||
uint64_t clkvalue,
|
||||
rsmi_clk_type_t clkType);
|
||||
|
||||
/**
|
||||
* @brief This function sets 1 of the 3 voltage curve points.
|
||||
*
|
||||
* @details Given a device index @p dv_ind, a voltage point @p vpoint
|
||||
* and a voltage value @p voltvalue this function will set voltage curve point
|
||||
*
|
||||
* @param[in] dv_ind a device index
|
||||
*
|
||||
* @param[in] vpoint voltage point [0|1|2] on the voltage curve
|
||||
*
|
||||
* @param[in] clkvalue clock value component of voltage curve point.
|
||||
* Frequency values are in MHz.
|
||||
*
|
||||
* @param[in] voltvalue voltage value component of voltage curve point.
|
||||
* Voltage is in mV.
|
||||
*
|
||||
* @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_od_volt_info_set(uint32_t dv_ind, uint32_t vpoint,
|
||||
uint64_t clkvalue, uint64_t voltvalue);
|
||||
|
||||
/**
|
||||
* @brief This function will retrieve the current valid regions in the
|
||||
* frequency/voltage space.
|
||||
|
||||
@@ -595,6 +595,122 @@ def resetXgmiErr(deviceList):
|
||||
printLogSpacer()
|
||||
|
||||
|
||||
def setClockRange(deviceList, clkType, level, value, autoRespond):
|
||||
""" Set the range for the specified clktype in the PowerPlay table for a list of devices.
|
||||
|
||||
Parameters:
|
||||
deviceList -- List of DRM devices (can be a single-item list)
|
||||
clktype -- [sclk|mclk] Which clock type to apply the range to
|
||||
level -- [0|1] Whether to set the minimum (0) or maximum (1) speed
|
||||
value -- Value to apply to the clock range
|
||||
autoRespond -- Response to automatically provide for all prompts
|
||||
"""
|
||||
global RETCODE
|
||||
if clkType not in {'sclk', 'mclk'}:
|
||||
printLog(None, 'Invalid range identifier %s' % (clkType), None)
|
||||
RETCODE = 1
|
||||
return
|
||||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
printErrLog(device, 'Unable to set %s range' % (clkType))
|
||||
logging.error('%s is not an integer', value)
|
||||
RETCODE = 1
|
||||
return
|
||||
confirmOutOfSpecWarning(autoRespond)
|
||||
printLogSpacer(' Set Valid %s Range ' % (clkType))
|
||||
for device in deviceList:
|
||||
if clkType == 'sclk':
|
||||
ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(level)), int(value), rsmi_clk_names_dict[clkType])
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set %s level %s to %s(MHz)' % (clkType, level, value), None)
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s level %s to %s(MHz)' % (clkType, level, value))
|
||||
RETCODE = 1
|
||||
elif clkType == 'mclk':
|
||||
ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(level)), int(value), rsmi_clk_names_dict[clkType])
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set %s level %s to %s(MHz)' % (clkType, level, value), None)
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s level %s to %s(MHz)' % (clkType, level, value))
|
||||
RETCODE = 1
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s range' % (clkType))
|
||||
logging.error('Unsupported range type %s', clkType)
|
||||
RETCODE = 1
|
||||
|
||||
|
||||
def setVoltageCurve(deviceList, point, clk, volt, autoRespond):
|
||||
""" Set voltage curve for a point in the PowerPlay table for a list of devices.
|
||||
|
||||
Parameters:
|
||||
deviceList -- List of DRM devices (can be a single-item list)
|
||||
point -- Point on the voltage curve to modify
|
||||
clk -- Clock speed specified for this curve point
|
||||
volt -- Voltage specified for this curve point
|
||||
autoRespond -- Response to automatically provide for all prompts
|
||||
"""
|
||||
global RETCODE
|
||||
value = '%s %s %s' % (point, clk, volt)
|
||||
try:
|
||||
any(int(item) for item in value)
|
||||
except ValueError:
|
||||
printLogNoDev('Unable to set Voltage curve')
|
||||
logging.error('Non-integer characters are present in %s', value)
|
||||
RETCODE = 1
|
||||
return
|
||||
confirmOutOfSpecWarning(autoRespond)
|
||||
for device in deviceList:
|
||||
ret = rocmsmi.rsmi_dev_od_volt_info_set(device, int(point), int(clk), int(volt))
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None)
|
||||
else:
|
||||
printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt))
|
||||
RETCODE = 1
|
||||
|
||||
|
||||
def setPowerPlayTableLevel(deviceList, clkType, point, clk, volt, autoRespond):
|
||||
""" Set clock frequency and voltage for a level in the PowerPlay table for a list of devices.
|
||||
|
||||
Parameters:
|
||||
deviceList -- List of DRM devices (can be a single-item list)
|
||||
clktype -- [sclk|mclk] Which clock type to apply the range to
|
||||
point -- Point on the voltage curve to modify
|
||||
clk -- Clock speed specified for this curve point
|
||||
volt -- Voltage specified for this curve point
|
||||
autoRespond -- Response to automatically provide for all prompts
|
||||
"""
|
||||
global RETCODE
|
||||
value = '%s %s %s' % (point, clk, volt)
|
||||
try:
|
||||
any(int(item) for item in value.split())
|
||||
except ValueError:
|
||||
printLogNoDev('Unable to set PowerPlay table level')
|
||||
logging.error('Non-integer characters are present in %s', value)
|
||||
RETCODE = 1
|
||||
return
|
||||
confirmOutOfSpecWarning(autoRespond)
|
||||
for device in deviceList:
|
||||
if clkType == 'sclk':
|
||||
ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(point)), int(clk), rsmi_clk_names_dict[clkType])
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None)
|
||||
else:
|
||||
printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt))
|
||||
RETCODE = 1
|
||||
elif clkType == 'mclk':
|
||||
ret = rocmsmi.rsmi_dev_od_clk_info_set(device, rsmi_freq_ind_t(int(point)), int(clk), rsmi_clk_names_dict[clkType])
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt), None)
|
||||
else:
|
||||
printErrLog(device, 'Unable to set voltage point %s to %s(MHz) %s(mV)' % (point, clk, volt))
|
||||
RETCODE = 1
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s range' % (clkType))
|
||||
logging.error('Unsupported range type %s', clkType)
|
||||
RETCODE = 1
|
||||
|
||||
|
||||
def setClockOverDrive(deviceList, clktype, value, autoRespond):
|
||||
""" Set clock speed to OverDrive for a list of devices
|
||||
|
||||
@@ -712,12 +828,14 @@ def setClocks(deviceList, clktype, clk):
|
||||
printLog(device, 'Successfully set %s bitmask to' % (clktype), str(bitmask))
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s bitmask to: %s' % (clktype, str(bitmask)))
|
||||
RETCODE = 1
|
||||
else:
|
||||
ret = rocmsmi.rsmi_dev_pci_bandwidth_set(device, freq_bitmask)
|
||||
if rsmi_ret_ok(ret, device):
|
||||
printLog(device, 'Successfully set %s to level bitmask' % (clktype), str(bitmask))
|
||||
else:
|
||||
printErrLog(device, 'Unable to set %s bitmask to: %s' % (clktype, str(bitmask)))
|
||||
RETCODE = 1
|
||||
printLogSpacer()
|
||||
|
||||
|
||||
@@ -2465,12 +2583,9 @@ if __name__ == '__main__':
|
||||
if args.setpcie:
|
||||
setClocks(deviceList, 'pcie', args.setpcie)
|
||||
if args.setslevel:
|
||||
pass
|
||||
# TODO: setPowerPlayTableLevel(deviceList, \'sclk\', args.setslevel, args.autorespond)
|
||||
setPowerPlayTableLevel(deviceList, 'sclk', args.setslevel[0], args.setslevel[1], args.setslevel[2], args.autorespond)
|
||||
if args.setmlevel:
|
||||
pass
|
||||
# TODO: setPowerPlayTableLevel(deviceList, \'mclk\', args.setmlevel, args.autorespond)
|
||||
# Don't do reset in combination with any other command
|
||||
setPowerPlayTableLevel(deviceList, 'mclk', args.setmlevel[0], args.setmlevel[1], args.setmlevel[2], args.autorespond)
|
||||
if args.resetfans:
|
||||
resetFans(deviceList)
|
||||
if args.setfan:
|
||||
@@ -2488,14 +2603,11 @@ if __name__ == '__main__':
|
||||
if args.setprofile:
|
||||
setProfile(deviceList, args.setprofile)
|
||||
if args.setvc:
|
||||
pass
|
||||
# TODO: setVoltageCurve(deviceList, args.setvc[0], args.setvc[1], args.setvc[2], args.autorespond)
|
||||
setVoltageCurve(deviceList, args.setvc[0], args.setvc[1], args.setvc[2], args.autorespond)
|
||||
if args.setsrange:
|
||||
pass
|
||||
# TODO: setClockRange(deviceList, \'sclk\', args.setsrange[0], args.setsrange[1], args.autorespond)
|
||||
setClockRange(deviceList, 'sclk', args.setsrange[0], args.setsrange[1], args.autorespond)
|
||||
if args.setmrange:
|
||||
pass
|
||||
# TODO: setClockRange(deviceList, \'mclk\', args.setmrange[0], args.setmrange[1], args.autorespond)
|
||||
setClockRange(deviceList, 'mclk', args.setmrange[0], args.setmrange[1], args.autorespond)
|
||||
if args.resetprofile:
|
||||
resetProfile(deviceList)
|
||||
if args.resetxgmierr:
|
||||
|
||||
@@ -817,6 +817,15 @@ rsmi_dev_perf_level_set(int32_t dv_ind, rsmi_dev_perf_level_t perf_level) {
|
||||
CATCH
|
||||
}
|
||||
|
||||
static rsmi_status_t
|
||||
set_dev_range(uint32_t dv_ind, std::string range) {
|
||||
|
||||
GET_DEV_FROM_INDX
|
||||
|
||||
int ret = dev->writeDevInfo(amd::smi::kDevPowerODVoltage, range);
|
||||
return amd::smi::ErrnoToRsmiStatus(ret);
|
||||
}
|
||||
|
||||
static rsmi_status_t get_frequencies(amd::smi::DevInfoTypes type,
|
||||
uint32_t dv_ind, rsmi_frequencies_t *f, uint32_t *lanes = nullptr) {
|
||||
TRY
|
||||
@@ -1024,6 +1033,98 @@ static rsmi_status_t get_od_clk_volt_info(uint32_t dv_ind,
|
||||
CATCH
|
||||
}
|
||||
|
||||
|
||||
rsmi_status_t rsmi_dev_od_clk_info_set(uint32_t dv_ind, rsmi_freq_ind_t level,
|
||||
uint64_t clkvalue,
|
||||
rsmi_clk_type_t clkType) {
|
||||
TRY
|
||||
rsmi_status_t ret;
|
||||
|
||||
std::string sysvalue;
|
||||
std::map<rsmi_clk_type_t, std::string> ClkStateMap = {
|
||||
{RSMI_CLK_TYPE_SYS, "s"},
|
||||
{RSMI_CLK_TYPE_MEM, "m"},
|
||||
};
|
||||
|
||||
// Set perf. level to manual so that we can then set the power profile
|
||||
ret = rsmi_dev_perf_level_set(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.
|
||||
|
||||
switch (clkType) {
|
||||
case RSMI_CLK_TYPE_SYS:
|
||||
sysvalue = ClkStateMap[clkType];
|
||||
sysvalue += ' ' + std::to_string(level);
|
||||
sysvalue += ' ' + std::to_string(clkvalue);
|
||||
sysvalue += '\n';
|
||||
break;
|
||||
|
||||
case RSMI_CLK_TYPE_MEM:
|
||||
sysvalue = ClkStateMap[clkType];
|
||||
sysvalue += ' ' + std::to_string(level);
|
||||
sysvalue += ' ' + std::to_string(clkvalue);
|
||||
sysvalue += '\n';
|
||||
break;
|
||||
|
||||
default:
|
||||
return RSMI_STATUS_INVALID_ARGS;
|
||||
}
|
||||
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_od_volt_info_set(uint32_t dv_ind, uint32_t vpoint,
|
||||
uint64_t clkvalue, uint64_t voltvalue) {
|
||||
TRY
|
||||
rsmi_status_t ret;
|
||||
|
||||
// Set perf. level to manual so that we can then set the power profile
|
||||
ret = rsmi_dev_perf_level_set(dv_ind, RSMI_DEV_PERF_LEVEL_MANUAL);
|
||||
if (ret != RSMI_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// For sclk voltage curve, enter the new values by writing a string that
|
||||
// contains “vc point clock voltage” to the file. The points are indexed
|
||||
// by 0, 1 and 2. E.g., “vc 0 300 600” will update point1 with clock set
|
||||
// as 300Mhz and voltage as 600mV. “vc 2 1000 1000” will update point3
|
||||
// with clock set as 1000Mhz and voltage 1000mV.
|
||||
|
||||
std::string sysvalue = "vc";
|
||||
sysvalue += ' ' + std::to_string(vpoint);
|
||||
sysvalue += ' ' + std::to_string(clkvalue);
|
||||
sysvalue += ' ' + std::to_string(voltvalue);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
static void get_vc_region(uint32_t start_ind,
|
||||
std::vector<std::string> *val_vec, rsmi_freq_volt_region_t *p) {
|
||||
assert(p != nullptr);
|
||||
@@ -1092,6 +1193,7 @@ static rsmi_status_t get_od_clk_volt_curve_regions(uint32_t dv_ind,
|
||||
return RSMI_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
static rsmi_status_t set_power_profile(uint32_t dv_ind,
|
||||
rsmi_power_profile_preset_masks_t profile) {
|
||||
TRY
|
||||
|
||||
@@ -364,6 +364,8 @@ static const std::map<const char *, dev_depends_t> kDevFuncDependsMap = {
|
||||
{"rsmi_dev_overdrive_level_set", {{kDevOverDriveLevelFName}, {}}},
|
||||
{"rsmi_dev_vbios_version_get", {{kDevVBiosVerFName}, {}}},
|
||||
{"rsmi_dev_od_volt_info_get", {{kDevPowerODVoltageFName}, {}}},
|
||||
{"rsmi_dev_od_volt_info_set", {{kDevPowerODVoltageFName,
|
||||
kDevPerfLevelFName}, {}}},
|
||||
{"rsmi_dev_od_volt_curve_regions_get", {{kDevPowerODVoltageFName}, {}}},
|
||||
{"rsmi_dev_ecc_enabled_get", {{kDevErrCntFeaturesFName}, {}}},
|
||||
{"rsmi_dev_ecc_status_get", {{kDevErrCntFeaturesFName}, {}}},
|
||||
@@ -571,6 +573,7 @@ int Device::writeDevInfo(DevInfoTypes type, uint64_t val) {
|
||||
switch (type) {
|
||||
// The caller is responsible for making sure "val" is within a valid range
|
||||
case kDevOverDriveLevel: // integer between 0 and 20
|
||||
case kDevPowerODVoltage:
|
||||
case kDevPowerProfileMode:
|
||||
return writeDevInfoStr(type, std::to_string(val));
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user