diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 329 |
1 files changed, 145 insertions, 184 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 7df503aedb69..a59e04f3eeba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
| @@ -64,17 +64,13 @@ static const struct cg_flag_name clocks[] = { | |||
| 64 | 64 | ||
| 65 | void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) | 65 | void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev) |
| 66 | { | 66 | { |
| 67 | if (adev->pp_enabled) | ||
| 68 | /* TODO */ | ||
| 69 | return; | ||
| 70 | |||
| 71 | if (adev->pm.dpm_enabled) { | 67 | if (adev->pm.dpm_enabled) { |
| 72 | mutex_lock(&adev->pm.mutex); | 68 | mutex_lock(&adev->pm.mutex); |
| 73 | if (power_supply_is_system_supplied() > 0) | 69 | if (power_supply_is_system_supplied() > 0) |
| 74 | adev->pm.dpm.ac_power = true; | 70 | adev->pm.dpm.ac_power = true; |
| 75 | else | 71 | else |
| 76 | adev->pm.dpm.ac_power = false; | 72 | adev->pm.dpm.ac_power = false; |
| 77 | if (adev->pm.funcs->enable_bapm) | 73 | if (adev->powerplay.pp_funcs->enable_bapm) |
| 78 | amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power); | 74 | amdgpu_dpm_enable_bapm(adev, adev->pm.dpm.ac_power); |
| 79 | mutex_unlock(&adev->pm.mutex); | 75 | mutex_unlock(&adev->pm.mutex); |
| 80 | } | 76 | } |
| @@ -88,9 +84,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev, | |||
| 88 | struct amdgpu_device *adev = ddev->dev_private; | 84 | struct amdgpu_device *adev = ddev->dev_private; |
| 89 | enum amd_pm_state_type pm; | 85 | enum amd_pm_state_type pm; |
| 90 | 86 | ||
| 91 | if (adev->pp_enabled) { | 87 | if (adev->powerplay.pp_funcs->get_current_power_state) |
| 92 | pm = amdgpu_dpm_get_current_power_state(adev); | 88 | pm = amdgpu_dpm_get_current_power_state(adev); |
| 93 | } else | 89 | else |
| 94 | pm = adev->pm.dpm.user_state; | 90 | pm = adev->pm.dpm.user_state; |
| 95 | 91 | ||
| 96 | return snprintf(buf, PAGE_SIZE, "%s\n", | 92 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| @@ -118,8 +114,8 @@ static ssize_t amdgpu_set_dpm_state(struct device *dev, | |||
| 118 | goto fail; | 114 | goto fail; |
| 119 | } | 115 | } |
| 120 | 116 | ||
| 121 | if (adev->pp_enabled) { | 117 | if (adev->powerplay.pp_funcs->dispatch_tasks) { |
| 122 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); | 118 | amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL); |
| 123 | } else { | 119 | } else { |
| 124 | mutex_lock(&adev->pm.mutex); | 120 | mutex_lock(&adev->pm.mutex); |
| 125 | adev->pm.dpm.user_state = state; | 121 | adev->pm.dpm.user_state = state; |
| @@ -140,13 +136,17 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, | |||
| 140 | { | 136 | { |
| 141 | struct drm_device *ddev = dev_get_drvdata(dev); | 137 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 142 | struct amdgpu_device *adev = ddev->dev_private; | 138 | struct amdgpu_device *adev = ddev->dev_private; |
| 143 | enum amd_dpm_forced_level level; | 139 | enum amd_dpm_forced_level level = 0xff; |
| 144 | 140 | ||
| 145 | if ((adev->flags & AMD_IS_PX) && | 141 | if ((adev->flags & AMD_IS_PX) && |
| 146 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | 142 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) |
| 147 | return snprintf(buf, PAGE_SIZE, "off\n"); | 143 | return snprintf(buf, PAGE_SIZE, "off\n"); |
| 148 | 144 | ||
| 149 | level = amdgpu_dpm_get_performance_level(adev); | 145 | if (adev->powerplay.pp_funcs->get_performance_level) |
| 146 | level = amdgpu_dpm_get_performance_level(adev); | ||
| 147 | else | ||
| 148 | level = adev->pm.dpm.forced_level; | ||
| 149 | |||
| 150 | return snprintf(buf, PAGE_SIZE, "%s\n", | 150 | return snprintf(buf, PAGE_SIZE, "%s\n", |
| 151 | (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : | 151 | (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : |
| 152 | (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : | 152 | (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : |
| @@ -167,7 +167,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
| 167 | struct drm_device *ddev = dev_get_drvdata(dev); | 167 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 168 | struct amdgpu_device *adev = ddev->dev_private; | 168 | struct amdgpu_device *adev = ddev->dev_private; |
| 169 | enum amd_dpm_forced_level level; | 169 | enum amd_dpm_forced_level level; |
| 170 | enum amd_dpm_forced_level current_level; | 170 | enum amd_dpm_forced_level current_level = 0xff; |
| 171 | int ret = 0; | 171 | int ret = 0; |
| 172 | 172 | ||
| 173 | /* Can't force performance level when the card is off */ | 173 | /* Can't force performance level when the card is off */ |
| @@ -175,7 +175,8 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
| 175 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) | 175 | (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) |
| 176 | return -EINVAL; | 176 | return -EINVAL; |
| 177 | 177 | ||
| 178 | current_level = amdgpu_dpm_get_performance_level(adev); | 178 | if (adev->powerplay.pp_funcs->get_performance_level) |
| 179 | current_level = amdgpu_dpm_get_performance_level(adev); | ||
| 179 | 180 | ||
| 180 | if (strncmp("low", buf, strlen("low")) == 0) { | 181 | if (strncmp("low", buf, strlen("low")) == 0) { |
| 181 | level = AMD_DPM_FORCED_LEVEL_LOW; | 182 | level = AMD_DPM_FORCED_LEVEL_LOW; |
| @@ -203,9 +204,7 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, | |||
| 203 | if (current_level == level) | 204 | if (current_level == level) |
| 204 | return count; | 205 | return count; |
| 205 | 206 | ||
| 206 | if (adev->pp_enabled) | 207 | if (adev->powerplay.pp_funcs->force_performance_level) { |
| 207 | amdgpu_dpm_force_performance_level(adev, level); | ||
| 208 | else { | ||
| 209 | mutex_lock(&adev->pm.mutex); | 208 | mutex_lock(&adev->pm.mutex); |
| 210 | if (adev->pm.dpm.thermal_active) { | 209 | if (adev->pm.dpm.thermal_active) { |
| 211 | count = -EINVAL; | 210 | count = -EINVAL; |
| @@ -233,7 +232,7 @@ static ssize_t amdgpu_get_pp_num_states(struct device *dev, | |||
| 233 | struct pp_states_info data; | 232 | struct pp_states_info data; |
| 234 | int i, buf_len; | 233 | int i, buf_len; |
| 235 | 234 | ||
| 236 | if (adev->pp_enabled) | 235 | if (adev->powerplay.pp_funcs->get_pp_num_states) |
| 237 | amdgpu_dpm_get_pp_num_states(adev, &data); | 236 | amdgpu_dpm_get_pp_num_states(adev, &data); |
| 238 | 237 | ||
| 239 | buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); | 238 | buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); |
| @@ -257,8 +256,8 @@ static ssize_t amdgpu_get_pp_cur_state(struct device *dev, | |||
| 257 | enum amd_pm_state_type pm = 0; | 256 | enum amd_pm_state_type pm = 0; |
| 258 | int i = 0; | 257 | int i = 0; |
| 259 | 258 | ||
| 260 | if (adev->pp_enabled) { | 259 | if (adev->powerplay.pp_funcs->get_current_power_state |
| 261 | 260 | && adev->powerplay.pp_funcs->get_pp_num_states) { | |
| 262 | pm = amdgpu_dpm_get_current_power_state(adev); | 261 | pm = amdgpu_dpm_get_current_power_state(adev); |
| 263 | amdgpu_dpm_get_pp_num_states(adev, &data); | 262 | amdgpu_dpm_get_pp_num_states(adev, &data); |
| 264 | 263 | ||
| @@ -280,25 +279,10 @@ static ssize_t amdgpu_get_pp_force_state(struct device *dev, | |||
| 280 | { | 279 | { |
| 281 | struct drm_device *ddev = dev_get_drvdata(dev); | 280 | struct drm_device *ddev = dev_get_drvdata(dev); |
| 282 | struct amdgpu_device *adev = ddev->dev_private; | 281 | struct amdgpu_device *adev = ddev->dev_private; |
| 283 | struct pp_states_info data; | ||
| 284 | enum amd_pm_state_type pm = 0; | ||
| 285 | int i; | ||
| 286 | 282 | ||
| 287 | if (adev->pp_force_state_enabled && adev->pp_enabled) { | 283 | if (adev->pp_force_state_enabled) |
| 288 | pm = amdgpu_dpm_get_current_power_state(adev); | 284 | return amdgpu_get_pp_cur_state(dev, attr, buf); |
| 289 | amdgpu_dpm_get_pp_num_states(adev, &data); | 285 | else |
| 290 | |||
| 291 | for (i = 0; i < data.nums; i++) { | ||
| 292 | if (pm == data.states[i]) | ||
| 293 | break; | ||
| 294 | } | ||
| 295 | |||
| 296 | if (i == data.nums) | ||
| 297 | i = -EINVAL; | ||
| 298 | |||
| 299 | return snprintf(buf, PAGE_SIZE, "%d\n", i); | ||
| 300 | |||
| 301 | } else | ||
| 302 | return snprintf(buf, PAGE_SIZE, "\n"); | 286 | return snprintf(buf, PAGE_SIZE, "\n"); |
| 303 | } | 287 | } |
| 304 | 288 | ||
| @@ -315,7 +299,8 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
| 315 | 299 | ||
| 316 | if (strlen(buf) == 1) | 300 | if (strlen(buf) == 1) |
| 317 | adev->pp_force_state_enabled = false; | 301 | adev->pp_force_state_enabled = false; |
| 318 | else if (adev->pp_enabled) { | 302 | else if (adev->powerplay.pp_funcs->dispatch_tasks && |
| 303 | adev->powerplay.pp_funcs->get_pp_num_states) { | ||
| 319 | struct pp_states_info data; | 304 | struct pp_states_info data; |
| 320 | 305 | ||
| 321 | ret = kstrtoul(buf, 0, &idx); | 306 | ret = kstrtoul(buf, 0, &idx); |
| @@ -330,7 +315,7 @@ static ssize_t amdgpu_set_pp_force_state(struct device *dev, | |||
| 330 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && | 315 | if (state != POWER_STATE_TYPE_INTERNAL_BOOT && |
| 331 | state != POWER_STATE_TYPE_DEFAULT) { | 316 | state != POWER_STATE_TYPE_DEFAULT) { |
| 332 | amdgpu_dpm_dispatch_task(adev, | 317 | amdgpu_dpm_dispatch_task(adev, |
| 333 | AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); | 318 | AMD_PP_TASK_ENABLE_USER_STATE, &state, NULL); |
| 334 | adev->pp_force_state_enabled = true; | 319 | |
