aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
diff options
context:
space:
mode:
authorEric Huang <JinHuiEric.Huang@amd.com>2016-09-12 16:17:44 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-03-29 23:52:48 -0400
commit34bb2734d1bc3c72e4739234481c0efab0941d14 (patch)
treec31583ca0511581253f37aea943ba840d8388bfd /drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
parent3f14e6231858f4d9a2e965f54202f7a3f69c79d0 (diff)
drm/amd/amdgpu: add power profile sysfs entry
Add the sysfs entries pp_gfx_power_profile and pp_compute_power_profile which give user a way to set power profile through parameters minimum sclk, minimum mclk, activity threshold, up hysteresis and down hysteresis only when the entry power_dpm_force_performance_level is in default value "auto". It is read and write. Example: echo 500 800 20 0 5 > /sys/class/drm/card0/device/pp_*_power_profile cat /sys/class/drm/card0/device/pp_*_power_profile 500 800 20 0 5 Note: first parameter is sclk in MHz, second is mclk in MHz, third is activity threshold in percentage, fourth is up hysteresis in ms and fifth is down hysteresis in ms. echo set > /sys/class/drm/card0/device/pp_*_power_profile To set power profile state if it exists. echo reset > /sys/class/drm/card0/device/pp_*_power_profile To restore default state and clear previous setting. Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com> Acked-by: Rex Zhu <Rex.Zhu@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c192
1 files changed, 192 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 346e80a7119b..fd45212c4b98 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -610,6 +610,174 @@ fail:
610 return count; 610 return count;
611} 611}
612 612
613static ssize_t amdgpu_get_pp_power_profile(struct device *dev,
614 char *buf, struct amd_pp_profile *query)
615{
616 struct drm_device *ddev = dev_get_drvdata(dev);
617 struct amdgpu_device *adev = ddev->dev_private;
618 int ret = 0;
619
620 if (adev->pp_enabled)
621 ret = amdgpu_dpm_get_power_profile_state(
622 adev, query);
623 else if (adev->pm.funcs->get_power_profile_state)
624 ret = adev->pm.funcs->get_power_profile_state(
625 adev, query);
626
627 if (ret)
628 return ret;
629
630 return snprintf(buf, PAGE_SIZE,
631 "%d %d %d %d %d\n",
632 query->min_sclk / 100,
633 query->min_mclk / 100,
634 query->activity_threshold,
635 query->up_hyst,
636 query->down_hyst);
637}
638
639static ssize_t amdgpu_get_pp_gfx_power_profile(struct device *dev,
640 struct device_attribute *attr,
641 char *buf)
642{
643 struct amd_pp_profile query = {0};
644
645 query.type = AMD_PP_GFX_PROFILE;
646
647 return amdgpu_get_pp_power_profile(dev, buf, &query);
648}
649
650static ssize_t amdgpu_get_pp_compute_power_profile(struct device *dev,
651 struct device_attribute *attr,
652 char *buf)
653{
654 struct amd_pp_profile query = {0};
655
656 query.type = AMD_PP_COMPUTE_PROFILE;
657
658 return amdgpu_get_pp_power_profile(dev, buf, &query);
659}
660
661static ssize_t amdgpu_set_pp_power_profile(struct device *dev,
662 const char *buf,
663 size_t count,
664 struct amd_pp_profile *request)
665{
666 struct drm_device *ddev = dev_get_drvdata(dev);
667 struct amdgpu_device *adev = ddev->dev_private;
668 uint32_t loop = 0;
669 char *sub_str, buf_cpy[128], *tmp_str;
670 const char delimiter[3] = {' ', '\n', '\0'};
671 long int value;
672 int ret = 0;
673
674 if (strncmp("reset", buf, strlen("reset")) == 0) {
675 if (adev->pp_enabled)
676 ret = amdgpu_dpm_reset_power_profile_state(
677 adev, request);
678 else if (adev->pm.funcs->reset_power_profile_state)
679 ret = adev->pm.funcs->reset_power_profile_state(
680 adev, request);
681 if (ret) {
682 count = -EINVAL;
683 goto fail;
684 }
685 return count;
686 }
687
688 if (strncmp("set", buf, strlen("set")) == 0) {
689 if (adev->pp_enabled)
690 ret = amdgpu_dpm_set_power_profile_state(
691 adev, request);
692 else if (adev->pm.funcs->set_power_profile_state)
693 ret = adev->pm.funcs->set_power_profile_state(
694 adev, request);
695 if (ret) {
696 count = -EINVAL;
697 goto fail;
698 }
699 return count;
700 }
701
702 if (count + 1 >= 128) {
703 count = -EINVAL;
704 goto fail;
705 }
706
707 memcpy(buf_cpy, buf, count + 1);
708 tmp_str = buf_cpy;
709
710 while (tmp_str[0]) {
711 sub_str = strsep(&tmp_str, delimiter);
712 ret = kstrtol(sub_str, 0, &value);
713 if (ret) {
714 count = -EINVAL;
715 goto fail;
716 }
717
718 switch (loop) {
719 case 0:
720 /* input unit MHz convert to dpm table unit 10KHz*/
721 request->min_sclk = (uint32_t)value * 100;
722 break;
723 case 1:
724 /* input unit MHz convert to dpm table unit 10KHz*/
725 request->min_mclk = (uint32_t)value * 100;
726 break;
727 case 2:
728 request->activity_threshold = (uint16_t)value;
729 break;
730 case 3:
731 request->up_hyst = (uint8_t)value;
732 break;
733 case 4:
734 request->down_hyst = (uint8_t)value;
735 break;
736 default:
737 break;
738 }
739
740 loop++;
741 }
742
743 if (adev->pp_enabled)
744 ret = amdgpu_dpm_set_power_profile_state(
745 adev, request);
746 else if (adev->pm.funcs->set_power_profile_state)
747 ret = adev->pm.funcs->set_power_profile_state(
748 adev, request);
749
750 if (ret)
751 count = -EINVAL;
752
753fail:
754 return count;
755}
756
757static ssize_t amdgpu_set_pp_gfx_power_profile(struct device *dev,
758 struct device_attribute *attr,
759 const char *buf,
760 size_t count)
761{
762 struct amd_pp_profile request = {0};
763
764 request.type = AMD_PP_GFX_PROFILE;
765
766 return amdgpu_set_pp_power_profile(dev, buf, count, &request);
767}
768
769static ssize_t amdgpu_set_pp_compute_power_profile(struct device *dev,
770 struct device_attribute *attr,
771 const char *buf,
772 size_t count)
773{
774 struct amd_pp_profile request = {0};
775
776 request.type = AMD_PP_COMPUTE_PROFILE;
777
778 return amdgpu_set_pp_power_profile(dev, buf, count, &request);
779}
780
613static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); 781static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state);
614static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, 782static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR,
615 amdgpu_get_dpm_forced_performance_level, 783 amdgpu_get_dpm_forced_performance_level,
@@ -637,6 +805,12 @@ static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR,
637static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR, 805static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR,
638 amdgpu_get_pp_mclk_od, 806 amdgpu_get_pp_mclk_od,
639 amdgpu_set_pp_mclk_od); 807 amdgpu_set_pp_mclk_od);
808static DEVICE_ATTR(pp_gfx_power_profile, S_IRUGO | S_IWUSR,
809 amdgpu_get_pp_gfx_power_profile,
810 amdgpu_set_pp_gfx_power_profile);
811static DEVICE_ATTR(pp_compute_power_profile, S_IRUGO | S_IWUSR,
812 amdgpu_get_pp_compute_power_profile,
813 amdgpu_set_pp_compute_power_profile);
640 814
641static ssize_t amdgpu_hwmon_show_temp(struct device *dev, 815static ssize_t amdgpu_hwmon_show_temp(struct device *dev,
642 struct device_attribute *attr, 816 struct device_attribute *attr,
@@ -1255,6 +1429,20 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
1255 DRM_ERROR("failed to create device file pp_mclk_od\n"); 1429 DRM_ERROR("failed to create device file pp_mclk_od\n");
1256 return ret; 1430 return ret;
1257 } 1431 }
1432 ret = device_create_file(adev->dev,
1433 &dev_attr_pp_gfx_power_profile);
1434 if (ret) {
1435 DRM_ERROR("failed to create device file "
1436 "pp_gfx_power_profile\n");
1437 return ret;
1438 }
1439 ret = device_create_file(adev->dev,
1440 &dev_attr_pp_compute_power_profile);
1441 if (ret) {
1442 DRM_ERROR("failed to create device file "
1443 "pp_compute_power_profile\n");
1444 return ret;
1445 }
1258 1446
1259 ret = amdgpu_debugfs_pm_init(adev); 1447 ret = amdgpu_debugfs_pm_init(adev);
1260 if (ret) { 1448 if (ret) {
@@ -1284,6 +1472,10 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev)
1284 device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); 1472 device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie);
1285 device_remove_file(adev->dev, &dev_attr_pp_sclk_od); 1473 device_remove_file(adev->dev, &dev_attr_pp_sclk_od);
1286 device_remove_file(adev->dev, &dev_attr_pp_mclk_od); 1474 device_remove_file(adev->dev, &dev_attr_pp_mclk_od);
1475 device_remove_file(adev->dev,
1476 &dev_attr_pp_gfx_power_profile);
1477 device_remove_file(adev->dev,
1478 &dev_attr_pp_compute_power_profile);
1287} 1479}
1288 1480
1289void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) 1481void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)