aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Huang <JinHuiEric.Huang@amd.com>2016-05-24 15:11:17 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-07-07 14:50:55 -0400
commitf2bdc05f773ea68d31e2d50b9e791b7c7dcd1dfa (patch)
treec96bdf08a1ad3d8c22a8475779996aa8cb869ff7
parent6bb6b2972d0affe1f86881d64c787627b916c17e (diff)
drm/amdgpu: add the common code to support mclk OD
This implements mclk OverDrive(OD) through sysfs. The new entry pp_mclk_od is read/write. The value of input/output is an integer of the overclocking percentage. 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>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c55
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c40
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h2
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
1568struct amdgpu_dpm { 1570struct 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
530static 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
546static 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
572fail:
573 return count;
574}
575
530static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); 576static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state);
531static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, 577static 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,
551static DEVICE_ATTR(pp_sclk_od, S_IRUGO | S_IWUSR, 597static 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);
600static DEVICE_ATTR(pp_mclk_od, S_IRUGO | S_IWUSR,
601 amdgpu_get_pp_mclk_od,
602 amdgpu_set_pp_mclk_od);
554 603
555static ssize_t amdgpu_hwmon_show_temp(struct device *dev, 604static 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
1224void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) 1279void 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
851static 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
870static 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
851const struct amd_powerplay_funcs pp_dpm_funcs = { 889const 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
877static int amd_pp_instance_init(struct amd_pp_init *pp_init, 917static 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
350struct amd_powerplay { 352struct 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
345struct pp_table_func { 347struct pp_table_func {