summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c26
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c28
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c5
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c8
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c16
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h2
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h2
8 files changed, 64 insertions, 27 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 552452a654a5..f186c20f636b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3106,24 +3106,36 @@ static ssize_t amdgpu_debugfs_sensor_read(struct file *f, char __user *buf,
size_t size, loff_t *pos)
{
struct amdgpu_device *adev = file_inode(f)->i_private;
- int idx, r;
- int32_t value;
+ int idx, x, outsize, r, valuesize;
+ uint32_t values[16];
- if (size != 4 || *pos & 0x3)
+ if (size & 3 || *pos & 0x3)
return -EINVAL;
/* convert offset to sensor number */
idx = *pos >> 2;
+ valuesize = sizeof(values);
if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->read_sensor)
- r = adev->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, idx, &value);
+ r = adev->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, idx, &values[0], &valuesize);
else
return -EINVAL;
- if (!r)
- r = put_user(value, (int32_t *)buf);
+ if (size > valuesize)
+ return -EINVAL;
+
+ outsize = 0;
+ x = 0;
+ if (!r) {
+ while (size) {
+ r = put_user(values[x++], (int32_t *)buf);
+ buf += 4;
+ size -= 4;
+ outsize += 4;
+ }
+ }
- return !r ? 4 : r;
+ return !r ? outsize : r;
}
static ssize_t amdgpu_debugfs_wave_read(struct file *f, char __user *buf,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 5f09893c9674..5dd9daae9eef 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -290,9 +290,9 @@ struct amdgpu_dpm_funcs {
#define amdgpu_dpm_vblank_too_short(adev) (adev)->pm.funcs->vblank_too_short((adev))
#define amdgpu_dpm_enable_bapm(adev, e) (adev)->pm.funcs->enable_bapm((adev), (e))
-#define amdgpu_dpm_read_sensor(adev, idx, value) \
+#define amdgpu_dpm_read_sensor(adev, idx, value, size) \
((adev)->pp_enabled ? \
- (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value)) : \
+ (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \
-EINVAL)
#define amdgpu_dpm_get_temperature(adev) \
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
index 8a9a75a44b62..da877f3c10fc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
@@ -1534,6 +1534,7 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
{
uint32_t value;
struct pp_gpu_power query = {0};
+ int size;
/* sanity check PP is enabled */
if (!(adev->powerplay.pp_funcs &&
@@ -1541,16 +1542,18 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
return -EINVAL;
/* GPU Clocks */
+ size = sizeof(value);
seq_printf(m, "GFX Clocks and Power:\n");
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_MCLK, (void *)&value, &size))
seq_printf(m, "\t%u MHz (MCLK)\n", value/100);
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GFX_SCLK, (void *)&value, &size))
seq_printf(m, "\t%u MHz (SCLK)\n", value/100);
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDGFX, (void *)&value, &size))
seq_printf(m, "\t%u mV (VDDGFX)\n", value);
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VDDNB, (void *)&value, &size))
seq_printf(m, "\t%u mV (VDDNB)\n", value);
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query)) {
+ size = sizeof(query);
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_POWER, (void *)&query, &size)) {
seq_printf(m, "\t%u.%u W (VDDC)\n", query.vddc_power >> 8,
query.vddc_power & 0xff);
seq_printf(m, "\t%u.%u W (VDDCI)\n", query.vddci_power >> 8,
@@ -1560,38 +1563,39 @@ static int amdgpu_debugfs_pm_info_pp(struct seq_file *m, struct amdgpu_device *a
seq_printf(m, "\t%u.%u W (average GPU)\n", query.average_gpu_power >> 8,
query.average_gpu_power & 0xff);
}
+ size = sizeof(value);
seq_printf(m, "\n");
/* GPU Temp */
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_TEMP, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_TEMP, (void *)&value, &size))
seq_printf(m, "GPU Temperature: %u C\n", value/1000);
/* GPU Load */
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_LOAD, (void *)&value, &size))
seq_printf(m, "GPU Load: %u %%\n", value);
seq_printf(m, "\n");
/* UVD clocks */
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_POWER, (void *)&value)) {
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_POWER, (void *)&value, &size)) {
if (!value) {
seq_printf(m, "UVD: Disabled\n");
} else {
seq_printf(m, "UVD: Enabled\n");
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_DCLK, (void *)&value, &size))
seq_printf(m, "\t%u MHz (DCLK)\n", value/100);
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_UVD_VCLK, (void *)&value, &size))
seq_printf(m, "\t%u MHz (VCLK)\n", value/100);
}
}
seq_printf(m, "\n");
/* VCE clocks */
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_POWER, (void *)&value)) {
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_POWER, (void *)&value, &size)) {
if (!value) {
seq_printf(m, "VCE: Disabled\n");
} else {
seq_printf(m, "VCE: Enabled\n");
- if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_ECCLK, (void *)&value))
+ if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_VCE_ECCLK, (void *)&value, &size))
seq_printf(m, "\t%u MHz (ECCLK)\n", value/100);
}
}
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index 81e6856ffa11..fde8fcd46b58 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -880,7 +880,8 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
}
-static int pp_dpm_read_sensor(void *handle, int idx, void *value)
+static int pp_dpm_read_sensor(void *handle, int idx,
+ void *value, int *size)
{
struct pp_hwmgr *hwmgr;
struct pp_instance *pp_handle = (struct pp_instance *)handle;
@@ -898,7 +899,7 @@ static int pp_dpm_read_sensor(void *handle, int idx, void *value)
return 0;
}
- return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value);
+ return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value, size);
}
static struct amd_vce_state*
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index edc3029df785..7aa5ca815a3a 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -1813,7 +1813,8 @@ static int cz_thermal_get_temperature(struct pp_hwmgr *hwmgr)
return actual_temp;
}
-static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value)
+static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx,
+ void *value, int *size)
{
struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
@@ -1837,6 +1838,11 @@ static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value)
uint16_t vddnb, vddgfx;
int result;
+ /* size must be at least 4 bytes for all sensors */
+ if (*size < 4)
+ return -EINVAL;
+ *size = 4;
+
switch (idx) {
case AMDGPU_PP_SENSOR_GFX_SCLK:
if (sclk_index < NUM_SCLK_LEVELS) {
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index 5a4ee43b3d65..13b35be3174c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -3320,22 +3320,29 @@ static int smu7_get_gpu_power(struct pp_hwmgr *hwmgr,
return 0;
}
-static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value)
+static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx,
+ void *value, int *size)
{
uint32_t sclk, mclk, activity_percent;
uint32_t offset;
struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+ /* size must be at least 4 bytes for all sensors */
+ if (*size < 4)
+ return -EINVAL;
+
switch (idx) {
case AMDGPU_PP_SENSOR_GFX_SCLK:
smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
*((uint32_t *)value) = sclk;
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_GFX_MCLK:
smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
*((uint32_t *)value) = mclk;
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_GPU_LOAD:
offset = data->soft_regs_start + smum_get_offsetof(hwmgr->smumgr,
@@ -3346,17 +3353,24 @@ static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, void *value)
activity_percent += 0x80;
activity_percent >>= 8;
*((uint32_t *)value) = activity_percent > 100 ? 100 : activity_percent;
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_GPU_TEMP:
*((uint32_t *)value) = smu7_thermal_get_temperature(hwmgr);
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_UVD_POWER:
*((uint32_t *)value) = data->uvd_power_gated ? 0 : 1;
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_VCE_POWER:
*((uint32_t *)value) = data->vce_power_gated ? 0 : 1;
+ *size = 4;
return 0;
case AMDGPU_PP_SENSOR_GPU_POWER:
+ if (*size < sizeof(struct pp_gpu_power))
+ return -EINVAL;
+ *size = sizeof(struct pp_gpu_power);
return smu7_get_gpu_power(hwmgr, (struct pp_gpu_power *)value);
default:
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
index ab99013eba77..c0bf3af6846d 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
@@ -367,7 +367,7 @@ struct amd_powerplay_funcs {
int (*set_sclk_od)(void *handle, uint32_t value);
int (*get_mclk_od)(void *handle);
int (*set_mclk_od)(void *handle, uint32_t value);
- int (*read_sensor)(void *handle, int idx, void *value);
+ int (*read_sensor)(void *handle, int idx, void *value, int *size);
struct amd_vce_state* (*get_vce_clock_state)(void *handle, unsigned idx);
int (*reset_power_profile_state)(void *handle,
struct amd_pp_profile *request);
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index fa3bf50eff82..8cf5aed055b6 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -355,7 +355,7 @@ struct pp_hwmgr_func {
int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value);
int (*get_mclk_od)(struct pp_hwmgr *hwmgr);
int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value);
- int (*read_sensor)(struct pp_hwmgr *hwmgr, int idx, void *value);
+ int (*read_sensor)(struct pp_hwmgr *hwmgr, int idx, void *value, int *size);
int (*request_firmware)(struct pp_hwmgr *hwmgr);
int (*release_firmware)(struct pp_hwmgr *hwmgr);
int (*set_power_profile_state)(struct pp_hwmgr *hwmgr,