Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/powerplay: add some sysfs interfaces for powerplay.

The new sysfs interfaces:
pp_num_states: Read-only, return the number of all pp states, 0 if powerplay is not available.
pp_cur_state: Read-only, return the index number of current pp state.
pp_force_state: Read-write, to write a power state index will switch to selected state forcedly and
enable forced state mode, disable forced state mode. such as "echo >...".
pp_table: Read-write, binary output, to be used to read or write the dpm table, the maximum
file size is 4KB of page size.
pp_dpm_sclk: Read-write, reading will return a dpm levels list, to write an index number will force
powerplay to set the corresponding dpm level.
pp_dpm_mclk: same as sclk.
pp_dpm_pcie: same as sclk.

And add new setting "manual" to the existing interface power_dpm_force_performance_level.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Eric Huang and committed by
Alex Deucher
f3898ea1 c7e6be23

+488 -2
+17
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1503 1503 AMDGPU_DPM_FORCED_LEVEL_AUTO = 0, 1504 1504 AMDGPU_DPM_FORCED_LEVEL_LOW = 1, 1505 1505 AMDGPU_DPM_FORCED_LEVEL_HIGH = 2, 1506 + AMDGPU_DPM_FORCED_LEVEL_MANUAL = 3, 1506 1507 }; 1507 1508 1508 1509 struct amdgpu_vce_state { ··· 2015 2014 /* powerplay */ 2016 2015 struct amd_powerplay powerplay; 2017 2016 bool pp_enabled; 2017 + bool pp_force_state_enabled; 2018 2018 2019 2019 /* dpm */ 2020 2020 struct amdgpu_pm pm; ··· 2302 2300 2303 2301 #define amdgpu_dpm_get_performance_level(adev) \ 2304 2302 (adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle) 2303 + 2304 + #define amdgpu_dpm_get_pp_num_states(adev, data) \ 2305 + (adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data) 2306 + 2307 + #define amdgpu_dpm_get_pp_table(adev, table) \ 2308 + (adev)->powerplay.pp_funcs->get_pp_table((adev)->powerplay.pp_handle, table) 2309 + 2310 + #define amdgpu_dpm_set_pp_table(adev, buf, size) \ 2311 + (adev)->powerplay.pp_funcs->set_pp_table((adev)->powerplay.pp_handle, buf, size) 2312 + 2313 + #define amdgpu_dpm_print_clock_levels(adev, type, buf) \ 2314 + (adev)->powerplay.pp_funcs->print_clock_levels((adev)->powerplay.pp_handle, type, buf) 2315 + 2316 + #define amdgpu_dpm_force_clock_level(adev, type, level) \ 2317 + (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level) 2305 2318 2306 2319 #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ 2307 2320 (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output))
+335 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
··· 119 119 level = amdgpu_dpm_get_performance_level(adev); 120 120 return snprintf(buf, PAGE_SIZE, "%s\n", 121 121 (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : 122 - (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); 122 + (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : 123 + (level == AMD_DPM_FORCED_LEVEL_HIGH) ? "high" : 124 + (level == AMD_DPM_FORCED_LEVEL_MANUAL) ? "manual" : "unknown"); 123 125 } else { 124 126 enum amdgpu_dpm_forced_level level; 125 127 ··· 148 146 level = AMDGPU_DPM_FORCED_LEVEL_HIGH; 149 147 } else if (strncmp("auto", buf, strlen("auto")) == 0) { 150 148 level = AMDGPU_DPM_FORCED_LEVEL_AUTO; 149 + } else if (strncmp("manual", buf, strlen("manual")) == 0) { 150 + level = AMDGPU_DPM_FORCED_LEVEL_MANUAL; 151 151 } else { 152 152 count = -EINVAL; 153 153 goto fail; ··· 176 172 return count; 177 173 } 178 174 175 + static ssize_t amdgpu_get_pp_num_states(struct device *dev, 176 + struct device_attribute *attr, 177 + char *buf) 178 + { 179 + struct drm_device *ddev = dev_get_drvdata(dev); 180 + struct amdgpu_device *adev = ddev->dev_private; 181 + struct pp_states_info data; 182 + int i, buf_len; 183 + 184 + if (adev->pp_enabled) 185 + amdgpu_dpm_get_pp_num_states(adev, &data); 186 + 187 + buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); 188 + for (i = 0; i < data.nums; i++) 189 + buf_len += snprintf(buf + buf_len, PAGE_SIZE, "%d %s\n", i, 190 + (data.states[i] == POWER_STATE_TYPE_INTERNAL_BOOT) ? "boot" : 191 + (data.states[i] == POWER_STATE_TYPE_BATTERY) ? "battery" : 192 + (data.states[i] == POWER_STATE_TYPE_BALANCED) ? "balanced" : 193 + (data.states[i] == POWER_STATE_TYPE_PERFORMANCE) ? "performance" : "default"); 194 + 195 + return buf_len; 196 + } 197 + 198 + static ssize_t amdgpu_get_pp_cur_state(struct device *dev, 199 + struct device_attribute *attr, 200 + char *buf) 201 + { 202 + struct drm_device *ddev = dev_get_drvdata(dev); 203 + struct amdgpu_device *adev = ddev->dev_private; 204 + struct pp_states_info data; 205 + enum amd_pm_state_type pm = 0; 206 + int i = 0; 207 + 208 + if (adev->pp_enabled) { 209 + 210 + pm = amdgpu_dpm_get_current_power_state(adev); 211 + amdgpu_dpm_get_pp_num_states(adev, &data); 212 + 213 + for (i = 0; i < data.nums; i++) { 214 + if (pm == data.states[i]) 215 + break; 216 + } 217 + 218 + if (i == data.nums) 219 + i = -EINVAL; 220 + } 221 + 222 + return snprintf(buf, PAGE_SIZE, "%d\n", i); 223 + } 224 + 225 + static ssize_t amdgpu_get_pp_force_state(struct device *dev, 226 + struct device_attribute *attr, 227 + char *buf) 228 + { 229 + struct drm_device *ddev = dev_get_drvdata(dev); 230 + struct amdgpu_device *adev = ddev->dev_private; 231 + struct pp_states_info data; 232 + enum amd_pm_state_type pm = 0; 233 + int i; 234 + 235 + if (adev->pp_force_state_enabled && adev->pp_enabled) { 236 + pm = amdgpu_dpm_get_current_power_state(adev); 237 + amdgpu_dpm_get_pp_num_states(adev, &data); 238 + 239 + for (i = 0; i < data.nums; i++) { 240 + if (pm == data.states[i]) 241 + break; 242 + } 243 + 244 + if (i == data.nums) 245 + i = -EINVAL; 246 + 247 + return snprintf(buf, PAGE_SIZE, "%d\n", i); 248 + 249 + } else 250 + return snprintf(buf, PAGE_SIZE, "\n"); 251 + } 252 + 253 + static ssize_t amdgpu_set_pp_force_state(struct device *dev, 254 + struct device_attribute *attr, 255 + const char *buf, 256 + size_t count) 257 + { 258 + struct drm_device *ddev = dev_get_drvdata(dev); 259 + struct amdgpu_device *adev = ddev->dev_private; 260 + enum amd_pm_state_type state = 0; 261 + long idx; 262 + int ret; 263 + 264 + if (strlen(buf) == 1) 265 + adev->pp_force_state_enabled = false; 266 + else { 267 + ret = kstrtol(buf, 0, &idx); 268 + 269 + if (ret) { 270 + count = -EINVAL; 271 + goto fail; 272 + } 273 + 274 + if (adev->pp_enabled) { 275 + struct pp_states_info data; 276 + amdgpu_dpm_get_pp_num_states(adev, &data); 277 + state = data.states[idx]; 278 + /* only set user selected power states */ 279 + if (state != POWER_STATE_TYPE_INTERNAL_BOOT && 280 + state != POWER_STATE_TYPE_DEFAULT) { 281 + amdgpu_dpm_dispatch_task(adev, 282 + AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); 283 + adev->pp_force_state_enabled = true; 284 + } 285 + } 286 + } 287 + fail: 288 + return count; 289 + } 290 + 291 + static ssize_t amdgpu_get_pp_table(struct device *dev, 292 + struct device_attribute *attr, 293 + char *buf) 294 + { 295 + struct drm_device *ddev = dev_get_drvdata(dev); 296 + struct amdgpu_device *adev = ddev->dev_private; 297 + char *table = NULL; 298 + int size, i; 299 + 300 + if (adev->pp_enabled) 301 + size = amdgpu_dpm_get_pp_table(adev, &table); 302 + else 303 + return 0; 304 + 305 + if (size >= PAGE_SIZE) 306 + size = PAGE_SIZE - 1; 307 + 308 + for (i = 0; i < size; i++) { 309 + sprintf(buf + i, "%02x", table[i]); 310 + } 311 + sprintf(buf + i, "\n"); 312 + 313 + return size; 314 + } 315 + 316 + static ssize_t amdgpu_set_pp_table(struct device *dev, 317 + struct device_attribute *attr, 318 + const char *buf, 319 + size_t count) 320 + { 321 + struct drm_device *ddev = dev_get_drvdata(dev); 322 + struct amdgpu_device *adev = ddev->dev_private; 323 + 324 + if (adev->pp_enabled) 325 + amdgpu_dpm_set_pp_table(adev, buf, count); 326 + 327 + return count; 328 + } 329 + 330 + static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, 331 + struct device_attribute *attr, 332 + char *buf) 333 + { 334 + struct drm_device *ddev = dev_get_drvdata(dev); 335 + struct amdgpu_device *adev = ddev->dev_private; 336 + ssize_t size = 0; 337 + 338 + if (adev->pp_enabled) 339 + size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); 340 + 341 + return size; 342 + } 343 + 344 + static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, 345 + struct device_attribute *attr, 346 + const char *buf, 347 + size_t count) 348 + { 349 + struct drm_device *ddev = dev_get_drvdata(dev); 350 + struct amdgpu_device *adev = ddev->dev_private; 351 + int ret; 352 + long level; 353 + 354 + ret = kstrtol(buf, 0, &level); 355 + 356 + if (ret) { 357 + count = -EINVAL; 358 + goto fail; 359 + } 360 + 361 + if (adev->pp_enabled) 362 + amdgpu_dpm_force_clock_level(adev, PP_SCLK, level); 363 + fail: 364 + return count; 365 + } 366 + 367 + static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, 368 + struct device_attribute *attr, 369 + char *buf) 370 + { 371 + struct drm_device *ddev = dev_get_drvdata(dev); 372 + struct amdgpu_device *adev = ddev->dev_private; 373 + ssize_t size = 0; 374 + 375 + if (adev->pp_enabled) 376 + size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); 377 + 378 + return size; 379 + } 380 + 381 + static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, 382 + struct device_attribute *attr, 383 + const char *buf, 384 + size_t count) 385 + { 386 + struct drm_device *ddev = dev_get_drvdata(dev); 387 + struct amdgpu_device *adev = ddev->dev_private; 388 + int ret; 389 + long level; 390 + 391 + ret = kstrtol(buf, 0, &level); 392 + 393 + if (ret) { 394 + count = -EINVAL; 395 + goto fail; 396 + } 397 + 398 + if (adev->pp_enabled) 399 + amdgpu_dpm_force_clock_level(adev, PP_MCLK, level); 400 + fail: 401 + return count; 402 + } 403 + 404 + static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, 405 + struct device_attribute *attr, 406 + char *buf) 407 + { 408 + struct drm_device *ddev = dev_get_drvdata(dev); 409 + struct amdgpu_device *adev = ddev->dev_private; 410 + ssize_t size = 0; 411 + 412 + if (adev->pp_enabled) 413 + size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); 414 + 415 + return size; 416 + } 417 + 418 + static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, 419 + struct device_attribute *attr, 420 + const char *buf, 421 + size_t count) 422 + { 423 + struct drm_device *ddev = dev_get_drvdata(dev); 424 + struct amdgpu_device *adev = ddev->dev_private; 425 + int ret; 426 + long level; 427 + 428 + ret = kstrtol(buf, 0, &level); 429 + 430 + if (ret) { 431 + count = -EINVAL; 432 + goto fail; 433 + } 434 + 435 + if (adev->pp_enabled) 436 + amdgpu_dpm_force_clock_level(adev, PP_PCIE, level); 437 + fail: 438 + return count; 439 + } 440 + 179 441 static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); 180 442 static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, 181 443 amdgpu_get_dpm_forced_performance_level, 182 444 amdgpu_set_dpm_forced_performance_level); 445 + static DEVICE_ATTR(pp_num_states, S_IRUGO, amdgpu_get_pp_num_states, NULL); 446 + static DEVICE_ATTR(pp_cur_state, S_IRUGO, amdgpu_get_pp_cur_state, NULL); 447 + static DEVICE_ATTR(pp_force_state, S_IRUGO | S_IWUSR, 448 + amdgpu_get_pp_force_state, 449 + amdgpu_set_pp_force_state); 450 + static DEVICE_ATTR(pp_table, S_IRUGO | S_IWUSR, 451 + amdgpu_get_pp_table, 452 + amdgpu_set_pp_table); 453 + static DEVICE_ATTR(pp_dpm_sclk, S_IRUGO | S_IWUSR, 454 + amdgpu_get_pp_dpm_sclk, 455 + amdgpu_set_pp_dpm_sclk); 456 + static DEVICE_ATTR(pp_dpm_mclk, S_IRUGO | S_IWUSR, 457 + amdgpu_get_pp_dpm_mclk, 458 + amdgpu_set_pp_dpm_mclk); 459 + static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR, 460 + amdgpu_get_pp_dpm_pcie, 461 + amdgpu_set_pp_dpm_pcie); 183 462 184 463 static ssize_t amdgpu_hwmon_show_temp(struct device *dev, 185 464 struct device_attribute *attr, ··· 1052 765 DRM_ERROR("failed to create device file for dpm state\n"); 1053 766 return ret; 1054 767 } 768 + 769 + if (adev->pp_enabled) { 770 + ret = device_create_file(adev->dev, &dev_attr_pp_num_states); 771 + if (ret) { 772 + DRM_ERROR("failed to create device file pp_num_states\n"); 773 + return ret; 774 + } 775 + ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); 776 + if (ret) { 777 + DRM_ERROR("failed to create device file pp_cur_state\n"); 778 + return ret; 779 + } 780 + ret = device_create_file(adev->dev, &dev_attr_pp_force_state); 781 + if (ret) { 782 + DRM_ERROR("failed to create device file pp_force_state\n"); 783 + return ret; 784 + } 785 + ret = device_create_file(adev->dev, &dev_attr_pp_table); 786 + if (ret) { 787 + DRM_ERROR("failed to create device file pp_table\n"); 788 + return ret; 789 + } 790 + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); 791 + if (ret) { 792 + DRM_ERROR("failed to create device file pp_dpm_sclk\n"); 793 + return ret; 794 + } 795 + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk); 796 + if (ret) { 797 + DRM_ERROR("failed to create device file pp_dpm_mclk\n"); 798 + return ret; 799 + } 800 + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie); 801 + if (ret) { 802 + DRM_ERROR("failed to create device file pp_dpm_pcie\n"); 803 + return ret; 804 + } 805 + } 1055 806 ret = amdgpu_debugfs_pm_init(adev); 1056 807 if (ret) { 1057 808 DRM_ERROR("Failed to register debugfs file for dpm!\n"); ··· 1107 782 hwmon_device_unregister(adev->pm.int_hwmon_dev); 1108 783 device_remove_file(adev->dev, &dev_attr_power_dpm_state); 1109 784 device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); 785 + if (adev->pp_enabled) { 786 + device_remove_file(adev->dev, &dev_attr_pp_num_states); 787 + device_remove_file(adev->dev, &dev_attr_pp_cur_state); 788 + device_remove_file(adev->dev, &dev_attr_pp_force_state); 789 + device_remove_file(adev->dev, &dev_attr_pp_table); 790 + device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); 791 + device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); 792 + device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); 793 + } 1110 794 } 1111 795 1112 796 void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
+115 -1
drivers/gpu/drm/amd/powerplay/amd_powerplay.c
··· 433 433 case PP_StateUILabel_Performance: 434 434 return POWER_STATE_TYPE_PERFORMANCE; 435 435 default: 436 - return POWER_STATE_TYPE_DEFAULT; 436 + if (state->classification.flags & PP_StateClassificationFlag_Boot) 437 + return POWER_STATE_TYPE_INTERNAL_BOOT; 438 + else 439 + return POWER_STATE_TYPE_DEFAULT; 437 440 } 438 441 } 439 442 ··· 538 535 return hwmgr->hwmgr_func->get_temperature(hwmgr); 539 536 } 540 537 538 + static int pp_dpm_get_pp_num_states(void *handle, 539 + struct pp_states_info *data) 540 + { 541 + struct pp_hwmgr *hwmgr; 542 + int i; 543 + 544 + if (!handle) 545 + return -EINVAL; 546 + 547 + hwmgr = ((struct pp_instance *)handle)->hwmgr; 548 + 549 + if (hwmgr == NULL || hwmgr->ps == NULL) 550 + return -EINVAL; 551 + 552 + data->nums = hwmgr->num_ps; 553 + 554 + for (i = 0; i < hwmgr->num_ps; i++) { 555 + struct pp_power_state *state = (struct pp_power_state *) 556 + ((unsigned long)hwmgr->ps + i * hwmgr->ps_size); 557 + switch (state->classification.ui_label) { 558 + case PP_StateUILabel_Battery: 559 + data->states[i] = POWER_STATE_TYPE_BATTERY; 560 + break; 561 + case PP_StateUILabel_Balanced: 562 + data->states[i] = POWER_STATE_TYPE_BALANCED; 563 + break; 564 + case PP_StateUILabel_Performance: 565 + data->states[i] = POWER_STATE_TYPE_PERFORMANCE; 566 + break; 567 + default: 568 + if (state->classification.flags & PP_StateClassificationFlag_Boot) 569 + data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT; 570 + else 571 + data->states[i] = POWER_STATE_TYPE_DEFAULT; 572 + } 573 + } 574 + 575 + return 0; 576 + } 577 + 578 + static int pp_dpm_get_pp_table(void *handle, char **table) 579 + { 580 + struct pp_hwmgr *hwmgr; 581 + 582 + if (!handle) 583 + return -EINVAL; 584 + 585 + hwmgr = ((struct pp_instance *)handle)->hwmgr; 586 + 587 + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || 588 + hwmgr->hwmgr_func->get_pp_table == NULL) 589 + return -EINVAL; 590 + 591 + return hwmgr->hwmgr_func->get_pp_table(hwmgr, table); 592 + } 593 + 594 + static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) 595 + { 596 + struct pp_hwmgr *hwmgr; 597 + 598 + if (!handle) 599 + return -EINVAL; 600 + 601 + hwmgr = ((struct pp_instance *)handle)->hwmgr; 602 + 603 + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || 604 + hwmgr->hwmgr_func->set_pp_table == NULL) 605 + return -EINVAL; 606 + 607 + return hwmgr->hwmgr_func->set_pp_table(hwmgr, buf, size); 608 + } 609 + 610 + static int pp_dpm_force_clock_level(void *handle, 611 + enum pp_clock_type type, int level) 612 + { 613 + struct pp_hwmgr *hwmgr; 614 + 615 + if (!handle) 616 + return -EINVAL; 617 + 618 + hwmgr = ((struct pp_instance *)handle)->hwmgr; 619 + 620 + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || 621 + hwmgr->hwmgr_func->force_clock_level == NULL) 622 + return -EINVAL; 623 + 624 + return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, level); 625 + } 626 + 627 + static int pp_dpm_print_clock_levels(void *handle, 628 + enum pp_clock_type type, char *buf) 629 + { 630 + struct pp_hwmgr *hwmgr; 631 + 632 + if (!handle) 633 + return -EINVAL; 634 + 635 + hwmgr = ((struct pp_instance *)handle)->hwmgr; 636 + 637 + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || 638 + hwmgr->hwmgr_func->print_clock_levels == NULL) 639 + return -EINVAL; 640 + 641 + return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf); 642 + } 643 + 541 644 const struct amd_powerplay_funcs pp_dpm_funcs = { 542 645 .get_temperature = pp_dpm_get_temperature, 543 646 .load_firmware = pp_dpm_load_fw, ··· 661 552 .get_fan_control_mode = pp_dpm_get_fan_control_mode, 662 553 .set_fan_speed_percent = pp_dpm_set_fan_speed_percent, 663 554 .get_fan_speed_percent = pp_dpm_get_fan_speed_percent, 555 + .get_pp_num_states = pp_dpm_get_pp_num_states, 556 + .get_pp_table = pp_dpm_get_pp_table, 557 + .set_pp_table = pp_dpm_set_pp_table, 558 + .force_clock_level = pp_dpm_force_clock_level, 559 + .print_clock_levels = pp_dpm_print_clock_levels, 664 560 }; 665 561 666 562 static int amd_pp_instance_init(struct amd_pp_init *pp_init,
+17
drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
··· 123 123 AMD_DPM_FORCED_LEVEL_AUTO = 0, 124 124 AMD_DPM_FORCED_LEVEL_LOW = 1, 125 125 AMD_DPM_FORCED_LEVEL_HIGH = 2, 126 + AMD_DPM_FORCED_LEVEL_MANUAL = 3, 126 127 }; 127 128 128 129 struct amd_pp_init { ··· 226 225 PP_GROUP_MAX 227 226 }; 228 227 228 + enum pp_clock_type { 229 + PP_SCLK, 230 + PP_MCLK, 231 + PP_PCIE, 232 + }; 233 + 234 + struct pp_states_info { 235 + uint32_t nums; 236 + uint32_t states[16]; 237 + }; 238 + 229 239 #define PP_GROUP_MASK 0xF0000000 230 240 #define PP_GROUP_SHIFT 28 231 241 ··· 290 278 int (*get_fan_control_mode)(void *handle); 291 279 int (*set_fan_speed_percent)(void *handle, uint32_t percent); 292 280 int (*get_fan_speed_percent)(void *handle, uint32_t *speed); 281 + int (*get_pp_num_states)(void *handle, struct pp_states_info *data); 282 + int (*get_pp_table)(void *handle, char **table); 283 + int (*set_pp_table)(void *handle, const char *buf, size_t size); 284 + int (*force_clock_level)(void *handle, enum pp_clock_type type, int level); 285 + int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); 293 286 }; 294 287 295 288 struct amd_powerplay {
+4
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 327 327 int (*get_dal_power_level)(struct pp_hwmgr *hwmgr, 328 328 struct amd_pp_dal_clock_info *info); 329 329 int (*power_off_asic)(struct pp_hwmgr *hwmgr); 330 + int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); 331 + int (*set_pp_table)(struct pp_hwmgr *hwmgr, const char *buf, size_t size); 332 + int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, int level); 333 + int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); 330 334 }; 331 335 332 336 struct pp_table_func {