diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 1060 | 
1 files changed, 766 insertions, 294 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index f205f56e3358..b03b1eb7ba04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -37,6 +37,7 @@  #include <linux/hwmon.h>  #include <linux/hwmon-sysfs.h>  #include <linux/nospec.h> +#include <linux/pm_runtime.h>  #include "hwmgr.h"  #define WIDTH_4K 3840 @@ -158,6 +159,14 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	enum amd_pm_state_type pm; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		if (adev->smu.ppt_funcs->get_current_power_state) @@ -170,6 +179,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,  		pm = adev->pm.dpm.user_state;  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return snprintf(buf, PAGE_SIZE, "%s\n",  			(pm == POWER_STATE_TYPE_BATTERY) ? "battery" :  			(pm == POWER_STATE_TYPE_BALANCED) ? "balanced" : "performance"); @@ -183,6 +195,10 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	enum amd_pm_state_type  state; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL;  	if (strncmp("battery", buf, strlen("battery")) == 0)  		state = POWER_STATE_TYPE_BATTERY; @@ -190,10 +206,12 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,  		state = POWER_STATE_TYPE_BALANCED;  	else if (strncmp("performance", buf, strlen("performance")) == 0)  		state = POWER_STATE_TYPE_PERFORMANCE; -	else { -		count = -EINVAL; -		goto fail; -	} +	else +		return -EINVAL; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		mutex_lock(&adev->pm.mutex); @@ -206,12 +224,11 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev,  		adev->pm.dpm.user_state = state;  		mutex_unlock(&adev->pm.mutex); -		/* Can't set dpm state when the card is off */ -		if (!(adev->flags & AMD_IS_PX) || -		    (ddev->switch_power_state == DRM_SWITCH_POWER_ON)) -			amdgpu_pm_compute_clocks(adev); +		amdgpu_pm_compute_clocks(adev);  	} -fail: +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return count;  } @@ -282,13 +299,14 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	enum amd_dpm_forced_level level = 0xff; +	int ret; -	if (amdgpu_sriov_vf(adev)) +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))  		return 0; -	if ((adev->flags & AMD_IS_PX) && -	    (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return snprintf(buf, PAGE_SIZE, "off\n"); +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev))  		level = smu_get_performance_level(&adev->smu); @@ -297,6 +315,9 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev,  	else  		level = adev->pm.dpm.forced_level; +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return snprintf(buf, PAGE_SIZE, "%s\n",  			(level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" :  			(level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : @@ -320,9 +341,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,  	enum amd_dpm_forced_level current_level = 0xff;  	int ret = 0; -	/* Can't force performance level when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))  		return -EINVAL;  	if (strncmp("low", buf, strlen("low")) == 0) { @@ -344,30 +363,23 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,  	} else if (strncmp("profile_peak", buf, strlen("profile_peak")) == 0) {  		level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;  	}  else { -		count = -EINVAL; -		goto fail; +		return -EINVAL;  	} -	/* handle sriov case here */ -	if (amdgpu_sriov_vf(adev)) { -		if (amdgim_is_hwperf(adev) && -		    adev->virt.ops->force_dpm_level) { -			mutex_lock(&adev->pm.mutex); -			adev->virt.ops->force_dpm_level(adev, level); -			mutex_unlock(&adev->pm.mutex); -			return count; -		} else { -			return -EINVAL; -		} -	} +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev))  		current_level = smu_get_performance_level(&adev->smu);  	else if (adev->powerplay.pp_funcs->get_performance_level)  		current_level = amdgpu_dpm_get_performance_level(adev); -	if (current_level == level) +	if (current_level == level) { +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev);  		return count; +	}  	/* profile_exit setting is valid only when current mode is in profile mode */  	if (!(current_level & (AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | @@ -376,29 +388,40 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev,  	    AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)) &&  	    (level == AMD_DPM_FORCED_LEVEL_PROFILE_EXIT)) {  		pr_err("Currently not in any profile mode!\n"); +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev);  		return -EINVAL;  	}  	if (is_support_sw_smu(adev)) {  		ret = smu_force_performance_level(&adev->smu, level); -		if (ret) -			count = -EINVAL; +		if (ret) { +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev); +			return -EINVAL; +		}  	} else if (adev->powerplay.pp_funcs->force_performance_level) {  		mutex_lock(&adev->pm.mutex);  		if (adev->pm.dpm.thermal_active) { -			count = -EINVAL;  			mutex_unlock(&adev->pm.mutex); -			goto fail; +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev); +			return -EINVAL;  		}  		ret = amdgpu_dpm_force_performance_level(adev, level); -		if (ret) -			count = -EINVAL; -		else +		if (ret) { +			mutex_unlock(&adev->pm.mutex); +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev); +			return -EINVAL; +		} else {  			adev->pm.dpm.forced_level = level; +		}  		mutex_unlock(&adev->pm.mutex);  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); -fail:  	return count;  } @@ -411,6 +434,10 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,  	struct pp_states_info data;  	int i, buf_len, ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		ret = smu_get_power_num_states(&adev->smu, &data);  		if (ret) @@ -418,6 +445,9 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev,  	} else if (adev->powerplay.pp_funcs->get_pp_num_states)  		amdgpu_dpm_get_pp_num_states(adev, &data); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums);  	for (i = 0; i < data.nums; i++)  		buf_len += snprintf(buf + buf_len, PAGE_SIZE, "%d %s\n", i, @@ -440,6 +470,13 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev,  	enum amd_pm_state_type pm = 0;  	int i = 0, ret = 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		pm = smu_get_current_power_state(smu);  		ret = smu_get_power_num_states(smu, &data); @@ -451,6 +488,9 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev,  		amdgpu_dpm_get_pp_num_states(adev, &data);  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	for (i = 0; i < data.nums; i++) {  		if (pm == data.states[i])  			break; @@ -469,6 +509,9 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; +  	if (adev->pp_force_state_enabled)  		return amdgpu_get_pp_cur_state(dev, attr, buf);  	else @@ -486,6 +529,9 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,  	unsigned long idx;  	int ret; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL; +  	if (strlen(buf) == 1)  		adev->pp_force_state_enabled = false;  	else if (is_support_sw_smu(adev)) @@ -495,14 +541,18 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,  		struct pp_states_info data;  		ret = kstrtoul(buf, 0, &idx); -		if (ret || idx >= ARRAY_SIZE(data.states)) { -			count = -EINVAL; -			goto fail; -		} +		if (ret || idx >= ARRAY_SIZE(data.states)) +			return -EINVAL; +  		idx = array_index_nospec(idx, ARRAY_SIZE(data.states));  		amdgpu_dpm_get_pp_num_states(adev, &data);  		state = data.states[idx]; + +		ret = pm_runtime_get_sync(ddev->dev); +		if (ret < 0) +			return ret; +  		/* only set user selected power states */  		if (state != POWER_STATE_TYPE_INTERNAL_BOOT &&  		    state != POWER_STATE_TYPE_DEFAULT) { @@ -510,8 +560,10 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev,  					AMD_PP_TASK_ENABLE_USER_STATE, &state);  			adev->pp_force_state_enabled = true;  		} +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev);  	} -fail: +  	return count;  } @@ -533,17 +585,32 @@ static ssize_t amdgpu_get_pp_table(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	char *table = NULL; -	int size; +	int size, ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		size = smu_sys_get_pp_table(&adev->smu, (void **)&table); +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev);  		if (size < 0)  			return size; -	} -	else if (adev->powerplay.pp_funcs->get_pp_table) +	} else if (adev->powerplay.pp_funcs->get_pp_table) {  		size = amdgpu_dpm_get_pp_table(adev, &table); -	else +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev); +		if (size < 0) +			return size; +	} else { +		pm_runtime_mark_last_busy(ddev->dev); +		pm_runtime_put_autosuspend(ddev->dev);  		return 0; +	}  	if (size >= PAGE_SIZE)  		size = PAGE_SIZE - 1; @@ -562,13 +629,26 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,  	struct amdgpu_device *adev = ddev->dev_private;  	int ret = 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		ret = smu_sys_set_pp_table(&adev->smu, (void *)buf, count); -		if (ret) +		if (ret) { +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev);  			return ret; +		}  	} else if (adev->powerplay.pp_funcs->set_pp_table)  		amdgpu_dpm_set_pp_table(adev, buf, count); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return count;  } @@ -654,6 +734,9 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,  	const char delimiter[3] = {' ', '\n', '\0'};  	uint32_t type; +	if (amdgpu_sriov_vf(adev)) +		return -EINVAL; +  	if (count > 127)  		return -EINVAL; @@ -689,18 +772,28 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,  			tmp_str++;  	} +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		ret = smu_od_edit_dpm_table(&adev->smu, type,  					    parameter, parameter_size); -		if (ret) +		if (ret) { +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev);  			return -EINVAL; +		}  	} else {  		if (adev->powerplay.pp_funcs->odn_edit_dpm_table) {  			ret = amdgpu_dpm_odn_edit_dpm_table(adev, type,  						parameter, parameter_size); -			if (ret) +			if (ret) { +				pm_runtime_mark_last_busy(ddev->dev); +				pm_runtime_put_autosuspend(ddev->dev);  				return -EINVAL; +			}  		}  		if (type == PP_OD_COMMIT_DPM_TABLE) { @@ -708,12 +801,18 @@ static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,  				amdgpu_dpm_dispatch_task(adev,  						AMD_PP_TASK_READJUST_POWER_STATE,  						NULL); +				pm_runtime_mark_last_busy(ddev->dev); +				pm_runtime_put_autosuspend(ddev->dev);  				return count;  			} else { +				pm_runtime_mark_last_busy(ddev->dev); +				pm_runtime_put_autosuspend(ddev->dev);  				return -EINVAL;  			}  		}  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	return count;  } @@ -724,24 +823,33 @@ static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; -	uint32_t size = 0; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		size = smu_print_clk_levels(&adev->smu, SMU_OD_SCLK, buf);  		size += smu_print_clk_levels(&adev->smu, SMU_OD_MCLK, buf+size);  		size += smu_print_clk_levels(&adev->smu, SMU_OD_VDDC_CURVE, buf+size);  		size += smu_print_clk_levels(&adev->smu, SMU_OD_RANGE, buf+size); -		return size;  	} else if (adev->powerplay.pp_funcs->print_clock_levels) {  		size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);  		size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size);  		size += amdgpu_dpm_print_clock_levels(adev, OD_VDDC_CURVE, buf+size);  		size += amdgpu_dpm_print_clock_levels(adev, OD_RANGE, buf+size); -		return size;  	} else { -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n");  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +	return size;  }  /** @@ -770,21 +878,36 @@ static ssize_t amdgpu_set_pp_feature_status(struct device *dev,  	uint64_t featuremask;  	int ret; +	if (amdgpu_sriov_vf(adev)) +		return -EINVAL; +  	ret = kstrtou64(buf, 0, &featuremask);  	if (ret)  		return -EINVAL;  	pr_debug("featuremask = 0x%llx\n", featuremask); +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		ret = smu_sys_set_pp_feature_mask(&adev->smu, featuremask); -		if (ret) +		if (ret) { +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev);  			return -EINVAL; +		}  	} else if (adev->powerplay.pp_funcs->set_ppfeature_status) {  		ret = amdgpu_dpm_set_ppfeature_status(adev, featuremask); -		if (ret) +		if (ret) { +			pm_runtime_mark_last_busy(ddev->dev); +			pm_runtime_put_autosuspend(ddev->dev);  			return -EINVAL; +		}  	} +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	return count;  } @@ -795,13 +918,27 @@ static ssize_t amdgpu_get_pp_feature_status(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; -	if (is_support_sw_smu(adev)) { -		return smu_sys_get_pp_feature_mask(&adev->smu, buf); -	} else if (adev->powerplay.pp_funcs->get_ppfeature_status) -		return amdgpu_dpm_get_ppfeature_status(adev, buf); +	if (amdgpu_sriov_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; + +	if (is_support_sw_smu(adev)) +		size = smu_sys_get_pp_feature_mask(&adev->smu, buf); +	else if (adev->powerplay.pp_funcs->get_ppfeature_status) +		size = amdgpu_dpm_get_ppfeature_status(adev, buf); +	else +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); -	return snprintf(buf, PAGE_SIZE, "\n"); +	return size;  }  /** @@ -840,17 +977,27 @@ static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; -	if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && -	    adev->virt.ops->get_pp_clk) -		return adev->virt.ops->get_pp_clk(adev, PP_SCLK, buf); +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_SCLK, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_SCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  /* @@ -899,18 +1046,25 @@ static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev,  	int ret;  	uint32_t mask = 0; -	if (amdgpu_sriov_vf(adev)) -		return 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL;  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_SCLK, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_SCLK, mask); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	if (ret)  		return -EINVAL; @@ -923,17 +1077,27 @@ static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; -	if (amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev) && -	    adev->virt.ops->get_pp_clk) -		return adev->virt.ops->get_pp_clk(adev, PP_MCLK, buf); +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_MCLK, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_MCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, @@ -943,21 +1107,28 @@ static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; -	int ret;  	uint32_t mask = 0; +	int ret; -	if (amdgpu_sriov_vf(adev)) -		return 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +			return -EINVAL;  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_MCLK, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_MCLK, mask); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	if (ret)  		return -EINVAL; @@ -970,13 +1141,27 @@ static ssize_t amdgpu_get_pp_dpm_socclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_SOCCLK, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_SOCCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_SOCCLK, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_SOCCLK, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev, @@ -989,14 +1174,26 @@ static ssize_t amdgpu_set_pp_dpm_socclk(struct device *dev,  	int ret;  	uint32_t mask = 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL; +  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_SOCCLK, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_SOCCLK, mask); +	else +		ret = 0; + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	if (ret)  		return -EINVAL; @@ -1010,13 +1207,27 @@ static ssize_t amdgpu_get_pp_dpm_fclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_FCLK, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_FCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_FCLK, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_FCLK, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev, @@ -1029,14 +1240,26 @@ static ssize_t amdgpu_set_pp_dpm_fclk(struct device *dev,  	int ret;  	uint32_t mask = 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL; +  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_FCLK, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_FCLK, mask); +	else +		ret = 0; + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	if (ret)  		return -EINVAL; @@ -1050,13 +1273,27 @@ static ssize_t amdgpu_get_pp_dpm_dcefclk(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_DCEFCLK, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_DCEFCLK, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_DCEFCLK, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_DCEFCLK, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev, @@ -1069,14 +1306,26 @@ static ssize_t amdgpu_set_pp_dpm_dcefclk(struct device *dev,  	int ret;  	uint32_t mask = 0; +	if (amdgpu_sriov_vf(adev)) +		return -EINVAL; +  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_DCEFCLK, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_DCEFCLK, mask); +	else +		ret = 0; + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	if (ret)  		return -EINVAL; @@ -1090,13 +1339,27 @@ static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_print_clk_levels(&adev->smu, SMU_PCIE, buf); +		size = smu_print_clk_levels(&adev->smu, SMU_PCIE, buf);  	else if (adev->powerplay.pp_funcs->print_clock_levels) -		return amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); +		size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf);  	else -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); + +	return size;  }  static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, @@ -1109,14 +1372,26 @@ static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev,  	int ret;  	uint32_t mask = 0; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL; +  	ret = amdgpu_read_mask(buf, count, &mask);  	if (ret)  		return ret; +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_force_clk_levels(&adev->smu, SMU_PCIE, mask, true);  	else if (adev->powerplay.pp_funcs->force_clock_level)  		ret = amdgpu_dpm_force_clock_level(adev, PP_PCIE, mask); +	else +		ret = 0; + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev);  	if (ret)  		return -EINVAL; @@ -1131,12 +1406,23 @@ static ssize_t amdgpu_get_pp_sclk_od(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	uint32_t value = 0; +	int ret; + +	if (amdgpu_sriov_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev))  		value = smu_get_od_percentage(&(adev->smu), SMU_OD_SCLK);  	else if (adev->powerplay.pp_funcs->get_sclk_od)  		value = amdgpu_dpm_get_sclk_od(adev); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return snprintf(buf, PAGE_SIZE, "%d\n", value);  } @@ -1150,12 +1436,17 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev,  	int ret;  	long int value; +	if (amdgpu_sriov_vf(adev)) +		return -EINVAL; +  	ret = kstrtol(buf, 0, &value); -	if (ret) { -		count = -EINVAL; -		goto fail; -	} +	if (ret) +		return -EINVAL; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		value = smu_set_od_percentage(&(adev->smu), SMU_OD_SCLK, (uint32_t)value); @@ -1171,7 +1462,9 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev,  		}  	} -fail: +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return count;  } @@ -1182,12 +1475,23 @@ static ssize_t amdgpu_get_pp_mclk_od(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	uint32_t value = 0; +	int ret; + +	if (amdgpu_sriov_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev))  		value = smu_get_od_percentage(&(adev->smu), SMU_OD_MCLK);  	else if (adev->powerplay.pp_funcs->get_mclk_od)  		value = amdgpu_dpm_get_mclk_od(adev); +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return snprintf(buf, PAGE_SIZE, "%d\n", value);  } @@ -1201,12 +1505,17 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,  	int ret;  	long int value; +	if (amdgpu_sriov_vf(adev)) +		return 0; +  	ret = kstrtol(buf, 0, &value); -	if (ret) { -		count = -EINVAL; -		goto fail; -	} +	if (ret) +		return -EINVAL; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		value = smu_set_od_percentage(&(adev->smu), SMU_OD_MCLK, (uint32_t)value); @@ -1222,7 +1531,9 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev,  		}  	} -fail: +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return count;  } @@ -1252,13 +1563,27 @@ static ssize_t amdgpu_get_pp_power_profile_mode(struct device *dev,  {  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	ssize_t size; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) -		return smu_get_power_profile_mode(&adev->smu, buf); +		size = smu_get_power_profile_mode(&adev->smu, buf);  	else if (adev->powerplay.pp_funcs->get_power_profile_mode) -		return amdgpu_dpm_get_power_profile_mode(adev, buf); +		size = amdgpu_dpm_get_power_profile_mode(adev, buf); +	else +		size = snprintf(buf, PAGE_SIZE, "\n"); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); -	return snprintf(buf, PAGE_SIZE, "\n"); +	return size;  } @@ -1283,7 +1608,10 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,  	tmp[1] = '\0';  	ret = kstrtol(tmp, 0, &profile_mode);  	if (ret) -		goto fail; +		return -EINVAL; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return -EINVAL;  	if (profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {  		if (count < 2 || count > 127) @@ -1295,23 +1623,30 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,  		while (tmp_str[0]) {  			sub_str = strsep(&tmp_str, delimiter);  			ret = kstrtol(sub_str, 0, ¶meter[parameter_size]); -			if (ret) { -				count = -EINVAL; -				goto fail; -			} +			if (ret) +				return -EINVAL;  			parameter_size++;  			while (isspace(*tmp_str))  				tmp_str++;  		}  	}  	parameter[parameter_size] = profile_mode; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev))  		ret = smu_set_power_profile_mode(&adev->smu, parameter, parameter_size, true);  	else if (adev->powerplay.pp_funcs->set_power_profile_mode)  		ret = amdgpu_dpm_set_power_profile_mode(adev, parameter, parameter_size); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	if (!ret)  		return count; -fail: +  	return -EINVAL;  } @@ -1331,10 +1666,20 @@ static ssize_t amdgpu_get_busy_percent(struct device *dev,  	struct amdgpu_device *adev = ddev->dev_private;  	int r, value, size = sizeof(value); +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	r = pm_runtime_get_sync(ddev->dev); +	if (r < 0) +		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); +  	if (r)  		return r; @@ -1357,10 +1702,20 @@ static ssize_t amdgpu_get_memory_busy_percent(struct device *dev,  	struct amdgpu_device *adev = ddev->dev_private;  	int r, value, size = sizeof(value); +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	r = pm_runtime_get_sync(ddev->dev); +	if (r < 0) +		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); +  	if (r)  		return r; @@ -1386,8 +1741,20 @@ static ssize_t amdgpu_get_pcie_bw(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private;  	uint64_t count0, count1; +	int ret; + +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; + +	ret = pm_runtime_get_sync(ddev->dev); +	if (ret < 0) +		return ret;  	amdgpu_asic_get_pcie_usage(adev, &count0, &count1); + +	pm_runtime_mark_last_busy(ddev->dev); +	pm_runtime_put_autosuspend(ddev->dev); +  	return snprintf(buf, PAGE_SIZE,	"%llu %llu %i\n",  			count0, count1, pcie_get_mps(adev->pdev));  } @@ -1409,6 +1776,9 @@ static ssize_t amdgpu_get_unique_id(struct device *dev,  	struct drm_device *ddev = dev_get_drvdata(dev);  	struct amdgpu_device *adev = ddev->dev_private; +	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev)) +		return 0; +  	if (adev->unique_id)  		return snprintf(buf, PAGE_SIZE, "%016llx\n", adev->unique_id); @@ -1472,42 +1842,43 @@ static ssize_t amdgpu_hwmon_show_temp(struct device *dev,  				      char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	int channel = to_sensor_dev_attr(attr)->index;  	int r, temp = 0, size = sizeof(temp); -	/* Can't get temperature when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; -  	if (channel >= PP_TEMP_MAX)  		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		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); -		if (r) -			return r;  		break;  	case PP_TEMP_EDGE:  		/* get current edge temperature */  		r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_EDGE_TEMP,  					   (void *)&temp, &size); -		if (r) -			return r;  		break;  	case PP_TEMP_MEM:  		/* get current memory temperature */  		r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MEM_TEMP,  					   (void *)&temp, &size); -		if (r) -			return r; +		break; +	default: +		r = -EINVAL;  		break;  	} +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (r) +		return r; +  	return snprintf(buf, PAGE_SIZE, "%d\n", temp);  } @@ -1603,15 +1974,27 @@ static ssize_t amdgpu_hwmon_get_pwm1_enable(struct device *dev,  {  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	u32 pwm_mode = 0; +	int ret; + +	ret = pm_runtime_get_sync(adev->ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		pwm_mode = smu_get_fan_control_mode(&adev->smu);  	} else { -		if (!adev->powerplay.pp_funcs->get_fan_control_mode) +		if (!adev->powerplay.pp_funcs->get_fan_control_mode) { +			pm_runtime_mark_last_busy(adev->ddev->dev); +			pm_runtime_put_autosuspend(adev->ddev->dev);  			return -EINVAL; +		}  		pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);  	} +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	return sprintf(buf, "%i\n", pwm_mode);  } @@ -1621,27 +2004,32 @@ static ssize_t amdgpu_hwmon_set_pwm1_enable(struct device *dev,  					    size_t count)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	int err; +	int err, ret;  	int value; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; -  	err = kstrtoint(buf, 10, &value);  	if (err)  		return err; +	ret = pm_runtime_get_sync(adev->ddev->dev); +	if (ret < 0) +		return ret; +  	if (is_support_sw_smu(adev)) {  		smu_set_fan_control_mode(&adev->smu, value);  	} else { -		if (!adev->powerplay.pp_funcs->set_fan_control_mode) +		if (!adev->powerplay.pp_funcs->set_fan_control_mode) { +			pm_runtime_mark_last_busy(adev->ddev->dev); +			pm_runtime_put_autosuspend(adev->ddev->dev);  			return -EINVAL; +		}  		amdgpu_dpm_set_fan_control_mode(adev, value);  	} +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	return count;  } @@ -1668,34 +2056,43 @@ static ssize_t amdgpu_hwmon_set_pwm1(struct device *dev,  	u32 value;  	u32 pwm_mode; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; +  	if (is_support_sw_smu(adev))  		pwm_mode = smu_get_fan_control_mode(&adev->smu);  	else  		pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); +  	if (pwm_mode != AMD_FAN_CTRL_MANUAL) {  		pr_info("manual fan speed control should be enabled first\n"); +		pm_runtime_mark_last_busy(adev->ddev->dev); +		pm_runtime_put_autosuspend(adev->ddev->dev);  		return -EINVAL;  	}  	err = kstrtou32(buf, 10, &value); -	if (err) +	if (err) { +		pm_runtime_mark_last_busy(adev->ddev->dev); +		pm_runtime_put_autosuspend(adev->ddev->dev);  		return err; +	}  	value = (value * 100) / 255; -	if (is_support_sw_smu(adev)) { +	if (is_support_sw_smu(adev))  		err = smu_set_fan_speed_percent(&adev->smu, value); -		if (err) -			return err; -	} else if (adev->powerplay.pp_funcs->set_fan_speed_percent) { +	else if (adev->powerplay.pp_funcs->set_fan_speed_percent)  		err = amdgpu_dpm_set_fan_speed_percent(adev, value); -		if (err) -			return err; -	} +	else +		err = -EINVAL; + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (err) +		return err;  	return count;  } @@ -1708,20 +2105,22 @@ static ssize_t amdgpu_hwmon_get_pwm1(struct device *dev,  	int err;  	u32 speed = 0; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; -	if (is_support_sw_smu(adev)) { +	if (is_support_sw_smu(adev))  		err = smu_get_fan_speed_percent(&adev->smu, &speed); -		if (err) -			return err; -	} else if (adev->powerplay.pp_funcs->get_fan_speed_percent) { +	else if (adev->powerplay.pp_funcs->get_fan_speed_percent)  		err = amdgpu_dpm_get_fan_speed_percent(adev, &speed); -		if (err) -			return err; -	} +	else +		err = -EINVAL; + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (err) +		return err;  	speed = (speed * 255) / 100; @@ -1736,20 +2135,22 @@ static ssize_t amdgpu_hwmon_get_fan1_input(struct device *dev,  	int err;  	u32 speed = 0; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; -	if (is_support_sw_smu(adev)) { +	if (is_support_sw_smu(adev))  		err = smu_get_fan_speed_rpm(&adev->smu, &speed); -		if (err) -			return err; -	} else if (adev->powerplay.pp_funcs->get_fan_speed_rpm) { +	else if (adev->powerplay.pp_funcs->get_fan_speed_rpm)  		err = amdgpu_dpm_get_fan_speed_rpm(adev, &speed); -		if (err) -			return err; -	} +	else +		err = -EINVAL; + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (err) +		return err;  	return sprintf(buf, "%i\n", speed);  } @@ -1763,8 +2164,16 @@ static ssize_t amdgpu_hwmon_get_fan1_min(struct device *dev,  	u32 size = sizeof(min_rpm);  	int r; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r; +  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MIN_FAN_RPM,  				   (void *)&min_rpm, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -1780,8 +2189,16 @@ static ssize_t amdgpu_hwmon_get_fan1_max(struct device *dev,  	u32 size = sizeof(max_rpm);  	int r; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r; +  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_MAX_FAN_RPM,  				   (void *)&max_rpm, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -1796,20 +2213,22 @@ static ssize_t amdgpu_hwmon_get_fan1_target(struct device *dev,  	int err;  	u32 rpm = 0; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; -	if (is_support_sw_smu(adev)) { +	if (is_support_sw_smu(adev))  		err = smu_get_fan_speed_rpm(&adev->smu, &rpm); -		if (err) -			return err; -	} else if (adev->powerplay.pp_funcs->get_fan_speed_rpm) { +	else if (adev->powerplay.pp_funcs->get_fan_speed_rpm)  		err = amdgpu_dpm_get_fan_speed_rpm(adev, &rpm); -		if (err) -			return err; -	} +	else +		err = -EINVAL; + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (err) +		return err;  	return sprintf(buf, "%i\n", rpm);  } @@ -1823,32 +2242,40 @@ static ssize_t amdgpu_hwmon_set_fan1_target(struct device *dev,  	u32 value;  	u32 pwm_mode; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; +  	if (is_support_sw_smu(adev))  		pwm_mode = smu_get_fan_control_mode(&adev->smu);  	else  		pwm_mode = amdgpu_dpm_get_fan_control_mode(adev); -	if (pwm_mode != AMD_FAN_CTRL_MANUAL) +	if (pwm_mode != AMD_FAN_CTRL_MANUAL) { +		pm_runtime_mark_last_busy(adev->ddev->dev); +		pm_runtime_put_autosuspend(adev->ddev->dev);  		return -ENODATA; - -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	}  	err = kstrtou32(buf, 10, &value); -	if (err) +	if (err) { +		pm_runtime_mark_last_busy(adev->ddev->dev); +		pm_runtime_put_autosuspend(adev->ddev->dev);  		return err; +	} -	if (is_support_sw_smu(adev)) { +	if (is_support_sw_smu(adev))  		err = smu_set_fan_speed_rpm(&adev->smu, value); -		if (err) -			return err; -	} else if (adev->powerplay.pp_funcs->set_fan_speed_rpm) { +	else if (adev->powerplay.pp_funcs->set_fan_speed_rpm)  		err = amdgpu_dpm_set_fan_speed_rpm(adev, value); -		if (err) -			return err; -	} +	else +		err = -EINVAL; + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	if (err) +		return err;  	return count;  } @@ -1859,15 +2286,27 @@ static ssize_t amdgpu_hwmon_get_fan1_enable(struct device *dev,  {  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	u32 pwm_mode = 0; +	int ret; + +	ret = pm_runtime_get_sync(adev->ddev->dev); +	if (ret < 0) +		return ret;  	if (is_support_sw_smu(adev)) {  		pwm_mode = smu_get_fan_control_mode(&adev->smu);  	} else { -		if (!adev->powerplay.pp_funcs->get_fan_control_mode) +		if (!adev->powerplay.pp_funcs->get_fan_control_mode) { +			pm_runtime_mark_last_busy(adev->ddev->dev); +			pm_runtime_put_autosuspend(adev->ddev->dev);  			return -EINVAL; +		}  		pwm_mode = amdgpu_dpm_get_fan_control_mode(adev);  	} + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	return sprintf(buf, "%i\n", pwm_mode == AMD_FAN_CTRL_AUTO ? 0 : 1);  } @@ -1881,12 +2320,6 @@ static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev,  	int value;  	u32 pwm_mode; -	/* Can't adjust fan when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (adev->ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; - -  	err = kstrtoint(buf, 10, &value);  	if (err)  		return err; @@ -1898,14 +2331,24 @@ static ssize_t amdgpu_hwmon_set_fan1_enable(struct device *dev,  	else  		return -EINVAL; +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; +  	if (is_support_sw_smu(adev)) {  		smu_set_fan_control_mode(&adev->smu, pwm_mode);  	} else { -		if (!adev->powerplay.pp_funcs->set_fan_control_mode) +		if (!adev->powerplay.pp_funcs->set_fan_control_mode) { +			pm_runtime_mark_last_busy(adev->ddev->dev); +			pm_runtime_put_autosuspend(adev->ddev->dev);  			return -EINVAL; +		}  		amdgpu_dpm_set_fan_control_mode(adev, pwm_mode);  	} +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	return count;  } @@ -1914,18 +2357,20 @@ static ssize_t amdgpu_hwmon_show_vddgfx(struct device *dev,  					char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	u32 vddgfx;  	int r, size = sizeof(vddgfx); -	/* Can't get voltage when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	/* get the voltage */  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX,  				   (void *)&vddgfx, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -1944,7 +2389,6 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,  				       char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	u32 vddnb;  	int r, size = sizeof(vddnb); @@ -1952,14 +2396,17 @@ static ssize_t amdgpu_hwmon_show_vddnb(struct device *dev,  	if  (!(adev->flags & AMD_IS_APU))  		return -EINVAL; -	/* Can't get voltage when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	/* get the voltage */  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB,  				   (void *)&vddnb, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -1978,19 +2425,21 @@ static ssize_t amdgpu_hwmon_show_power_avg(struct device *dev,  					   char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	u32 query = 0;  	int r, size = sizeof(u32);  	unsigned uw; -	/* Can't get power when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		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->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -2013,16 +2462,27 @@ static ssize_t amdgpu_hwmon_show_power_cap_max(struct device *dev,  {  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	uint32_t limit = 0; +	ssize_t size; +	int r; + +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	if (is_support_sw_smu(adev)) {  		smu_get_power_limit(&adev->smu, &limit, true, true); -		return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); +		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);  	} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {  		adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, true); -		return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); +		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);  	} else { -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n");  	} + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	return size;  }  static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev, @@ -2031,16 +2491,27 @@ static ssize_t amdgpu_hwmon_show_power_cap(struct device *dev,  {  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	uint32_t limit = 0; +	ssize_t size; +	int r; + +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	if (is_support_sw_smu(adev)) {  		smu_get_power_limit(&adev->smu, &limit, false,  true); -		return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); +		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);  	} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_power_limit) {  		adev->powerplay.pp_funcs->get_power_limit(adev->powerplay.pp_handle, &limit, false); -		return snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000); +		size = snprintf(buf, PAGE_SIZE, "%u\n", limit * 1000000);  	} else { -		return snprintf(buf, PAGE_SIZE, "\n"); +		size = snprintf(buf, PAGE_SIZE, "\n");  	} + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); + +	return size;  } @@ -2053,19 +2524,29 @@ static ssize_t amdgpu_hwmon_set_power_cap(struct device *dev,  	int err;  	u32 value; +	if (amdgpu_sriov_vf(adev)) +		return -EINVAL; +  	err = kstrtou32(buf, 10, &value);  	if (err)  		return err;  	value = value / 1000000; /* convert to Watt */ -	if (is_support_sw_smu(adev)) { + +	err = pm_runtime_get_sync(adev->ddev->dev); +	if (err < 0) +		return err; + +	if (is_support_sw_smu(adev))  		err = smu_set_power_limit(&adev->smu, value); -	} else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_power_limit) { +	else if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->set_power_limit)  		err = adev->powerplay.pp_funcs->set_power_limit(adev->powerplay.pp_handle, value); -	} else { +	else  		err = -EINVAL; -	} + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev);  	if (err)  		return err; @@ -2078,18 +2559,20 @@ static ssize_t amdgpu_hwmon_show_sclk(struct device *dev,  				      char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	uint32_t sclk;  	int r, size = sizeof(sclk); -	/* Can't get voltage when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	/* get the sclk */  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK,  				   (void *)&sclk, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -2108,18 +2591,20 @@ static ssize_t amdgpu_hwmon_show_mclk(struct device *dev,  				      char *buf)  {  	struct amdgpu_device *adev = dev_get_drvdata(dev); -	struct drm_device *ddev = adev->ddev;  	uint32_t mclk;  	int r, size = sizeof(mclk); -	/* Can't get voltage when the card is off */ -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) -		return -EINVAL; +	r = pm_runtime_get_sync(adev->ddev->dev); +	if (r < 0) +		return r;  	/* get the sclk */  	r = amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK,  				   (void *)&mclk, &size); + +	pm_runtime_mark_last_busy(adev->ddev->dev); +	pm_runtime_put_autosuspend(adev->ddev->dev); +  	if (r)  		return r; @@ -2299,6 +2784,23 @@ static umode_t hwmon_attributes_visible(struct kobject *kobj,  	struct amdgpu_device *adev = dev_get_drvdata(dev);  	umode_t effective_mode = attr->mode; +	/* 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; + +	/* there is no fan under pp one vf mode */ +	if (amdgpu_sriov_is_pp_one_vf(adev) && +	    (attr == &sensor_dev_attr_pwm1.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_max.dev_attr.attr || +	     attr == &sensor_dev_attr_pwm1_min.dev_attr.attr || +	     attr == &sensor_dev_attr_fan1_input.dev_attr.attr || +	     attr == &sensor_dev_attr_fan1_min.dev_attr.attr || +	     attr == &sensor_dev_attr_fan1_max.dev_attr.attr || +	     attr == &sensor_dev_attr_fan1_target.dev_attr.attr || +	     attr == &sensor_dev_attr_fan1_enable.dev_attr.attr)) +		return 0; +  	/* Skip fan attributes if fan is not present */  	if (adev->pm.no_fan && (attr == &sensor_dev_attr_pwm1.dev_attr.attr ||  	    attr == &sensor_dev_attr_pwm1_enable.dev_attr.attr || @@ -2666,17 +3168,12 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)  void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)  {  	int ret = 0; -	if (is_support_sw_smu(adev)) { -	    ret = smu_dpm_set_power_gate(&adev->smu, AMD_IP_BLOCK_TYPE_UVD, enable); -	    if (ret) -		DRM_ERROR("[SW SMU]: dpm enable uvd failed, state = %s, ret = %d. \n", -			  enable ? "true" : "false", ret); -	} else if (adev->powerplay.pp_funcs->set_powergating_by_smu) { -		/* enable/disable UVD */ -		mutex_lock(&adev->pm.mutex); -		amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); -		mutex_unlock(&adev->pm.mutex); -	} + +	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); +	if (ret) +		DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", +			  enable ? "enable" : "disable", ret); +  	/* enable/disable Low Memory PState for UVD (4k videos) */  	if (adev->asic_type == CHIP_STONEY &&  		adev->uvd.decode_image_width >= WIDTH_4K) { @@ -2693,17 +3190,11 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)  void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)  {  	int ret = 0; -	if (is_support_sw_smu(adev)) { -	    ret = smu_dpm_set_power_gate(&adev->smu, AMD_IP_BLOCK_TYPE_VCE, enable); -	    if (ret) -		DRM_ERROR("[SW SMU]: dpm enable vce failed, state = %s, ret = %d. \n", -			  enable ? "true" : "false", ret); -	} else if (adev->powerplay.pp_funcs->set_powergating_by_smu) { -		/* enable/disable VCE */ -		mutex_lock(&adev->pm.mutex); -		amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); -		mutex_unlock(&adev->pm.mutex); -	} + +	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); +	if (ret) +		DRM_ERROR("Dpm %s vce failed, ret = %d. \n", +			  enable ? "enable" : "disable", ret);  }  void amdgpu_pm_print_power_states(struct amdgpu_device *adev) @@ -2718,42 +3209,14 @@ void amdgpu_pm_print_power_states(struct amdgpu_device *adev)  } -int amdgpu_pm_virt_sysfs_init(struct amdgpu_device *adev) +void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)  {  	int ret = 0; -	if (!(amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev))) -		return ret; - -	ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); -	if (ret) { -		DRM_ERROR("failed to create device file pp_dpm_sclk\n"); -		return ret; -	} - -	ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk); -	if (ret) { -		DRM_ERROR("failed to create device file pp_dpm_mclk\n"); -		return ret; -	} - -	ret = device_create_file(adev->dev, &dev_attr_power_dpm_force_performance_level); -	if (ret) { -		DRM_ERROR("failed to create device file for dpm state\n"); -		return ret; -	} - -	return ret; -} - -void amdgpu_pm_virt_sysfs_fini(struct amdgpu_device *adev) -{ -	if (!(amdgpu_sriov_vf(adev) && amdgim_is_hwperf(adev))) -		return; - -	device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); -	device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); -	device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); +	ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable); +	if (ret) +		DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n", +			  enable ? "enable" : "disable", ret);  }  int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version) @@ -3163,8 +3626,12 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)  	struct drm_info_node *node = (struct drm_info_node *) m->private;  	struct drm_device *dev = node->minor->dev;  	struct amdgpu_device *adev = dev->dev_private; -	struct drm_device *ddev = adev->ddev;  	u32 flags = 0; +	int r; + +	r = pm_runtime_get_sync(dev->dev); +	if (r < 0) +		return r;  	amdgpu_device_ip_get_clockgating_state(adev, &flags);  	seq_printf(m, "Clock Gating Flags Mask: 0x%x\n", flags); @@ -3173,23 +3640,28 @@ static int amdgpu_debugfs_pm_info(struct seq_file *m, void *data)  	if (!adev->pm.dpm_enabled) {  		seq_printf(m, "dpm not enabled\n"); +		pm_runtime_mark_last_busy(dev->dev); +		pm_runtime_put_autosuspend(dev->dev);  		return 0;  	} -	if  ((adev->flags & AMD_IS_PX) && -	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) { -		seq_printf(m, "PX asic powered off\n"); -	} else if (!is_support_sw_smu(adev) && adev->powerplay.pp_funcs->debugfs_print_current_performance_level) { + +	if (!is_support_sw_smu(adev) && +	    adev->powerplay.pp_funcs->debugfs_print_current_performance_level) {  		mutex_lock(&adev->pm.mutex);  		if (adev->powerplay.pp_funcs->debugfs_print_current_performance_level)  			adev->powerplay.pp_funcs->debugfs_print_current_performance_level(adev, m);  		else  			seq_printf(m, "Debugfs support not implemented for this asic\n");  		mutex_unlock(&adev->pm.mutex); +		r = 0;  	} else { -		return amdgpu_debugfs_pm_info_pp(m, adev); +		r = amdgpu_debugfs_pm_info_pp(m, adev);  	} -	return 0; +	pm_runtime_mark_last_busy(dev->dev); +	pm_runtime_put_autosuspend(dev->dev); + +	return r;  }  static const struct drm_info_list amdgpu_pm_info_list[] = { |