The clocks are returned in Mhz and the temperature in millidegrees. v2: - add sub-queries for AMDPGU_INFO_GPU_SENSOR_* - do not break the ABI Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 3 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 38 +++++++++++++++++++++++++++++++++ include/uapi/drm/amdgpu_drm.h | 12 +++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index f275a6b54e9f..bae3ab8407b0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -59,9 +59,10 @@ * - 3.7.0 - Add support for VCE clock list packet * - 3.8.0 - Add support raster config init in the kernel * - 3.9.0 - Add support for memory query info about VRAM and GTT. + * - 3.10.0 - Add support for clocks/temperature query info. */ #define KMS_DRIVER_MAJOR 3 -#define KMS_DRIVER_MINOR 9 +#define KMS_DRIVER_MINOR 10 #define KMS_DRIVER_PATCHLEVEL 0 int amdgpu_vram_limit = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index d5f9d6a4b661..16365528b6a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -241,6 +241,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file uint32_t ui32 = 0; uint64_t ui64 = 0; int i, found; + int ui32_size = sizeof(ui32); if (!info->return_size || !info->return_pointer) return -EINVAL; @@ -597,6 +598,43 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file return -EINVAL; } } + case AMDGPU_INFO_GPU_SENSOR: { + switch (info->gpu_sensor_info.type) { + case AMDGPU_INFO_GPU_SENSOR_SCLK: + /* get sclk in Mhz */ + if (!amdgpu_dpm_read_sensor(adev, + AMDGPU_PP_SENSOR_GFX_SCLK, + (void *)&ui32, &ui32_size)) { + ui32 /= 100; + return copy_to_user(out, &ui32, + min(size, 4u)) ? -EFAULT : 0; + } + return -EINVAL; + case AMDGPU_INFO_GPU_SENSOR_MCLK: + /* get mclk in Mhz */ + if (!amdgpu_dpm_read_sensor(adev, + AMDGPU_PP_SENSOR_GFX_MCLK, + (void *)&ui32, &ui32_size)) { + ui32 /= 100; + return copy_to_user(out, &ui32, + min(size, 4u)) ? -EFAULT : 0; + } + return -EINVAL; + case AMDGPU_INFO_GPU_SENSOR_TEMP: + /* get temperature in millidegrees C */ + if (!amdgpu_dpm_read_sensor(adev, + AMDGPU_PP_SENSOR_GPU_TEMP, + (void *)&ui32, &ui32_size)) { + return copy_to_user(out, &ui32, + min(size, 4u)) ? -EFAULT : 0; + } + return -EINVAL; + default: + DRM_DEBUG_KMS("Invalid request %d\n", + info->gpu_sensor_info.type); + return -EINVAL; + } + } default: DRM_DEBUG_KMS("Invalid request %d\n", info->query); return -EINVAL; diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 07e3710f91cc..8235bb20c9dc 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -534,6 +534,14 @@ struct drm_amdgpu_cs_chunk_data { #define AMDGPU_INFO_VBIOS_IMAGE 0x2 /* Query UVD handles */ #define AMDGPU_INFO_NUM_HANDLES 0x1C +/* Query GPU sensor related information */ +#define AMDGPU_INFO_GPU_SENSOR 0x1D + /* Query the current shader clock */ + #define AMDGPU_INFO_GPU_SENSOR_SCLK 0x1 + /* Query the current memory clock */ + #define AMDGPU_INFO_GPU_SENSOR_MCLK 0x2 + /* Query the current temperature */ + #define AMDGPU_INFO_GPU_SENSOR_TEMP 0x3 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT 0 #define AMDGPU_INFO_MMR_SE_INDEX_MASK 0xff @@ -597,6 +605,10 @@ struct drm_amdgpu_info { __u32 type; __u32 offset; } vbios_info; + + struct { + __u32 type; + } gpu_sensor_info; }; }; -- 2.11.1