diff options
Diffstat (limited to 'drivers/gpu/drm/amd')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 55 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 40 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 2 |
5 files changed, 107 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index bf398a421de6..33bc79e378e1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -1563,6 +1563,8 @@ struct amdgpu_dpm_funcs { | |||
| 1563 | int (*print_clock_levels)(struct amdgpu_device *adev, enum pp_clock_type type, char *buf); | 1563 | int (*print_clock_levels)(struct amdgpu_device *adev, enum pp_clock_type type, char *buf); |
| 1564 | int (*get_sclk_od)(struct amdgpu_device *adev); | 1564 | int (*get_sclk_od)(struct amdgpu_device *adev); |
| 1565 | int (*set_sclk_od)(struct amdgpu_device *adev, uint32_t value); | 1565 | int (*set_sclk_od)(struct amdgpu_device *adev, uint32_t value); |
| 1566 | int (*get_mclk_od)(struct amdgpu_device *adev); | ||
| 1567 | int (*set_mclk_od)(struct amdgpu_device *adev, uint32_t value); | ||
| 1566 | }; | 1568 | }; |
| 1567 | 1569 | ||
| 1568 | struct amdgpu_dpm { | 1570 | struct amdgpu_dpm { |
| @@ -2351,6 +2353,12 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) | |||
| 2351 | #define amdgpu_dpm_set_sclk_od(adev, value) \ | 2353 | #define amdgpu_dpm_set_sclk_od(adev, value) \ |
| 2352 | (adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value) | 2354 | (adev)->powerplay.pp_funcs->set_sclk_od((adev)->powerplay.pp_handle, value) |
| 2353 | 2355 | ||
| 2356 | #define amdgpu_dpm_get_mclk_od(adev) \ | ||
| 2357 | ((adev)->powerplay.pp_funcs->get_mclk_od((adev)->powerplay.pp_handle)) | ||
| 2358 | |||
| 2359 | #define amdgpu_dpm_set_mclk_od(adev, value) \ | ||
| 2360 | ((adev)->powerplay.pp_funcs->set_mclk_od((adev)->powerplay.pp_handle, value)) | ||
| 2361 | |||
| 2354 | #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ | 2362 | #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ |
| 2355 | (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) | 2363 | (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) |
| 2356 | 2364 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index d6484d6e60dd..250f8693f170 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | |||
| @@ -527,6 +527,52 @@ fail: | |||
| 527 | return count; | 527 | return count; |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | static ssize_t amdgpu_get_pp_mclk_od(struct device *dev, | ||
| 531 | struct device_attribute *attr, | ||
| 532 | char *buf) | ||
| 533 | { | ||
| 534 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
| 535 | struct amdgpu_device *adev = ddev->dev_private; | ||
| 536 | uint32_t value = 0; | ||
| 537 | |||
| 538 | if (adev->pp_enabled) | ||
| 539 | value = amdgpu_dpm_get_mclk_od(adev); | ||
| 540 | else if (adev->pm.funcs->get_mclk_od) | ||
| 541 | value = adev->pm.funcs->get_mclk_od(adev); | ||
| 542 | |||
| 543 | return snprintf(buf, PAGE_SIZE, "%d\n", value); | ||
| 544 | } | ||
| 545 | |||
| 546 | static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, | ||
| 547 | struct device_attribute *attr, | ||
| 548 | const char *buf, | ||
| 549 | size_t count) | ||
| 550 | { | ||
| 551 | struct drm_device *ddev = dev_get_drvdata(dev); | ||
| 552 | struct amdgpu_device *adev = ddev->dev_private; | ||
| 553 | int ret; | ||
| 554 | long int value; | ||
| 555 | |||
| 556 | ret = kstrtol(buf, 0, &value); | ||
| 557 | |||
| 558 | if (ret) { | ||
| 559 | count = -EINVAL; | ||
| 560 | goto fail; | ||
| 561 | } | ||
| 562 | |||
| 563 | if (adev->pp_enabled) { | ||
| 564 | amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); | ||
| 565 | amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_READJUST_POWER_STATE, NULL, NULL); | ||
| 566 | } else if (adev->pm.funcs->set_mclk_od) { | ||
| 567 | adev->pm.funcs->set_mclk_od(adev, (uint32_t)value); | ||
| 568 | adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; | ||
| 569 | amdgpu_pm_compute_clocks(adev); | ||
| 570 | } | ||
| 571 | |||
| 572 | fail: | ||
| 573 | return count; | ||
| 574 | } | ||
| 575 | |||
| 530 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); | 576 | static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); |
| 531 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, | 577 | static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, |
| 532 | amdgpu_get_dpm_forced_performance_level, | 578 | amdgpu_get_dpm_forced_performance_level, |
| @@ -551,6 +597,9 @@ static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR, | |||
| 551 | static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR, | 597 | static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR, |
| 552 | amdgpu_get_pp_sclk_od, | 598 | amdgpu_get_pp_sclk_od, |
| 553 | amdgpu_set_pp_sclk_od); | 599 | amdgpu_set_pp_sclk_od); |
| 600 | static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR, | ||
| 601 | amdgpu_get_pp_mclk_od, | ||
| 602 | amdgpu_set_pp_mclk_od); | ||
| 554 | 603 | ||
| 555 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, | 604 | static ssize_t amdgpu_hwmon_show_temp(struct device *dev, |
| 556 | struct device_attribute *attr, | 605 | struct device_attribute *attr, |
| @@ -1191,6 +1240,11 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) | |||
| 1191 | DRM_ERROR("failed to create device file pp_sclk_od\n"); | 1240 | DRM_ERROR("failed to create device file pp_sclk_od\n"); |
| 1192 | return ret; | 1241 | return ret; |
| 1193 | } | 1242 | } |
| 1243 | ret = device_create_file(adev->dev, &dev_attr_pp_mclk_od); | ||
| 1244 | if (ret) { | ||
| 1245 | DRM_ERROR("failed to create device file pp_mclk_od\n"); | ||
| 1246 | return ret; | ||
| 1247 | } | ||
| 1194 | 1248 | ||
| 1195 | ret = amdgpu_debugfs_pm_init(adev); | 1249 | ret = amdgpu_debugfs_pm_init(adev); |
| 1196 | if (ret) { | 1250 | if (ret) { |
| @@ -1219,6 +1273,7 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) | |||
| 1219 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); | 1273 | device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); |
| 1220 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); | 1274 | device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); |
| 1221 | device_remove_file(adev->dev, &dev_attr_pp_sclk_od); | 1275 | device_remove_file(adev->dev, &dev_attr_pp_sclk_od); |
| 1276 | device_remove_file(adev->dev, &dev_attr_pp_mclk_od); | ||
| 1222 | } | 1277 | } |
| 1223 | 1278 | ||
| 1224 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) | 1279 | void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 8fa6f594d3ad..e931e87757de 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c | |||
| @@ -848,6 +848,44 @@ static int pp_dpm_set_sclk_od(void *handle, uint32_t value) | |||
| 848 | return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value); | 848 | return hwmgr->hwmgr_func->set_sclk_od(hwmgr, value); |
| 849 | } | 849 | } |
| 850 | 850 | ||
| 851 | static int pp_dpm_get_mclk_od(void *handle) | ||
| 852 | { | ||
| 853 | struct pp_hwmgr *hwmgr; | ||
| 854 | |||
| 855 | if (!handle) | ||
| 856 | return -EINVAL; | ||
| 857 | |||
| 858 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
| 859 | |||
| 860 | PP_CHECK_HW(hwmgr); | ||
| 861 | |||
| 862 | if (hwmgr->hwmgr_func->get_mclk_od == NULL) { | ||
| 863 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
| 864 | return 0; | ||
| 865 | } | ||
| 866 | |||
| 867 | return hwmgr->hwmgr_func->get_mclk_od(hwmgr); | ||
| 868 | } | ||
| 869 | |||
| 870 | static int pp_dpm_set_mclk_od(void *handle, uint32_t value) | ||
| 871 | { | ||
| 872 | struct pp_hwmgr *hwmgr; | ||
| 873 | |||
| 874 | if (!handle) | ||
| 875 | return -EINVAL; | ||
| 876 | |||
| 877 | hwmgr = ((struct pp_instance *)handle)->hwmgr; | ||
| 878 | |||
| 879 | PP_CHECK_HW(hwmgr); | ||
| 880 | |||
| 881 | if (hwmgr->hwmgr_func->set_mclk_od == NULL) { | ||
| 882 | printk(KERN_INFO "%s was not implemented.\n", __func__); | ||
| 883 | return 0; | ||
| 884 | } | ||
| 885 | |||
| 886 | return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value); | ||
| 887 | } | ||
| 888 | |||
| 851 | const struct amd_powerplay_funcs pp_dpm_funcs = { | 889 | const struct amd_powerplay_funcs pp_dpm_funcs = { |
| 852 | .get_temperature = pp_dpm_get_temperature, | 890 | .get_temperature = pp_dpm_get_temperature, |
| 853 | .load_firmware = pp_dpm_load_fw, | 891 | .load_firmware = pp_dpm_load_fw, |
| @@ -872,6 +910,8 @@ const struct amd_powerplay_funcs pp_dpm_funcs = { | |||
| 872 | .print_clock_levels = pp_dpm_print_clock_levels, | 910 | .print_clock_levels = pp_dpm_print_clock_levels, |
| 873 | .get_sclk_od = pp_dpm_get_sclk_od, | 911 | .get_sclk_od = pp_dpm_get_sclk_od, |
| 874 | .set_sclk_od = pp_dpm_set_sclk_od, | 912 | .set_sclk_od = pp_dpm_set_sclk_od, |
| 913 | .get_mclk_od = pp_dpm_get_mclk_od, | ||
| 914 | .set_mclk_od = pp_dpm_set_mclk_od, | ||
| 875 | }; | 915 | }; |
| 876 | 916 | ||
| 877 | static int amd_pp_instance_init(struct amd_pp_init *pp_init, | 917 | static int amd_pp_instance_init(struct amd_pp_init *pp_init, |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index de1d6a81a6a4..d0dfaf9dfa06 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | |||
| @@ -345,6 +345,8 @@ struct amd_powerplay_funcs { | |||
| 345 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); | 345 | int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); |
| 346 | int (*get_sclk_od)(void *handle); | 346 | int (*get_sclk_od)(void *handle); |
| 347 | int (*set_sclk_od)(void *handle, uint32_t value); | 347 | int (*set_sclk_od)(void *handle, uint32_t value); |
| 348 | int (*get_mclk_od)(void *handle); | ||
| 349 | int (*set_mclk_od)(void *handle, uint32_t value); | ||
| 348 | }; | 350 | }; |
| 349 | 351 | ||
| 350 | struct amd_powerplay { | 352 | struct amd_powerplay { |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 3d9a413cf9c8..bcb224b01584 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
| @@ -340,6 +340,8 @@ struct pp_hwmgr_func { | |||
| 340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); | 340 | int (*enable_per_cu_power_gating)(struct pp_hwmgr *hwmgr, bool enable); |
| 341 | int (*get_sclk_od)(struct pp_hwmgr *hwmgr); | 341 | int (*get_sclk_od)(struct pp_hwmgr *hwmgr); |
| 342 | int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); | 342 | int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); |
| 343 | int (*get_mclk_od)(struct pp_hwmgr *hwmgr); | ||
| 344 | int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); | ||
| 343 | }; | 345 | }; |
| 344 | 346 | ||
| 345 | struct pp_table_func { | 347 | struct pp_table_func { |
