diff options
Diffstat (limited to 'drivers/gpu/drm/amd/pm')
101 files changed, 8285 insertions, 2231 deletions
diff --git a/drivers/gpu/drm/amd/pm/Makefile b/drivers/gpu/drm/amd/pm/Makefile index 51751db436b0..ebbf188f625c 100644 --- a/drivers/gpu/drm/amd/pm/Makefile +++ b/drivers/gpu/drm/amd/pm/Makefile @@ -30,6 +30,7 @@ subdir-ccflags-y += \ -I$(FULL_AMD_PATH)/pm/swsmu/smu11 \ -I$(FULL_AMD_PATH)/pm/swsmu/smu12 \ -I$(FULL_AMD_PATH)/pm/swsmu/smu13 \ + -I$(FULL_AMD_PATH)/pm/swsmu/smu14 \ -I$(FULL_AMD_PATH)/pm/powerplay/inc \ -I$(FULL_AMD_PATH)/pm/powerplay/smumgr\ -I$(FULL_AMD_PATH)/pm/powerplay/hwmgr \ diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 078aaaa53162..8ec11da0319f 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -93,6 +93,7 @@ int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block case AMD_IP_BLOCK_TYPE_JPEG: case AMD_IP_BLOCK_TYPE_GMC: case AMD_IP_BLOCK_TYPE_ACP: + case AMD_IP_BLOCK_TYPE_VPE: if (pp_funcs && pp_funcs->set_powergating_by_smu) ret = (pp_funcs->set_powergating_by_smu( (adev)->powerplay.pp_handle, block_type, gate)); @@ -180,6 +181,24 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, return ret; } +int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en) +{ + int ret = 0; + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + + if (pp_funcs && pp_funcs->notify_rlc_state) { + mutex_lock(&adev->pm.mutex); + + ret = pp_funcs->notify_rlc_state( + adev->powerplay.pp_handle, + en); + + mutex_unlock(&adev->pm.mutex); + } + + return ret; +} + bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; @@ -351,14 +370,43 @@ int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev, return ret; } -int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en) +int amdgpu_dpm_get_xgmi_plpd_mode(struct amdgpu_device *adev, char **mode_desc) { struct smu_context *smu = adev->powerplay.pp_handle; - int ret = 0; + int mode = XGMI_PLPD_NONE; + + if (is_support_sw_smu(adev)) { + mode = smu->plpd_mode; + if (mode_desc == NULL) + return mode; + switch (smu->plpd_mode) { + case XGMI_PLPD_DISALLOW: + *mode_desc = "disallow"; + break; + case XGMI_PLPD_DEFAULT: + *mode_desc = "default"; + break; + case XGMI_PLPD_OPTIMIZED: + *mode_desc = "optimized"; + break; + case XGMI_PLPD_NONE: + default: + *mode_desc = "none"; + break; + } + } + + return mode; +} + +int amdgpu_dpm_set_xgmi_plpd_mode(struct amdgpu_device *adev, int mode) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + int ret = -EOPNOTSUPP; if (is_support_sw_smu(adev)) { mutex_lock(&adev->pm.mutex); - ret = smu_allow_xgmi_power_down(smu, en); + ret = smu_set_xgmi_plpd_mode(smu, mode); mutex_unlock(&adev->pm.mutex); } @@ -461,7 +509,7 @@ int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors senso int amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device *adev, uint32_t *limit) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - int ret = -EINVAL; + int ret = -EOPNOTSUPP; if (pp_funcs && pp_funcs->get_apu_thermal_limit) { mutex_lock(&adev->pm.mutex); @@ -475,7 +523,7 @@ int amdgpu_dpm_get_apu_thermal_limit(struct amdgpu_device *adev, uint32_t *limit int amdgpu_dpm_set_apu_thermal_limit(struct amdgpu_device *adev, uint32_t limit) { const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; - int ret = -EINVAL; + int ret = -EOPNOTSUPP; if (pp_funcs && pp_funcs->set_apu_thermal_limit) { mutex_lock(&adev->pm.mutex); @@ -1152,7 +1200,7 @@ int amdgpu_dpm_get_sclk_od(struct amdgpu_device *adev) int ret = 0; if (!pp_funcs->get_sclk_od) - return 0; + return -EOPNOTSUPP; mutex_lock(&adev->pm.mutex); ret = pp_funcs->get_sclk_od(adev->powerplay.pp_handle); @@ -1166,7 +1214,7 @@ int amdgpu_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value) const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; if (is_support_sw_smu(adev)) - return 0; + return -EOPNOTSUPP; mutex_lock(&adev->pm.mutex); if (pp_funcs->set_sclk_od) @@ -1189,7 +1237,7 @@ int amdgpu_dpm_get_mclk_od(struct amdgpu_device *adev) int ret = 0; if (!pp_funcs->get_mclk_od) - return 0; + return -EOPNOTSUPP; mutex_lock(&adev->pm.mutex); ret = pp_funcs->get_mclk_od(adev->powerplay.pp_handle); @@ -1203,7 +1251,7 @@ int amdgpu_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value) const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; if (is_support_sw_smu(adev)) - return 0; + return -EOPNOTSUPP; mutex_lock(&adev->pm.mutex); if (pp_funcs->set_mclk_od) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 9ef88a0b1b57..49028dde0f87 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -35,6 +35,44 @@ #include <linux/pm_runtime.h> #include <asm/processor.h> +#define MAX_NUM_OF_FEATURES_PER_SUBSET 8 +#define MAX_NUM_OF_SUBSETS 8 + +struct od_attribute { + struct kobj_attribute attribute; + struct list_head entry; +}; + +struct od_kobj { + struct kobject kobj; + struct list_head entry; + struct list_head attribute; + void *priv; +}; + +struct od_feature_ops { + umode_t (*is_visible)(struct amdgpu_device *adev); + ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +}; + +struct od_feature_item { + const char *name; + struct od_feature_ops ops; +}; + +struct od_feature_container { + char *name; + struct od_feature_ops ops; + struct od_feature_item sub_feature[MAX_NUM_OF_FEATURES_PER_SUBSET]; +}; + +struct od_feature_set { + struct od_feature_container containers[MAX_NUM_OF_SUBSETS]; +}; + static const struct hwmon_temp_label { enum PP_HWMON_TEMP channel; const char *label; @@ -643,18 +681,14 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, * They can be used to calibrate the sclk voltage curve. This is * available for Vega20 and NV1X. * - * - voltage offset for the six anchor points of the v/f curve labeled - * OD_VDDC_CURVE. They can be used to calibrate the v/f curve. This - * is only availabe for some SMU13 ASICs. - * * - voltage offset(in mV) applied on target voltage calculation. - * This is available for Sienna Cichlid, Navy Flounder and Dimgrey - * Cavefish. For these ASICs, the target voltage calculation can be - * illustrated by "voltage = voltage calculated from v/f curve + - * overdrive vddgfx offset" + * This is available for Sienna Cichlid, Navy Flounder, Dimgrey + * Cavefish and some later SMU13 ASICs. For these ASICs, the target + * voltage calculation can be illustrated by "voltage = voltage + * calculated from v/f curve + overdrive vddgfx offset" * - * - a list of valid ranges for sclk, mclk, and voltage curve points - * labeled OD_RANGE + * - a list of valid ranges for sclk, mclk, voltage curve points + * or voltage offset labeled OD_RANGE * * < For APUs > * @@ -686,24 +720,17 @@ static ssize_t amdgpu_set_pp_table(struct device *dev, * E.g., "p 2 0 800" would set the minimum core clock on core * 2 to 800Mhz. * - * For sclk voltage curve, - * - For NV1X, 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. - * - For SMU13 ASICs, enter the new values by writing a string that - * contains "vc anchor_point_index voltage_offset" to the file. - * There are total six anchor points defined on the v/f curve with - * index as 0 - 5. - * - "vc 0 10" will update the voltage offset for point1 as 10mv. - * - "vc 5 -10" will update the voltage offset for point6 as -10mv. - * - * To update the voltage offset applied for gfxclk/voltage calculation, - * enter the new value by writing a string that contains "vo offset". - * This is supported by Sienna Cichlid, Navy Flounder and Dimgrey Cavefish. - * And the offset can be a positive or negative value. + * For sclk voltage curve supported by Vega20 and NV1X, 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. + * + * For voltage offset supported by Sienna Cichlid, Navy Flounder, Dimgrey + * Cavefish and some later SMU13 ASICs, enter the new value by writing a + * string that contains "vo offset". E.g., "vo -10" will update the extra + * voltage offset applied to the whole v/f curve line as -10mv. * * - When you have edited all of the states as needed, write "c" (commit) * to the file to commit your changes @@ -734,7 +761,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, if (adev->in_suspend && !adev->in_runpm) return -EPERM; - if (count > 127) + if (count > 127 || count == 0) return -EINVAL; if (*buf == 's') @@ -743,7 +770,7 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, type = PP_OD_EDIT_CCLK_VDDC_TABLE; else if (*buf == 'm') type = PP_OD_EDIT_MCLK_VDDC_TABLE; - else if(*buf == 'r') + else if (*buf == 'r') type = PP_OD_RESTORE_DEFAULT_TABLE; else if (*buf == 'c') type = PP_OD_COMMIT_DPM_TABLE; @@ -754,7 +781,8 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, else return -EINVAL; - memcpy(buf_cpy, buf, count+1); + memcpy(buf_cpy, buf, count); + buf_cpy[count] = 0; tmp_str = buf_cpy; @@ -771,6 +799,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev, return -EINVAL; parameter_size++; + if (!tmp_str) + break; + while (isspace(*tmp_str)) tmp_str++; } @@ -956,7 +987,16 @@ static ssize_t amdgpu_get_pp_features(struct device *dev, * pp_dpm_fclk interface is only available for Vega20 and later ASICs. * * Reading back the files will show you the available power levels within - * the power state and the clock information for those levels. + * the power state and the clock information for those levels. If deep sleep is + * applied to a clock, the level will be denoted by a special level 'S:' + * E.g., :: + * + * S: 19Mhz * + * 0: 615Mhz + * 1: 800Mhz + * 2: 888Mhz + * 3: 1000Mhz + * * * To manually adjust these states, first select manual using * power_dpm_force_performance_level. @@ -1467,6 +1507,32 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev, return -EINVAL; } +static int amdgpu_hwmon_get_sensor_generic(struct amdgpu_device *adev, + enum amd_pp_sensors sensor, + void *query) +{ + int r, size = sizeof(uint32_t); + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + r = pm_runtime_get_sync(adev_to_drm(adev)->dev); + if (r < 0) { + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + return r; + } + + /* get the sensor value */ + r = amdgpu_dpm_read_sensor(adev, sensor, query, &size); + + pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); + pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + + return r; +} + /** * DOC: gpu_busy_percent * @@ -1481,26 +1547,10 @@ static ssize_t amdgpu_get_gpu_busy_percent(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); - int r, value, size = sizeof(value); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - /* read the IP busy sensor */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, - (void *)&value, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); + unsigned int value; + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_LOAD, &value); if (r) return r; @@ -1521,26 +1571,10 @@ static ssize_t amdgpu_get_mem_busy_percent(struct device *dev, { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); - int r, value, size = sizeof(value); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - /* read the IP busy sensor */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_LOAD, - (void *)&value, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); + unsigned int value; + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_LOAD, &value); if (r) return r; @@ -1814,45 +1848,15 @@ out: return size; } -static int amdgpu_device_read_powershift(struct amdgpu_device *adev, - uint32_t *ss_power, bool dgpu_share) -{ - struct drm_device *ddev = adev_to_drm(adev); - uint32_t size; - int r = 0; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(ddev->dev); - if (r < 0) { - pm_runtime_put_autosuspend(ddev->dev); - return r; - } - - if (dgpu_share) - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, - (void *)ss_power, &size); - else - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, - (void *)ss_power, &size); - - pm_runtime_mark_last_busy(ddev->dev); - pm_runtime_put_autosuspend(ddev->dev); - return r; -} - static int amdgpu_show_powershift_percent(struct device *dev, - char *buf, bool dgpu_share) + char *buf, enum amd_pp_sensors sensor) { struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); uint32_t ss_power; int r = 0, i; - r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power); if (r == -EOPNOTSUPP) { /* sensor not available on dGPU, try to read from APU */ adev = NULL; @@ -1865,14 +1869,15 @@ static int amdgpu_show_powershift_percent(struct device *dev, } mutex_unlock(&mgpu_info.mutex); if (adev) - r = amdgpu_device_read_powershift(adev, &ss_power, dgpu_share); + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&ss_power); } - if (!r) - r = sysfs_emit(buf, "%u%%\n", ss_power); + if (r) + return r; - return r; + return sysfs_emit(buf, "%u%%\n", ss_power); } + /** * DOC: smartshift_apu_power * @@ -1886,7 +1891,7 @@ static int amdgpu_show_powershift_percent(struct device *dev, static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device_attribute *attr, char *buf) { - return amdgpu_show_powershift_percent(dev, buf, false); + return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_APU_SHARE); } /** @@ -1902,7 +1907,7 @@ static ssize_t amdgpu_get_smartshift_apu_power(struct device *dev, struct device static ssize_t amdgpu_get_smartshift_dgpu_power(struct device *dev, struct device_attribute *attr, char *buf) { - return amdgpu_show_powershift_percent(dev, buf, true); + return amdgpu_show_powershift_percent(dev, buf, AMDGPU_PP_SENSOR_SS_DGPU_SHARE); } /** @@ -1965,7 +1970,6 @@ out: return r; } - static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) { @@ -1978,20 +1982,84 @@ static int ss_power_attr_update(struct amdgpu_device *adev, struct amdgpu_device static int ss_bias_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) { - uint32_t ss_power, size; + uint32_t ss_power; if (!amdgpu_device_supports_smart_shift(adev_to_drm(adev))) *states = ATTR_STATE_UNSUPPORTED; - else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, - (void *)&ss_power, &size)) + else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_APU_SHARE, + (void *)&ss_power)) *states = ATTR_STATE_UNSUPPORTED; - else if (amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, - (void *)&ss_power, &size)) + else if (amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_SS_DGPU_SHARE, + (void *)&ss_power)) *states = ATTR_STATE_UNSUPPORTED; return 0; } +/* Following items will be read out to indicate current plpd policy: + * - -1: none + * - 0: disallow + * - 1: default + * - 2: optimized + */ +static ssize_t amdgpu_get_xgmi_plpd_policy(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + char *mode_desc = "none"; + int mode; + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + mode = amdgpu_dpm_get_xgmi_plpd_mode(adev, &mode_desc); + + return sysfs_emit(buf, "%d: %s\n", mode, mode_desc); +} + +/* Following argument value is expected from user to change plpd policy + * - arg 0: disallow plpd + * - arg 1: default policy + * - arg 2: optimized policy + */ +static ssize_t amdgpu_set_xgmi_plpd_policy(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + int mode, ret; + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + ret = kstrtos32(buf, 0, &mode); + if (ret) + return -EINVAL; + + ret = pm_runtime_get_sync(ddev->dev); + if (ret < 0) { + pm_runtime_put_autosuspend(ddev->dev); + return ret; + } + + ret = amdgpu_dpm_set_xgmi_plpd_mode(adev, mode); + + pm_runtime_mark_last_busy(ddev->dev); + pm_runtime_put_autosuspend(ddev->dev); + + if (ret) + return ret; + + return count; +} + static struct amdgpu_device_attr amdgpu_device_attrs[] = { AMDGPU_DEVICE_ATTR_RW(power_dpm_state, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), AMDGPU_DEVICE_ATTR_RW(power_dpm_force_performance_level, ATTR_FLAG_BASIC|ATTR_FLAG_ONEVF), @@ -2027,14 +2095,15 @@ static struct amdgpu_device_attr amdgpu_device_attrs[] = { .attr_update = ss_power_attr_update), AMDGPU_DEVICE_ATTR_RW(smartshift_bias, ATTR_FLAG_BASIC, .attr_update = ss_bias_attr_update), + AMDGPU_DEVICE_ATTR_RW(xgmi_plpd_policy, ATTR_FLAG_BASIC), }; static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) { struct device_attribute *dev_attr = &attr->dev_attr; - uint32_t mp1_ver = adev->ip_versions[MP1_HWIP][0]; - uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; + uint32_t mp1_ver = amdgpu_ip_version(adev, MP1_HWIP, 0); + uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0); const char *attr_name = dev_attr->attr.name; if (!(attr->flags & mask)) { @@ -2049,8 +2118,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dcefclk)) { if (gc_ver < IP_VERSION(9, 0, 0) || - gc_ver == IP_VERSION(9, 4, 1) || - gc_ver == IP_VERSION(9, 4, 2)) + !amdgpu_device_has_display_hardware(adev)) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_fclk)) { if (mp1_ver < IP_VERSION(10, 0, 0)) @@ -2077,6 +2145,7 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 2): + case IP_VERSION(11, 0, 3): *states = ATTR_STATE_SUPPORTED; break; default: @@ -2096,7 +2165,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || gc_ver == IP_VERSION(11, 0, 2) || - gc_ver == IP_VERSION(11, 0, 3))) + gc_ver == IP_VERSION(11, 0, 3) || + gc_ver == IP_VERSION(9, 4, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_vclk1)) { if (!((gc_ver == IP_VERSION(10, 3, 1) || @@ -2110,7 +2180,8 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ gc_ver == IP_VERSION(10, 1, 2) || gc_ver == IP_VERSION(11, 0, 0) || gc_ver == IP_VERSION(11, 0, 2) || - gc_ver == IP_VERSION(11, 0, 3))) + gc_ver == IP_VERSION(11, 0, 3) || + gc_ver == IP_VERSION(9, 4, 3))) *states = ATTR_STATE_UNSUPPORTED; } else if (DEVICE_ATTR_IS(pp_dpm_dclk1)) { if (!((gc_ver == IP_VERSION(10, 3, 1) || @@ -2121,7 +2192,27 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ } else if (DEVICE_ATTR_IS(pp_power_profile_mode)) { if (amdgpu_dpm_get_power_profile_mode(adev, NULL) == -EOPNOTSUPP) *states = ATTR_STATE_UNSUPPORTED; - else if (gc_ver == IP_VERSION(10, 3, 0) && amdgpu_sriov_vf(adev)) + else if ((gc_ver == IP_VERSION(10, 3, 0) || + gc_ver == IP_VERSION(11, 0, 3)) && amdgpu_sriov_vf(adev)) + *states = ATTR_STATE_UNSUPPORTED; + } else if (DEVICE_ATTR_IS(xgmi_plpd_policy)) { + if (amdgpu_dpm_get_xgmi_plpd_mode(adev, NULL) == XGMI_PLPD_NONE) + *states = ATTR_STATE_UNSUPPORTED; + } else if (DEVICE_ATTR_IS(pp_mclk_od)) { + if (amdgpu_dpm_get_mclk_od(adev) == -EOPNOTSUPP) + *states = ATTR_STATE_UNSUPPORTED; + } else if (DEVICE_ATTR_IS(pp_sclk_od)) { + if (amdgpu_dpm_get_sclk_od(adev) == -EOPNOTSUPP) + *states = ATTR_STATE_UNSUPPORTED; + } else if (DEVICE_ATTR_IS(apu_thermal_cap)) { + u32 limit; + + if (amdgpu_dpm_get_apu_thermal_limit(adev, &limit) == + -EOPNOTSUPP) + *states = ATTR_STATE_UNSUPPORTED; + } else if (DEVICE_ATTR_IS(pp_dpm_pcie)) { + if (gc_ver == IP_VERSION(9, 4, 2) || + gc_ver == IP_VERSION(9, 4, 3)) *states = ATTR_STATE_UNSUPPORTED; } @@ -2172,15 +2263,19 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev, uint32_t mask, struct list_head *attr_list) { int ret = 0; - struct device_attribute *dev_attr = &attr->dev_attr; - const char *name = dev_attr->attr.name; enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED; struct amdgpu_device_attr_entry *attr_entry; + struct device_attribute *dev_attr; + const char *name; int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update; - BUG_ON(!attr); + if (!attr) + return -EINVAL; + + dev_attr = &attr->dev_attr; + name = dev_attr->attr.name; attr_update = attr->attr_update ? attr->attr_update : default_attr_update; @@ -2266,46 +2361,32 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); int channel = to_sensor_dev_attr(attr)->index; - int r, temp = 0, size = sizeof(temp); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; + int r, temp = 0; if (channel >= PP_TEMP_MAX) return -EINVAL; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - switch (channel) { case PP_TEMP_JUNCTION: /* get current junction temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_HOTSPOT_TEMP, + (void *)&temp); break; case PP_TEMP_EDGE: /* get current edge temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_EDGE_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_EDGE_TEMP, + (void *)&temp); break; case PP_TEMP_MEM: /* get current memory temperature */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_TEMP, - (void *)&temp, &size); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MEM_TEMP, + (void *)&temp); break; default: r = -EINVAL; break; } - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - if (r) return r; @@ -2589,25 +2670,10 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 min_rpm = 0; - u32 size = sizeof(min_rpm); int r; - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM, - (void *)&min_rpm, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM, + (void *)&min_rpm); if (r) return r; @@ -2621,25 +2687,10 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 max_rpm = 0; - u32 size = sizeof(max_rpm); int r; - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM, - (void *)&max_rpm, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM, + (void *)&max_rpm); if (r) return r; @@ -2801,26 +2852,11 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 vddgfx; - int r, size = sizeof(vddgfx); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, - (void *)&vddgfx, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDGFX, + (void *)&vddgfx); if (r) return r; @@ -2840,30 +2876,15 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); u32 vddnb; - int r, size = sizeof(vddnb); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; + int r; /* only APUs have vddnb */ if (!(adev->flags & AMD_IS_APU)) return -EINVAL; - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, - (void *)&vddnb, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_VDDNB, + (void *)&vddnb); if (r) return r; @@ -2877,49 +2898,49 @@ static ssize_t amdgpu_hwmon_show_vddnb_label(struct device *dev, return sysfs_emit(buf, "vddnb\n"); } -static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, - struct device_attribute *attr, - char *buf) +static int amdgpu_hwmon_get_power(struct device *dev, + enum amd_pp_sensors sensor) { struct amdgpu_device *adev = dev_get_drvdata(dev); + unsigned int uw; u32 query = 0; - int r, size = sizeof(u32); - unsigned uw; - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } - - /* get the voltage */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, - (void *)&query, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); + int r; + r = amdgpu_hwmon_get_sensor_generic(adev, sensor, (void *)&query); if (r) return r; /* convert to microwatts */ uw = (query >> 8) * 1000000 + (query & 0xff) * 1000; - return sysfs_emit(buf, "%u\n", uw); + return uw; } -static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev, + struct device_attribute *attr, + char *buf) { - return sysfs_emit(buf, "%i\n", 0); + ssize_t val; + + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_AVG_POWER); + if (val < 0) + return val; + + return sysfs_emit(buf, "%zd\n", val); } +static ssize_t amdgpu_hwmon_show_power_input(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t val; + + val = amdgpu_hwmon_get_power(dev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER); + if (val < 0) + return val; + + return sysfs_emit(buf, "%zd\n", val); +} static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev, struct device_attribute *attr, @@ -2957,6 +2978,12 @@ static ssize_t amdgpu_hwmon_show_power_cap_generic(struct device *dev, return size; } +static ssize_t amdgpu_hwmon_show_power_cap_min(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return amdgpu_hwmon_show_power_cap_generic(dev, attr, buf, PP_PWR_LIMIT_MIN); +} static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev, struct device_attribute *attr, @@ -2987,7 +3014,7 @@ static ssize_t amdgpu_hwmon_show_power_label(struct device *dev, char *buf) { struct amdgpu_device *adev = dev_get_drvdata(dev); - uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; + uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0); if (gc_ver == IP_VERSION(10, 3, 1)) return sysfs_emit(buf, "%s\n", @@ -3045,26 +3072,11 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); uint32_t sclk; - int r, size = sizeof(sclk); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the sclk */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, - (void *)&sclk, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_SCLK, + (void *)&sclk); if (r) return r; @@ -3084,26 +3096,11 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev, { struct amdgpu_device *adev = dev_get_drvdata(dev); uint32_t mclk; - int r, size = sizeof(mclk); - - if (amdgpu_in_reset(adev)) - return -EPERM; - if (adev->in_suspend && !adev->in_runpm) - return -EPERM; - - r = pm_runtime_get_sync(adev_to_drm(adev)->dev); - if (r < 0) { - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - return r; - } + int r; /* get the sclk */ - r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, - (void *)&mclk, &size); - - pm_runtime_mark_last_busy(adev_to_drm(adev)->dev); - pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); - + r = amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GFX_MCLK, + (void *)&mclk); if (r) return r; @@ -3163,6 +3160,8 @@ static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, * * - power1_average: average power used by the SoC in microWatts. On APUs this includes the CPU. * + * - power1_input: instantaneous power used by the SoC in microWatts. On APUs this includes the CPU. + * * - power1_cap_min: minimum cap supported in microWatts * * - power1_cap_max: maximum cap supported in microWatts @@ -3231,6 +3230,7 @@ static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, amdgpu_hwmon_show_vddgfx_label, NU static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, amdgpu_hwmon_show_vddnb, NULL, 0); static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, amdgpu_hwmon_show_vddnb_label, NULL, 0); static SENSOR_DEVICE_ATTR(power1_average, S_IRUGO, amdgpu_hwmon_show_power_avg, NULL, 0); +static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, amdgpu_hwmon_show_power_input, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap_max, S_IRUGO, amdgpu_hwmon_show_power_cap_max, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap_min, S_IRUGO, amdgpu_hwmon_show_power_cap_min, NULL, 0); static SENSOR_DEVICE_ATTR(power1_cap, S_IRUGO | S_IWUSR, amdgpu_hwmon_show_power_cap, amdgpu_hwmon_set_power_cap, 0); @@ -3277,6 +3277,7 @@ static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_label.dev_attr.attr, &sensor_dev_attr_power1_average.dev_attr.attr, + &sensor_dev_attr_power1_input.dev_attr.attr, &sensor_dev_attr_power1_cap_max.dev_attr.attr, &sensor_dev_attr_power1_cap_min.dev_attr.attr, &sensor_dev_attr_power1_cap.dev_attr.attr, @@ -3301,11 +3302,8 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, struct device *dev = kobj_to_dev(kobj); struct amdgpu_device *adev = dev_get_drvdata(dev); umode_t effective_mode = attr->mode; - uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; - - /* under multi-vf mode, the hwmon attributes are all not supported */ - if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) - return 0; + uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0); + uint32_t tmp; /* under pp one vf mode manage of hwmon attributes is not supported */ if (amdgpu_sriov_is_pp_one_vf(adev)) @@ -3387,6 +3385,14 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, (attr == &sensor_dev_attr_power1_average.dev_attr.attr)) return 0; + /* not all products support both average and instantaneous */ + if (attr == &sensor_dev_attr_power1_average.dev_attr.attr && + amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&tmp) == -EOPNOTSUPP) + return 0; + if (attr == &sensor_dev_attr_power1_input.dev_attr.attr && + amdgpu_hwmon_get_sensor_generic(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&tmp) == -EOPNOTSUPP) + return 0; + /* hide max/min values if we can't both query and manage the fan */ if (((amdgpu_dpm_set_fan_speed_pwm(adev, U32_MAX) == -EOPNOTSUPP) && (amdgpu_dpm_get_fan_speed_pwm(adev, NULL) == -EOPNOTSUPP) && @@ -3425,22 +3431,27 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj, (gc_ver != IP_VERSION(9, 4, 3)) && (attr == &sensor_dev_attr_temp2_input.dev_attr.attr || attr == &sensor_dev_attr_temp2_label.dev_attr.attr || + attr == &sensor_dev_attr_temp2_crit.dev_attr.attr || attr == &sensor_dev_attr_temp3_input.dev_attr.attr || - attr == &sensor_dev_attr_temp3_label.dev_attr.attr)) + attr == &sensor_dev_attr_temp3_label.dev_attr.attr || + attr == &sensor_dev_attr_temp3_crit.dev_attr.attr)) return 0; /* hotspot temperature for gc 9,4,3*/ - if ((gc_ver == IP_VERSION(9, 4, 3)) && - (attr == &sensor_dev_attr_temp1_input.dev_attr.attr || - attr == &sensor_dev_attr_temp1_label.dev_attr.attr)) - return 0; + if (gc_ver == IP_VERSION(9, 4, 3)) { + if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr || + attr == &sensor_dev_attr_temp1_emergency.dev_attr.attr || + attr == &sensor_dev_attr_temp1_label.dev_attr.attr) + return 0; + + if (attr == &sensor_dev_attr_temp2_emergency.dev_attr.attr || + attr == &sensor_dev_attr_temp3_emergency.dev_attr.attr) + return attr->mode; + } /* only SOC15 dGPUs support hotspot and mem temperatures */ - if (((adev->flags & AMD_IS_APU) || gc_ver < IP_VERSION(9, 0, 0) || - (gc_ver == IP_VERSION(9, 4, 3))) && - (attr == &sensor_dev_attr_temp2_crit.dev_attr.attr || - attr == &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr || - attr == &sensor_dev_attr_temp3_crit.dev_attr.attr || + if (((adev->flags & AMD_IS_APU) || gc_ver < IP_VERSION(9, 0, 0)) && + (attr == &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr || attr == &sensor_dev_attr_temp3_crit_hyst.dev_attr.attr || attr == &sensor_dev_attr_temp1_emergency.dev_attr.attr || attr == &sensor_dev_attr_temp2_emergency.dev_attr.attr || @@ -3470,10 +3481,703 @@ static const struct attribute_group *hwmon_groups[] = { NULL }; -int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) +static int amdgpu_retrieve_od_settings(struct amdgpu_device *adev, + enum pp_clock_type od_type, + char *buf) +{ + int size = 0; + int ret; + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + ret = pm_runtime_get_sync(adev->dev); + if (ret < 0) { + pm_runtime_put_autosuspend(adev->dev); + return ret; + } + + size = amdgpu_dpm_print_clock_levels(adev, od_type, buf); + if (size == 0) + size = sysfs_emit(buf, "\n"); + + pm_runtime_mark_last_busy(adev->dev); + pm_runtime_put_autosuspend(adev->dev); + + return size; +} + +static int parse_input_od_command_lines(const char *buf, + size_t count, + u32 *type, + long *params, + uint32_t *num_of_params) +{ + const char delimiter[3] = {' ', '\n', '\0'}; + uint32_t parameter_size = 0; + char buf_cpy[128] = {0}; + char *tmp_str, *sub_str; + int ret; + + if (count > sizeof(buf_cpy) - 1) + return -EINVAL; + + memcpy(buf_cpy, buf, count); + tmp_str = buf_cpy; + + /* skip heading spaces */ + while (isspace(*tmp_str)) + tmp_str++; + + switch (*tmp_str) { + case 'c': + *type = PP_OD_COMMIT_DPM_TABLE; + return 0; + case 'r': + params[parameter_size] = *type; + *num_of_params = 1; + *type = PP_OD_RESTORE_DEFAULT_TABLE; + return 0; + default: + break; + } + + while ((sub_str = strsep(&tmp_str, delimiter)) != NULL) { + if (strlen(sub_str) == 0) + continue; + + ret = kstrtol(sub_str, 0, ¶ms[parameter_size]); + if (ret) + return -EINVAL; + parameter_size++; + + while (isspace(*tmp_str)) + tmp_str++; + } + + *num_of_params = parameter_size; + + return 0; +} + +static int +amdgpu_distribute_custom_od_settings(struct amdgpu_device *adev, + enum PP_OD_DPM_TABLE_COMMAND cmd_type, + const char *in_buf, + size_t count) +{ + uint32_t parameter_size = 0; + long parameter[64]; + int ret; + + if (amdgpu_in_reset(adev)) + return -EPERM; + if (adev->in_suspend && !adev->in_runpm) + return -EPERM; + + ret = parse_input_od_command_lines(in_buf, + count, + &cmd_type, + parameter, + ¶meter_size); + if (ret) + return ret; + + ret = pm_runtime_get_sync(adev->dev); + if (ret < 0) + goto err_out0; + + ret = amdgpu_dpm_odn_edit_dpm_table(adev, + cmd_type, + parameter, + parameter_size); + if (ret) + goto err_out1; + + if (cmd_type == PP_OD_COMMIT_DPM_TABLE) { + ret = amdgpu_dpm_dispatch_task(adev, + AMD_PP_TASK_READJUST_POWER_STATE, + NULL); + if (ret) + goto err_out1; + } + + pm_runtime_mark_last_busy(adev->dev); + pm_runtime_put_autosuspend(adev->dev); + + return count; + +err_out1: + pm_runtime_mark_last_busy(adev->dev); +err_out0: + pm_runtime_put_autosuspend(adev->dev); + + return ret; +} + +/** + * DOC: fan_curve + * + * The amdgpu driver provides a sysfs API for checking and adjusting the fan + * control curve line. + * + * Reading back the file shows you the current settings(temperature in Celsius + * degree and fan speed in pwm) applied to every anchor point of the curve line + * and their permitted ranges if changable. + * + * Writing a desired string(with the format like "anchor_point_index temperature + * fan_speed_in_pwm") to the file, change the settings for the specific anchor + * point accordingly. + * + * When you have finished the editing, write "c" (commit) to the file to commit + * your changes. + * + * If you want to reset to the default value, write "r" (reset) to the file to + * reset them + * + * There are two fan control modes supported: auto and manual. With auto mode, + * PMFW handles the fan speed control(how fan speed reacts to ASIC temperature). + * While with manual mode, users can set their own fan curve line as what + * described here. Normally the ASIC is booted up with auto mode. Any + * settings via this interface will switch the fan control to manual mode + * implicitly. + */ +static ssize_t fan_curve_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_CURVE, buf); +} + +static ssize_t fan_curve_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_distribute_custom_od_settings(adev, + PP_OD_EDIT_FAN_CURVE, + buf, + count); +} + +static umode_t fan_curve_visible(struct amdgpu_device *adev) +{ + umode_t umode = 0000; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_CURVE_RETRIEVE) + umode |= S_IRUSR | S_IRGRP | S_IROTH; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_CURVE_SET) + umode |= S_IWUSR; + + return umode; +} + +/** + * DOC: acoustic_limit_rpm_threshold + * + * The amdgpu driver provides a sysfs API for checking and adjusting the + * acoustic limit in RPM for fan control. + * + * Reading back the file shows you the current setting and the permitted + * ranges if changable. + * + * Writing an integer to the file, change the setting accordingly. + * + * When you have finished the editing, write "c" (commit) to the file to commit + * your changes. + * + * If you want to reset to the default value, write "r" (reset) to the file to + * reset them + * + * This setting works under auto fan control mode only. It adjusts the PMFW's + * behavior about the maximum speed in RPM the fan can spin. Setting via this + * interface will switch the fan control to auto mode implicitly. + */ +static ssize_t acoustic_limit_threshold_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_ACOUSTIC_LIMIT, buf); +} + +static ssize_t acoustic_limit_threshold_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_distribute_custom_od_settings(adev, + PP_OD_EDIT_ACOUSTIC_LIMIT, + buf, + count); +} + +static umode_t acoustic_limit_threshold_visible(struct amdgpu_device *adev) +{ + umode_t umode = 0000; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_RETRIEVE) + umode |= S_IRUSR | S_IRGRP | S_IROTH; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_SET) + umode |= S_IWUSR; + + return umode; +} + +/** + * DOC: acoustic_target_rpm_threshold + * + * The amdgpu driver provides a sysfs API for checking and adjusting the + * acoustic target in RPM for fan control. + * + * Reading back the file shows you the current setting and the permitted + * ranges if changable. + * + * Writing an integer to the file, change the setting accordingly. + * + * When you have finished the editing, write "c" (commit) to the file to commit + * your changes. + * + * If you want to reset to the default value, write "r" (reset) to the file to + * reset them + * + * This setting works under auto fan control mode only. It can co-exist with + * other settings which can work also under auto mode. It adjusts the PMFW's + * behavior about the maximum speed in RPM the fan can spin when ASIC + * temperature is not greater than target temperature. Setting via this + * interface will switch the fan control to auto mode implicitly. + */ +static ssize_t acoustic_target_threshold_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_ACOUSTIC_TARGET, buf); +} + +static ssize_t acoustic_target_threshold_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_distribute_custom_od_settings(adev, + PP_OD_EDIT_ACOUSTIC_TARGET, + buf, + count); +} + +static umode_t acoustic_target_threshold_visible(struct amdgpu_device *adev) +{ + umode_t umode = 0000; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_RETRIEVE) + umode |= S_IRUSR | S_IRGRP | S_IROTH; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_SET) + umode |= S_IWUSR; + + return umode; +} + +/** + * DOC: fan_target_temperature + * + * The amdgpu driver provides a sysfs API for checking and adjusting the + * target tempeature in Celsius degree for fan control. + * + * Reading back the file shows you the current setting and the permitted + * ranges if changable. + * + * Writing an integer to the file, change the setting accordingly. + * + * When you have finished the editing, write "c" (commit) to the file to commit + * your changes. + * + * If you want to reset to the default value, write "r" (reset) to the file to + * reset them + * + * This setting works under auto fan control mode only. It can co-exist with + * other settings which can work also under auto mode. Paring with the + * acoustic_target_rpm_threshold setting, they define the maximum speed in + * RPM the fan can spin when ASIC temperature is not greater than target + * temperature. Setting via this interface will switch the fan control to + * auto mode implicitly. + */ +static ssize_t fan_target_temperature_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_TARGET_TEMPERATURE, buf); +} + +static ssize_t fan_target_temperature_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_distribute_custom_od_settings(adev, + PP_OD_EDIT_FAN_TARGET_TEMPERATURE, + buf, + count); +} + +static umode_t fan_target_temperature_visible(struct amdgpu_device *adev) { + umode_t umode = 0000; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE) + umode |= S_IRUSR | S_IRGRP | S_IROTH; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET) + umode |= S_IWUSR; + + return umode; +} + +/** + * DOC: fan_minimum_pwm + * + * The amdgpu driver provides a sysfs API for checking and adjusting the + * minimum fan speed in PWM. + * + * Reading back the file shows you the current setting and the permitted + * ranges if changable. + * + * Writing an integer to the file, change the setting accordingly. + * + * When you have finished the editing, write "c" (commit) to the file to commit + * your changes. + * + * If you want to reset to the default value, write "r" (reset) to the file to + * reset them + * + * This setting works under auto fan control mode only. It can co-exist with + * other settings which can work also under auto mode. It adjusts the PMFW's + * behavior about the minimum fan speed in PWM the fan should spin. Setting + * via this interface will switch the fan control to auto mode implicitly. + */ +static ssize_t fan_minimum_pwm_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_retrieve_od_settings(adev, OD_FAN_MINIMUM_PWM, buf); +} + +static ssize_t fan_minimum_pwm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, + size_t count) +{ + struct od_kobj *container = container_of(kobj, struct od_kobj, kobj); + struct amdgpu_device *adev = (struct amdgpu_device *)container->priv; + + return (ssize_t)amdgpu_distribute_custom_od_settings(adev, + PP_OD_EDIT_FAN_MINIMUM_PWM, + buf, + count); +} + +static umode_t fan_minimum_pwm_visible(struct amdgpu_device *adev) +{ + umode_t umode = 0000; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE) + umode |= S_IRUSR | S_IRGRP | S_IROTH; + + if (adev->pm.od_feature_mask & OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET) + umode |= S_IWUSR; + + return umode; +} + +static struct od_feature_set amdgpu_od_set = { + .containers = { + [0] = { + .name = "fan_ctrl", + .sub_feature = { + [0] = { + .name = "fan_curve", + .ops = { + .is_visible = fan_curve_visible, + .show = fan_curve_show, + .store = fan_curve_store, + }, + }, + [1] = { + .name = "acoustic_limit_rpm_threshold", + .ops = { + .is_visible = acoustic_limit_threshold_visible, + .show = acoustic_limit_threshold_show, + .store = acoustic_limit_threshold_store, + }, + }, + [2] = { + .name = "acoustic_target_rpm_threshold", + .ops = { + .is_visible = acoustic_target_threshold_visible, + .show = acoustic_target_threshold_show, + .store = acoustic_target_threshold_store, + }, + }, + [3] = { + .name = "fan_target_temperature", + .ops = { + .is_visible = fan_target_temperature_visible, + .show = fan_target_temperature_show, + .store = fan_target_temperature_store, + }, + }, + [4] = { + .name = "fan_minimum_pwm", + .ops = { + .is_visible = fan_minimum_pwm_visible, + .show = fan_minimum_pwm_show, + .store = fan_minimum_pwm_store, + }, + }, + }, + }, + }, +}; + +static void od_kobj_release(struct kobject *kobj) +{ + struct od_kobj *od_kobj = container_of(kobj, struct od_kobj, kobj); + + kfree(od_kobj); +} + +static const struct kobj_type od_ktype = { + .release = od_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, +}; + +static void amdgpu_od_set_fini(struct amdgpu_device *adev) +{ + struct od_kobj *container, *container_next; + struct od_attribute *attribute, *attribute_next; + + if (list_empty(&adev->pm.od_kobj_list)) + return; + + list_for_each_entry_safe(container, container_next, + &adev->pm.od_kobj_list, entry) { + list_del(&container->entry); + + list_for_each_entry_safe(attribute, attribute_next, + &container->attribute, entry) { + list_del(&attribute->entry); + sysfs_remove_file(&container->kobj, + &attribute->attribute.attr); + kfree(attribute); + } + + kobject_put(&container->kobj); + } +} + +static bool amdgpu_is_od_feature_supported(struct amdgpu_device *adev, + struct od_feature_ops *feature_ops) +{ + umode_t mode; + + if (!feature_ops->is_visible) + return false; + + /* + * If the feature has no user read and write mode set, + * we can assume the feature is actually not supported.(?) + * And the revelant sysfs interface should not be exposed. + */ + mode = feature_ops->is_visible(adev); + if (mode & (S_IRUSR | S_IWUSR)) + return true; + + return false; +} + +static bool amdgpu_od_is_self_contained(struct amdgpu_device *adev, + struct od_feature_container *container) +{ + int i; + + /* + * If there is no valid entry within the container, the container + * is recognized as a self contained container. And the valid entry + * here means it has a valid naming and it is visible/supported by + * the ASIC. + */ + for (i = 0; i < ARRAY_SIZE(container->sub_feature); i++) { + if (container->sub_feature[i].name && + amdgpu_is_od_feature_supported(adev, + &container->sub_feature[i].ops)) + return false; + } + + return true; +} + +static int amdgpu_od_set_init(struct amdgpu_device *adev) +{ + struct od_kobj *top_set, *sub_set; + struct od_attribute *attribute; + struct od_feature_container *container; + struct od_feature_item *feature; + int i, j; int ret; + + /* Setup the top `gpu_od` directory which holds all other OD interfaces */ + top_set = kzalloc(sizeof(*top_set), GFP_KERNEL); + if (!top_set) + return -ENOMEM; + list_add(&top_set->entry, &adev->pm.od_kobj_list); + + ret = kobject_init_and_add(&top_set->kobj, + &od_ktype, + &adev->dev->kobj, + "%s", + "gpu_od"); + if (ret) + goto err_out; + INIT_LIST_HEAD(&top_set->attribute); + top_set->priv = adev; + + for (i = 0; i < ARRAY_SIZE(amdgpu_od_set.containers); i++) { + container = &amdgpu_od_set.containers[i]; + + if (!container->name) + continue; + + /* + * If there is valid entries within the container, the container + * will be presented as a sub directory and all its holding entries + * will be presented as plain files under it. + * While if there is no valid entry within the container, the container + * itself will be presented as a plain file under top `gpu_od` directory. + */ + if (amdgpu_od_is_self_contained(adev, container)) { + if (!amdgpu_is_od_feature_supported(adev, + &container->ops)) + continue; + + /* + * The container is presented as a plain file under top `gpu_od` + * directory. + */ + attribute = kzalloc(sizeof(*attribute), GFP_KERNEL); + if (!attribute) { + ret = -ENOMEM; + goto err_out; + } + list_add(&attribute->entry, &top_set->attribute); + + attribute->attribute.attr.mode = + container->ops.is_visible(adev); + attribute->attribute.attr.name = container->name; + attribute->attribute.show = + container->ops.show; + attribute->attribute.store = + container->ops.store; + ret = sysfs_create_file(&top_set->kobj, + &attribute->attribute.attr); + if (ret) + goto err_out; + } else { + /* The container is presented as a sub directory. */ + sub_set = kzalloc(sizeof(*sub_set), GFP_KERNEL); + if (!sub_set) { + ret = -ENOMEM; + goto err_out; + } + list_add(&sub_set->entry, &adev->pm.od_kobj_list); + + ret = kobject_init_and_add(&sub_set->kobj, + &od_ktype, + &top_set->kobj, + "%s", + container->name); + if (ret) + goto err_out; + INIT_LIST_HEAD(&sub_set->attribute); + sub_set->priv = adev; + + for (j = 0; j < ARRAY_SIZE(container->sub_feature); j++) { + feature = &container->sub_feature[j]; + if (!feature->name) + continue; + + if (!amdgpu_is_od_feature_supported(adev, + &feature->ops)) + continue; + + /* + * With the container presented as a sub directory, the entry within + * it is presented as a plain file under the sub directory. + */ + attribute = kzalloc(sizeof(*attribute), GFP_KERNEL); + if (!attribute) { + ret = -ENOMEM; + goto err_out; + } + list_add(&attribute->entry, &sub_set->attribute); + + attribute->attribute.attr.mode = + feature->ops.is_visible(adev); + attribute->attribute.attr.name = feature->name; + attribute->attribute.show = + feature->ops.show; + attribute->attribute.store = + feature->ops.store; + ret = sysfs_create_file(&sub_set->kobj, + &attribute->attribute.attr); + if (ret) + goto err_out; + } + } + } + + return 0; + +err_out: + amdgpu_od_set_fini(adev); + + return ret; +} + +int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) +{ + enum amdgpu_sriov_vf_mode mode; uint32_t mask = 0; + int ret; if (adev->pm.sysfs_initialized) return 0; @@ -3483,17 +4187,21 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) if (adev->pm.dpm_enabled == 0) return 0; - adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, - DRIVER_NAME, adev, - hwmon_groups); - if (IS_ERR(adev->pm.int_hwmon_dev)) { - ret = PTR_ERR(adev->pm.int_hwmon_dev); - dev_err(adev->dev, - "Unable to register hwmon device: %d\n", ret); - return ret; + mode = amdgpu_virt_get_sriov_vf_mode(adev); + + /* under multi-vf mode, the hwmon attributes are all not supported */ + if (mode != SRIOV_VF_MODE_MULTI_VF) { + adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev, + DRIVER_NAME, adev, + hwmon_groups); + if (IS_ERR(adev->pm.int_hwmon_dev)) { + ret = PTR_ERR(adev->pm.int_hwmon_dev); + dev_err(adev->dev, "Unable to register hwmon device: %d\n", ret); + return ret; + } } - switch (amdgpu_virt_get_sriov_vf_mode(adev)) { + switch (mode) { case SRIOV_VF_MODE_ONE_VF: mask = ATTR_FLAG_ONEVF; break; @@ -3512,15 +4220,31 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) mask, &adev->pm.pm_attr_list); if (ret) - return ret; + goto err_out0; + + if (amdgpu_dpm_is_overdrive_supported(adev)) { + ret = amdgpu_od_set_init(adev); + if (ret) + goto err_out1; + } adev->pm.sysfs_initialized = true; return 0; + +err_out1: + amdgpu_device_attr_remove_groups(adev, &adev->pm.pm_attr_list); +err_out0: + if (adev->pm.int_hwmon_dev) + hwmon_device_unregister(adev->pm.int_hwmon_dev); + + return ret; } void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) { + amdgpu_od_set_fini(adev); + if (adev->pm.int_hwmon_dev) hwmon_device_unregister(adev->pm.int_hwmon_dev); @@ -3533,7 +4257,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) #if defined(CONFIG_DEBUG_FS) static void amdgpu_debugfs_prints_cpu_info(struct seq_file *m, - struct amdgpu_device *adev) { + struct amdgpu_device *adev) +{ uint16_t *p_val; uint32_t size; int i; @@ -3556,8 +4281,8 @@ static void amdgpu_debugfs_prints_cpu_info(struct seq_file *m, static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *adev) { - uint32_t mp1_ver = adev->ip_versions[MP1_HWIP][0]; - uint32_t gc_ver = adev->ip_versions[GC_HWIP][0]; + uint32_t mp1_ver = amdgpu_ip_version(adev, MP1_HWIP, 0); + uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0); uint32_t value; uint64_t value64 = 0; uint32_t query = 0; @@ -3582,8 +4307,11 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size)) seq_printf(m, "\t%u mV (VDDNB)\n", value); size = sizeof(uint32_t); - if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query, &size)) - seq_printf(m, "\t%u.%u W (average GPU)\n", query >> 8, query & 0xff); + if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_AVG_POWER, (void *)&query, &size)) + seq_printf(m, "\t%u.%02u W (average GPU)\n", query >> 8, query & 0xff); + size = sizeof(uint32_t); + if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_INPUT_POWER, (void *)&query, &size)) + seq_printf(m, "\t%u.%02u W (current GPU)\n", query >> 8, query & 0xff); size = sizeof(value); seq_printf(m, "\n"); diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h index 42172b00be66..482ea30147ab 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -314,6 +314,17 @@ struct config_table_setting uint16_t fclk_average_tau; }; +#define OD_OPS_SUPPORT_FAN_CURVE_RETRIEVE BIT(0) +#define OD_OPS_SUPPORT_FAN_CURVE_SET BIT(1) +#define OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_RETRIEVE BIT(2) +#define OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_SET BIT(3) +#define OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_RETRIEVE BIT(4) +#define OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_SET BIT(5) +#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE BIT(6) +#define OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET BIT(7) +#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE BIT(8) +#define OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET BIT(9) + struct amdgpu_pm { struct mutex mutex; u32 current_sclk; @@ -366,6 +377,9 @@ struct amdgpu_pm { struct config_table_setting config_table; /* runtime mode */ enum amdgpu_runpm_mode rpm_mode; + + struct list_head od_kobj_list; + uint32_t od_feature_mask; }; int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor, @@ -401,6 +415,8 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev); int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, enum pp_mp1_state mp1_state); +int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en); + int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev); int amdgpu_dpm_baco_exit(struct amdgpu_device *adev); @@ -410,7 +426,10 @@ int amdgpu_dpm_baco_enter(struct amdgpu_device *adev); int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev, uint32_t cstate); -int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en); +int amdgpu_dpm_get_xgmi_plpd_mode(struct amdgpu_device *adev, + char **mode); + +int amdgpu_dpm_set_xgmi_plpd_mode(struct amdgpu_device *adev, int mode); int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h b/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h index 52045ad59bed..eec816f0cbf9 100644 --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_pm.h @@ -24,8 +24,7 @@ #ifndef __AMDGPU_PM_H__ #define __AMDGPU_PM_H__ -struct cg_flag_name -{ +struct cg_flag_name { u64 flag; const char *name; }; diff --git a/drivers/gpu/drm/amd/pm/inc/smu_v13_0_0_pptable.h b/drivers/gpu/drm/amd/pm/inc/smu_v13_0_0_pptable.h index 1dc7a065a6d4..251ed011b3b0 100644 --- a/drivers/gpu/drm/amd/pm/inc/smu_v13_0_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/inc/smu_v13_0_0_pptable.h @@ -41,8 +41,7 @@ #define SMU_13_0_0_PP_OVERDRIVE_VERSION 0x83 // OverDrive 8 Table Version 0.2 #define SMU_13_0_0_PP_POWERSAVINGCLOCK_VERSION 0x01 // Power Saving Clock Table Version 1.00 -enum SMU_13_0_0_ODFEATURE_CAP -{ +enum SMU_13_0_0_ODFEATURE_CAP { SMU_13_0_0_ODCAP_GFXCLK_LIMITS = 0, SMU_13_0_0_ODCAP_UCLK_LIMITS, SMU_13_0_0_ODCAP_POWER_LIMIT, @@ -62,8 +61,7 @@ enum SMU_13_0_0_ODFEATURE_CAP SMU_13_0_0_ODCAP_COUNT, }; -enum SMU_13_0_0_ODFEATURE_ID -{ +enum SMU_13_0_0_ODFEATURE_ID { SMU_13_0_0_ODFEATURE_GFXCLK_LIMITS = 1 << SMU_13_0_0_ODCAP_GFXCLK_LIMITS, //GFXCLK Limit feature SMU_13_0_0_ODFEATURE_UCLK_LIMITS = 1 << SMU_13_0_0_ODCAP_UCLK_LIMITS, //UCLK Limit feature SMU_13_0_0_ODFEATURE_POWER_LIMIT = 1 << SMU_13_0_0_ODCAP_POWER_LIMIT, //Power Limit feature @@ -85,8 +83,7 @@ enum SMU_13_0_0_ODFEATURE_ID #define SMU_13_0_0_MAX_ODFEATURE 32 //Maximum Number of OD Features -enum SMU_13_0_0_ODSETTING_ID -{ +enum SMU_13_0_0_ODSETTING_ID { SMU_13_0_0_ODSETTING_GFXCLKFMAX = 0, SMU_13_0_0_ODSETTING_GFXCLKFMIN, SMU_13_0_0_ODSETTING_UCLKFMIN, @@ -123,8 +120,7 @@ enum SMU_13_0_0_ODSETTING_ID }; #define SMU_13_0_0_MAX_ODSETTING 64 //Maximum Number of ODSettings -enum SMU_13_0_0_PWRMODE_SETTING -{ +enum SMU_13_0_0_PWRMODE_SETTING { SMU_13_0_0_PMSETTING_POWER_LIMIT_QUIET = 0, SMU_13_0_0_PMSETTING_POWER_LIMIT_BALANCE, SMU_13_0_0_PMSETTING_POWER_LIMIT_TURBO, @@ -144,8 +140,7 @@ enum SMU_13_0_0_PWRMODE_SETTING }; #define SMU_13_0_0_MAX_PMSETTING 32 //Maximum Number of PowerMode Settings -struct smu_13_0_0_overdrive_table -{ +struct smu_13_0_0_overdrive_table { uint8_t revision; //Revision = SMU_13_0_0_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -156,8 +151,7 @@ struct smu_13_0_0_overdrive_table int16_t pm_setting[SMU_13_0_0_MAX_PMSETTING]; //Optimized power mode feature settings }; -enum SMU_13_0_0_PPCLOCK_ID -{ +enum SMU_13_0_0_PPCLOCK_ID { SMU_13_0_0_PPCLOCK_GFXCLK = 0, SMU_13_0_0_PPCLOCK_SOCCLK, SMU_13_0_0_PPCLOCK_UCLK, @@ -175,8 +169,7 @@ enum SMU_13_0_0_PPCLOCK_ID }; #define SMU_13_0_0_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_13_0_0_powerplay_table -{ +struct smu_13_0_0_powerplay_table { struct atom_common_table_header header; //For SMU13, header.format_revision = 15, header.content_revision = 0 uint8_t table_revision; //For SMU13, table_revision = 2 uint8_t padding; diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c index 36c831b280ed..5d28c951a319 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c @@ -191,8 +191,7 @@ static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev, } #if 0 -static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 1, 4, 1 }, { 2, 5, 1 }, @@ -204,32 +203,27 @@ static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = { 0xffffffff } }; -static const struct kv_lcac_config_values mc0_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values mc0_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 0xffffffff } }; -static const struct kv_lcac_config_values mc1_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values mc1_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 0xffffffff } }; -static const struct kv_lcac_config_values mc2_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values mc2_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 0xffffffff } }; -static const struct kv_lcac_config_values mc3_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values mc3_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 0xffffffff } }; -static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] = -{ +static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] = { { 0, 4, 1 }, { 1, 4, 1 }, { 2, 5, 1 }, @@ -260,39 +254,32 @@ static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] = { 0xffffffff } }; -static const struct kv_lcac_config_reg sx0_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg sx0_cac_config_reg[] = { { 0xc0400d00, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; -static const struct kv_lcac_config_reg mc0_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg mc0_cac_config_reg[] = { { 0xc0400d30, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; -static const struct kv_lcac_config_reg mc1_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg mc1_cac_config_reg[] = { { 0xc0400d3c, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; -static const struct kv_lcac_config_reg mc2_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg mc2_cac_config_reg[] = { { 0xc0400d48, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; -static const struct kv_lcac_config_reg mc3_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg mc3_cac_config_reg[] = { { 0xc0400d54, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; -static const struct kv_lcac_config_reg cpl_cac_config_reg[] = -{ +static const struct kv_lcac_config_reg cpl_cac_config_reg[] = { { 0xc0400d80, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 } }; #endif -static const struct kv_pt_config_reg didt_config_kv[] = -{ +static const struct kv_pt_config_reg didt_config_kv[] = { { 0x10, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND }, { 0x10, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND }, { 0x10, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND }, @@ -1173,9 +1160,9 @@ static void kv_calculate_dfs_bypass_settings(struct amdgpu_device *adev) pi->graphics_level[i].ClkBypassCntl = 2; else if (kv_get_clock_difference(table->entries[i].clk, 26600) < 200) pi->graphics_level[i].ClkBypassCntl = 7; - else if (kv_get_clock_difference(table->entries[i].clk , 20000) < 200) + else if (kv_get_clock_difference(table->entries[i].clk, 20000) < 200) pi->graphics_level[i].ClkBypassCntl = 6; - else if (kv_get_clock_difference(table->entries[i].clk , 10000) < 200) + else if (kv_get_clock_difference(table->entries[i].clk, 10000) < 200) pi->graphics_level[i].ClkBypassCntl = 8; else pi->graphics_level[i].ClkBypassCntl = 0; @@ -1825,7 +1812,7 @@ static void kv_set_valid_clock_range(struct amdgpu_device *adev, if ((new_ps->levels[0].sclk - table->entries[pi->highest_valid].sclk_frequency) > (table->entries[pi->lowest_valid].sclk_frequency - - new_ps->levels[new_ps->num_levels -1].sclk)) + new_ps->levels[new_ps->num_levels - 1].sclk)) pi->highest_valid = pi->lowest_valid; else pi->lowest_valid = pi->highest_valid; @@ -3333,8 +3320,7 @@ static const struct amd_ip_funcs kv_dpm_ip_funcs = { .set_powergating_state = kv_dpm_set_powergating_state, }; -const struct amdgpu_ip_block_version kv_smu_ip_block = -{ +const struct amdgpu_ip_block_version kv_smu_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 1, .minor = 0, diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/r600_dpm.h b/drivers/gpu/drm/amd/pm/legacy-dpm/r600_dpm.h index 055321f61ca7..3e7caa715533 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/r600_dpm.h +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/r600_dpm.h @@ -117,8 +117,7 @@ enum r600_display_watermark { R600_DISPLAY_WATERMARK_HIGH = 1, }; -enum r600_display_gap -{ +enum r600_display_gap { R600_PM_DISPLAY_GAP_VBLANK_OR_WM = 0, R600_PM_DISPLAY_GAP_VBLANK = 1, R600_PM_DISPLAY_GAP_WATERMARK = 2, diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index 02e69ccff3ba..fc8e4ac6c8e7 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -6600,7 +6600,7 @@ static int si_dpm_get_fan_speed_pwm(void *handle, tmp64 = (u64)duty * 255; do_div(tmp64, duty100); - *speed = MIN((u32)tmp64, 255); + *speed = min_t(u32, tmp64, 255); return 0; } diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/sislands_smc.h b/drivers/gpu/drm/amd/pm/legacy-dpm/sislands_smc.h index c7dc117a688c..90ec411c5029 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/sislands_smc.h +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/sislands_smc.h @@ -29,8 +29,7 @@ #define SISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 16 -struct PP_SIslands_Dpm2PerfLevel -{ +struct PP_SIslands_Dpm2PerfLevel { uint8_t MaxPS; uint8_t TgtAct; uint8_t MaxPS_StepInc; @@ -47,8 +46,7 @@ struct PP_SIslands_Dpm2PerfLevel typedef struct PP_SIslands_Dpm2PerfLevel PP_SIslands_Dpm2PerfLevel; -struct PP_SIslands_DPM2Status -{ +struct PP_SIslands_DPM2Status { uint32_t dpm2Flags; uint8_t CurrPSkip; uint8_t CurrPSkipPowerShift; @@ -68,8 +66,7 @@ struct PP_SIslands_DPM2Status typedef struct PP_SIslands_DPM2Status PP_SIslands_DPM2Status; -struct PP_SIslands_DPM2Parameters -{ +struct PP_SIslands_DPM2Parameters { uint32_t TDPLimit; uint32_t NearTDPLimit; uint32_t SafePowerLimit; @@ -78,8 +75,7 @@ struct PP_SIslands_DPM2Parameters }; typedef struct PP_SIslands_DPM2Parameters PP_SIslands_DPM2Parameters; -struct PP_SIslands_PAPMStatus -{ +struct PP_SIslands_PAPMStatus { uint32_t EstimatedDGPU_T; uint32_t EstimatedDGPU_P; uint32_t EstimatedAPU_T; @@ -89,8 +85,7 @@ struct PP_SIslands_PAPMStatus }; typedef struct PP_SIslands_PAPMStatus PP_SIslands_PAPMStatus; -struct PP_SIslands_PAPMParameters -{ +struct PP_SIslands_PAPMParameters { uint32_t NearTDPLimitTherm; uint32_t NearTDPLimitPAPM; uint32_t PlatformPowerLimit; @@ -100,8 +95,7 @@ struct PP_SIslands_PAPMParameters }; typedef struct PP_SIslands_PAPMParameters PP_SIslands_PAPMParameters; -struct SISLANDS_SMC_SCLK_VALUE -{ +struct SISLANDS_SMC_SCLK_VALUE { uint32_t vCG_SPLL_FUNC_CNTL; uint32_t vCG_SPLL_FUNC_CNTL_2; uint32_t vCG_SPLL_FUNC_CNTL_3; @@ -113,8 +107,7 @@ struct SISLANDS_SMC_SCLK_VALUE typedef struct SISLANDS_SMC_SCLK_VALUE SISLANDS_SMC_SCLK_VALUE; -struct SISLANDS_SMC_MCLK_VALUE -{ +struct SISLANDS_SMC_MCLK_VALUE { uint32_t vMPLL_FUNC_CNTL; uint32_t vMPLL_FUNC_CNTL_1; uint32_t vMPLL_FUNC_CNTL_2; @@ -129,8 +122,7 @@ struct SISLANDS_SMC_MCLK_VALUE typedef struct SISLANDS_SMC_MCLK_VALUE SISLANDS_SMC_MCLK_VALUE; -struct SISLANDS_SMC_VOLTAGE_VALUE -{ +struct SISLANDS_SMC_VOLTAGE_VALUE { uint16_t value; uint8_t index; uint8_t phase_settings; @@ -138,8 +130,7 @@ struct SISLANDS_SMC_VOLTAGE_VALUE typedef struct SISLANDS_SMC_VOLTAGE_VALUE SISLANDS_SMC_VOLTAGE_VALUE; -struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL -{ +struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL { uint8_t ACIndex; uint8_t displayWatermark; uint8_t gen2PCIE; @@ -180,8 +171,7 @@ struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL typedef struct SISLANDS_SMC_HW_PERFORMANCE_LEVEL SISLANDS_SMC_HW_PERFORMANCE_LEVEL; -struct SISLANDS_SMC_SWSTATE -{ +struct SISLANDS_SMC_SWSTATE { uint8_t flags; uint8_t levelCount; uint8_t padding2; @@ -205,8 +195,7 @@ struct SISLANDS_SMC_SWSTATE_SINGLE { #define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3 #define SISLANDS_SMC_VOLTAGEMASK_MAX 4 -struct SISLANDS_SMC_VOLTAGEMASKTABLE -{ +struct SISLANDS_SMC_VOLTAGEMASKTABLE { uint32_t lowMask[SISLANDS_SMC_VOLTAGEMASK_MAX]; }; @@ -214,8 +203,7 @@ typedef struct SISLANDS_SMC_VOLTAGEMASKTABLE SISLANDS_SMC_VOLTAGEMASKTABLE; #define SISLANDS_MAX_NO_VREG_STEPS 32 -struct SISLANDS_SMC_STATETABLE -{ +struct SISLANDS_SMC_STATETABLE { uint8_t thermalProtectType; uint8_t systemFlags; uint8_t maxVDDCIndexInPPTable; @@ -254,8 +242,7 @@ typedef struct SISLANDS_SMC_STATETABLE SISLANDS_SMC_STATETABLE; #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd 0x11c #define SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc 0x120 -struct PP_SIslands_FanTable -{ +struct PP_SIslands_FanTable { uint8_t fdo_mode; uint8_t padding; int16_t temp_min; @@ -285,8 +272,7 @@ typedef struct PP_SIslands_FanTable PP_SIslands_FanTable; #define SMC_SISLANDS_SCALE_I 7 #define SMC_SISLANDS_SCALE_R 12 -struct PP_SIslands_CacConfig -{ +struct PP_SIslands_CacConfig { uint16_t cac_lkge_lut[SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES]; uint32_t lkge_lut_V0; uint32_t lkge_lut_Vstep; @@ -308,23 +294,20 @@ typedef struct PP_SIslands_CacConfig PP_SIslands_CacConfig; #define SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE 16 #define SMC_SISLANDS_MC_REGISTER_ARRAY_SET_COUNT 20 -struct SMC_SIslands_MCRegisterAddress -{ +struct SMC_SIslands_MCRegisterAddress { uint16_t s0; uint16_t s1; }; typedef struct SMC_SIslands_MCRegisterAddress SMC_SIslands_MCRegisterAddress; -struct SMC_SIslands_MCRegisterSet -{ +struct SMC_SIslands_MCRegisterSet { uint32_t value[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE]; }; typedef struct SMC_SIslands_MCRegisterSet SMC_SIslands_MCRegisterSet; -struct SMC_SIslands_MCRegisters -{ +struct SMC_SIslands_MCRegisters { uint8_t last; uint8_t reserved[3]; SMC_SIslands_MCRegisterAddress address[SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE]; @@ -333,8 +316,7 @@ struct SMC_SIslands_MCRegisters typedef struct SMC_SIslands_MCRegisters SMC_SIslands_MCRegisters; -struct SMC_SIslands_MCArbDramTimingRegisterSet -{ +struct SMC_SIslands_MCArbDramTimingRegisterSet { uint32_t mc_arb_dram_timing; uint32_t mc_arb_dram_timing2; uint8_t mc_arb_rfsh_rate; @@ -344,8 +326,7 @@ struct SMC_SIslands_MCArbDramTimingRegisterSet typedef struct SMC_SIslands_MCArbDramTimingRegisterSet SMC_SIslands_MCArbDramTimingRegisterSet; -struct SMC_SIslands_MCArbDramTimingRegisters -{ +struct SMC_SIslands_MCArbDramTimingRegisters { uint8_t arb_current; uint8_t reserved[3]; SMC_SIslands_MCArbDramTimingRegisterSet data[16]; @@ -353,8 +334,7 @@ struct SMC_SIslands_MCArbDramTimingRegisters typedef struct SMC_SIslands_MCArbDramTimingRegisters SMC_SIslands_MCArbDramTimingRegisters; -struct SMC_SISLANDS_SPLL_DIV_TABLE -{ +struct SMC_SISLANDS_SPLL_DIV_TABLE { uint32_t freq[256]; uint32_t ss[256]; }; @@ -374,8 +354,7 @@ typedef struct SMC_SISLANDS_SPLL_DIV_TABLE SMC_SISLANDS_SPLL_DIV_TABLE; #define SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE 16 -struct Smc_SIslands_DTE_Configuration -{ +struct Smc_SIslands_DTE_Configuration { uint32_t tau[SMC_SISLANDS_DTE_MAX_FILTER_STAGES]; uint32_t R[SMC_SISLANDS_DTE_MAX_FILTER_STAGES]; uint32_t K; diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index ff360c699171..914c15387157 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -612,7 +612,7 @@ static int pp_dpm_get_pp_num_states(void *handle, memset(data, 0, sizeof(*data)); - if (!hwmgr || !hwmgr->pm_en ||!hwmgr->ps) + if (!hwmgr || !hwmgr->pm_en || !hwmgr->ps) return -EINVAL; data->nums = hwmgr->num_ps; @@ -644,7 +644,7 @@ static int pp_dpm_get_pp_table(void *handle, char **table) { struct pp_hwmgr *hwmgr = handle; - if (!hwmgr || !hwmgr->pm_en ||!hwmgr->soft_pp_table) + if (!hwmgr || !hwmgr->pm_en || !hwmgr->soft_pp_table) return -EINVAL; *table = (char *)hwmgr->soft_pp_table; @@ -1002,7 +1002,7 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, struct pp_hwmgr *hwmgr = handle; int ret = 0; - if (!hwmgr || !hwmgr->pm_en ||!limit) + if (!hwmgr || !hwmgr->pm_en || !limit) return -EINVAL; if (power_type != PP_PWR_TYPE_SUSTAINED) @@ -1022,6 +1022,9 @@ static int pp_get_power_limit(void *handle, uint32_t *limit, *limit /= 100; } break; + case PP_PWR_LIMIT_MIN: + *limit = 0; + break; default: ret = -EOPNOTSUPP; break; @@ -1047,7 +1050,7 @@ static int pp_get_display_power_level(void *handle, { struct pp_hwmgr *hwmgr = handle; - if (!hwmgr || !hwmgr->pm_en ||!output) + if (!hwmgr || !hwmgr->pm_en || !output) return -EINVAL; return phm_get_dal_power_level(hwmgr, output); @@ -1120,7 +1123,7 @@ static int pp_get_clock_by_type_with_latency(void *handle, { struct pp_hwmgr *hwmgr = handle; - if (!hwmgr || !hwmgr->pm_en ||!clocks) + if (!hwmgr || !hwmgr->pm_en || !clocks) return -EINVAL; return phm_get_clock_by_type_with_latency(hwmgr, type, clocks); @@ -1132,7 +1135,7 @@ static int pp_get_clock_by_type_with_voltage(void *handle, { struct pp_hwmgr *hwmgr = handle; - if (!hwmgr || !hwmgr->pm_en ||!clocks) + if (!hwmgr || !hwmgr->pm_en || !clocks) return -EINVAL; return phm_get_clock_by_type_with_voltage(hwmgr, type, clocks); @@ -1155,7 +1158,7 @@ static int pp_display_clock_voltage_request(void *handle, { struct pp_hwmgr *hwmgr = handle; - if (!hwmgr || !hwmgr->pm_en ||!clock) + if (!hwmgr || !hwmgr->pm_en || !clock) return -EINVAL; return phm_display_clock_voltage_request(hwmgr, clock); @@ -1167,7 +1170,7 @@ static int pp_get_display_mode_validation_clocks(void *handle, struct pp_hwmgr *hwmgr = handle; int ret = 0; - if (!hwmgr || !hwmgr->pm_en ||!clocks) + if (!hwmgr || !hwmgr->pm_en || !clocks) return -EINVAL; clocks->level = PP_DAL_POWERLEVEL_7; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ci_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ci_baco.c index 45f608838f6e..65b95d6be5c5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ci_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ci_baco.c @@ -38,8 +38,7 @@ #include "gca/gfx_7_2_d.h" #include "gca/gfx_7_2_sh_mask.h" -static const struct baco_cmd_entry gpio_tbl[] = -{ +static const struct baco_cmd_entry gpio_tbl[] = { { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, @@ -52,15 +51,13 @@ static const struct baco_cmd_entry gpio_tbl[] = { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } }; -static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = -{ +static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } }; -static const struct baco_cmd_entry use_bclk_tbl[] = -{ +static const struct baco_cmd_entry use_bclk_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, @@ -82,8 +79,7 @@ static const struct baco_cmd_entry use_bclk_tbl[] = { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } }; -static const struct baco_cmd_entry turn_off_plls_tbl[] = -{ +static const struct baco_cmd_entry turn_off_plls_tbl[] = { { CMD_READMODIFYWRITE, mmDISPPLL_BG_CNTL, DISPPLL_BG_CNTL__DISPPLL_BG_PDN_MASK, DISPPLL_BG_CNTL__DISPPLL_BG_PDN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_DC }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_DC__OSC_EN_MASK, CG_CLKPIN_CNTL_DC__OSC_EN__SHIFT, 0, 0x0 }, @@ -120,8 +116,7 @@ static const struct baco_cmd_entry turn_off_plls_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x2 } }; -static const struct baco_cmd_entry enter_baco_tbl[] = -{ +static const struct baco_cmd_entry enter_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x01 }, { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, 0, 5, 0x02 }, @@ -136,8 +131,7 @@ static const struct baco_cmd_entry enter_baco_tbl[] = #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK -static const struct baco_cmd_entry exit_baco_tbl[] = -{ +static const struct baco_cmd_entry exit_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, @@ -152,8 +146,7 @@ static const struct baco_cmd_entry exit_baco_tbl[] = { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } }; -static const struct baco_cmd_entry clean_baco_tbl[] = -{ +static const struct baco_cmd_entry clean_baco_tbl[] = { { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 }, { CMD_WRITE, mmCP_PFP_UCODE_ADDR, 0, 0, 0, 0 } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/common_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/common_baco.c index 1c73776bd606..fd79337a3536 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/common_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/common_baco.c @@ -42,7 +42,7 @@ static bool baco_wait_register(struct pp_hwmgr *hwmgr, u32 reg, u32 mask, u32 va } static bool baco_cmd_handler(struct pp_hwmgr *hwmgr, u32 command, u32 reg, u32 mask, - u32 shift, u32 value, u32 timeout) + u32 shift, u32 value, u32 timeout) { struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); u32 data; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/fiji_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/fiji_baco.c index c0368f2dfb21..b3e768fa79f2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/fiji_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/fiji_baco.c @@ -36,8 +36,7 @@ #include "smu/smu_7_1_3_sh_mask.h" -static const struct baco_cmd_entry gpio_tbl[] = -{ +static const struct baco_cmd_entry gpio_tbl[] = { { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, @@ -50,15 +49,13 @@ static const struct baco_cmd_entry gpio_tbl[] = { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } }; -static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = -{ +static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } }; -static const struct baco_cmd_entry use_bclk_tbl[] = -{ +static const struct baco_cmd_entry use_bclk_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, @@ -78,8 +75,7 @@ static const struct baco_cmd_entry use_bclk_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 } }; -static const struct baco_cmd_entry turn_off_plls_tbl[] = -{ +static const struct baco_cmd_entry turn_off_plls_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, @@ -88,8 +84,7 @@ static const struct baco_cmd_entry turn_off_plls_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x8000000, 0x1b, 0, 0x0 } }; -static const struct baco_cmd_entry clk_req_b_tbl[] = -{ +static const struct baco_cmd_entry clk_req_b_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_CLKPIN_CNTL_2 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN_MASK, CG_CLKPIN_CNTL_2__FORCE_BIF_REFCLK_EN__SHIFT, 0, 0x0 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixMPLL_BYPASSCLK_SEL }, @@ -104,8 +99,7 @@ static const struct baco_cmd_entry clk_req_b_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 } }; -static const struct baco_cmd_entry enter_baco_tbl[] = -{ +static const struct baco_cmd_entry enter_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, @@ -122,8 +116,7 @@ static const struct baco_cmd_entry enter_baco_tbl[] = #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK -static const struct baco_cmd_entry exit_baco_tbl[] = -{ +static const struct baco_cmd_entry exit_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, @@ -138,8 +131,7 @@ static const struct baco_cmd_entry exit_baco_tbl[] = { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } }; -static const struct baco_cmd_entry clean_baco_tbl[] = -{ +static const struct baco_cmd_entry clean_baco_tbl[] = { { CMD_WRITE, mmBIOS_SCRATCH_0, 0, 0, 0, 0 }, { CMD_WRITE, mmBIOS_SCRATCH_1, 0, 0, 0, 0 }, { CMD_WRITE, mmBIOS_SCRATCH_2, 0, 0, 0, 0 }, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c index f2cef0930aa9..2b5ac21fee39 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c @@ -120,7 +120,7 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) case CHIP_TOPAZ: hwmgr->smumgr_funcs = &iceland_smu_funcs; topaz_set_asic_special_caps(hwmgr); - hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK | + hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK | PP_ENABLE_GFX_CG_THRU_SMU); hwmgr->pp_table_version = PP_TABLE_V0; hwmgr->od_enabled = false; @@ -133,7 +133,7 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) case CHIP_FIJI: hwmgr->smumgr_funcs = &fiji_smu_funcs; fiji_set_asic_special_caps(hwmgr); - hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK | + hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK | PP_ENABLE_GFX_CG_THRU_SMU); break; case CHIP_POLARIS11: @@ -195,7 +195,7 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) int hwmgr_sw_init(struct pp_hwmgr *hwmgr) { - if (!hwmgr|| !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init) + if (!hwmgr || !hwmgr->smumgr_funcs || !hwmgr->smumgr_funcs->smu_init) return -EINVAL; phm_register_irq_handlers(hwmgr); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/polaris_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/polaris_baco.c index 8f8e296f2fe9..a6a6d43b09f8 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/polaris_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/polaris_baco.c @@ -35,8 +35,7 @@ #include "smu/smu_7_1_3_d.h" #include "smu/smu_7_1_3_sh_mask.h" -static const struct baco_cmd_entry gpio_tbl[] = -{ +static const struct baco_cmd_entry gpio_tbl[] = { { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, @@ -49,15 +48,13 @@ static const struct baco_cmd_entry gpio_tbl[] = { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } }; -static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = -{ +static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } }; -static const struct baco_cmd_entry use_bclk_tbl[] = -{ +static const struct baco_cmd_entry use_bclk_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, @@ -70,8 +67,7 @@ static const struct baco_cmd_entry use_bclk_tbl[] = { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } }; -static const struct baco_cmd_entry turn_off_plls_tbl[] = -{ +static const struct baco_cmd_entry turn_off_plls_tbl[] = { { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 }, { CMD_DELAY_US, 0, 0, 0, 1, 0x0 }, { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 }, @@ -92,8 +88,7 @@ static const struct baco_cmd_entry turn_off_plls_tbl[] = { CMD_DELAY_US, 0, 0, 0, 5, 0x0 } }; -static const struct baco_cmd_entry clk_req_b_tbl[] = -{ +static const struct baco_cmd_entry clk_req_b_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixTHM_CLK_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__CMON_CLK_SEL_MASK, THM_CLK_CNTL__CMON_CLK_SEL__SHIFT, 0, 0x1 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 }, @@ -108,8 +103,7 @@ static const struct baco_cmd_entry clk_req_b_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x4 } }; -static const struct baco_cmd_entry enter_baco_tbl[] = -{ +static const struct baco_cmd_entry enter_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, @@ -126,8 +120,7 @@ static const struct baco_cmd_entry enter_baco_tbl[] = #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK -static const struct baco_cmd_entry exit_baco_tbl[] = -{ +static const struct baco_cmd_entry exit_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, @@ -142,14 +135,12 @@ static const struct baco_cmd_entry exit_baco_tbl[] = { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } }; -static const struct baco_cmd_entry clean_baco_tbl[] = -{ +static const struct baco_cmd_entry clean_baco_tbl[] = { { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } }; -static const struct baco_cmd_entry use_bclk_tbl_vg[] = -{ +static const struct baco_cmd_entry use_bclk_tbl_vg[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0500170 }, @@ -160,8 +151,7 @@ static const struct baco_cmd_entry use_bclk_tbl_vg[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL_MASK, MPLL_BYPASSCLK_SEL__MPLL_CLKOUT_SEL__SHIFT, 0, 0x2 } }; -static const struct baco_cmd_entry turn_off_plls_tbl_vg[] = -{ +static const struct baco_cmd_entry turn_off_plls_tbl_vg[] = { { CMD_READMODIFYWRITE, mmDC_GPIO_PAD_STRENGTH_1, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP_MASK, DC_GPIO_PAD_STRENGTH_1__GENLK_STRENGTH_SP__SHIFT, 0, 0x1 }, { CMD_DELAY_US, 0, 0, 0, 1, 0x0 }, { CMD_READMODIFYWRITE, mmMC_SEQ_DRAM, MC_SEQ_DRAM__RST_CTL_MASK, MC_SEQ_DRAM__RST_CTL__SHIFT, 0, 0x1 }, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.h index b3103bd4be42..1f987e846628 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.h @@ -278,16 +278,14 @@ struct pp_atom_ctrl__avfs_parameters { uint8_t ucReserved; }; -struct _AtomCtrl_HiLoLeakageOffsetTable -{ +struct _AtomCtrl_HiLoLeakageOffsetTable { USHORT usHiLoLeakageThreshold; USHORT usEdcDidtLoDpm7TableOffset; USHORT usEdcDidtHiDpm7TableOffset; }; typedef struct _AtomCtrl_HiLoLeakageOffsetTable AtomCtrl_HiLoLeakageOffsetTable; -struct _AtomCtrl_EDCLeakgeTable -{ +struct _AtomCtrl_EDCLeakgeTable { ULONG DIDT_REG[24]; }; typedef struct _AtomCtrl_EDCLeakgeTable AtomCtrl_EDCLeakgeTable; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h index 2fc1733bcdcf..e86e05c786d9 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.h @@ -147,8 +147,7 @@ struct pp_atomfwctrl_bios_boot_up_values { uint8_t ucCoolingID; }; -struct pp_atomfwctrl_smc_dpm_parameters -{ +struct pp_atomfwctrl_smc_dpm_parameters { uint8_t liquid1_i2c_address; uint8_t liquid2_i2c_address; uint8_t vr_i2c_address; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h index dac29fe6cfc6..6f54c410c2f9 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h @@ -166,7 +166,7 @@ static fInt fNaturalLog(fInt value) error_term = fAdd(fNegativeOne, value); - return (fAdd(solution, error_term)); + return fAdd(solution, error_term); } static fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength) @@ -230,7 +230,7 @@ static fInt ConvertToFraction(int X) /*Add all range checking here. Is it possib static fInt fNegate(fInt X) { fInt CONSTANT_NEGONE = ConvertToFraction(-1); - return (fMultiply(X, CONSTANT_NEGONE)); + return fMultiply(X, CONSTANT_NEGONE); } static fInt Convert_ULONG_ToFraction(uint32_t X) @@ -382,14 +382,14 @@ static int ConvertBackToInteger (fInt A) /*THIS is the function that will be use scaledDecimal.full = uGetScaledDecimal(A); - fullNumber = fAdd(scaledDecimal,scaledReal); + fullNumber = fAdd(scaledDecimal, scaledReal); return fullNumber.full; } static fInt fGetSquare(fInt A) { - return fMultiply(A,A); + return fMultiply(A, A); } /* x_new = x_old - (x_old^2 - C) / (2 * x_old) */ @@ -447,7 +447,7 @@ static fInt fSqrt(fInt num) } while (uAbs(error) > 0); - return (x_new); + return x_new; } static void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[]) @@ -459,7 +459,7 @@ static void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[]) f_CONSTANT100 = ConvertToFraction(100); f_CONSTANT10 = ConvertToFraction(10); - while(GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) { + while (GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) { A = fDivide(A, f_CONSTANT10); B = fDivide(B, f_CONSTANT10); C = fDivide(C, f_CONSTANT10); @@ -515,7 +515,7 @@ static int uGetScaledDecimal (fInt A) /*Converts the fractional portion to whole dec[i] = tmp / (1 << SHIFT_AMOUNT); tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]); tmp *= 10; - scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i); + scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 - i); } return scaledDecimal; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h index b0ac4d121adc..2cf2a7b12623 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pptable_v1_0.h @@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State { typedef struct _ATOM_Tonga_State_Array { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_State_Array; typedef struct _ATOM_Tonga_MCLK_Dependency_Record { @@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Record { typedef struct _ATOM_Tonga_MCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_MCLK_Dependency_Table; typedef struct _ATOM_Tonga_SCLK_Dependency_Record { @@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Record { typedef struct _ATOM_Tonga_SCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_SCLK_Dependency_Table; typedef struct _ATOM_Polaris_SCLK_Dependency_Record { @@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Record { typedef struct _ATOM_Polaris_SCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Polaris_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Polaris_SCLK_Dependency_Table; typedef struct _ATOM_Tonga_PCIE_Record { @@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Record { typedef struct _ATOM_Tonga_PCIE_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_PCIE_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_PCIE_Table; typedef struct _ATOM_Polaris10_PCIE_Record { @@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Record { typedef struct _ATOM_Polaris10_PCIE_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Polaris10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Polaris10_PCIE_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Polaris10_PCIE_Table; @@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Record { typedef struct _ATOM_Tonga_MM_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_MM_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_MM_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_MM_Dependency_Table; typedef struct _ATOM_Tonga_Voltage_Lookup_Record { @@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Record { typedef struct _ATOM_Tonga_Voltage_Lookup_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_Voltage_Lookup_Table; typedef struct _ATOM_Tonga_Fan_Table { @@ -367,7 +367,7 @@ typedef struct _ATOM_Tonga_VCE_State_Record { typedef struct _ATOM_Tonga_VCE_State_Table { UCHAR ucRevId; UCHAR ucNumEntries; - ATOM_Tonga_VCE_State_Record entries[1]; + ATOM_Tonga_VCE_State_Record entries[]; } ATOM_Tonga_VCE_State_Table; typedef struct _ATOM_Tonga_PowerTune_Table { @@ -419,8 +419,7 @@ typedef struct _ATOM_Fiji_PowerTune_Table { USHORT usReserved; } ATOM_Fiji_PowerTune_Table; -typedef struct _ATOM_Polaris_PowerTune_Table -{ +typedef struct _ATOM_Polaris_PowerTune_Table { UCHAR ucRevId; USHORT usTDP; USHORT usConfigurableTDP; @@ -482,7 +481,7 @@ typedef struct _ATOM_Tonga_Hard_Limit_Record { typedef struct _ATOM_Tonga_Hard_Limit_Table { UCHAR ucRevId; UCHAR ucNumEntries; - ATOM_Tonga_Hard_Limit_Record entries[1]; + ATOM_Tonga_Hard_Limit_Record entries[]; } ATOM_Tonga_Hard_Limit_Table; typedef struct _ATOM_Tonga_GPIO_Table { diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c index 182118e3fd5f..5794b64507bf 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c @@ -1237,7 +1237,7 @@ static int get_vce_clock_voltage_limit_table(struct pp_hwmgr *hwmgr, const VCEClockInfoArray *array) { unsigned long i; - struct phm_vce_clock_voltage_dependency_table *vce_table = NULL; + struct phm_vce_clock_voltage_dependency_table *vce_table; vce_table = kzalloc(struct_size(vce_table, entries, table->numEntries), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 86d6e88c7386..02ba68d7c654 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -430,37 +430,37 @@ static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, } /* temporary hardcoded clock voltage breakdown tables */ -static const DpmClock_t VddDcfClk[]= { +static const DpmClock_t VddDcfClk[] = { { 300, 2600}, { 600, 3200}, { 600, 3600}, }; -static const DpmClock_t VddSocClk[]= { +static const DpmClock_t VddSocClk[] = { { 478, 2600}, { 722, 3200}, { 722, 3600}, }; -static const DpmClock_t VddFClk[]= { +static const DpmClock_t VddFClk[] = { { 400, 2600}, {1200, 3200}, {1200, 3600}, }; -static const DpmClock_t VddDispClk[]= { +static const DpmClock_t VddDispClk[] = { { 435, 2600}, { 661, 3200}, {1086, 3600}, }; -static const DpmClock_t VddDppClk[]= { +static const DpmClock_t VddDppClk[] = { { 435, 2600}, { 661, 3200}, { 661, 3600}, }; -static const DpmClock_t VddPhyClk[]= { +static const DpmClock_t VddPhyClk[] = { { 540, 2600}, { 810, 3200}, { 810, 3600}, @@ -1358,7 +1358,7 @@ static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr, struct amdgpu_device *adev = hwmgr->adev; int i; - smu_set_watermarks_for_clocks_ranges(table,wm_with_clock_ranges); + smu_set_watermarks_for_clocks_ranges(table, wm_with_clock_ranges); if (adev->apu_flags & AMD_APU_IS_RAVEN2) { for (i = 0; i < NUM_WM_RANGES; i++) @@ -1461,7 +1461,7 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) phm_get_sysfs_buf(&buf, &size); - size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n",title[0], + size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n", title[0], title[1], title[2], title[3], title[4], title[5]); for (i = 0; i <= PP_SMC_POWER_PROFILE_COMPUTE; i++) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.h index 808e0ecbe1f0..42adc2a3dcbc 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.h @@ -192,7 +192,7 @@ struct smu10_clock_voltage_dependency_record { struct smu10_voltage_dependency_table { uint32_t count; - struct smu10_clock_voltage_dependency_record entries[]; + struct smu10_clock_voltage_dependency_record entries[] __counted_by(count); }; struct smu10_clock_voltage_information { diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 1cb402264497..11372fcc59c8 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -83,15 +83,15 @@ #define PCIE_BUS_CLK 10000 #define TCLK (PCIE_BUS_CLK / 10) -static struct profile_mode_setting smu7_profiling[7] = - {{0, 0, 0, 0, 0, 0, 0, 0}, +static struct profile_mode_setting smu7_profiling[7] = { + {0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 100, 30, 1, 0, 100, 10}, {1, 10, 0, 30, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 10, 16, 31}, {1, 0, 11, 50, 1, 0, 100, 10}, {1, 0, 5, 30, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, - }; +}; #define PPSMC_MSG_SetVBITimeout_VEGAM ((uint16_t) 0x310) @@ -904,7 +904,7 @@ static int smu7_setup_dpm_tables_v1(struct pp_hwmgr *hwmgr) dep_sclk_table->entries[i].clk; data->dpm_table.sclk_table.dpm_levels[data->dpm_table.sclk_table.count].enabled = - (i == 0) ? true : false; + i == 0; data->dpm_table.sclk_table.count++; } } @@ -919,7 +919,7 @@ static int smu7_setup_dpm_tables_v1(struct pp_hwmgr *hwmgr) data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].value = dep_mclk_table->entries[i].clk; data->dpm_table.mclk_table.dpm_levels[data->dpm_table.mclk_table.count].enabled = - (i == 0) ? true : false; + i == 0; data->dpm_table.mclk_table.count++; } } @@ -950,7 +950,7 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr) odn_table->odn_core_clock_dpm_levels.num_of_pl = data->golden_dpm_table.sclk_table.count; entries = odn_table->odn_core_clock_dpm_levels.entries; - for (i=0; i<data->golden_dpm_table.sclk_table.count; i++) { + for (i = 0; i < data->golden_dpm_table.sclk_table.count; i++) { entries[i].clock = data->golden_dpm_table.sclk_table.dpm_levels[i].value; entries[i].enabled = true; entries[i].vddc = dep_sclk_table->entries[i].vddc; @@ -962,7 +962,7 @@ static int smu7_odn_initial_default_setting(struct pp_hwmgr *hwmgr) odn_table->odn_memory_clock_dpm_levels.num_of_pl = data->golden_dpm_table.mclk_table.count; entries = odn_table->odn_memory_clock_dpm_levels.entries; - for (i=0; i<data->golden_dpm_table.mclk_table.count; i++) { + for (i = 0; i < data->golden_dpm_table.mclk_table.count; i++) { entries[i].clock = data->golden_dpm_table.mclk_table.dpm_levels[i].value; entries[i].enabled = true; entries[i].vddc = dep_mclk_table->entries[i].vddc; @@ -1813,19 +1813,17 @@ static void smu7_init_dpm_defaults(struct pp_hwmgr *hwmgr) data->static_screen_threshold = SMU7_STATICSCREENTHRESHOLD_DFLT; data->static_screen_threshold_unit = SMU7_STATICSCREENTHRESHOLDUNIT_DFLT; data->voting_rights_clients[0] = SMU7_VOTINGRIGHTSCLIENTS_DFLT0; - data->voting_rights_clients[1]= SMU7_VOTINGRIGHTSCLIENTS_DFLT1; + data->voting_rights_clients[1] = SMU7_VOTINGRIGHTSCLIENTS_DFLT1; data->voting_rights_clients[2] = SMU7_VOTINGRIGHTSCLIENTS_DFLT2; - data->voting_rights_clients[3]= SMU7_VOTINGRIGHTSCLIENTS_DFLT3; - data->voting_rights_clients[4]= SMU7_VOTINGRIGHTSCLIENTS_DFLT4; - data->voting_rights_clients[5]= SMU7_VOTINGRIGHTSCLIENTS_DFLT5; - data->voting_rights_clients[6]= SMU7_VOTINGRIGHTSCLIENTS_DFLT6; - data->voting_rights_clients[7]= SMU7_VOTINGRIGHTSCLIENTS_DFLT7; + data->voting_rights_clients[3] = SMU7_VOTINGRIGHTSCLIENTS_DFLT3; + data->voting_rights_clients[4] = SMU7_VOTINGRIGHTSCLIENTS_DFLT4; + data->voting_rights_clients[5] = SMU7_VOTINGRIGHTSCLIENTS_DFLT5; + data->voting_rights_clients[6] = SMU7_VOTINGRIGHTSCLIENTS_DFLT6; + data->voting_rights_clients[7] = SMU7_VOTINGRIGHTSCLIENTS_DFLT7; data->mclk_dpm_key_disabled = hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true; data->sclk_dpm_key_disabled = hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true; - data->pcie_dpm_key_disabled = - !amdgpu_device_pcie_dynamic_switching_supported() || - !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); + data->pcie_dpm_key_disabled = !(hwmgr->feature_mask & PP_PCIE_DPM_MASK); /* need to set voltage control types before EVV patching */ data->voltage_control = SMU7_VOLTAGE_CONTROL_NONE; data->vddci_control = SMU7_VOLTAGE_CONTROL_NONE; @@ -2002,7 +2000,7 @@ static int smu7_calculate_ro_range(struct pp_hwmgr *hwmgr) } else if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision) || ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) { min = 900; - max= 2100; + max = 2100; } else if (hwmgr->chip_id == CHIP_POLARIS10) { if (adev->pdev->subsystem_vendor == 0x106B) { min = 1000; @@ -4018,7 +4016,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, offset = data->soft_regs_start + smum_get_offsetof(hwmgr, SMU_SoftRegisters, (idx == AMDGPU_PP_SENSOR_GPU_LOAD) ? - AverageGraphicsActivity: + AverageGraphicsActivity : AverageMemoryActivity); activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset); @@ -4039,7 +4037,7 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; return 0; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: return smu7_get_gpu_power(hwmgr, (uint32_t *)value); case AMDGPU_PP_SENSOR_VDDGFX: if ((data->vr_config & VRCONF_VDDGFX_MASK) == diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_powertune.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_powertune.c index 21be23ec3c79..65001bed0a9a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_powertune.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_powertune.c @@ -520,8 +520,7 @@ static const struct gpu_pt_config_reg DIDTConfig_Polaris12[] = { { 0xFFFFFFFF } }; -static const struct gpu_pt_config_reg DIDTConfig_Polaris11_Kicker[] = -{ +static const struct gpu_pt_config_reg DIDTConfig_Polaris11_Kicker[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value Type * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -646,7 +645,7 @@ static const struct gpu_pt_config_reg DIDTConfig_Polaris11_Kicker[] = { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, - { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT,0x01aa, GPU_CONFIGREG_DIDT_IND }, + { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT, 0x01aa, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__UNUSED_0_MASK, DIDT_TCP_STALL_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, @@ -666,8 +665,7 @@ static const struct gpu_pt_config_reg DIDTConfig_Polaris11_Kicker[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct gpu_pt_config_reg GCCACConfig_VegaM[] = -{ +static const struct gpu_pt_config_reg GCCACConfig_VegaM[] = { // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Offset Mask Shift Value Type // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -703,8 +701,7 @@ static const struct gpu_pt_config_reg GCCACConfig_VegaM[] = { 0xFFFFFFFF } // End of list }; -static const struct gpu_pt_config_reg DIDTConfig_VegaM[] = -{ +static const struct gpu_pt_config_reg DIDTConfig_VegaM[] = { // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Offset Mask Shift Value Type // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -831,7 +828,7 @@ static const struct gpu_pt_config_reg DIDTConfig_VegaM[] = { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_CTRL_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_HI__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO_MASK, DIDT_TCP_STALL_CTRL__DIDT_STALL_DELAY_LO__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, - { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT,0x01aa, GPU_CONFIGREG_DIDT_IND }, + { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD_MASK, DIDT_TCP_STALL_CTRL__DIDT_HI_POWER_THRESHOLD__SHIFT, 0x01aa, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_STALL_CTRL, DIDT_TCP_STALL_CTRL__UNUSED_0_MASK, DIDT_TCP_STALL_CTRL__UNUSED_0__SHIFT, 0x0000, GPU_CONFIGREG_DIDT_IND }, { ixDIDT_TCP_TUNING_CTRL, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE_MASK, DIDT_TCP_TUNING_CTRL__DIDT_TUNING_ENABLE__SHIFT, 0x0001, GPU_CONFIGREG_DIDT_IND }, @@ -1103,7 +1100,7 @@ int smu7_enable_smc_cac(struct pp_hwmgr *hwmgr) PP_ASSERT_WITH_CODE((0 == smc_result), "Failed to enable CAC in SMC.", result = -1); - data->cac_enabled = (0 == smc_result) ? true : false; + data->cac_enabled = smc_result == 0; } return result; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c index a6c3610db23e..a8fc0fa44db6 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_thermal.c @@ -72,7 +72,7 @@ int smu7_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, tmp64 = (uint64_t)duty * 255; do_div(tmp64, duty100); - *speed = MIN((uint32_t)tmp64, 255); + *speed = min_t(uint32_t, tmp64, 255); return 0; } @@ -210,7 +210,7 @@ int smu7_fan_ctrl_set_fan_speed_pwm(struct pp_hwmgr *hwmgr, if (hwmgr->thermal_controller.fanInfo.bNoFan) return 0; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) smu7_fan_ctrl_stop_smc_fan_control(hwmgr); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c index d0b1ab6c4523..79a566f3564a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c @@ -696,7 +696,7 @@ int smu_get_voltage_dependency_table_ppt_v1( return -EINVAL); dep_table->count = allowed_dep_table->count; - for (i=0; i<dep_table->count; i++) { + for (i = 0; i < dep_table->count; i++) { dep_table->entries[i].clk = allowed_dep_table->entries[i].clk; dep_table->entries[i].vddInd = allowed_dep_table->entries[i].vddInd; dep_table->entries[i].vdd_offset = allowed_dep_table->entries[i].vdd_offset; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h index 2a75da1e9f03..83b3c9315143 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h @@ -194,7 +194,7 @@ int smu_set_watermarks_for_clocks_ranges(void *wt_table, #define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \ PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, \ (fieldval) << PHM_FIELD_SHIFT(reg, field), \ - PHM_FIELD_MASK(reg, field) ) + PHM_FIELD_MASK(reg, field)) #define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, \ diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/tonga_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/tonga_baco.c index ea743bea8e29..432d4fd2a0ba 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/tonga_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/tonga_baco.c @@ -36,8 +36,7 @@ #include "smu/smu_7_1_2_sh_mask.h" -static const struct baco_cmd_entry gpio_tbl[] = -{ +static const struct baco_cmd_entry gpio_tbl[] = { { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, @@ -50,15 +49,13 @@ static const struct baco_cmd_entry gpio_tbl[] = { CMD_READMODIFYWRITE, mmDC_GPIO_SYNCA_MASK, 0, 0, 0, 0x00001111 } }; -static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = -{ +static const struct baco_cmd_entry enable_fb_req_rej_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, 0xC0300024 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, 0x1, 0x0, 0, 0x1 }, { CMD_WRITE, mmBIF_FB_EN, 0, 0, 0, 0x0 } }; -static const struct baco_cmd_entry use_bclk_tbl[] = -{ +static const struct baco_cmd_entry use_bclk_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN_MASK, CG_SPLL_FUNC_CNTL__SPLL_BYPASS_EN__SHIFT, 0, 0x1 }, { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL_2 }, @@ -80,8 +77,7 @@ static const struct baco_cmd_entry use_bclk_tbl[] = { CMD_READMODIFYWRITE, mmMPLL_CNTL_MODE, MPLL_CNTL_MODE__MPLL_MCLK_SEL_MASK, MPLL_CNTL_MODE__MPLL_MCLK_SEL__SHIFT, 0, 0x0 } }; -static const struct baco_cmd_entry turn_off_plls_tbl[] = -{ +static const struct baco_cmd_entry turn_off_plls_tbl[] = { { CMD_WRITE, mmGCK_SMC_IND_INDEX, 0, 0, 0, ixCG_SPLL_FUNC_CNTL }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_RESET_MASK, CG_SPLL_FUNC_CNTL__SPLL_RESET__SHIFT, 0, 0x1 }, { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, CG_SPLL_FUNC_CNTL__SPLL_PWRON_MASK, CG_SPLL_FUNC_CNTL__SPLL_PWRON__SHIFT, 0, 0x0 }, @@ -112,8 +108,7 @@ static const struct baco_cmd_entry turn_off_plls_tbl[] = { CMD_READMODIFYWRITE, mmGCK_SMC_IND_DATA, THM_CLK_CNTL__TMON_CLK_SEL_MASK, THM_CLK_CNTL__TMON_CLK_SEL__SHIFT, 0, 0x1 } }; -static const struct baco_cmd_entry enter_baco_tbl[] = -{ +static const struct baco_cmd_entry enter_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_SCLK_SWITCH__SHIFT, 0, 0x01 }, { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_BIF_SCLK_SWITCH_MASK, 0, 5, 0x40000 }, @@ -130,8 +125,7 @@ static const struct baco_cmd_entry enter_baco_tbl[] = #define BACO_CNTL__PWRGOOD_MASK BACO_CNTL__PWRGOOD_GPIO_MASK+BACO_CNTL__PWRGOOD_MEM_MASK+BACO_CNTL__PWRGOOD_DVO_MASK -static const struct baco_cmd_entry exit_baco_tbl[] = -{ +static const struct baco_cmd_entry exit_baco_tbl[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, @@ -146,22 +140,19 @@ static const struct baco_cmd_entry exit_baco_tbl[] = { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } }; -static const struct baco_cmd_entry clean_baco_tbl[] = -{ +static const struct baco_cmd_entry clean_baco_tbl[] = { { CMD_WRITE, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } }; -static const struct baco_cmd_entry gpio_tbl_iceland[] = -{ +static const struct baco_cmd_entry gpio_tbl_iceland[] = { { CMD_WRITE, mmGPIOPAD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PD_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_PU_EN, 0, 0, 0, 0x0 }, { CMD_WRITE, mmGPIOPAD_MASK, 0, 0, 0, 0xff77ffff } }; -static const struct baco_cmd_entry exit_baco_tbl_iceland[] = -{ +static const struct baco_cmd_entry exit_baco_tbl_iceland[] = { { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_RESET_EN_MASK, BACO_CNTL__BACO_RESET_EN__SHIFT, 0, 0x01 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_BCLK_OFF_MASK, BACO_CNTL__BACO_BCLK_OFF__SHIFT, 0, 0x00 }, { CMD_READMODIFYWRITE, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0x00 }, @@ -177,8 +168,7 @@ static const struct baco_cmd_entry exit_baco_tbl_iceland[] = { CMD_WAITFOR, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0x00 } }; -static const struct baco_cmd_entry clean_baco_tbl_iceland[] = -{ +static const struct baco_cmd_entry clean_baco_tbl_iceland[] = { { CMD_WRITE, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_baco.c index 46bb16c29cf6..6836e98d37be 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_baco.c @@ -31,24 +31,22 @@ -static const struct soc15_baco_cmd_entry pre_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry pre_baco_tbl[] = { {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIF_DOORBELL_CNTL), BIF_DOORBELL_CNTL__DOORBELL_MONITOR_EN_MASK, BIF_DOORBELL_CNTL__DOORBELL_MONITOR_EN__SHIFT, 0, 1}, {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIF_FB_EN), 0, 0, 0, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_DSTATE_BYPASS_MASK, BACO_CNTL__BACO_DSTATE_BYPASS__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_RST_INTR_MASK_MASK, BACO_CNTL__BACO_RST_INTR_MASK__SHIFT, 0, 1} }; -static const struct soc15_baco_cmd_entry enter_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry enter_baco_tbl[] = { {CMD_WAITFOR, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__SOC_DOMAIN_IDLE_MASK, THM_BACO_CNTL__SOC_DOMAIN_IDLE__SHIFT, 0xffffffff, 0x80000000}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_BIF_LCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_LCLK_SWITCH__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_DUMMY_EN_MASK, BACO_CNTL__BACO_DUMMY_EN__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SOC_VDCI_RESET_MASK, THM_BACO_CNTL__BACO_SOC_VDCI_RESET__SHIFT, 0, 1}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SMNCLK_MUX_MASK, THM_BACO_CNTL__BACO_SMNCLK_MUX__SHIFT,0, 1}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SMNCLK_MUX_MASK, THM_BACO_CNTL__BACO_SMNCLK_MUX__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_ISO_EN_MASK, THM_BACO_CNTL__BACO_ISO_EN__SHIFT, 0, 1}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_AEB_ISO_EN_MASK, THM_BACO_CNTL__BACO_AEB_ISO_EN__SHIFT,0, 1}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_AEB_ISO_EN_MASK, THM_BACO_CNTL__BACO_AEB_ISO_EN__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_ANA_ISO_EN_MASK, THM_BACO_CNTL__BACO_ANA_ISO_EN__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SOC_REFCLK_OFF_MASK, THM_BACO_CNTL__BACO_SOC_REFCLK_OFF__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 1}, @@ -58,13 +56,12 @@ static const struct soc15_baco_cmd_entry enter_baco_tbl[] = {CMD_WAITFOR, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_MODE_MASK, BACO_CNTL__BACO_MODE__SHIFT, 0xffffffff, 0x100} }; -static const struct soc15_baco_cmd_entry exit_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry exit_baco_tbl[] = { {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0}, - {CMD_DELAY_MS, 0, 0, 0, 0, 0, 0, 10,0}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SOC_REFCLK_OFF_MASK, THM_BACO_CNTL__BACO_SOC_REFCLK_OFF__SHIFT, 0,0}, + {CMD_DELAY_MS, 0, 0, 0, 0, 0, 0, 10, 0}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SOC_REFCLK_OFF_MASK, THM_BACO_CNTL__BACO_SOC_REFCLK_OFF__SHIFT, 0, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_ANA_ISO_EN_MASK, THM_BACO_CNTL__BACO_ANA_ISO_EN__SHIFT, 0, 0}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_AEB_ISO_EN_MASK, THM_BACO_CNTL__BACO_AEB_ISO_EN__SHIFT,0, 0}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_AEB_ISO_EN_MASK, THM_BACO_CNTL__BACO_AEB_ISO_EN__SHIFT, 0, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_ISO_EN_MASK, THM_BACO_CNTL__BACO_ISO_EN__SHIFT, 0, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_PWROKRAW_CNTL_MASK, THM_BACO_CNTL__BACO_PWROKRAW_CNTL__SHIFT, 0, 1}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SMNCLK_MUX_MASK, THM_BACO_CNTL__BACO_SMNCLK_MUX__SHIFT, 0, 0}, @@ -74,13 +71,12 @@ static const struct soc15_baco_cmd_entry exit_baco_tbl[] = {CMD_WAITFOR, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_EXIT_MASK, 0, 0xffffffff, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(THM, 0, mmTHM_BACO_CNTL), THM_BACO_CNTL__BACO_SB_AXI_FENCE_MASK, THM_BACO_CNTL__BACO_SB_AXI_FENCE__SHIFT, 0, 0}, {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_DUMMY_EN_MASK, BACO_CNTL__BACO_DUMMY_EN__SHIFT, 0, 0}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_BIF_LCLK_SWITCH_MASK ,BACO_CNTL__BACO_BIF_LCLK_SWITCH__SHIFT, 0, 0}, - {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_EN_MASK , BACO_CNTL__BACO_EN__SHIFT, 0,0}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_BIF_LCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_LCLK_SWITCH__SHIFT, 0, 0}, + {CMD_READMODIFYWRITE, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 0}, {CMD_WAITFOR, SOC15_REG_ENTRY(NBIF, 0, mmBACO_CNTL), BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0} }; -static const struct soc15_baco_cmd_entry clean_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry clean_baco_tbl[] = { {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_6), 0, 0, 0, 0}, {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_7), 0, 0, 0, 0}, }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index c51dd4c74fe9..6d6bc6a380b3 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -1375,8 +1375,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) dep_mm_table->entries[i].eclk) { dpm_table->dpm_levels[dpm_table->count].value = dep_mm_table->entries[i].eclk; - dpm_table->dpm_levels[dpm_table->count].enabled = - (i == 0) ? true : false; + dpm_table->dpm_levels[dpm_table->count].enabled = i == 0; dpm_table->count++; } } @@ -1391,8 +1390,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) dep_mm_table->entries[i].vclk) { dpm_table->dpm_levels[dpm_table->count].value = dep_mm_table->entries[i].vclk; - dpm_table->dpm_levels[dpm_table->count].enabled = - (i == 0) ? true : false; + dpm_table->dpm_levels[dpm_table->count].enabled = i == 0; dpm_table->count++; } } @@ -1405,8 +1403,7 @@ static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) dep_mm_table->entries[i].dclk) { dpm_table->dpm_levels[dpm_table->count].value = dep_mm_table->entries[i].dclk; - dpm_table->dpm_levels[dpm_table->count].enabled = - (i == 0) ? true : false; + dpm_table->dpm_levels[dpm_table->count].enabled = i == 0; dpm_table->count++; } } @@ -3969,7 +3966,7 @@ static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = vega10_get_gpu_power(hwmgr, (uint32_t *)value); break; case AMDGPU_PP_SENSOR_VDDGFX: diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c index 309a9d3bc1b7..3007b054c873 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c @@ -30,8 +30,7 @@ #include "pp_debug.h" #include "soc15_common.h" -static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -55,8 +54,7 @@ static const struct vega10_didt_config_reg SEDiDtTuningCtrlConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEDiDtCtrl3Config_vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtCtrl3Config_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -120,8 +118,7 @@ static const struct vega10_didt_config_reg SEDiDtCtrl3Config_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEDiDtCtrl2Config_Vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtCtrl2Config_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -149,8 +146,7 @@ static const struct vega10_didt_config_reg SEDiDtCtrl2Config_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEDiDtCtrl1Config_Vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtCtrl1Config_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -172,8 +168,7 @@ static const struct vega10_didt_config_reg SEDiDtCtrl1Config_Vega10[] = }; -static const struct vega10_didt_config_reg SEDiDtWeightConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtWeightConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -201,8 +196,7 @@ static const struct vega10_didt_config_reg SEDiDtWeightConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEDiDtCtrl0Config_Vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtCtrl0Config_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -260,8 +254,7 @@ static const struct vega10_didt_config_reg SEDiDtCtrl0Config_Vega10[] = }; -static const struct vega10_didt_config_reg SEDiDtStallCtrlConfig_vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtStallCtrlConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -293,8 +286,7 @@ static const struct vega10_didt_config_reg SEDiDtStallCtrlConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEDiDtStallPatternConfig_vega10[] = -{ +static const struct vega10_didt_config_reg SEDiDtStallPatternConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -362,8 +354,7 @@ static const struct vega10_didt_config_reg SEDiDtStallPatternConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SELCacConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SELCacConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -401,8 +392,7 @@ static const struct vega10_didt_config_reg SELCacConfig_Vega10[] = }; -static const struct vega10_didt_config_reg SEEDCStallPatternConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCStallPatternConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -431,8 +421,7 @@ static const struct vega10_didt_config_reg SEEDCStallPatternConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCForceStallPatternConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCForceStallPatternConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -451,8 +440,7 @@ static const struct vega10_didt_config_reg SEEDCForceStallPatternConfig_Vega10[] { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCStallDelayConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCStallDelayConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -478,8 +466,7 @@ static const struct vega10_didt_config_reg SEEDCStallDelayConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCThresholdConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCThresholdConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -492,8 +479,7 @@ static const struct vega10_didt_config_reg SEEDCThresholdConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCCtrlResetConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCCtrlResetConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -514,8 +500,7 @@ static const struct vega10_didt_config_reg SEEDCCtrlResetConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCCtrlConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCCtrlConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -536,8 +521,7 @@ static const struct vega10_didt_config_reg SEEDCCtrlConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg SEEDCCtrlForceStallConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg SEEDCCtrlForceStallConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -571,8 +555,7 @@ static const struct vega10_didt_config_reg SEEDCCtrlForceStallConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg GCDiDtDroopCtrlConfig_vega10[] = -{ +static const struct vega10_didt_config_reg GCDiDtDroopCtrlConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -586,8 +569,7 @@ static const struct vega10_didt_config_reg GCDiDtDroopCtrlConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg GCDiDtCtrl0Config_vega10[] = -{ +static const struct vega10_didt_config_reg GCDiDtCtrl0Config_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -601,8 +583,7 @@ static const struct vega10_didt_config_reg GCDiDtCtrl0Config_vega10[] = }; -static const struct vega10_didt_config_reg PSMSEEDCStallPatternConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg PSMSEEDCStallPatternConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -621,8 +602,7 @@ static const struct vega10_didt_config_reg PSMSEEDCStallPatternConfig_Vega10[] { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMSEEDCStallDelayConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg PSMSEEDCStallDelayConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -651,8 +631,7 @@ static const struct vega10_didt_config_reg PSMSEEDCStallDelayConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMSEEDCCtrlResetConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg PSMSEEDCCtrlResetConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -673,8 +652,7 @@ static const struct vega10_didt_config_reg PSMSEEDCCtrlResetConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMSEEDCCtrlConfig_Vega10[] = -{ +static const struct vega10_didt_config_reg PSMSEEDCCtrlConfig_Vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -695,8 +673,7 @@ static const struct vega10_didt_config_reg PSMSEEDCCtrlConfig_Vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMGCEDCDroopCtrlConfig_vega10[] = -{ +static const struct vega10_didt_config_reg PSMGCEDCDroopCtrlConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -710,8 +687,7 @@ static const struct vega10_didt_config_reg PSMGCEDCDroopCtrlConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMGCEDCCtrlResetConfig_vega10[] = -{ +static const struct vega10_didt_config_reg PSMGCEDCCtrlResetConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -726,8 +702,7 @@ static const struct vega10_didt_config_reg PSMGCEDCCtrlResetConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg PSMGCEDCCtrlConfig_vega10[] = -{ +static const struct vega10_didt_config_reg PSMGCEDCCtrlConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -742,8 +717,7 @@ static const struct vega10_didt_config_reg PSMGCEDCCtrlConfig_vega10[] = { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg AvfsPSMResetConfig_vega10[]= -{ +static const struct vega10_didt_config_reg AvfsPSMResetConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -756,8 +730,7 @@ static const struct vega10_didt_config_reg AvfsPSMResetConfig_vega10[]= { 0xFFFFFFFF } /* End of list */ }; -static const struct vega10_didt_config_reg AvfsPSMInitConfig_vega10[] = -{ +static const struct vega10_didt_config_reg AvfsPSMInitConfig_vega10[] = { /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- * Offset Mask Shift Value * --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -919,7 +892,7 @@ static int vega10_enable_cac_driving_se_didt_config(struct pp_hwmgr *hwmgr) mutex_lock(&adev->grbm_idx_mutex); for (count = 0; count < num_se; count++) { - data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); + data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | (count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data); result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT); @@ -970,7 +943,7 @@ static int vega10_enable_psm_gc_didt_config(struct pp_hwmgr *hwmgr) mutex_lock(&adev->grbm_idx_mutex); for (count = 0; count < num_se; count++) { - data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); + data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | (count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data); result = vega10_program_didt_config_registers(hwmgr, SEDiDtStallCtrlConfig_vega10, VEGA10_CONFIGREG_DIDT); @@ -1031,7 +1004,7 @@ static int vega10_enable_se_edc_config(struct pp_hwmgr *hwmgr) mutex_lock(&adev->grbm_idx_mutex); for (count = 0; count < num_se; count++) { - data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); + data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | (count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data); result = vega10_program_didt_config_registers(hwmgr, SEDiDtWeightConfig_Vega10, VEGA10_CONFIGREG_DIDT); result |= vega10_program_didt_config_registers(hwmgr, SEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); @@ -1081,7 +1054,7 @@ static int vega10_enable_psm_gc_edc_config(struct pp_hwmgr *hwmgr) mutex_lock(&adev->grbm_idx_mutex); for (count = 0; count < num_se; count++) { - data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | ( count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); + data = GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK | GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK | (count << GRBM_GFX_INDEX__SE_INDEX__SHIFT); WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, data); result = vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT); result |= vega10_program_didt_config_registers(hwmgr, PSMSEEDCStallDelayConfig_Vega10, VEGA10_CONFIGREG_DIDT); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h index 9c479bd9a786..de2926df5ed7 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_pptable.h @@ -129,7 +129,7 @@ typedef struct _ATOM_Vega10_State { typedef struct _ATOM_Vega10_State_Array { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_State states[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_State states[]; /* Dynamically allocate entries. */ } ATOM_Vega10_State_Array; typedef struct _ATOM_Vega10_CLK_Dependency_Record { @@ -169,37 +169,37 @@ typedef struct _ATOM_Vega10_GFXCLK_Dependency_Table { typedef struct _ATOM_Vega10_MCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_MCLK_Dependency_Table; typedef struct _ATOM_Vega10_SOCCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_SOCCLK_Dependency_Table; typedef struct _ATOM_Vega10_DCEFCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_DCEFCLK_Dependency_Table; typedef struct _ATOM_Vega10_PIXCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_PIXCLK_Dependency_Table; typedef struct _ATOM_Vega10_DISPCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries.*/ - ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_DISPCLK_Dependency_Table; typedef struct _ATOM_Vega10_PHYCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_CLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_PHYCLK_Dependency_Table; typedef struct _ATOM_Vega10_MM_Dependency_Record { @@ -213,7 +213,7 @@ typedef struct _ATOM_Vega10_MM_Dependency_Record { typedef struct _ATOM_Vega10_MM_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries */ - ATOM_Vega10_MM_Dependency_Record entries[1]; /* Dynamically allocate entries */ + ATOM_Vega10_MM_Dependency_Record entries[]; /* Dynamically allocate entries */ } ATOM_Vega10_MM_Dependency_Table; typedef struct _ATOM_Vega10_PCIE_Record { @@ -225,7 +225,7 @@ typedef struct _ATOM_Vega10_PCIE_Record { typedef struct _ATOM_Vega10_PCIE_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries */ - ATOM_Vega10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Vega10_PCIE_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Vega10_PCIE_Table; typedef struct _ATOM_Vega10_Voltage_Lookup_Record { @@ -235,7 +235,7 @@ typedef struct _ATOM_Vega10_Voltage_Lookup_Record { typedef struct _ATOM_Vega10_Voltage_Lookup_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries */ - ATOM_Vega10_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries */ + ATOM_Vega10_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries */ } ATOM_Vega10_Voltage_Lookup_Table; typedef struct _ATOM_Vega10_Fan_Table { @@ -317,19 +317,17 @@ typedef struct _ATOM_Vega10_Thermal_Controller { UCHAR ucFlags; /* to be defined */ } ATOM_Vega10_Thermal_Controller; -typedef struct _ATOM_Vega10_VCE_State_Record -{ +typedef struct _ATOM_Vega10_VCE_State_Record { UCHAR ucVCEClockIndex; /*index into usVCEDependencyTableOffset of 'ATOM_Vega10_MM_Dependency_Table' type */ UCHAR ucFlag; /* 2 bits indicates memory p-states */ UCHAR ucSCLKIndex; /* index into ATOM_Vega10_SCLK_Dependency_Table */ UCHAR ucMCLKIndex; /* index into ATOM_Vega10_MCLK_Dependency_Table */ } ATOM_Vega10_VCE_State_Record; -typedef struct _ATOM_Vega10_VCE_State_Table -{ +typedef struct _ATOM_Vega10_VCE_State_Table { UCHAR ucRevId; UCHAR ucNumEntries; - ATOM_Vega10_VCE_State_Record entries[1]; + ATOM_Vega10_VCE_State_Record entries[]; } ATOM_Vega10_VCE_State_Table; typedef struct _ATOM_Vega10_PowerTune_Table { @@ -361,8 +359,7 @@ typedef struct _ATOM_Vega10_PowerTune_Table { USHORT usTemperatureLimitTedge; } ATOM_Vega10_PowerTune_Table; -typedef struct _ATOM_Vega10_PowerTune_Table_V2 -{ +typedef struct _ATOM_Vega10_PowerTune_Table_V2 { UCHAR ucRevId; USHORT usSocketPowerLimit; USHORT usBatteryPowerLimit; @@ -388,8 +385,7 @@ typedef struct _ATOM_Vega10_PowerTune_Table_V2 USHORT usTemperatureLimitTedge; } ATOM_Vega10_PowerTune_Table_V2; -typedef struct _ATOM_Vega10_PowerTune_Table_V3 -{ +typedef struct _ATOM_Vega10_PowerTune_Table_V3 { UCHAR ucRevId; USHORT usSocketPowerLimit; USHORT usBatteryPowerLimit; @@ -428,15 +424,13 @@ typedef struct _ATOM_Vega10_Hard_Limit_Record { USHORT usVddMemLimit; } ATOM_Vega10_Hard_Limit_Record; -typedef struct _ATOM_Vega10_Hard_Limit_Table -{ +typedef struct _ATOM_Vega10_Hard_Limit_Table { UCHAR ucRevId; UCHAR ucNumEntries; - ATOM_Vega10_Hard_Limit_Record entries[1]; + ATOM_Vega10_Hard_Limit_Record entries[]; } ATOM_Vega10_Hard_Limit_Table; -typedef struct _Vega10_PPTable_Generic_SubTable_Header -{ +typedef struct _Vega10_PPTable_Generic_SubTable_Header { UCHAR ucRevId; } Vega10_PPTable_Generic_SubTable_Header; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c index bb90d8abf79b..3be616af327e 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c @@ -372,9 +372,9 @@ static int get_mm_clock_voltage_table( return 0; } -static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t* sda) +static void get_scl_sda_value(uint8_t line, uint8_t *scl, uint8_t *sda) { - switch(line){ + switch (line) { case Vega10_I2CLineID_DDC1: *scl = Vega10_I2C_DDC1CLK; *sda = Vega10_I2C_DDC1DATA; @@ -954,7 +954,7 @@ static int init_powerplay_extended_tables( if (!result && powerplay_table->usPixclkDependencyTableOffset) result = get_pix_clk_voltage_dependency_table(hwmgr, &pp_table_info->vdd_dep_on_pixclk, - (const ATOM_Vega10_PIXCLK_Dependency_Table*) + (const ATOM_Vega10_PIXCLK_Dependency_Table *) pixclk_dep_table); if (!result && powerplay_table->usPhyClkDependencyTableOffset) diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c index 190af79f3236..379012494da5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c @@ -81,7 +81,7 @@ int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, tmp64 = (uint64_t)duty * 255; do_div(tmp64, duty100); - *speed = MIN((uint32_t)tmp64, 255); + *speed = min_t(uint32_t, tmp64, 255); return 0; } @@ -255,7 +255,7 @@ int vega10_fan_ctrl_set_fan_speed_pwm(struct pp_hwmgr *hwmgr, if (hwmgr->thermal_controller.fanInfo.bNoFan) return 0; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) vega10_fan_ctrl_stop_smc_fan_control(hwmgr); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_baco.c index bc53cce4f32d..32cc8de296e4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_baco.c @@ -29,16 +29,14 @@ #include "vega12_ppsmc.h" #include "vega12_baco.h" -static const struct soc15_baco_cmd_entry pre_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry pre_baco_tbl[] = { { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmBIF_DOORBELL_CNTL_BASE_IDX, mmBIF_DOORBELL_CNTL, BIF_DOORBELL_CNTL__DOORBELL_MONITOR_EN_MASK, BIF_DOORBELL_CNTL__DOORBELL_MONITOR_EN__SHIFT, 0, 0 }, { CMD_WRITE, NBIF_HWID, 0, mmBIF_FB_EN_BASE_IDX, mmBIF_FB_EN, 0, 0, 0, 0 }, { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_DSTATE_BYPASS_MASK, BACO_CNTL__BACO_DSTATE_BYPASS__SHIFT, 0, 1 }, { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_RST_INTR_MASK_MASK, BACO_CNTL__BACO_RST_INTR_MASK__SHIFT, 0, 1 } }; -static const struct soc15_baco_cmd_entry enter_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry enter_baco_tbl[] = { { CMD_WAITFOR, THM_HWID, 0, mmTHM_BACO_CNTL_BASE_IDX, mmTHM_BACO_CNTL, THM_BACO_CNTL__SOC_DOMAIN_IDLE_MASK, THM_BACO_CNTL__SOC_DOMAIN_IDLE__SHIFT, 0xffffffff, 0x80000000 }, { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_EN_MASK, BACO_CNTL__BACO_EN__SHIFT, 0, 1 }, { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_BIF_LCLK_SWITCH_MASK, BACO_CNTL__BACO_BIF_LCLK_SWITCH__SHIFT, 0, 1 }, @@ -56,8 +54,7 @@ static const struct soc15_baco_cmd_entry enter_baco_tbl[] = { CMD_WAITFOR, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, BACO_CNTL__BACO_MODE__SHIFT, 0xffffffff, 0x100 } }; -static const struct soc15_baco_cmd_entry exit_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry exit_baco_tbl[] = { { CMD_READMODIFYWRITE, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_POWER_OFF_MASK, BACO_CNTL__BACO_POWER_OFF__SHIFT, 0, 0 }, { CMD_DELAY_MS, 0, 0, 0, 0, 0, 0, 10, 0 }, { CMD_READMODIFYWRITE, THM_HWID, 0, mmTHM_BACO_CNTL_BASE_IDX, mmTHM_BACO_CNTL, THM_BACO_CNTL__BACO_SOC_REFCLK_OFF_MASK, THM_BACO_CNTL__BACO_SOC_REFCLK_OFF__SHIFT, 0, 0 }, @@ -77,8 +74,7 @@ static const struct soc15_baco_cmd_entry exit_baco_tbl[] = { CMD_WAITFOR, NBIF_HWID, 0, mmRCC_BACO_CNTL_MISC_BASE_IDX, mmBACO_CNTL, BACO_CNTL__BACO_MODE_MASK, 0, 0xffffffff, 0 } }; -static const struct soc15_baco_cmd_entry clean_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry clean_baco_tbl[] = { { CMD_WRITE, NBIF_HWID, 0, mmBIOS_SCRATCH_6_BASE_IDX, mmBIOS_SCRATCH_6, 0, 0, 0, 0 }, { CMD_WRITE, NBIF_HWID, 0, mmBIOS_SCRATCH_7_BASE_IDX, mmBIOS_SCRATCH_7, 0, 0, 0, 0 } }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c index 1937be1cf5b4..460067933de2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -1529,7 +1529,7 @@ static int vega12_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = vega12_get_gpu_power(hwmgr, (uint32_t *)value); if (!ret) *size = 4; @@ -1623,13 +1623,13 @@ static int vega12_notify_smc_display_config_after_ps_adjustment( if (data->smu_features[GNLD_DPM_DCEFCLK].supported) { clock_req.clock_type = amd_pp_dcef_clock; - clock_req.clock_freq_in_khz = min_clocks.dcefClock/10; + clock_req.clock_freq_in_khz = min_clocks.dcefClock / 10; if (!vega12_display_clock_voltage_request(hwmgr, &clock_req)) { if (data->smu_features[GNLD_DS_DCEFCLK].supported) PP_ASSERT_WITH_CODE( !smum_send_msg_to_smc_with_parameter( hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, - min_clocks.dcefClockInSR /100, + min_clocks.dcefClockInSR / 100, NULL), "Attempt to set divider for DCEFCLK Failed!", return -1); @@ -2354,8 +2354,8 @@ static int vega12_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) uint32_t i, latency; disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && - !hwmgr->display_config->multi_monitor_in_sync) || - vblank_too_short; + !hwmgr->display_config->multi_monitor_in_sync) || + vblank_too_short; latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; /* gfxclk */ @@ -2522,7 +2522,7 @@ static int vega12_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr, dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinByFreq, - (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level, + (PPCLK_UCLK << 16) | dpm_table->dpm_state.hard_min_level, NULL)), "[SetUclkToHightestDpmLevel] Set hard min uclk failed!", return ret); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.h index aa63ae41942d..9f2ce4308548 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.h @@ -38,8 +38,7 @@ #define VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS 8 #define VG12_PSUEDO_NUM_UCLK_DPM_LEVELS 4 -enum -{ +enum { GNLD_DPM_PREFETCHER = 0, GNLD_DPM_GFXCLK, GNLD_DPM_UCLK, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_pptable.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_pptable.h index bf4f5095b80d..9b8435a4d306 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_pptable.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_pptable.h @@ -72,8 +72,7 @@ enum ATOM_VEGA12_PPCLOCK_ID { typedef enum ATOM_VEGA12_PPCLOCK_ID ATOM_VEGA12_PPCLOCK_ID; -typedef struct _ATOM_VEGA12_POWERPLAYTABLE -{ +typedef struct _ATOM_VEGA12_POWERPLAYTABLE { struct atom_common_table_header sHeader; UCHAR ucTableRevision; USHORT usTableSize; @@ -92,11 +91,11 @@ typedef struct _ATOM_VEGA12_POWERPLAYTABLE USHORT usODPowerSavePowerLimit; USHORT usSoftwareShutdownTemp; - ULONG PowerSavingClockMax [ATOM_VEGA12_PPCLOCK_COUNT]; - ULONG PowerSavingClockMin [ATOM_VEGA12_PPCLOCK_COUNT]; + ULONG PowerSavingClockMax[ATOM_VEGA12_PPCLOCK_COUNT]; + ULONG PowerSavingClockMin[ATOM_VEGA12_PPCLOCK_COUNT]; - ULONG ODSettingsMax [ATOM_VEGA12_ODSETTING_COUNT]; - ULONG ODSettingsMin [ATOM_VEGA12_ODSETTING_COUNT]; + ULONG ODSettingsMax[ATOM_VEGA12_ODSETTING_COUNT]; + ULONG ODSettingsMin[ATOM_VEGA12_ODSETTING_COUNT]; USHORT usReserve[5]; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_baco.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_baco.c index 8d99c7a5abf8..994c0d374bfa 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_baco.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_baco.c @@ -31,8 +31,7 @@ #include "amdgpu_ras.h" -static const struct soc15_baco_cmd_entry clean_baco_tbl[] = -{ +static const struct soc15_baco_cmd_entry clean_baco_tbl[] = { {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_6), 0, 0, 0, 0}, {CMD_WRITE, SOC15_REG_ENTRY(NBIF, 0, mmBIOS_SCRATCH_7), 0, 0, 0, 0}, }; @@ -90,11 +89,11 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) data |= 0x80000000; WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); - if(smum_send_msg_to_smc_with_parameter(hwmgr, + if (smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0, NULL)) return -EINVAL; } else { - if(smum_send_msg_to_smc_with_parameter(hwmgr, + if (smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 1, NULL)) return -EINVAL; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 4e19ccbdb807..3b33af30eb0f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -1402,7 +1402,7 @@ static int vega20_od8_set_settings( "Failed to export over drive table!", return ret); - switch(index) { + switch (index) { case OD8_SETTING_GFXCLK_FMIN: od_table.GfxclkFmin = (uint16_t)value; break; @@ -2129,7 +2129,7 @@ static int vega20_get_metrics_table(struct pp_hwmgr *hwmgr, return ret; } -static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, +static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, int idx, uint32_t *query) { int ret = 0; @@ -2140,10 +2140,17 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr, return ret; /* For the 40.46 release, they changed the value name */ - if (hwmgr->smu_version == 0x282e00) - *query = metrics_table.AverageSocketPower << 8; - else + switch (idx) { + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: + if (hwmgr->smu_version == 0x282e00) + *query = metrics_table.AverageSocketPower << 8; + else + ret = -EOPNOTSUPP; + break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *query = metrics_table.CurrSocketPower << 8; + break; + } return ret; } @@ -2253,9 +2260,10 @@ static int vega20_read_sensor(struct pp_hwmgr *hwmgr, int idx, *((uint32_t *)value) = data->vce_power_gated ? 0 : 1; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: *size = 16; - ret = vega20_get_gpu_power(hwmgr, (uint32_t *)value); + ret = vega20_get_gpu_power(hwmgr, idx, (uint32_t *)value); break; case AMDGPU_PP_SENSOR_VDDGFX: val_vid = (RREG32_SOC15(SMUIO, 0, mmSMUSVI0_TEL_PLANE0) & @@ -2360,7 +2368,7 @@ static int vega20_notify_smc_display_config_after_ps_adjustment( dpm_table->dpm_state.hard_min_level = min_clocks.memoryClock / 100; PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinByFreq, - (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level, + (PPCLK_UCLK << 16) | dpm_table->dpm_state.hard_min_level, NULL)), "[SetHardMinFreq] Set hard min uclk failed!", return ret); @@ -3579,7 +3587,7 @@ static int vega20_set_uclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr, dpm_table->dpm_state.hard_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinByFreq, - (PPCLK_UCLK << 16 ) | dpm_table->dpm_state.hard_min_level, + (PPCLK_UCLK << 16) | dpm_table->dpm_state.hard_min_level, NULL)), "[SetUclkToHightestDpmLevel] Set hard min uclk failed!", return ret); @@ -3605,7 +3613,7 @@ static int vega20_set_fclk_to_highest_dpm_level(struct pp_hwmgr *hwmgr) dpm_table->dpm_state.soft_min_level = dpm_table->dpm_levels[dpm_table->count - 1].value; PP_ASSERT_WITH_CODE(!(ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetSoftMinByFreq, - (PPCLK_FCLK << 16 ) | dpm_table->dpm_state.soft_min_level, + (PPCLK_FCLK << 16) | dpm_table->dpm_state.soft_min_level, NULL)), "[SetFclkToHightestDpmLevel] Set soft min fclk failed!", return ret); @@ -3727,8 +3735,8 @@ static int vega20_apply_clocks_adjust_rules(struct pp_hwmgr *hwmgr) uint32_t i, latency; disable_mclk_switching = ((1 < hwmgr->display_config->num_display) && - !hwmgr->display_config->multi_monitor_in_sync) || - vblank_too_short; + !hwmgr->display_config->multi_monitor_in_sync) || + vblank_too_short; latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency; /* gfxclk */ diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.h index 075c0094da9c..1ba9b5fe2a5d 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.h @@ -385,8 +385,7 @@ struct vega20_odn_data { struct vega20_odn_temp_table odn_temp_table; }; -enum OD8_FEATURE_ID -{ +enum OD8_FEATURE_ID { OD8_GFXCLK_LIMITS = 1 << 0, OD8_GFXCLK_CURVE = 1 << 1, OD8_UCLK_MAX = 1 << 2, @@ -399,8 +398,7 @@ enum OD8_FEATURE_ID OD8_FAN_ZERO_RPM_CONTROL = 1 << 9 }; -enum OD8_SETTING_ID -{ +enum OD8_SETTING_ID { OD8_SETTING_GFXCLK_FMIN = 0, OD8_SETTING_GFXCLK_FMAX, OD8_SETTING_GFXCLK_FREQ1, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_pptable.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_pptable.h index 2222e29405c6..b468dddbefff 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_pptable.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_pptable.h @@ -73,14 +73,13 @@ enum ATOM_VEGA20_ODSETTING_ID { }; typedef enum ATOM_VEGA20_ODSETTING_ID ATOM_VEGA20_ODSETTING_ID; -typedef struct _ATOM_VEGA20_OVERDRIVE8_RECORD -{ +typedef struct _ATOM_VEGA20_OVERDRIVE8_RECORD { UCHAR ucODTableRevision; ULONG ODFeatureCount; - UCHAR ODFeatureCapabilities [ATOM_VEGA20_ODFEATURE_MAX_COUNT]; //OD feature support flags + UCHAR ODFeatureCapabilities[ATOM_VEGA20_ODFEATURE_MAX_COUNT]; //OD feature support flags ULONG ODSettingCount; - ULONG ODSettingsMax [ATOM_VEGA20_ODSETTING_MAX_COUNT]; //Upper Limit for each OD Setting - ULONG ODSettingsMin [ATOM_VEGA20_ODSETTING_MAX_COUNT]; //Lower Limit for each OD Setting + ULONG ODSettingsMax[ATOM_VEGA20_ODSETTING_MAX_COUNT]; //Upper Limit for each OD Setting + ULONG ODSettingsMin[ATOM_VEGA20_ODSETTING_MAX_COUNT]; //Lower Limit for each OD Setting } ATOM_VEGA20_OVERDRIVE8_RECORD; enum ATOM_VEGA20_PPCLOCK_ID { @@ -99,16 +98,14 @@ enum ATOM_VEGA20_PPCLOCK_ID { }; typedef enum ATOM_VEGA20_PPCLOCK_ID ATOM_VEGA20_PPCLOCK_ID; -typedef struct _ATOM_VEGA20_POWER_SAVING_CLOCK_RECORD -{ +typedef struct _ATOM_VEGA20_POWER_SAVING_CLOCK_RECORD { UCHAR ucTableRevision; ULONG PowerSavingClockCount; // Count of PowerSavingClock Mode - ULONG PowerSavingClockMax [ATOM_VEGA20_PPCLOCK_MAX_COUNT]; // PowerSavingClock Mode Clock Maximum array In MHz - ULONG PowerSavingClockMin [ATOM_VEGA20_PPCLOCK_MAX_COUNT]; // PowerSavingClock Mode Clock Minimum array In MHz + ULONG PowerSavingClockMax[ATOM_VEGA20_PPCLOCK_MAX_COUNT]; // PowerSavingClock Mode Clock Maximum array In MHz + ULONG PowerSavingClockMin[ATOM_VEGA20_PPCLOCK_MAX_COUNT]; // PowerSavingClock Mode Clock Minimum array In MHz } ATOM_VEGA20_POWER_SAVING_CLOCK_RECORD; -typedef struct _ATOM_VEGA20_POWERPLAYTABLE -{ +typedef struct _ATOM_VEGA20_POWERPLAYTABLE { struct atom_common_table_header sHeader; UCHAR ucTableRevision; USHORT usTableSize; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c index e9737ca8418a..a3331ffb2daf 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_thermal.c @@ -131,7 +131,7 @@ int vega20_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, tmp64 = (uint64_t)duty * 255; do_div(tmp64, duty100); - *speed = MIN((uint32_t)tmp64, 255); + *speed = min_t(uint32_t, tmp64, 255); return 0; } @@ -144,7 +144,7 @@ int vega20_fan_ctrl_set_fan_speed_pwm(struct pp_hwmgr *hwmgr, uint32_t duty; uint64_t tmp64; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl)) vega20_fan_ctrl_stop_smc_fan_control(hwmgr); diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/pm/powerplay/inc/hardwaremanager.h index 01a7d66864f2..f4f9a104d170 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/hardwaremanager.h @@ -44,8 +44,7 @@ struct phm_fan_speed_info { }; /* Automatic Power State Throttling */ -enum PHM_AutoThrottleSource -{ +enum PHM_AutoThrottleSource { PHM_AutoThrottleSource_Thermal, PHM_AutoThrottleSource_External }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h index 612d66aeaab9..81650727a5de 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h @@ -190,8 +190,7 @@ struct phm_vce_clock_voltage_dependency_table { }; -enum SMU_ASIC_RESET_MODE -{ +enum SMU_ASIC_RESET_MODE { SMU_ASIC_RESET_MODE_0, SMU_ASIC_RESET_MODE_1, SMU_ASIC_RESET_MODE_2, @@ -516,7 +515,7 @@ struct phm_vq_budgeting_record { struct phm_vq_budgeting_table { uint8_t numEntries; - struct phm_vq_budgeting_record entries[1]; + struct phm_vq_budgeting_record entries[0]; }; struct phm_clock_and_voltage_limits { @@ -607,8 +606,7 @@ struct phm_ppt_v2_information { uint8_t uc_dcef_dpm_voltage_mode; }; -struct phm_ppt_v3_information -{ +struct phm_ppt_v3_information { uint8_t uc_thermal_controller_type; uint16_t us_small_power_limit1; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/pp_thermal.h b/drivers/gpu/drm/amd/pm/powerplay/inc/pp_thermal.h index f7c41185097e..2003acc70ca0 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/pp_thermal.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/pp_thermal.h @@ -25,14 +25,12 @@ #include "power_state.h" -static const struct PP_TemperatureRange __maybe_unused SMU7ThermalWithDelayPolicy[] = -{ +static const struct PP_TemperatureRange __maybe_unused SMU7ThermalWithDelayPolicy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; -static const struct PP_TemperatureRange __maybe_unused SMU7ThermalPolicy[] = -{ +static const struct PP_TemperatureRange __maybe_unused SMU7ThermalPolicy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu7.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu7.h index e14072d45918..bfce9087a47f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu7.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu7.h @@ -101,8 +101,7 @@ #define VR_SMIO_PATTERN_2 4 #define VR_STATIC_VOLTAGE 5 -struct SMU7_PIDController -{ +struct SMU7_PIDController { uint32_t Ki; int32_t LFWindupUL; int32_t LFWindupLL; @@ -136,8 +135,7 @@ typedef struct SMU7_PIDController SMU7_PIDController; #define SMU7_VCE_MCLK_HANDSHAKE_DISABLE 0x00010000 #define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000 -struct SMU7_Firmware_Header -{ +struct SMU7_Firmware_Header { uint32_t Digest[5]; uint32_t Version; uint32_t HeaderSize; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu71.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu71.h index 71c9b2d28640..b5f177412769 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu71.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu71.h @@ -118,8 +118,7 @@ typedef struct { #endif -struct SMU71_PIDController -{ +struct SMU71_PIDController { uint32_t Ki; int32_t LFWindupUpperLim; int32_t LFWindupLowerLim; @@ -133,8 +132,7 @@ struct SMU71_PIDController typedef struct SMU71_PIDController SMU71_PIDController; -struct SMU7_LocalDpmScoreboard -{ +struct SMU7_LocalDpmScoreboard { uint32_t PercentageBusy; int32_t PIDError; @@ -179,8 +177,8 @@ struct SMU7_LocalDpmScoreboard uint8_t DteClampMode; uint8_t FpsClampMode; - uint16_t LevelResidencyCounters [SMU71_MAX_LEVELS_GRAPHICS]; - uint16_t LevelSwitchCounters [SMU71_MAX_LEVELS_GRAPHICS]; + uint16_t LevelResidencyCounters[SMU71_MAX_LEVELS_GRAPHICS]; + uint16_t LevelSwitchCounters[SMU71_MAX_LEVELS_GRAPHICS]; void (*TargetStateCalculator)(uint8_t); void (*SavedTargetStateCalculator)(uint8_t); @@ -200,8 +198,7 @@ typedef struct SMU7_LocalDpmScoreboard SMU7_LocalDpmScoreboard; #define SMU7_MAX_VOLTAGE_CLIENTS 12 -struct SMU7_VoltageScoreboard -{ +struct SMU7_VoltageScoreboard { uint16_t CurrentVoltage; uint16_t HighestVoltage; uint16_t MaxVid; @@ -325,8 +322,7 @@ typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard; // -------------------------------------------------------------------------------------------------- -struct SMU7_ThermalScoreboard -{ +struct SMU7_ThermalScoreboard { int16_t GpuLimit; int16_t GpuHyst; uint16_t CurrGnbTemp; @@ -360,8 +356,7 @@ typedef struct SMU7_ThermalScoreboard SMU7_ThermalScoreboard; #define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000 // All 'soft registers' should be uint32_t. -struct SMU71_SoftRegisters -{ +struct SMU71_SoftRegisters { uint32_t RefClockFrequency; uint32_t PmTimerPeriod; uint32_t FeatureEnables; @@ -413,8 +408,7 @@ struct SMU71_SoftRegisters typedef struct SMU71_SoftRegisters SMU71_SoftRegisters; -struct SMU71_Firmware_Header -{ +struct SMU71_Firmware_Header { uint32_t Digest[5]; uint32_t Version; uint32_t HeaderSize; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu73.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu73.h index c6b12a4c00db..cf4b2c3c65bc 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu73.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu73.h @@ -37,8 +37,7 @@ enum Poly3rdOrderCoeff { POLY_3RD_ORDER_COUNT }; -struct SMU7_Poly3rdOrder_Data -{ +struct SMU7_Poly3rdOrder_Data { int32_t a; int32_t b; int32_t c; @@ -51,8 +50,7 @@ struct SMU7_Poly3rdOrder_Data typedef struct SMU7_Poly3rdOrder_Data SMU7_Poly3rdOrder_Data; -struct Power_Calculator_Data -{ +struct Power_Calculator_Data { uint16_t NoLoadVoltage; uint16_t LoadVoltage; uint16_t Resistance; @@ -71,8 +69,7 @@ struct Power_Calculator_Data typedef struct Power_Calculator_Data PowerCalculatorData_t; -struct Gc_Cac_Weight_Data -{ +struct Gc_Cac_Weight_Data { uint8_t index; uint32_t value; }; @@ -187,8 +184,7 @@ typedef struct { #define SMU73_THERMAL_CLAMP_MODE_COUNT 8 -struct SMU7_HystController_Data -{ +struct SMU7_HystController_Data { uint16_t waterfall_up; uint16_t waterfall_down; uint16_t waterfall_limit; @@ -199,8 +195,7 @@ struct SMU7_HystController_Data typedef struct SMU7_HystController_Data SMU7_HystController_Data; -struct SMU73_PIDController -{ +struct SMU73_PIDController { uint32_t Ki; int32_t LFWindupUpperLim; int32_t LFWindupLowerLim; @@ -215,8 +210,7 @@ struct SMU73_PIDController typedef struct SMU73_PIDController SMU73_PIDController; -struct SMU7_LocalDpmScoreboard -{ +struct SMU7_LocalDpmScoreboard { uint32_t PercentageBusy; int32_t PIDError; @@ -261,8 +255,8 @@ struct SMU7_LocalDpmScoreboard uint8_t DteClampMode; uint8_t FpsClampMode; - uint16_t LevelResidencyCounters [SMU73_MAX_LEVELS_GRAPHICS]; - uint16_t LevelSwitchCounters [SMU73_MAX_LEVELS_GRAPHICS]; + uint16_t LevelResidencyCounters[SMU73_MAX_LEVELS_GRAPHICS]; + uint16_t LevelSwitchCounters[SMU73_MAX_LEVELS_GRAPHICS]; void (*TargetStateCalculator)(uint8_t); void (*SavedTargetStateCalculator)(uint8_t); @@ -315,8 +309,7 @@ typedef uint8_t (*VoltageChangeHandler_t)(uint16_t, uint8_t); typedef uint32_t SMU_VoltageLevel; -struct SMU7_VoltageScoreboard -{ +struct SMU7_VoltageScoreboard { SMU_VoltageLevel TargetVoltage; uint16_t MaxVid; uint8_t HighestVidOffset; @@ -354,7 +347,7 @@ struct SMU7_VoltageScoreboard VoltageChangeHandler_t functionLinks[6]; - uint16_t * VddcFollower1; + uint16_t *VddcFollower1; int16_t Driver_OD_RequestedVidOffset1; int16_t Driver_OD_RequestedVidOffset2; @@ -366,8 +359,7 @@ typedef struct SMU7_VoltageScoreboard SMU7_VoltageScoreboard; // ------------------------------------------------------------------------------------------------------------------------- #define SMU7_MAX_PCIE_LINK_SPEEDS 3 /* 0:Gen1 1:Gen2 2:Gen3 */ -struct SMU7_PCIeLinkSpeedScoreboard -{ +struct SMU7_PCIeLinkSpeedScoreboard { uint8_t DpmEnable; uint8_t DpmRunning; uint8_t DpmForce; @@ -396,8 +388,7 @@ typedef struct SMU7_PCIeLinkSpeedScoreboard SMU7_PCIeLinkSpeedScoreboard; #define SMU7_SCALE_I 7 #define SMU7_SCALE_R 12 -struct SMU7_PowerScoreboard -{ +struct SMU7_PowerScoreboard { uint32_t GpuPower; uint32_t VddcPower; @@ -436,8 +427,7 @@ typedef struct SMU7_PowerScoreboard SMU7_PowerScoreboard; #define SMU7_VCE_SCLK_HANDSHAKE_DISABLE 0x00020000 // All 'soft registers' should be uint32_t. -struct SMU73_SoftRegisters -{ +struct SMU73_SoftRegisters { uint32_t RefClockFrequency; uint32_t PmTimerPeriod; uint32_t FeatureEnables; @@ -493,8 +483,7 @@ struct SMU73_SoftRegisters typedef struct SMU73_SoftRegisters SMU73_SoftRegisters; -struct SMU73_Firmware_Header -{ +struct SMU73_Firmware_Header { uint32_t Digest[5]; uint32_t Version; uint32_t HeaderSize; @@ -708,9 +697,9 @@ typedef struct VFT_CELL_t VFT_CELL_t; struct VFT_TABLE_t { VFT_CELL_t Cell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS]; - uint16_t AvfsGbv [NUM_VFT_COLUMNS]; - uint16_t BtcGbv [NUM_VFT_COLUMNS]; - uint16_t Temperature [TEMP_RANGE_MAXSTEPS]; + uint16_t AvfsGbv[NUM_VFT_COLUMNS]; + uint16_t BtcGbv[NUM_VFT_COLUMNS]; + uint16_t Temperature[TEMP_RANGE_MAXSTEPS]; uint8_t NumTemperatureSteps; uint8_t padding[3]; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu73_discrete.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu73_discrete.h index 5916be08a7fe..fd0964ac465e 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu73_discrete.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu73_discrete.h @@ -27,8 +27,7 @@ #pragma pack(push, 1) -struct SMIO_Pattern -{ +struct SMIO_Pattern { uint16_t Voltage; uint8_t Smio; uint8_t padding; @@ -36,8 +35,7 @@ struct SMIO_Pattern typedef struct SMIO_Pattern SMIO_Pattern; -struct SMIO_Table -{ +struct SMIO_Table { SMIO_Pattern Pattern[SMU_MAX_SMIO_LEVELS]; }; @@ -100,8 +98,7 @@ struct SMU73_Discrete_Ulv { typedef struct SMU73_Discrete_Ulv SMU73_Discrete_Ulv; -struct SMU73_Discrete_MemoryLevel -{ +struct SMU73_Discrete_MemoryLevel { uint32_t MinVoltage; uint32_t MinMvdd; @@ -124,10 +121,9 @@ struct SMU73_Discrete_MemoryLevel typedef struct SMU73_Discrete_MemoryLevel SMU73_Discrete_MemoryLevel; -struct SMU73_Discrete_LinkLevel -{ +struct SMU73_Discrete_LinkLevel { uint8_t PcieGenSpeed; ///< 0:PciE-gen1 1:PciE-gen2 2:PciE-gen3 - uint8_t PcieLaneCount; ///< 1=x1, 2=x2, 3=x4, 4=x8, 5=x12, 6=x16 + uint8_t PcieLaneCount; ///< 1=x1, 2=x2, 3=x4, 4=x8, 5=x12, 6=x16 uint8_t EnabledForActivity; uint8_t SPC; uint32_t DownThreshold; @@ -139,8 +135,7 @@ typedef struct SMU73_Discrete_LinkLevel SMU73_Discrete_LinkLevel; // MC ARB DRAM Timing registers. -struct SMU73_Discrete_MCArbDramTimingTableEntry -{ +struct SMU73_Discrete_MCArbDramTimingTableEntry { uint32_t McArbDramTiming; uint32_t McArbDramTiming2; uint8_t McArbBurstTime; @@ -151,16 +146,14 @@ struct SMU73_Discrete_MCArbDramTimingTableEntry typedef struct SMU73_Discrete_MCArbDramTimingTableEntry SMU73_Discrete_MCArbDramTimingTableEntry; -struct SMU73_Discrete_MCArbDramTimingTable -{ +struct SMU73_Discrete_MCArbDramTimingTable { SMU73_Discrete_MCArbDramTimingTableEntry entries[SMU__NUM_SCLK_DPM_STATE][SMU__NUM_MCLK_DPM_LEVELS]; }; typedef struct SMU73_Discrete_MCArbDramTimingTable SMU73_Discrete_MCArbDramTimingTable; // UVD VCLK/DCLK state (level) definition. -struct SMU73_Discrete_UvdLevel -{ +struct SMU73_Discrete_UvdLevel { uint32_t VclkFrequency; uint32_t DclkFrequency; uint32_t MinVoltage; @@ -172,8 +165,7 @@ struct SMU73_Discrete_UvdLevel typedef struct SMU73_Discrete_UvdLevel SMU73_Discrete_UvdLevel; // Clocks for other external blocks (VCE, ACP, SAMU). -struct SMU73_Discrete_ExtClkLevel -{ +struct SMU73_Discrete_ExtClkLevel { uint32_t Frequency; uint32_t MinVoltage; uint8_t Divider; @@ -182,8 +174,7 @@ struct SMU73_Discrete_ExtClkLevel typedef struct SMU73_Discrete_ExtClkLevel SMU73_Discrete_ExtClkLevel; -struct SMU73_Discrete_StateInfo -{ +struct SMU73_Discrete_StateInfo { uint32_t SclkFrequency; uint32_t MclkFrequency; uint32_t VclkFrequency; @@ -206,8 +197,7 @@ struct SMU73_Discrete_StateInfo typedef struct SMU73_Discrete_StateInfo SMU73_Discrete_StateInfo; -struct SMU73_Discrete_DpmTable -{ +struct SMU73_Discrete_DpmTable { // Multi-DPM controller settings SMU73_PIDController GraphicsPIDController; SMU73_PIDController MemoryPIDController; @@ -225,9 +215,9 @@ struct SMU73_Discrete_DpmTable uint32_t MvddLevelCount; - uint8_t BapmVddcVidHiSidd [SMU73_MAX_LEVELS_VDDC]; - uint8_t BapmVddcVidLoSidd [SMU73_MAX_LEVELS_VDDC]; - uint8_t BapmVddcVidHiSidd2 [SMU73_MAX_LEVELS_VDDC]; + uint8_t BapmVddcVidHiSidd[SMU73_MAX_LEVELS_VDDC]; + uint8_t BapmVddcVidLoSidd[SMU73_MAX_LEVELS_VDDC]; + uint8_t BapmVddcVidHiSidd2[SMU73_MAX_LEVELS_VDDC]; uint8_t GraphicsDpmLevelCount; uint8_t MemoryDpmLevelCount; @@ -246,19 +236,19 @@ struct SMU73_Discrete_DpmTable uint32_t Reserved[4]; // State table entries for each DPM state - SMU73_Discrete_GraphicsLevel GraphicsLevel [SMU73_MAX_LEVELS_GRAPHICS]; + SMU73_Discrete_GraphicsLevel GraphicsLevel[SMU73_MAX_LEVELS_GRAPHICS]; SMU73_Discrete_MemoryLevel MemoryACPILevel; - SMU73_Discrete_MemoryLevel MemoryLevel [SMU73_MAX_LEVELS_MEMORY]; - SMU73_Discrete_LinkLevel LinkLevel [SMU73_MAX_LEVELS_LINK]; + SMU73_Discrete_MemoryLevel MemoryLevel[SMU73_MAX_LEVELS_MEMORY]; + SMU73_Discrete_LinkLevel LinkLevel[SMU73_MAX_LEVELS_LINK]; SMU73_Discrete_ACPILevel ACPILevel; - SMU73_Discrete_UvdLevel UvdLevel [SMU73_MAX_LEVELS_UVD]; - SMU73_Discrete_ExtClkLevel VceLevel [SMU73_MAX_LEVELS_VCE]; - SMU73_Discrete_ExtClkLevel AcpLevel [SMU73_MAX_LEVELS_ACP]; - SMU73_Discrete_ExtClkLevel SamuLevel [SMU73_MAX_LEVELS_SAMU]; + SMU73_Discrete_UvdLevel UvdLevel[SMU73_MAX_LEVELS_UVD]; + SMU73_Discrete_ExtClkLevel VceLevel[SMU73_MAX_LEVELS_VCE]; + SMU73_Discrete_ExtClkLevel AcpLevel[SMU73_MAX_LEVELS_ACP]; + SMU73_Discrete_ExtClkLevel SamuLevel[SMU73_MAX_LEVELS_SAMU]; SMU73_Discrete_Ulv Ulv; uint32_t SclkStepSize; - uint32_t Smio [SMU73_MAX_ENTRIES_SMIO]; + uint32_t Smio[SMU73_MAX_ENTRIES_SMIO]; uint8_t UvdBootLevel; uint8_t VceBootLevel; @@ -368,8 +358,7 @@ typedef struct SMU73_Discrete_DpmTable SMU73_Discrete_DpmTable; // --------------------------------------------------- Fan Table ----------------------------------------------------------- -struct SMU73_Discrete_FanTable -{ +struct SMU73_Discrete_FanTable { uint16_t FdoMode; int16_t TempMin; int16_t TempMed; @@ -397,8 +386,7 @@ typedef struct SMU73_Discrete_FanTable SMU73_Discrete_FanTable; -struct SMU7_MclkDpmScoreboard -{ +struct SMU7_MclkDpmScoreboard { uint32_t PercentageBusy; @@ -448,8 +436,8 @@ struct SMU7_MclkDpmScoreboard uint8_t VbiWaitCounter; uint8_t EnabledLevelsChange; - uint16_t LevelResidencyCounters [SMU73_MAX_LEVELS_MEMORY]; - uint16_t LevelSwitchCounters [SMU73_MAX_LEVELS_MEMORY]; + uint16_t LevelResidencyCounters[SMU73_MAX_LEVELS_MEMORY]; + uint16_t LevelSwitchCounters[SMU73_MAX_LEVELS_MEMORY]; void (*TargetStateCalculator)(uint8_t); void (*SavedTargetStateCalculator)(uint8_t); @@ -469,8 +457,7 @@ struct SMU7_MclkDpmScoreboard typedef struct SMU7_MclkDpmScoreboard SMU7_MclkDpmScoreboard; -struct SMU7_UlvScoreboard -{ +struct SMU7_UlvScoreboard { uint8_t EnterUlv; uint8_t ExitUlv; uint8_t UlvActive; @@ -485,8 +472,7 @@ struct SMU7_UlvScoreboard typedef struct SMU7_UlvScoreboard SMU7_UlvScoreboard; -struct VddgfxSavedRegisters -{ +struct VddgfxSavedRegisters { uint32_t GPU_DBG[3]; uint32_t MEC_BaseAddress_Hi; uint32_t MEC_BaseAddress_Lo; @@ -497,8 +483,7 @@ struct VddgfxSavedRegisters typedef struct VddgfxSavedRegisters VddgfxSavedRegisters; -struct SMU7_VddGfxScoreboard -{ +struct SMU7_VddGfxScoreboard { uint8_t VddGfxEnable; uint8_t VddGfxActive; uint8_t VPUResetOccured; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu75.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu75.h index 771523001533..7d5ed7751976 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu75.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu75.h @@ -224,8 +224,8 @@ struct SMU7_LocalDpmScoreboard { uint8_t DteClampMode; uint8_t FpsClampMode; - uint16_t LevelResidencyCounters [SMU75_MAX_LEVELS_GRAPHICS]; - uint16_t LevelSwitchCounters [SMU75_MAX_LEVELS_GRAPHICS]; + uint16_t LevelResidencyCounters[SMU75_MAX_LEVELS_GRAPHICS]; + uint16_t LevelSwitchCounters[SMU75_MAX_LEVELS_GRAPHICS]; void (*TargetStateCalculator)(uint8_t); void (*SavedTargetStateCalculator)(uint8_t); @@ -316,7 +316,7 @@ struct SMU7_VoltageScoreboard { VoltageChangeHandler_t functionLinks[6]; - uint16_t * VddcFollower1; + uint16_t *VddcFollower1; int16_t Driver_OD_RequestedVidOffset1; int16_t Driver_OD_RequestedVidOffset2; }; @@ -677,9 +677,9 @@ typedef struct SCS_CELL_t SCS_CELL_t; struct VFT_TABLE_t { VFT_CELL_t Cell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS]; - uint16_t AvfsGbv [NUM_VFT_COLUMNS]; - uint16_t BtcGbv [NUM_VFT_COLUMNS]; - int16_t Temperature [TEMP_RANGE_MAXSTEPS]; + uint16_t AvfsGbv[NUM_VFT_COLUMNS]; + uint16_t BtcGbv[NUM_VFT_COLUMNS]; + int16_t Temperature[TEMP_RANGE_MAXSTEPS]; #ifdef SMU__FIRMWARE_SCKS_PRESENT__1 SCS_CELL_t ScksCell[TEMP_RANGE_MAXSTEPS][NUM_VFT_COLUMNS]; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu7_fusion.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu7_fusion.h index 78ada9ffd508..e130f52fe8d6 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu7_fusion.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu7_fusion.h @@ -36,8 +36,7 @@ #define SMU7_NUM_NON_TES 2 // All 'soft registers' should be uint32_t. -struct SMU7_SoftRegisters -{ +struct SMU7_SoftRegisters { uint32_t RefClockFrequency; uint32_t PmTimerP; uint32_t FeatureEnables; @@ -80,8 +79,7 @@ struct SMU7_SoftRegisters typedef struct SMU7_SoftRegisters SMU7_SoftRegisters; -struct SMU7_Fusion_GraphicsLevel -{ +struct SMU7_Fusion_GraphicsLevel { uint32_t MinVddNb; uint32_t SclkFrequency; @@ -111,8 +109,7 @@ struct SMU7_Fusion_GraphicsLevel typedef struct SMU7_Fusion_GraphicsLevel SMU7_Fusion_GraphicsLevel; -struct SMU7_Fusion_GIOLevel -{ +struct SMU7_Fusion_GIOLevel { uint8_t EnabledForActivity; uint8_t LclkDid; uint8_t Vid; @@ -137,8 +134,7 @@ struct SMU7_Fusion_GIOLevel typedef struct SMU7_Fusion_GIOLevel SMU7_Fusion_GIOLevel; // UVD VCLK/DCLK state (level) definition. -struct SMU7_Fusion_UvdLevel -{ +struct SMU7_Fusion_UvdLevel { uint32_t VclkFrequency; uint32_t DclkFrequency; uint16_t MinVddNb; @@ -155,8 +151,7 @@ struct SMU7_Fusion_UvdLevel typedef struct SMU7_Fusion_UvdLevel SMU7_Fusion_UvdLevel; // Clocks for other external blocks (VCE, ACP, SAMU). -struct SMU7_Fusion_ExtClkLevel -{ +struct SMU7_Fusion_ExtClkLevel { uint32_t Frequency; uint16_t MinVoltage; uint8_t Divider; @@ -166,8 +161,7 @@ struct SMU7_Fusion_ExtClkLevel }; typedef struct SMU7_Fusion_ExtClkLevel SMU7_Fusion_ExtClkLevel; -struct SMU7_Fusion_ACPILevel -{ +struct SMU7_Fusion_ACPILevel { uint32_t Flags; uint32_t MinVddNb; uint32_t SclkFrequency; @@ -181,8 +175,7 @@ struct SMU7_Fusion_ACPILevel typedef struct SMU7_Fusion_ACPILevel SMU7_Fusion_ACPILevel; -struct SMU7_Fusion_NbDpm -{ +struct SMU7_Fusion_NbDpm { uint8_t DpmXNbPsHi; uint8_t DpmXNbPsLo; uint8_t Dpm0PgNbPsHi; @@ -197,8 +190,7 @@ struct SMU7_Fusion_NbDpm typedef struct SMU7_Fusion_NbDpm SMU7_Fusion_NbDpm; -struct SMU7_Fusion_StateInfo -{ +struct SMU7_Fusion_StateInfo { uint32_t SclkFrequency; uint32_t LclkFrequency; uint32_t VclkFrequency; @@ -214,8 +206,7 @@ struct SMU7_Fusion_StateInfo typedef struct SMU7_Fusion_StateInfo SMU7_Fusion_StateInfo; -struct SMU7_Fusion_DpmTable -{ +struct SMU7_Fusion_DpmTable { uint32_t SystemFlags; SMU7_PIDController GraphicsPIDController; @@ -230,12 +221,12 @@ struct SMU7_Fusion_DpmTable uint8_t SamuLevelCount; uint16_t FpsHighT; - SMU7_Fusion_GraphicsLevel GraphicsLevel [SMU__NUM_SCLK_DPM_STATE]; + SMU7_Fusion_GraphicsLevel GraphicsLevel[SMU__NUM_SCLK_DPM_STATE]; SMU7_Fusion_ACPILevel ACPILevel; - SMU7_Fusion_UvdLevel UvdLevel [SMU7_MAX_LEVELS_UVD]; - SMU7_Fusion_ExtClkLevel VceLevel [SMU7_MAX_LEVELS_VCE]; - SMU7_Fusion_ExtClkLevel AcpLevel [SMU7_MAX_LEVELS_ACP]; - SMU7_Fusion_ExtClkLevel SamuLevel [SMU7_MAX_LEVELS_SAMU]; + SMU7_Fusion_UvdLevel UvdLevel[SMU7_MAX_LEVELS_UVD]; + SMU7_Fusion_ExtClkLevel VceLevel[SMU7_MAX_LEVELS_VCE]; + SMU7_Fusion_ExtClkLevel AcpLevel[SMU7_MAX_LEVELS_ACP]; + SMU7_Fusion_ExtClkLevel SamuLevel[SMU7_MAX_LEVELS_SAMU]; uint8_t UvdBootLevel; uint8_t VceBootLevel; @@ -266,10 +257,9 @@ struct SMU7_Fusion_DpmTable }; -struct SMU7_Fusion_GIODpmTable -{ +struct SMU7_Fusion_GIODpmTable { - SMU7_Fusion_GIOLevel GIOLevel [SMU7_MAX_LEVELS_GIO]; + SMU7_Fusion_GIOLevel GIOLevel[SMU7_MAX_LEVELS_GIO]; SMU7_PIDController GioPIDController; diff --git a/drivers/gpu/drm/amd/pm/powerplay/inc/smu9_driver_if.h b/drivers/gpu/drm/amd/pm/powerplay/inc/smu9_driver_if.h index faae4b918d90..2c69a5694f94 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/inc/smu9_driver_if.h +++ b/drivers/gpu/drm/amd/pm/powerplay/inc/smu9_driver_if.h @@ -178,20 +178,20 @@ typedef struct { uint8_t padding8_2[2]; /* SOC Frequencies */ - PllSetting_t GfxclkLevel [NUM_GFXCLK_DPM_LEVELS]; + PllSetting_t GfxclkLevel[NUM_GFXCLK_DPM_LEVELS]; - uint8_t SocclkDid [NUM_SOCCLK_DPM_LEVELS]; /* DID */ - uint8_t SocDpmVoltageIndex [NUM_SOCCLK_DPM_LEVELS]; + uint8_t SocclkDid[NUM_SOCCLK_DPM_LEVELS]; /* DID */ + uint8_t SocDpmVoltageIndex[NUM_SOCCLK_DPM_LEVELS]; - uint8_t VclkDid [NUM_UVD_DPM_LEVELS]; /* DID */ - uint8_t DclkDid [NUM_UVD_DPM_LEVELS]; /* DID */ - uint8_t UvdDpmVoltageIndex [NUM_UVD_DPM_LEVELS]; + uint8_t VclkDid[NUM_UVD_DPM_LEVELS]; /* DID */ + uint8_t DclkDid[NUM_UVD_DPM_LEVELS]; /* DID */ + uint8_t UvdDpmVoltageIndex[NUM_UVD_DPM_LEVELS]; - uint8_t EclkDid [NUM_VCE_DPM_LEVELS]; /* DID */ - uint8_t VceDpmVoltageIndex [NUM_VCE_DPM_LEVELS]; + uint8_t EclkDid[NUM_VCE_DPM_LEVELS]; /* DID */ + uint8_t VceDpmVoltageIndex[NUM_VCE_DPM_LEVELS]; - uint8_t Mp0clkDid [NUM_MP0CLK_DPM_LEVELS]; /* DID */ - uint8_t Mp0DpmVoltageIndex [NUM_MP0CLK_DPM_LEVELS]; + uint8_t Mp0clkDid[NUM_MP0CLK_DPM_LEVELS]; /* DID */ + uint8_t Mp0DpmVoltageIndex[NUM_MP0CLK_DPM_LEVELS]; DisplayClockTable_t DisplayClockTable[DSPCLK_COUNT][NUM_DSPCLK_LEVELS]; QuadraticInt_t DisplayClock2Gfxclk[DSPCLK_COUNT]; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c index 4bc8db1be738..9e4228232f02 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c @@ -2732,7 +2732,7 @@ static bool ci_is_dpm_running(struct pp_hwmgr *hwmgr) static int ci_smu_init(struct pp_hwmgr *hwmgr) { - struct ci_smumgr *ci_priv = NULL; + struct ci_smumgr *ci_priv; ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c index 02c094a06605..5e43ad2b2956 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c @@ -332,7 +332,7 @@ static bool fiji_is_hw_avfs_present(struct pp_hwmgr *hwmgr) static int fiji_smu_init(struct pp_hwmgr *hwmgr) { - struct fiji_smumgr *fiji_priv = NULL; + struct fiji_smumgr *fiji_priv; fiji_priv = kzalloc(sizeof(struct fiji_smumgr), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c index 060fc140c574..97d9802fe673 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c @@ -259,7 +259,7 @@ static int iceland_start_smu(struct pp_hwmgr *hwmgr) static int iceland_smu_init(struct pp_hwmgr *hwmgr) { - struct iceland_smumgr *iceland_priv = NULL; + struct iceland_smumgr *iceland_priv; iceland_priv = kzalloc(sizeof(struct iceland_smumgr), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c index e7ed2a7adf8f..ff6b563ecbf5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c @@ -1888,7 +1888,7 @@ static int polaris10_populate_avfs_parameters(struct pp_hwmgr *hwmgr) (avfs_params.ucEnableGB_VDROOP_TABLE_CKSOFF << BTCGB1_Vdroop_Enable_SHIFT) | (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) | (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT); - data->apply_avfs_cks_off_voltage = (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false; + data->apply_avfs_cks_off_voltage = avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1; } return result; } diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c index acbe41174d7e..6fe6e6abb5d8 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c @@ -226,7 +226,7 @@ static int tonga_start_smu(struct pp_hwmgr *hwmgr) static int tonga_smu_init(struct pp_hwmgr *hwmgr) { - struct tonga_smumgr *tonga_priv = NULL; + struct tonga_smumgr *tonga_priv; tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL); if (tonga_priv == NULL) diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c index 7d024d3facef..34c9f59b889a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c @@ -295,9 +295,8 @@ static int vegam_process_firmware_header(struct pp_hwmgr *hwmgr) static bool vegam_is_dpm_running(struct pp_hwmgr *hwmgr) { - return (1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, - CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON)) - ? true : false; + return 1 == PHM_READ_INDIRECT_FIELD(hwmgr->device, + CGS_IND_REG__SMC, FEATURE_STATUS, VOLTAGE_CONTROLLER_ON); } static uint32_t vegam_get_mac_definition(uint32_t value) @@ -1660,7 +1659,7 @@ static int vegam_populate_avfs_parameters(struct pp_hwmgr *hwmgr) (avfs_params.ucEnableGB_FUSE_TABLE_CKSON << AVFSGB0_Vdroop_Enable_SHIFT) | (avfs_params.ucEnableGB_FUSE_TABLE_CKSOFF << AVFSGB1_Vdroop_Enable_SHIFT); data->apply_avfs_cks_off_voltage = - (avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1) ? true : false; + avfs_params.ucEnableApplyAVFS_CKS_OFF_Voltage == 1; } return result; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/Makefile b/drivers/gpu/drm/amd/pm/swsmu/Makefile index 7987c6cf849d..e5fdda49c96c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/Makefile +++ b/drivers/gpu/drm/amd/pm/swsmu/Makefile @@ -22,7 +22,7 @@ AMD_SWSMU_PATH = ../pm/swsmu -SWSMU_LIBS = smu11 smu12 smu13 +SWSMU_LIBS = smu11 smu12 smu13 smu14 AMD_SWSMU = $(addsuffix /Makefile,$(addprefix $(FULL_AMD_PATH)/pm/swsmu/,$(SWSMU_LIBS))) diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 222af2fae745..e1a5ee911dbb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -43,6 +43,7 @@ #include "smu_v13_0_5_ppt.h" #include "smu_v13_0_6_ppt.h" #include "smu_v13_0_7_ppt.h" +#include "smu_v14_0_0_ppt.h" #include "amd_pcie.h" /* @@ -215,6 +216,20 @@ static int smu_set_gfx_imu_enable(struct smu_context *smu) return smu_set_gfx_power_up_by_imu(smu); } +static bool is_vcn_enabled(struct amdgpu_device *adev) +{ + int i; + + for (i = 0; i < adev->num_ip_blocks; i++) { + if ((adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_VCN || + adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_JPEG) && + !adev->ip_blocks[i].status.valid) + return false; + } + + return true; +} + static int smu_dpm_set_vcn_enable(struct smu_context *smu, bool enable) { @@ -222,6 +237,12 @@ static int smu_dpm_set_vcn_enable(struct smu_context *smu, struct smu_power_gate *power_gate = &smu_power->power_gate; int ret = 0; + /* + * don't poweron vcn/jpeg when they are skipped. + */ + if (!is_vcn_enabled(smu->adev)) + return 0; + if (!smu->ppt_funcs->dpm_set_vcn_enable) return 0; @@ -242,6 +263,9 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu, struct smu_power_gate *power_gate = &smu_power->power_gate; int ret = 0; + if (!is_vcn_enabled(smu->adev)) + return 0; + if (!smu->ppt_funcs->dpm_set_jpeg_enable) return 0; @@ -255,6 +279,49 @@ static int smu_dpm_set_jpeg_enable(struct smu_context *smu, return ret; } +static int smu_dpm_set_vpe_enable(struct smu_context *smu, + bool enable) +{ + struct smu_power_context *smu_power = &smu->smu_power; + struct smu_power_gate *power_gate = &smu_power->power_gate; + int ret = 0; + + if (!smu->ppt_funcs->dpm_set_vpe_enable) + return 0; + + if (atomic_read(&power_gate->vpe_gated) ^ enable) + return 0; + + ret = smu->ppt_funcs->dpm_set_vpe_enable(smu, enable); + if (!ret) + atomic_set(&power_gate->vpe_gated, !enable); + + return ret; +} + +static int smu_dpm_set_umsch_mm_enable(struct smu_context *smu, + bool enable) +{ + struct smu_power_context *smu_power = &smu->smu_power; + struct smu_power_gate *power_gate = &smu_power->power_gate; + int ret = 0; + + if (!smu->adev->enable_umsch_mm) + return 0; + + if (!smu->ppt_funcs->dpm_set_umsch_mm_enable) + return 0; + + if (atomic_read(&power_gate->umsch_mm_gated) ^ enable) + return 0; + + ret = smu->ppt_funcs->dpm_set_umsch_mm_enable(smu, enable); + if (!ret) + atomic_set(&power_gate->umsch_mm_gated, !enable); + + return ret; +} + /** * smu_dpm_set_power_gate - power gate/ungate the specific IP block * @@ -313,6 +380,12 @@ static int smu_dpm_set_power_gate(void *handle, dev_err(smu->adev->dev, "Failed to power %s JPEG!\n", gate ? "gate" : "ungate"); break; + case AMD_IP_BLOCK_TYPE_VPE: + ret = smu_dpm_set_vpe_enable(smu, !gate); + if (ret) + dev_err(smu->adev->dev, "Failed to power %s VPE!\n", + gate ? "gate" : "ungate"); + break; default: dev_err(smu->adev->dev, "Unsupported block type!\n"); return -EINVAL; @@ -462,7 +535,7 @@ bool is_support_sw_smu(struct amdgpu_device *adev) if (adev->asic_type == CHIP_VEGA20) return false; - if (adev->ip_versions[MP1_HWIP][0] >= IP_VERSION(11, 0, 0)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) >= IP_VERSION(11, 0, 0)) return true; return false; @@ -580,7 +653,7 @@ static int smu_set_funcs(struct amdgpu_device *adev) if (adev->pm.pp_feature & PP_OVERDRIVE_MASK) smu->od_enabled = true; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): case IP_VERSION(11, 0, 9): @@ -618,7 +691,7 @@ static int smu_set_funcs(struct amdgpu_device *adev) adev->pm.pp_feature &= ~PP_GFXOFF_MASK; arcturus_set_ppt_funcs(smu); /* OD is not supported on Arcturus */ - smu->od_enabled =false; + smu->od_enabled = false; break; case IP_VERSION(13, 0, 2): aldebaran_set_ppt_funcs(smu); @@ -637,6 +710,9 @@ static int smu_set_funcs(struct amdgpu_device *adev) case IP_VERSION(13, 0, 7): smu_v13_0_7_set_ppt_funcs(smu); break; + case IP_VERSION(14, 0, 0): + smu_v14_0_0_set_ppt_funcs(smu); + break; default: return -EINVAL; } @@ -657,7 +733,7 @@ static int smu_early_init(void *handle) smu->adev = adev; smu->pm_enabled = !!amdgpu_dpm; smu->is_apu = false; - smu->smu_baco.state = SMU_BACO_STATE_EXIT; + smu->smu_baco.state = SMU_BACO_STATE_NONE; smu->smu_baco.platform_support = false; smu->user_dpm_profile.fan_mode = -1; @@ -752,8 +828,8 @@ static int smu_late_init(void *handle) } } - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 1)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 3))) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 1)) || + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 3))) return 0; if (!amdgpu_sriov_vf(adev) || smu->od_enabled) { @@ -773,7 +849,8 @@ static int smu_late_init(void *handle) ret = smu_get_asic_power_limits(smu, &smu->current_power_limit, &smu->default_power_limit, - &smu->max_power_limit); + &smu->max_power_limit, + &smu->min_power_limit); if (ret) { dev_err(adev->dev, "Failed to get asic power limits!\n"); return ret; @@ -1107,6 +1184,21 @@ static void smu_swctf_delayed_work_handler(struct work_struct *work) orderly_poweroff(true); } +static void smu_init_xgmi_plpd_mode(struct smu_context *smu) +{ + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) { + smu->plpd_mode = XGMI_PLPD_DEFAULT; + return; + } + + /* PMFW put PLPD into default policy after enabling the feature */ + if (smu_feature_is_enabled(smu, + SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT)) + smu->plpd_mode = XGMI_PLPD_DEFAULT; + else + smu->plpd_mode = XGMI_PLPD_NONE; +} + static int smu_sw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -1127,6 +1219,8 @@ static int smu_sw_init(void *handle) atomic_set(&smu->smu_power.power_gate.vcn_gated, 1); atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1); + atomic_set(&smu->smu_power.power_gate.vpe_gated, 1); + atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1); smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT]; smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0; @@ -1232,11 +1326,11 @@ static int smu_smc_hw_setup(struct smu_context *smu) { struct smu_feature *feature = &smu->smu_feature; struct amdgpu_device *adev = smu->adev; - uint32_t pcie_gen = 0, pcie_width = 0; + uint8_t pcie_gen = 0, pcie_width = 0; uint64_t features_supported; int ret = 0; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 11): case IP_VERSION(11, 5, 0): @@ -1338,6 +1432,8 @@ static int smu_smc_hw_setup(struct smu_context *smu) return ret; } + smu_init_xgmi_plpd_mode(smu); + ret = smu_feature_get_enabled_mask(smu, &features_supported); if (ret) { dev_err(adev->dev, "Failed to retrieve supported dpm features!\n"); @@ -1426,7 +1522,7 @@ static int smu_start_smc_engine(struct smu_context *smu) int ret = 0; if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { - if (adev->ip_versions[MP1_HWIP][0] < IP_VERSION(11, 0, 0)) { + if (amdgpu_ip_version(adev, MP1_HWIP, 0) < IP_VERSION(11, 0, 0)) { if (smu->ppt_funcs->load_microcode) { ret = smu->ppt_funcs->load_microcode(smu); if (ret) @@ -1477,6 +1573,8 @@ static int smu_hw_init(void *handle) return ret; smu_dpm_set_vcn_enable(smu, true); smu_dpm_set_jpeg_enable(smu, true); + smu_dpm_set_vpe_enable(smu, true); + smu_dpm_set_umsch_mm_enable(smu, true); smu_set_gfx_cgpg(smu, true); } @@ -1526,7 +1624,7 @@ static int smu_disable_dpms(struct smu_context *smu) * For SMU 13.0.0 and 13.0.7, PMFW will handle the DPM features(disablement or others) * properly on suspend/reset/unload. Driver involvement may cause some unexpected issues. */ - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 0): case IP_VERSION(13, 0, 7): case IP_VERSION(13, 0, 10): @@ -1547,7 +1645,7 @@ static int smu_disable_dpms(struct smu_context *smu) * properly. */ if (smu->uploading_custom_pp_table) { - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): case IP_VERSION(11, 0, 9): @@ -1567,7 +1665,7 @@ static int smu_disable_dpms(struct smu_context *smu) * on BACO in. Driver involvement is unnecessary. */ if (use_baco) { - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): @@ -1580,13 +1678,14 @@ static int smu_disable_dpms(struct smu_context *smu) } /* - * For SMU 13.0.4/11, PMFW will handle the features disablement properly + * For SMU 13.0.4/11 and 14.0.0, PMFW will handle the features disablement properly * for gpu reset and S0i3 cases. Driver involvement is unnecessary. */ if (amdgpu_in_reset(adev) || adev->in_s0ix) { - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 4): case IP_VERSION(13, 0, 11): + case IP_VERSION(14, 0, 0): return 0; default: break; @@ -1611,7 +1710,18 @@ static int smu_disable_dpms(struct smu_context *smu) } } - if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2) && + /* Notify SMU RLC is going to be off, stop RLC and SMU interaction. + * otherwise SMU will hang while interacting with RLC if RLC is halted + * this is a WA for Vangogh asic which fix the SMU hang issue. + */ + ret = smu_notify_rlc_state(smu, false); + if (ret) { + dev_err(adev->dev, "Fail to notify rlc status!\n"); + return ret; + } + + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2) && + !((adev->flags & AMD_IS_APU) && adev->gfx.imu.funcs) && !amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->stop) adev->gfx.rlc.funcs->stop(adev); @@ -1643,16 +1753,39 @@ static int smu_smc_hw_cleanup(struct smu_context *smu) return 0; } +static int smu_reset_mp1_state(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if ((!adev->in_runpm) && (!adev->in_suspend) && + (!amdgpu_in_reset(adev))) + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { + case IP_VERSION(13, 0, 0): + case IP_VERSION(13, 0, 7): + case IP_VERSION(13, 0, 10): + ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD); + break; + default: + break; + } + + return ret; +} + static int smu_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = adev->powerplay.pp_handle; + int ret; - if (amdgpu_sriov_vf(adev)&& !amdgpu_sriov_is_pp_one_vf(adev)) + if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; smu_dpm_set_vcn_enable(smu, false); smu_dpm_set_jpeg_enable(smu, false); + smu_dpm_set_vpe_enable(smu, false); + smu_dpm_set_umsch_mm_enable(smu, false); adev->vcn.cur_state = AMD_PG_STATE_GATE; adev->jpeg.cur_state = AMD_PG_STATE_GATE; @@ -1662,7 +1795,15 @@ static int smu_hw_fini(void *handle) adev->pm.dpm_enabled = false; - return smu_smc_hw_cleanup(smu); + ret = smu_smc_hw_cleanup(smu); + if (ret) + return ret; + + ret = smu_reset_mp1_state(smu); + if (ret) + return ret; + + return 0; } static void smu_late_fini(void *handle) @@ -1700,7 +1841,7 @@ static int smu_suspend(void *handle) int ret; uint64_t count; - if (amdgpu_sriov_vf(adev)&& !amdgpu_sriov_is_pp_one_vf(adev)) + if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) return 0; if (!smu->pm_enabled) @@ -2138,23 +2279,6 @@ static int smu_set_df_cstate(void *handle, return ret; } -int smu_allow_xgmi_power_down(struct smu_context *smu, bool en) -{ - int ret = 0; - - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) - return -EOPNOTSUPP; - - if (!smu->ppt_funcs || !smu->ppt_funcs->allow_xgmi_power_down) - return 0; - - ret = smu->ppt_funcs->allow_xgmi_power_down(smu, en); - if (ret) - dev_err(smu->adev->dev, "[AllowXgmiPowerDown] failed!\n"); - - return ret; -} - int smu_write_watermarks_table(struct smu_context *smu) { if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) @@ -2217,8 +2341,7 @@ const struct amd_ip_funcs smu_ip_funcs = { .set_powergating_state = smu_set_powergating_state, }; -const struct amdgpu_ip_block_version smu_v11_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v11_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 11, .minor = 0, @@ -2226,8 +2349,7 @@ const struct amdgpu_ip_block_version smu_v11_0_ip_block = .funcs = &smu_ip_funcs, }; -const struct amdgpu_ip_block_version smu_v12_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v12_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 12, .minor = 0, @@ -2235,8 +2357,7 @@ const struct amdgpu_ip_block_version smu_v12_0_ip_block = .funcs = &smu_ip_funcs, }; -const struct amdgpu_ip_block_version smu_v13_0_ip_block = -{ +const struct amdgpu_ip_block_version smu_v13_0_ip_block = { .type = AMD_IP_BLOCK_TYPE_SMC, .major = 13, .minor = 0, @@ -2244,6 +2365,14 @@ const struct amdgpu_ip_block_version smu_v13_0_ip_block = .funcs = &smu_ip_funcs, }; +const struct amdgpu_ip_block_version smu_v14_0_ip_block = { + .type = AMD_IP_BLOCK_TYPE_SMC, + .major = 14, + .minor = 0, + .rev = 0, + .funcs = &smu_ip_funcs, +}; + static int smu_load_microcode(void *handle) { struct smu_context *smu = handle; @@ -2337,7 +2466,7 @@ int smu_get_power_limit(void *handle, if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) return -EOPNOTSUPP; - switch(pp_power_type) { + switch (pp_power_type) { case PP_PWR_TYPE_SUSTAINED: limit_type = SMU_DEFAULT_PPT_LIMIT; break; @@ -2346,10 +2475,9 @@ int smu_get_power_limit(void *handle, break; default: return -EOPNOTSUPP; - break; } - switch(pp_limit_level){ + switch (pp_limit_level) { case PP_PWR_LIMIT_CURRENT: limit_level = SMU_PPT_LIMIT_CURRENT; break; @@ -2360,9 +2488,10 @@ int smu_get_power_limit(void *handle, limit_level = SMU_PPT_LIMIT_MAX; break; case PP_PWR_LIMIT_MIN: + limit_level = SMU_PPT_LIMIT_MIN; + break; default: return -EOPNOTSUPP; - break; } if (limit_type != SMU_DEFAULT_PPT_LIMIT) { @@ -2371,7 +2500,7 @@ int smu_get_power_limit(void *handle, } else { switch (limit_level) { case SMU_PPT_LIMIT_CURRENT: - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 2): case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 11): @@ -2379,8 +2508,7 @@ int smu_get_power_limit(void *handle, case IP_VERSION(11, 0, 13): ret = smu_get_asic_power_limits(smu, &smu->current_power_limit, - NULL, - NULL); + NULL, NULL, NULL); break; default: break; @@ -2393,8 +2521,11 @@ int smu_get_power_limit(void *handle, case SMU_PPT_LIMIT_MAX: *limit = smu->max_power_limit; break; - default: + case SMU_PPT_LIMIT_MIN: + *limit = smu->min_power_limit; break; + default: + return -EINVAL; } } @@ -2415,10 +2546,10 @@ static int smu_set_power_limit(void *handle, uint32_t limit) if (smu->ppt_funcs->set_power_limit) return smu->ppt_funcs->set_power_limit(smu, limit_type, limit); - if (limit > smu->max_power_limit) { + if ((limit > smu->max_power_limit) || (limit < smu->min_power_limit)) { dev_err(smu->adev->dev, - "New power limit (%d) is over the max allowed %d\n", - limit, smu->max_power_limit); + "New power limit (%d) is out of range [%d,%d]\n", + limit, smu->min_power_limit, smu->max_power_limit); return -EINVAL; } @@ -2484,6 +2615,16 @@ static enum smu_clk_type smu_convert_to_smuclk(enum pp_clock_type type) clk_type = SMU_OD_VDDGFX_OFFSET; break; case OD_CCLK: clk_type = SMU_OD_CCLK; break; + case OD_FAN_CURVE: + clk_type = SMU_OD_FAN_CURVE; break; + case OD_ACOUSTIC_LIMIT: + clk_type = SMU_OD_ACOUSTIC_LIMIT; break; + case OD_ACOUSTIC_TARGET: + clk_type = SMU_OD_ACOUSTIC_TARGET; break; + case OD_FAN_TARGET_TEMPERATURE: + clk_type = SMU_OD_FAN_TARGET_TEMPERATURE; break; + case OD_FAN_MINIMUM_PWM: + clk_type = SMU_OD_FAN_MINIMUM_PWM; break; default: clk_type = SMU_CLK_COUNT; break; } @@ -2595,7 +2736,7 @@ static int smu_read_sensor(void *handle, *size = 4; break; case AMDGPU_PP_SENSOR_VCN_POWER_STATE: - *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0: 1; + *(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0 : 1; *size = 4; break; case AMDGPU_PP_SENSOR_MIN_FAN_RPM: @@ -2617,7 +2758,7 @@ unlock: static int smu_get_apu_thermal_limit(void *handle, uint32_t *limit) { - int ret = -EINVAL; + int ret = -EOPNOTSUPP; struct smu_context *smu = handle; if (smu->ppt_funcs && smu->ppt_funcs->get_apu_thermal_limit) @@ -2628,7 +2769,7 @@ static int smu_get_apu_thermal_limit(void *handle, uint32_t *limit) static int smu_set_apu_thermal_limit(void *handle, uint32_t limit) { - int ret = -EINVAL; + int ret = -EOPNOTSUPP; struct smu_context *smu = handle; if (smu->ppt_funcs && smu->ppt_funcs->set_apu_thermal_limit) @@ -2868,7 +3009,7 @@ static int smu_set_xgmi_pstate(void *handle, if (smu->ppt_funcs->set_xgmi_pstate) ret = smu->ppt_funcs->set_xgmi_pstate(smu, pstate); - if(ret) + if (ret) dev_err(smu->adev->dev, "Failed to set XGMI pstate!\n"); return ret; @@ -3127,6 +3268,30 @@ static int smu_get_prv_buffer_details(void *handle, void **addr, size_t *size) return 0; } +int smu_set_xgmi_plpd_mode(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode) +{ + int ret = -EOPNOTSUPP; + + if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) + return ret; + + /* PLPD policy is not supported if it's NONE */ + if (smu->plpd_mode == XGMI_PLPD_NONE) + return ret; + + if (smu->plpd_mode == mode) + return 0; + + if (smu->ppt_funcs && smu->ppt_funcs->select_xgmi_plpd_policy) + ret = smu->ppt_funcs->select_xgmi_plpd_policy(smu, mode); + + if (!ret) + smu->plpd_mode = mode; + + return ret; +} + static const struct amd_pm_funcs swsmu_pm_funcs = { /* export for sysfs */ .set_fan_control_mode = smu_set_fan_control_mode, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 6e2069dcb6b9..f8b2e6cc2568 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -200,29 +200,25 @@ struct smu_power_state { struct smu_hw_power_state hardware; }; -enum smu_power_src_type -{ +enum smu_power_src_type { SMU_POWER_SOURCE_AC, SMU_POWER_SOURCE_DC, SMU_POWER_SOURCE_COUNT, }; -enum smu_ppt_limit_type -{ +enum smu_ppt_limit_type { SMU_DEFAULT_PPT_LIMIT = 0, SMU_FAST_PPT_LIMIT, }; -enum smu_ppt_limit_level -{ +enum smu_ppt_limit_level { SMU_PPT_LIMIT_MIN = -1, SMU_PPT_LIMIT_CURRENT, SMU_PPT_LIMIT_DEFAULT, SMU_PPT_LIMIT_MAX, }; -enum smu_memory_pool_size -{ +enum smu_memory_pool_size { SMU_MEMORY_POOL_SIZE_ZERO = 0, SMU_MEMORY_POOL_SIZE_256_MB = 0x10000000, SMU_MEMORY_POOL_SIZE_512_MB = 0x20000000, @@ -282,8 +278,7 @@ struct smu_clock_info { uint32_t max_bus_bandwidth; }; -struct smu_bios_boot_up_values -{ +struct smu_bios_boot_up_values { uint32_t revision; uint32_t gfxclk; uint32_t uclk; @@ -305,8 +300,7 @@ struct smu_bios_boot_up_values uint32_t firmware_caps; }; -enum smu_table_id -{ +enum smu_table_id { SMU_TABLE_PPTABLE = 0, SMU_TABLE_WATERMARKS, SMU_TABLE_CUSTOM_DPM, @@ -326,8 +320,7 @@ enum smu_table_id SMU_TABLE_COUNT, }; -struct smu_table_context -{ +struct smu_table_context { void *power_play_table; uint32_t power_play_table_size; void *hardcode_pptable; @@ -381,6 +374,8 @@ struct smu_power_gate { bool vce_gated; atomic_t vcn_gated; atomic_t jpeg_gated; + atomic_t vpe_gated; + atomic_t umsch_mm_gated; }; struct smu_power_context { @@ -390,8 +385,7 @@ struct smu_power_context { }; #define SMU_FEATURE_MAX (64) -struct smu_feature -{ +struct smu_feature { uint32_t feature_num; DECLARE_BITMAP(supported, SMU_FEATURE_MAX); DECLARE_BITMAP(allowed, SMU_FEATURE_MAX); @@ -416,21 +410,19 @@ struct mclock_latency_table { struct mclk_latency_entries entries[MAX_REGULAR_DPM_NUM]; }; -enum smu_reset_mode -{ +enum smu_reset_mode { SMU_RESET_MODE_0, SMU_RESET_MODE_1, SMU_RESET_MODE_2, }; -enum smu_baco_state -{ +enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, + SMU_BACO_STATE_NONE, }; -struct smu_baco_context -{ +struct smu_baco_context { uint32_t state; bool platform_support; bool maco_support; @@ -478,8 +470,7 @@ struct stb_context { #define WORKLOAD_POLICY_MAX 7 -struct smu_context -{ +struct smu_context { struct amdgpu_device *adev; struct amdgpu_irq_src irq_source; @@ -510,6 +501,7 @@ struct smu_context uint32_t current_power_limit; uint32_t default_power_limit; uint32_t max_power_limit; + uint32_t min_power_limit; /* soft pptable */ uint32_t ppt_offset_bytes; @@ -575,6 +567,8 @@ struct smu_context u32 debug_resp_reg; struct delayed_work swctf_delayed_work; + + enum pp_xgmi_plpd_mode plpd_mode; }; struct i2c_adapter; @@ -829,9 +823,10 @@ struct pptable_funcs { * @get_power_limit: Get the device's power limits. */ int (*get_power_limit)(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit); + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit); /** * @get_ppt_limit: Get the device's ppt limits. @@ -845,10 +840,10 @@ struct pptable_funcs { int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state); /** - * @allow_xgmi_power_down: Enable/disable external global memory - * interconnect power down. + * @select_xgmi_plpd_policy: Select xgmi per-link power down policy. */ - int (*allow_xgmi_power_down)(struct smu_context *smu, bool en); + int (*select_xgmi_plpd_policy)(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode); /** * @update_pcie_parameters: Update and upload the system's PCIe @@ -856,7 +851,7 @@ struct pptable_funcs { * &pcie_gen_cap: Maximum allowed PCIe generation. * &pcie_width_cap: Maximum allowed PCIe width. */ - int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap); + int (*update_pcie_parameters)(struct smu_context *smu, uint8_t pcie_gen_cap, uint8_t pcie_width_cap); /** * @i2c_init: Initialize i2c. @@ -1043,10 +1038,7 @@ struct pptable_funcs { enum smu_feature_mask mask); /** - * @notify_display_change: Enable fast memory clock switching. - * - * Allows for fine grained memory clock switching but has more stringent - * timing requirements. + * @notify_display_change: General interface call to let SMU know about DC change */ int (*notify_display_change)(struct smu_context *smu); @@ -1356,6 +1348,23 @@ struct pptable_funcs { * @init_pptable_microcode: Prepare the pptable microcode to upload via PSP */ int (*init_pptable_microcode)(struct smu_context *smu); + + /** + * @dpm_set_vpe_enable: Enable/disable VPE engine dynamic power + * management. + */ + int (*dpm_set_vpe_enable)(struct smu_context *smu, bool enable); + + /** + * @dpm_set_umsch_mm_enable: Enable/disable UMSCH engine dynamic power + * management. + */ + int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable); + + /** + * @notify_rlc_state: Notify RLC power state to SMU. + */ + int (*notify_rlc_state)(struct smu_context *smu, bool en); }; typedef enum { @@ -1398,6 +1407,17 @@ typedef enum { METRICS_PCIE_RATE, METRICS_PCIE_WIDTH, METRICS_CURR_FANPWM, + METRICS_CURR_SOCKETPOWER, + METRICS_AVERAGE_VPECLK, + METRICS_AVERAGE_IPUCLK, + METRICS_AVERAGE_MPIPUCLK, + METRICS_THROTTLER_RESIDENCY_PROCHOT, + METRICS_THROTTLER_RESIDENCY_SPL, + METRICS_THROTTLER_RESIDENCY_FPPT, + METRICS_THROTTLER_RESIDENCY_SPPT, + METRICS_THROTTLER_RESIDENCY_THM_CORE, + METRICS_THROTTLER_RESIDENCY_THM_GFX, + METRICS_THROTTLER_RESIDENCY_THM_SOC, } MetricsMember_t; enum smu_cmn2asic_mapping_type { @@ -1497,7 +1517,8 @@ int smu_set_gfx_power_up_by_imu(struct smu_context *smu); int smu_set_ac_dc(struct smu_context *smu); -int smu_allow_xgmi_power_down(struct smu_context *smu, bool en); +int smu_set_xgmi_plpd_mode(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode); int smu_get_entrycount_gfxoff(struct smu_context *smu, u64 *value); diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h index 7589faa0232d..779c2524806c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_5.h @@ -23,7 +23,7 @@ #ifndef __SMU13_DRIVER_IF_V13_0_5_H__ #define __SMU13_DRIVER_IF_V13_0_5_H__ -#define SMU13_0_5_DRIVER_IF_VERSION 4 +#define SMU13_0_5_DRIVER_IF_VERSION 5 // Throttler Status Bitmask #define THROTTLER_STATUS_BIT_SPL 0 @@ -103,7 +103,6 @@ typedef struct { uint16_t ThrottlerStatus; uint16_t CurrentSocketPower; //[mW] - uint16_t spare1; } SmuMetrics_t; //Freq in MHz diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_6.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_6.h index ca4a5e99ccd1..ced348d2e8bb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_6.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_6.h @@ -65,6 +65,94 @@ typedef enum { #define CMDCONFIG_RESTART_MASK (1 << CMDCONFIG_RESTART_BIT) #define CMDCONFIG_READWRITE_MASK (1 << CMDCONFIG_READWRITE_BIT) +typedef enum { + // MMHUB + CODE_DAGB0, + CODE_EA0 = 5, + CODE_UTCL2_ROUTER = 10, + CODE_VML2, + CODE_VML2_WALKER, + CODE_MMCANE, + + // VCN + // VCN VCPU + CODE_VIDD, + CODE_VIDV, + // VCN JPEG + CODE_JPEG0S, + CODE_JPEG0D, + CODE_JPEG1S, + CODE_JPEG1D, + CODE_JPEG2S, + CODE_JPEG2D, + CODE_JPEG3S, + CODE_JPEG3D, + CODE_JPEG4S, + CODE_JPEG4D, + CODE_JPEG5S, + CODE_JPEG5D, + CODE_JPEG6S, + CODE_JPEG6D, + CODE_JPEG7S, + CODE_JPEG7D, + // VCN MMSCH + CODE_MMSCHD, + + // SDMA + CODE_SDMA0, + CODE_SDMA1, + CODE_SDMA2, + CODE_SDMA3, + + // SOC + CODE_HDP, + CODE_ATHUB, + CODE_IH, + CODE_XHUB_POISON, + CODE_SMN_SLVERR = 40, + CODE_WDT, + + CODE_UNKNOWN = 42, + CODE_COUNT, +} ERR_CODE_e; + +typedef enum { + // SH POISON FED + SH_FED_CODE, + // GCEA Pin UE_ERR regs + GCEA_CODE, + SQ_CODE, + LDS_CODE, + GDS_CODE, + SP0_CODE, + SP1_CODE, + TCC_CODE, + TCA_CODE, + TCX_CODE, + CPC_CODE, + CPF_CODE, + CPG_CODE, + SPI_CODE, + RLC_CODE, + // GCEA Pin, UE_EDC regs + SQC_CODE, + TA_CODE, + TD_CODE, + TCP_CODE, + TCI_CODE, + // GC Router + GC_ROUTER_CODE, + VML2_CODE, + VML2_WALKER_CODE, + ATCL2_CODE, + GC_CANE_CODE, + + // SOC error codes 40-42 are common with ERR_CODE_e + MP5_CODE_SMN_SLVERR = 40, + MP5_CODE_UNKNOWN = 42, +} GC_ERROR_CODE_e; + + typedef struct { uint8_t ReadWriteData; //Return data for read. Data to send for write uint8_t CmdConfig; //Includes whether associated command should have a stop or restart command, and is a read or write @@ -132,6 +220,9 @@ typedef struct { #define THROTTLER_THERMAL_VR_BIT 3//VRHOT #define THROTTLER_THERMAL_HBM_BIT 4 +#define ClearMcaOnRead_UE_FLAG_MASK 0x1 +#define ClearMcaOnRead_CE_POLL_MASK 0x2 + // These defines are used with the following messages: // SMC_MSG_TransferTableDram2Smu // SMC_MSG_TransferTableSmu2Dram diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h new file mode 100644 index 000000000000..8f42771e1f0a --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu14_driver_if_v14_0_0.h @@ -0,0 +1,237 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef SMU14_DRIVER_IF_V14_0_0_H +#define SMU14_DRIVER_IF_V14_0_0_H + +// *** IMPORTANT *** +// SMU TEAM: Always increment the interface version if +// any structure is changed in this file +#define PMFW_DRIVER_IF_VERSION 7 + +typedef struct { + int32_t value; + uint32_t numFractionalBits; +} FloatInIntFormat_t; + +typedef enum { + DSPCLK_DCFCLK = 0, + DSPCLK_DISPCLK, + DSPCLK_PIXCLK, + DSPCLK_PHYCLK, + DSPCLK_COUNT, +} DSPCLK_e; + +typedef struct { + uint16_t Freq; // in MHz + uint16_t Vid; // min voltage in SVI3 VID +} DisplayClockTable_t; + +typedef struct { + uint16_t MinClock; // This is either DCFCLK or SOCCLK (in MHz) + uint16_t MaxClock; // This is either DCFCLK or SOCCLK (in MHz) + uint16_t MinMclk; + uint16_t MaxMclk; + + uint8_t WmSetting; + uint8_t WmType; // Used for normal pstate change or memory retraining + uint8_t Padding[2]; +} WatermarkRowGeneric_t; + +#define NUM_WM_RANGES 4 +#define WM_PSTATE_CHG 0 +#define WM_RETRAINING 1 + +typedef enum { + WM_SOCCLK = 0, + WM_DCFCLK, + WM_COUNT, +} WM_CLOCK_e; + +typedef struct { + // Watermarks + WatermarkRowGeneric_t WatermarkRow[WM_COUNT][NUM_WM_RANGES]; + + uint32_t MmHubPadding[7]; // SMU internal use +} Watermarks_t; + +typedef enum { + CUSTOM_DPM_SETTING_GFXCLK, + CUSTOM_DPM_SETTING_CCLK, + CUSTOM_DPM_SETTING_FCLK_CCX, + CUSTOM_DPM_SETTING_FCLK_GFX, + CUSTOM_DPM_SETTING_FCLK_STALLS, + CUSTOM_DPM_SETTING_LCLK, + CUSTOM_DPM_SETTING_COUNT, +} CUSTOM_DPM_SETTING_e; + +typedef struct { + uint8_t ActiveHystLimit; + uint8_t IdleHystLimit; + uint8_t FPS; + uint8_t MinActiveFreqType; + FloatInIntFormat_t MinActiveFreq; + FloatInIntFormat_t PD_Data_limit; + FloatInIntFormat_t PD_Data_time_constant; + FloatInIntFormat_t PD_Data_error_coeff; + FloatInIntFormat_t PD_Data_error_rate_coeff; +} DpmActivityMonitorCoeffExt_t; + +typedef struct { + DpmActivityMonitorCoeffExt_t DpmActivityMonitorCoeff[CUSTOM_DPM_SETTING_COUNT]; +} CustomDpmSettings_t; + +#define NUM_DCFCLK_DPM_LEVELS 8 +#define NUM_DISPCLK_DPM_LEVELS 8 +#define NUM_DPPCLK_DPM_LEVELS 8 +#define NUM_SOCCLK_DPM_LEVELS 8 +#define NUM_VCN_DPM_LEVELS 8 +#define NUM_SOC_VOLTAGE_LEVELS 8 +#define NUM_VPE_DPM_LEVELS 8 +#define NUM_FCLK_DPM_LEVELS 8 +#define NUM_MEM_PSTATE_LEVELS 4 + + +typedef struct { + uint32_t UClk; + uint32_t MemClk; + uint32_t Voltage; + uint8_t WckRatio; + uint8_t Spare[3]; +} MemPstateTable_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 VClocks[NUM_VCN_DPM_LEVELS]; + uint32_t DClocks[NUM_VCN_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 VcnClkLevelsEnabled; //Applies to both Vclk and Dclk + uint8_t VpeClkLevelsEnabled; + + uint8_t NumMemPstatesEnabled; + uint8_t NumFclkLevelsEnabled; + uint8_t spare[2]; + + uint32_t MinGfxClk; + uint32_t MaxGfxClk; +} DpmClocks_t; + +typedef struct { + uint16_t CoreFrequency[16]; //Target core frequency [MHz] + uint16_t CorePower[16]; //CAC calculated core power [mW] + uint16_t CoreTemperature[16]; //TSEN measured core temperature [centi-C] + uint16_t GfxTemperature; //TSEN measured GFX temperature [centi-C] + uint16_t SocTemperature; //TSEN measured SOC temperature [centi-C] + uint16_t StapmOpnLimit; //Maximum IRM defined STAPM power limit [mW] + uint16_t StapmCurrentLimit; //Time filtered STAPM power limit [mW] + uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz] + uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz] + uint16_t SkinTemp; //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C] + uint16_t GfxclkFrequency; //Time filtered target GFXCLK frequency [MHz] + uint16_t FclkFrequency; //Time filtered target FCLK frequency [MHz] + uint16_t GfxActivity; //Time filtered GFX busy % [0-100] + uint16_t SocclkFrequency; //Time filtered target SOCCLK frequency [MHz] + uint16_t VclkFrequency; //Time filtered target VCLK frequency [MHz] + uint16_t VcnActivity; //Time filtered VCN busy % [0-100] + uint16_t VpeclkFrequency; //Time filtered target VPECLK frequency [MHz] + uint16_t IpuclkFrequency; //Time filtered target IPUCLK frequency [MHz] + uint16_t IpuBusy[8]; //Time filtered IPU per-column busy % [0-100] + uint16_t DRAMReads; //Time filtered DRAM read bandwidth [MB/sec] + uint16_t DRAMWrites; //Time filtered DRAM write bandwidth [MB/sec] + uint16_t CoreC0Residency[16]; //Time filtered per-core C0 residency % [0-100] + uint16_t IpuPower; //Time filtered IPU power [mW] + uint32_t ApuPower; //Time filtered APU power [mW] + uint32_t GfxPower; //Time filtered GFX power [mW] + uint32_t dGpuPower; //Time filtered dGPU power [mW] + uint32_t SocketPower; //Time filtered power used for PPT/STAPM [APU+dGPU] [mW] + uint32_t AllCorePower; //Time filtered sum of core power across all cores in the socket [mW] + uint32_t FilterAlphaValue; //Metrics table alpha filter time constant [us] + uint32_t MetricsCounter; //Counter that is incremented on every metrics table update [PM_TIMER cycles] + uint16_t MemclkFrequency; //Time filtered target MEMCLK frequency [MHz] + uint16_t MpipuclkFrequency; //Time filtered target MPIPUCLK frequency [MHz] + uint16_t IpuReads; //Time filtered IPU read bandwidth [MB/sec] + uint16_t IpuWrites; //Time filtered IPU write bandwidth [MB/sec] + uint32_t ThrottleResidency_PROCHOT; //Counter that is incremented on every metrics table update when PROCHOT was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_SPL; //Counter that is incremented on every metrics table update when SPL was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_FPPT; //Counter that is incremented on every metrics table update when fast PPT was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_SPPT; //Counter that is incremented on every metrics table update when slow PPT was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_THM_CORE; //Counter that is incremented on every metrics table update when CORE thermal throttling was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_THM_GFX; //Counter that is incremented on every metrics table update when GFX thermal throttling was engaged [PM_TIMER cycles] + uint32_t ThrottleResidency_THM_SOC; //Counter that is incremented on every metrics table update when SOC thermal throttling was engaged [PM_TIMER cycles] + uint16_t Psys; //Time filtered Psys power [mW] + uint16_t spare1; + uint32_t spare[6]; +} SmuMetrics_t; + +//ISP tile definitions +typedef enum { + TILE_XTILE = 0, //ONO0 + TILE_MTILE, //ONO1 + TILE_PDP, //ONO2 + TILE_CSTAT, //ONO2 + TILE_LME, //ONO3 + TILE_BYRP, //ONO4 + TILE_GRBP, //ONO4 + TILE_MCFP, //ONO4 + TILE_YUVP, //ONO4 + TILE_MCSC, //ONO4 + TILE_GDC, //ONO5 + TILE_MAX +} TILE_NUM_e; + +// Tile Selection (Based on arguments) +#define ISP_TILE_SEL(tile) (1<<tile) +#define ISP_TILE_SEL_ALL 0x7FF + +// Workload bits +#define WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT 0 +#define WORKLOAD_PPLIB_VIDEO_BIT 2 +#define WORKLOAD_PPLIB_VR_BIT 3 +#define WORKLOAD_PPLIB_COMPUTE_BIT 4 +#define WORKLOAD_PPLIB_CUSTOM_BIT 5 +#define WORKLOAD_PPLIB_COUNT 6 + +#define TABLE_BIOS_IF 0 // Called by BIOS +#define TABLE_WATERMARKS 1 // Called by DAL through VBIOS +#define TABLE_CUSTOM_DPM 2 // Called by Driver +#define TABLE_BIOS_GPIO_CONFIG 3 // Called by BIOS +#define TABLE_DPMCLOCKS 4 // Called by Driver and VBIOS +#define TABLE_SPARE0 5 // Unused +#define TABLE_MODERN_STDBY 6 // Called by Tools for Modern Standby Log +#define TABLE_SMU_METRICS 7 // Called by Driver and SMF/PMF +#define TABLE_COUNT 8 + +#endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h index 10cff75b44d5..e2ee855c7748 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h @@ -138,7 +138,10 @@ #define PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel 0x4A #define PPSMC_MSG_SetPriorityDeltaGain 0x4B #define PPSMC_MSG_AllowIHHostInterrupt 0x4C -#define PPSMC_Message_Count 0x4D + +#define PPSMC_MSG_DALNotPresent 0x4E + +#define PPSMC_Message_Count 0x4F //Debug Dump Message #define DEBUGSMC_MSG_TestMessage 0x1 diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h index 252aef190c5c..fef2d290f3f2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_pmfw.h @@ -123,7 +123,7 @@ typedef enum { VOLTAGE_GUARDBAND_COUNT } GFX_GUARDBAND_e; -#define SMU_METRICS_TABLE_VERSION 0x5 +#define SMU_METRICS_TABLE_VERSION 0x9 typedef struct __attribute__((packed, aligned(4))) { uint32_t AccumulationCounter; @@ -198,7 +198,7 @@ typedef struct __attribute__((packed, aligned(4))) { uint32_t SocketThmResidencyAcc; uint32_t VrThmResidencyAcc; uint32_t HbmThmResidencyAcc; - uint32_t spare; + uint32_t GfxLockXCDMak; // New Items at end to maintain driver compatibility uint32_t GfxclkFrequency[8]; @@ -207,6 +207,18 @@ typedef struct __attribute__((packed, aligned(4))) { uint64_t PublicSerialNumber_AID[4]; uint64_t PublicSerialNumber_XCD[8]; uint64_t PublicSerialNumber_CCD[12]; + + //XGMI Data tranfser size + uint64_t XgmiReadDataSizeAcc[8];//in KByte + uint64_t XgmiWriteDataSizeAcc[8];//in KByte + + //PCIE BW Data and error count + uint32_t PcieBandwidth[4]; + uint32_t PCIeL0ToRecoveryCountAcc; // The Pcie counter itself is accumulated + uint32_t PCIenReplayAAcc; // The Pcie counter itself is accumulated + uint32_t PCIenReplayARolloverCountAcc; // The Pcie counter itself is accumulated + uint32_t PCIeNAKSentCountAcc; // The Pcie counter itself is accumulated + uint32_t PCIeNAKReceivedCountAcc; // The Pcie counter itself is accumulated } MetricsTable_t; #define SMU_VF_METRICS_TABLE_VERSION 0x3 diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_ppsmc.h index ae4f44c4b877..509e3cd483fb 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_ppsmc.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_6_ppsmc.h @@ -83,13 +83,35 @@ #define PPSMC_MSG_GetMinGfxDpmFreq 0x32 #define PPSMC_MSG_GetMaxGfxDpmFreq 0x33 #define PPSMC_MSG_PrepareForDriverUnload 0x34 -#define PPSMC_Message_Count 0x35 +#define PPSMC_MSG_ReadThrottlerLimit 0x35 +#define PPSMC_MSG_QueryValidMcaCount 0x36 +#define PPSMC_MSG_McaBankDumpDW 0x37 +#define PPSMC_MSG_GetCTFLimit 0x38 +#define PPSMC_MSG_ClearMcaOnRead 0x39 +#define PPSMC_MSG_QueryValidMcaCeCount 0x3A +#define PPSMC_MSG_McaBankCeDumpDW 0x3B +#define PPSMC_MSG_SelectPLPDMode 0x40 +#define PPSMC_Message_Count 0x41 //PPSMC Reset Types for driver msg argument #define PPSMC_RESET_TYPE_DRIVER_MODE_1_RESET 0x1 #define PPSMC_RESET_TYPE_DRIVER_MODE_2_RESET 0x2 #define PPSMC_RESET_TYPE_DRIVER_MODE_3_RESET 0x3 +//PPSMC Reset Types for driver msg argument +#define PPSMC_THROTTLING_LIMIT_TYPE_SOCKET 0x1 +#define PPSMC_THROTTLING_LIMIT_TYPE_HBM 0x2 + +//CTF/Throttle Limit types +#define PPSMC_AID_THM_TYPE 0x1 +#define PPSMC_CCD_THM_TYPE 0x2 +#define PPSMC_XCD_THM_TYPE 0x3 +#define PPSMC_HBM_THM_TYPE 0x4 + +//PLPD modes +#define PPSMC_PLPD_MODE_DEFAULT 0x1 +#define PPSMC_PLPD_MODE_OPTIMIZED 0x2 + typedef uint32_t PPSMC_Result; typedef uint32_t PPSMC_MSG; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_pmfw.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_pmfw.h new file mode 100644 index 000000000000..356e0f57a426 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_pmfw.h @@ -0,0 +1,157 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __SMU_V14_0_0_PMFW_H__ +#define __SMU_V14_0_0_PMFW_H__ + +#include "smu14_driver_if_v14_0_0.h" + +#pragma pack(push, 1) + +#define ENABLE_DEBUG_FEATURES + +// Firmware features +// Feature Control Defines +#define FEATURE_CCLK_DPM_BIT 0 +#define FEATURE_FAN_CONTROLLER_BIT 1 +#define FEATURE_DATA_CALCULATION_BIT 2 +#define FEATURE_PPT_BIT 3 +#define FEATURE_TDC_BIT 4 +#define FEATURE_THERMAL_BIT 5 +#define FEATURE_FIT_BIT 6 +#define FEATURE_EDC_BIT 7 +#define FEATURE_PLL_POWER_DOWN_BIT 8 +#define FEATURE_VDDOFF_BIT 9 +#define FEATURE_VCN_DPM_BIT 10 +#define FEATURE_DS_MPM_BIT 11 +#define FEATURE_FCLK_DPM_BIT 12 +#define FEATURE_SOCCLK_DPM_BIT 13 +#define FEATURE_DS_MPIO_BIT 14 +#define FEATURE_LCLK_DPM_BIT 15 +#define FEATURE_SHUBCLK_DPM_BIT 16 +#define FEATURE_DCFCLK_DPM_BIT 17 +#define FEATURE_ISP_DPM_BIT 18 +#define FEATURE_IPU_DPM_BIT 19 +#define FEATURE_GFX_DPM_BIT 20 +#define FEATURE_DS_GFXCLK_BIT 21 +#define FEATURE_DS_SOCCLK_BIT 22 +#define FEATURE_DS_LCLK_BIT 23 +#define FEATURE_LOW_POWER_DCNCLKS_BIT 24 // for all DISP clks +#define FEATURE_DS_SHUBCLK_BIT 25 +#define FEATURE_SPARE0_BIT 26 //SPARE +#define FEATURE_ZSTATES_BIT 27 +#define FEATURE_IOMMUL2_PG_BIT 28 +#define FEATURE_DS_FCLK_BIT 29 +#define FEATURE_DS_SMNCLK_BIT 30 +#define FEATURE_DS_MP1CLK_BIT 31 +#define FEATURE_WHISPER_MODE_BIT 32 +#define FEATURE_SMU_LOW_POWER_BIT 33 +#define FEATURE_SMART_L3_RINSER_BIT 34 +#define FEATURE_SPARE1_BIT 35 //SPARE +#define FEATURE_PSI_BIT 36 +#define FEATURE_PROCHOT_BIT 37 +#define FEATURE_CPUOFF_BIT 38 +#define FEATURE_STAPM_BIT 39 +#define FEATURE_S0I3_BIT 40 +#define FEATURE_DF_LIGHT_CSTATE 41 +#define FEATURE_PERF_LIMIT_BIT 42 +#define FEATURE_CORE_DLDO_BIT 43 +#define FEATURE_DVO_BIT 44 +#define FEATURE_DS_VCN_BIT 45 +#define FEATURE_CPPC_BIT 46 +#define FEATURE_CPPC_PREFERRED_CORES 47 +#define FEATURE_DF_CSTATES_BIT 48 +#define FEATURE_SPARE2_BIT 49 //SPARE +#define FEATURE_ATHUB_PG_BIT 50 +#define FEATURE_VDDOFF_ECO_BIT 51 +#define FEATURE_ZSTATES_ECO_BIT 52 +#define FEATURE_CC6_BIT 53 +#define FEATURE_DS_UMCCLK_BIT 54 +#define FEATURE_DS_ISPCLK_BIT 55 +#define FEATURE_DS_HSPCLK_BIT 56 +#define FEATURE_P3T_BIT 57 +#define FEATURE_DS_IPUCLK_BIT 58 +#define FEATURE_DS_VPECLK_BIT 59 +#define FEATURE_VPE_DPM_BIT 60 +#define FEATURE_SPARE_61 61 +#define FEATURE_FP_DIDT 62 +#define NUM_FEATURES 63 + +// Firmware Header/Footer +struct SMU14_Firmware_Footer { + uint32_t Signature; +}; +typedef struct SMU14_Firmware_Footer SMU14_Firmware_Footer; + +// PSP3.0 Header Definition +typedef struct { + uint32_t ImageVersion; + uint32_t ImageVersion2; // This is repeated because DW0 cannot be written in SRAM due to HW bug. + uint32_t Padding0[3]; + uint32_t SizeFWSigned; + uint32_t Padding1[25]; + uint32_t FirmwareType; + uint32_t Filler[32]; +} SMU_Firmware_Header; + +typedef struct { + // MP1_EXT_SCRATCH0 + uint32_t DpmHandlerID : 8; + uint32_t ActivityMonitorID : 8; + uint32_t DpmTimerID : 8; + uint32_t DpmHubID : 4; + uint32_t DpmHubTask : 4; + // MP1_EXT_SCRATCH1 + uint32_t CclkSyncStatus : 8; + uint32_t Ccx0CpuOff : 2; + uint32_t Ccx1CpuOff : 2; + uint32_t GfxOffStatus : 2; + uint32_t VddOff : 1; + uint32_t InWhisperMode : 1; + uint32_t ZstateStatus : 4; + uint32_t spare0 : 4; + uint32_t DstateFun : 4; + uint32_t DstateDev : 4; + // MP1_EXT_SCRATCH2 + uint32_t P2JobHandler :24; + uint32_t RsmuPmiP2PendingCnt : 8; + // MP1_EXT_SCRATCH3 + uint32_t PostCode :32; + // MP1_EXT_SCRATCH4 + uint32_t MsgPortBusy :24; + uint32_t RsmuPmiP1Pending : 1; + uint32_t DfCstateExitPending : 1; + uint32_t Ccx0Pc6ExitPending : 1; + uint32_t Ccx1Pc6ExitPending : 1; + uint32_t WarmResetPending : 1; + uint32_t spare1 : 3; + // MP1_EXT_SCRATCH5 + uint32_t IdleMask :32; + // MP1_EXT_SCRATCH6 = RTOS threads' status + // MP1_EXT_SCRATCH7 = RTOS Current Job +} FwStatus_t; + + +#pragma pack(pop) + +#endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_ppsmc.h new file mode 100644 index 000000000000..8a8a57c56bc0 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v14_0_0_ppsmc.h @@ -0,0 +1,143 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __SMU_V14_0_0_PPSMC_H__ +#define __SMU_V14_0_0_PPSMC_H__ + +/*! @mainpage PMFW-PPS (PPLib) Message Interface + This documentation contains the subsections:\n\n + @ref ResponseCodes\n + @ref definitions\n + @ref enums\n +*/ + +/** @def PPS_PMFW_IF_VER +* PPS (PPLib) to PMFW IF version 1.0 +*/ +#define PPS_PMFW_IF_VER "1.0" ///< Major.Minor + +/** @defgroup ResponseCodes PMFW Response Codes +* @{ +*/ +// SMU Response Codes: +#define PPSMC_Result_OK 0x1 ///< Message Response OK +#define PPSMC_Result_Failed 0xFF ///< Message Response Failed +#define PPSMC_Result_UnknownCmd 0xFE ///< Message Response Unknown Command +#define PPSMC_Result_CmdRejectedPrereq 0xFD ///< Message Response Command Failed Prerequisite +#define PPSMC_Result_CmdRejectedBusy 0xFC ///< Message Response Command Rejected due to PMFW is busy. Sender should retry sending this message +/** @}*/ + +/** @defgroup definitions Message definitions +* @{ +*/ +// Message Definitions: +#define PPSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team +#define PPSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version +#define PPSMC_MSG_GetDriverIfVersion 0x03 ///< Get PMFW_DRIVER_IF version +#define PPSMC_MSG_SPARE0 0x04 ///< SPARE +#define PPSMC_MSG_SPARE1 0x05 ///< SPARE +#define PPSMC_MSG_PowerDownVcn 0x06 ///< Power down VCN +#define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default +#define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display +#define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz +#define PPSMC_MSG_SPARE2 0x0A ///< SPARE +#define PPSMC_MSG_SPARE3 0x0B ///< SPARE +#define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload +#define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer +#define PPSMC_MSG_SetDriverDramAddrLow 0x0E ///< Set low 32 bits of DRAM address for Driver table transfer +#define PPSMC_MSG_TransferTableSmu2Dram 0x0F ///< Transfer driver interface table from PMFW SRAM to DRAM +#define PPSMC_MSG_TransferTableDram2Smu 0x10 ///< Transfer driver interface table from DRAM to PMFW SRAM +#define PPSMC_MSG_GfxDeviceDriverReset 0x11 ///< Request GFX mode 2 reset +#define PPSMC_MSG_GetEnabledSmuFeatures 0x12 ///< Get enabled features in PMFW +#define PPSMC_MSG_SetHardMinSocclkByFreq 0x13 ///< Set hard min for SOC CLK +#define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK +#define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK) + +#define PPSMC_MSG_EnableGfxImu 0x16 ///< Enable GFX IMU + +#define PPSMC_MSG_spare_0x17 0x17 +#define PPSMC_MSG_spare_0x18 0x18 +#define PPSMC_MSG_AllowGfxOff 0x19 ///< Inform PMFW of allowing GFXOFF entry +#define PPSMC_MSG_DisallowGfxOff 0x1A ///< Inform PMFW of disallowing GFXOFF entry +#define PPSMC_MSG_SetSoftMaxGfxClk 0x1B ///< Set soft max for GFX CLK +#define PPSMC_MSG_SetHardMinGfxClk 0x1C ///< Set hard min for GFX CLK + +#define PPSMC_MSG_SetSoftMaxSocclkByFreq 0x1D ///< Set soft max for SOC CLK +#define PPSMC_MSG_SetSoftMaxFclkByFreq 0x1E ///< Set soft max for FCLK +#define PPSMC_MSG_SetSoftMaxVcn 0x1F ///< Set soft max for VCN clocks (VCLK and DCLK) +#define PPSMC_MSG_spare_0x20 0x20 +#define PPSMC_MSG_PowerDownJpeg 0x21 ///< Power down Jpeg +#define PPSMC_MSG_PowerUpJpeg 0x22 ///< Power up Jpeg; VCN is power gated by default + +#define PPSMC_MSG_SetHardMinFclkByFreq 0x23 ///< Set hard min for FCLK +#define PPSMC_MSG_SetSoftMinSocclkByFreq 0x24 ///< Set soft min for SOC CLK +#define PPSMC_MSG_AllowZstates 0x25 ///< Inform PMFM of allowing Zstate entry, i.e. no Miracast activity +#define PPSMC_MSG_Reserved 0x26 ///< Not used +#define PPSMC_MSG_Reserved1 0x27 ///< Not used, previously PPSMC_MSG_RequestActiveWgp +#define PPSMC_MSG_Reserved2 0x28 ///< Not used, previously PPSMC_MSG_QueryActiveWgp +#define PPSMC_MSG_PowerDownIspByTile 0x29 ///< ISP is power gated by default +#define PPSMC_MSG_PowerUpIspByTile 0x2A ///< This message is used to power up ISP tiles and enable the ISP DPM +#define PPSMC_MSG_SetHardMinIspiclkByFreq 0x2B ///< Set HardMin by frequency for ISPICLK +#define PPSMC_MSG_SetHardMinIspxclkByFreq 0x2C ///< Set HardMin by frequency for ISPXCLK +#define PPSMC_MSG_PowerDownUmsch 0x2D ///< Power down VCN.UMSCH (aka VSCH) scheduler +#define PPSMC_MSG_PowerUpUmsch 0x2E ///< Power up VCN.UMSCH (aka VSCH) scheduler +#define PPSMC_Message_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis +#define PPSMC_Message_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn +#define PPSMC_MSG_PowerUpVpe 0x31 ///< Power up VPE +#define PPSMC_MSG_PowerDownVpe 0x32 ///< Power down VPE +#define PPSMC_MSG_GetVpeDpmTable 0x33 ///< Get VPE DPM table +#define PPSMC_MSG_EnableLSdma 0x34 ///< Enable LSDMA +#define PPSMC_MSG_DisableLSdma 0x35 ///< Disable LSDMA +#define PPSMC_MSG_SetSoftMaxVpe 0x36 ///< +#define PPSMC_MSG_SetSoftMinVpe 0x37 ///< +#define PPSMC_Message_Count 0x38 ///< Total number of PPSMC messages +/** @}*/ + +/** +* @defgroup enums Enum Definitions +* @{ +*/ + +/** @enum Mode_Reset_e +* Mode reset type, argument for PPSMC_MSG_GfxDeviceDriverReset +*/ +//argument for PPSMC_MSG_GfxDeviceDriverReset +typedef enum { + MODE1_RESET = 1, ///< Mode reset type 1 + MODE2_RESET = 2 ///< Mode reset type 2 +} Mode_Reset_e; + +/** @}*/ + +/** @enum ZStates_e +* Zstate types, argument for PPSMC_MSG_AllowZstates +*/ +//Argument for PPSMC_MSG_AllowZstates +typedef enum { + DISALLOW_ZSTATES = 0, ///< Disallow Zstates + ALLOW_ZSTATES_Z8 = 8, ///< Allows Z8 only + ALLOW_ZSTATES_Z9 = 9, ///< Allows Z9 and Z8 +} ZStates_e; + +/** @}*/ +#endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h index beab6d7b28b7..630132c4a76b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_11_0_cdr_table.h @@ -52,8 +52,7 @@ static unsigned int DbiPrbs7[] = //4096 bytes, 256 byte aligned -static unsigned int NoDbiPrbs7[] = -{ +static unsigned int NoDbiPrbs7[] = { 0x0f0f0f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f00f0f, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f0f0f0, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f00f0f, 0xf0f00f0f, 0xf0f00f0f, 0x0f0ff0f0, 0xf0f0f0f0, 0xf0f0f0f0, 0x0f0ff0f0, 0x0f0f0f0f, 0x0f0f0f0f, 0xf0f0f0f0, 0xf0f00f0f, 0x0f0f0f0f, 0xf0f00f0f, 0x0f0ff0f0, 0x0f0f0f0f, 0xf0f0f0f0, 0x0f0ff0f0, 0xf0f00f0f, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0ff0f0, 0xf0f0f0f0, 0xf0f00f0f, 0xf0f0f0f0, 0x0f0f0f0f, 0x0f0ff0f0, 0xf0f00f0f, @@ -121,8 +120,7 @@ static unsigned int NoDbiPrbs7[] = }; // 4096 bytes, 256 byte aligned -static unsigned int DbiPrbs7[] = -{ +static unsigned int DbiPrbs7[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x00000000, 0xffffffff, 0x00000000, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000, 0xffff0000, 0xffffffff, 0xffffffff, 0x00000000, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffff0000, 0xffffffff, 0x00000000, 0xffff0000, 0x0000ffff, 0x0000ffff, 0x00000000, 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000, 0xffffffff, 0xffff0000, 0x0000ffff, diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h index 297b70b9388f..9dd47d91093e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h @@ -84,6 +84,7 @@ __SMU_DUMMY_MAP(SetTjMax), \ __SMU_DUMMY_MAP(SetFanTemperatureTarget), \ __SMU_DUMMY_MAP(PrepareMp1ForUnload), \ + __SMU_DUMMY_MAP(GetCTFLimit), \ __SMU_DUMMY_MAP(DramLogSetDramAddrHigh), \ __SMU_DUMMY_MAP(DramLogSetDramAddrLow), \ __SMU_DUMMY_MAP(DramLogSetDramSize), \ @@ -245,7 +246,20 @@ __SMU_DUMMY_MAP(AllowGpo), \ __SMU_DUMMY_MAP(Mode2Reset), \ __SMU_DUMMY_MAP(RequestI2cTransaction), \ - __SMU_DUMMY_MAP(GetMetricsTable), + __SMU_DUMMY_MAP(GetMetricsTable), \ + __SMU_DUMMY_MAP(DALNotPresent), \ + __SMU_DUMMY_MAP(ClearMcaOnRead), \ + __SMU_DUMMY_MAP(QueryValidMcaCount), \ + __SMU_DUMMY_MAP(QueryValidMcaCeCount), \ + __SMU_DUMMY_MAP(McaBankDumpDW), \ + __SMU_DUMMY_MAP(McaBankCeDumpDW), \ + __SMU_DUMMY_MAP(SelectPLPDMode), \ + __SMU_DUMMY_MAP(PowerUpVpe), \ + __SMU_DUMMY_MAP(PowerDownVpe), \ + __SMU_DUMMY_MAP(PowerUpUmsch), \ + __SMU_DUMMY_MAP(PowerDownUmsch), \ + __SMU_DUMMY_MAP(SetSoftMaxVpe), \ + __SMU_DUMMY_MAP(SetSoftMinVpe), #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) SMU_MSG_##type @@ -278,6 +292,11 @@ enum smu_clk_type { SMU_OD_VDDC_CURVE, SMU_OD_RANGE, SMU_OD_VDDGFX_OFFSET, + SMU_OD_FAN_CURVE, + SMU_OD_ACOUSTIC_LIMIT, + SMU_OD_ACOUSTIC_TARGET, + SMU_OD_FAN_TARGET_TEMPERATURE, + SMU_OD_FAN_MINIMUM_PWM, SMU_CLK_COUNT, }; @@ -402,7 +421,9 @@ enum smu_clk_type { __SMU_DUMMY_MAP(MEM_TEMP_READ), \ __SMU_DUMMY_MAP(ATHUB_MMHUB_PG), \ __SMU_DUMMY_MAP(BACO_CG), \ - __SMU_DUMMY_MAP(SOC_CG), + __SMU_DUMMY_MAP(SOC_CG), \ + __SMU_DUMMY_MAP(LOW_POWER_DCNCLKS), \ + __SMU_DUMMY_MAP(WHISPER_MODE), #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(feature) SMU_FEATURE_##feature##_BIT diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h index d466db6f0ad4..a0e5ad0381d6 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h @@ -64,11 +64,9 @@ #define LINK_SPEED_MAX 3 static const __maybe_unused uint16_t link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const __maybe_unused uint16_t link_speed[] = {25, 50, 80, 160}; static const -struct smu_temperature_range __maybe_unused smu11_thermal_policy[] = -{ +struct smu_temperature_range __maybe_unused smu11_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; @@ -96,8 +94,8 @@ struct smu_11_0_dpm_table { }; struct smu_11_0_pcie_table { - uint8_t pcie_gen[MAX_PCIE_CONF]; - uint8_t pcie_lane[MAX_PCIE_CONF]; + uint8_t pcie_gen[MAX_PCIE_CONF]; + uint8_t pcie_lane[MAX_PCIE_CONF]; }; struct smu_11_0_dpm_tables { diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h index 0116e3d04fad..df7430876e0c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0_pptable.h @@ -101,8 +101,7 @@ enum SMU_11_0_ODSETTING_ID { }; #define SMU_11_0_MAX_ODSETTING 32 //Maximum Number of ODSettings -struct smu_11_0_overdrive_table -{ +struct smu_11_0_overdrive_table { uint8_t revision; //Revision = SMU_11_0_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -127,8 +126,7 @@ enum SMU_11_0_PPCLOCK_ID { }; #define SMU_11_0_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_11_0_power_saving_clock_table -{ +struct smu_11_0_power_saving_clock_table { uint8_t revision; //Revision = SMU_11_0_PP_POWERSAVINGCLOCK_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t count; //power_saving_clock_count = SMU_11_0_PPCLOCK_COUNT @@ -136,8 +134,7 @@ struct smu_11_0_power_saving_clock_table uint32_t min[SMU_11_0_MAX_PPCLOCK]; //PowerSavingClock Mode Clock Minimum array In MHz }; -struct smu_11_0_powerplay_table -{ +struct smu_11_0_powerplay_table { struct atom_common_table_header header; uint8_t table_revision; uint16_t table_size; //Driver portion table size. The offset to smc_pptable including header size @@ -145,14 +142,14 @@ struct smu_11_0_powerplay_table uint32_t golden_revision; uint16_t format_id; uint32_t platform_caps; //POWERPLAYABLE::ulPlatformCaps - + uint8_t thermal_controller_type; //one of SMU_11_0_PP_THERMALCONTROLLER uint16_t small_power_limit1; uint16_t small_power_limit2; uint16_t boost_power_limit; - uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. - uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. + uint16_t od_turbo_power_limit; //Power limit setting for Turbo mode in Performance UI Tuning. + uint16_t od_power_save_power_limit; //Power limit setting for PowerSave/Optimal mode in Performance UI Tuning. uint16_t software_shutdown_temp; uint16_t reserve[6]; //Zero filled field reserved for future use diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h index 355c156d871a..95cb919718ae 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h @@ -296,8 +296,10 @@ int smu_v13_0_get_pptable_from_firmware(struct smu_context *smu, uint32_t pptable_id); int smu_v13_0_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap); + uint8_t pcie_gen_cap, + uint8_t pcie_width_cap); + +int smu_v13_0_disable_pmfw_state(struct smu_context *smu); #endif #endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h index eadbe0149cae..eb694f9f556d 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0_7_pptable.h @@ -41,8 +41,7 @@ #define SMU_13_0_7_PP_OVERDRIVE_VERSION 0x83 // OverDrive 8 Table Version 0.2 #define SMU_13_0_7_PP_POWERSAVINGCLOCK_VERSION 0x01 // Power Saving Clock Table Version 1.00 -enum SMU_13_0_7_ODFEATURE_CAP -{ +enum SMU_13_0_7_ODFEATURE_CAP { SMU_13_0_7_ODCAP_GFXCLK_LIMITS = 0, SMU_13_0_7_ODCAP_UCLK_LIMITS, SMU_13_0_7_ODCAP_POWER_LIMIT, @@ -62,8 +61,7 @@ enum SMU_13_0_7_ODFEATURE_CAP SMU_13_0_7_ODCAP_COUNT, }; -enum SMU_13_0_7_ODFEATURE_ID -{ +enum SMU_13_0_7_ODFEATURE_ID { SMU_13_0_7_ODFEATURE_GFXCLK_LIMITS = 1 << SMU_13_0_7_ODCAP_GFXCLK_LIMITS, //GFXCLK Limit feature SMU_13_0_7_ODFEATURE_UCLK_LIMITS = 1 << SMU_13_0_7_ODCAP_UCLK_LIMITS, //UCLK Limit feature SMU_13_0_7_ODFEATURE_POWER_LIMIT = 1 << SMU_13_0_7_ODCAP_POWER_LIMIT, //Power Limit feature @@ -85,8 +83,7 @@ enum SMU_13_0_7_ODFEATURE_ID #define SMU_13_0_7_MAX_ODFEATURE 32 //Maximum Number of OD Features -enum SMU_13_0_7_ODSETTING_ID -{ +enum SMU_13_0_7_ODSETTING_ID { SMU_13_0_7_ODSETTING_GFXCLKFMAX = 0, SMU_13_0_7_ODSETTING_GFXCLKFMIN, SMU_13_0_7_ODSETTING_UCLKFMIN, @@ -123,8 +120,7 @@ enum SMU_13_0_7_ODSETTING_ID }; #define SMU_13_0_7_MAX_ODSETTING 64 //Maximum Number of ODSettings -enum SMU_13_0_7_PWRMODE_SETTING -{ +enum SMU_13_0_7_PWRMODE_SETTING { SMU_13_0_7_PMSETTING_POWER_LIMIT_QUIET = 0, SMU_13_0_7_PMSETTING_POWER_LIMIT_BALANCE, SMU_13_0_7_PMSETTING_POWER_LIMIT_TURBO, @@ -144,8 +140,7 @@ enum SMU_13_0_7_PWRMODE_SETTING }; #define SMU_13_0_7_MAX_PMSETTING 32 //Maximum Number of PowerMode Settings -struct smu_13_0_7_overdrive_table -{ +struct smu_13_0_7_overdrive_table { uint8_t revision; //Revision = SMU_13_0_7_PP_OVERDRIVE_VERSION uint8_t reserve[3]; //Zero filled field reserved for future use uint32_t feature_count; //Total number of supported features @@ -156,8 +151,7 @@ struct smu_13_0_7_overdrive_table int16_t pm_setting[SMU_13_0_7_MAX_PMSETTING]; //Optimized power mode feature settings }; -enum SMU_13_0_7_PPCLOCK_ID -{ +enum SMU_13_0_7_PPCLOCK_ID { SMU_13_0_7_PPCLOCK_GFXCLK = 0, SMU_13_0_7_PPCLOCK_SOCCLK, SMU_13_0_7_PPCLOCK_UCLK, @@ -175,8 +169,7 @@ enum SMU_13_0_7_PPCLOCK_ID }; #define SMU_13_0_7_MAX_PPCLOCK 16 //Maximum Number of PP Clocks -struct smu_13_0_7_powerplay_table -{ +struct smu_13_0_7_powerplay_table { struct atom_common_table_header header; //For PLUM_BONITO, header.format_revision = 15, header.content_revision = 0 uint8_t table_revision; //For PLUM_BONITO, table_revision = 2 uint8_t padding; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h new file mode 100644 index 000000000000..a5b569976f19 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v14_0.h @@ -0,0 +1,230 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#ifndef __SMU_V14_0_H__ +#define __SMU_V14_0_H__ + +#include "amdgpu_smu.h" + +#define SMU14_DRIVER_IF_VERSION_INV 0xFFFFFFFF +#define SMU14_DRIVER_IF_VERSION_SMU_V14_0_2 0x1 +#define SMU14_DRIVER_IF_VERSION_SMU_V14_0_0 0x6 + +#define FEATURE_MASK(feature) (1ULL << feature) + +/* MP Apertures */ +#define MP0_Public 0x03800000 +#define MP0_SRAM 0x03900000 +#define MP1_Public 0x03b00000 +#define MP1_SRAM 0x03c00004 + +/* address block */ +#define smnMP1_FIRMWARE_FLAGS 0x3010028 +#define smnMP1_PUB_CTRL 0x3010d10 + +#define MAX_DPM_LEVELS 16 +#define MAX_PCIE_CONF 3 + +struct smu_14_0_max_sustainable_clocks { + uint32_t display_clock; + uint32_t phy_clock; + uint32_t pixel_clock; + uint32_t uclock; + uint32_t dcef_clock; + uint32_t soc_clock; +}; + +struct smu_14_0_dpm_clk_level { + bool enabled; + uint32_t value; +}; + +struct smu_14_0_dpm_table { + uint32_t min; /* MHz */ + uint32_t max; /* MHz */ + uint32_t count; + bool is_fine_grained; + struct smu_14_0_dpm_clk_level dpm_levels[MAX_DPM_LEVELS]; +}; + +struct smu_14_0_pcie_table { + uint8_t pcie_gen[MAX_PCIE_CONF]; + uint8_t pcie_lane[MAX_PCIE_CONF]; + uint16_t clk_freq[MAX_PCIE_CONF]; + uint32_t num_of_link_levels; +}; + +struct smu_14_0_dpm_tables { + struct smu_14_0_dpm_table soc_table; + struct smu_14_0_dpm_table gfx_table; + struct smu_14_0_dpm_table uclk_table; + struct smu_14_0_dpm_table eclk_table; + struct smu_14_0_dpm_table vclk_table; + struct smu_14_0_dpm_table dclk_table; + struct smu_14_0_dpm_table dcef_table; + struct smu_14_0_dpm_table pixel_table; + struct smu_14_0_dpm_table display_table; + struct smu_14_0_dpm_table phy_table; + struct smu_14_0_dpm_table fclk_table; + struct smu_14_0_pcie_table pcie_table; +}; + +struct smu_14_0_dpm_context { + struct smu_14_0_dpm_tables dpm_tables; + uint32_t workload_policy_mask; + uint32_t dcef_min_ds_clk; +}; + +enum smu_14_0_power_state { + SMU_14_0_POWER_STATE__D0 = 0, + SMU_14_0_POWER_STATE__D1, + SMU_14_0_POWER_STATE__D3, /* Sleep*/ + SMU_14_0_POWER_STATE__D4, /* Hibernate*/ + SMU_14_0_POWER_STATE__D5, /* Power off*/ +}; + +struct smu_14_0_power_context { + uint32_t power_source; + uint8_t in_power_limit_boost_mode; + enum smu_14_0_power_state power_state; +}; + +#if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) + +int smu_v14_0_init_microcode(struct smu_context *smu); + +void smu_v14_0_fini_microcode(struct smu_context *smu); + +int smu_v14_0_load_microcode(struct smu_context *smu); + +int smu_v14_0_init_smc_tables(struct smu_context *smu); + +int smu_v14_0_fini_smc_tables(struct smu_context *smu); + +int smu_v14_0_init_power(struct smu_context *smu); + +int smu_v14_0_fini_power(struct smu_context *smu); + +int smu_v14_0_check_fw_status(struct smu_context *smu); + +int smu_v14_0_setup_pptable(struct smu_context *smu); + +int smu_v14_0_get_vbios_bootup_values(struct smu_context *smu); + +int smu_v14_0_check_fw_version(struct smu_context *smu); + +int smu_v14_0_set_driver_table_location(struct smu_context *smu); + +int smu_v14_0_set_tool_table_location(struct smu_context *smu); + +int smu_v14_0_notify_memory_pool_location(struct smu_context *smu); + +int smu_v14_0_system_features_control(struct smu_context *smu, + bool en); + +int smu_v14_0_set_allowed_mask(struct smu_context *smu); + +int smu_v14_0_notify_display_change(struct smu_context *smu); + +int smu_v14_0_get_current_power_limit(struct smu_context *smu, + uint32_t *power_limit); + +int smu_v14_0_set_power_limit(struct smu_context *smu, + enum smu_ppt_limit_type limit_type, + uint32_t limit); + +int smu_v14_0_gfx_off_control(struct smu_context *smu, bool enable); + +int smu_v14_0_register_irq_handler(struct smu_context *smu); + +int smu_v14_0_baco_set_armd3_sequence(struct smu_context *smu, + enum smu_baco_seq baco_seq); + +bool smu_v14_0_baco_is_support(struct smu_context *smu); + +enum smu_baco_state smu_v14_0_baco_get_state(struct smu_context *smu); + +int smu_v14_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state); + +int smu_v14_0_baco_enter(struct smu_context *smu); +int smu_v14_0_baco_exit(struct smu_context *smu); + +int smu_v14_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, + uint32_t *min, uint32_t *max); + +int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_type clk_type, + uint32_t min, uint32_t max); + +int smu_v14_0_set_hard_freq_limited_range(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t min, + uint32_t max); + +int smu_v14_0_set_performance_level(struct smu_context *smu, + enum amd_dpm_forced_level level); + +int smu_v14_0_set_power_source(struct smu_context *smu, + enum smu_power_src_type power_src); + +int smu_v14_0_set_single_dpm_table(struct smu_context *smu, + enum smu_clk_type clk_type, + struct smu_14_0_dpm_table *single_dpm_table); + +int smu_v14_0_gfx_ulv_control(struct smu_context *smu, + bool enablement); + +int smu_v14_0_wait_for_event(struct smu_context *smu, enum smu_event_type event, + uint64_t event_arg); + +int smu_v14_0_set_vcn_enable(struct smu_context *smu, + bool enable); + +int smu_v14_0_set_jpeg_enable(struct smu_context *smu, + bool enable); + +int smu_v14_0_init_pptable_microcode(struct smu_context *smu); + +int smu_v14_0_run_btc(struct smu_context *smu); + +int smu_v14_0_gpo_control(struct smu_context *smu, + bool enablement); + +int smu_v14_0_deep_sleep_control(struct smu_context *smu, + bool enablement); + +int smu_v14_0_set_gfx_power_up_by_imu(struct smu_context *smu); + +int smu_v14_0_set_default_dpm_tables(struct smu_context *smu); + +int smu_v14_0_get_pptable_from_firmware(struct smu_context *smu, + void **table, + uint32_t *size, + uint32_t pptable_id); + +int smu_v14_0_od_edit_dpm_table(struct smu_context *smu, + enum PP_OD_DPM_TABLE_COMMAND type, + long input[], uint32_t size); + +void smu_v14_0_set_smu_mailbox_registers(struct smu_context *smu); + +#endif +#endif diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index 3bb18396d2f9..2cb6b68222ba 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -569,9 +569,9 @@ static int arcturus_populate_umd_state_clk(struct smu_context *smu) return 0; } -static int arcturus_get_clk_table(struct smu_context *smu, - struct pp_clock_levels_with_latency *clocks, - struct smu_11_0_dpm_table *dpm_table) +static void arcturus_get_clk_table(struct smu_context *smu, + struct pp_clock_levels_with_latency *clocks, + struct smu_11_0_dpm_table *dpm_table) { uint32_t i; @@ -584,8 +584,6 @@ static int arcturus_get_clk_table(struct smu_context *smu, dpm_table->dpm_levels[i].value * 1000; clocks->data[i].latency_in_us = 0; } - - return 0; } static int arcturus_freqs_in_same_level(int32_t frequency1, @@ -598,7 +596,7 @@ static int arcturus_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -757,173 +755,133 @@ static int arcturus_get_current_clk_freq_by_table(struct smu_context *smu, value); } -static int arcturus_print_clk_levels(struct smu_context *smu, - enum smu_clk_type type, char *buf) +static int arcturus_emit_clk_levels(struct smu_context *smu, + enum smu_clk_type type, char *buf, int *offset) { - int i, now, size = 0; int ret = 0; struct pp_clock_levels_with_latency clocks; struct smu_11_0_dpm_table *single_dpm_table; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_11_0_dpm_context *dpm_context = NULL; uint32_t gen_speed, lane_width; - - smu_cmn_get_sysfs_buf(&buf, &size); + uint32_t i, cur_value = 0; + bool freq_match; + unsigned int clock_mhz; + static const char attempt_string[] = "Attempt to get current"; if (amdgpu_ras_intr_triggered()) { - size += sysfs_emit_at(buf, size, "unavailable\n"); - return size; + *offset += sysfs_emit_at(buf, *offset, "unavailable\n"); + return -EBUSY; } dpm_context = smu_dpm->dpm_context; switch (type) { case SMU_SCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current gfx clk Failed!"); + dev_err(smu->adev->dev, "%s gfx clk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.gfx_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get gfx clk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - /* - * For DPM disabled case, there will be only one clock level. - * And it's safe to assume that is always the current clock. - */ - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, - clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_MCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_UCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_UCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current mclk Failed!"); + dev_err(smu->adev->dev, "%s mclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.uclk_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get memory clk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_SOCCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current socclk Failed!"); + dev_err(smu->adev->dev, "%s socclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.soc_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get socclk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_FCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_FCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_FCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current fclk Failed!"); + dev_err(smu->adev->dev, "%s fclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.fclk_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get fclk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_VCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_VCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_VCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current vclk Failed!"); + dev_err(smu->adev->dev, "%s vclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.vclk_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get vclk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_DCLK: - ret = arcturus_get_current_clk_freq_by_table(smu, SMU_DCLK, &now); + ret = arcturus_get_current_clk_freq_by_table(smu, SMU_DCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current dclk Failed!"); + dev_err(smu->adev->dev, "%s dclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.dclk_table); - ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get dclk levels Failed!"); - return ret; - } + arcturus_get_clk_table(smu, &clocks, single_dpm_table); - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (arcturus_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); break; case SMU_PCIE: gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu); lane_width = smu_v11_0_get_current_pcie_link_width_level(smu); - size += sysfs_emit_at(buf, size, "0: %s %s %dMhz *\n", + break; + + default: + return -EINVAL; + } + + switch (type) { + case SMU_SCLK: + case SMU_MCLK: + case SMU_SOCCLK: + case SMU_FCLK: + case SMU_VCLK: + case SMU_DCLK: + /* + * For DPM disabled case, there will be only one clock level. + * And it's safe to assume that is always the current clock. + */ + for (i = 0; i < clocks.num_levels; i++) { + clock_mhz = clocks.data[i].clocks_in_khz / 1000; + freq_match = arcturus_freqs_in_same_level(clock_mhz, cur_value); + freq_match |= (clocks.num_levels == 1); + + *offset += sysfs_emit_at(buf, *offset, "%d: %uMhz %s\n", + i, clock_mhz, + freq_match ? "*" : ""); + } + break; + + case SMU_PCIE: + *offset += sysfs_emit_at(buf, *offset, "0: %s %s %dMhz *\n", (gen_speed == 0) ? "2.5GT/s," : (gen_speed == 1) ? "5.0GT/s," : (gen_speed == 2) ? "8.0GT/s," : @@ -938,10 +896,10 @@ static int arcturus_print_clk_levels(struct smu_context *smu, break; default: - break; + return -EINVAL; } - return size; + return 0; } static int arcturus_upload_dpm_level(struct smu_context *smu, @@ -1005,17 +963,10 @@ static int arcturus_force_clk_levels(struct smu_context *smu, struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_11_0_dpm_table *single_dpm_table = NULL; uint32_t soft_min_level, soft_max_level; - uint32_t smu_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(smu->adev->dev, "Failed to get smu version!\n"); - return ret; - } - - if ((smu_version >= 0x361200) && - (smu_version <= 0x361a00)) { + if ((smu->smc_fw_version >= 0x361200) && + (smu->smc_fw_version <= 0x361a00)) { dev_err(smu->adev->dev, "Forcing clock level is not supported with " "54.18 - 54.26(included) SMU firmwares\n"); return -EOPNOTSUPP; @@ -1130,7 +1081,7 @@ static int arcturus_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = arcturus_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -1169,6 +1120,7 @@ static int arcturus_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1244,7 +1196,7 @@ static int arcturus_set_fan_speed_pwm(struct smu_context *smu, uint32_t duty100, duty; uint64_t tmp64; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1_ARCT), CG_FDO_CTRL1, FMAX_DUTY100); @@ -1308,7 +1260,7 @@ static int arcturus_get_fan_speed_pwm(struct smu_context *smu, if (duty100) { tmp64 = (uint64_t)duty * 255; do_div(tmp64, duty100); - *speed = MIN((uint32_t)tmp64, 255); + *speed = min_t(uint32_t, tmp64, 255); } else { *speed = 0; } @@ -1326,14 +1278,15 @@ static int arcturus_get_fan_parameters(struct smu_context *smu) } static int arcturus_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_11_0_powerplay_table *powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit, od_percent; + uint32_t power_limit, od_percent_upper, od_percent_lower; if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { /* the last hope to figure out the ppt limit */ @@ -1350,17 +1303,25 @@ static int arcturus_get_power_limit(struct smu_context *smu, if (default_power_limit) *default_power_limit = power_limit; - if (max_power_limit) { - if (smu->od_enabled) { - od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + if (smu->od_enabled) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } else { + od_percent_upper = 0; + od_percent_lower = 100; + } - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", + od_percent_upper, od_percent_lower, power_limit); - power_limit *= (100 + od_percent); - power_limit /= 100; - } + if (max_power_limit) { + *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit /= 100; + } - *max_power_limit = power_limit; + if (min_power_limit) { + *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit /= 100; } return 0; @@ -1385,16 +1346,11 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, uint32_t i, size = 0; int16_t workload_type = 0; int result = 0; - uint32_t smu_version; if (!buf) return -EINVAL; - result = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (result) - return result; - - if (smu_version >= 0x360d00) + if (smu->smc_fw_version >= 0x360d00) size += sysfs_emit_at(buf, size, "%16s %s %s %s %s %s %s %s %s %s %s\n", title[0], title[1], title[2], title[3], title[4], title[5], title[6], title[7], title[8], title[9], title[10]); @@ -1413,7 +1369,7 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, if (workload_type < 0) continue; - if (smu_version >= 0x360d00) { + if (smu->smc_fw_version >= 0x360d00) { result = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, @@ -1428,7 +1384,7 @@ static int arcturus_get_power_profile_mode(struct smu_context *smu, size += sysfs_emit_at(buf, size, "%2d %14s%s\n", i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); - if (smu_version >= 0x360d00) { + if (smu->smc_fw_version >= 0x360d00) { size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", " ", 0, @@ -1470,19 +1426,15 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, int workload_type = 0; uint32_t profile_mode = input[size]; int ret = 0; - uint32_t smu_version; if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode); return -EINVAL; } - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) - return ret; if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) && - (smu_version >=0x360d00)) { + (smu->smc_fw_version >= 0x360d00)) { ret = smu_cmn_update_table(smu, SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, @@ -1558,15 +1510,6 @@ static int arcturus_set_power_profile_mode(struct smu_context *smu, static int arcturus_set_performance_level(struct smu_context *smu, enum amd_dpm_forced_level level) { - uint32_t smu_version; - int ret; - - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(smu->adev->dev, "Failed to get smu version!\n"); - return ret; - } - switch (level) { case AMD_DPM_FORCED_LEVEL_HIGH: case AMD_DPM_FORCED_LEVEL_LOW: @@ -1574,8 +1517,8 @@ static int arcturus_set_performance_level(struct smu_context *smu, case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: - if ((smu_version >= 0x361200) && - (smu_version <= 0x361a00)) { + if ((smu->smc_fw_version >= 0x361200) && + (smu->smc_fw_version <= 0x361a00)) { dev_err(smu->adev->dev, "Forcing clock level is not supported with " "54.18 - 54.26(included) SMU firmwares\n"); return -EOPNOTSUPP; @@ -2213,16 +2156,11 @@ static void arcturus_i2c_control_fini(struct smu_context *smu) static void arcturus_get_unique_id(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - uint32_t top32 = 0, bottom32 = 0, smu_version; + uint32_t top32 = 0, bottom32 = 0; uint64_t id; - if (smu_cmn_get_smc_version(smu, NULL, &smu_version)) { - dev_warn(adev->dev, "Failed to get smu version, cannot get unique_id or serial_number\n"); - return; - } - /* PPSMC_MSG_ReadSerial* is supported by 54.23.0 and onwards */ - if (smu_version < 0x361700) { + if (smu->smc_fw_version < 0x361700) { dev_warn(adev->dev, "ReadSerial is only supported by PMFW 54.23.0 and onwards\n"); return; } @@ -2233,18 +2171,12 @@ static void arcturus_get_unique_id(struct smu_context *smu) id = ((uint64_t)bottom32 << 32) | top32; adev->unique_id = id; - /* For Arcturus-and-later, unique_id == serial_number, so convert it to a - * 16-digit HEX string for convenience and backwards-compatibility - */ - sprintf(adev->serial, "%llx", id); } static int arcturus_set_df_cstate(struct smu_context *smu, enum pp_df_cstate state) { struct amdgpu_device *adev = smu->adev; - uint32_t smu_version; - int ret; /* * Arcturus does not need the cstate disablement @@ -2253,14 +2185,8 @@ static int arcturus_set_df_cstate(struct smu_context *smu, if (amdgpu_in_reset(adev) || adev->in_suspend) return 0; - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(smu->adev->dev, "Failed to get smu version!\n"); - return ret; - } - /* PPSMC_MSG_DFCstateControl is supported by 54.15.0 and onwards */ - if (smu_version < 0x360F00) { + if (smu->smc_fw_version < 0x360F00) { dev_err(smu->adev->dev, "DFCstateControl is only supported by PMFW 54.15.0 and onwards\n"); return -EINVAL; } @@ -2268,33 +2194,25 @@ static int arcturus_set_df_cstate(struct smu_context *smu, return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL); } -static int arcturus_allow_xgmi_power_down(struct smu_context *smu, bool en) +static int arcturus_select_xgmi_plpd_policy(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode) { - uint32_t smu_version; - int ret; - - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(smu->adev->dev, "Failed to get smu version!\n"); - return ret; - } - /* PPSMC_MSG_GmiPwrDnControl is supported by 54.23.0 and onwards */ - if (smu_version < 0x00361700) { + if (smu->smc_fw_version < 0x00361700) { dev_err(smu->adev->dev, "XGMI power down control is only supported by PMFW 54.23.0 and onwards\n"); return -EINVAL; } - if (en) + if (mode == XGMI_PLPD_DEFAULT) return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GmiPwrDnControl, - 1, - NULL); - - return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GmiPwrDnControl, - 0, - NULL); + 1, NULL); + else if (mode == XGMI_PLPD_DISALLOW) + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GmiPwrDnControl, + 0, NULL); + else + return -EINVAL; } static const struct throttling_logging_label { @@ -2312,7 +2230,7 @@ static const struct throttling_logging_label { static void arcturus_log_thermal_throttling_event(struct smu_context *smu) { int ret; - int throttler_idx, throtting_events = 0, buf_idx = 0; + int throttler_idx, throttling_events = 0, buf_idx = 0; struct amdgpu_device *adev = smu->adev; uint32_t throttler_status; char log_buf[256]; @@ -2327,11 +2245,11 @@ static void arcturus_log_thermal_throttling_event(struct smu_context *smu) for (throttler_idx = 0; throttler_idx < ARRAY_SIZE(logging_label); throttler_idx++) { if (throttler_status & logging_label[throttler_idx].feature_mask) { - throtting_events++; + throttling_events++; buf_idx += snprintf(log_buf + buf_idx, sizeof(log_buf) - buf_idx, "%s%s", - throtting_events > 1 ? " and " : "", + throttling_events > 1 ? " and " : "", logging_label[throttler_idx].label); if (buf_idx >= sizeof(log_buf)) { dev_err(adev->dev, "buffer overflow!\n"); @@ -2432,7 +2350,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .set_default_dpm_table = arcturus_set_default_dpm_table, .populate_umd_state_clk = arcturus_populate_umd_state_clk, .get_thermal_temperature_range = arcturus_get_thermal_temperature_range, - .print_clk_levels = arcturus_print_clk_levels, + .emit_clk_levels = arcturus_emit_clk_levels, .force_clk_levels = arcturus_force_clk_levels, .read_sensor = arcturus_read_sensor, .get_fan_speed_pwm = arcturus_get_fan_speed_pwm, @@ -2496,7 +2414,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = { .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, .set_df_cstate = arcturus_set_df_cstate, - .allow_xgmi_power_down = arcturus_allow_xgmi_power_down, + .select_xgmi_plpd_policy = arcturus_select_xgmi_plpd_policy, .log_thermal_throttling_event = arcturus_log_thermal_throttling_event, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index ca4d97b7f576..9548bd3c624b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -154,10 +154,14 @@ cyan_skillfish_get_smu_metrics_data(struct smu_context *smu, case METRICS_CURR_UCLK: *value = metrics->Current.MemclkFrequency; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; + case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; case METRICS_TEMPERATURE_EDGE: *value = metrics->Current.GfxTemperature / 100 * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; @@ -208,12 +212,18 @@ static int cyan_skillfish_read_sensor(struct smu_context *smu, *(uint32_t *)data *= 100; *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = cyan_skillfish_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_TEMPERATURE_HOTSPOT, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index 95f6d821bacb..a38233cc5b7f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -136,7 +136,7 @@ static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0), MSG_MAP(BacoAudioD3PME, PPSMC_MSG_BacoAudioD3PME, 0), MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), - MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE,PPSMC_MSG_DALDisableDummyPstateChange, 0), + MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALDisableDummyPstateChange, 0), MSG_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALEnableDummyPstateChange, 0), MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm, 0), MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive, 0), @@ -345,8 +345,8 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, /* DPM UCLK enablement should be skipped for navi10 A0 secure board */ if (!(is_asic_secure(smu) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && - (adev->rev_id == 0)) && + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0)) && + (adev->rev_id == 0)) && (adev->pm.pp_feature & PP_MCLK_DPM_MASK)) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) @@ -354,7 +354,7 @@ navi10_get_allowed_feature_mask(struct smu_context *smu, /* DS SOCCLK enablement should be skipped for navi10 A0 secure board */ if (is_asic_secure(smu) && - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0)) && (adev->rev_id == 0)) *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_DS_SOCCLK_BIT); @@ -556,7 +556,7 @@ static int navi10_get_legacy_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_legacy_t *metrics = (SmuMetrics_legacy_t *)smu_table->metrics_table; int ret = 0; @@ -642,7 +642,7 @@ static int navi10_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -731,7 +731,7 @@ static int navi12_get_legacy_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_NV12_legacy_t *metrics = (SmuMetrics_NV12_legacy_t *)smu_table->metrics_table; int ret = 0; @@ -817,7 +817,7 @@ static int navi12_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_NV12_t *metrics = (SmuMetrics_NV12_t *)smu_table->metrics_table; int ret = 0; @@ -907,18 +907,11 @@ static int navi1x_get_smu_metrics_data(struct smu_context *smu, uint32_t *value) { struct amdgpu_device *adev = smu->adev; - uint32_t smu_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(adev->dev, "Failed to get smu version!\n"); - return ret; - } - - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 9): - if (smu_version > 0x00341C00) + if (smu->smc_fw_version > 0x00341C00) ret = navi12_get_smu_metrics_data(smu, member, value); else ret = navi12_get_legacy_smu_metrics_data(smu, member, value); @@ -926,8 +919,12 @@ static int navi1x_get_smu_metrics_data(struct smu_context *smu, case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): default: - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && smu_version > 0x00351F00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && smu_version > 0x002A3B00)) + if (((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 5)) && + smu->smc_fw_version > 0x00351F00) || + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 0)) && + smu->smc_fw_version > 0x002A3B00)) ret = navi10_get_smu_metrics_data(smu, member, value); else ret = navi10_get_legacy_smu_metrics_data(smu, member, value); @@ -1686,7 +1683,7 @@ static int navi10_force_clk_levels(struct smu_context *smu, return 0; break; case SMU_DCEFCLK: - dev_info(smu->adev->dev,"Setting DCEFCLK min/max dpm level is not supported!\n"); + dev_info(smu->adev->dev, "Setting DCEFCLK min/max dpm level is not supported!\n"); break; default: @@ -1712,7 +1709,7 @@ static int navi10_populate_umd_state_clk(struct smu_context *smu) uint32_t sclk_freq; pstate_table->gfxclk_pstate.min = gfx_table->min; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 0): switch (adev->pdev->revision) { case 0xf0: /* XTX */ @@ -2182,7 +2179,7 @@ static int navi10_read_sensor(struct smu_context *smu, struct smu_table_context *table_context = &smu->smu_table; PPTable_t *pptable = table_context->driver_pptable; - if(!data || !size) + if (!data || !size) return -EINVAL; switch (sensor) { @@ -2202,7 +2199,7 @@ static int navi10_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = navi1x_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -2240,6 +2237,7 @@ static int navi10_read_sensor(struct smu_context *smu, ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -2317,30 +2315,31 @@ static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal; uint32_t max_memory_clock = max_sustainable_clocks->uclock; - if(smu->disable_uclk_switch == disable_memory_clock_switch) + if (smu->disable_uclk_switch == disable_memory_clock_switch) return 0; - if(disable_memory_clock_switch) + if (disable_memory_clock_switch) ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0); else ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0); - if(!ret) + if (!ret) smu->disable_uclk_switch = disable_memory_clock_switch; return ret; } static int navi10_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_11_0_powerplay_table *powerplay_table = (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; struct smu_11_0_overdrive_table *od_settings = smu->od_settings; PPTable_t *pptable = smu->smu_table.driver_pptable; - uint32_t power_limit, od_percent; + uint32_t power_limit, od_percent_upper, od_percent_lower; if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { /* the last hope to figure out the ppt limit */ @@ -2357,26 +2356,34 @@ static int navi10_get_power_limit(struct smu_context *smu, if (default_power_limit) *default_power_limit = power_limit; - if (max_power_limit) { - if (smu->od_enabled && + if (smu->od_enabled && navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) { - od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]); + } else { + od_percent_upper = 0; + od_percent_lower = 100; + } - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", + od_percent_upper, od_percent_lower, power_limit); - power_limit *= (100 + od_percent); - power_limit /= 100; - } + if (max_power_limit) { + *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit /= 100; + } - *max_power_limit = power_limit; + if (min_power_limit) { + *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit /= 100; } return 0; } static int navi10_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) + uint8_t pcie_gen_cap, + uint8_t pcie_width_cap) { struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; PPTable_t *pptable = smu->smu_table.driver_pptable; @@ -2559,7 +2566,8 @@ static int navi10_set_default_od_settings(struct smu_context *smu) return 0; } -static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) { +static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) +{ int i; int ret = 0; struct smu_table_context *table_context = &smu->smu_table; @@ -2752,8 +2760,8 @@ static bool navi10_need_umc_cdr_workaround(struct smu_context *smu) if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) return false; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0) || + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 5)) return true; return false; @@ -2841,19 +2849,12 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) struct amdgpu_device *adev = smu->adev; uint8_t umc_fw_greater_than_v136 = false; uint8_t umc_fw_disable_cdr = false; - uint32_t pmfw_version; uint32_t param; int ret = 0; if (!navi10_need_umc_cdr_workaround(smu)) return 0; - ret = smu_cmn_get_smc_version(smu, NULL, &pmfw_version); - if (ret) { - dev_err(adev->dev, "Failed to get smu version!\n"); - return ret; - } - /* * The messages below are only supported by Navi10 42.53.0 and later * PMFWs and Navi14 53.29.0 and later PMFWs. @@ -2861,8 +2862,10 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) * - PPSMC_MSG_SetDriverDummyTableDramAddrLow * - PPSMC_MSG_GetUMCFWWA */ - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && (pmfw_version >= 0x2a3500)) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && (pmfw_version >= 0x351D00))) { + if (((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 0)) && + (smu->smc_fw_version >= 0x2a3500)) || + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 5)) && + (smu->smc_fw_version >= 0x351D00))) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GET_UMC_FW_WA, 0, @@ -2881,13 +2884,15 @@ static int navi10_run_umc_cdr_workaround(struct smu_context *smu) return 0; if (umc_fw_disable_cdr) { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 0)) return navi10_umc_hybrid_cdr_workaround(smu); } else { return navi10_set_dummy_pstates_table_location(smu); } } else { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 0)) return navi10_umc_hybrid_cdr_workaround(smu); } @@ -3345,18 +3350,11 @@ static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, void **table) { struct amdgpu_device *adev = smu->adev; - uint32_t smu_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(adev->dev, "Failed to get smu version!\n"); - return ret; - } - - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 9): - if (smu_version > 0x00341C00) + if (smu->smc_fw_version > 0x00341C00) ret = navi12_get_gpu_metrics(smu, table); else ret = navi12_get_legacy_gpu_metrics(smu, table); @@ -3364,11 +3362,15 @@ static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): default: - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 5)) && smu_version > 0x00351F00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 0)) && smu_version > 0x002A3B00)) + if (((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 5)) && + smu->smc_fw_version > 0x00351F00) || + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 0)) && + smu->smc_fw_version > 0x002A3B00)) ret = navi10_get_gpu_metrics(smu, table); else - ret =navi10_get_legacy_gpu_metrics(smu, table); + ret = navi10_get_legacy_gpu_metrics(smu, table); break; } @@ -3383,7 +3385,7 @@ static int navi10_enable_mgpu_fan_boost(struct smu_context *smu) uint32_t param = 0; /* Navi12 does not support this */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 9)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 9)) return 0; /* diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index f0800c0c5168..1de9f8b5cc5f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -73,12 +73,16 @@ #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15 -#define GET_PPTABLE_MEMBER(field, member) do {\ - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13))\ - (*member) = (smu->smu_table.driver_pptable + offsetof(PPTable_beige_goby_t, field));\ - else\ - (*member) = (smu->smu_table.driver_pptable + offsetof(PPTable_t, field));\ -} while(0) +#define GET_PPTABLE_MEMBER(field, member) \ + do { \ + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == \ + IP_VERSION(11, 0, 13)) \ + (*member) = (smu->smu_table.driver_pptable + \ + offsetof(PPTable_beige_goby_t, field)); \ + else \ + (*member) = (smu->smu_table.driver_pptable + \ + offsetof(PPTable_t, field)); \ + } while (0) /* STB FIFO depth is in 64bit units */ #define SIENNA_CICHLID_STB_DEPTH_UNIT_BYTES 8 @@ -91,7 +95,7 @@ static int get_table_size(struct smu_context *smu) { - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 13)) return sizeof(PPTable_beige_goby_t); else return sizeof(PPTable_t); @@ -309,7 +313,7 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu, } if ((adev->pm.pp_feature & PP_GFX_DCS_MASK) && - (adev->ip_versions[MP1_HWIP][0] > IP_VERSION(11, 0, 7)) && + (amdgpu_ip_version(adev, MP1_HWIP, 0) > IP_VERSION(11, 0, 7)) && !(adev->flags & AMD_IS_APU)) *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_DCS_BIT); @@ -434,7 +438,7 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu) PPTable_beige_goby_t *ppt_beige_goby; PPTable_t *ppt; - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 13)) ppt_beige_goby = smu->smu_table.driver_pptable; else ppt = smu->smu_table.driver_pptable; @@ -447,7 +451,7 @@ static int sienna_cichlid_append_powerplay_table(struct smu_context *smu) if (ret) return ret; - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 13)) smu_memcpy_trailing(ppt_beige_goby, I2cControllers, BoardReserved, smc_dpm_table, I2cControllers); else @@ -616,11 +620,12 @@ static uint32_t sienna_cichlid_get_throttler_status_locked(struct smu_context *s static int sienna_cichlid_get_power_limit(struct smu_context *smu, uint32_t *current_power_limit, uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_11_0_7_powerplay_table *powerplay_table = (struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table; - uint32_t power_limit, od_percent; + uint32_t power_limit, od_percent_upper, od_percent_lower; uint16_t *table_member; GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member); @@ -635,21 +640,26 @@ static int sienna_cichlid_get_power_limit(struct smu_context *smu, if (default_power_limit) *default_power_limit = power_limit; - if (max_power_limit) { - if (smu->od_enabled) { - od_percent = - le32_to_cpu(powerplay_table->overdrive_table.max[ - SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + if (smu->od_enabled) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]); + } else { + od_percent_upper = 0; + od_percent_lower = 100; + } - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", - od_percent, power_limit); + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", + od_percent_upper, od_percent_lower, power_limit); - power_limit *= (100 + od_percent); - power_limit /= 100; - } - *max_power_limit = power_limit; + if (max_power_limit) { + *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit /= 100; } + if (min_power_limit) { + *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit /= 100; + } return 0; } @@ -668,7 +678,7 @@ static void sienna_cichlid_get_smartshift_power_percentage(struct smu_context *s uint32_t cur_power_limit; if (metrics_v4->ApuSTAPMSmartShiftLimit != 0) { - sienna_cichlid_get_power_limit(smu, &cur_power_limit, NULL, NULL); + sienna_cichlid_get_power_limit(smu, &cur_power_limit, NULL, NULL, NULL); apu_power_limit = metrics_v4->ApuSTAPMLimit; dgpu_power_limit = cur_power_limit; powerRatio = (((apu_power_limit + @@ -725,7 +735,7 @@ static int sienna_cichlid_get_smu_metrics_data(struct smu_context *smu, uint32_t apu_percent = 0; uint32_t dgpu_percent = 0; - switch (smu->adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(smu->adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): if (smu->smc_fw_version >= 0x3A4900) use_metrics_v3 = true; @@ -1275,7 +1285,6 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu, uint32_t mark_index = 0; uint32_t gen_speed, lane_width; uint32_t min_value, max_value; - uint32_t smu_version; smu_cmn_get_sysfs_buf(&buf, &size); @@ -1384,9 +1393,9 @@ static int sienna_cichlid_print_clk_levels(struct smu_context *smu, * OD GFX Voltage Offset functionality is supported only by 58.41.0 * and onwards SMU firmwares. */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu_version < 0x003a2900)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 7)) && + (smu->smc_fw_version < 0x003a2900)) break; size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n"); @@ -1494,7 +1503,7 @@ static int sienna_cichlid_populate_umd_state_clk(struct smu_context *smu) pstate_table->socclk_pstate.min = soc_table->min; pstate_table->socclk_pstate.peak = soc_table->max; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 11): pstate_table->gfxclk_pstate.standard = SIENNA_CICHLID_UMD_PSTATE_PROFILING_GFXCLK; @@ -1902,7 +1911,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = sienna_cichlid_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -1945,7 +1954,8 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, *size = 4; break; case AMDGPU_PP_SENSOR_SS_APU_SHARE: - if (adev->ip_versions[MP1_HWIP][0] != IP_VERSION(11, 0, 7)) { + if (amdgpu_ip_version(adev, MP1_HWIP, 0) != + IP_VERSION(11, 0, 7)) { ret = sienna_cichlid_get_smu_metrics_data(smu, METRICS_SS_APU_SHARE, (uint32_t *)data); *size = 4; @@ -1954,7 +1964,8 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, } break; case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: - if (adev->ip_versions[MP1_HWIP][0] != IP_VERSION(11, 0, 7)) { + if (amdgpu_ip_version(adev, MP1_HWIP, 0) != + IP_VERSION(11, 0, 7)) { ret = sienna_cichlid_get_smu_metrics_data(smu, METRICS_SS_DGPU_SHARE, (uint32_t *)data); *size = 4; @@ -1962,6 +1973,7 @@ static int sienna_cichlid_read_sensor(struct smu_context *smu, ret = -EOPNOTSUPP; } break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1977,7 +1989,7 @@ static void sienna_cichlid_get_unique_id(struct smu_context *smu) /* Only supported as of version 0.58.83.0 and only on Sienna Cichlid */ if (smu->smc_fw_version < 0x3A5300 || - smu->adev->ip_versions[MP1_HWIP][0] != IP_VERSION(11, 0, 7)) + amdgpu_ip_version(smu->adev, MP1_HWIP, 0) != IP_VERSION(11, 0, 7)) return; if (sienna_cichlid_get_smu_metrics_data(smu, METRICS_UNIQUE_ID_UPPER32, &upper32)) @@ -1988,8 +2000,6 @@ static void sienna_cichlid_get_unique_id(struct smu_context *smu) out: adev->unique_id = ((uint64_t)upper32 << 32) | lower32; - if (adev->serial[0] == '\0') - sprintf(adev->serial, "%016llx", adev->unique_id); } static int sienna_cichlid_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states) @@ -2082,35 +2092,38 @@ static int sienna_cichlid_display_disable_memory_clock_switch(struct smu_context } static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) + uint8_t pcie_gen_cap, + uint8_t pcie_width_cap) { struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; - u32 smu_pcie_arg; + uint8_t *table_member1, *table_member2; + uint8_t min_gen_speed, max_gen_speed; + uint8_t min_lane_width, max_lane_width; + uint32_t smu_pcie_arg; int ret, i; - /* PCIE gen speed and lane width override */ - if (!amdgpu_device_pcie_dynamic_switching_supported()) { - if (pcie_table->pcie_gen[NUM_LINK_LEVELS - 1] < pcie_gen_cap) - pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS - 1]; - - if (pcie_table->pcie_lane[NUM_LINK_LEVELS - 1] < pcie_width_cap) - pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS - 1]; - - /* Force all levels to use the same settings */ - for (i = 0; i < NUM_LINK_LEVELS; i++) { - pcie_table->pcie_gen[i] = pcie_gen_cap; - pcie_table->pcie_lane[i] = pcie_width_cap; - } + GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1); + GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2); + + min_gen_speed = max_t(uint8_t, 0, table_member1[0]); + max_gen_speed = min(pcie_gen_cap, table_member1[1]); + min_gen_speed = min_gen_speed > max_gen_speed ? + max_gen_speed : min_gen_speed; + min_lane_width = max_t(uint8_t, 1, table_member2[0]); + max_lane_width = min(pcie_width_cap, table_member2[1]); + min_lane_width = min_lane_width > max_lane_width ? + max_lane_width : min_lane_width; + + if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { + pcie_table->pcie_gen[0] = max_gen_speed; + pcie_table->pcie_lane[0] = max_lane_width; } else { - for (i = 0; i < NUM_LINK_LEVELS; i++) { - if (pcie_table->pcie_gen[i] > pcie_gen_cap) - pcie_table->pcie_gen[i] = pcie_gen_cap; - if (pcie_table->pcie_lane[i] > pcie_width_cap) - pcie_table->pcie_lane[i] = pcie_width_cap; - } + pcie_table->pcie_gen[0] = min_gen_speed; + pcie_table->pcie_lane[0] = min_lane_width; } + pcie_table->pcie_gen[1] = max_gen_speed; + pcie_table->pcie_lane[1] = max_lane_width; for (i = 0; i < NUM_LINK_LEVELS; i++) { smu_pcie_arg = (i << 16 | @@ -2139,16 +2152,14 @@ static void sienna_cichlid_dump_od_table(struct smu_context *smu, OverDriveTable_t *od_table) { struct amdgpu_device *adev = smu->adev; - uint32_t smu_version; dev_dbg(smu->adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax); dev_dbg(smu->adev->dev, "OD: Uclk: (%d, %d)\n", od_table->UclkFmin, od_table->UclkFmax); - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (!((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu_version < 0x003a2900))) + if (!((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 7)) && + (smu->smc_fw_version < 0x003a2900))) dev_dbg(smu->adev->dev, "OD: VddGfxOffset: %d\n", od_table->VddGfxOffset); } @@ -2226,7 +2237,6 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu, enum SMU_11_0_7_ODSETTING_ID freq_setting; uint16_t *freq_ptr; int i, ret = 0; - uint32_t smu_version; if (!smu->od_enabled) { dev_warn(smu->adev->dev, "OverDrive is not enabled!\n"); @@ -2379,9 +2389,9 @@ static int sienna_cichlid_od_edit_dpm_table(struct smu_context *smu, * OD GFX Voltage Offset functionality is supported only by 58.41.0 * and onwards SMU firmwares. */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && - (smu_version < 0x003a2900)) { + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 7)) && + (smu->smc_fw_version < 0x003a2900)) { dev_err(smu->adev->dev, "OD GFX Voltage offset functionality is supported " "only by 58.41.0 and onwards SMU firmwares!\n"); return -EOPNOTSUPP; @@ -2451,13 +2461,17 @@ static bool sienna_cichlid_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; uint32_t val; - u32 smu_version; + uint32_t smu_version; + int ret; /** * SRIOV env will not support SMU mode1 reset * PM FW support mode1 reset from 58.26 */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); + ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); + if (ret) + return false; + if (amdgpu_sriov_vf(adev) || (smu_version < 0x003a1a00)) return false; @@ -3104,7 +3118,8 @@ static void sienna_cichlid_dump_pptable(struct smu_context *smu) PPTable_t *pptable = table_context->driver_pptable; int i; - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) { + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 13)) { beige_goby_dump_pptable(smu); return; } @@ -3909,7 +3924,7 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, uint16_t average_gfx_activity; int ret = 0; - switch (smu->adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(smu->adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): if (smu->smc_fw_version >= 0x3A4900) use_metrics_v3 = true; @@ -4025,8 +4040,10 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = use_metrics_v3 ? metrics_v3->CurrFanSpeed : use_metrics_v2 ? metrics_v2->CurrFanSpeed : metrics->CurrFanSpeed; - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)) && smu->smc_fw_version > 0x003A1E00) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 11)) && smu->smc_fw_version > 0x00410400)) { + if (((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 7)) && + smu->smc_fw_version > 0x003A1E00) || + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 11)) && + smu->smc_fw_version > 0x00410400)) { gpu_metrics->pcie_link_width = use_metrics_v3 ? metrics_v3->PcieWidth : use_metrics_v2 ? metrics_v2->PcieWidth : metrics->PcieWidth; gpu_metrics->pcie_link_speed = link_speed[use_metrics_v3 ? metrics_v3->PcieRate : @@ -4047,14 +4064,9 @@ static ssize_t sienna_cichlid_get_gpu_metrics(struct smu_context *smu, static int sienna_cichlid_check_ecc_table_support(struct smu_context *smu) { - uint32_t if_version = 0xff, smu_version = 0xff; int ret = 0; - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) - return -EOPNOTSUPP; - - if (smu_version < SUPPORT_ECCTABLE_SMU_VERSION) + if (smu->smc_fw_version < SUPPORT_ECCTABLE_SMU_VERSION) ret = -EOPNOTSUPP; return ret; @@ -4120,17 +4132,13 @@ static int sienna_cichlid_enable_mgpu_fan_boost(struct smu_context *smu) static int sienna_cichlid_gpo_control(struct smu_context *smu, bool enablement) { - uint32_t smu_version; int ret = 0; if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFX_GPO_BIT)) { - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) - return ret; if (enablement) { - if (smu_version < 0x003a2500) { + if (smu->smc_fw_version < 0x003a2500) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetGpoFeaturePMask, GFX_GPO_PACE_MASK | GFX_GPO_DEM_MASK, @@ -4142,7 +4150,7 @@ static int sienna_cichlid_gpo_control(struct smu_context *smu, NULL); } } else { - if (smu_version < 0x003a2500) { + if (smu->smc_fw_version < 0x003a2500) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetGpoFeaturePMask, 0, @@ -4161,18 +4169,11 @@ static int sienna_cichlid_gpo_control(struct smu_context *smu, static int sienna_cichlid_notify_2nd_usb20_port(struct smu_context *smu) { - uint32_t smu_version; - int ret = 0; - - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) - return ret; - /* * Message SMU_MSG_Enable2ndUSB20Port is supported by 58.45 * onwards PMFWs. */ - if (smu_version < 0x003A2D00) + if (smu->smc_fw_version < 0x003A2D00) return 0; return smu_cmn_send_smc_msg_with_param(smu, @@ -4252,7 +4253,7 @@ static int sienna_cichlid_get_default_config_table_settings(struct smu_context * table->gfx_activity_average_tau = 10; table->mem_activity_average_tau = 10; table->socket_power_average_tau = 100; - if (adev->ip_versions[MP1_HWIP][0] != IP_VERSION(11, 0, 7)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) != IP_VERSION(11, 0, 7)) table->apu_socket_power_average_tau = 100; return 0; @@ -4319,13 +4320,10 @@ static bool sienna_cichlid_is_mode2_reset_supported(struct smu_context *smu) static int sienna_cichlid_mode2_reset(struct smu_context *smu) { - u32 smu_version; int ret = 0, index; struct amdgpu_device *adev = smu->adev; int timeout = 100; - smu_cmn_get_smc_version(smu, NULL, &smu_version); - index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_DriverMode2Reset); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index aa4a5498a12f..5a314d0316c1 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -101,8 +101,8 @@ int smu_v11_0_init_microcode(struct smu_context *smu) struct amdgpu_firmware_info *ucode = NULL; if (amdgpu_sriov_vf(adev) && - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 9)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 7)))) + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 9)) || + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 7)))) return 0; amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); @@ -213,7 +213,7 @@ int smu_v11_0_check_fw_version(struct smu_context *smu) if (smu->is_apu) adev->pm.fw_version = smu_version; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 0): smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_NV10; break; @@ -246,7 +246,7 @@ int smu_v11_0_check_fw_version(struct smu_context *smu) break; default: dev_err(smu->adev->dev, "smu unsupported IP version: 0x%x.\n", - adev->ip_versions[MP1_HWIP][0]); + amdgpu_ip_version(adev, MP1_HWIP, 0)); smu->smc_driver_if_version = SMU11_DRIVER_IF_VERSION_INV; break; } @@ -474,9 +474,10 @@ int smu_v11_0_init_power(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; struct smu_power_context *smu_power = &smu->smu_power; - size_t size = adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 5, 0) ? - sizeof(struct smu_11_5_power_context) : - sizeof(struct smu_11_0_power_context); + size_t size = amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 5, 0) ? + sizeof(struct smu_11_5_power_context) : + sizeof(struct smu_11_0_power_context); smu_power->power_context = kzalloc(size, GFP_KERNEL); if (!smu_power->power_context) @@ -731,10 +732,10 @@ int smu_v11_0_init_display_count(struct smu_context *smu, uint32_t count) /* Navy_Flounder/Dimgrey_Cavefish do not support to change * display num currently */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 11) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 5, 0) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 12) || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 13)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 11) || + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 5, 0) || + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 12) || + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 13)) return 0; return smu_cmn_send_smc_msg_with_param(smu, @@ -1103,7 +1104,7 @@ int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable) int ret = 0; struct amdgpu_device *adev = smu->adev; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 0): case IP_VERSION(11, 0, 5): case IP_VERSION(11, 0, 9): @@ -1173,7 +1174,7 @@ smu_v11_0_set_fan_speed_pwm(struct smu_context *smu, uint32_t speed) uint32_t duty100, duty; uint64_t tmp64; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), CG_FDO_CTRL1, FMAX_DUTY100); @@ -1248,7 +1249,7 @@ int smu_v11_0_get_fan_speed_pwm(struct smu_context *smu, tmp64 = (uint64_t)duty * 255; do_div(tmp64, duty100); - *speed = MIN((uint32_t)tmp64, 255); + *speed = min_t(uint32_t, tmp64, 255); return 0; } @@ -1591,7 +1592,7 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) return 0; if (state == SMU_BACO_STATE_ENTER) { - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(11, 0, 7): case IP_VERSION(11, 0, 11): case IP_VERSION(11, 0, 12): @@ -1610,7 +1611,8 @@ int smu_v11_0_baco_set_state(struct smu_context *smu, enum smu_baco_state state) default: if (!ras || !adev->ras_enabled || adev->gmc.xgmi.pending_reset) { - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 2)) { + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(11, 0, 2)) { data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL_ARCT); data |= 0x80000000; WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL_ARCT, data); @@ -1894,7 +1896,7 @@ int smu_v11_0_set_performance_level(struct smu_context *smu, * Separate MCLK and SOCCLK soft min/max settings are not allowed * on Arcturus. */ - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(11, 0, 2)) { + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(11, 0, 2)) { mclk_min = mclk_max = 0; socclk_min = socclk_max = 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 067b4e0b026c..2ff6deedef95 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -225,14 +225,6 @@ static int vangogh_tables_init(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; struct smu_table *tables = smu_table->tables; - uint32_t if_version; - uint32_t smu_version; - uint32_t ret = 0; - - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { - return ret; - } SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); @@ -242,24 +234,15 @@ static int vangogh_tables_init(struct smu_context *smu) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffExt_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); + SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, max(sizeof(SmuMetrics_t), sizeof(SmuMetrics_legacy_t)), + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - if (if_version < 0x3) { - SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_legacy_t), - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_legacy_t), GFP_KERNEL); - } else { - SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); - } + smu_table->metrics_table = kzalloc(max(sizeof(SmuMetrics_t), sizeof(SmuMetrics_legacy_t)), GFP_KERNEL); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; - if (smu_version >= 0x043F3E00) - smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_3); - else - smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2); + smu_table->gpu_metrics_table_size = max(sizeof(struct gpu_metrics_v2_3), sizeof(struct gpu_metrics_v2_2)); smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); if (!smu_table->gpu_metrics_table) goto err1_out; @@ -390,6 +373,10 @@ static int vangogh_get_smu_metrics_data(struct smu_context *smu, *value = metrics->Current.UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->Average.CurrentSocketPower << 8) / + 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->Current.CurrentSocketPower << 8) / 1000; break; @@ -426,17 +413,9 @@ static int vangogh_common_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct amdgpu_device *adev = smu->adev; - uint32_t if_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, &if_version, NULL); - if (ret) { - dev_err(adev->dev, "Failed to get smu if version!\n"); - return ret; - } - - if (if_version < 0x3) + if (smu->smc_fw_if_version < 0x3) ret = vangogh_get_legacy_smu_metrics_data(smu, member, value); else ret = vangogh_get_smu_metrics_data(smu, member, value); @@ -809,17 +788,9 @@ static int vangogh_print_clk_levels(struct smu_context *smu, static int vangogh_common_print_clk_levels(struct smu_context *smu, enum smu_clk_type clk_type, char *buf) { - struct amdgpu_device *adev = smu->adev; - uint32_t if_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, &if_version, NULL); - if (ret) { - dev_err(adev->dev, "Failed to get smu if version!\n"); - return ret; - } - - if (if_version < 0x3) + if (smu->smc_fw_if_version < 0x3) ret = vangogh_print_legacy_clk_levels(smu, clk_type, buf); else ret = vangogh_print_clk_levels(smu, clk_type, buf); @@ -1536,12 +1507,18 @@ static int vangogh_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = vangogh_common_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = vangogh_common_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, @@ -1854,6 +1831,86 @@ static ssize_t vangogh_get_gpu_metrics_v2_3(struct smu_context *smu, return sizeof(struct gpu_metrics_v2_3); } +static ssize_t vangogh_get_gpu_metrics_v2_4(struct smu_context *smu, + void **table) +{ + SmuMetrics_t metrics; + struct smu_table_context *smu_table = &smu->smu_table; + struct gpu_metrics_v2_4 *gpu_metrics = + (struct gpu_metrics_v2_4 *)smu_table->gpu_metrics_table; + int ret = 0; + + ret = smu_cmn_get_metrics_table(smu, &metrics, true); + if (ret) + return ret; + + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 4); + + gpu_metrics->temperature_gfx = metrics.Current.GfxTemperature; + gpu_metrics->temperature_soc = metrics.Current.SocTemperature; + memcpy(&gpu_metrics->temperature_core[0], + &metrics.Current.CoreTemperature[0], + sizeof(uint16_t) * 4); + gpu_metrics->temperature_l3[0] = metrics.Current.L3Temperature[0]; + + gpu_metrics->average_temperature_gfx = metrics.Average.GfxTemperature; + gpu_metrics->average_temperature_soc = metrics.Average.SocTemperature; + memcpy(&gpu_metrics->average_temperature_core[0], + &metrics.Average.CoreTemperature[0], + sizeof(uint16_t) * 4); + gpu_metrics->average_temperature_l3[0] = metrics.Average.L3Temperature[0]; + + gpu_metrics->average_gfx_activity = metrics.Average.GfxActivity; + gpu_metrics->average_mm_activity = metrics.Average.UvdActivity; + + gpu_metrics->average_socket_power = metrics.Average.CurrentSocketPower; + gpu_metrics->average_cpu_power = metrics.Average.Power[0]; + gpu_metrics->average_soc_power = metrics.Average.Power[1]; + gpu_metrics->average_gfx_power = metrics.Average.Power[2]; + + gpu_metrics->average_cpu_voltage = metrics.Average.Voltage[0]; + gpu_metrics->average_soc_voltage = metrics.Average.Voltage[1]; + gpu_metrics->average_gfx_voltage = metrics.Average.Voltage[2]; + + gpu_metrics->average_cpu_current = metrics.Average.Current[0]; + gpu_metrics->average_soc_current = metrics.Average.Current[1]; + gpu_metrics->average_gfx_current = metrics.Average.Current[2]; + + memcpy(&gpu_metrics->average_core_power[0], + &metrics.Average.CorePower[0], + sizeof(uint16_t) * 4); + + gpu_metrics->average_gfxclk_frequency = metrics.Average.GfxclkFrequency; + gpu_metrics->average_socclk_frequency = metrics.Average.SocclkFrequency; + gpu_metrics->average_uclk_frequency = metrics.Average.MemclkFrequency; + gpu_metrics->average_fclk_frequency = metrics.Average.MemclkFrequency; + gpu_metrics->average_vclk_frequency = metrics.Average.VclkFrequency; + gpu_metrics->average_dclk_frequency = metrics.Average.DclkFrequency; + + gpu_metrics->current_gfxclk = metrics.Current.GfxclkFrequency; + gpu_metrics->current_socclk = metrics.Current.SocclkFrequency; + gpu_metrics->current_uclk = metrics.Current.MemclkFrequency; + gpu_metrics->current_fclk = metrics.Current.MemclkFrequency; + gpu_metrics->current_vclk = metrics.Current.VclkFrequency; + gpu_metrics->current_dclk = metrics.Current.DclkFrequency; + + memcpy(&gpu_metrics->current_coreclk[0], + &metrics.Current.CoreFrequency[0], + sizeof(uint16_t) * 4); + gpu_metrics->current_l3clk[0] = metrics.Current.L3Frequency[0]; + + gpu_metrics->throttle_status = metrics.Current.ThrottlerStatus; + gpu_metrics->indep_throttle_status = + smu_cmn_get_indep_throttler_status(metrics.Current.ThrottlerStatus, + vangogh_throttler_map); + + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + + *table = (void *)gpu_metrics; + + return sizeof(struct gpu_metrics_v2_4); +} + static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, void **table) { @@ -1921,25 +1978,30 @@ static ssize_t vangogh_get_gpu_metrics(struct smu_context *smu, static ssize_t vangogh_common_get_gpu_metrics(struct smu_context *smu, void **table) { - uint32_t if_version; - uint32_t smu_version; + uint32_t smu_program; + uint32_t fw_version; int ret = 0; - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { - return ret; - } - - if (smu_version >= 0x043F3E00) { - if (if_version < 0x3) - ret = vangogh_get_legacy_gpu_metrics_v2_3(smu, table); + smu_program = (smu->smc_fw_version >> 24) & 0xff; + fw_version = smu->smc_fw_version & 0xffffff; + if (smu_program == 6) { + if (fw_version >= 0x3F0800) + ret = vangogh_get_gpu_metrics_v2_4(smu, table); else ret = vangogh_get_gpu_metrics_v2_3(smu, table); + } else { - if (if_version < 0x3) - ret = vangogh_get_legacy_gpu_metrics(smu, table); - else - ret = vangogh_get_gpu_metrics(smu, table); + if (smu->smc_fw_version >= 0x043F3E00) { + if (smu->smc_fw_if_version < 0x3) + ret = vangogh_get_legacy_gpu_metrics_v2_3(smu, table); + else + ret = vangogh_get_gpu_metrics_v2_3(smu, table); + } else { + if (smu->smc_fw_if_version < 0x3) + ret = vangogh_get_legacy_gpu_metrics(smu, table); + else + ret = vangogh_get_gpu_metrics(smu, table); + } } return ret; @@ -2131,8 +2193,7 @@ static int vangogh_get_dpm_clock_table(struct smu_context *smu, struct dpm_clock return 0; } - -static int vangogh_system_features_control(struct smu_context *smu, bool en) +static int vangogh_notify_rlc_state(struct smu_context *smu, bool en) { struct amdgpu_device *adev = smu->adev; int ret = 0; @@ -2243,7 +2304,8 @@ static u32 vangogh_get_gfxoff_status(struct smu_context *smu) static int vangogh_get_power_limit(struct smu_context *smu, uint32_t *current_power_limit, uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_11_5_power_context *power_context = smu->smu_power.power_context; @@ -2265,6 +2327,8 @@ static int vangogh_get_power_limit(struct smu_context *smu, *default_power_limit = ppt_limit / 1000; if (max_power_limit) *max_power_limit = 29; + if (min_power_limit) + *min_power_limit = 0; ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPPTLimit, &ppt_limit); if (ret) { @@ -2458,7 +2522,7 @@ static const struct pptable_funcs vangogh_ppt_funcs = { .print_clk_levels = vangogh_common_print_clk_levels, .set_default_dpm_table = vangogh_set_default_dpm_tables, .set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters, - .system_features_control = vangogh_system_features_control, + .notify_rlc_state = vangogh_notify_rlc_state, .feature_is_enabled = smu_cmn_feature_is_enabled, .set_power_profile_mode = vangogh_set_power_profile_mode, .get_power_profile_mode = vangogh_get_power_profile_mode, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 8a8ba25c9ad7..8908bbb3ff1f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -262,15 +262,15 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu, /* mclk levels are in reverse order */ *mclk_mask = NUM_MEMCLK_DPM_LEVELS - 1; } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) { - if(sclk_mask) + if (sclk_mask) /* The sclk as gfxclk and has three level about max/min/current */ *sclk_mask = 3 - 1; - if(mclk_mask) + if (mclk_mask) /* mclk levels are in reverse order */ *mclk_mask = 0; - if(soc_mask) + if (soc_mask) *soc_mask = NUM_SOCCLK_DPM_LEVELS - 1; } @@ -1197,9 +1197,13 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->AverageUvdActivity / 100; break; - case METRICS_AVERAGE_SOCKETPOWER: - if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) && (adev->pm.fw_version >= 0x40000f)) || - ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0)) && (adev->pm.fw_version >= 0x373200))) + case METRICS_CURR_SOCKETPOWER: + if (((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(12, 0, 1)) && + (adev->pm.fw_version >= 0x40000f)) || + ((amdgpu_ip_version(adev, MP1_HWIP, 0) == + IP_VERSION(12, 0, 0)) && + (adev->pm.fw_version >= 0x373200))) *value = metrics->CurrentSocketPower << 8; else *value = (metrics->CurrentSocketPower << 8) / 1000; @@ -1297,9 +1301,9 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = renoir_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -1315,6 +1319,7 @@ static int renoir_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c index c788aa7a99a9..5e408a195860 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c @@ -205,7 +205,8 @@ int smu_v12_0_set_default_dpm_tables(struct smu_context *smu) return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); } -int smu_v12_0_mode2_reset(struct smu_context *smu){ +int smu_v12_0_mode2_reset(struct smu_context *smu) +{ return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, SMU_RESET_MODE_2, NULL); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index ce50ef46e73f..f1440869d1ce 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -94,8 +94,7 @@ */ #define SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION 0x00443300 -static const struct smu_temperature_range smu13_thermal_policy[] = -{ +static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; @@ -196,7 +195,7 @@ static const struct cmn2asic_mapping aldebaran_feature_mask_map[SMU_FEATURE_COUN ALDEBARAN_FEA_MAP(SMU_FEATURE_FW_CTF_BIT, FEATURE_FW_CTF_BIT), ALDEBARAN_FEA_MAP(SMU_FEATURE_THERMAL_BIT, FEATURE_THERMAL_BIT), ALDEBARAN_FEA_MAP(SMU_FEATURE_OUT_OF_BAND_MONITOR_BIT, FEATURE_OUT_OF_BAND_MONITOR_BIT), - ALDEBARAN_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT,FEATURE_XGMI_PER_LINK_PWR_DWN), + ALDEBARAN_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT, FEATURE_XGMI_PER_LINK_PWR_DWN), ALDEBARAN_FEA_MAP(SMU_FEATURE_DF_CSTATE_BIT, FEATURE_DF_CSTATE), }; @@ -258,8 +257,11 @@ static int aldebaran_tables_init(struct smu_context *smu) } smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL); - if (!smu_table->ecc_table) + if (!smu_table->ecc_table) { + kfree(smu_table->metrics_table); + kfree(smu_table->gpu_metrics_table); return -ENOMEM; + } return 0; } @@ -468,18 +470,12 @@ static bool aldebaran_is_primary(struct smu_context *smu) static int aldebaran_run_board_btc(struct smu_context *smu) { - u32 smu_version; int ret; if (!aldebaran_is_primary(smu)) return 0; - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) { - dev_err(smu->adev->dev, "Failed to get smu version!\n"); - return ret; - } - if (smu_version <= 0x00441d00) + if (smu->smc_fw_version <= 0x00441d00) return 0; ret = smu_cmn_send_smc_msg(smu, SMU_MSG_BoardPowerCalibration, NULL); @@ -551,9 +547,9 @@ static int aldebaran_populate_umd_state_clk(struct smu_context *smu) return 0; } -static int aldebaran_get_clk_table(struct smu_context *smu, - struct pp_clock_levels_with_latency *clocks, - struct smu_13_0_dpm_table *dpm_table) +static void aldebaran_get_clk_table(struct smu_context *smu, + struct pp_clock_levels_with_latency *clocks, + struct smu_13_0_dpm_table *dpm_table) { uint32_t i; @@ -567,7 +563,6 @@ static int aldebaran_get_clk_table(struct smu_context *smu, clocks->data[i].latency_in_us = 0; } - return 0; } static int aldebaran_freqs_in_same_level(int32_t frequency1, @@ -580,7 +575,7 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; @@ -626,9 +621,10 @@ static int aldebaran_get_smu_metrics_data(struct smu_context *smu, break; case METRICS_AVERAGE_SOCKETPOWER: /* Valid power data is available only from primary die */ - *value = aldebaran_is_primary(smu) ? - metrics->AverageSocketPower << 8 : - 0; + if (aldebaran_is_primary(smu)) + *value = metrics->AverageSocketPower << 8; + else + ret = -EOPNOTSUPP; break; case METRICS_TEMPERATURE_EDGE: *value = metrics->TemperatureEdge * @@ -736,25 +732,26 @@ static int aldebaran_get_current_clk_freq_by_table(struct smu_context *smu, value); } -static int aldebaran_print_clk_levels(struct smu_context *smu, - enum smu_clk_type type, char *buf) +static int aldebaran_emit_clk_levels(struct smu_context *smu, + enum smu_clk_type type, char *buf, int *offset) { - int i, now, size = 0; int ret = 0; struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; struct pp_clock_levels_with_latency clocks; struct smu_13_0_dpm_table *single_dpm_table; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_13_0_dpm_context *dpm_context = NULL; + uint32_t i; int display_levels; uint32_t freq_values[3] = {0}; - uint32_t min_clk, max_clk; - - smu_cmn_get_sysfs_buf(&buf, &size); + uint32_t min_clk, max_clk, cur_value = 0; + bool freq_match; + unsigned int clock_mhz; + static const char attempt_string[] = "Attempt to get current"; if (amdgpu_ras_intr_triggered()) { - size += sysfs_emit_at(buf, size, "unavailable\n"); - return size; + *offset += sysfs_emit_at(buf, *offset, "unavailable\n"); + return -EBUSY; } dpm_context = smu_dpm->dpm_context; @@ -762,21 +759,17 @@ static int aldebaran_print_clk_levels(struct smu_context *smu, switch (type) { case SMU_OD_SCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "GFXCLK"); + *offset += sysfs_emit_at(buf, *offset, "%s:\n", "GFXCLK"); fallthrough; case SMU_SCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_GFXCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current gfx clk Failed!"); + dev_err(smu->adev->dev, "%s gfx clk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.gfx_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get gfx clk levels Failed!"); - return ret; - } + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); display_levels = (clocks.num_levels == 1) ? 1 : 2; @@ -787,147 +780,110 @@ static int aldebaran_print_clk_levels(struct smu_context *smu, freq_values[1] = max_clk; /* fine-grained dpm has only 2 levels */ - if (now > min_clk && now < max_clk) { + if (cur_value > min_clk && cur_value < max_clk) { display_levels++; freq_values[2] = max_clk; - freq_values[1] = now; + freq_values[1] = cur_value; } - - for (i = 0; i < display_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, - freq_values[i], - (display_levels == 1) ? - "*" : - (aldebaran_freqs_in_same_level( - freq_values[i], now) ? - "*" : - "")); - break; case SMU_OD_MCLK: - size += sysfs_emit_at(buf, size, "%s:\n", "MCLK"); + *offset += sysfs_emit_at(buf, *offset, "%s:\n", "MCLK"); fallthrough; case SMU_MCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_UCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_UCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current mclk Failed!"); + dev_err(smu->adev->dev, "%s mclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.uclk_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get memory clk levels Failed!"); - return ret; - } - - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? "*" : - (aldebaran_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); break; case SMU_SOCCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_SOCCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current socclk Failed!"); + dev_err(smu->adev->dev, "%s socclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.soc_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get socclk levels Failed!"); - return ret; - } - - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? "*" : - (aldebaran_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); break; case SMU_FCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_FCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_FCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current fclk Failed!"); + dev_err(smu->adev->dev, "%s fclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.fclk_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get fclk levels Failed!"); - return ret; - } - - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (aldebaran_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); break; case SMU_VCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_VCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_VCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current vclk Failed!"); + dev_err(smu->adev->dev, "%s vclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.vclk_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get vclk levels Failed!"); - return ret; - } - - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (aldebaran_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); break; case SMU_DCLK: - ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_DCLK, &now); + ret = aldebaran_get_current_clk_freq_by_table(smu, SMU_DCLK, &cur_value); if (ret) { - dev_err(smu->adev->dev, "Attempt to get current dclk Failed!"); + dev_err(smu->adev->dev, "%s dclk Failed!", attempt_string); return ret; } single_dpm_table = &(dpm_context->dpm_tables.dclk_table); - ret = aldebaran_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, "Attempt to get dclk levels Failed!"); - return ret; - } - - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", - i, single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? "*" : - (aldebaran_freqs_in_same_level( - clocks.data[i].clocks_in_khz / 1000, - now) ? "*" : "")); + aldebaran_get_clk_table(smu, &clocks, single_dpm_table); break; default: + return -EINVAL; + } + + switch (type) { + case SMU_OD_SCLK: + case SMU_SCLK: + for (i = 0; i < display_levels; i++) { + clock_mhz = freq_values[i]; + freq_match = aldebaran_freqs_in_same_level(clock_mhz, cur_value); + freq_match |= (display_levels == 1); + + *offset += sysfs_emit_at(buf, *offset, "%d: %uMhz %s\n", i, + clock_mhz, + (freq_match) ? "*" : ""); + } break; + + case SMU_OD_MCLK: + case SMU_MCLK: + case SMU_SOCCLK: + case SMU_FCLK: + case SMU_VCLK: + case SMU_DCLK: + for (i = 0; i < clocks.num_levels; i++) { + clock_mhz = clocks.data[i].clocks_in_khz / 1000; + freq_match = aldebaran_freqs_in_same_level(clock_mhz, cur_value); + freq_match |= (clocks.num_levels == 1); + + *offset += sysfs_emit_at(buf, *offset, "%d: %uMhz %s\n", + i, clock_mhz, + (freq_match) ? "*" : ""); + } + break; + default: + return -EINVAL; } - return size; + return 0; } static int aldebaran_upload_dpm_level(struct smu_context *smu, @@ -1095,16 +1051,6 @@ static int aldebaran_get_current_activity_percent(struct smu_context *smu, return ret; } -static int aldebaran_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return aldebaran_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int aldebaran_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1158,8 +1104,10 @@ static int aldebaran_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = aldebaran_get_gpu_power(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: + ret = aldebaran_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: @@ -1184,6 +1132,7 @@ static int aldebaran_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1193,9 +1142,10 @@ static int aldebaran_read_sensor(struct smu_context *smu, } static int aldebaran_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { PPTable_t *pptable = smu->smu_table.driver_pptable; uint32_t power_limit = 0; @@ -1208,7 +1158,8 @@ static int aldebaran_get_power_limit(struct smu_context *smu, *default_power_limit = 0; if (max_power_limit) *max_power_limit = 0; - + if (min_power_limit) + *min_power_limit = 0; dev_warn(smu->adev->dev, "PPT feature is not enabled, power values can't be fetched."); @@ -1243,6 +1194,9 @@ static int aldebaran_get_power_limit(struct smu_context *smu, *max_power_limit = pptable->PptLimit; } + if (min_power_limit) + *min_power_limit = 0; + return 0; } @@ -1626,8 +1580,6 @@ static void aldebaran_get_unique_id(struct smu_context *smu) out: adev->unique_id = ((uint64_t)upper32 << 32) | lower32; - if (adev->serial[0] == '\0') - sprintf(adev->serial, "%016llx", adev->unique_id); } static bool aldebaran_is_baco_supported(struct smu_context *smu) @@ -1652,20 +1604,27 @@ static int aldebaran_set_df_cstate(struct smu_context *smu, return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL); } -static int aldebaran_allow_xgmi_power_down(struct smu_context *smu, bool en) +static int aldebaran_select_xgmi_plpd_policy(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode) { struct amdgpu_device *adev = smu->adev; /* The message only works on master die and NACK will be sent back for other dies, only send it on master die */ - if (!adev->smuio.funcs->get_socket_id(adev) && - !adev->smuio.funcs->get_die_id(adev)) + if (adev->smuio.funcs->get_socket_id(adev) || + adev->smuio.funcs->get_die_id(adev)) + return 0; + + if (mode == XGMI_PLPD_DEFAULT) return smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GmiPwrDnControl, - en ? 0 : 1, - NULL); + SMU_MSG_GmiPwrDnControl, + 0, NULL); + else if (mode == XGMI_PLPD_DISALLOW) + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GmiPwrDnControl, + 1, NULL); else - return 0; + return -EINVAL; } static const struct throttling_logging_label { @@ -1681,7 +1640,7 @@ static const struct throttling_logging_label { static void aldebaran_log_thermal_throttling_event(struct smu_context *smu) { int ret; - int throttler_idx, throtting_events = 0, buf_idx = 0; + int throttler_idx, throttling_events = 0, buf_idx = 0; struct amdgpu_device *adev = smu->adev; uint32_t throttler_status; char log_buf[256]; @@ -1696,11 +1655,11 @@ static void aldebaran_log_thermal_throttling_event(struct smu_context *smu) for (throttler_idx = 0; throttler_idx < ARRAY_SIZE(logging_label); throttler_idx++) { if (throttler_status & logging_label[throttler_idx].feature_mask) { - throtting_events++; + throttling_events++; buf_idx += snprintf(log_buf + buf_idx, sizeof(log_buf) - buf_idx, "%s%s", - throtting_events > 1 ? " and " : "", + throttling_events > 1 ? " and " : "", logging_label[throttler_idx].label); if (buf_idx >= sizeof(log_buf)) { dev_err(adev->dev, "buffer overflow!\n"); @@ -1812,24 +1771,15 @@ static ssize_t aldebaran_get_gpu_metrics(struct smu_context *smu, static int aldebaran_check_ecc_table_support(struct smu_context *smu, int *ecctable_version) { - uint32_t if_version = 0xff, smu_version = 0xff; - int ret = 0; - - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { - /* return not support if failed get smu_version */ - ret = -EOPNOTSUPP; - } - - if (smu_version < SUPPORT_ECCTABLE_SMU_VERSION) - ret = -EOPNOTSUPP; - else if (smu_version >= SUPPORT_ECCTABLE_SMU_VERSION && - smu_version < SUPPORT_ECCTABLE_V2_SMU_VERSION) + if (smu->smc_fw_version < SUPPORT_ECCTABLE_SMU_VERSION) + return -EOPNOTSUPP; + else if (smu->smc_fw_version >= SUPPORT_ECCTABLE_SMU_VERSION && + smu->smc_fw_version < SUPPORT_ECCTABLE_V2_SMU_VERSION) *ecctable_version = 1; else *ecctable_version = 2; - return ret; + return 0; } static ssize_t aldebaran_get_ecc_info(struct smu_context *smu, @@ -1892,7 +1842,7 @@ static ssize_t aldebaran_get_ecc_info(struct smu_context *smu, static int aldebaran_mode1_reset(struct smu_context *smu) { - u32 smu_version, fatal_err, param; + u32 fatal_err, param; int ret = 0; struct amdgpu_device *adev = smu->adev; struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); @@ -1903,14 +1853,12 @@ static int aldebaran_mode1_reset(struct smu_context *smu) /* * PM FW support SMU_MSG_GfxDeviceDriverReset from 68.07 */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (smu_version < 0x00440700) { + if (smu->smc_fw_version < 0x00440700) { ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL); - } - else { + } else { /* fatal error triggered by ras, PMFW supports the flag from 68.44.0 */ - if ((smu_version >= 0x00442c00) && ras && + if ((smu->smc_fw_version >= 0x00442c00) && ras && atomic_read(&ras->in_recovery)) fatal_err = 1; @@ -1927,18 +1875,15 @@ static int aldebaran_mode1_reset(struct smu_context *smu) static int aldebaran_mode2_reset(struct smu_context *smu) { - u32 smu_version; int ret = 0, index; struct amdgpu_device *adev = smu->adev; int timeout = 10; - smu_cmn_get_smc_version(smu, NULL, &smu_version); - index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_GfxDeviceDriverReset); mutex_lock(&smu->message_lock); - if (smu_version >= 0x00441400) { + if (smu->smc_fw_version >= 0x00441400) { ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2); /* This is similar to FLR, wait till max FLR timeout */ msleep(100); @@ -1965,7 +1910,7 @@ static int aldebaran_mode2_reset(struct smu_context *smu) } else { dev_err(adev->dev, "smu fw 0x%x does not support MSG_GfxDeviceDriverReset MSG\n", - smu_version); + smu->smc_fw_version); } if (ret == 1) @@ -1988,14 +1933,20 @@ static bool aldebaran_is_mode1_reset_supported(struct smu_context *smu) { #if 0 struct amdgpu_device *adev = smu->adev; - u32 smu_version; uint32_t val; + uint32_t smu_version; + int ret; + /** * PM FW version support mode1 reset from 68.07 */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); + ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); + if (ret) + return false; + if ((smu_version < 0x00440700)) return false; + /** * mode1 reset relies on PSP, so we should check if * PSP is alive. @@ -2039,19 +1990,10 @@ static int aldebaran_smu_send_hbm_bad_page_num(struct smu_context *smu, static int aldebaran_check_bad_channel_info_support(struct smu_context *smu) { - uint32_t if_version = 0xff, smu_version = 0xff; - int ret = 0; - - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) { - /* return not support if failed get smu_version */ - ret = -EOPNOTSUPP; - } - - if (smu_version < SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION) - ret = -EOPNOTSUPP; + if (smu->smc_fw_version < SUPPORT_BAD_CHANNEL_INFO_MSG_VERSION) + return -EOPNOTSUPP; - return ret; + return 0; } static int aldebaran_send_hbm_bad_channel_flag(struct smu_context *smu, @@ -2079,7 +2021,7 @@ static const struct pptable_funcs aldebaran_ppt_funcs = { .set_default_dpm_table = aldebaran_set_default_dpm_table, .populate_umd_state_clk = aldebaran_populate_umd_state_clk, .get_thermal_temperature_range = aldebaran_get_thermal_temperature_range, - .print_clk_levels = aldebaran_print_clk_levels, + .emit_clk_levels = aldebaran_emit_clk_levels, .force_clk_levels = aldebaran_force_clk_levels, .read_sensor = aldebaran_read_sensor, .set_performance_level = aldebaran_set_performance_level, @@ -2116,12 +2058,12 @@ static const struct pptable_funcs aldebaran_ppt_funcs = { .register_irq_handler = smu_v13_0_register_irq_handler, .set_azalia_d3_pme = smu_v13_0_set_azalia_d3_pme, .get_max_sustainable_clocks_by_dc = smu_v13_0_get_max_sustainable_clocks_by_dc, - .baco_is_support= aldebaran_is_baco_supported, + .baco_is_support = aldebaran_is_baco_supported, .get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq, .set_soft_freq_limited_range = aldebaran_set_soft_freq_limited_range, .od_edit_dpm_table = aldebaran_usr_edit_dpm_table, .set_df_cstate = aldebaran_set_df_cstate, - .allow_xgmi_power_down = aldebaran_allow_xgmi_power_down, + .select_xgmi_plpd_policy = aldebaran_select_xgmi_plpd_policy, .log_thermal_throttling_event = aldebaran_log_thermal_throttling_event, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 9b62b45ebb7f..cf1b84060bc3 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -82,8 +82,9 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin"); #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000 #define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE +#define ENABLE_IMU_ARG_GFXOFF_ENABLE 1 + static const int link_width[] = {0, 1, 2, 4, 8, 12, 16}; -static const int link_speed[] = {25, 50, 80, 160}; const int pmfw_decoded_link_speed[5] = {1, 2, 3, 4, 5}; const int pmfw_decoded_link_width[7] = {0, 1, 2, 4, 8, 12, 16}; @@ -197,9 +198,9 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu) if (!adev->scpm_enabled) return 0; - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) || - (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10))) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 7)) || + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0)) || + (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10))) return 0; /* override pptable_id from driver parameter */ @@ -235,7 +236,7 @@ int smu_v13_0_check_fw_status(struct smu_context *smu) struct amdgpu_device *adev = smu->adev; uint32_t mp1_fw_flags; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 4): case IP_VERSION(13, 0, 11): mp1_fw_flags = RREG32_PCIE(MP1_Public | @@ -270,7 +271,7 @@ int smu_v13_0_check_fw_version(struct smu_context *smu) smu_minor = (smu_version >> 8) & 0xff; smu_debug = (smu_version >> 0) & 0xff; if (smu->is_apu || - adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6)) + amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 6)) adev->pm.fw_version = smu_version; /* only for dGPU w/ SMU13*/ @@ -803,7 +804,7 @@ int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable) int ret = 0; struct amdgpu_device *adev = smu->adev; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 0): case IP_VERSION(13, 0, 1): case IP_VERSION(13, 0, 3): @@ -838,12 +839,8 @@ int smu_v13_0_notify_display_change(struct smu_context *smu) { int ret = 0; - if (!smu->pm_enabled) - return ret; - - if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) && - smu->adev->gmc.vram_type == AMDGPU_VRAM_TYPE_HBM) - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1, NULL); + if (!amdgpu_device_has_dc_support(smu->adev)) + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DALNotPresent, NULL); return ret; } @@ -1121,7 +1118,7 @@ smu_v13_0_display_clock_voltage_request(struct smu_context *smu, ret = smu_v13_0_set_hard_freq_limited_range(smu, clk_select, clk_freq, 0); - if(clk_select == SMU_UCLK) + if (clk_select == SMU_UCLK) smu->hard_min_uclk_req_from_dal = clk_freq; } @@ -1175,7 +1172,7 @@ int smu_v13_0_set_fan_speed_pwm(struct smu_context *smu, uint32_t duty100, duty; uint64_t tmp64; - speed = MIN(speed, 255); + speed = min_t(uint32_t, speed, 255); if (smu_v13_0_auto_fan_control(smu, 0)) return -EINVAL; @@ -1437,8 +1434,7 @@ static int smu_v13_0_irq_process(struct amdgpu_device *adev, return 0; } -static const struct amdgpu_irq_src_funcs smu_v13_0_irq_funcs = -{ +static const struct amdgpu_irq_src_funcs smu_v13_0_irq_funcs = { .set = smu_v13_0_set_irq_state, .process = smu_v13_0_irq_process, }; @@ -1786,7 +1782,7 @@ int smu_v13_0_set_performance_level(struct smu_context *smu, * Unset those settings for SMU 13.0.2. As soft limits settings * for those clock domains are not supported. */ - if (smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) { + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 2)) { mclk_min = mclk_max = 0; socclk_min = socclk_max = 0; vclk_min = vclk_max = 0; @@ -1933,7 +1929,7 @@ static int smu_v13_0_get_dpm_level_count(struct smu_context *smu, ret = smu_v13_0_get_dpm_freq_by_index(smu, clk_type, 0xff, value); /* SMU v13.0.2 FW returns 0 based max level, increment by one for it */ - if((smu->adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) && (!ret && value)) + if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 2)) && (!ret && value)) ++(*value); return ret; @@ -1993,7 +1989,7 @@ int smu_v13_0_set_single_dpm_table(struct smu_context *smu, return ret; } - if (smu->adev->ip_versions[MP1_HWIP][0] != IP_VERSION(13, 0, 2)) { + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) != IP_VERSION(13, 0, 2)) { ret = smu_v13_0_get_fine_grained_status(smu, clk_type, &single_dpm_table->is_fine_grained); @@ -2264,7 +2260,7 @@ int smu_v13_0_baco_set_state(struct smu_context *smu, if (state == SMU_BACO_STATE_ENTER) { ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnterBaco, - smu_baco->maco_support ? + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? BACO_SEQ_BAMACO : BACO_SEQ_BACO, NULL); } else { @@ -2308,11 +2304,17 @@ int smu_v13_0_baco_exit(struct smu_context *smu) int smu_v13_0_set_gfx_power_up_by_imu(struct smu_context *smu) { uint16_t index; + struct amdgpu_device *adev = smu->adev; + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnableGfxImu, + ENABLE_IMU_ARG_GFXOFF_ENABLE, NULL); + } index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_EnableGfxImu); - /* Param 1 to tell PMFW to enable GFXOFF feature */ - return smu_cmn_send_msg_without_waiting(smu, index, 1); + return smu_cmn_send_msg_without_waiting(smu, index, + ENABLE_IMU_ARG_GFXOFF_ENABLE); } int smu_v13_0_od_edit_dpm_table(struct smu_context *smu, @@ -2426,8 +2428,8 @@ int smu_v13_0_mode1_reset(struct smu_context *smu) } int smu_v13_0_update_pcie_parameters(struct smu_context *smu, - uint32_t pcie_gen_cap, - uint32_t pcie_width_cap) + uint8_t pcie_gen_cap, + uint8_t pcie_width_cap) { struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_13_0_pcie_table *pcie_table = @@ -2436,7 +2438,10 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu, uint32_t smu_pcie_arg; int ret, i; - if (!amdgpu_device_pcie_dynamic_switching_supported()) { + if (!num_of_levels) + return 0; + + if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) { if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap) pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1]; @@ -2472,3 +2477,16 @@ int smu_v13_0_update_pcie_parameters(struct smu_context *smu, return 0; } + +int smu_v13_0_disable_pmfw_state(struct smu_context *smu) +{ + int ret; + struct amdgpu_device *adev = smu->adev; + + WREG32_PCIE(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff), 0); + + ret = RREG32_PCIE(MP1_Public | + (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); + + return ret == 0 ? 0 : -EINVAL; +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 0fb6be11a0cc..82c4e1f1c6f0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -96,6 +96,20 @@ */ #define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 +#define PP_OD_FEATURE_FAN_CURVE_TEMP 5 +#define PP_OD_FEATURE_FAN_CURVE_PWM 6 +#define PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT 7 +#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8 +#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9 +#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10 + +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -154,6 +168,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(AllowGpo, PPSMC_MSG_SetGpoAllow, 0), MSG_MAP(AllowIHHostInterrupt, PPSMC_MSG_AllowIHHostInterrupt, 0), MSG_MAP(ReenableAcDcInterrupt, PPSMC_MSG_ReenableAcDcInterrupt, 0), + MSG_MAP(DALNotPresent, PPSMC_MSG_DALNotPresent, 0), }; static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = { @@ -167,6 +182,7 @@ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = { CLK_MAP(VCLK1, PPCLK_VCLK_1), CLK_MAP(DCLK, PPCLK_DCLK_0), CLK_MAP(DCLK1, PPCLK_DCLK_1), + CLK_MAP(DCEFCLK, PPCLK_DCFCLK), }; static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] = { @@ -280,7 +296,6 @@ smu_v13_0_0_get_allowed_feature_mask(struct smu_context *smu, uint32_t *feature_mask, uint32_t num) { struct amdgpu_device *adev = smu->adev; - u32 smu_version; if (num > 2) return -EINVAL; @@ -300,8 +315,7 @@ smu_v13_0_0_get_allowed_feature_mask(struct smu_context *smu, *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT); /* PMFW 78.58 contains a critical fix for gfxoff feature */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if ((smu_version < 0x004e3a00) || + if ((smu->smc_fw_version < 0x004e3a00) || !(adev->pm.pp_feature & PP_GFXOFF_MASK)) *(uint64_t *)feature_mask &= ~FEATURE_MASK(FEATURE_GFXOFF_BIT); @@ -332,45 +346,33 @@ static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu) table_context->power_play_table; struct smu_baco_context *smu_baco = &smu->smu_baco; PPTable_t *pptable = smu->smu_table.driver_pptable; -#if 0 - PPTable_t *pptable = smu->smu_table.driver_pptable; const OverDriveLimits_t * const overdrive_upperlimits = &pptable->SkuTable.OverDriveLimitsBasicMax; const OverDriveLimits_t * const overdrive_lowerlimits = &pptable->SkuTable.OverDriveLimitsMin; -#endif if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC) smu->dc_controlled_by_gpio = true; - if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO || - powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) + if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO) { smu_baco->platform_support = true; - if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) - smu_baco->maco_support = true; + if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO) + smu_baco->maco_support = true; + } - /* - * We are in the transition to a new OD mechanism. - * Disable the OD feature support for SMU13 temporarily. - * TODO: get this reverted when new OD mechanism online - */ -#if 0 if (!overdrive_lowerlimits->FeatureCtrlMask || !overdrive_upperlimits->FeatureCtrlMask) smu->od_enabled = false; + table_context->thermal_controller_type = + powerplay_table->thermal_controller_type; + /* * Instead of having its own buffer space and get overdrive_table copied, * smu->od_settings just points to the actual overdrive_table */ smu->od_settings = &powerplay_table->overdrive_table; -#else - smu->od_enabled = false; -#endif - - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; smu->adev->pm.no_fan = !(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT)); @@ -698,6 +700,22 @@ static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu) pcie_table->num_of_link_levels++; } + /* dcefclk dpm table setup */ + dpm_table = &dpm_context->dpm_tables.dcef_table; + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) { + ret = smu_v13_0_set_single_dpm_table(smu, + SMU_DCEFCLK, + dpm_table); + if (ret) + return ret; + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; + dpm_table->dpm_levels[0].enabled = true; + dpm_table->min = dpm_table->dpm_levels[0].value; + dpm_table->max = dpm_table->dpm_levels[0].value; + } + return 0; } @@ -785,6 +803,9 @@ static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu, case METRICS_CURR_FCLK: *value = metrics->CurrClock[PPCLK_FCLK]; break; + case METRICS_CURR_DCEFCLK: + *value = metrics->CurrClock[PPCLK_DCFCLK]; + break; case METRICS_AVERAGE_GFXCLK: if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD) *value = metrics->AverageGfxclkFrequencyPostDs; @@ -947,7 +968,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_0_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -991,6 +1012,7 @@ static int smu_v13_0_0_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1037,6 +1059,9 @@ static int smu_v13_0_0_get_current_clk_freq_by_table(struct smu_context *smu, case PPCLK_DCLK_1: member_type = METRICS_AVERAGE_DCLK1; break; + case PPCLK_DCFCLK: + member_type = METRICS_CURR_DCEFCLK; + break; default: return -EINVAL; } @@ -1058,7 +1083,6 @@ static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1070,29 +1094,52 @@ static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; + break; + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; + break; + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; + case PP_OD_FEATURE_FAN_CURVE_TEMP: + od_min_setting = overdrive_lowerlimits->FanLinearTempPoints; + od_max_setting = overdrive_upperlimits->FanLinearTempPoints; + break; + case PP_OD_FEATURE_FAN_CURVE_PWM: + od_min_setting = overdrive_lowerlimits->FanLinearPwmPoints; + od_max_setting = overdrive_upperlimits->FanLinearPwmPoints; + break; + case PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT: + od_min_setting = overdrive_lowerlimits->AcousticLimitRpmThreshold; + od_max_setting = overdrive_upperlimits->AcousticLimitRpmThreshold; + break; + case PP_OD_FEATURE_FAN_ACOUSTIC_TARGET: + od_min_setting = overdrive_lowerlimits->AcousticTargetRpmThreshold; + od_max_setting = overdrive_upperlimits->AcousticTargetRpmThreshold; + break; + case PP_OD_FEATURE_FAN_TARGET_TEMPERATURE: + od_min_setting = overdrive_lowerlimits->FanTargetTemperature; + od_max_setting = overdrive_upperlimits->FanTargetTemperature; + break; + case PP_OD_FEATURE_FAN_MINIMUM_PWM: + od_min_setting = overdrive_lowerlimits->FanMinimumPwm; + od_max_setting = overdrive_upperlimits->FanMinimumPwm; + break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1188,6 +1235,9 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, case SMU_DCLK1: single_dpm_table = &(dpm_context->dpm_tables.dclk_table); break; + case SMU_DCEFCLK: + single_dpm_table = &(dpm_context->dpm_tables.dcef_table); + break; default: break; } @@ -1201,6 +1251,7 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, case SMU_VCLK1: case SMU_DCLK: case SMU_DCLK1: + case SMU_DCEFCLK: ret = smu_v13_0_0_get_current_clk_freq_by_table(smu, clk_type, &curr_freq); if (ret) { dev_err(smu->adev->dev, "Failed to get current clock freq!"); @@ -1296,16 +1347,115 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, od_table->OverDriveTable.UclkFmax); break; - case SMU_OD_VDDC_CURVE: + case SMU_OD_VDDGFX_OFFSET: if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) break; - size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n"); - for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) - size += sysfs_emit_at(buf, size, "%d: %dmv\n", + size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n"); + size += sysfs_emit_at(buf, size, "%dmV\n", + od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]); + break; + + case SMU_OD_FAN_CURVE: + if (!smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_FAN_CURVE:\n"); + for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++) + size += sysfs_emit_at(buf, size, "%d: %dC %d%%\n", i, - od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]); + (int)od_table->OverDriveTable.FanLinearTempPoints[i], + (int)od_table->OverDriveTable.FanLinearPwmPoints[i]); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_TEMP, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "FAN_CURVE(hotspot temp): %uC %uC\n", + min_value, max_value); + + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_PWM, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "FAN_CURVE(fan speed): %u%% %u%%\n", + min_value, max_value); + + break; + + case SMU_OD_ACOUSTIC_LIMIT: + if (!smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_LIMIT:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.AcousticLimitRpmThreshold); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "ACOUSTIC_LIMIT: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_ACOUSTIC_TARGET: + if (!smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_TARGET:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.AcousticTargetRpmThreshold); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_TARGET, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "ACOUSTIC_TARGET: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_FAN_TARGET_TEMPERATURE: + if (!smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "FAN_TARGET_TEMPERATURE:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.FanTargetTemperature); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_TARGET_TEMPERATURE, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "TARGET_TEMPERATURE: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_FAN_MINIMUM_PWM: + if (!smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "FAN_MINIMUM_PWM:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.FanMinimumPwm); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_MINIMUM_PWM, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "MINIMUM_PWM: %u %u\n", + min_value, max_value); break; case SMU_OD_RANGE: @@ -1318,13 +1468,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1333,13 +1481,11 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1348,11 +1494,10 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); - size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", + size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n", min_value, max_value); } break; @@ -1364,6 +1509,60 @@ static int smu_v13_0_0_print_clk_levels(struct smu_context *smu, return size; } + +static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long input) +{ + struct smu_table_context *table_context = &smu->smu_table; + OverDriveTableExternal_t *boot_overdrive_table = + (OverDriveTableExternal_t *)table_context->boot_overdrive_table; + OverDriveTableExternal_t *od_table = + (OverDriveTableExternal_t *)table_context->overdrive_table; + struct amdgpu_device *adev = smu->adev; + int i; + + switch (input) { + case PP_OD_EDIT_FAN_CURVE: + for (i = 0; i < NUM_OD_FAN_MAX_POINTS; i++) { + od_table->OverDriveTable.FanLinearTempPoints[i] = + boot_overdrive_table->OverDriveTable.FanLinearTempPoints[i]; + od_table->OverDriveTable.FanLinearPwmPoints[i] = + boot_overdrive_table->OverDriveTable.FanLinearPwmPoints[i]; + } + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_ACOUSTIC_LIMIT: + od_table->OverDriveTable.AcousticLimitRpmThreshold = + boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_ACOUSTIC_TARGET: + od_table->OverDriveTable.AcousticTargetRpmThreshold = + boot_overdrive_table->OverDriveTable.AcousticTargetRpmThreshold; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_FAN_TARGET_TEMPERATURE: + od_table->OverDriveTable.FanTargetTemperature = + boot_overdrive_table->OverDriveTable.FanTargetTemperature; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_FAN_MINIMUM_PWM: + od_table->OverDriveTable.FanMinimumPwm = + boot_overdrive_table->OverDriveTable.FanMinimumPwm; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + default: + dev_info(adev->dev, "Invalid table index: %ld\n", input); + return -EINVAL; + } + + return 0; +} + static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], @@ -1373,7 +1572,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1394,8 +1593,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1411,8 +1609,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1457,8 +1654,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1474,8 +1670,7 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1505,40 +1700,167 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, } break; - case PP_OD_EDIT_VDDC_CURVE: + case PP_OD_EDIT_VDDGFX_OFFSET: if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { - dev_warn(adev->dev, "VF curve setting not supported!\n"); + dev_warn(adev->dev, "Gfx offset setting not supported!\n"); return -ENOTSUPP; } - if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS || + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_GFX_VF_CURVE, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) + od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0]; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_CURVE: + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + if (input[0] >= NUM_OD_FAN_MAX_POINTS - 1 || input[0] < 0) return -EINVAL; smu_v13_0_0_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_FAN_CURVE_TEMP, &minimum, &maximum); if (input[1] < minimum || input[1] > maximum) { - dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", + dev_info(adev->dev, "Fan curve temp setting(%ld) must be within [%d, %d]!\n", input[1], minimum, maximum); return -EINVAL; } - od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1]; - od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_PWM, + &minimum, + &maximum); + if (input[2] < minimum || + input[2] > maximum) { + dev_info(adev->dev, "Fan curve pwm setting(%ld) must be within [%d, %d]!\n", + input[2], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanLinearTempPoints[input[0]] = input[1]; + od_table->OverDriveTable.FanLinearPwmPoints[input[0]] = input[2]; + od_table->OverDriveTable.FanMode = FAN_MODE_MANUAL_LINEAR; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_ACOUSTIC_LIMIT: + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "acoustic limit threshold setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.AcousticLimitRpmThreshold = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_ACOUSTIC_TARGET: + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_TARGET, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "acoustic target threshold setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.AcousticTargetRpmThreshold = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_TARGET_TEMPERATURE: + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_TARGET_TEMPERATURE, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "fan target temperature setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanTargetTemperature = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_MINIMUM_PWM: + if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_0_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_MINIMUM_PWM, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "fan minimum pwm setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanMinimumPwm = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); break; case PP_OD_RESTORE_DEFAULT_TABLE: - feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask; - memcpy(od_table, + if (size == 1) { + ret = smu_v13_0_0_od_restore_table_single(smu, input[0]); + if (ret) + return ret; + } else { + feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask; + memcpy(od_table, table_context->boot_overdrive_table, sizeof(OverDriveTableExternal_t)); - od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask; + od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask; + } fallthrough; - case PP_OD_COMMIT_DPM_TABLE: /* * The member below instructs PMFW the settings focused in @@ -1547,10 +1869,10 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_0_dump_od_table(smu, od_table); ret = smu_v13_0_0_upload_overdrive_table(smu, od_table); @@ -1560,9 +1882,9 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, @@ -1698,7 +2020,6 @@ static int smu_v13_0_0_get_thermal_temperature_range(struct smu_context *smu, return 0; } -#define MAX(a, b) ((a) > (b) ? (a) : (b)) static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, void **table) { @@ -1722,12 +2043,12 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->temperature_mem = metrics->AvgTemperature[TEMP_MEM]; gpu_metrics->temperature_vrgfx = metrics->AvgTemperature[TEMP_VR_GFX]; gpu_metrics->temperature_vrsoc = metrics->AvgTemperature[TEMP_VR_SOC]; - gpu_metrics->temperature_vrmem = MAX(metrics->AvgTemperature[TEMP_VR_MEM0], + gpu_metrics->temperature_vrmem = max(metrics->AvgTemperature[TEMP_VR_MEM0], metrics->AvgTemperature[TEMP_VR_MEM1]); gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity; gpu_metrics->average_umc_activity = metrics->AverageUclkActivity; - gpu_metrics->average_mm_activity = MAX(metrics->Vcn0ActivityPercentage, + gpu_metrics->average_mm_activity = max(metrics->Vcn0ActivityPercentage, metrics->Vcn1ActivityPercentage); gpu_metrics->average_socket_power = metrics->AverageSocketPower; @@ -1765,7 +2086,10 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); @@ -1778,6 +2102,24 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, return sizeof(struct gpu_metrics_v1_3); } +static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + if (smu_v13_0_0_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + adev->pm.od_feature_mask |= OD_OPS_SUPPORT_FAN_CURVE_RETRIEVE | + OD_OPS_SUPPORT_FAN_CURVE_SET | + OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_RETRIEVE | + OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_SET | + OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_RETRIEVE | + OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_SET | + OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE | + OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET | + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE | + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET; +} + static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu) { OverDriveTableExternal_t *od_table = @@ -1827,8 +2169,24 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu) for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) user_od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = user_od_table_bak.OverDriveTable.VoltageOffsetPerZoneBoundary[i]; + for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++) { + user_od_table->OverDriveTable.FanLinearTempPoints[i] = + user_od_table_bak.OverDriveTable.FanLinearTempPoints[i]; + user_od_table->OverDriveTable.FanLinearPwmPoints[i] = + user_od_table_bak.OverDriveTable.FanLinearPwmPoints[i]; + } + user_od_table->OverDriveTable.AcousticLimitRpmThreshold = + user_od_table_bak.OverDriveTable.AcousticLimitRpmThreshold; + user_od_table->OverDriveTable.AcousticTargetRpmThreshold = + user_od_table_bak.OverDriveTable.AcousticTargetRpmThreshold; + user_od_table->OverDriveTable.FanTargetTemperature = + user_od_table_bak.OverDriveTable.FanTargetTemperature; + user_od_table->OverDriveTable.FanMinimumPwm = + user_od_table_bak.OverDriveTable.FanMinimumPwm; } + smu_v13_0_0_set_supported_od_feature_mask(smu); + return 0; } @@ -1839,9 +2197,10 @@ static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu) OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table; int res; - user_od_table->OverDriveTable.FeatureCtrlMask = 1U << PP_OD_FEATURE_GFXCLK_BIT | - 1U << PP_OD_FEATURE_UCLK_BIT | - 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; + user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | + BIT(PP_OD_FEATURE_UCLK_BIT) | + BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | + BIT(PP_OD_FEATURE_FAN_CURVE_BIT); res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table); user_od_table->OverDriveTable.FeatureCtrlMask = 0; if (res == 0) @@ -1927,8 +2286,6 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu) out: adev->unique_id = ((uint64_t)upper32 << 32) | lower32; - if (adev->serial[0] == '\0') - sprintf(adev->serial, "%016llx", adev->unique_id); } static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu, @@ -1948,7 +2305,7 @@ static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu, } /* Convert the PMFW output which is in percent to pwm(255) based */ - *speed = MIN(*speed * 255 / 100, 255); + *speed = min(*speed * 255 / 100, (uint32_t)255); return 0; } @@ -1984,16 +2341,17 @@ static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu) } static int smu_v13_0_0_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_table_context *table_context = &smu->smu_table; struct smu_13_0_0_powerplay_table *powerplay_table = (struct smu_13_0_0_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent; + uint32_t power_limit, od_percent_upper, od_percent_lower; if (smu_v13_0_get_current_power_limit(smu, &power_limit)) power_limit = smu->adev->pm.ac_power ? @@ -2005,16 +2363,25 @@ static int smu_v13_0_0_get_power_limit(struct smu_context *smu, if (default_power_limit) *default_power_limit = power_limit; - if (max_power_limit) { - if (smu->od_enabled) { - od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + if (smu->od_enabled) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]); + } else { + od_percent_upper = 0; + od_percent_lower = 100; + } - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", + od_percent_upper, od_percent_lower, power_limit); - power_limit *= (100 + od_percent); - power_limit /= 100; - } - *max_power_limit = power_limit; + if (max_power_limit) { + *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit /= 100; + } + + if (min_power_limit) { + *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit /= 100; } return 0; @@ -2109,6 +2476,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, DpmActivityMonitorCoeffInt_t *activity_monitor = &(activity_monitor_external.DpmActivityMonitorCoeffInt); int workload_type, ret = 0; + u32 workload_mask; smu->power_profile_mode = input[size]; @@ -2162,45 +2530,31 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, } } - if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE && - (((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xC8)) || - ((smu->adev->pdev->device == 0x744C) && (smu->adev->pdev->revision == 0xCC)))) { - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, - WORKLOAD_PPLIB_COMPUTE_BIT, - (void *)(&activity_monitor_external), - false); - if (ret) { - dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); - return ret; - } - - ret = smu_cmn_update_table(smu, - SMU_TABLE_ACTIVITY_MONITOR_COEFF, - WORKLOAD_PPLIB_CUSTOM_BIT, - (void *)(&activity_monitor_external), - true); - if (ret) { - dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); - return ret; - } - - workload_type = smu_cmn_to_asic_specific_index(smu, - CMN2ASIC_MAPPING_WORKLOAD, - PP_SMC_POWER_PROFILE_CUSTOM); - } else { - /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ - workload_type = smu_cmn_to_asic_specific_index(smu, + /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ + workload_type = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_WORKLOAD, smu->power_profile_mode); - } if (workload_type < 0) return -EINVAL; + workload_mask = 1 << workload_type; + + /* Add optimizations for SMU13.0.0. Reuse the power saving profile */ + if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE && + (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0)) && + ((smu->adev->pm.fw_version == 0x004e6601) || + (smu->adev->pm.fw_version >= 0x004e7400))) { + workload_type = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_WORKLOAD, + PP_SMC_POWER_PROFILE_POWERSAVING); + if (workload_type >= 0) + workload_mask |= 1 << workload_type; + } + return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, - 1 << workload_type, + workload_mask, NULL); } @@ -2211,7 +2565,8 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } @@ -2219,27 +2574,37 @@ static int smu_v13_0_0_baco_enter(struct smu_context *smu) static int smu_v13_0_0_baco_exit(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + int ret; if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { /* Wait for PMFW handling for the Dstate change */ usleep_range(10000, 11000); - return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); + ret = smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); } else { - return smu_v13_0_baco_exit(smu); + ret = smu_v13_0_baco_exit(smu); } + + if (!ret) + adev->gfx.is_poweron = false; + + return ret; } static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; u32 smu_version; + int ret; /* SRIOV does not support SMU mode1 reset */ if (amdgpu_sriov_vf(adev)) return false; /* PMFW support is available since 78.41 */ - smu_cmn_get_smc_version(smu, NULL, &smu_version); + ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); + if (ret) + return false; + if (smu_version < 0x004e2900) return false; @@ -2407,7 +2772,13 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu, switch (mp1_state) { case PP_MP1_STATE_UNLOAD: - ret = smu_cmn_set_mp1_state(smu, mp1_state); + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_PrepareMp1ForUnload, + 0x55, NULL); + + if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) + ret = smu_v13_0_disable_pmfw_state(smu); + break; default: /* Ignore others */ @@ -2430,13 +2801,10 @@ static void smu_v13_0_0_set_mode1_reset_param(struct smu_context *smu, uint32_t supported_version, uint32_t *param) { - uint32_t smu_version; struct amdgpu_device *adev = smu->adev; struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); - smu_cmn_get_smc_version(smu, NULL, &smu_version); - - if ((smu_version >= supported_version) && + if ((smu->smc_fw_version >= supported_version) && ras && atomic_read(&ras->in_recovery)) /* Set RAS fatal error reset flag */ *param = 1 << 16; @@ -2450,7 +2818,7 @@ static int smu_v13_0_0_mode1_reset(struct smu_context *smu) uint32_t param; struct amdgpu_device *adev = smu->adev; - switch (adev->ip_versions[MP1_HWIP][0]) { + switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { case IP_VERSION(13, 0, 0): /* SMU 13_0_0 PMFW supports RAS fatal error reset from 78.77 */ smu_v13_0_0_set_mode1_reset_param(smu, 0x004e4d00, ¶m); @@ -2483,7 +2851,7 @@ static int smu_v13_0_0_mode2_reset(struct smu_context *smu) int ret; struct amdgpu_device *adev = smu->adev; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10)) ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode2Reset, NULL); else return -EOPNOTSUPP; @@ -2495,7 +2863,7 @@ static int smu_v13_0_0_enable_gfx_features(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10)) return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnableAllSmuFeatures, FEATURE_PWR_GFX, NULL); else @@ -2552,15 +2920,10 @@ static int smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context *smu, static int smu_v13_0_0_check_ecc_table_support(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - uint32_t if_version = 0xff, smu_version = 0xff; int ret = 0; - ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); - if (ret) - return -EOPNOTSUPP; - - if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)) && - (smu_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10)) && + (smu->smc_fw_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION)) return ret; else return -EOPNOTSUPP; @@ -2686,6 +3049,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { .send_hbm_bad_channel_flag = smu_v13_0_0_send_bad_mem_channel_flag, .gpo_control = smu_v13_0_gpo_control, .get_ecc_info = smu_v13_0_0_get_ecc_info, + .notify_display_change = smu_v13_0_notify_display_change, }; void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index ef37dda9908f..bb98156b2fa1 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -257,7 +257,7 @@ static ssize_t smu_v13_0_4_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_gfx_activity = metrics.GfxActivity; gpu_metrics->average_mm_activity = metrics.UvdActivity; - gpu_metrics->average_socket_power = metrics.CurrentSocketPower; + gpu_metrics->average_socket_power = metrics.AverageSocketPower; gpu_metrics->average_gfx_power = metrics.Power[0]; gpu_metrics->average_soc_power = metrics.Power[1]; memcpy(&gpu_metrics->average_core_power[0], @@ -321,6 +321,9 @@ static int smu_v13_0_4_get_smu_metrics_data(struct smu_context *smu, *value = metrics->UvdActivity; break; case METRICS_AVERAGE_SOCKETPOWER: + *value = (metrics->AverageSocketPower << 8) / 1000; + break; + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -569,12 +572,18 @@ static int smu_v13_0_4_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_4_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; case AMDGPU_PP_SENSOR_EDGE_TEMP: ret = smu_v13_0_4_get_smu_metrics_data(smu, METRICS_TEMPERATURE_EDGE, @@ -1135,7 +1144,7 @@ void smu_v13_0_4_set_ppt_funcs(struct smu_context *smu) smu->smc_driver_if_version = SMU13_0_4_DRIVER_IF_VERSION; smu->is_apu = true; - if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 4)) + if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 4)) smu_v13_0_4_set_smu_mailbox_registers(smu); else smu_v13_0_set_smu_mailbox_registers(smu); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index 42f110602eb1..0dce672ac1b9 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -75,7 +75,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_5_message_map[SMU_MSG_MAX_COUNT] = MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), - MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu , 1), + MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), MSG_MAP(GetGfxclkFrequency, PPSMC_MSG_GetGfxclkFrequency, 1), MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), @@ -288,7 +288,7 @@ static int smu_v13_0_5_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -332,9 +332,9 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = smu_v13_0_5_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -388,6 +388,7 @@ static int smu_v13_0_5_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; @@ -1059,7 +1060,7 @@ static int smu_v13_0_5_set_performance_level(struct smu_context *smu, return -EINVAL; } - if (sclk_min && sclk_max && smu_v13_0_5_clk_dpm_is_enabled(smu, SMU_SCLK)) { + if (sclk_min && sclk_max) { ret = smu_v13_0_5_set_soft_freq_limited_range(smu, SMU_SCLK, sclk_min, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index dc6104a04dce..900a2d9e6d85 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -44,9 +44,11 @@ #include "amdgpu_xgmi.h" #include <linux/pci.h> #include "amdgpu_ras.h" +#include "amdgpu_mca.h" #include "smu_cmn.h" #include "mp/mp_13_0_6_offset.h" #include "mp/mp_13_0_6_sh_mask.h" +#include "umc_v12_0.h" #undef MP1_Public #undef smnMP1_FIRMWARE_FLAGS @@ -64,6 +66,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -80,18 +84,48 @@ /* possible frequency drift (1Mhz) */ #define EPSILON 1 -#define smnPCIE_ESM_CTRL 0x193D0 +#define smnPCIE_ESM_CTRL 0x93D0 #define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4 #define MAX_LINK_WIDTH 6 +#define smnPCIE_LC_SPEED_CNTL 0x1a340290 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0 +#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5 +#define LINK_SPEED_MAX 4 + +#define SMU_13_0_6_DSCLK_THRESHOLD 140 + +#define MCA_BANK_IPID(_ip, _hwid, _type) \ + [AMDGPU_MCA_IP_##_ip] = { .hwid = _hwid, .mcatype = _type, } + +struct mca_bank_ipid { + enum amdgpu_mca_ip ip; + uint16_t hwid; + uint16_t mcatype; +}; + +struct mca_ras_info { + enum amdgpu_ras_block blkid; + enum amdgpu_mca_ip ip; + int *err_code_array; + int err_code_count; + int (*get_err_count)(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count); + bool (*bank_is_valid)(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry); +}; + +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), - MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 1), - MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 1), + MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0), + MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0), MSG_MAP(RequestI2cTransaction, PPSMC_MSG_RequestI2cTransaction, 0), MSG_MAP(GetMetricsTable, PPSMC_MSG_GetMetricsTable, 1), MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1), @@ -102,8 +136,8 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0), MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0), MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0), - MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 0), - MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 0), + MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1), + MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1), MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1), MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1), @@ -122,11 +156,19 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU MSG_MAP(EnableDeterminism, PPSMC_MSG_EnableDeterminism, 0), MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0), MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0), - MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 0), - MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 0), + MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 1), + MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 1), MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 0), MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 0), MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0), + MSG_MAP(GetCTFLimit, PPSMC_MSG_GetCTFLimit, 0), + MSG_MAP(GetThermalLimit, PPSMC_MSG_ReadThrottlerLimit, 0), + MSG_MAP(ClearMcaOnRead, PPSMC_MSG_ClearMcaOnRead, 0), + MSG_MAP(QueryValidMcaCount, PPSMC_MSG_QueryValidMcaCount, 0), + MSG_MAP(QueryValidMcaCeCount, PPSMC_MSG_QueryValidMcaCeCount, 0), + MSG_MAP(McaBankDumpDW, PPSMC_MSG_McaBankDumpDW, 0), + MSG_MAP(McaBankCeDumpDW, PPSMC_MSG_McaBankCeDumpDW, 0), + MSG_MAP(SelectPLPDMode, PPSMC_MSG_SelectPLPDMode, 0), }; static const struct cmn2asic_mapping smu_v13_0_6_clk_map[SMU_CLK_COUNT] = { @@ -201,6 +243,8 @@ struct PPTable_t { }; #define SMUQ10_TO_UINT(x) ((x) >> 10) +#define SMUQ10_FRAC(x) ((x) & 0x3ff) +#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200)) struct smu_v13_0_6_dpm_map { enum smu_clk_type clk_type; @@ -209,6 +253,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) +{ + const struct smc_firmware_header_v2_1 *v2_1; + const struct common_firmware_header *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[15]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct common_firmware_header *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(hdr); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries + * are used to carry p2s tables. + */ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + + le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE); + } + + return 0; +out: + amdgpu_ucode_release(&adev->pm.fw); + + return ret; +} + static int smu_v13_0_6_tables_init(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; @@ -232,7 +340,7 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu) return -ENOMEM; smu_table->metrics_time = 0; - smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_3); + smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_4); smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); if (!smu_table->gpu_metrics_table) { @@ -326,35 +434,45 @@ static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu) MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; struct PPTable_t *pptable = (struct PPTable_t *)smu_table->driver_pptable; - int ret; - int i; + int ret, i, retry = 100; /* Store one-time values in driver PPTable */ if (!pptable->Init) { - ret = smu_v13_0_6_get_metrics_table(smu, NULL, false); - if (ret) - return ret; + while (--retry) { + ret = smu_v13_0_6_get_metrics_table(smu, NULL, true); + if (ret) + return ret; + + /* Ensure that metrics have been updated */ + if (metrics->AccumulationCounter) + break; + + usleep_range(1000, 1100); + } + + if (!retry) + return -ETIME; pptable->MaxSocketPowerLimit = - SMUQ10_TO_UINT(metrics->MaxSocketPowerLimit); + SMUQ10_ROUND(metrics->MaxSocketPowerLimit); pptable->MaxGfxclkFrequency = - SMUQ10_TO_UINT(metrics->MaxGfxclkFrequency); + SMUQ10_ROUND(metrics->MaxGfxclkFrequency); pptable->MinGfxclkFrequency = - SMUQ10_TO_UINT(metrics->MinGfxclkFrequency); + SMUQ10_ROUND(metrics->MinGfxclkFrequency); for (i = 0; i < 4; ++i) { pptable->FclkFrequencyTable[i] = - SMUQ10_TO_UINT(metrics->FclkFrequencyTable[i]); + SMUQ10_ROUND(metrics->FclkFrequencyTable[i]); pptable->UclkFrequencyTable[i] = - SMUQ10_TO_UINT(metrics->UclkFrequencyTable[i]); - pptable->SocclkFrequencyTable[i] = SMUQ10_TO_UINT( + SMUQ10_ROUND(metrics->UclkFrequencyTable[i]); + pptable->SocclkFrequencyTable[i] = SMUQ10_ROUND( metrics->SocclkFrequencyTable[i]); pptable->VclkFrequencyTable[i] = - SMUQ10_TO_UINT(metrics->VclkFrequencyTable[i]); + SMUQ10_ROUND(metrics->VclkFrequencyTable[i]); pptable->DclkFrequencyTable[i] = - SMUQ10_TO_UINT(metrics->DclkFrequencyTable[i]); + SMUQ10_ROUND(metrics->DclkFrequencyTable[i]); pptable->LclkFrequencyTable[i] = - SMUQ10_TO_UINT(metrics->LclkFrequencyTable[i]); + SMUQ10_ROUND(metrics->LclkFrequencyTable[i]); } /* use AID0 serial number by default */ @@ -662,7 +780,6 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu, struct smu_table_context *smu_table = &smu->smu_table; MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table; struct amdgpu_device *adev = smu->adev; - uint32_t smu_version; int ret = 0; int xcc_id; @@ -674,53 +791,52 @@ static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu, switch (member) { case METRICS_CURR_GFXCLK: case METRICS_AVERAGE_GFXCLK: - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (smu_version >= 0x552F00) { + if (smu->smc_fw_version >= 0x552F00) { xcc_id = GET_INST(GC, 0); - *value = SMUQ10_TO_UINT(metrics->GfxclkFrequency[xcc_id]); + *value = SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]); } else { *value = 0; } break; case METRICS_CURR_SOCCLK: case METRICS_AVERAGE_SOCCLK: - *value = SMUQ10_TO_UINT(metrics->SocclkFrequency[0]); + *value = SMUQ10_ROUND(metrics->SocclkFrequency[0]); break; case METRICS_CURR_UCLK: case METRICS_AVERAGE_UCLK: - *value = SMUQ10_TO_UINT(metrics->UclkFrequency); + *value = SMUQ10_ROUND(metrics->UclkFrequency); break; case METRICS_CURR_VCLK: - *value = SMUQ10_TO_UINT(metrics->VclkFrequency[0]); + *value = SMUQ10_ROUND(metrics->VclkFrequency[0]); break; case METRICS_CURR_DCLK: - *value = SMUQ10_TO_UINT(metrics->DclkFrequency[0]); + *value = SMUQ10_ROUND(metrics->DclkFrequency[0]); break; case METRICS_CURR_FCLK: - *value = SMUQ10_TO_UINT(metrics->FclkFrequency); + *value = SMUQ10_ROUND(metrics->FclkFrequency); break; case METRICS_AVERAGE_GFXACTIVITY: - *value = SMUQ10_TO_UINT(metrics->SocketGfxBusy); + *value = SMUQ10_ROUND(metrics->SocketGfxBusy); break; case METRICS_AVERAGE_MEMACTIVITY: - *value = SMUQ10_TO_UINT(metrics->DramBandwidthUtilization); + *value = SMUQ10_ROUND(metrics->DramBandwidthUtilization); break; - case METRICS_AVERAGE_SOCKETPOWER: - *value = SMUQ10_TO_UINT(metrics->SocketPower) << 8; + case METRICS_CURR_SOCKETPOWER: + *value = SMUQ10_ROUND(metrics->SocketPower) << 8; break; case METRICS_TEMPERATURE_HOTSPOT: - *value = SMUQ10_TO_UINT(metrics->MaxSocketTemperature) * + *value = SMUQ10_ROUND(metrics->MaxSocketTemperature) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; case METRICS_TEMPERATURE_MEM: - *value = SMUQ10_TO_UINT(metrics->MaxHbmTemperature) * + *value = SMUQ10_ROUND(metrics->MaxHbmTemperature) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; /* This is the max of all VRs and not just SOC VR. * No need to define another data type for the same. */ case METRICS_TEMPERATURE_VRSOC: - *value = SMUQ10_TO_UINT(metrics->MaxVrTemperature) * + *value = SMUQ10_ROUND(metrics->MaxVrTemperature) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; break; default: @@ -766,18 +882,64 @@ static int smu_v13_0_6_get_current_clk_freq_by_table(struct smu_context *smu, return smu_v13_0_6_get_smu_metrics_data(smu, member_type, value); } +static int smu_v13_0_6_print_clks(struct smu_context *smu, char *buf, int size, + struct smu_13_0_dpm_table *single_dpm_table, + uint32_t curr_clk, const char *clk_name) +{ + struct pp_clock_levels_with_latency clocks; + int i, ret, level = -1; + uint32_t clk1, clk2; + + ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); + if (ret) { + dev_err(smu->adev->dev, "Attempt to get %s clk levels failed!", + clk_name); + return ret; + } + + if (!clocks.num_levels) + return -EINVAL; + + if (curr_clk < SMU_13_0_6_DSCLK_THRESHOLD) { + size = sysfs_emit_at(buf, size, "S: %uMhz *\n", curr_clk); + for (i = 0; i < clocks.num_levels; i++) + size += sysfs_emit_at(buf, size, "%d: %uMhz\n", i, + clocks.data[i].clocks_in_khz / + 1000); + + } else { + if ((clocks.num_levels == 1) || + (curr_clk < (clocks.data[0].clocks_in_khz / 1000))) + level = 0; + for (i = 0; i < clocks.num_levels; i++) { + clk1 = clocks.data[i].clocks_in_khz / 1000; + + if (i < (clocks.num_levels - 1)) + clk2 = clocks.data[i + 1].clocks_in_khz / 1000; + + if (curr_clk >= clk1 && curr_clk < clk2) { + level = (curr_clk - clk1) <= (clk2 - curr_clk) ? + i : + i + 1; + } + + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, + clk1, (level == i) ? "*" : ""); + } + } + + return size; +} + static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, enum smu_clk_type type, char *buf) { - int i, now, size = 0; + int now, size = 0; int ret = 0; struct smu_umd_pstate_table *pstate_table = &smu->pstate_table; - struct pp_clock_levels_with_latency clocks; struct smu_13_0_dpm_table *single_dpm_table; struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_13_0_dpm_context *dpm_context = NULL; - uint32_t display_levels; - uint32_t freq_values[3] = { 0 }; uint32_t min_clk, max_clk; smu_cmn_get_sysfs_buf(&buf, &size); @@ -802,50 +964,32 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, return ret; } - single_dpm_table = &(dpm_context->dpm_tables.gfx_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get gfx clk levels Failed!"); - return ret; - } - - display_levels = clocks.num_levels; - min_clk = pstate_table->gfxclk_pstate.curr.min; max_clk = pstate_table->gfxclk_pstate.curr.max; - freq_values[0] = min_clk; - freq_values[1] = max_clk; - - /* fine-grained dpm has only 2 levels */ - if (now > min_clk && now < max_clk) { - display_levels = clocks.num_levels + 1; - freq_values[2] = max_clk; - freq_values[1] = now; - } - - /* - * For DPM disabled case, there will be only one clock level. - * And it's safe to assume that is always the current clock. - */ - if (display_levels == clocks.num_levels) { - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - freq_values[i], - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - freq_values[i], now) ? - "*" : - "")); + if (now < SMU_13_0_6_DSCLK_THRESHOLD) { + size += sysfs_emit_at(buf, size, "S: %uMhz *\n", + now); + size += sysfs_emit_at(buf, size, "0: %uMhz\n", + min_clk); + size += sysfs_emit_at(buf, size, "1: %uMhz\n", + max_clk); + + } else if (!smu_v13_0_6_freqs_in_same_level(now, min_clk) && + !smu_v13_0_6_freqs_in_same_level(now, max_clk)) { + size += sysfs_emit_at(buf, size, "0: %uMhz\n", + min_clk); + size += sysfs_emit_at(buf, size, "1: %uMhz *\n", + now); + size += sysfs_emit_at(buf, size, "2: %uMhz\n", + max_clk); } else { - for (i = 0; i < display_levels; i++) - size += sysfs_emit_at(buf, size, - "%d: %uMhz %s\n", i, - freq_values[i], - i == 1 ? "*" : ""); + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", + min_clk, + smu_v13_0_6_freqs_in_same_level(now, min_clk) ? "*" : ""); + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", + max_clk, + smu_v13_0_6_freqs_in_same_level(now, max_clk) ? "*" : ""); } break; @@ -863,26 +1007,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, } single_dpm_table = &(dpm_context->dpm_tables.uclk_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get memory clk levels Failed!"); - return ret; - } - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - clocks.data[i].clocks_in_khz / - 1000, - now) ? - "*" : - "")); - break; + return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table, + now, "mclk"); case SMU_SOCCLK: ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_SOCCLK, @@ -894,26 +1021,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, } single_dpm_table = &(dpm_context->dpm_tables.soc_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get socclk levels Failed!"); - return ret; - } - for (i = 0; i < clocks.num_levels; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - clocks.data[i].clocks_in_khz / 1000, - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - clocks.data[i].clocks_in_khz / - 1000, - now) ? - "*" : - "")); - break; + return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table, + now, "socclk"); case SMU_FCLK: ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_FCLK, @@ -925,26 +1035,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, } single_dpm_table = &(dpm_context->dpm_tables.fclk_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get fclk levels Failed!"); - return ret; - } - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - clocks.data[i].clocks_in_khz / - 1000, - now) ? - "*" : - "")); - break; + return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table, + now, "fclk"); case SMU_VCLK: ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_VCLK, @@ -956,26 +1049,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, } single_dpm_table = &(dpm_context->dpm_tables.vclk_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get vclk levels Failed!"); - return ret; - } - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - clocks.data[i].clocks_in_khz / - 1000, - now) ? - "*" : - "")); - break; + return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table, + now, "vclk"); case SMU_DCLK: ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_DCLK, @@ -987,26 +1063,9 @@ static int smu_v13_0_6_print_clk_levels(struct smu_context *smu, } single_dpm_table = &(dpm_context->dpm_tables.dclk_table); - ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table); - if (ret) { - dev_err(smu->adev->dev, - "Attempt to get dclk levels Failed!"); - return ret; - } - for (i = 0; i < single_dpm_table->count; i++) - size += sysfs_emit_at( - buf, size, "%d: %uMhz %s\n", i, - single_dpm_table->dpm_levels[i].value, - (clocks.num_levels == 1) ? - "*" : - (smu_v13_0_6_freqs_in_same_level( - clocks.data[i].clocks_in_khz / - 1000, - now) ? - "*" : - "")); - break; + return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table, + now, "dclk"); default: break; @@ -1158,15 +1217,6 @@ static int smu_v13_0_6_get_current_activity_percent(struct smu_context *smu, return ret; } -static int smu_v13_0_6_get_gpu_power(struct smu_context *smu, uint32_t *value) -{ - if (!value) - return -EINVAL; - - return smu_v13_0_6_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, - value); -} - static int smu_v13_0_6_thermal_get_temperature(struct smu_context *smu, enum amd_pp_sensors sensor, uint32_t *value) @@ -1212,8 +1262,10 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: - ret = smu_v13_0_6_get_gpu_power(smu, (uint32_t *)data); + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v13_0_6_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); *size = 4; break; case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: @@ -1239,6 +1291,7 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; @@ -1248,13 +1301,14 @@ static int smu_v13_0_6_read_sensor(struct smu_context *smu, } static int smu_v13_0_6_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { - struct smu_table_context *smu_table = &smu->smu_table; - struct PPTable_t *pptable = - (struct PPTable_t *)smu_table->driver_pptable; + struct smu_table_context *smu_table = &smu->smu_table; + struct PPTable_t *pptable = + (struct PPTable_t *)smu_table->driver_pptable; uint32_t power_limit = 0; int ret; @@ -1274,6 +1328,8 @@ static int smu_v13_0_6_get_power_limit(struct smu_context *smu, *max_power_limit = pptable->MaxSocketPowerLimit; } + if (min_power_limit) + *min_power_limit = 0; return 0; } @@ -1370,8 +1426,7 @@ static int smu_v13_0_6_set_irq_state(struct amdgpu_device *adev, return 0; } -static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs = -{ +static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs = { .set = smu_v13_0_6_set_irq_state, .process = smu_v13_0_6_irq_process, }; @@ -1399,10 +1454,7 @@ static int smu_v13_0_6_register_irq_handler(struct smu_context *smu) static int smu_v13_0_6_notify_unload(struct smu_context *smu) { - uint32_t smu_version; - - smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (smu_version <= 0x553500) + if (amdgpu_in_reset(smu->adev)) return 0; dev_dbg(smu->adev->dev, "Notify PMFW about driver unload"); @@ -1412,12 +1464,27 @@ static int smu_v13_0_6_notify_unload(struct smu_context *smu) return 0; } +static int smu_v13_0_6_mca_set_debug_mode(struct smu_context *smu, bool enable) +{ + /* NOTE: this ClearMcaOnRead message is only supported for smu version 85.72.0 or higher */ + if (smu->smc_fw_version < 0x554800) + return 0; + + amdgpu_ras_set_mca_debug_mode(smu->adev, enable); + return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ClearMcaOnRead, + enable ? 0 : ClearMcaOnRead_UE_FLAG_MASK | ClearMcaOnRead_CE_POLL_MASK, + NULL); +} + static int smu_v13_0_6_system_features_control(struct smu_context *smu, bool enable) { struct amdgpu_device *adev = smu->adev; int ret = 0; + if (amdgpu_sriov_vf(adev)) + return 0; + if (enable) { if (!(adev->flags & AMD_IS_APU)) ret = smu_v13_0_system_features_control(smu, enable); @@ -1660,13 +1727,11 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu, static int smu_v13_0_6_get_enabled_mask(struct smu_context *smu, uint64_t *feature_mask) { - uint32_t smu_version; int ret; - smu_cmn_get_smc_version(smu, NULL, &smu_version); ret = smu_cmn_get_enabled_mask(smu, feature_mask); - if (ret == -EIO && smu_version < 0x552F00) { + if (ret == -EIO && smu->smc_fw_version < 0x552F00) { *feature_mask = 0; ret = 0; } @@ -1870,8 +1935,6 @@ static void smu_v13_0_6_get_unique_id(struct smu_context *smu) (struct PPTable_t *)smu_table->driver_pptable; adev->unique_id = pptable->PublicSerialNumber_AID; - if (adev->serial[0] == '\0') - sprintf(adev->serial, "%016llx", adev->unique_id); } static bool smu_v13_0_6_is_baco_supported(struct smu_context *smu) @@ -1881,19 +1944,6 @@ static bool smu_v13_0_6_is_baco_supported(struct smu_context *smu) return false; } -static int smu_v13_0_6_set_df_cstate(struct smu_context *smu, - enum pp_df_cstate state) -{ - return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, - state, NULL); -} - -static int smu_v13_0_6_allow_xgmi_power_down(struct smu_context *smu, bool en) -{ - return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GmiPwrDnControl, - en ? 0 : 1, NULL); -} - static const char *const throttling_logging_label[] = { [THROTTLER_PROCHOT_BIT] = "Prochot", [THROTTLER_PPT_BIT] = "PPT", @@ -1904,7 +1954,7 @@ static const char *const throttling_logging_label[] = { static void smu_v13_0_6_log_thermal_throttling_event(struct smu_context *smu) { - int throttler_idx, throtting_events = 0, buf_idx = 0; + int throttler_idx, throttling_events = 0, buf_idx = 0; struct amdgpu_device *adev = smu->adev; uint32_t throttler_status; char log_buf[256]; @@ -1918,10 +1968,10 @@ static void smu_v13_0_6_log_thermal_throttling_event(struct smu_context *smu) throttler_idx < ARRAY_SIZE(throttling_logging_label); throttler_idx++) { if (throttler_status & (1U << throttler_idx)) { - throtting_events++; + throttling_events++; buf_idx += snprintf( log_buf + buf_idx, sizeof(log_buf) - buf_idx, - "%s%s", throtting_events > 1 ? " and " : "", + "%s%s", throttling_events > 1 ? " and " : "", throttling_logging_label[throttler_idx]); if (buf_idx >= sizeof(log_buf)) { dev_err(adev->dev, "buffer overflow!\n"); @@ -1952,6 +2002,7 @@ smu_v13_0_6_get_current_pcie_link_width_level(struct smu_context *smu) static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + uint32_t speed_level; uint32_t esm_ctrl; /* TODO: confirm this on real target */ @@ -1959,67 +2010,80 @@ static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu) if ((esm_ctrl >> 15) & 0x1FFFF) return (((esm_ctrl >> 8) & 0x3F) + 128); - return smu_v13_0_get_current_pcie_link_speed(smu); + speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) & + PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK) + >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT; + if (speed_level > LINK_SPEED_MAX) + speed_level = 0; + + return pcie_gen_to_speed(speed_level + 1); } static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table) { struct smu_table_context *smu_table = &smu->smu_table; - struct gpu_metrics_v1_3 *gpu_metrics = - (struct gpu_metrics_v1_3 *)smu_table->gpu_metrics_table; + struct gpu_metrics_v1_4 *gpu_metrics = + (struct gpu_metrics_v1_4 *)smu_table->gpu_metrics_table; struct amdgpu_device *adev = smu->adev; - int ret = 0, inst0, xcc0; + int ret = 0, xcc_id, inst, i; MetricsTable_t *metrics; u16 link_width_level; - inst0 = adev->sdma.instance[0].aid_id; - xcc0 = GET_INST(GC, 0); - metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL); ret = smu_v13_0_6_get_metrics_table(smu, metrics, true); - if (ret) + if (ret) { + kfree(metrics); return ret; + } - smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3); + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 4); gpu_metrics->temperature_hotspot = - SMUQ10_TO_UINT(metrics->MaxSocketTemperature); + SMUQ10_ROUND(metrics->MaxSocketTemperature); /* Individual HBM stack temperature is not reported */ gpu_metrics->temperature_mem = - SMUQ10_TO_UINT(metrics->MaxHbmTemperature); + SMUQ10_ROUND(metrics->MaxHbmTemperature); /* Reports max temperature of all voltage rails */ gpu_metrics->temperature_vrsoc = - SMUQ10_TO_UINT(metrics->MaxVrTemperature); + SMUQ10_ROUND(metrics->MaxVrTemperature); gpu_metrics->average_gfx_activity = - SMUQ10_TO_UINT(metrics->SocketGfxBusy); + SMUQ10_ROUND(metrics->SocketGfxBusy); gpu_metrics->average_umc_activity = - SMUQ10_TO_UINT(metrics->DramBandwidthUtilization); + SMUQ10_ROUND(metrics->DramBandwidthUtilization); - gpu_metrics->average_socket_power = - SMUQ10_TO_UINT(metrics->SocketPower); + gpu_metrics->curr_socket_power = + SMUQ10_ROUND(metrics->SocketPower); /* Energy counter reported in 15.259uJ (2^-16) units */ gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc; - gpu_metrics->current_gfxclk = - SMUQ10_TO_UINT(metrics->GfxclkFrequency[xcc0]); - gpu_metrics->current_socclk = - SMUQ10_TO_UINT(metrics->SocclkFrequency[inst0]); - gpu_metrics->current_uclk = SMUQ10_TO_UINT(metrics->UclkFrequency); - gpu_metrics->current_vclk0 = - SMUQ10_TO_UINT(metrics->VclkFrequency[inst0]); - gpu_metrics->current_dclk0 = - SMUQ10_TO_UINT(metrics->DclkFrequency[inst0]); - - gpu_metrics->average_gfxclk_frequency = gpu_metrics->current_gfxclk; - gpu_metrics->average_socclk_frequency = gpu_metrics->current_socclk; - gpu_metrics->average_uclk_frequency = gpu_metrics->current_uclk; - gpu_metrics->average_vclk0_frequency = gpu_metrics->current_vclk0; - gpu_metrics->average_dclk0_frequency = gpu_metrics->current_dclk0; + for (i = 0; i < MAX_GFX_CLKS; i++) { + xcc_id = GET_INST(GC, i); + if (xcc_id >= 0) + gpu_metrics->current_gfxclk[i] = + SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]); + + if (i < MAX_CLKS) { + gpu_metrics->current_socclk[i] = + SMUQ10_ROUND(metrics->SocclkFrequency[i]); + inst = GET_INST(VCN, i); + if (inst >= 0) { + gpu_metrics->current_vclk0[i] = + SMUQ10_ROUND(metrics->VclkFrequency[inst]); + gpu_metrics->current_dclk0[i] = + SMUQ10_ROUND(metrics->DclkFrequency[inst]); + } + } + } + + gpu_metrics->current_uclk = SMUQ10_ROUND(metrics->UclkFrequency); /* Throttle status is not reported through metrics now */ gpu_metrics->throttle_status = 0; + /* Clock Lock Status. Each bit corresponds to each GFXCLK instance */ + gpu_metrics->gfxclk_lock_status = metrics->GfxLockXCDMak >> GET_INST(GC, 0); + if (!(adev->flags & AMD_IS_APU)) { link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu); if (link_width_level > MAX_LINK_WIDTH) @@ -2029,21 +2093,41 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table DECODE_LANE_WIDTH(link_width_level); gpu_metrics->pcie_link_speed = smu_v13_0_6_get_current_pcie_link_speed(smu); + gpu_metrics->pcie_bandwidth_acc = + SMUQ10_ROUND(metrics->PcieBandwidthAcc[0]); + gpu_metrics->pcie_bandwidth_inst = + SMUQ10_ROUND(metrics->PcieBandwidth[0]); + gpu_metrics->pcie_l0_to_recov_count_acc = + metrics->PCIeL0ToRecoveryCountAcc; + gpu_metrics->pcie_replay_count_acc = + metrics->PCIenReplayAAcc; + gpu_metrics->pcie_replay_rover_count_acc = + metrics->PCIenReplayARolloverCountAcc; } gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); gpu_metrics->gfx_activity_acc = - SMUQ10_TO_UINT(metrics->SocketGfxBusyAcc); + SMUQ10_ROUND(metrics->SocketGfxBusyAcc); gpu_metrics->mem_activity_acc = - SMUQ10_TO_UINT(metrics->DramBandwidthUtilizationAcc); + SMUQ10_ROUND(metrics->DramBandwidthUtilizationAcc); + + for (i = 0; i < NUM_XGMI_LINKS; i++) { + gpu_metrics->xgmi_read_data_acc[i] = + SMUQ10_ROUND(metrics->XgmiReadDataSizeAcc[i]); + gpu_metrics->xgmi_write_data_acc[i] = + SMUQ10_ROUND(metrics->XgmiWriteDataSizeAcc[i]); + } + + gpu_metrics->xgmi_link_width = SMUQ10_ROUND(metrics->XgmiWidth); + gpu_metrics->xgmi_link_speed = SMUQ10_ROUND(metrics->XgmiBitrate); gpu_metrics->firmware_timestamp = metrics->Timestamp; *table = (void *)gpu_metrics; kfree(metrics); - return sizeof(struct gpu_metrics_v1_3); + return sizeof(*gpu_metrics); } static int smu_v13_0_6_mode2_reset(struct smu_context *smu) @@ -2091,19 +2175,93 @@ out: return ret; } +static int smu_v13_0_6_get_thermal_temperature_range(struct smu_context *smu, + struct smu_temperature_range *range) +{ + struct amdgpu_device *adev = smu->adev; + u32 aid_temp, xcd_temp, max_temp; + u32 ccd_temp = 0; + int ret; + + if (amdgpu_sriov_vf(smu->adev)) + return 0; + + if (!range) + return -EINVAL; + + /*Check smu version, GetCtfLimit message only supported for smu version 85.69 or higher */ + if (smu->smc_fw_version < 0x554500) + return 0; + + /* Get SOC Max operating temperature */ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit, + PPSMC_AID_THM_TYPE, &aid_temp); + if (ret) + goto failed; + if (adev->flags & AMD_IS_APU) { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit, + PPSMC_CCD_THM_TYPE, &ccd_temp); + if (ret) + goto failed; + } + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit, + PPSMC_XCD_THM_TYPE, &xcd_temp); + if (ret) + goto failed; + range->hotspot_emergency_max = max3(aid_temp, xcd_temp, ccd_temp) * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + + /* Get HBM Max operating temperature */ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit, + PPSMC_HBM_THM_TYPE, &max_temp); + if (ret) + goto failed; + range->mem_emergency_max = + max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + + /* Get SOC thermal throttle limit */ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetThermalLimit, + PPSMC_THROTTLING_LIMIT_TYPE_SOCKET, + &max_temp); + if (ret) + goto failed; + range->hotspot_crit_max = + max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + + /* Get HBM thermal throttle limit */ + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetThermalLimit, + PPSMC_THROTTLING_LIMIT_TYPE_HBM, + &max_temp); + if (ret) + goto failed; + + range->mem_crit_max = max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + +failed: + return ret; +} + static int smu_v13_0_6_mode1_reset(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + struct amdgpu_hive_info *hive = NULL; + u32 hive_ras_recovery = 0; struct amdgpu_ras *ras; u32 fatal_err, param; int ret = 0; + hive = amdgpu_get_xgmi_hive(adev); ras = amdgpu_ras_get_context(adev); fatal_err = 0; param = SMU_RESET_MODE_1; + if (hive) { + hive_ras_recovery = atomic_read(&hive->ras_recovery); + amdgpu_put_xgmi_hive(hive); + } + /* fatal error triggered by ras, PMFW supports the flag */ - if (ras && atomic_read(&ras->in_recovery)) + if (ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery)) fatal_err = 1; param |= (fatal_err << 16); @@ -2118,8 +2276,7 @@ static int smu_v13_0_6_mode1_reset(struct smu_context *smu) static bool smu_v13_0_6_is_mode1_reset_supported(struct smu_context *smu) { - /* TODO: Enable this when FW support is added */ - return false; + return true; } static bool smu_v13_0_6_is_mode2_reset_supported(struct smu_context *smu) @@ -2143,6 +2300,525 @@ static int smu_v13_0_6_smu_send_hbm_bad_page_num(struct smu_context *smu, return ret; } +static int smu_v13_0_6_post_init(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + if (!amdgpu_sriov_vf(adev) && adev->ras_enabled) + return smu_v13_0_6_mca_set_debug_mode(smu, false); + + return 0; +} + +static int mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + + return smu_v13_0_6_mca_set_debug_mode(smu, enable); +} + +static int smu_v13_0_6_get_valid_mca_count(struct smu_context *smu, enum amdgpu_mca_error_type type, uint32_t *count) +{ + uint32_t msg; + int ret; + + if (!count) + return -EINVAL; + + switch (type) { + case AMDGPU_MCA_ERROR_TYPE_UE: + msg = SMU_MSG_QueryValidMcaCount; + break; + case AMDGPU_MCA_ERROR_TYPE_CE: + msg = SMU_MSG_QueryValidMcaCeCount; + break; + default: + return -EINVAL; + } + + ret = smu_cmn_send_smc_msg(smu, msg, count); + if (ret) { + *count = 0; + return ret; + } + + return 0; +} + +static int __smu_v13_0_6_mca_dump_bank(struct smu_context *smu, enum amdgpu_mca_error_type type, + int idx, int offset, uint32_t *val) +{ + uint32_t msg, param; + + switch (type) { + case AMDGPU_MCA_ERROR_TYPE_UE: + msg = SMU_MSG_McaBankDumpDW; + break; + case AMDGPU_MCA_ERROR_TYPE_CE: + msg = SMU_MSG_McaBankCeDumpDW; + break; + default: + return -EINVAL; + } + + param = ((idx & 0xffff) << 16) | (offset & 0xfffc); + + return smu_cmn_send_smc_msg_with_param(smu, msg, param, val); +} + +static int smu_v13_0_6_mca_dump_bank(struct smu_context *smu, enum amdgpu_mca_error_type type, + int idx, int offset, uint32_t *val, int count) +{ + int ret, i; + + if (!val) + return -EINVAL; + + for (i = 0; i < count; i++) { + ret = __smu_v13_0_6_mca_dump_bank(smu, type, idx, offset + (i << 2), &val[i]); + if (ret) + return ret; + } + + return 0; +} + +static const struct mca_bank_ipid smu_v13_0_6_mca_ipid_table[AMDGPU_MCA_IP_COUNT] = { + MCA_BANK_IPID(UMC, 0x96, 0x0), + MCA_BANK_IPID(SMU, 0x01, 0x1), + MCA_BANK_IPID(MP5, 0x01, 0x2), + MCA_BANK_IPID(PCS_XGMI, 0x50, 0x0), +}; + +static void mca_bank_entry_info_decode(struct mca_bank_entry *entry, struct mca_bank_info *info) +{ + uint64_t ipid = entry->regs[MCA_REG_IDX_IPID]; + uint32_t insthi; + + /* NOTE: All MCA IPID register share the same format, + * so the driver can share the MCMP1 register header file. + * */ + + info->hwid = REG_GET_FIELD(ipid, MCMP1_IPIDT0, HardwareID); + info->mcatype = REG_GET_FIELD(ipid, MCMP1_IPIDT0, McaType); + + insthi = REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdHi); + info->aid = ((insthi >> 2) & 0x03); + info->socket_id = insthi & 0x03; +} + +static int mca_bank_read_reg(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, + int idx, int reg_idx, uint64_t *val) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + uint32_t data[2] = {0, 0}; + int ret; + + if (!val || reg_idx >= MCA_REG_IDX_COUNT) + return -EINVAL; + + ret = smu_v13_0_6_mca_dump_bank(smu, type, idx, reg_idx * 8, data, ARRAY_SIZE(data)); + if (ret) + return ret; + + *val = (uint64_t)data[1] << 32 | data[0]; + + dev_dbg(adev->dev, "mca read bank reg: type:%s, index: %d, reg_idx: %d, val: 0x%016llx\n", + type == AMDGPU_MCA_ERROR_TYPE_UE ? "UE" : "CE", idx, reg_idx, *val); + + return 0; +} + +static int mca_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, + int idx, struct mca_bank_entry *entry) +{ + int i, ret; + + /* NOTE: populated all mca register by default */ + for (i = 0; i < ARRAY_SIZE(entry->regs); i++) { + ret = mca_bank_read_reg(adev, type, idx, i, &entry->regs[i]); + if (ret) + return ret; + } + + entry->idx = idx; + entry->type = type; + + mca_bank_entry_info_decode(entry, &entry->info); + + return 0; +} + +static int mca_decode_ipid_to_hwip(uint64_t val) +{ + const struct mca_bank_ipid *ipid; + uint16_t hwid, mcatype; + int i; + + hwid = REG_GET_FIELD(val, MCMP1_IPIDT0, HardwareID); + mcatype = REG_GET_FIELD(val, MCMP1_IPIDT0, McaType); + + for (i = 0; i < ARRAY_SIZE(smu_v13_0_6_mca_ipid_table); i++) { + ipid = &smu_v13_0_6_mca_ipid_table[i]; + + if (!ipid->hwid) + continue; + + if (ipid->hwid == hwid && ipid->mcatype == mcatype) + return i; + } + + return AMDGPU_MCA_IP_UNKNOW; +} + +static int mca_umc_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count) +{ + uint64_t status0; + + status0 = entry->regs[MCA_REG_IDX_STATUS]; + + if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) { + *count = 0; + return 0; + } + + if (type == AMDGPU_MCA_ERROR_TYPE_UE && umc_v12_0_is_uncorrectable_error(status0)) + *count = 1; + else if (type == AMDGPU_MCA_ERROR_TYPE_CE && umc_v12_0_is_correctable_error(status0)) + *count = 1; + + return 0; +} + +static int mca_pcs_xgmi_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, + uint32_t *count) +{ + u32 ext_error_code; + + ext_error_code = MCA_REG__STATUS__ERRORCODEEXT(entry->regs[MCA_REG_IDX_STATUS]); + + if (type == AMDGPU_MCA_ERROR_TYPE_UE && ext_error_code == 0) + *count = 1; + else if (type == AMDGPU_MCA_ERROR_TYPE_CE && ext_error_code == 6) + *count = 1; + + return 0; +} + +static bool mca_smu_check_error_code(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras, + uint32_t errcode) +{ + int i; + + if (!mca_ras->err_code_count || !mca_ras->err_code_array) + return true; + + for (i = 0; i < mca_ras->err_code_count; i++) { + if (errcode == mca_ras->err_code_array[i]) + return true; + } + + return false; +} + +static int mca_gfx_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count) +{ + uint64_t status0, misc0; + + status0 = entry->regs[MCA_REG_IDX_STATUS]; + if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) { + *count = 0; + return 0; + } + + if (type == AMDGPU_MCA_ERROR_TYPE_UE && + REG_GET_FIELD(status0, MCMP1_STATUST0, UC) == 1 && + REG_GET_FIELD(status0, MCMP1_STATUST0, PCC) == 1) { + *count = 1; + return 0; + } else { + misc0 = entry->regs[MCA_REG_IDX_MISC0]; + *count = REG_GET_FIELD(misc0, MCMP1_MISC0T0, ErrCnt); + } + + return 0; +} + +static int mca_smu_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count) +{ + uint64_t status0, misc0; + + status0 = entry->regs[MCA_REG_IDX_STATUS]; + if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) { + *count = 0; + return 0; + } + + if (type == AMDGPU_MCA_ERROR_TYPE_UE && + REG_GET_FIELD(status0, MCMP1_STATUST0, UC) == 1 && + REG_GET_FIELD(status0, MCMP1_STATUST0, PCC) == 1) { + if (count) + *count = 1; + return 0; + } + + misc0 = entry->regs[MCA_REG_IDX_MISC0]; + *count = REG_GET_FIELD(misc0, MCMP1_MISC0T0, ErrCnt); + + return 0; +} + +static bool mca_gfx_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry) +{ + uint32_t instlo; + + instlo = REG_GET_FIELD(entry->regs[MCA_REG_IDX_IPID], MCMP1_IPIDT0, InstanceIdLo); + switch (instlo) { + case 0x36430400: /* SMNAID XCD 0 */ + case 0x38430400: /* SMNAID XCD 1 */ + case 0x40430400: /* SMNXCD XCD 0, NOTE: FIXME: fix this error later */ + return true; + default: + return false; + } + + return false; +}; + +static bool mca_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + uint32_t errcode, instlo; + + instlo = REG_GET_FIELD(entry->regs[MCA_REG_IDX_IPID], MCMP1_IPIDT0, InstanceIdLo); + if (instlo != 0x03b30400) + return false; + + if (!(adev->flags & AMD_IS_APU) && smu->smc_fw_version >= 0x00555600) { + errcode = MCA_REG__SYND__ERRORINFORMATION(entry->regs[MCA_REG_IDX_SYND]); + errcode &= 0xff; + } else { + errcode = REG_GET_FIELD(entry->regs[MCA_REG_IDX_STATUS], MCMP1_STATUST0, ErrorCode); + } + + return mca_smu_check_error_code(adev, mca_ras, errcode); +} + +static int sdma_err_codes[] = { CODE_SDMA0, CODE_SDMA1, CODE_SDMA2, CODE_SDMA3 }; +static int mmhub_err_codes[] = { + CODE_DAGB0, CODE_DAGB0 + 1, CODE_DAGB0 + 2, CODE_DAGB0 + 3, CODE_DAGB0 + 4, /* DAGB0-4 */ + CODE_EA0, CODE_EA0 + 1, CODE_EA0 + 2, CODE_EA0 + 3, CODE_EA0 + 4, /* MMEA0-4*/ + CODE_VML2, CODE_VML2_WALKER, CODE_MMCANE, +}; + +static const struct mca_ras_info mca_ras_table[] = { + { + .blkid = AMDGPU_RAS_BLOCK__UMC, + .ip = AMDGPU_MCA_IP_UMC, + .get_err_count = mca_umc_mca_get_err_count, + }, { + .blkid = AMDGPU_RAS_BLOCK__GFX, + .ip = AMDGPU_MCA_IP_SMU, + .get_err_count = mca_gfx_mca_get_err_count, + .bank_is_valid = mca_gfx_smu_bank_is_valid, + }, { + .blkid = AMDGPU_RAS_BLOCK__SDMA, + .ip = AMDGPU_MCA_IP_SMU, + .err_code_array = sdma_err_codes, + .err_code_count = ARRAY_SIZE(sdma_err_codes), + .get_err_count = mca_smu_mca_get_err_count, + .bank_is_valid = mca_smu_bank_is_valid, + }, { + .blkid = AMDGPU_RAS_BLOCK__MMHUB, + .ip = AMDGPU_MCA_IP_SMU, + .err_code_array = mmhub_err_codes, + .err_code_count = ARRAY_SIZE(mmhub_err_codes), + .get_err_count = mca_smu_mca_get_err_count, + .bank_is_valid = mca_smu_bank_is_valid, + }, { + .blkid = AMDGPU_RAS_BLOCK__XGMI_WAFL, + .ip = AMDGPU_MCA_IP_PCS_XGMI, + .get_err_count = mca_pcs_xgmi_mca_get_err_count, + }, +}; + +static const struct mca_ras_info *mca_get_mca_ras_info(struct amdgpu_device *adev, enum amdgpu_ras_block blkid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mca_ras_table); i++) { + if (mca_ras_table[i].blkid == blkid) + return &mca_ras_table[i]; + } + + return NULL; +} + +static int mca_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count) +{ + struct smu_context *smu = adev->powerplay.pp_handle; + int ret; + + switch (type) { + case AMDGPU_MCA_ERROR_TYPE_UE: + case AMDGPU_MCA_ERROR_TYPE_CE: + ret = smu_v13_0_6_get_valid_mca_count(smu, type, count); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static bool mca_bank_is_valid(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras, + enum amdgpu_mca_error_type type, struct mca_bank_entry *entry) +{ + if (mca_decode_ipid_to_hwip(entry->regs[MCA_REG_IDX_IPID]) != mca_ras->ip) + return false; + + if (mca_ras->bank_is_valid) + return mca_ras->bank_is_valid(mca_ras, adev, type, entry); + + return true; +} + +static int __mca_smu_get_ras_mca_set(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras, + enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set) +{ + struct mca_bank_entry entry; + uint32_t mca_cnt; + int i, ret; + + ret = mca_get_valid_mca_count(adev, type, &mca_cnt); + if (ret) + return ret; + + /* if valid mca bank count is 0, the driver can return 0 directly */ + if (!mca_cnt) + return 0; + + for (i = 0; i < mca_cnt; i++) { + memset(&entry, 0, sizeof(entry)); + ret = mca_get_mca_entry(adev, type, i, &entry); + if (ret) + return ret; + + if (mca_ras && !mca_bank_is_valid(adev, mca_ras, type, &entry)) + continue; + + ret = amdgpu_mca_bank_set_add_entry(mca_set, &entry); + if (ret) + return ret; + } + + return 0; +} + +static int mca_smu_get_ras_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk, + enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set) +{ + const struct mca_ras_info *mca_ras = NULL; + + if (!mca_set) + return -EINVAL; + + if (blk != AMDGPU_RAS_BLOCK_COUNT) { + mca_ras = mca_get_mca_ras_info(adev, blk); + if (!mca_ras) + return -EOPNOTSUPP; + } + + return __mca_smu_get_ras_mca_set(adev, mca_ras, type, mca_set); +} + +static int mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, + struct mca_bank_entry *entry, uint32_t *count) +{ + const struct mca_ras_info *mca_ras; + + if (!entry || !count) + return -EINVAL; + + mca_ras = mca_get_mca_ras_info(adev, blk); + if (!mca_ras) + return -EOPNOTSUPP; + + if (!mca_bank_is_valid(adev, mca_ras, type, entry)) { + *count = 0; + return 0; + } + + return mca_ras->get_err_count(mca_ras, adev, type, entry, count); +} + +static int mca_smu_get_mca_entry(struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, int idx, struct mca_bank_entry *entry) +{ + return mca_get_mca_entry(adev, type, idx, entry); +} + +static int mca_smu_get_valid_mca_count(struct amdgpu_device *adev, + enum amdgpu_mca_error_type type, uint32_t *count) +{ + return mca_get_valid_mca_count(adev, type, count); +} + +static const struct amdgpu_mca_smu_funcs smu_v13_0_6_mca_smu_funcs = { + .max_ue_count = 12, + .max_ce_count = 12, + .mca_set_debug_mode = mca_smu_set_debug_mode, + .mca_get_ras_mca_set = mca_smu_get_ras_mca_set, + .mca_parse_mca_error_count = mca_smu_parse_mca_error_count, + .mca_get_mca_entry = mca_smu_get_mca_entry, + .mca_get_valid_mca_count = mca_smu_get_valid_mca_count, +}; + +static int smu_v13_0_6_select_xgmi_plpd_policy(struct smu_context *smu, + enum pp_xgmi_plpd_mode mode) +{ + struct amdgpu_device *adev = smu->adev; + int ret, param; + + switch (mode) { + case XGMI_PLPD_DEFAULT: + param = PPSMC_PLPD_MODE_DEFAULT; + break; + case XGMI_PLPD_OPTIMIZED: + param = PPSMC_PLPD_MODE_OPTIMIZED; + break; + case XGMI_PLPD_DISALLOW: + param = 0; + break; + default: + return -EINVAL; + } + + if (mode == XGMI_PLPD_DISALLOW) + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GmiPwrDnControl, + param, NULL); + else + /* change xgmi per-link power down policy */ + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SelectPLPDMode, + param, NULL); + + if (ret) + dev_err(adev->dev, + "select xgmi per-link power down policy %d failed\n", + mode); + + return ret; +} + static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { /* init dpm */ .get_allowed_feature_mask = smu_v13_0_6_get_allowed_feature_mask, @@ -2156,6 +2832,8 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .get_power_limit = smu_v13_0_6_get_power_limit, .is_dpm_running = smu_v13_0_6_is_dpm_running, .get_unique_id = smu_v13_0_6_get_unique_id, + .init_microcode = smu_v13_0_6_init_microcode, + .fini_microcode = smu_v13_0_fini_microcode, .init_smc_tables = smu_v13_0_6_init_smc_tables, .fini_smc_tables = smu_v13_0_fini_smc_tables, .init_power = smu_v13_0_init_power, @@ -2181,12 +2859,11 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .get_dpm_ultimate_freq = smu_v13_0_6_get_dpm_ultimate_freq, .set_soft_freq_limited_range = smu_v13_0_6_set_soft_freq_limited_range, .od_edit_dpm_table = smu_v13_0_6_usr_edit_dpm_table, - .set_df_cstate = smu_v13_0_6_set_df_cstate, - .allow_xgmi_power_down = smu_v13_0_6_allow_xgmi_power_down, + .select_xgmi_plpd_policy = smu_v13_0_6_select_xgmi_plpd_policy, .log_thermal_throttling_event = smu_v13_0_6_log_thermal_throttling_event, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, - .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, .get_gpu_metrics = smu_v13_0_6_get_gpu_metrics, + .get_thermal_temperature_range = smu_v13_0_6_get_thermal_temperature_range, .mode1_reset_is_support = smu_v13_0_6_is_mode1_reset_supported, .mode2_reset_is_support = smu_v13_0_6_is_mode2_reset_supported, .mode1_reset = smu_v13_0_6_mode1_reset, @@ -2195,6 +2872,7 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .i2c_init = smu_v13_0_6_i2c_control_init, .i2c_fini = smu_v13_0_6_i2c_control_fini, .send_hbm_bad_pages_num = smu_v13_0_6_smu_send_hbm_bad_page_num, + .post_init = smu_v13_0_6_post_init, }; void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu) @@ -2206,4 +2884,5 @@ void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu) smu->table_map = smu_v13_0_6_table_map; smu->smc_driver_if_version = SMU13_0_6_DRIVER_IF_VERSION; smu_v13_0_set_smu_mailbox_registers(smu); + amdgpu_mca_smu_init_funcs(smu->adev, &smu_v13_0_6_mca_smu_funcs); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 62f2886ab4df..81eafed76045 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -72,6 +72,20 @@ #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 +#define PP_OD_FEATURE_GFXCLK_FMIN 0 +#define PP_OD_FEATURE_GFXCLK_FMAX 1 +#define PP_OD_FEATURE_UCLK_FMIN 2 +#define PP_OD_FEATURE_UCLK_FMAX 3 +#define PP_OD_FEATURE_GFX_VF_CURVE 4 +#define PP_OD_FEATURE_FAN_CURVE_TEMP 5 +#define PP_OD_FEATURE_FAN_CURVE_PWM 6 +#define PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT 7 +#define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8 +#define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9 +#define PP_OD_FEATURE_FAN_MINIMUM_PWM 10 + +#define LINK_SPEED_MAX 3 + static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -139,6 +153,7 @@ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = { CLK_MAP(VCLK1, PPCLK_VCLK_1), CLK_MAP(DCLK, PPCLK_DCLK_0), CLK_MAP(DCLK1, PPCLK_DCLK_1), + CLK_MAP(DCEFCLK, PPCLK_DCFCLK), }; static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] = { @@ -323,39 +338,34 @@ static int smu_v13_0_7_check_powerplay_table(struct smu_context *smu) struct smu_baco_context *smu_baco = &smu->smu_baco; PPTable_t *smc_pptable = table_context->driver_pptable; BoardTable_t *BoardTable = &smc_pptable->BoardTable; -#if 0 const OverDriveLimits_t * const overdrive_upperlimits = &smc_pptable->SkuTable.OverDriveLimitsBasicMax; const OverDriveLimits_t * const overdrive_lowerlimits = &smc_pptable->SkuTable.OverDriveLimitsMin; -#endif if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_HARDWAREDC) smu->dc_controlled_by_gpio = true; - if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO || - powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO) + if (powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_BACO) { smu_baco->platform_support = true; - if (smu_baco->platform_support && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) - smu_baco->maco_support = true; + if ((powerplay_table->platform_caps & SMU_13_0_7_PP_PLATFORM_CAP_MACO) + && (BoardTable->HsrEnabled || BoardTable->VddqOffEnabled)) + smu_baco->maco_support = true; + } -#if 0 if (!overdrive_lowerlimits->FeatureCtrlMask || !overdrive_upperlimits->FeatureCtrlMask) smu->od_enabled = false; + table_context->thermal_controller_type = + powerplay_table->thermal_controller_type; + /* * Instead of having its own buffer space and get overdrive_table copied, * smu->od_settings just points to the actual overdrive_table */ smu->od_settings = &powerplay_table->overdrive_table; -#else - smu->od_enabled = false; -#endif - - table_context->thermal_controller_type = - powerplay_table->thermal_controller_type; return 0; } @@ -392,8 +402,7 @@ static int smu_v13_0_7_check_fw_status(struct smu_context *smu) } #ifndef atom_smc_dpm_info_table_13_0_7 -struct atom_smc_dpm_info_table_13_0_7 -{ +struct atom_smc_dpm_info_table_13_0_7 { struct atom_common_table_header table_header; BoardTable_t BoardTable; }; @@ -500,7 +509,7 @@ static int smu_v13_0_7_tables_init(struct smu_context *smu) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, sizeof(DpmActivityMonitorCoeffIntExternal_t), PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM); + AMDGPU_GEM_DOMAIN_VRAM); SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); @@ -689,6 +698,22 @@ static int smu_v13_0_7_set_default_dpm_table(struct smu_context *smu) pcie_table->num_of_link_levels++; } + /* dcefclk dpm table setup */ + dpm_table = &dpm_context->dpm_tables.dcef_table; + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) { + ret = smu_v13_0_set_single_dpm_table(smu, + SMU_DCEFCLK, + dpm_table); + if (ret) + return ret; + } else { + dpm_table->count = 1; + dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; + dpm_table->dpm_levels[0].enabled = true; + dpm_table->min = dpm_table->dpm_levels[0].value; + dpm_table->max = dpm_table->dpm_levels[0].value; + } + return 0; } @@ -734,7 +759,7 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; SmuMetrics_t *metrics = &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics); int ret = 0; @@ -770,6 +795,9 @@ static int smu_v13_0_7_get_smu_metrics_data(struct smu_context *smu, case METRICS_CURR_FCLK: *value = metrics->CurrClock[PPCLK_FCLK]; break; + case METRICS_CURR_DCEFCLK: + *value = metrics->CurrClock[PPCLK_DCFCLK]; + break; case METRICS_AVERAGE_GFXCLK: *value = metrics->AverageGfxclkFrequencyPreDs; break; @@ -929,7 +957,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: ret = smu_v13_0_7_get_smu_metrics_data(smu, METRICS_AVERAGE_SOCKETPOWER, (uint32_t *)data); @@ -973,6 +1001,7 @@ static int smu_v13_0_7_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: default: ret = -EOPNOTSUPP; break; @@ -1019,6 +1048,9 @@ static int smu_v13_0_7_get_current_clk_freq_by_table(struct smu_context *smu, case PPCLK_DCLK_1: member_type = METRICS_CURR_DCLK1; break; + case PPCLK_DCFCLK: + member_type = METRICS_CURR_DCEFCLK; + break; default: return -EINVAL; } @@ -1040,7 +1072,6 @@ static bool smu_v13_0_7_is_od_feature_supported(struct smu_context *smu, static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int od_feature_bit, - bool lower_boundary, int32_t *min, int32_t *max) { @@ -1052,29 +1083,52 @@ static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, int32_t od_min_setting, od_max_setting; switch (od_feature_bit) { - case PP_OD_FEATURE_GFXCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->GfxclkFmin; - od_max_setting = overdrive_upperlimits->GfxclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->GfxclkFmax; - od_max_setting = overdrive_upperlimits->GfxclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMIN: + od_min_setting = overdrive_lowerlimits->GfxclkFmin; + od_max_setting = overdrive_upperlimits->GfxclkFmin; break; - case PP_OD_FEATURE_UCLK_BIT: - if (lower_boundary) { - od_min_setting = overdrive_lowerlimits->UclkFmin; - od_max_setting = overdrive_upperlimits->UclkFmin; - } else { - od_min_setting = overdrive_lowerlimits->UclkFmax; - od_max_setting = overdrive_upperlimits->UclkFmax; - } + case PP_OD_FEATURE_GFXCLK_FMAX: + od_min_setting = overdrive_lowerlimits->GfxclkFmax; + od_max_setting = overdrive_upperlimits->GfxclkFmax; + break; + case PP_OD_FEATURE_UCLK_FMIN: + od_min_setting = overdrive_lowerlimits->UclkFmin; + od_max_setting = overdrive_upperlimits->UclkFmin; break; - case PP_OD_FEATURE_GFX_VF_CURVE_BIT: + case PP_OD_FEATURE_UCLK_FMAX: + od_min_setting = overdrive_lowerlimits->UclkFmax; + od_max_setting = overdrive_upperlimits->UclkFmax; + break; + case PP_OD_FEATURE_GFX_VF_CURVE: od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary; od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary; break; + case PP_OD_FEATURE_FAN_CURVE_TEMP: + od_min_setting = overdrive_lowerlimits->FanLinearTempPoints; + od_max_setting = overdrive_upperlimits->FanLinearTempPoints; + break; + case PP_OD_FEATURE_FAN_CURVE_PWM: + od_min_setting = overdrive_lowerlimits->FanLinearPwmPoints; + od_max_setting = overdrive_upperlimits->FanLinearPwmPoints; + break; + case PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT: + od_min_setting = overdrive_lowerlimits->AcousticLimitRpmThreshold; + od_max_setting = overdrive_upperlimits->AcousticLimitRpmThreshold; + break; + case PP_OD_FEATURE_FAN_ACOUSTIC_TARGET: + od_min_setting = overdrive_lowerlimits->AcousticTargetRpmThreshold; + od_max_setting = overdrive_upperlimits->AcousticTargetRpmThreshold; + break; + case PP_OD_FEATURE_FAN_TARGET_TEMPERATURE: + od_min_setting = overdrive_lowerlimits->FanTargetTemperature; + od_max_setting = overdrive_upperlimits->FanTargetTemperature; + break; + case PP_OD_FEATURE_FAN_MINIMUM_PWM: + od_min_setting = overdrive_lowerlimits->FanMinimumPwm; + od_max_setting = overdrive_upperlimits->FanMinimumPwm; + break; default: + od_min_setting = od_max_setting = INT_MAX; break; } @@ -1170,6 +1224,9 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, case SMU_DCLK1: single_dpm_table = &(dpm_context->dpm_tables.dclk_table); break; + case SMU_DCEFCLK: + single_dpm_table = &(dpm_context->dpm_tables.dcef_table); + break; default: break; } @@ -1183,6 +1240,7 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, case SMU_VCLK1: case SMU_DCLK: case SMU_DCLK1: + case SMU_DCEFCLK: ret = smu_v13_0_7_get_current_clk_freq_by_table(smu, clk_type, &curr_freq); if (ret) { dev_err(smu->adev->dev, "Failed to get current clock freq!"); @@ -1278,16 +1336,115 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, od_table->OverDriveTable.UclkFmax); break; - case SMU_OD_VDDC_CURVE: + case SMU_OD_VDDGFX_OFFSET: if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) break; - size += sysfs_emit_at(buf, size, "OD_VDDC_CURVE:\n"); - for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) - size += sysfs_emit_at(buf, size, "%d: %dmv\n", + size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n"); + size += sysfs_emit_at(buf, size, "%dmV\n", + od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]); + break; + + case SMU_OD_FAN_CURVE: + if (!smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_FAN_CURVE:\n"); + for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++) + size += sysfs_emit_at(buf, size, "%d: %dC %d%%\n", i, - od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i]); + (int)od_table->OverDriveTable.FanLinearTempPoints[i], + (int)od_table->OverDriveTable.FanLinearPwmPoints[i]); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_TEMP, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "FAN_CURVE(hotspot temp): %uC %uC\n", + min_value, max_value); + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_PWM, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "FAN_CURVE(fan speed): %u%% %u%%\n", + min_value, max_value); + + break; + + case SMU_OD_ACOUSTIC_LIMIT: + if (!smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_LIMIT:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.AcousticLimitRpmThreshold); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "ACOUSTIC_LIMIT: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_ACOUSTIC_TARGET: + if (!smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_TARGET:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.AcousticTargetRpmThreshold); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_TARGET, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "ACOUSTIC_TARGET: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_FAN_TARGET_TEMPERATURE: + if (!smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "FAN_TARGET_TEMPERATURE:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.FanTargetTemperature); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_TARGET_TEMPERATURE, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "TARGET_TEMPERATURE: %u %u\n", + min_value, max_value); + break; + + case SMU_OD_FAN_MINIMUM_PWM: + if (!smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + break; + + size += sysfs_emit_at(buf, size, "FAN_MINIMUM_PWM:\n"); + size += sysfs_emit_at(buf, size, "%d\n", + (int)od_table->OverDriveTable.FanMinimumPwm); + + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_MINIMUM_PWM, + &min_value, + &max_value); + size += sysfs_emit_at(buf, size, "MINIMUM_PWM: %u %u\n", + min_value, max_value); break; case SMU_OD_RANGE: @@ -1300,13 +1457,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", @@ -1315,13 +1470,11 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &min_value, NULL); smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, NULL, &max_value); size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n", @@ -1330,11 +1483,10 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_GFX_VF_CURVE, &min_value, &max_value); - size += sysfs_emit_at(buf, size, "VDDC_CURVE: %7dmv %10dmv\n", + size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n", min_value, max_value); } break; @@ -1346,6 +1498,59 @@ static int smu_v13_0_7_print_clk_levels(struct smu_context *smu, return size; } +static int smu_v13_0_7_od_restore_table_single(struct smu_context *smu, long input) +{ + struct smu_table_context *table_context = &smu->smu_table; + OverDriveTableExternal_t *boot_overdrive_table = + (OverDriveTableExternal_t *)table_context->boot_overdrive_table; + OverDriveTableExternal_t *od_table = + (OverDriveTableExternal_t *)table_context->overdrive_table; + struct amdgpu_device *adev = smu->adev; + int i; + + switch (input) { + case PP_OD_EDIT_FAN_CURVE: + for (i = 0; i < NUM_OD_FAN_MAX_POINTS; i++) { + od_table->OverDriveTable.FanLinearTempPoints[i] = + boot_overdrive_table->OverDriveTable.FanLinearTempPoints[i]; + od_table->OverDriveTable.FanLinearPwmPoints[i] = + boot_overdrive_table->OverDriveTable.FanLinearPwmPoints[i]; + } + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_ACOUSTIC_LIMIT: + od_table->OverDriveTable.AcousticLimitRpmThreshold = + boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_ACOUSTIC_TARGET: + od_table->OverDriveTable.AcousticTargetRpmThreshold = + boot_overdrive_table->OverDriveTable.AcousticTargetRpmThreshold; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_FAN_TARGET_TEMPERATURE: + od_table->OverDriveTable.FanTargetTemperature = + boot_overdrive_table->OverDriveTable.FanTargetTemperature; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + case PP_OD_EDIT_FAN_MINIMUM_PWM: + od_table->OverDriveTable.FanMinimumPwm = + boot_overdrive_table->OverDriveTable.FanMinimumPwm; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + default: + dev_info(adev->dev, "Invalid table index: %ld\n", input); + return -EINVAL; + } + + return 0; +} + static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], @@ -1355,7 +1560,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, OverDriveTableExternal_t *od_table = (OverDriveTableExternal_t *)table_context->overdrive_table; struct amdgpu_device *adev = smu->adev; - uint32_t offset_of_featurectrlmask; + uint32_t offset_of_voltageoffset; int32_t minimum, maximum; uint32_t feature_ctrlmask; int i, ret = 0; @@ -1376,8 +1581,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - true, + PP_OD_FEATURE_GFXCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1393,8 +1597,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFXCLK_BIT, - false, + PP_OD_FEATURE_GFXCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1439,8 +1642,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, switch (input[i]) { case 0: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - true, + PP_OD_FEATURE_UCLK_FMIN, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1456,8 +1658,7 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, case 1: smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_UCLK_BIT, - false, + PP_OD_FEATURE_UCLK_FMAX, &minimum, &maximum); if (input[i + 1] < minimum || @@ -1487,38 +1688,166 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, } break; - case PP_OD_EDIT_VDDC_CURVE: + case PP_OD_EDIT_VDDGFX_OFFSET: if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) { - dev_warn(adev->dev, "VF curve setting not supported!\n"); + dev_warn(adev->dev, "Gfx offset setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_GFX_VF_CURVE, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) + od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0]; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_CURVE: + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); return -ENOTSUPP; } - if (input[0] >= PP_NUM_OD_VF_CURVE_POINTS || + if (input[0] >= NUM_OD_FAN_MAX_POINTS - 1 || input[0] < 0) return -EINVAL; smu_v13_0_7_get_od_setting_limits(smu, - PP_OD_FEATURE_GFX_VF_CURVE_BIT, - true, + PP_OD_FEATURE_FAN_CURVE_TEMP, &minimum, &maximum); if (input[1] < minimum || input[1] > maximum) { - dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n", + dev_info(adev->dev, "Fan curve temp setting(%ld) must be within [%d, %d]!\n", input[1], minimum, maximum); return -EINVAL; } - od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[input[0]] = input[1]; - od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_CURVE_PWM, + &minimum, + &maximum); + if (input[2] < minimum || + input[2] > maximum) { + dev_info(adev->dev, "Fan curve pwm setting(%ld) must be within [%d, %d]!\n", + input[2], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanLinearTempPoints[input[0]] = input[1]; + od_table->OverDriveTable.FanLinearPwmPoints[input[0]] = input[2]; + od_table->OverDriveTable.FanMode = FAN_MODE_MANUAL_LINEAR; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_ACOUSTIC_LIMIT: + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "acoustic limit threshold setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.AcousticLimitRpmThreshold = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_ACOUSTIC_TARGET: + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_ACOUSTIC_TARGET, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "acoustic target threshold setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.AcousticTargetRpmThreshold = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_TARGET_TEMPERATURE: + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_TARGET_TEMPERATURE, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "fan target temperature setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanTargetTemperature = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + break; + + case PP_OD_EDIT_FAN_MINIMUM_PWM: + if (!smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) { + dev_warn(adev->dev, "Fan curve setting not supported!\n"); + return -ENOTSUPP; + } + + smu_v13_0_7_get_od_setting_limits(smu, + PP_OD_FEATURE_FAN_MINIMUM_PWM, + &minimum, + &maximum); + if (input[0] < minimum || + input[0] > maximum) { + dev_info(adev->dev, "fan minimum pwm setting(%ld) must be within [%d, %d]!\n", + input[0], minimum, maximum); + return -EINVAL; + } + + od_table->OverDriveTable.FanMinimumPwm = input[0]; + od_table->OverDriveTable.FanMode = FAN_MODE_AUTO; + od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT); break; case PP_OD_RESTORE_DEFAULT_TABLE: - feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask; - memcpy(od_table, - table_context->boot_overdrive_table, - sizeof(OverDriveTableExternal_t)); - od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask; + if (size == 1) { + ret = smu_v13_0_7_od_restore_table_single(smu, input[0]); + if (ret) + return ret; + } else { + feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask; + memcpy(od_table, + table_context->boot_overdrive_table, + sizeof(OverDriveTableExternal_t)); + od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask; + } fallthrough; case PP_OD_COMMIT_DPM_TABLE: @@ -1529,10 +1858,10 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, * It does not contain actual informations about user's custom * settings. Thus we do not cache it. */ - offset_of_featurectrlmask = offsetof(OverDriveTable_t, FeatureCtrlMask); - if (memcmp((u8 *)od_table + offset_of_featurectrlmask, - table_context->user_overdrive_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask)) { + offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary); + if (memcmp((u8 *)od_table + offset_of_voltageoffset, + table_context->user_overdrive_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) { smu_v13_0_7_dump_od_table(smu, od_table); ret = smu_v13_0_7_upload_overdrive_table(smu, od_table); @@ -1542,9 +1871,9 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu, } od_table->OverDriveTable.FeatureCtrlMask = 0; - memcpy(table_context->user_overdrive_table + offset_of_featurectrlmask, - (u8 *)od_table + offset_of_featurectrlmask, - sizeof(OverDriveTableExternal_t) - offset_of_featurectrlmask); + memcpy(table_context->user_overdrive_table + offset_of_voltageoffset, + (u8 *)od_table + offset_of_voltageoffset, + sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset); if (!memcmp(table_context->user_overdrive_table, table_context->boot_overdrive_table, @@ -1641,8 +1970,7 @@ static int smu_v13_0_7_force_clk_levels(struct smu_context *smu, return ret; } -static const struct smu_temperature_range smu13_thermal_policy[] = -{ +static const struct smu_temperature_range smu13_thermal_policy[] = { {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000}, { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000}, }; @@ -1678,7 +2006,6 @@ static int smu_v13_0_7_get_thermal_temperature_range(struct smu_context *smu, return 0; } -#define MAX(a, b) ((a) > (b) ? (a) : (b)) static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, void **table) { @@ -1702,12 +2029,12 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, gpu_metrics->temperature_mem = metrics->AvgTemperature[TEMP_MEM]; gpu_metrics->temperature_vrgfx = metrics->AvgTemperature[TEMP_VR_GFX]; gpu_metrics->temperature_vrsoc = metrics->AvgTemperature[TEMP_VR_SOC]; - gpu_metrics->temperature_vrmem = MAX(metrics->AvgTemperature[TEMP_VR_MEM0], + gpu_metrics->temperature_vrmem = max(metrics->AvgTemperature[TEMP_VR_MEM0], metrics->AvgTemperature[TEMP_VR_MEM1]); gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity; gpu_metrics->average_umc_activity = metrics->AverageUclkActivity; - gpu_metrics->average_mm_activity = MAX(metrics->Vcn0ActivityPercentage, + gpu_metrics->average_mm_activity = max(metrics->Vcn0ActivityPercentage, metrics->Vcn1ActivityPercentage); gpu_metrics->average_socket_power = metrics->AverageSocketPower; @@ -1743,7 +2070,10 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, gpu_metrics->current_fan_speed = metrics->AvgFanRpm; gpu_metrics->pcie_link_width = metrics->PcieWidth; - gpu_metrics->pcie_link_speed = metrics->PcieRate; + if ((metrics->PcieRate - 1) > LINK_SPEED_MAX) + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1); + else + gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate); gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); @@ -1756,6 +2086,24 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, return sizeof(struct gpu_metrics_v1_3); } +static void smu_v13_0_7_set_supported_od_feature_mask(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + if (smu_v13_0_7_is_od_feature_supported(smu, + PP_OD_FEATURE_FAN_CURVE_BIT)) + adev->pm.od_feature_mask |= OD_OPS_SUPPORT_FAN_CURVE_RETRIEVE | + OD_OPS_SUPPORT_FAN_CURVE_SET | + OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_RETRIEVE | + OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_SET | + OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_RETRIEVE | + OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_SET | + OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE | + OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET | + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE | + OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET; +} + static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu) { OverDriveTableExternal_t *od_table = @@ -1805,8 +2153,24 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu) for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++) user_od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = user_od_table_bak.OverDriveTable.VoltageOffsetPerZoneBoundary[i]; + for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++) { + user_od_table->OverDriveTable.FanLinearTempPoints[i] = + user_od_table_bak.OverDriveTable.FanLinearTempPoints[i]; + user_od_table->OverDriveTable.FanLinearPwmPoints[i] = + user_od_table_bak.OverDriveTable.FanLinearPwmPoints[i]; + } + user_od_table->OverDriveTable.AcousticLimitRpmThreshold = + user_od_table_bak.OverDriveTable.AcousticLimitRpmThreshold; + user_od_table->OverDriveTable.AcousticTargetRpmThreshold = + user_od_table_bak.OverDriveTable.AcousticTargetRpmThreshold; + user_od_table->OverDriveTable.FanTargetTemperature = + user_od_table_bak.OverDriveTable.FanTargetTemperature; + user_od_table->OverDriveTable.FanMinimumPwm = + user_od_table_bak.OverDriveTable.FanMinimumPwm; } + smu_v13_0_7_set_supported_od_feature_mask(smu); + return 0; } @@ -1817,9 +2181,10 @@ static int smu_v13_0_7_restore_user_od_settings(struct smu_context *smu) OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table; int res; - user_od_table->OverDriveTable.FeatureCtrlMask = 1U << PP_OD_FEATURE_GFXCLK_BIT | - 1U << PP_OD_FEATURE_UCLK_BIT | - 1U << PP_OD_FEATURE_GFX_VF_CURVE_BIT; + user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | + BIT(PP_OD_FEATURE_UCLK_BIT) | + BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | + BIT(PP_OD_FEATURE_FAN_CURVE_BIT); res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table); user_od_table->OverDriveTable.FeatureCtrlMask = 0; if (res == 0) @@ -1904,7 +2269,7 @@ static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu, } /* Convert the PMFW output which is in percent to pwm(255) based */ - *speed = MIN(*speed * 255 / 100, 255); + *speed = min(*speed * 255 / 100, (uint32_t)255); return 0; } @@ -1940,16 +2305,17 @@ static int smu_v13_0_7_enable_mgpu_fan_boost(struct smu_context *smu) } static int smu_v13_0_7_get_power_limit(struct smu_context *smu, - uint32_t *current_power_limit, - uint32_t *default_power_limit, - uint32_t *max_power_limit) + uint32_t *current_power_limit, + uint32_t *default_power_limit, + uint32_t *max_power_limit, + uint32_t *min_power_limit) { struct smu_table_context *table_context = &smu->smu_table; struct smu_13_0_7_powerplay_table *powerplay_table = (struct smu_13_0_7_powerplay_table *)table_context->power_play_table; PPTable_t *pptable = table_context->driver_pptable; SkuTable_t *skutable = &pptable->SkuTable; - uint32_t power_limit, od_percent; + uint32_t power_limit, od_percent_upper, od_percent_lower; if (smu_v13_0_get_current_power_limit(smu, &power_limit)) power_limit = smu->adev->pm.ac_power ? @@ -1961,16 +2327,25 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, if (default_power_limit) *default_power_limit = power_limit; - if (max_power_limit) { - if (smu->od_enabled) { - od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + if (smu->od_enabled) { + od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]); + } else { + od_percent_upper = 0; + od_percent_lower = 100; + } - dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); + dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n", + od_percent_upper, od_percent_lower, power_limit); - power_limit *= (100 + od_percent); - power_limit /= 100; - } - *max_power_limit = power_limit; + if (max_power_limit) { + *max_power_limit = power_limit * (100 + od_percent_upper); + *max_power_limit /= 100; + } + + if (min_power_limit) { + *min_power_limit = power_limit * (100 - od_percent_lower); + *min_power_limit /= 100; } return 0; @@ -2124,7 +2499,13 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu, switch (mp1_state) { case PP_MP1_STATE_UNLOAD: - ret = smu_cmn_set_mp1_state(smu, mp1_state); + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_PrepareMp1ForUnload, + 0x55, NULL); + + if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) + ret = smu_v13_0_disable_pmfw_state(smu); + break; default: /* Ignore others */ @@ -2141,7 +2522,8 @@ static int smu_v13_0_7_baco_enter(struct smu_context *smu) if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) return smu_v13_0_baco_set_armd3_sequence(smu, - smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); + (smu_baco->maco_support && amdgpu_runtime_pm != 1) ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO); else return smu_v13_0_baco_enter(smu); } @@ -2149,14 +2531,20 @@ static int smu_v13_0_7_baco_enter(struct smu_context *smu) static int smu_v13_0_7_baco_exit(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; + int ret; if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { /* Wait for PMFW handling for the Dstate change */ usleep_range(10000, 11000); - return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); + ret = smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); } else { - return smu_v13_0_baco_exit(smu); + ret = smu_v13_0_baco_exit(smu); } + + if (!ret) + adev->gfx.is_poweron = false; + + return ret; } static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index a1be2029ba4a..2d1736234b4a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -365,7 +365,7 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu, case METRICS_AVERAGE_VCNACTIVITY: *value = metrics->UvdActivity; break; - case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: @@ -423,9 +423,9 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; - case AMDGPU_PP_SENSOR_GPU_POWER: + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: ret = yellow_carp_get_smu_metrics_data(smu, - METRICS_AVERAGE_SOCKETPOWER, + METRICS_CURR_SOCKETPOWER, (uint32_t *)data); *size = 4; break; @@ -479,6 +479,7 @@ static int yellow_carp_read_sensor(struct smu_context *smu, (uint32_t *)data); *size = 4; break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: default: ret = -EOPNOTSUPP; break; @@ -1023,24 +1024,24 @@ static uint32_t yellow_carp_get_umd_pstate_clk_default(struct smu_context *smu, switch (clk_type) { case SMU_GFXCLK: case SMU_SCLK: - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 8)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 8)) clk_limit = SMU_13_0_8_UMD_PSTATE_GFXCLK; - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 1) || - (adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 3)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 1) || + (amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 3)) clk_limit = SMU_13_0_1_UMD_PSTATE_GFXCLK; break; case SMU_SOCCLK: - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 8)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 8)) clk_limit = SMU_13_0_8_UMD_PSTATE_SOCCLK; - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 1) || - (adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 3)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 1) || + (amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 3)) clk_limit = SMU_13_0_1_UMD_PSTATE_SOCCLK; break; case SMU_FCLK: - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 8)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 8)) clk_limit = SMU_13_0_8_UMD_PSTATE_FCLK; - if ((adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 1) || - (adev->ip_versions[MP1_HWIP][0]) == IP_VERSION(13, 0, 3)) + if ((amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 1) || + (amdgpu_ip_version(adev, MP1_HWIP, 0)) == IP_VERSION(13, 0, 3)) clk_limit = SMU_13_0_1_UMD_PSTATE_FCLK; break; default: diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/Makefile b/drivers/gpu/drm/amd/pm/swsmu/smu14/Makefile new file mode 100644 index 000000000000..ddbac5c655f7 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/Makefile @@ -0,0 +1,30 @@ +# +# Copyright 2023 Advanced Micro Devices, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +# +# Makefile for the 'smu manager' sub-component of powerplay. +# It provides the smu management services for the driver. + +SMU14_MGR = smu_v14_0.o smu_v14_0_0_ppt.o + +AMD_SWSMU_SMU14MGR = $(addprefix $(AMD_SWSMU_PATH)/smu14/,$(SMU14_MGR)) + +AMD_POWERPLAY_FILES += $(AMD_SWSMU_SMU14MGR) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c new file mode 100644 index 000000000000..d8f8ad0e7137 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c @@ -0,0 +1,1729 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <linux/firmware.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/reboot.h> + +#define SWSMU_CODE_LAYER_L3 + +#include "amdgpu.h" +#include "amdgpu_smu.h" +#include "atomfirmware.h" +#include "amdgpu_atomfirmware.h" +#include "amdgpu_atombios.h" +#include "smu_v14_0.h" +#include "soc15_common.h" +#include "atom.h" +#include "amdgpu_ras.h" +#include "smu_cmn.h" + +#include "asic_reg/mp/mp_14_0_0_offset.h" +#include "asic_reg/mp/mp_14_0_0_sh_mask.h" + +/* + * DO NOT use these for err/warn/info/debug messages. + * Use dev_err, dev_warn, dev_info and dev_dbg instead. + * They are more MGPU friendly. + */ +#undef pr_err +#undef pr_warn +#undef pr_info +#undef pr_debug + +MODULE_FIRMWARE("amdgpu/smu_14_0_2.bin"); + +int smu_v14_0_init_microcode(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + char fw_name[30]; + char ucode_prefix[15]; + int err = 0; + const struct smc_firmware_header_v1_0 *hdr; + const struct common_firmware_header *header; + struct amdgpu_firmware_info *ucode = NULL; + + /* doesn't need to load smu firmware in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + err = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (err) + goto out; + + hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(&hdr->header); + adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version); + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC]; + ucode->ucode_id = AMDGPU_UCODE_ID_SMC; + ucode->fw = adev->pm.fw; + header = (const struct common_firmware_header *)ucode->fw->data; + adev->firmware.fw_size += + ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE); + } + +out: + if (err) + amdgpu_ucode_release(&adev->pm.fw); + return err; +} + +void smu_v14_0_fini_microcode(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + amdgpu_ucode_release(&adev->pm.fw); + adev->pm.fw_version = 0; +} + +int smu_v14_0_load_microcode(struct smu_context *smu) +{ +#if 0 + struct amdgpu_device *adev = smu->adev; + const uint32_t *src; + const struct smc_firmware_header_v1_0 *hdr; + uint32_t addr_start = MP1_SRAM; + uint32_t i; + uint32_t smc_fw_size; + uint32_t mp1_fw_flags; + + hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; + src = (const uint32_t *)(adev->pm.fw->data + + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); + smc_fw_size = hdr->header.ucode_size_bytes; + + for (i = 1; i < smc_fw_size/4 - 1; i++) { + WREG32_PCIE(addr_start, src[i]); + addr_start += 4; + } + + WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff), + 1 & MP1_SMN_PUB_CTRL__LX3_RESET_MASK); + WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff), + 1 & ~MP1_SMN_PUB_CTRL__LX3_RESET_MASK); + + for (i = 0; i < adev->usec_timeout; i++) { + mp1_fw_flags = RREG32_PCIE(MP1_Public | + (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); + if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> + MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) + break; + udelay(1); + } + + if (i == adev->usec_timeout) + return -ETIME; + +#endif + return 0; + +} + +int smu_v14_0_init_pptable_microcode(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + struct amdgpu_firmware_info *ucode = NULL; + uint32_t size = 0, pptable_id = 0; + int ret = 0; + void *table; + + /* doesn't need to load smu firmware in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) + return 0; + + if (!adev->scpm_enabled) + return 0; + + /* override pptable_id from driver parameter */ + if (amdgpu_smu_pptable_id >= 0) { + pptable_id = amdgpu_smu_pptable_id; + dev_info(adev->dev, "override pptable id %d\n", pptable_id); + } else { + pptable_id = smu->smu_table.boot_values.pp_table_id; + } + + /* "pptable_id == 0" means vbios carries the pptable. */ + if (!pptable_id) + return 0; + + ret = smu_v14_0_get_pptable_from_firmware(smu, &table, &size, pptable_id); + if (ret) + return ret; + + smu->pptable_firmware.data = table; + smu->pptable_firmware.size = size; + + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_PPTABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_PPTABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += + ALIGN(smu->pptable_firmware.size, PAGE_SIZE); + + return 0; +} + +int smu_v14_0_check_fw_status(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t mp1_fw_flags; + + mp1_fw_flags = RREG32_PCIE(MP1_Public | + (smnMP1_FIRMWARE_FLAGS & 0xffffffff)); + + if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >> + MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT) + return 0; + + return -EIO; +} + +int smu_v14_0_check_fw_version(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t if_version = 0xff, smu_version = 0xff; + uint8_t smu_program, smu_major, smu_minor, smu_debug; + int ret = 0; + + ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version); + if (ret) + return ret; + + smu_program = (smu_version >> 24) & 0xff; + smu_major = (smu_version >> 16) & 0xff; + smu_minor = (smu_version >> 8) & 0xff; + smu_debug = (smu_version >> 0) & 0xff; + if (smu->is_apu) + adev->pm.fw_version = smu_version; + + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(14, 0, 2): + smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_2; + break; + case IP_VERSION(14, 0, 0): + if ((smu->smc_fw_version < 0x5d3a00)) + dev_warn(smu->adev->dev, "The PMFW version(%x) is behind in this BIOS!\n", smu->smc_fw_version); + smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0; + break; + default: + dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n", + adev->ip_versions[MP1_HWIP][0]); + smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_INV; + break; + } + + if (adev->pm.fw) + dev_dbg(smu->adev->dev, "smu fw reported program %d, version = 0x%08x (%d.%d.%d)\n", + smu_program, smu_version, smu_major, smu_minor, smu_debug); + + /* + * 1. if_version mismatch is not critical as our fw is designed + * to be backward compatible. + * 2. New fw usually brings some optimizations. But that's visible + * only on the paired driver. + * Considering above, we just leave user a verbal message instead + * of halt driver loading. + */ + if (if_version != smu->smc_driver_if_version) { + dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, " + "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n", + smu->smc_driver_if_version, if_version, + smu_program, smu_version, smu_major, smu_minor, smu_debug); + dev_info(adev->dev, "SMU driver if version not matched\n"); + } + + return ret; +} + +static int smu_v14_0_set_pptable_v2_0(struct smu_context *smu, void **table, uint32_t *size) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t ppt_offset_bytes; + const struct smc_firmware_header_v2_0 *v2; + + v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data; + + ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes); + *size = le32_to_cpu(v2->ppt_size_bytes); + *table = (uint8_t *)v2 + ppt_offset_bytes; + + return 0; +} + +static int smu_v14_0_set_pptable_v2_1(struct smu_context *smu, void **table, + uint32_t *size, uint32_t pptable_id) +{ + struct amdgpu_device *adev = smu->adev; + const struct smc_firmware_header_v2_1 *v2_1; + struct smc_soft_pptable_entry *entries; + uint32_t pptable_count = 0; + int i = 0; + + v2_1 = (const struct smc_firmware_header_v2_1 *) adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry *) + ((uint8_t *)v2_1 + le32_to_cpu(v2_1->pptable_entry_offset)); + pptable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < pptable_count; i++) { + if (le32_to_cpu(entries[i].id) == pptable_id) { + *table = ((uint8_t *)v2_1 + le32_to_cpu(entries[i].ppt_offset_bytes)); + *size = le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (i == pptable_count) + return -EINVAL; + + return 0; +} + +static int smu_v14_0_get_pptable_from_vbios(struct smu_context *smu, void **table, uint32_t *size) +{ + struct amdgpu_device *adev = smu->adev; + uint16_t atom_table_size; + uint8_t frev, crev; + int ret, index; + + dev_info(adev->dev, "use vbios provided pptable\n"); + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + powerplayinfo); + + ret = amdgpu_atombios_get_data_table(adev, index, &atom_table_size, &frev, &crev, + (uint8_t **)table); + if (ret) + return ret; + + if (size) + *size = atom_table_size; + + return 0; +} + +int smu_v14_0_get_pptable_from_firmware(struct smu_context *smu, + void **table, + uint32_t *size, + uint32_t pptable_id) +{ + const struct smc_firmware_header_v1_0 *hdr; + struct amdgpu_device *adev = smu->adev; + uint16_t version_major, version_minor; + int ret; + + hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data; + if (!hdr) + return -EINVAL; + + dev_info(adev->dev, "use driver provided pptable %d\n", pptable_id); + + version_major = le16_to_cpu(hdr->header.header_version_major); + version_minor = le16_to_cpu(hdr->header.header_version_minor); + if (version_major != 2) { + dev_err(adev->dev, "Unsupported smu firmware version %d.%d\n", + version_major, version_minor); + return -EINVAL; + } + + switch (version_minor) { + case 0: + ret = smu_v14_0_set_pptable_v2_0(smu, table, size); + break; + case 1: + ret = smu_v14_0_set_pptable_v2_1(smu, table, size, pptable_id); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +int smu_v14_0_setup_pptable(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t size = 0, pptable_id = 0; + void *table; + int ret = 0; + + /* override pptable_id from driver parameter */ + if (amdgpu_smu_pptable_id >= 0) { + pptable_id = amdgpu_smu_pptable_id; + dev_info(adev->dev, "override pptable id %d\n", pptable_id); + } else { + pptable_id = smu->smu_table.boot_values.pp_table_id; + } + + /* force using vbios pptable in sriov mode */ + if ((amdgpu_sriov_vf(adev) || !pptable_id) && (amdgpu_emu_mode != 1)) + ret = smu_v14_0_get_pptable_from_vbios(smu, &table, &size); + else + ret = smu_v14_0_get_pptable_from_firmware(smu, &table, &size, pptable_id); + + if (ret) + return ret; + + if (!smu->smu_table.power_play_table) + smu->smu_table.power_play_table = table; + if (!smu->smu_table.power_play_table_size) + smu->smu_table.power_play_table_size = size; + + return 0; +} + +int smu_v14_0_init_smc_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct smu_table *tables = smu_table->tables; + int ret = 0; + + smu_table->driver_pptable = + kzalloc(tables[SMU_TABLE_PPTABLE].size, GFP_KERNEL); + if (!smu_table->driver_pptable) { + ret = -ENOMEM; + goto err0_out; + } + + smu_table->max_sustainable_clocks = + kzalloc(sizeof(struct smu_14_0_max_sustainable_clocks), GFP_KERNEL); + if (!smu_table->max_sustainable_clocks) { + ret = -ENOMEM; + goto err1_out; + } + + if (tables[SMU_TABLE_OVERDRIVE].size) { + smu_table->overdrive_table = + kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL); + if (!smu_table->overdrive_table) { + ret = -ENOMEM; + goto err2_out; + } + + smu_table->boot_overdrive_table = + kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL); + if (!smu_table->boot_overdrive_table) { + ret = -ENOMEM; + goto err3_out; + } + } + + smu_table->combo_pptable = + kzalloc(tables[SMU_TABLE_COMBO_PPTABLE].size, GFP_KERNEL); + if (!smu_table->combo_pptable) { + ret = -ENOMEM; + goto err4_out; + } + + return 0; + +err4_out: + kfree(smu_table->boot_overdrive_table); +err3_out: + kfree(smu_table->overdrive_table); +err2_out: + kfree(smu_table->max_sustainable_clocks); +err1_out: + kfree(smu_table->driver_pptable); +err0_out: + return ret; +} + +int smu_v14_0_fini_smc_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct smu_dpm_context *smu_dpm = &smu->smu_dpm; + + kfree(smu_table->gpu_metrics_table); + kfree(smu_table->combo_pptable); + kfree(smu_table->boot_overdrive_table); + kfree(smu_table->overdrive_table); + kfree(smu_table->max_sustainable_clocks); + kfree(smu_table->driver_pptable); + smu_table->gpu_metrics_table = NULL; + smu_table->combo_pptable = NULL; + smu_table->boot_overdrive_table = NULL; + smu_table->overdrive_table = NULL; + smu_table->max_sustainable_clocks = NULL; + smu_table->driver_pptable = NULL; + kfree(smu_table->hardcode_pptable); + smu_table->hardcode_pptable = NULL; + + kfree(smu_table->ecc_table); + kfree(smu_table->metrics_table); + kfree(smu_table->watermarks_table); + smu_table->ecc_table = NULL; + smu_table->metrics_table = NULL; + smu_table->watermarks_table = NULL; + smu_table->metrics_time = 0; + + kfree(smu_dpm->dpm_context); + kfree(smu_dpm->golden_dpm_context); + kfree(smu_dpm->dpm_current_power_state); + kfree(smu_dpm->dpm_request_power_state); + smu_dpm->dpm_context = NULL; + smu_dpm->golden_dpm_context = NULL; + smu_dpm->dpm_context_size = 0; + smu_dpm->dpm_current_power_state = NULL; + smu_dpm->dpm_request_power_state = NULL; + + return 0; +} + +int smu_v14_0_init_power(struct smu_context *smu) +{ + struct smu_power_context *smu_power = &smu->smu_power; + + if (smu_power->power_context || smu_power->power_context_size != 0) + return -EINVAL; + + smu_power->power_context = kzalloc(sizeof(struct smu_14_0_dpm_context), + GFP_KERNEL); + if (!smu_power->power_context) + return -ENOMEM; + smu_power->power_context_size = sizeof(struct smu_14_0_dpm_context); + + return 0; +} + +int smu_v14_0_fini_power(struct smu_context *smu) +{ + struct smu_power_context *smu_power = &smu->smu_power; + + if (!smu_power->power_context || smu_power->power_context_size == 0) + return -EINVAL; + + kfree(smu_power->power_context); + smu_power->power_context = NULL; + smu_power->power_context_size = 0; + + return 0; +} + +int smu_v14_0_get_vbios_bootup_values(struct smu_context *smu) +{ + int ret, index; + uint16_t size; + uint8_t frev, crev; + struct atom_common_table_header *header; + struct atom_firmware_info_v3_4 *v_3_4; + struct atom_firmware_info_v3_3 *v_3_3; + struct atom_firmware_info_v3_1 *v_3_1; + struct atom_smu_info_v3_6 *smu_info_v3_6; + struct atom_smu_info_v4_0 *smu_info_v4_0; + + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + firmwareinfo); + + ret = amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev, + (uint8_t **)&header); + if (ret) + return ret; + + if (header->format_revision != 3) { + dev_err(smu->adev->dev, "unknown atom_firmware_info version! for smu14\n"); + return -EINVAL; + } + + switch (header->content_revision) { + case 0: + case 1: + case 2: + v_3_1 = (struct atom_firmware_info_v3_1 *)header; + smu->smu_table.boot_values.revision = v_3_1->firmware_revision; + smu->smu_table.boot_values.gfxclk = v_3_1->bootup_sclk_in10khz; + smu->smu_table.boot_values.uclk = v_3_1->bootup_mclk_in10khz; + smu->smu_table.boot_values.socclk = 0; + smu->smu_table.boot_values.dcefclk = 0; + smu->smu_table.boot_values.vddc = v_3_1->bootup_vddc_mv; + smu->smu_table.boot_values.vddci = v_3_1->bootup_vddci_mv; + smu->smu_table.boot_values.mvddc = v_3_1->bootup_mvddc_mv; + smu->smu_table.boot_values.vdd_gfx = v_3_1->bootup_vddgfx_mv; + smu->smu_table.boot_values.cooling_id = v_3_1->coolingsolution_id; + smu->smu_table.boot_values.pp_table_id = 0; + break; + case 3: + v_3_3 = (struct atom_firmware_info_v3_3 *)header; + smu->smu_table.boot_values.revision = v_3_3->firmware_revision; + smu->smu_table.boot_values.gfxclk = v_3_3->bootup_sclk_in10khz; + smu->smu_table.boot_values.uclk = v_3_3->bootup_mclk_in10khz; + smu->smu_table.boot_values.socclk = 0; + smu->smu_table.boot_values.dcefclk = 0; + smu->smu_table.boot_values.vddc = v_3_3->bootup_vddc_mv; + smu->smu_table.boot_values.vddci = v_3_3->bootup_vddci_mv; + smu->smu_table.boot_values.mvddc = v_3_3->bootup_mvddc_mv; + smu->smu_table.boot_values.vdd_gfx = v_3_3->bootup_vddgfx_mv; + smu->smu_table.boot_values.cooling_id = v_3_3->coolingsolution_id; + smu->smu_table.boot_values.pp_table_id = v_3_3->pplib_pptable_id; + break; + case 4: + default: + v_3_4 = (struct atom_firmware_info_v3_4 *)header; + smu->smu_table.boot_values.revision = v_3_4->firmware_revision; + smu->smu_table.boot_values.gfxclk = v_3_4->bootup_sclk_in10khz; + smu->smu_table.boot_values.uclk = v_3_4->bootup_mclk_in10khz; + smu->smu_table.boot_values.socclk = 0; + smu->smu_table.boot_values.dcefclk = 0; + smu->smu_table.boot_values.vddc = v_3_4->bootup_vddc_mv; + smu->smu_table.boot_values.vddci = v_3_4->bootup_vddci_mv; + smu->smu_table.boot_values.mvddc = v_3_4->bootup_mvddc_mv; + smu->smu_table.boot_values.vdd_gfx = v_3_4->bootup_vddgfx_mv; + smu->smu_table.boot_values.cooling_id = v_3_4->coolingsolution_id; + smu->smu_table.boot_values.pp_table_id = v_3_4->pplib_pptable_id; + break; + } + + smu->smu_table.boot_values.format_revision = header->format_revision; + smu->smu_table.boot_values.content_revision = header->content_revision; + + index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, + smu_info); + if (!amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev, + (uint8_t **)&header)) { + + if ((frev == 3) && (crev == 6)) { + smu_info_v3_6 = (struct atom_smu_info_v3_6 *)header; + + smu->smu_table.boot_values.socclk = smu_info_v3_6->bootup_socclk_10khz; + smu->smu_table.boot_values.vclk = smu_info_v3_6->bootup_vclk_10khz; + smu->smu_table.boot_values.dclk = smu_info_v3_6->bootup_dclk_10khz; + smu->smu_table.boot_values.fclk = smu_info_v3_6->bootup_fclk_10khz; + } else if ((frev == 3) && (crev == 1)) { + return 0; + } else if ((frev == 4) && (crev == 0)) { + smu_info_v4_0 = (struct atom_smu_info_v4_0 *)header; + + smu->smu_table.boot_values.socclk = smu_info_v4_0->bootup_socclk_10khz; + smu->smu_table.boot_values.dcefclk = smu_info_v4_0->bootup_dcefclk_10khz; + smu->smu_table.boot_values.vclk = smu_info_v4_0->bootup_vclk0_10khz; + smu->smu_table.boot_values.dclk = smu_info_v4_0->bootup_dclk0_10khz; + smu->smu_table.boot_values.fclk = smu_info_v4_0->bootup_fclk_10khz; + } else { + dev_warn(smu->adev->dev, "Unexpected and unhandled version: %d.%d\n", + (uint32_t)frev, (uint32_t)crev); + } + } + + return 0; +} + + +int smu_v14_0_notify_memory_pool_location(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct smu_table *memory_pool = &smu_table->memory_pool; + int ret = 0; + uint64_t address; + uint32_t address_low, address_high; + + if (memory_pool->size == 0 || memory_pool->cpu_addr == NULL) + return ret; + + address = memory_pool->mc_address; + address_high = (uint32_t)upper_32_bits(address); + address_low = (uint32_t)lower_32_bits(address); + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrHigh, + address_high, NULL); + if (ret) + return ret; + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrLow, + address_low, NULL); + if (ret) + return ret; + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramSize, + (uint32_t)memory_pool->size, NULL); + if (ret) + return ret; + + return ret; +} + +int smu_v14_0_set_driver_table_location(struct smu_context *smu) +{ + struct smu_table *driver_table = &smu->smu_table.driver_table; + int ret = 0; + + if (driver_table->mc_address) { + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetDriverDramAddrHigh, + upper_32_bits(driver_table->mc_address), + NULL); + if (!ret) + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetDriverDramAddrLow, + lower_32_bits(driver_table->mc_address), + NULL); + } + + return ret; +} + +int smu_v14_0_set_tool_table_location(struct smu_context *smu) +{ + int ret = 0; + struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG]; + + if (tool_table->mc_address) { + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetToolsDramAddrHigh, + upper_32_bits(tool_table->mc_address), + NULL); + if (!ret) + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetToolsDramAddrLow, + lower_32_bits(tool_table->mc_address), + NULL); + } + + return ret; +} + +int smu_v14_0_set_allowed_mask(struct smu_context *smu) +{ + struct smu_feature *feature = &smu->smu_feature; + int ret = 0; + uint32_t feature_mask[2]; + + if (bitmap_empty(feature->allowed, SMU_FEATURE_MAX) || + feature->feature_num < 64) + return -EINVAL; + + bitmap_to_arr32(feature_mask, feature->allowed, 64); + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetAllowedFeaturesMaskHigh, + feature_mask[1], NULL); + if (ret) + return ret; + + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_SetAllowedFeaturesMaskLow, + feature_mask[0], + NULL); +} + +int smu_v14_0_gfx_off_control(struct smu_context *smu, bool enable) +{ + int ret = 0; + struct amdgpu_device *adev = smu->adev; + + switch (adev->ip_versions[MP1_HWIP][0]) { + case IP_VERSION(14, 0, 2): + case IP_VERSION(14, 0, 0): + if (!(adev->pm.pp_feature & PP_GFXOFF_MASK)) + return 0; + if (enable) + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL); + else + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL); + break; + default: + break; + } + + return ret; +} + +int smu_v14_0_system_features_control(struct smu_context *smu, + bool en) +{ + return smu_cmn_send_smc_msg(smu, (en ? SMU_MSG_EnableAllSmuFeatures : + SMU_MSG_DisableAllSmuFeatures), NULL); +} + +int smu_v14_0_notify_display_change(struct smu_context *smu) +{ + int ret = 0; + + if (!smu->pm_enabled) + return ret; + + if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) && + smu->adev->gmc.vram_type == AMDGPU_VRAM_TYPE_HBM) + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1, NULL); + + return ret; +} + +int smu_v14_0_get_current_power_limit(struct smu_context *smu, + uint32_t *power_limit) +{ + int power_src; + int ret = 0; + + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) + return -EINVAL; + + power_src = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_PWR, + smu->adev->pm.ac_power ? + SMU_POWER_SOURCE_AC : + SMU_POWER_SOURCE_DC); + if (power_src < 0) + return -EINVAL; + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GetPptLimit, + power_src << 16, + power_limit); + if (ret) + dev_err(smu->adev->dev, "[%s] get PPT limit failed!", __func__); + + return ret; +} + +int smu_v14_0_set_power_limit(struct smu_context *smu, + enum smu_ppt_limit_type limit_type, + uint32_t limit) +{ + int ret = 0; + + if (limit_type != SMU_DEFAULT_PPT_LIMIT) + return -EINVAL; + + if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) { + dev_err(smu->adev->dev, "Setting new power limit is not supported!\n"); + return -EOPNOTSUPP; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit, NULL); + if (ret) { + dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__); + return ret; + } + + smu->current_power_limit = limit; + + return 0; +} + +static int smu_v14_0_set_irq_state(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + unsigned tyep, + enum amdgpu_interrupt_state state) +{ + uint32_t val = 0; + + switch (state) { + case AMDGPU_IRQ_STATE_DISABLE: + /* For THM irqs */ + // TODO + + /* For MP1 SW irqs */ + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1); + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); + + break; + case AMDGPU_IRQ_STATE_ENABLE: + /* For THM irqs */ + // TODO + + /* For MP1 SW irqs */ + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT); + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE); + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0); + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val); + + val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL); + val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0); + WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val); + + break; + default: + break; + } + + return 0; +} + +static int smu_v14_0_irq_process(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry) +{ + // TODO + + return 0; +} + +static const struct amdgpu_irq_src_funcs smu_v14_0_irq_funcs = { + .set = smu_v14_0_set_irq_state, + .process = smu_v14_0_irq_process, +}; + +int smu_v14_0_register_irq_handler(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + struct amdgpu_irq_src *irq_src = &smu->irq_source; + int ret = 0; + + if (amdgpu_sriov_vf(adev)) + return 0; + + irq_src->num_types = 1; + irq_src->funcs = &smu_v14_0_irq_funcs; + + // TODO: THM related + + ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_MP1, + 0xfe, + irq_src); + if (ret) + return ret; + + return ret; +} + +static int smu_v14_0_wait_for_reset_complete(struct smu_context *smu, + uint64_t event_arg) +{ + int ret = 0; + + dev_dbg(smu->adev->dev, "waiting for smu reset complete\n"); + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GfxDriverResetRecovery, NULL); + + return ret; +} + +int smu_v14_0_wait_for_event(struct smu_context *smu, enum smu_event_type event, + uint64_t event_arg) +{ + int ret = -EINVAL; + + switch (event) { + case SMU_EVENT_RESET_COMPLETE: + ret = smu_v14_0_wait_for_reset_complete(smu, event_arg); + break; + default: + break; + } + + return ret; +} + +int smu_v14_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, + uint32_t *min, uint32_t *max) +{ + int ret = 0, clk_id = 0; + uint32_t param = 0; + uint32_t clock_limit; + + if (!smu_cmn_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_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; + } + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); + if (clk_id < 0) { + ret = -EINVAL; + goto failed; + } + param = (clk_id & 0xffff) << 16; + + if (max) { + if (smu->adev->pm.ac_power) + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GetMaxDpmFreq, + param, + max); + else + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GetDcModeMaxDpmFreq, + param, + max); + if (ret) + goto failed; + } + + if (min) { + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param, min); + if (ret) + goto failed; + } + +failed: + return ret; +} + +int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t min, + uint32_t max) +{ + int ret = 0, clk_id = 0; + uint32_t param; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) + return 0; + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); + if (clk_id < 0) + return clk_id; + + if (max > 0) { + param = (uint32_t)((clk_id << 16) | (max & 0xffff)); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq, + param, NULL); + if (ret) + goto out; + } + + if (min > 0) { + param = (uint32_t)((clk_id << 16) | (min & 0xffff)); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq, + param, NULL); + if (ret) + goto out; + } + +out: + return ret; +} + +int smu_v14_0_set_hard_freq_limited_range(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t min, + uint32_t max) +{ + int ret = 0, clk_id = 0; + uint32_t param; + + if (min <= 0 && max <= 0) + return -EINVAL; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) + return 0; + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); + if (clk_id < 0) + return clk_id; + + if (max > 0) { + param = (uint32_t)((clk_id << 16) | (max & 0xffff)); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMaxByFreq, + param, NULL); + if (ret) + return ret; + } + + if (min > 0) { + param = (uint32_t)((clk_id << 16) | (min & 0xffff)); + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq, + param, NULL); + if (ret) + return ret; + } + + return ret; +} + +int smu_v14_0_set_performance_level(struct smu_context *smu, + enum amd_dpm_forced_level level) +{ + struct smu_14_0_dpm_context *dpm_context = + smu->smu_dpm.dpm_context; + struct smu_14_0_dpm_table *gfx_table = + &dpm_context->dpm_tables.gfx_table; + struct smu_14_0_dpm_table *mem_table = + &dpm_context->dpm_tables.uclk_table; + struct smu_14_0_dpm_table *soc_table = + &dpm_context->dpm_tables.soc_table; + struct smu_14_0_dpm_table *vclk_table = + &dpm_context->dpm_tables.vclk_table; + struct smu_14_0_dpm_table *dclk_table = + &dpm_context->dpm_tables.dclk_table; + struct smu_14_0_dpm_table *fclk_table = + &dpm_context->dpm_tables.fclk_table; + struct smu_umd_pstate_table *pstate_table = + &smu->pstate_table; + struct amdgpu_device *adev = smu->adev; + uint32_t sclk_min = 0, sclk_max = 0; + uint32_t mclk_min = 0, mclk_max = 0; + uint32_t socclk_min = 0, socclk_max = 0; + uint32_t vclk_min = 0, vclk_max = 0; + uint32_t dclk_min = 0, dclk_max = 0; + uint32_t fclk_min = 0, fclk_max = 0; + int ret = 0, i; + + switch (level) { + case AMD_DPM_FORCED_LEVEL_HIGH: + sclk_min = sclk_max = gfx_table->max; + mclk_min = mclk_max = mem_table->max; + socclk_min = socclk_max = soc_table->max; + vclk_min = vclk_max = vclk_table->max; + dclk_min = dclk_max = dclk_table->max; + fclk_min = fclk_max = fclk_table->max; + break; + case AMD_DPM_FORCED_LEVEL_LOW: + sclk_min = sclk_max = gfx_table->min; + mclk_min = mclk_max = mem_table->min; + socclk_min = socclk_max = soc_table->min; + vclk_min = vclk_max = vclk_table->min; + dclk_min = dclk_max = dclk_table->min; + fclk_min = fclk_max = fclk_table->min; + break; + case AMD_DPM_FORCED_LEVEL_AUTO: + sclk_min = gfx_table->min; + sclk_max = gfx_table->max; + mclk_min = mem_table->min; + mclk_max = mem_table->max; + socclk_min = soc_table->min; + socclk_max = soc_table->max; + vclk_min = vclk_table->min; + vclk_max = vclk_table->max; + dclk_min = dclk_table->min; + dclk_max = dclk_table->max; + fclk_min = fclk_table->min; + fclk_max = fclk_table->max; + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: + sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard; + mclk_min = mclk_max = pstate_table->uclk_pstate.standard; + socclk_min = socclk_max = pstate_table->socclk_pstate.standard; + vclk_min = vclk_max = pstate_table->vclk_pstate.standard; + dclk_min = dclk_max = pstate_table->dclk_pstate.standard; + fclk_min = fclk_max = pstate_table->fclk_pstate.standard; + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: + sclk_min = sclk_max = pstate_table->gfxclk_pstate.min; + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: + mclk_min = mclk_max = pstate_table->uclk_pstate.min; + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: + sclk_min = sclk_max = pstate_table->gfxclk_pstate.peak; + mclk_min = mclk_max = pstate_table->uclk_pstate.peak; + socclk_min = socclk_max = pstate_table->socclk_pstate.peak; + vclk_min = vclk_max = pstate_table->vclk_pstate.peak; + dclk_min = dclk_max = pstate_table->dclk_pstate.peak; + fclk_min = fclk_max = pstate_table->fclk_pstate.peak; + break; + case AMD_DPM_FORCED_LEVEL_MANUAL: + case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: + return 0; + default: + dev_err(adev->dev, "Invalid performance level %d\n", level); + return -EINVAL; + } + + if (sclk_min && sclk_max) { + ret = smu_v14_0_set_soft_freq_limited_range(smu, + SMU_GFXCLK, + sclk_min, + sclk_max); + if (ret) + return ret; + + pstate_table->gfxclk_pstate.curr.min = sclk_min; + pstate_table->gfxclk_pstate.curr.max = sclk_max; + } + + if (mclk_min && mclk_max) { + ret = smu_v14_0_set_soft_freq_limited_range(smu, + SMU_MCLK, + mclk_min, + mclk_max); + if (ret) + return ret; + + pstate_table->uclk_pstate.curr.min = mclk_min; + pstate_table->uclk_pstate.curr.max = mclk_max; + } + + if (socclk_min && socclk_max) { + ret = smu_v14_0_set_soft_freq_limited_range(smu, + SMU_SOCCLK, + socclk_min, + socclk_max); + if (ret) + return ret; + + pstate_table->socclk_pstate.curr.min = socclk_min; + pstate_table->socclk_pstate.curr.max = socclk_max; + } + + if (vclk_min && vclk_max) { + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + ret = smu_v14_0_set_soft_freq_limited_range(smu, + i ? SMU_VCLK1 : SMU_VCLK, + vclk_min, + vclk_max); + if (ret) + return ret; + } + pstate_table->vclk_pstate.curr.min = vclk_min; + pstate_table->vclk_pstate.curr.max = vclk_max; + } + + if (dclk_min && dclk_max) { + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + ret = smu_v14_0_set_soft_freq_limited_range(smu, + i ? SMU_DCLK1 : SMU_DCLK, + dclk_min, + dclk_max); + if (ret) + return ret; + } + pstate_table->dclk_pstate.curr.min = dclk_min; + pstate_table->dclk_pstate.curr.max = dclk_max; + } + + if (fclk_min && fclk_max) { + ret = smu_v14_0_set_soft_freq_limited_range(smu, + SMU_FCLK, + fclk_min, + fclk_max); + if (ret) + return ret; + + pstate_table->fclk_pstate.curr.min = fclk_min; + pstate_table->fclk_pstate.curr.max = fclk_max; + } + + return ret; +} + +int smu_v14_0_set_power_source(struct smu_context *smu, + enum smu_power_src_type power_src) +{ + int pwr_source; + + pwr_source = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_PWR, + (uint32_t)power_src); + if (pwr_source < 0) + return -EINVAL; + + return smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_NotifyPowerSource, + pwr_source, + NULL); +} + +static int smu_v14_0_get_dpm_freq_by_index(struct smu_context *smu, + enum smu_clk_type clk_type, + uint16_t level, + uint32_t *value) +{ + int ret = 0, clk_id = 0; + uint32_t param; + + if (!value) + return -EINVAL; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) + return 0; + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); + if (clk_id < 0) + return clk_id; + + param = (uint32_t)(((clk_id & 0xffff) << 16) | (level & 0xffff)); + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GetDpmFreqByIndex, + param, + value); + if (ret) + return ret; + + *value = *value & 0x7fffffff; + + return ret; +} + +static int smu_v14_0_get_dpm_level_count(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t *value) +{ + int ret; + + ret = smu_v14_0_get_dpm_freq_by_index(smu, clk_type, 0xff, value); + + return ret; +} + +static int smu_v14_0_get_fine_grained_status(struct smu_context *smu, + enum smu_clk_type clk_type, + bool *is_fine_grained_dpm) +{ + int ret = 0, clk_id = 0; + uint32_t param; + uint32_t value; + + if (!is_fine_grained_dpm) + return -EINVAL; + + if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) + return 0; + + clk_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_CLK, + clk_type); + if (clk_id < 0) + return clk_id; + + param = (uint32_t)(((clk_id & 0xffff) << 16) | 0xff); + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_GetDpmFreqByIndex, + param, + &value); + if (ret) + return ret; + + /* + * BIT31: 1 - Fine grained DPM, 0 - Dicrete DPM + * now, we un-support it + */ + *is_fine_grained_dpm = value & 0x80000000; + + return 0; +} + +int smu_v14_0_set_single_dpm_table(struct smu_context *smu, + enum smu_clk_type clk_type, + struct smu_14_0_dpm_table *single_dpm_table) +{ + int ret = 0; + uint32_t clk; + int i; + + ret = smu_v14_0_get_dpm_level_count(smu, + clk_type, + &single_dpm_table->count); + if (ret) { + dev_err(smu->adev->dev, "[%s] failed to get dpm levels!\n", __func__); + return ret; + } + + ret = smu_v14_0_get_fine_grained_status(smu, + clk_type, + &single_dpm_table->is_fine_grained); + if (ret) { + dev_err(smu->adev->dev, "[%s] failed to get fine grained status!\n", __func__); + return ret; + } + + for (i = 0; i < single_dpm_table->count; i++) { + ret = smu_v14_0_get_dpm_freq_by_index(smu, + clk_type, + i, + &clk); + if (ret) { + dev_err(smu->adev->dev, "[%s] failed to get dpm freq by index!\n", __func__); + return ret; + } + + single_dpm_table->dpm_levels[i].value = clk; + single_dpm_table->dpm_levels[i].enabled = true; + + if (i == 0) + single_dpm_table->min = clk; + else if (i == single_dpm_table->count - 1) + single_dpm_table->max = clk; + } + + return 0; +} + +int smu_v14_0_set_vcn_enable(struct smu_context *smu, + bool enable) +{ + struct amdgpu_device *adev = smu->adev; + int i, ret = 0; + + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + + ret = smu_cmn_send_smc_msg_with_param(smu, enable ? + SMU_MSG_PowerUpVcn : SMU_MSG_PowerDownVcn, + i << 16U, NULL); + if (ret) + return ret; + } + + return ret; +} + +int smu_v14_0_set_jpeg_enable(struct smu_context *smu, + bool enable) +{ + return smu_cmn_send_smc_msg_with_param(smu, enable ? + SMU_MSG_PowerUpJpeg : SMU_MSG_PowerDownJpeg, + 0, NULL); +} + +int smu_v14_0_run_btc(struct smu_context *smu) +{ + int res; + + res = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL); + if (res) + dev_err(smu->adev->dev, "RunDcBtc failed!\n"); + + return res; +} + +int smu_v14_0_gpo_control(struct smu_context *smu, + bool enablement) +{ + int res; + + res = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_AllowGpo, + enablement ? 1 : 0, + NULL); + if (res) + dev_err(smu->adev->dev, "SetGpoAllow %d failed!\n", enablement); + + return res; +} + +int smu_v14_0_deep_sleep_control(struct smu_context *smu, + bool enablement) +{ + struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_GFXCLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_GFXCLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s GFXCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_UCLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_UCLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s UCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_FCLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_FCLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s FCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_SOCCLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_SOCCLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s SOCCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_LCLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_LCLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s LCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_VCN_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_VCN_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s VCN DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP0CLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP0CLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s MP0/MPIOCLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP1CLK_BIT)) { + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP1CLK_BIT, enablement); + if (ret) { + dev_err(adev->dev, "Failed to %s MP1CLK DS!\n", enablement ? "enable" : "disable"); + return ret; + } + } + + return ret; +} + +int smu_v14_0_gfx_ulv_control(struct smu_context *smu, + bool enablement) +{ + int ret = 0; + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_GFX_ULV_BIT)) + ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_GFX_ULV_BIT, enablement); + + return ret; +} + +int smu_v14_0_baco_set_armd3_sequence(struct smu_context *smu, + enum smu_baco_seq baco_seq) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + int ret; + + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_ArmD3, + baco_seq, + NULL); + if (ret) + return ret; + + if (baco_seq == BACO_SEQ_BAMACO || + baco_seq == BACO_SEQ_BACO) + smu_baco->state = SMU_BACO_STATE_ENTER; + else + smu_baco->state = SMU_BACO_STATE_EXIT; + + return 0; +} + +bool smu_v14_0_baco_is_support(struct smu_context *smu) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + + if (amdgpu_sriov_vf(smu->adev) || + !smu_baco->platform_support) + return false; + + /* return true if ASIC is in BACO state already */ + if (smu_v14_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER) + return true; + + if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) && + !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT)) + return false; + + return true; +} + +enum smu_baco_state smu_v14_0_baco_get_state(struct smu_context *smu) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + + return smu_baco->state; +} + +int smu_v14_0_baco_set_state(struct smu_context *smu, + enum smu_baco_state state) +{ + struct smu_baco_context *smu_baco = &smu->smu_baco; + struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if (smu_v14_0_baco_get_state(smu) == state) + return 0; + + if (state == SMU_BACO_STATE_ENTER) { + ret = smu_cmn_send_smc_msg_with_param(smu, + SMU_MSG_EnterBaco, + smu_baco->maco_support ? + BACO_SEQ_BAMACO : BACO_SEQ_BACO, + NULL); + } else { + ret = smu_cmn_send_smc_msg(smu, + SMU_MSG_ExitBaco, + NULL); + if (ret) + return ret; + + /* clear vbios scratch 6 and 7 for coming asic reinit */ + WREG32(adev->bios_scratch_reg_offset + 6, 0); + WREG32(adev->bios_scratch_reg_offset + 7, 0); + } + + if (!ret) + smu_baco->state = state; + + return ret; +} + +int smu_v14_0_baco_enter(struct smu_context *smu) +{ + int ret = 0; + + ret = smu_v14_0_baco_set_state(smu, + SMU_BACO_STATE_ENTER); + if (ret) + return ret; + + msleep(10); + + return ret; +} + +int smu_v14_0_baco_exit(struct smu_context *smu) +{ + return smu_v14_0_baco_set_state(smu, + SMU_BACO_STATE_EXIT); +} + +int smu_v14_0_set_gfx_power_up_by_imu(struct smu_context *smu) +{ + uint16_t index; + + index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, + SMU_MSG_EnableGfxImu); + /* Param 1 to tell PMFW to enable GFXOFF feature */ + return smu_cmn_send_msg_without_waiting(smu, index, 1); +} + +int smu_v14_0_set_default_dpm_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, + smu_table->clocks_table, false); +} + +int smu_v14_0_od_edit_dpm_table(struct smu_context *smu, + enum PP_OD_DPM_TABLE_COMMAND type, + long input[], uint32_t size) +{ + struct smu_dpm_context *smu_dpm = &(smu->smu_dpm); + int ret = 0; + + /* Only allowed in manual mode */ + if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) + return -EINVAL; + + switch (type) { + case PP_OD_EDIT_SCLK_VDDC_TABLE: + if (size != 2) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } + + if (input[0] == 0) { + if (input[1] < smu->gfx_default_hard_min_freq) { + dev_warn(smu->adev->dev, + "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n", + input[1], smu->gfx_default_hard_min_freq); + return -EINVAL; + } + smu->gfx_actual_hard_min_freq = input[1]; + } else if (input[0] == 1) { + if (input[1] > smu->gfx_default_soft_max_freq) { + dev_warn(smu->adev->dev, + "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n", + input[1], smu->gfx_default_soft_max_freq); + return -EINVAL; + } + smu->gfx_actual_soft_max_freq = input[1]; + } else { + return -EINVAL; + } + break; + case PP_OD_RESTORE_DEFAULT_TABLE: + if (size != 0) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } + smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; + smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; + break; + case PP_OD_COMMIT_DPM_TABLE: + if (size != 0) { + dev_err(smu->adev->dev, "Input parameter number not correct\n"); + return -EINVAL; + } + if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) { + dev_err(smu->adev->dev, + "The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n", + smu->gfx_actual_hard_min_freq, + smu->gfx_actual_soft_max_freq); + return -EINVAL; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, + smu->gfx_actual_hard_min_freq, + NULL); + if (ret) { + dev_err(smu->adev->dev, "Set hard min sclk failed!"); + return ret; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, + smu->gfx_actual_soft_max_freq, + NULL); + if (ret) { + dev_err(smu->adev->dev, "Set soft max sclk failed!"); + return ret; + } + break; + default: + return -ENOSYS; + } + + return ret; +} + diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c new file mode 100644 index 000000000000..94ccdbfd7090 --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c @@ -0,0 +1,1139 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "smu_types.h" +#define SWSMU_CODE_LAYER_L2 + +#include "amdgpu.h" +#include "amdgpu_smu.h" +#include "smu_v14_0.h" +#include "smu14_driver_if_v14_0_0.h" +#include "smu_v14_0_0_ppt.h" +#include "smu_v14_0_0_ppsmc.h" +#include "smu_v14_0_0_pmfw.h" +#include "smu_cmn.h" + +/* + * DO NOT use these for err/warn/info/debug messages. + * Use dev_err, dev_warn, dev_info and dev_dbg instead. + * They are more MGPU friendly. + */ +#undef pr_err +#undef pr_warn +#undef pr_info +#undef pr_debug + +#define mmMP1_SMN_C2PMSG_66 0x0282 +#define mmMP1_SMN_C2PMSG_66_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_82 0x0292 +#define mmMP1_SMN_C2PMSG_82_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_90 0x029a +#define mmMP1_SMN_C2PMSG_90_BASE_IDX 0 + +#define FEATURE_MASK(feature) (1ULL << feature) +#define SMC_DPM_FEATURE ( \ + FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ + FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ + FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ + FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ + FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ + FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ + FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ + FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ + FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ + FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ + FEATURE_MASK(FEATURE_VPE_DPM_BIT)) + +static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = { + MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), + MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1), + MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), + MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 1), + MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 1), + MSG_MAP(SetHardMinVcn, PPSMC_MSG_SetHardMinVcn, 1), + MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxclk, 1), + MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), + MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1), + MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1), + MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1), + MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1), + MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1), + MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1), + MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1), + MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 1), + MSG_MAP(SetSoftMinVcn, PPSMC_MSG_SetSoftMinVcn, 1), + MSG_MAP(EnableGfxImu, PPSMC_MSG_EnableGfxImu, 1), + MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 1), + MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 1), + MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1), + MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1), + MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1), + MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1), + MSG_MAP(SetSoftMaxVcn, PPSMC_MSG_SetSoftMaxVcn, 1), + MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 1), + MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 1), + MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1), + MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1), + MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1), + MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1), + MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 1), + MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 1), + MSG_MAP(PowerUpVpe, PPSMC_MSG_PowerUpVpe, 1), + MSG_MAP(PowerDownVpe, PPSMC_MSG_PowerDownVpe, 1), + MSG_MAP(PowerUpUmsch, PPSMC_MSG_PowerUpUmsch, 1), + MSG_MAP(PowerDownUmsch, PPSMC_MSG_PowerDownUmsch, 1), + MSG_MAP(SetSoftMaxVpe, PPSMC_MSG_SetSoftMaxVpe, 1), + MSG_MAP(SetSoftMinVpe, PPSMC_MSG_SetSoftMinVpe, 1), +}; + +static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = { + FEA_MAP(CCLK_DPM), + FEA_MAP(FAN_CONTROLLER), + FEA_MAP(PPT), + FEA_MAP(TDC), + FEA_MAP(THERMAL), + FEA_MAP(VCN_DPM), + FEA_MAP_REVERSE(FCLK), + FEA_MAP_REVERSE(SOCCLK), + FEA_MAP(LCLK_DPM), + FEA_MAP(SHUBCLK_DPM), + FEA_MAP(DCFCLK_DPM), + FEA_MAP_HALF_REVERSE(GFX), + FEA_MAP(DS_GFXCLK), + FEA_MAP(DS_SOCCLK), + FEA_MAP(DS_LCLK), + FEA_MAP(LOW_POWER_DCNCLKS), + FEA_MAP(DS_FCLK), + FEA_MAP(DS_MP1CLK), + FEA_MAP(PSI), + FEA_MAP(PROCHOT), + FEA_MAP(CPUOFF), + FEA_MAP(STAPM), + FEA_MAP(S0I3), + FEA_MAP(PERF_LIMIT), + FEA_MAP(CORE_DLDO), + FEA_MAP(DS_VCN), + FEA_MAP(CPPC), + FEA_MAP(DF_CSTATES), + FEA_MAP(ATHUB_PG), +}; + +static struct cmn2asic_mapping smu_v14_0_0_table_map[SMU_TABLE_COUNT] = { + TAB_MAP_VALID(WATERMARKS), + TAB_MAP_VALID(SMU_METRICS), + TAB_MAP_VALID(CUSTOM_DPM), + TAB_MAP_VALID(DPMCLOCKS), +}; + +static int smu_v14_0_0_init_smc_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct smu_table *tables = smu_table->tables; + + 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), + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); + SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); + + smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + if (!smu_table->metrics_table) + goto err0_out; + smu_table->metrics_time = 0; + + smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + if (!smu_table->clocks_table) + goto err1_out; + + smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + if (!smu_table->watermarks_table) + goto err2_out; + + smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v3_0); + smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); + if (!smu_table->gpu_metrics_table) + goto err3_out; + + return 0; + +err3_out: + kfree(smu_table->watermarks_table); +err2_out: + kfree(smu_table->clocks_table); +err1_out: + kfree(smu_table->metrics_table); +err0_out: + return -ENOMEM; +} + +static int smu_v14_0_0_fini_smc_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + kfree(smu_table->clocks_table); + smu_table->clocks_table = NULL; + + kfree(smu_table->metrics_table); + smu_table->metrics_table = NULL; + + kfree(smu_table->watermarks_table); + smu_table->watermarks_table = NULL; + + kfree(smu_table->gpu_metrics_table); + smu_table->gpu_metrics_table = NULL; + + return 0; +} + +static int smu_v14_0_0_system_features_control(struct smu_context *smu, bool en) +{ + struct amdgpu_device *adev = smu->adev; + int ret = 0; + + if (!en && !adev->in_s0ix) + ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL); + + return ret; +} + +static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu, + MetricsMember_t member, + uint32_t *value) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; + int ret = 0; + + ret = smu_cmn_get_metrics_table(smu, NULL, false); + if (ret) + return ret; + + switch (member) { + case METRICS_AVERAGE_GFXCLK: + *value = metrics->GfxclkFrequency; + break; + case METRICS_AVERAGE_SOCCLK: + *value = metrics->SocclkFrequency; + break; + case METRICS_AVERAGE_VCLK: + *value = metrics->VclkFrequency; + break; + case METRICS_AVERAGE_DCLK: + *value = 0; + break; + case METRICS_AVERAGE_UCLK: + *value = metrics->MemclkFrequency; + break; + case METRICS_AVERAGE_FCLK: + *value = metrics->FclkFrequency; + break; + case METRICS_AVERAGE_VPECLK: + *value = metrics->VpeclkFrequency; + break; + case METRICS_AVERAGE_IPUCLK: + *value = metrics->IpuclkFrequency; + break; + case METRICS_AVERAGE_MPIPUCLK: + *value = metrics->MpipuclkFrequency; + break; + case METRICS_AVERAGE_GFXACTIVITY: + *value = metrics->GfxActivity / 100; + break; + case METRICS_AVERAGE_VCNACTIVITY: + *value = metrics->VcnActivity / 100; + break; + case METRICS_AVERAGE_SOCKETPOWER: + case METRICS_CURR_SOCKETPOWER: + *value = (metrics->SocketPower / 1000 << 8) + + (metrics->SocketPower % 1000 / 10); + break; + case METRICS_TEMPERATURE_EDGE: + *value = metrics->GfxTemperature / 100 * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + break; + case METRICS_TEMPERATURE_HOTSPOT: + *value = metrics->SocTemperature / 100 * + SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; + break; + case METRICS_THROTTLER_RESIDENCY_PROCHOT: + *value = metrics->ThrottleResidency_PROCHOT; + break; + case METRICS_THROTTLER_RESIDENCY_SPL: + *value = metrics->ThrottleResidency_SPL; + break; + case METRICS_THROTTLER_RESIDENCY_FPPT: + *value = metrics->ThrottleResidency_FPPT; + break; + case METRICS_THROTTLER_RESIDENCY_SPPT: + *value = metrics->ThrottleResidency_SPPT; + break; + case METRICS_THROTTLER_RESIDENCY_THM_CORE: + *value = metrics->ThrottleResidency_THM_CORE; + break; + case METRICS_THROTTLER_RESIDENCY_THM_GFX: + *value = metrics->ThrottleResidency_THM_GFX; + break; + case METRICS_THROTTLER_RESIDENCY_THM_SOC: + *value = metrics->ThrottleResidency_THM_SOC; + break; + case METRICS_VOLTAGE_VDDGFX: + *value = 0; + break; + case METRICS_VOLTAGE_VDDSOC: + *value = 0; + break; + case METRICS_SS_APU_SHARE: + /* return the percentage of APU power with respect to APU's power limit. + * percentage is reported, this isn't boost value. Smartshift power + * boost/shift is only when the percentage is more than 100. + */ + if (metrics->StapmOpnLimit > 0) + *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit; + else + *value = 0; + break; + case METRICS_SS_DGPU_SHARE: + /* return the percentage of dGPU power with respect to dGPU's power limit. + * percentage is reported, this isn't boost value. Smartshift power + * boost/shift is only when the percentage is more than 100. + */ + if ((metrics->dGpuPower > 0) && + (metrics->StapmCurrentLimit > metrics->StapmOpnLimit)) + *value = (metrics->dGpuPower * 100) / + (metrics->StapmCurrentLimit - metrics->StapmOpnLimit); + else + *value = 0; + break; + default: + *value = UINT_MAX; + break; + } + + return ret; +} + +static int smu_v14_0_0_read_sensor(struct smu_context *smu, + enum amd_pp_sensors sensor, + void *data, uint32_t *size) +{ + int ret = 0; + + if (!data || !size) + return -EINVAL; + + switch (sensor) { + case AMDGPU_PP_SENSOR_GPU_LOAD: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXACTIVITY, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_GPU_AVG_POWER: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_AVERAGE_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_GPU_INPUT_POWER: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_CURR_SOCKETPOWER, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_EDGE_TEMP: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_EDGE, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_TEMPERATURE_HOTSPOT, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_GFX_MCLK: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_AVERAGE_UCLK, + (uint32_t *)data); + *(uint32_t *)data *= 100; + *size = 4; + break; + case AMDGPU_PP_SENSOR_GFX_SCLK: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_AVERAGE_GFXCLK, + (uint32_t *)data); + *(uint32_t *)data *= 100; + *size = 4; + break; + case AMDGPU_PP_SENSOR_VDDGFX: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDGFX, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_VDDNB: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_VOLTAGE_VDDSOC, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_SS_APU_SHARE: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_SS_APU_SHARE, + (uint32_t *)data); + *size = 4; + break; + case AMDGPU_PP_SENSOR_SS_DGPU_SHARE: + ret = smu_v14_0_0_get_smu_metrics_data(smu, + METRICS_SS_DGPU_SHARE, + (uint32_t *)data); + *size = 4; + break; + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu) +{ + int ret = 0; + uint64_t feature_enabled; + + ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); + + if (ret) + return false; + + return !!(feature_enabled & SMC_DPM_FEATURE); +} + +static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu, + struct pp_smu_wm_range_sets *clock_ranges) +{ + int i; + int ret = 0; + Watermarks_t *table = smu->smu_table.watermarks_table; + + if (!table || !clock_ranges) + return -EINVAL; + + if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || + clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) + return -EINVAL; + + for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { + table->WatermarkRow[WM_DCFCLK][i].MinClock = + clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; + table->WatermarkRow[WM_DCFCLK][i].MaxClock = + clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; + table->WatermarkRow[WM_DCFCLK][i].MinMclk = + clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; + table->WatermarkRow[WM_DCFCLK][i].MaxMclk = + clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; + + table->WatermarkRow[WM_DCFCLK][i].WmSetting = + clock_ranges->reader_wm_sets[i].wm_inst; + } + + for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { + table->WatermarkRow[WM_SOCCLK][i].MinClock = + clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; + table->WatermarkRow[WM_SOCCLK][i].MaxClock = + clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; + table->WatermarkRow[WM_SOCCLK][i].MinMclk = + clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; + table->WatermarkRow[WM_SOCCLK][i].MaxMclk = + clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; + + table->WatermarkRow[WM_SOCCLK][i].WmSetting = + clock_ranges->writer_wm_sets[i].wm_inst; + } + + smu->watermarks_bitmap |= WATERMARKS_EXIST; + + /* pass data to smu controller */ + if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && + !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { + ret = smu_cmn_write_watermarks_table(smu); + if (ret) { + dev_err(smu->adev->dev, "Failed to update WMTABLE!"); + return ret; + } + smu->watermarks_bitmap |= WATERMARKS_LOADED; + } + + return 0; +} + +static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, + void **table) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct gpu_metrics_v3_0 *gpu_metrics = + (struct gpu_metrics_v3_0 *)smu_table->gpu_metrics_table; + SmuMetrics_t metrics; + int ret = 0; + + ret = smu_cmn_get_metrics_table(smu, &metrics, true); + if (ret) + return ret; + + smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0); + + gpu_metrics->temperature_gfx = metrics.GfxTemperature; + gpu_metrics->temperature_soc = metrics.SocTemperature; + memcpy(&gpu_metrics->temperature_core[0], + &metrics.CoreTemperature[0], + sizeof(uint16_t) * 16); + gpu_metrics->temperature_skin = metrics.SkinTemp; + + gpu_metrics->average_gfx_activity = metrics.GfxActivity; + gpu_metrics->average_vcn_activity = metrics.VcnActivity; + memcpy(&gpu_metrics->average_ipu_activity[0], + &metrics.IpuBusy[0], + sizeof(uint16_t) * 8); + memcpy(&gpu_metrics->average_core_c0_activity[0], + &metrics.CoreC0Residency[0], + sizeof(uint16_t) * 16); + gpu_metrics->average_dram_reads = metrics.DRAMReads; + gpu_metrics->average_dram_writes = metrics.DRAMWrites; + gpu_metrics->average_ipu_reads = metrics.IpuReads; + gpu_metrics->average_ipu_writes = metrics.IpuWrites; + + gpu_metrics->average_socket_power = metrics.SocketPower; + gpu_metrics->average_ipu_power = metrics.IpuPower; + gpu_metrics->average_apu_power = metrics.ApuPower; + gpu_metrics->average_gfx_power = metrics.GfxPower; + gpu_metrics->average_dgpu_power = metrics.dGpuPower; + gpu_metrics->average_all_core_power = metrics.AllCorePower; + gpu_metrics->average_sys_power = metrics.Psys; + memcpy(&gpu_metrics->average_core_power[0], + &metrics.CorePower[0], + sizeof(uint16_t) * 16); + + gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency; + gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency; + gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency; + gpu_metrics->average_fclk_frequency = metrics.FclkFrequency; + gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; + gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency; + gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; + gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency; + + memcpy(&gpu_metrics->current_coreclk[0], + &metrics.CoreFrequency[0], + sizeof(uint16_t) * 16); + gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq; + gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq; + + gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT; + gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL; + gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT; + gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT; + gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE; + gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX; + gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC; + + gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue; + gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); + + *table = (void *)gpu_metrics; + + return sizeof(struct gpu_metrics_v3_0); +} + +static int smu_v14_0_0_mode2_reset(struct smu_context *smu) +{ + int ret; + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset, + SMU_RESET_MODE_2, NULL); + + if (ret) + dev_err(smu->adev->dev, "Failed to mode2 reset!\n"); + + return ret; +} + +static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t dpm_level, + uint32_t *freq) +{ + DpmClocks_t *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_VCLK: + if (dpm_level >= clk_table->VcnClkLevelsEnabled) + return -EINVAL; + *freq = clk_table->VClocks[dpm_level]; + break; + case SMU_DCLK: + if (dpm_level >= clk_table->VcnClkLevelsEnabled) + return -EINVAL; + *freq = clk_table->DClocks[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 bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu, + enum smu_clk_type clk_type) +{ + enum smu_feature_mask feature_id = 0; + + switch (clk_type) { + case SMU_MCLK: + case SMU_UCLK: + case SMU_FCLK: + feature_id = SMU_FEATURE_DPM_FCLK_BIT; + break; + case SMU_GFXCLK: + case SMU_SCLK: + feature_id = SMU_FEATURE_DPM_GFXCLK_BIT; + break; + case SMU_SOCCLK: + feature_id = SMU_FEATURE_DPM_SOCCLK_BIT; + break; + case SMU_VCLK: + case SMU_DCLK: + feature_id = SMU_FEATURE_VCN_DPM_BIT; + break; + default: + return true; + } + + return smu_cmn_feature_is_enabled(smu, feature_id); +} + +static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t *min, + uint32_t *max) +{ + DpmClocks_t *clk_table = smu->smu_table.clocks_table; + uint32_t clock_limit; + uint32_t max_dpm_level, min_dpm_level; + int ret = 0; + + if (!smu_v14_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; + case SMU_VCLK: + clock_limit = smu->smu_table.boot_values.vclk; + break; + case SMU_DCLK: + clock_limit = smu->smu_table.boot_values.dclk; + 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: + case SMU_FCLK: + max_dpm_level = 0; + break; + case SMU_SOCCLK: + max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1; + break; + case SMU_VCLK: + case SMU_DCLK: + max_dpm_level = clk_table->VcnClkLevelsEnabled - 1; + break; + default: + ret = -EINVAL; + goto failed; + } + + if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { + ret = smu_v14_0_0_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 = clk_table->NumFclkLevelsEnabled - 1; + break; + case SMU_SOCCLK: + min_dpm_level = 0; + break; + case SMU_VCLK: + case SMU_DCLK: + min_dpm_level = 0; + break; + default: + ret = -EINVAL; + goto failed; + } + + if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) { + ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min); + if (ret) + goto failed; + } + } + +failed: + return ret; +} + +static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t *value) +{ + MetricsMember_t member_type; + + switch (clk_type) { + case SMU_SOCCLK: + member_type = METRICS_AVERAGE_SOCCLK; + break; + case SMU_VCLK: + member_type = METRICS_AVERAGE_VCLK; + break; + case SMU_DCLK: + member_type = METRICS_AVERAGE_DCLK; + break; + case SMU_MCLK: + member_type = METRICS_AVERAGE_UCLK; + break; + case SMU_FCLK: + member_type = METRICS_AVERAGE_FCLK; + break; + case SMU_GFXCLK: + case SMU_SCLK: + member_type = METRICS_AVERAGE_GFXCLK; + break; + default: + return -EINVAL; + } + + return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value); +} + +static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t *count) +{ + DpmClocks_t *clk_table = smu->smu_table.clocks_table; + + switch (clk_type) { + case SMU_SOCCLK: + *count = clk_table->NumSocClkLevelsEnabled; + break; + case SMU_VCLK: + *count = clk_table->VcnClkLevelsEnabled; + break; + case SMU_DCLK: + *count = clk_table->VcnClkLevelsEnabled; + break; + case SMU_MCLK: + *count = clk_table->NumMemPstatesEnabled; + break; + case SMU_FCLK: + *count = clk_table->NumFclkLevelsEnabled; + break; + default: + break; + } + + return 0; +} + +static int smu_v14_0_0_print_clk_levels(struct smu_context *smu, + enum smu_clk_type clk_type, char *buf) +{ + int i, size = 0, ret = 0; + uint32_t cur_value = 0, value = 0, count = 0; + uint32_t min, max; + + smu_cmn_get_sysfs_buf(&buf, &size); + + switch (clk_type) { + case SMU_OD_SCLK: + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); + size += sysfs_emit_at(buf, size, "0: %10uMhz\n", + (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq); + size += sysfs_emit_at(buf, size, "1: %10uMhz\n", + (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq); + break; + case SMU_OD_RANGE: + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); + size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n", + smu->gfx_default_hard_min_freq, + smu->gfx_default_soft_max_freq); + break; + case SMU_SOCCLK: + case SMU_VCLK: + case SMU_DCLK: + case SMU_MCLK: + case SMU_FCLK: + ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); + if (ret) + break; + + ret = smu_v14_0_0_get_dpm_level_count(smu, clk_type, &count); + if (ret) + break; + + for (i = 0; i < count; i++) { + ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, i, &value); + if (ret) + break; + + size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value, + cur_value == value ? "*" : ""); + } + break; + case SMU_GFXCLK: + case SMU_SCLK: + ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value); + if (ret) + break; + min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq; + max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq; + if (cur_value == max) + i = 2; + else if (cur_value == min) + i = 0; + else + i = 1; + size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min, + i == 0 ? "*" : ""); + size += sysfs_emit_at(buf, size, "1: %uMhz %s\n", + i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */ + i == 1 ? "*" : ""); + size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max, + i == 2 ? "*" : ""); + break; + default: + break; + } + + return size; +} + +static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t min, + uint32_t max) +{ + enum smu_message_type msg_set_min, msg_set_max; + int ret = 0; + + if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) + return -EINVAL; + + switch (clk_type) { + case SMU_GFXCLK: + case SMU_SCLK: + msg_set_min = SMU_MSG_SetHardMinGfxClk; + msg_set_max = SMU_MSG_SetSoftMaxGfxClk; + break; + case SMU_FCLK: + msg_set_min = SMU_MSG_SetHardMinFclkByFreq; + msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; + break; + case SMU_SOCCLK: + msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; + msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; + break; + case SMU_VCLK: + case SMU_DCLK: + msg_set_min = SMU_MSG_SetHardMinVcn; + msg_set_max = SMU_MSG_SetSoftMaxVcn; + break; + default: + return -EINVAL; + } + + ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL); + if (ret) + return ret; + + return smu_cmn_send_smc_msg_with_param(smu, msg_set_max, + max, NULL); +} + +static int smu_v14_0_0_force_clk_levels(struct smu_context *smu, + enum smu_clk_type clk_type, + uint32_t mask) +{ + uint32_t soft_min_level = 0, soft_max_level = 0; + uint32_t min_freq = 0, max_freq = 0; + int ret = 0; + + soft_min_level = mask ? (ffs(mask) - 1) : 0; + soft_max_level = mask ? (fls(mask) - 1) : 0; + + switch (clk_type) { + case SMU_SOCCLK: + case SMU_FCLK: + case SMU_VCLK: + case SMU_DCLK: + ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); + if (ret) + break; + + ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); + if (ret) + break; + + ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int smu_v14_0_0_set_performance_level(struct smu_context *smu, + enum amd_dpm_forced_level level) +{ + struct amdgpu_device *adev = smu->adev; + uint32_t sclk_min = 0, sclk_max = 0; + uint32_t fclk_min = 0, fclk_max = 0; + uint32_t socclk_min = 0, socclk_max = 0; + int ret = 0; + + switch (level) { + case AMD_DPM_FORCED_LEVEL_HIGH: + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max); + sclk_min = sclk_max; + fclk_min = fclk_max; + socclk_min = socclk_max; + break; + case AMD_DPM_FORCED_LEVEL_LOW: + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL); + sclk_max = sclk_min; + fclk_max = fclk_min; + socclk_max = socclk_min; + break; + case AMD_DPM_FORCED_LEVEL_AUTO: + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max); + smu_v14_0_0_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max); + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: + case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: + case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: + /* Temporarily do nothing since the optimal clocks haven't been provided yet */ + break; + case AMD_DPM_FORCED_LEVEL_MANUAL: + case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: + return 0; + default: + dev_err(adev->dev, "Invalid performance level %d\n", level); + return -EINVAL; + } + + if (sclk_min && sclk_max) { + ret = smu_v14_0_0_set_soft_freq_limited_range(smu, + SMU_SCLK, + sclk_min, + sclk_max); + if (ret) + return ret; + + smu->gfx_actual_hard_min_freq = sclk_min; + smu->gfx_actual_soft_max_freq = sclk_max; + } + + if (fclk_min && fclk_max) { + ret = smu_v14_0_0_set_soft_freq_limited_range(smu, + SMU_FCLK, + fclk_min, + fclk_max); + if (ret) + return ret; + } + + if (socclk_min && socclk_max) { + ret = smu_v14_0_0_set_soft_freq_limited_range(smu, + SMU_SOCCLK, + socclk_min, + socclk_max); + if (ret) + return ret; + } + + return ret; +} + +static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu) +{ + DpmClocks_t *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_v14_0_0_set_vpe_enable(struct smu_context *smu, + bool enable) +{ + return smu_cmn_send_smc_msg_with_param(smu, enable ? + SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe, + 0, NULL); +} + +static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu, + bool enable) +{ + return smu_cmn_send_smc_msg_with_param(smu, enable ? + SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch, + 0, NULL); +} + +static const struct pptable_funcs smu_v14_0_0_ppt_funcs = { + .check_fw_status = smu_v14_0_check_fw_status, + .check_fw_version = smu_v14_0_check_fw_version, + .init_smc_tables = smu_v14_0_0_init_smc_tables, + .fini_smc_tables = smu_v14_0_0_fini_smc_tables, + .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values, + .system_features_control = smu_v14_0_0_system_features_control, + .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, + .send_smc_msg = smu_cmn_send_smc_msg, + .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable, + .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable, + .set_default_dpm_table = smu_v14_0_set_default_dpm_tables, + .read_sensor = smu_v14_0_0_read_sensor, + .is_dpm_running = smu_v14_0_0_is_dpm_running, + .set_watermarks_table = smu_v14_0_0_set_watermarks_table, + .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics, + .get_enabled_mask = smu_cmn_get_enabled_mask, + .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, + .set_driver_table_location = smu_v14_0_set_driver_table_location, + .gfx_off_control = smu_v14_0_gfx_off_control, + .mode2_reset = smu_v14_0_0_mode2_reset, + .get_dpm_ultimate_freq = smu_v14_0_0_get_dpm_ultimate_freq, + .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table, + .print_clk_levels = smu_v14_0_0_print_clk_levels, + .force_clk_levels = smu_v14_0_0_force_clk_levels, + .set_performance_level = smu_v14_0_0_set_performance_level, + .set_fine_grain_gfx_freq_parameters = smu_v14_0_0_set_fine_grain_gfx_freq_parameters, + .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu, + .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable, + .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable, +}; + +static void smu_v14_0_0_set_smu_mailbox_registers(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + + smu->param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82); + smu->msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66); + smu->resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90); +} + +void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu) +{ + + smu->ppt_funcs = &smu_v14_0_0_ppt_funcs; + smu->message_map = smu_v14_0_0_message_map; + smu->feature_map = smu_v14_0_0_feature_mask_map; + smu->table_map = smu_v14_0_0_table_map; + smu->is_apu = true; + + smu_v14_0_0_set_smu_mailbox_registers(smu); +} diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.h new file mode 100644 index 000000000000..93e645ee36df --- /dev/null +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.h @@ -0,0 +1,28 @@ +/* + * Copyright 2023 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#ifndef __SMU_V14_0_0_PPT_H__ +#define __SMU_V14_0_0_PPT_H__ + +extern void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu); + +#endif
\ No newline at end of file diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 3ecb900e6ecd..001a5cf09657 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -39,6 +39,8 @@ #define MP1_C2PMSG_90__CONTENT_MASK 0xFFFFFFFFL +const int link_speed[] = {25, 50, 80, 160, 320, 640}; + #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(type) #type static const char * const __smu_message_names[] = { @@ -691,7 +693,7 @@ int smu_cmn_feature_set_enabled(struct smu_context *smu, #undef __SMU_DUMMY_MAP #define __SMU_DUMMY_MAP(fea) #fea -static const char* __smu_feature_names[] = { +static const char *__smu_feature_names[] = { SMU_FEATURE_MASKS }; @@ -927,7 +929,7 @@ int smu_cmn_get_metrics_table(struct smu_context *smu, void *metrics_table, bool bypass_cache) { - struct smu_table_context *smu_table= &smu->smu_table; + struct smu_table_context *smu_table = &smu->smu_table; uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size; int ret = 0; @@ -969,7 +971,7 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) struct metrics_table_header *header = (struct metrics_table_header *)table; uint16_t structure_size; -#define METRICS_VERSION(a, b) ((a << 16) | b ) +#define METRICS_VERSION(a, b) ((a << 16) | b) switch (METRICS_VERSION(frev, crev)) { case METRICS_VERSION(1, 0): @@ -984,6 +986,9 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) case METRICS_VERSION(1, 3): structure_size = sizeof(struct gpu_metrics_v1_3); break; + case METRICS_VERSION(1, 4): + structure_size = sizeof(struct gpu_metrics_v1_4); + break; case METRICS_VERSION(2, 0): structure_size = sizeof(struct gpu_metrics_v2_0); break; @@ -996,6 +1001,12 @@ void smu_cmn_init_soft_gpu_metrics(void *table, uint8_t frev, uint8_t crev) case METRICS_VERSION(2, 3): structure_size = sizeof(struct gpu_metrics_v2_3); break; + case METRICS_VERSION(2, 4): + structure_size = sizeof(struct gpu_metrics_v2_4); + break; + case METRICS_VERSION(3, 0): + structure_size = sizeof(struct gpu_metrics_v3_0); + break; default: return; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index d7cd358a53bd..cc590e27d88a 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -30,6 +30,14 @@ #define FDO_PWM_MODE_STATIC 1 #define FDO_PWM_MODE_STATIC_RPM 5 +extern const int link_speed[]; + +/* Helper to Convert from PCIE Gen 1/2/3/4/5/6 to 0.1 GT/s speed units */ +static inline int pcie_gen_to_speed(uint32_t gen) +{ + return ((gen == 0) ? link_speed[0] : link_speed[gen - 1]); +} + int smu_cmn_send_msg_without_waiting(struct smu_context *smu, uint16_t msg_index, uint32_t param); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h index ceb13c838067..64766ac69c53 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_internal.h @@ -61,14 +61,14 @@ #define smu_feature_get_enabled_mask(smu, mask) smu_ppt_funcs(get_enabled_mask, -EOPNOTSUPP, smu, mask) #define smu_feature_is_enabled(smu, mask) smu_ppt_funcs(feature_is_enabled, 0, smu, mask) #define smu_disable_all_features_with_exception(smu, mask) smu_ppt_funcs(disable_all_features_with_exception, 0, smu, mask) -#define smu_is_dpm_running(smu) smu_ppt_funcs(is_dpm_running, 0 , smu) +#define smu_is_dpm_running(smu) smu_ppt_funcs(is_dpm_running, 0, smu) #define smu_notify_display_change(smu) smu_ppt_funcs(notify_display_change, 0, smu) #define smu_populate_umd_state_clk(smu) smu_ppt_funcs(populate_umd_state_clk, 0, smu) #define smu_enable_thermal_alert(smu) smu_ppt_funcs(enable_thermal_alert, 0, smu) #define smu_disable_thermal_alert(smu) smu_ppt_funcs(disable_thermal_alert, 0, smu) #define smu_smc_read_sensor(smu, sensor, data, size) smu_ppt_funcs(read_sensor, -EINVAL, smu, sensor, data, size) #define smu_pre_display_config_changed(smu) smu_ppt_funcs(pre_display_config_changed, 0, smu) -#define smu_display_config_changed(smu) smu_ppt_funcs(display_config_changed, 0 , smu) +#define smu_display_config_changed(smu) smu_ppt_funcs(display_config_changed, 0, smu) #define smu_apply_clocks_adjust_rules(smu) smu_ppt_funcs(apply_clocks_adjust_rules, 0, smu) #define smu_notify_smc_display_config(smu) smu_ppt_funcs(notify_smc_display_config, 0, smu) #define smu_run_btc(smu) smu_ppt_funcs(run_btc, 0, smu) @@ -85,7 +85,7 @@ #define smu_i2c_fini(smu) smu_ppt_funcs(i2c_fini, 0, smu) #define smu_get_unique_id(smu) smu_ppt_funcs(get_unique_id, 0, smu) #define smu_log_thermal_throttling(smu) smu_ppt_funcs(log_thermal_throttling_event, 0, smu) -#define smu_get_asic_power_limits(smu, current, default, max) smu_ppt_funcs(get_power_limit, 0, smu, current, default, max) +#define smu_get_asic_power_limits(smu, current, default, max, min) smu_ppt_funcs(get_power_limit, 0, smu, current, default, max, min) #define smu_get_pp_feature_mask(smu, buf) smu_ppt_funcs(get_pp_feature_mask, 0, smu, buf) #define smu_set_pp_feature_mask(smu, new_mask) smu_ppt_funcs(set_pp_feature_mask, 0, smu, new_mask) #define smu_gfx_ulv_control(smu, enablement) smu_ppt_funcs(gfx_ulv_control, 0, smu, enablement) @@ -97,6 +97,7 @@ #define smu_get_default_config_table_settings(smu, config_table) smu_ppt_funcs(get_default_config_table_settings, -EOPNOTSUPP, smu, config_table) #define smu_set_config_table(smu, config_table) smu_ppt_funcs(set_config_table, -EOPNOTSUPP, smu, config_table) #define smu_init_pptable_microcode(smu) smu_ppt_funcs(init_pptable_microcode, 0, smu) +#define smu_notify_rlc_state(smu, en) smu_ppt_funcs(notify_rlc_state, 0, smu, en) #endif #endif |