aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2018-01-16 05:35:15 -0500
committerAlex Deucher <alexander.deucher@amd.com>2018-02-19 14:18:17 -0500
commite3933f26b657c341055443103bad331f4537b113 (patch)
treec846b3c17e07d21987b9d397590d413f4db34173 /drivers/gpu/drm
parent897e1bbeec6bfb52dc075f9100b2a6f209d16583 (diff)
drm/amd/pp: Add edit/commit/show OD clock/voltage support in sysfs
when cat pp_od_clk_voltage it show OD_SCLK: 0: 300Mhz 800 mV 1: 466Mhz 818 mV 2: 751Mhz 824 mV 3: 1019Mhz 987 mV 4: 1074Mhz 1037 mV 5: 1126Mhz 1087 mV 6: 1169Mhz 1137 mV 7: 1206Mhz 1150 mV OD_MCLK: 0: 300Mhz 800 mV 1: 1650Mhz 1000 mV echo "s/m level clock voltage" to change sclk/mclk's clock and voltage echo "r" to restore default value. echo "c" to commit the user setting. Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c98
-rw-r--r--drivers/gpu/drm/amd/include/kgd_pp_interface.h1
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c19
4 files changed, 121 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 986f1d568758..4b5755e6e89d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -374,6 +374,10 @@ enum amdgpu_pcie_gen {
374 ((adev)->powerplay.pp_funcs->set_power_profile_mode(\ 374 ((adev)->powerplay.pp_funcs->set_power_profile_mode(\
375 (adev)->powerplay.pp_handle, parameter, size)) 375 (adev)->powerplay.pp_handle, parameter, size))
376 376
377#define amdgpu_dpm_odn_edit_dpm_table(adev, type, parameter, size) \
378 ((adev)->powerplay.pp_funcs->odn_edit_dpm_table(\
379 (adev)->powerplay.pp_handle, type, parameter, size))
380
377struct amdgpu_dpm { 381struct amdgpu_dpm {
378 struct amdgpu_ps *ps; 382 struct amdgpu_ps *ps;
379 /* number of valid power states */ 383 /* number of valid power states */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index ed9012a903b0..fda858ec3cad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -360,6 +360,90 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
360 return count; 360 return count;
361} 361}
362 362
363static ssize_t amdgpu_set_pp_od_clk_voltage(struct device *dev,
364 struct device_attribute *attr,
365 const char *buf,
366 size_t count)
367{
368 struct drm_device *ddev = dev_get_drvdata(dev);
369 struct amdgpu_device *adev = ddev->dev_private;
370 int ret;
371 uint32_t parameter_size = 0;
372 long parameter[64];
373 char buf_cpy[128];
374 char *tmp_str;
375 char *sub_str;
376 const char delimiter[3] = {' ', '\n', '\0'};
377 uint32_t type;
378
379 if (count > 127)
380 return -EINVAL;
381
382 if (*buf == 's')
383 type = PP_OD_EDIT_SCLK_VDDC_TABLE;
384 else if (*buf == 'm')
385 type = PP_OD_EDIT_MCLK_VDDC_TABLE;
386 else if(*buf == 'r')
387 type = PP_OD_RESTORE_DEFAULT_TABLE;
388 else if (*buf == 'c')
389 type = PP_OD_COMMIT_DPM_TABLE;
390 else
391 return -EINVAL;
392
393 memcpy(buf_cpy, buf, count+1);
394
395 tmp_str = buf_cpy;
396
397 while (isspace(*++tmp_str));
398
399 while (tmp_str[0]) {
400 sub_str = strsep(&tmp_str, delimiter);
401 ret = kstrtol(sub_str, 0, &parameter[parameter_size]);
402 if (ret)
403 return -EINVAL;
404 parameter_size++;
405
406 while (isspace(*tmp_str))
407 tmp_str++;
408 }
409
410 if (adev->powerplay.pp_funcs->odn_edit_dpm_table)
411 ret = amdgpu_dpm_odn_edit_dpm_table(adev, type,
412 parameter, parameter_size);
413
414 if (ret)
415 return -EINVAL;
416
417 if (type == PP_OD_COMMIT_DPM_TABLE) {
418 if (adev->powerplay.pp_funcs->dispatch_tasks) {
419 amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL);
420 return count;
421 } else {
422 return -EINVAL;
423 }
424 }
425
426 return count;
427}
428
429static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,
430 struct device_attribute *attr,
431 char *buf)
432{
433 struct drm_device *ddev = dev_get_drvdata(dev);
434 struct amdgpu_device *adev = ddev->dev_private;
435 uint32_t size = 0;
436
437 if (adev->powerplay.pp_funcs->print_clock_levels) {
438 size = amdgpu_dpm_print_clock_levels(adev, OD_SCLK, buf);
439 size += amdgpu_dpm_print_clock_levels(adev, OD_MCLK, buf+size);
440 return size;
441 } else {
442 return snprintf(buf, PAGE_SIZE, "\n");
443 }
444
445}
446
363static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, 447static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev,
364 struct device_attribute *attr, 448 struct device_attribute *attr,
365 char *buf) 449 char *buf)
@@ -842,6 +926,10 @@ static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
842static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR, 926static DEVICE_ATTR(pp_power_profile_mode, S_IRUGO | S_IWUSR,
843 amdgpu_get_pp_power_profile_mode, 927 amdgpu_get_pp_power_profile_mode,
844 amdgpu_set_pp_power_profile_mode); 928 amdgpu_set_pp_power_profile_mode);
929static DEVICE_ATTR(pp_od_clk_voltage, S_IRUGO | S_IWUSR,
930 amdgpu_get_pp_od_clk_voltage,
931 amdgpu_set_pp_od_clk_voltage);
932
845static ssize_t amdgpu_hwmon_show_temp(struct device *dev, 933static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
846 struct device_attribute *attr, 934 struct device_attribute *attr,
847 char *buf) 935 char *buf)
@@ -1481,7 +1569,13 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
1481 "pp_power_profile_mode\n"); 1569 "pp_power_profile_mode\n");
1482 return ret; 1570 return ret;
1483 } 1571 }
1484 1572 ret = device_create_file(adev->dev,
1573 &dev_attr_pp_od_clk_voltage);
1574 if (ret) {
1575 DRM_ERROR("failed to create device file "
1576 "pp_od_clk_voltage\n");
1577 return ret;
1578 }
1485 ret = amdgpu_debugfs_pm_init(adev); 1579 ret = amdgpu_debugfs_pm_init(adev);
1486 if (ret) { 1580 if (ret) {
1487 DRM_ERROR("Failed to register debugfs file for dpm!\n"); 1581 DRM_ERROR("Failed to register debugfs file for dpm!\n");
@@ -1519,6 +1613,8 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
1519 &dev_attr_pp_compute_power_profile); 1613 &dev_attr_pp_compute_power_profile);
1520 device_remove_file(adev->dev, 1614 device_remove_file(adev->dev,
1521 &dev_attr_pp_power_profile_mode); 1615 &dev_attr_pp_power_profile_mode);
1616 device_remove_file(adev->dev,
1617 &dev_attr_pp_od_clk_voltage);
1522} 1618}
1523 1619
1524void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) 1620void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
index e35dcd011dcc..b9aa9f416389 100644
--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
@@ -310,6 +310,7 @@ struct amd_pm_funcs {
310 struct amd_pp_simple_clock_info *clocks); 310 struct amd_pp_simple_clock_info *clocks);
311 int (*get_power_profile_mode)(void *handle, char *buf); 311 int (*get_power_profile_mode)(void *handle, char *buf);
312 int (*set_power_profile_mode)(void *handle, long *input, uint32_t size); 312 int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
313 int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
313}; 314};
314 315
315#endif 316#endif
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index d9cb424ff7e9..854c43c94714 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -1122,6 +1122,24 @@ static int pp_set_power_profile_mode(void *handle, long *input, uint32_t size)
1122 return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size); 1122 return hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, input, size);
1123} 1123}
1124 1124
1125static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size)
1126{
1127 struct pp_hwmgr *hwmgr;
1128 struct pp_instance *pp_handle = (struct pp_instance *)handle;
1129
1130 if (pp_check(pp_handle))
1131 return -EINVAL;
1132
1133 hwmgr = pp_handle->hwmgr;
1134
1135 if (hwmgr->hwmgr_func->odn_edit_dpm_table == NULL) {
1136 pr_info("%s was not implemented.\n", __func__);
1137 return -EINVAL;
1138 }
1139
1140 return hwmgr->hwmgr_func->odn_edit_dpm_table(hwmgr, type, input, size);
1141}
1142
1125static int pp_dpm_set_power_profile_state(void *handle, 1143static int pp_dpm_set_power_profile_state(void *handle,
1126 struct amd_pp_profile *request) 1144 struct amd_pp_profile *request)
1127{ 1145{
@@ -1507,6 +1525,7 @@ const struct amd_pm_funcs pp_dpm_funcs = {
1507 .notify_smu_memory_info = pp_dpm_notify_smu_memory_info, 1525 .notify_smu_memory_info = pp_dpm_notify_smu_memory_info,
1508 .get_power_profile_mode = pp_get_power_profile_mode, 1526 .get_power_profile_mode = pp_get_power_profile_mode,
1509 .set_power_profile_mode = pp_set_power_profile_mode, 1527 .set_power_profile_mode = pp_set_power_profile_mode,
1528 .odn_edit_dpm_table = pp_odn_edit_dpm_table,
1510/* export to DC */ 1529/* export to DC */
1511 .get_sclk = pp_dpm_get_sclk, 1530 .get_sclk = pp_dpm_get_sclk,
1512 .get_mclk = pp_dpm_get_mclk, 1531 .get_mclk = pp_dpm_get_mclk,