All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] drm/amdgpu: expose temp and shader/memory clocks
@ 2017-02-13 22:01 Samuel Pitoiset
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-13 22:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

Hi,

This series exposes the current GPU temperature and the current shader
clock (and eventually the memory clock for non-APUs boards). This adds
the same functionality as the Radeon driver. The main goal is to expose
the info through the GALLIUM_HUD in Mesa.

Alex Deucher suggested to wire-up the read_sensor() interface for
pre-powerplay chips. The rest of the series is quite simple.

This has only been tested on Polaris (RX480).

Please review!
Thanks.

Samuel Pitoiset (2):
  drm/amdgpu: implement read_sensor() for pre-powerplay chips
  drm/amdgpu: expose the current temperature and shader/memory clocks

 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 27 ++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34 +++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41 +++++++++++++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h           |  8 ++++++-
 7 files changed, 140 insertions(+), 3 deletions(-)

-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-13 22:01   ` Samuel Pitoiset
       [not found]     ` <20170213220132.1033-2-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-13 22:01   ` [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
                     ` (4 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-13 22:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

Currently, only the GPU temperature, the shader clock and
eventually the memory clock are implemented. The main goal
is to expose this info to the userspace like Radeon.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
 drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34 +++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41 +++++++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 98698dcf15c7..f1876808ff58 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
 				struct amdgpu_ps *cps,
 				struct amdgpu_ps *rps,
 				bool *equal);
+	int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
+			   int *size);
 
 	struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx);
 	int (*reset_power_profile_state)(struct amdgpu_device *adev,
@@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
 #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
 	((adev)->pp_enabled ? \
 		(adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \
-		-EINVAL)
+		(adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
 
 #define amdgpu_dpm_get_temperature(adev) \
 	((adev)->pp_enabled ?						\
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index 578878d1d4c0..e3a06d6d9e99 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		*((uint32_t *)value) = ci_get_average_sclk_freq(adev);
+		*size = 4;
+		return 0;
+	case AMDGPU_PP_SENSOR_GFX_MCLK:
+		*((uint32_t *)value) = ci_get_average_mclk_freq(adev);
+		*size = 4;
+		return 0;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = ci_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 const struct amd_ip_funcs ci_dpm_ip_funcs = {
 	.name = "ci_dpm",
 	.early_init = ci_dpm_early_init,
@@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = {
 	.set_power_profile_state = ci_dpm_set_power_profile_state,
 	.reset_power_profile_state = ci_dpm_reset_power_profile_state,
 	.switch_power_profile = ci_dpm_switch_power_profile,
+	.read_sensor = ci_dpm_read_sensor,
 };
 
 static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
index f5a343cb0010..13f323745729 100644
--- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
@@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	struct kv_power_info *pi = kv_get_pi(adev);
+	uint32_t sclk;
+	u32 pl_index =
+		(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
+		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
+		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
+
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
+			sclk = be32_to_cpu(
+				pi->graphics_level[pl_index].SclkFrequency);
+			*((uint32_t *)value) = sclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = kv_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 const struct amd_ip_funcs kv_dpm_ip_funcs = {
 	.name = "kv_dpm",
 	.early_init = kv_dpm_early_init,
@@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs kv_dpm_funcs = {
 	.enable_bapm = &kv_dpm_enable_bapm,
 	.get_vce_clock_state = amdgpu_get_vce_clock_state,
 	.check_state_equal = kv_check_state_equal,
+	.read_sensor = &kv_dpm_read_sensor,
 };
 
 static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index f55e45b52fbc..ded6b9b7153e 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
+	struct amdgpu_ps *rps = &eg_pi->current_rps;
+	struct  si_ps *ps = si_get_ps(rps);
+	uint32_t sclk, mclk;
+	u32 pl_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+		CURRENT_STATE_INDEX_SHIFT;
+
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		if (pl_index < ps->performance_level_count) {
+			sclk = ps->performance_levels[pl_index].sclk;
+			*((uint32_t *)value) = sclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GFX_MCLK:
+		if (pl_index < ps->performance_level_count) {
+			mclk = ps->performance_levels[pl_index].mclk;
+			*((uint32_t *)value) = mclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = si_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
 
 const struct amd_ip_funcs si_dpm_ip_funcs = {
 	.name = "si_dpm",
@@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = {
 	.get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
 	.check_state_equal = &si_check_state_equal,
 	.get_vce_clock_state = amdgpu_get_vce_clock_state,
+	.read_sensor = &si_dpm_read_sensor,
 };
 
 static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-13 22:01   ` [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
@ 2017-02-13 22:01   ` Samuel Pitoiset
       [not found]     ` <20170213220132.1033-3-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-14  0:00   ` [PATCH v2 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-13 22:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

The clocks are returned in Mhz and the temperature in millidegrees.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 27 +++++++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h           |  8 +++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

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..f032d0882bc5 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,32 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 			return -EINVAL;
 		}
 	}
+	case AMDGPU_INFO_CURRENT_GPU_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_CURRENT_GPU_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_CURRENT_GPU_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->query);
 		return -EINVAL;
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 07e3710f91cc..0db7a481046a 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -532,8 +532,14 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+/* Query the current shader clock */
+#define AMDGPU_INFO_CURRENT_GPU_SCLK		0x1c
+/* Query the current memory clock */
+#define AMDGPU_INFO_CURRENT_GPU_MCLK		0x1d
+/* Query the current temperature */
+#define AMDGPU_INFO_CURRENT_GPU_TEMP		0x1e
 /* Query UVD handles */
-#define AMDGPU_INFO_NUM_HANDLES			0x1C
+#define AMDGPU_INFO_NUM_HANDLES			0x1f
 
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]     ` <20170213220132.1033-2-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-13 22:13       ` Deucher, Alexander
       [not found]         ` <BN6PR12MB1652044A168BA6F29943A2C3F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  2017-02-13 23:17       ` Tom St Denis
  1 sibling, 1 reply; 18+ messages in thread
From: Deucher, Alexander @ 2017-02-13 22:13 UTC (permalink / raw)
  To: 'Samuel Pitoiset', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Samuel Pitoiset
> Sent: Monday, February 13, 2017 5:02 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Samuel Pitoiset
> Subject: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-
> powerplay chips
> 
> Currently, only the GPU temperature, the shader clock and
> eventually the memory clock are implemented. The main goal
> is to expose this info to the userspace like Radeon.
> 
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34
> +++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41
> +++++++++++++++++++++++++++++++++
>  4 files changed, 104 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 98698dcf15c7..f1876808ff58 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>  				struct amdgpu_ps *cps,
>  				struct amdgpu_ps *rps,
>  				bool *equal);
> +	int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
> +			   int *size);
> 
>  	struct amd_vce_state* (*get_vce_clock_state)(struct
> amdgpu_device *adev, unsigned idx);
>  	int (*reset_power_profile_state)(struct amdgpu_device *adev,
> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>  	((adev)->pp_enabled ? \
>  		(adev)->powerplay.pp_funcs->read_sensor(adev-
> >powerplay.pp_handle, (idx), (value), (size)) : \
> -		-EINVAL)
> +		(adev)->pm.funcs->read_sensor((adev), (idx), (value),
> (size)))
> 
>  #define amdgpu_dpm_get_temperature(adev) \
>  	((adev)->pp_enabled ?						\
> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> index 578878d1d4c0..e3a06d6d9e99 100644
> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct
> amdgpu_device *adev,
>  	return 0;
>  }
> 
> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		*((uint32_t *)value) = ci_get_average_sclk_freq(adev);
> +		*size = 4;
> +		return 0;
> +	case AMDGPU_PP_SENSOR_GFX_MCLK:
> +		*((uint32_t *)value) = ci_get_average_mclk_freq(adev);
> +		*size = 4;
> +		return 0;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = ci_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;

While you are here you could add AMDGPU_PP_SENSOR_GPU_LOAD.  See ci_dpm_debugfs_print_current_performance_level() for the activity percent  calculations.

Either way:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  const struct amd_ip_funcs ci_dpm_ip_funcs = {
>  	.name = "ci_dpm",
>  	.early_init = ci_dpm_early_init,
> @@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs
> ci_dpm_funcs = {
>  	.set_power_profile_state = ci_dpm_set_power_profile_state,
>  	.reset_power_profile_state = ci_dpm_reset_power_profile_state,
>  	.switch_power_profile = ci_dpm_switch_power_profile,
> +	.read_sensor = ci_dpm_read_sensor,
>  };
> 
>  static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> index f5a343cb0010..13f323745729 100644
> --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> @@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct
> amdgpu_device *adev,
>  	return 0;
>  }
> 
> +static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	struct kv_power_info *pi = kv_get_pi(adev);
> +	uint32_t sclk;
> +	u32 pl_index =
> +		(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX)
> &
> +
> 	TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MA
> SK) >>
> +
> 	TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SH
> IFT;
> +
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
> +			sclk = be32_to_cpu(
> +				pi->graphics_level[pl_index].SclkFrequency);
> +			*((uint32_t *)value) = sclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = kv_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  const struct amd_ip_funcs kv_dpm_ip_funcs = {
>  	.name = "kv_dpm",
>  	.early_init = kv_dpm_early_init,
> @@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs
> kv_dpm_funcs = {
>  	.enable_bapm = &kv_dpm_enable_bapm,
>  	.get_vce_clock_state = amdgpu_get_vce_clock_state,
>  	.check_state_equal = kv_check_state_equal,
> +	.read_sensor = &kv_dpm_read_sensor,
>  };
> 
>  static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> index f55e45b52fbc..ded6b9b7153e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> @@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct
> amdgpu_device *adev,
>  	return 0;
>  }
> 
> +static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
> +	struct amdgpu_ps *rps = &eg_pi->current_rps;
> +	struct  si_ps *ps = si_get_ps(rps);
> +	uint32_t sclk, mclk;
> +	u32 pl_index =
> +		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) &
> CURRENT_STATE_INDEX_MASK) >>
> +		CURRENT_STATE_INDEX_SHIFT;
> +
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		if (pl_index < ps->performance_level_count) {
> +			sclk = ps->performance_levels[pl_index].sclk;
> +			*((uint32_t *)value) = sclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GFX_MCLK:
> +		if (pl_index < ps->performance_level_count) {
> +			mclk = ps->performance_levels[pl_index].mclk;
> +			*((uint32_t *)value) = mclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = si_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> 
>  const struct amd_ip_funcs si_dpm_ip_funcs = {
>  	.name = "si_dpm",
> @@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs
> si_dpm_funcs = {
>  	.get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
>  	.check_state_equal = &si_check_state_equal,
>  	.get_vce_clock_state = amdgpu_get_vce_clock_state,
> +	.read_sensor = &si_dpm_read_sensor,
>  };
> 
>  static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
> --
> 2.11.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found]     ` <20170213220132.1033-3-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-13 22:20       ` Deucher, Alexander
       [not found]         ` <BN6PR12MB1652B624BD6BA79E9A7F54F1F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Deucher, Alexander @ 2017-02-13 22:20 UTC (permalink / raw)
  To: 'Samuel Pitoiset', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Samuel Pitoiset
> Sent: Monday, February 13, 2017 5:02 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Samuel Pitoiset
> Subject: [PATCH 2/2] drm/amdgpu: expose the current temperature and
> shader/memory clocks
> 
> The clocks are returned in Mhz and the temperature in millidegrees.
> 
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 ++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 27
> +++++++++++++++++++++++++++
>  include/uapi/drm/amdgpu_drm.h           |  8 +++++++-
>  3 files changed, 36 insertions(+), 2 deletions(-)
> 
> 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..f032d0882bc5 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,32 @@ static int amdgpu_info_ioctl(struct drm_device
> *dev, void *data, struct drm_file
>  			return -EINVAL;
>  		}
>  	}
> +	case AMDGPU_INFO_CURRENT_GPU_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_CURRENT_GPU_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_CURRENT_GPU_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->query);
>  		return -EINVAL;
> diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h
> index 07e3710f91cc..0db7a481046a 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -532,8 +532,14 @@ struct drm_amdgpu_cs_chunk_data {
>  	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>  	/* Subquery id: Query vbios image */
>  	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
> +/* Query the current shader clock */
> +#define AMDGPU_INFO_CURRENT_GPU_SCLK		0x1c
> +/* Query the current memory clock */
> +#define AMDGPU_INFO_CURRENT_GPU_MCLK		0x1d
> +/* Query the current temperature */
> +#define AMDGPU_INFO_CURRENT_GPU_TEMP		0x1e

I would suggest adding a single query for power related items.  E.g., AMDGPU_INFO_GPU_SENSOR and then add sub-queries for the different things you might want to query (temp, sclk, mclk, gpu load, voltages, etc.).  E.g., AMDGPU_INFO_GPU_SENSOR_SCLK, AMDGPU_INFO_GPU_SENSOR_MCLK, etc.

>  /* Query UVD handles */
> -#define AMDGPU_INFO_NUM_HANDLES			0x1C
> +#define AMDGPU_INFO_NUM_HANDLES			0x1f

Can't change an existing query.  New ones should be added to the end.

> 
>  #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
>  #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
> --
> 2.11.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found]         ` <BN6PR12MB1652B624BD6BA79E9A7F54F1F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2017-02-13 22:23           ` Samuel Pitoiset
  0 siblings, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-13 22:23 UTC (permalink / raw)
  To: Deucher, Alexander, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 02/13/2017 11:20 PM, Deucher, Alexander wrote:
>> -----Original Message-----
>> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
>> Of Samuel Pitoiset
>> Sent: Monday, February 13, 2017 5:02 PM
>> To: amd-gfx@lists.freedesktop.org
>> Cc: Samuel Pitoiset
>> Subject: [PATCH 2/2] drm/amdgpu: expose the current temperature and
>> shader/memory clocks
>>
>> The clocks are returned in Mhz and the temperature in millidegrees.
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 ++-
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 27
>> +++++++++++++++++++++++++++
>>  include/uapi/drm/amdgpu_drm.h           |  8 +++++++-
>>  3 files changed, 36 insertions(+), 2 deletions(-)
>>
>> 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..f032d0882bc5 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,32 @@ static int amdgpu_info_ioctl(struct drm_device
>> *dev, void *data, struct drm_file
>>  			return -EINVAL;
>>  		}
>>  	}
>> +	case AMDGPU_INFO_CURRENT_GPU_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_CURRENT_GPU_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_CURRENT_GPU_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->query);
>>  		return -EINVAL;
>> diff --git a/include/uapi/drm/amdgpu_drm.h
>> b/include/uapi/drm/amdgpu_drm.h
>> index 07e3710f91cc..0db7a481046a 100644
>> --- a/include/uapi/drm/amdgpu_drm.h
>> +++ b/include/uapi/drm/amdgpu_drm.h
>> @@ -532,8 +532,14 @@ struct drm_amdgpu_cs_chunk_data {
>>  	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>>  	/* Subquery id: Query vbios image */
>>  	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
>> +/* Query the current shader clock */
>> +#define AMDGPU_INFO_CURRENT_GPU_SCLK		0x1c
>> +/* Query the current memory clock */
>> +#define AMDGPU_INFO_CURRENT_GPU_MCLK		0x1d
>> +/* Query the current temperature */
>> +#define AMDGPU_INFO_CURRENT_GPU_TEMP		0x1e
>
> I would suggest adding a single query for power related items.  E.g., AMDGPU_INFO_GPU_SENSOR and then add sub-queries for the different things you might want to query (temp, sclk, mclk, gpu load, voltages, etc.).  E.g., AMDGPU_INFO_GPU_SENSOR_SCLK, AMDGPU_INFO_GPU_SENSOR_MCLK, etc.

Ok.

>
>>  /* Query UVD handles */
>> -#define AMDGPU_INFO_NUM_HANDLES			0x1C
>> +#define AMDGPU_INFO_NUM_HANDLES			0x1f
>
> Can't change an existing query.  New ones should be added to the end.

I thought this was just the total number of queries... But yeah, I 
shouldn't break the ABI.

Thanks for reviewing.

>
>>
>>  #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
>>  #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
>> --
>> 2.11.1
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]         ` <BN6PR12MB1652044A168BA6F29943A2C3F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2017-02-13 22:40           ` Tom St Denis
  0 siblings, 0 replies; 18+ messages in thread
From: Tom St Denis @ 2017-02-13 22:40 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 02/13/2017 05:13 PM, Deucher, Alexander wrote:
>> -----Original Message-----
>> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
>> Of Samuel Pitoiset
>> Sent: Monday, February 13, 2017 5:02 PM
>> To: amd-gfx@lists.freedesktop.org
>> Cc: Samuel Pitoiset
>> Subject: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-
>> powerplay chips
>>
>> Currently, only the GPU temperature, the shader clock and
>> eventually the memory clock are implemented. The main goal
>> is to expose this info to the userspace like Radeon.
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34
>> +++++++++++++++++++++++++++
>>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41
>> +++++++++++++++++++++++++++++++++
>>  4 files changed, 104 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> index 98698dcf15c7..f1876808ff58 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>>  				struct amdgpu_ps *cps,
>>  				struct amdgpu_ps *rps,
>>  				bool *equal);
>> +	int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
>> +			   int *size);
>>
>>  	struct amd_vce_state* (*get_vce_clock_state)(struct
>> amdgpu_device *adev, unsigned idx);
>>  	int (*reset_power_profile_state)(struct amdgpu_device *adev,
>> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>>  	((adev)->pp_enabled ? \
>>  		(adev)->powerplay.pp_funcs->read_sensor(adev-
>>> powerplay.pp_handle, (idx), (value), (size)) : \
>> -		-EINVAL)
>> +		(adev)->pm.funcs->read_sensor((adev), (idx), (value),
>> (size)))
>>
>>  #define amdgpu_dpm_get_temperature(adev) \
>>  	((adev)->pp_enabled ?						\
>> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> index 578878d1d4c0..e3a06d6d9e99 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct
>> amdgpu_device *adev,
>>  	return 0;
>>  }
>>
>> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>> +			      void *value, int *size)
>> +{
>> +	/* size must be at least 4 bytes for all sensors */
>> +	if (*size < 4)
>> +		return -EINVAL;
>> +
>> +	switch (idx) {
>> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
>> +		*((uint32_t *)value) = ci_get_average_sclk_freq(adev);
>> +		*size = 4;
>> +		return 0;
>> +	case AMDGPU_PP_SENSOR_GFX_MCLK:
>> +		*((uint32_t *)value) = ci_get_average_mclk_freq(adev);
>> +		*size = 4;
>> +		return 0;
>> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
>> +		*((uint32_t *)value) = ci_dpm_get_temp(adev);
>> +		*size = 4;
>> +		return 0;
>
> While you are here you could add AMDGPU_PP_SENSOR_GPU_LOAD.  See ci_dpm_debugfs_print_current_performance_level() for the activity percent  calculations.
>
> Either way:
> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

Once these land I can submit a patch to extend umr to read them.  Right 
now I only track sensors from ST/CZ and VI hardware.

Tom
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]     ` <20170213220132.1033-2-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-13 22:13       ` Deucher, Alexander
@ 2017-02-13 23:17       ` Tom St Denis
       [not found]         ` <f07176a7-6bfe-e98e-7f80-d8f2668d3045-5C7GfCeVMHo@public.gmane.org>
  1 sibling, 1 reply; 18+ messages in thread
From: Tom St Denis @ 2017-02-13 23:17 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

Hi Samuel,

It would be helpful to modify amdgpu_debugfs_sensor_read() to support 
dpm based sensors as well.  This will let me add it to umr.

If you can swing that in here that would be helpful if not I can submit 
my own patch when this lands.

Cheers,
Tom



On 02/13/2017 05:01 PM, Samuel Pitoiset wrote:
> Currently, only the GPU temperature, the shader clock and
> eventually the memory clock are implemented. The main goal
> is to expose this info to the userspace like Radeon.
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34 +++++++++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41 +++++++++++++++++++++++++++++++++
>  4 files changed, 104 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> index 98698dcf15c7..f1876808ff58 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>  				struct amdgpu_ps *cps,
>  				struct amdgpu_ps *rps,
>  				bool *equal);
> +	int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
> +			   int *size);
>
>  	struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx);
>  	int (*reset_power_profile_state)(struct amdgpu_device *adev,
> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>  	((adev)->pp_enabled ? \
>  		(adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \
> -		-EINVAL)
> +		(adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
>
>  #define amdgpu_dpm_get_temperature(adev) \
>  	((adev)->pp_enabled ?						\
> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> index 578878d1d4c0..e3a06d6d9e99 100644
> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct amdgpu_device *adev,
>  	return 0;
>  }
>
> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		*((uint32_t *)value) = ci_get_average_sclk_freq(adev);
> +		*size = 4;
> +		return 0;
> +	case AMDGPU_PP_SENSOR_GFX_MCLK:
> +		*((uint32_t *)value) = ci_get_average_mclk_freq(adev);
> +		*size = 4;
> +		return 0;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = ci_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  const struct amd_ip_funcs ci_dpm_ip_funcs = {
>  	.name = "ci_dpm",
>  	.early_init = ci_dpm_early_init,
> @@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = {
>  	.set_power_profile_state = ci_dpm_set_power_profile_state,
>  	.reset_power_profile_state = ci_dpm_reset_power_profile_state,
>  	.switch_power_profile = ci_dpm_switch_power_profile,
> +	.read_sensor = ci_dpm_read_sensor,
>  };
>
>  static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> index f5a343cb0010..13f323745729 100644
> --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
> @@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct amdgpu_device *adev,
>  	return 0;
>  }
>
> +static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	struct kv_power_info *pi = kv_get_pi(adev);
> +	uint32_t sclk;
> +	u32 pl_index =
> +		(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
> +		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
> +		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
> +
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
> +			sclk = be32_to_cpu(
> +				pi->graphics_level[pl_index].SclkFrequency);
> +			*((uint32_t *)value) = sclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = kv_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
>  const struct amd_ip_funcs kv_dpm_ip_funcs = {
>  	.name = "kv_dpm",
>  	.early_init = kv_dpm_early_init,
> @@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs kv_dpm_funcs = {
>  	.enable_bapm = &kv_dpm_enable_bapm,
>  	.get_vce_clock_state = amdgpu_get_vce_clock_state,
>  	.check_state_equal = kv_check_state_equal,
> +	.read_sensor = &kv_dpm_read_sensor,
>  };
>
>  static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> index f55e45b52fbc..ded6b9b7153e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
> @@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct amdgpu_device *adev,
>  	return 0;
>  }
>
> +static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
> +			      void *value, int *size)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
> +	struct amdgpu_ps *rps = &eg_pi->current_rps;
> +	struct  si_ps *ps = si_get_ps(rps);
> +	uint32_t sclk, mclk;
> +	u32 pl_index =
> +		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
> +		CURRENT_STATE_INDEX_SHIFT;
> +
> +	/* size must be at least 4 bytes for all sensors */
> +	if (*size < 4)
> +		return -EINVAL;
> +
> +	switch (idx) {
> +	case AMDGPU_PP_SENSOR_GFX_SCLK:
> +		if (pl_index < ps->performance_level_count) {
> +			sclk = ps->performance_levels[pl_index].sclk;
> +			*((uint32_t *)value) = sclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GFX_MCLK:
> +		if (pl_index < ps->performance_level_count) {
> +			mclk = ps->performance_levels[pl_index].mclk;
> +			*((uint32_t *)value) = mclk;
> +			*size = 4;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	case AMDGPU_PP_SENSOR_GPU_TEMP:
> +		*((uint32_t *)value) = si_dpm_get_temp(adev);
> +		*size = 4;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
>
>  const struct amd_ip_funcs si_dpm_ip_funcs = {
>  	.name = "si_dpm",
> @@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = {
>  	.get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
>  	.check_state_equal = &si_check_state_equal,
>  	.get_vce_clock_state = amdgpu_get_vce_clock_state,
> +	.read_sensor = &si_dpm_read_sensor,
>  };
>
>  static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]         ` <f07176a7-6bfe-e98e-7f80-d8f2668d3045-5C7GfCeVMHo@public.gmane.org>
@ 2017-02-13 23:40           ` Samuel Pitoiset
       [not found]             ` <924552e4-ed96-af5f-82e9-b1e78b265282-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-13 23:40 UTC (permalink / raw)
  To: Tom St Denis, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 02/14/2017 12:17 AM, Tom St Denis wrote:
> Hi Samuel,

Hi Tom,


>
> It would be helpful to modify amdgpu_debugfs_sensor_read() to support
> dpm based sensors as well.  This will let me add it to umr.

You mean removing the sanity check (for powerplay boards)? I can do that 
in a follow-up patch yes.

>
> If you can swing that in here that would be helpful if not I can submit
> my own patch when this lands.
>
> Cheers,
> Tom
>
>
>
> On 02/13/2017 05:01 PM, Samuel Pitoiset wrote:
>> Currently, only the GPU temperature, the shader clock and
>> eventually the memory clock are implemented. The main goal
>> is to expose this info to the userspace like Radeon.
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34 +++++++++++++++++++++++++++
>>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41
>> +++++++++++++++++++++++++++++++++
>>  4 files changed, 104 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> index 98698dcf15c7..f1876808ff58 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>>                  struct amdgpu_ps *cps,
>>                  struct amdgpu_ps *rps,
>>                  bool *equal);
>> +    int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
>> +               int *size);
>>
>>      struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device
>> *adev, unsigned idx);
>>      int (*reset_power_profile_state)(struct amdgpu_device *adev,
>> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>>      ((adev)->pp_enabled ? \
>>
>> (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle,
>> (idx), (value), (size)) : \
>> -        -EINVAL)
>> +        (adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
>>
>>  #define amdgpu_dpm_get_temperature(adev) \
>>      ((adev)->pp_enabled ?                        \
>> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> index 578878d1d4c0..e3a06d6d9e99 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct
>> amdgpu_device *adev,
>>      return 0;
>>  }
>>
>> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>> +                  void *value, int *size)
>> +{
>> +    /* size must be at least 4 bytes for all sensors */
>> +    if (*size < 4)
>> +        return -EINVAL;
>> +
>> +    switch (idx) {
>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>> +        *((uint32_t *)value) = ci_get_average_sclk_freq(adev);
>> +        *size = 4;
>> +        return 0;
>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>> +        *((uint32_t *)value) = ci_get_average_mclk_freq(adev);
>> +        *size = 4;
>> +        return 0;
>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>> +        *((uint32_t *)value) = ci_dpm_get_temp(adev);
>> +        *size = 4;
>> +        return 0;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +}
>> +
>>  const struct amd_ip_funcs ci_dpm_ip_funcs = {
>>      .name = "ci_dpm",
>>      .early_init = ci_dpm_early_init,
>> @@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs
>> ci_dpm_funcs = {
>>      .set_power_profile_state = ci_dpm_set_power_profile_state,
>>      .reset_power_profile_state = ci_dpm_reset_power_profile_state,
>>      .switch_power_profile = ci_dpm_switch_power_profile,
>> +    .read_sensor = ci_dpm_read_sensor,
>>  };
>>
>>  static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>> b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>> index f5a343cb0010..13f323745729 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>> @@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct
>> amdgpu_device *adev,
>>      return 0;
>>  }
>>
>> +static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>> +                  void *value, int *size)
>> +{
>> +    struct kv_power_info *pi = kv_get_pi(adev);
>> +    uint32_t sclk;
>> +    u32 pl_index =
>> +        (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
>> +
>> +    /* size must be at least 4 bytes for all sensors */
>> +    if (*size < 4)
>> +        return -EINVAL;
>> +
>> +    switch (idx) {
>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>> +        if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
>> +            sclk = be32_to_cpu(
>> +                pi->graphics_level[pl_index].SclkFrequency);
>> +            *((uint32_t *)value) = sclk;
>> +            *size = 4;
>> +            return 0;
>> +        }
>> +        return -EINVAL;
>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>> +        *((uint32_t *)value) = kv_dpm_get_temp(adev);
>> +        *size = 4;
>> +        return 0;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +}
>> +
>>  const struct amd_ip_funcs kv_dpm_ip_funcs = {
>>      .name = "kv_dpm",
>>      .early_init = kv_dpm_early_init,
>> @@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs
>> kv_dpm_funcs = {
>>      .enable_bapm = &kv_dpm_enable_bapm,
>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>>      .check_state_equal = kv_check_state_equal,
>> +    .read_sensor = &kv_dpm_read_sensor,
>>  };
>>
>>  static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>> b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>> index f55e45b52fbc..ded6b9b7153e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>> @@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct
>> amdgpu_device *adev,
>>      return 0;
>>  }
>>
>> +static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>> +                  void *value, int *size)
>> +{
>> +    struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
>> +    struct amdgpu_ps *rps = &eg_pi->current_rps;
>> +    struct  si_ps *ps = si_get_ps(rps);
>> +    uint32_t sclk, mclk;
>> +    u32 pl_index =
>> +        (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) &
>> CURRENT_STATE_INDEX_MASK) >>
>> +        CURRENT_STATE_INDEX_SHIFT;
>> +
>> +    /* size must be at least 4 bytes for all sensors */
>> +    if (*size < 4)
>> +        return -EINVAL;
>> +
>> +    switch (idx) {
>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>> +        if (pl_index < ps->performance_level_count) {
>> +            sclk = ps->performance_levels[pl_index].sclk;
>> +            *((uint32_t *)value) = sclk;
>> +            *size = 4;
>> +            return 0;
>> +        }
>> +        return -EINVAL;
>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>> +        if (pl_index < ps->performance_level_count) {
>> +            mclk = ps->performance_levels[pl_index].mclk;
>> +            *((uint32_t *)value) = mclk;
>> +            *size = 4;
>> +            return 0;
>> +        }
>> +        return -EINVAL;
>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>> +        *((uint32_t *)value) = si_dpm_get_temp(adev);
>> +        *size = 4;
>> +        return 0;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +}
>>
>>  const struct amd_ip_funcs si_dpm_ip_funcs = {
>>      .name = "si_dpm",
>> @@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs
>> si_dpm_funcs = {
>>      .get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
>>      .check_state_equal = &si_check_state_equal,
>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>> +    .read_sensor = &si_dpm_read_sensor,
>>  };
>>
>>  static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]             ` <924552e4-ed96-af5f-82e9-b1e78b265282-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-13 23:46               ` Tom St Denis
       [not found]                 ` <3ad85db6-0ba2-77c9-6d94-a875efffdabb-5C7GfCeVMHo@public.gmane.org>
  0 siblings, 1 reply; 18+ messages in thread
From: Tom St Denis @ 2017-02-13 23:46 UTC (permalink / raw)
  To: Samuel Pitoiset, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On 02/13/2017 06:40 PM, Samuel Pitoiset wrote:
>
>
> On 02/14/2017 12:17 AM, Tom St Denis wrote:
>> Hi Samuel,
>
> Hi Tom,
>
>
>>
>> It would be helpful to modify amdgpu_debugfs_sensor_read() to support
>> dpm based sensors as well.  This will let me add it to umr.
>
> You mean removing the sanity check (for powerplay boards)? I can do that
> in a follow-up patch yes.

As long as the path to or the pointer for read_sensor is not null.

It's been a while since I looked at the pm code but I wonder if a sanity 
check is still required even if you use the macro to read the sensor.

Tom


>
>>
>> If you can swing that in here that would be helpful if not I can submit
>> my own patch when this lands.
>>
>> Cheers,
>> Tom
>>
>>
>>
>> On 02/13/2017 05:01 PM, Samuel Pitoiset wrote:
>>> Currently, only the GPU temperature, the shader clock and
>>> eventually the memory clock are implemented. The main goal
>>> is to expose this info to the userspace like Radeon.
>>>
>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>>> ---
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>>>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>>>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34
>>> +++++++++++++++++++++++++++
>>>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41
>>> +++++++++++++++++++++++++++++++++
>>>  4 files changed, 104 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>> index 98698dcf15c7..f1876808ff58 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>>>                  struct amdgpu_ps *cps,
>>>                  struct amdgpu_ps *rps,
>>>                  bool *equal);
>>> +    int (*read_sensor)(struct amdgpu_device *adev, int idx, void
>>> *value,
>>> +               int *size);
>>>
>>>      struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device
>>> *adev, unsigned idx);
>>>      int (*reset_power_profile_state)(struct amdgpu_device *adev,
>>> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>>>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>>>      ((adev)->pp_enabled ? \
>>>
>>> (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle,
>>> (idx), (value), (size)) : \
>>> -        -EINVAL)
>>> +        (adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
>>>
>>>  #define amdgpu_dpm_get_temperature(adev) \
>>>      ((adev)->pp_enabled ?                        \
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>> b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>> index 578878d1d4c0..e3a06d6d9e99 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct
>>> amdgpu_device *adev,
>>>      return 0;
>>>  }
>>>
>>> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>> +                  void *value, int *size)
>>> +{
>>> +    /* size must be at least 4 bytes for all sensors */
>>> +    if (*size < 4)
>>> +        return -EINVAL;
>>> +
>>> +    switch (idx) {
>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>> +        *((uint32_t *)value) = ci_get_average_sclk_freq(adev);
>>> +        *size = 4;
>>> +        return 0;
>>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>>> +        *((uint32_t *)value) = ci_get_average_mclk_freq(adev);
>>> +        *size = 4;
>>> +        return 0;
>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>> +        *((uint32_t *)value) = ci_dpm_get_temp(adev);
>>> +        *size = 4;
>>> +        return 0;
>>> +    default:
>>> +        return -EINVAL;
>>> +    }
>>> +}
>>> +
>>>  const struct amd_ip_funcs ci_dpm_ip_funcs = {
>>>      .name = "ci_dpm",
>>>      .early_init = ci_dpm_early_init,
>>> @@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs
>>> ci_dpm_funcs = {
>>>      .set_power_profile_state = ci_dpm_set_power_profile_state,
>>>      .reset_power_profile_state = ci_dpm_reset_power_profile_state,
>>>      .switch_power_profile = ci_dpm_switch_power_profile,
>>> +    .read_sensor = ci_dpm_read_sensor,
>>>  };
>>>
>>>  static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>> b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>> index f5a343cb0010..13f323745729 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>> @@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct
>>> amdgpu_device *adev,
>>>      return 0;
>>>  }
>>>
>>> +static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>> +                  void *value, int *size)
>>> +{
>>> +    struct kv_power_info *pi = kv_get_pi(adev);
>>> +    uint32_t sclk;
>>> +    u32 pl_index =
>>> +        (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
>>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
>>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
>>> +
>>> +    /* size must be at least 4 bytes for all sensors */
>>> +    if (*size < 4)
>>> +        return -EINVAL;
>>> +
>>> +    switch (idx) {
>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>> +        if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
>>> +            sclk = be32_to_cpu(
>>> +                pi->graphics_level[pl_index].SclkFrequency);
>>> +            *((uint32_t *)value) = sclk;
>>> +            *size = 4;
>>> +            return 0;
>>> +        }
>>> +        return -EINVAL;
>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>> +        *((uint32_t *)value) = kv_dpm_get_temp(adev);
>>> +        *size = 4;
>>> +        return 0;
>>> +    default:
>>> +        return -EINVAL;
>>> +    }
>>> +}
>>> +
>>>  const struct amd_ip_funcs kv_dpm_ip_funcs = {
>>>      .name = "kv_dpm",
>>>      .early_init = kv_dpm_early_init,
>>> @@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs
>>> kv_dpm_funcs = {
>>>      .enable_bapm = &kv_dpm_enable_bapm,
>>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>>>      .check_state_equal = kv_check_state_equal,
>>> +    .read_sensor = &kv_dpm_read_sensor,
>>>  };
>>>
>>>  static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>> b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>> index f55e45b52fbc..ded6b9b7153e 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>> @@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct
>>> amdgpu_device *adev,
>>>      return 0;
>>>  }
>>>
>>> +static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>> +                  void *value, int *size)
>>> +{
>>> +    struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
>>> +    struct amdgpu_ps *rps = &eg_pi->current_rps;
>>> +    struct  si_ps *ps = si_get_ps(rps);
>>> +    uint32_t sclk, mclk;
>>> +    u32 pl_index =
>>> +        (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) &
>>> CURRENT_STATE_INDEX_MASK) >>
>>> +        CURRENT_STATE_INDEX_SHIFT;
>>> +
>>> +    /* size must be at least 4 bytes for all sensors */
>>> +    if (*size < 4)
>>> +        return -EINVAL;
>>> +
>>> +    switch (idx) {
>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>> +        if (pl_index < ps->performance_level_count) {
>>> +            sclk = ps->performance_levels[pl_index].sclk;
>>> +            *((uint32_t *)value) = sclk;
>>> +            *size = 4;
>>> +            return 0;
>>> +        }
>>> +        return -EINVAL;
>>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>>> +        if (pl_index < ps->performance_level_count) {
>>> +            mclk = ps->performance_levels[pl_index].mclk;
>>> +            *((uint32_t *)value) = mclk;
>>> +            *size = 4;
>>> +            return 0;
>>> +        }
>>> +        return -EINVAL;
>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>> +        *((uint32_t *)value) = si_dpm_get_temp(adev);
>>> +        *size = 4;
>>> +        return 0;
>>> +    default:
>>> +        return -EINVAL;
>>> +    }
>>> +}
>>>
>>>  const struct amd_ip_funcs si_dpm_ip_funcs = {
>>>      .name = "si_dpm",
>>> @@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs
>>> si_dpm_funcs = {
>>>      .get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
>>>      .check_state_equal = &si_check_state_equal,
>>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>>> +    .read_sensor = &si_dpm_read_sensor,
>>>  };
>>>
>>>  static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>>
>>
>> _______________________________________________
>> amd-gfx mailing list
>> amd-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v2 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-13 22:01   ` [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
  2017-02-13 22:01   ` [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
@ 2017-02-14  0:00   ` Samuel Pitoiset
  2017-02-14  0:01   ` [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-14  0:00 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

Add the GPU temperature, the shader clock and eventually the
memory clock (as well as the GPU load on CI). The main goal is
to expose this info to the userspace like Radeon.

v2: - add AMDGPU_PP_SENSOR_GPU_LOAD on CI
    - update the commit description

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 ++-
 drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 43 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34 ++++++++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41 +++++++++++++++++++++++++++++++
 4 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
index 98698dcf15c7..f1876808ff58 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
@@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
 				struct amdgpu_ps *cps,
 				struct amdgpu_ps *rps,
 				bool *equal);
+	int (*read_sensor)(struct amdgpu_device *adev, int idx, void *value,
+			   int *size);
 
 	struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device *adev, unsigned idx);
 	int (*reset_power_profile_state)(struct amdgpu_device *adev,
@@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
 #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
 	((adev)->pp_enabled ? \
 		(adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle, (idx), (value), (size)) : \
-		-EINVAL)
+		(adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
 
 #define amdgpu_dpm_get_temperature(adev) \
 	((adev)->pp_enabled ?						\
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
index 578878d1d4c0..b00e81db522d 100644
--- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
@@ -6936,6 +6936,48 @@ static int ci_dpm_switch_power_profile(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	u32 activity_percent = 50;
+	int ret;
+
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		*((uint32_t *)value) = ci_get_average_sclk_freq(adev);
+		*size = 4;
+		return 0;
+	case AMDGPU_PP_SENSOR_GFX_MCLK:
+		*((uint32_t *)value) = ci_get_average_mclk_freq(adev);
+		*size = 4;
+		return 0;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = ci_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	case AMDGPU_PP_SENSOR_GPU_LOAD:
+		ret = ci_read_smc_soft_register(adev,
+						offsetof(SMU7_SoftRegisters,
+							 AverageGraphicsA),
+						&activity_percent);
+		if (ret == 0) {
+			activity_percent += 0x80;
+			activity_percent >>= 8;
+			activity_percent =
+				activity_percent > 100 ? 100 : activity_percent;
+		}
+		*((uint32_t *)value) = activity_percent;
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 const struct amd_ip_funcs ci_dpm_ip_funcs = {
 	.name = "ci_dpm",
 	.early_init = ci_dpm_early_init,
@@ -6982,6 +7024,7 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = {
 	.set_power_profile_state = ci_dpm_set_power_profile_state,
 	.reset_power_profile_state = ci_dpm_reset_power_profile_state,
 	.switch_power_profile = ci_dpm_switch_power_profile,
+	.read_sensor = ci_dpm_read_sensor,
 };
 
 static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
index f5a343cb0010..13f323745729 100644
--- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
@@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	struct kv_power_info *pi = kv_get_pi(adev);
+	uint32_t sclk;
+	u32 pl_index =
+		(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
+		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
+		TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
+
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
+			sclk = be32_to_cpu(
+				pi->graphics_level[pl_index].SclkFrequency);
+			*((uint32_t *)value) = sclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = kv_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 const struct amd_ip_funcs kv_dpm_ip_funcs = {
 	.name = "kv_dpm",
 	.early_init = kv_dpm_early_init,
@@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs kv_dpm_funcs = {
 	.enable_bapm = &kv_dpm_enable_bapm,
 	.get_vce_clock_state = amdgpu_get_vce_clock_state,
 	.check_state_equal = kv_check_state_equal,
+	.read_sensor = &kv_dpm_read_sensor,
 };
 
 static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
index f55e45b52fbc..ded6b9b7153e 100644
--- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
+++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
@@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct amdgpu_device *adev,
 	return 0;
 }
 
+static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
+			      void *value, int *size)
+{
+	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
+	struct amdgpu_ps *rps = &eg_pi->current_rps;
+	struct  si_ps *ps = si_get_ps(rps);
+	uint32_t sclk, mclk;
+	u32 pl_index =
+		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
+		CURRENT_STATE_INDEX_SHIFT;
+
+	/* size must be at least 4 bytes for all sensors */
+	if (*size < 4)
+		return -EINVAL;
+
+	switch (idx) {
+	case AMDGPU_PP_SENSOR_GFX_SCLK:
+		if (pl_index < ps->performance_level_count) {
+			sclk = ps->performance_levels[pl_index].sclk;
+			*((uint32_t *)value) = sclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GFX_MCLK:
+		if (pl_index < ps->performance_level_count) {
+			mclk = ps->performance_levels[pl_index].mclk;
+			*((uint32_t *)value) = mclk;
+			*size = 4;
+			return 0;
+		}
+		return -EINVAL;
+	case AMDGPU_PP_SENSOR_GPU_TEMP:
+		*((uint32_t *)value) = si_dpm_get_temp(adev);
+		*size = 4;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
 
 const struct amd_ip_funcs si_dpm_ip_funcs = {
 	.name = "si_dpm",
@@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = {
 	.get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
 	.check_state_equal = &si_check_state_equal,
 	.get_vce_clock_state = amdgpu_get_vce_clock_state,
+	.read_sensor = &si_dpm_read_sensor,
 };
 
 static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (2 preceding siblings ...)
  2017-02-14  0:00   ` [PATCH v2 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
@ 2017-02-14  0:01   ` Samuel Pitoiset
       [not found]     ` <20170214000126.29947-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-15 19:15   ` [PATCH v3 2/2] drm/amdgpu: expose GPU sensor related information Samuel Pitoiset
  2017-02-15 21:57   ` [PATCH v4 " Samuel Pitoiset
  5 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-14  0:01 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

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@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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips
       [not found]                 ` <3ad85db6-0ba2-77c9-6d94-a875efffdabb-5C7GfCeVMHo@public.gmane.org>
@ 2017-02-14  0:13                   ` Samuel Pitoiset
  0 siblings, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-14  0:13 UTC (permalink / raw)
  To: Tom St Denis, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 02/14/2017 12:46 AM, Tom St Denis wrote:
> On 02/13/2017 06:40 PM, Samuel Pitoiset wrote:
>>
>>
>> On 02/14/2017 12:17 AM, Tom St Denis wrote:
>>> Hi Samuel,
>>
>> Hi Tom,
>>
>>
>>>
>>> It would be helpful to modify amdgpu_debugfs_sensor_read() to support
>>> dpm based sensors as well.  This will let me add it to umr.
>>
>> You mean removing the sanity check (for powerplay boards)? I can do that
>> in a follow-up patch yes.
>
> As long as the path to or the pointer for read_sensor is not null.
>
> It's been a while since I looked at the pm code but I wonder if a sanity
> check is still required even if you use the macro to read the sensor.

Ah yeah, not the function I was thinking of but should be pretty simple 
I think.

>
> Tom
>
>
>>
>>>
>>> If you can swing that in here that would be helpful if not I can submit
>>> my own patch when this lands.
>>>
>>> Cheers,
>>> Tom
>>>
>>>
>>>
>>> On 02/13/2017 05:01 PM, Samuel Pitoiset wrote:
>>>> Currently, only the GPU temperature, the shader clock and
>>>> eventually the memory clock are implemented. The main goal
>>>> is to expose this info to the userspace like Radeon.
>>>>
>>>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
>>>> ---
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h |  4 +++-
>>>>  drivers/gpu/drm/amd/amdgpu/ci_dpm.c     | 26 +++++++++++++++++++++
>>>>  drivers/gpu/drm/amd/amdgpu/kv_dpm.c     | 34
>>>> +++++++++++++++++++++++++++
>>>>  drivers/gpu/drm/amd/amdgpu/si_dpm.c     | 41
>>>> +++++++++++++++++++++++++++++++++
>>>>  4 files changed, 104 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>>> index 98698dcf15c7..f1876808ff58 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.h
>>>> @@ -270,6 +270,8 @@ struct amdgpu_dpm_funcs {
>>>>                  struct amdgpu_ps *cps,
>>>>                  struct amdgpu_ps *rps,
>>>>                  bool *equal);
>>>> +    int (*read_sensor)(struct amdgpu_device *adev, int idx, void
>>>> *value,
>>>> +               int *size);
>>>>
>>>>      struct amd_vce_state* (*get_vce_clock_state)(struct amdgpu_device
>>>> *adev, unsigned idx);
>>>>      int (*reset_power_profile_state)(struct amdgpu_device *adev,
>>>> @@ -293,7 +295,7 @@ struct amdgpu_dpm_funcs {
>>>>  #define amdgpu_dpm_read_sensor(adev, idx, value, size) \
>>>>      ((adev)->pp_enabled ? \
>>>>
>>>> (adev)->powerplay.pp_funcs->read_sensor(adev->powerplay.pp_handle,
>>>> (idx), (value), (size)) : \
>>>> -        -EINVAL)
>>>> +        (adev)->pm.funcs->read_sensor((adev), (idx), (value), (size)))
>>>>
>>>>  #define amdgpu_dpm_get_temperature(adev) \
>>>>      ((adev)->pp_enabled ?                        \
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>>> b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>>> index 578878d1d4c0..e3a06d6d9e99 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c
>>>> @@ -6936,6 +6936,31 @@ static int ci_dpm_switch_power_profile(struct
>>>> amdgpu_device *adev,
>>>>      return 0;
>>>>  }
>>>>
>>>> +static int ci_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>>> +                  void *value, int *size)
>>>> +{
>>>> +    /* size must be at least 4 bytes for all sensors */
>>>> +    if (*size < 4)
>>>> +        return -EINVAL;
>>>> +
>>>> +    switch (idx) {
>>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>>> +        *((uint32_t *)value) = ci_get_average_sclk_freq(adev);
>>>> +        *size = 4;
>>>> +        return 0;
>>>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>>>> +        *((uint32_t *)value) = ci_get_average_mclk_freq(adev);
>>>> +        *size = 4;
>>>> +        return 0;
>>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>>> +        *((uint32_t *)value) = ci_dpm_get_temp(adev);
>>>> +        *size = 4;
>>>> +        return 0;
>>>> +    default:
>>>> +        return -EINVAL;
>>>> +    }
>>>> +}
>>>> +
>>>>  const struct amd_ip_funcs ci_dpm_ip_funcs = {
>>>>      .name = "ci_dpm",
>>>>      .early_init = ci_dpm_early_init,
>>>> @@ -6982,6 +7007,7 @@ static const struct amdgpu_dpm_funcs
>>>> ci_dpm_funcs = {
>>>>      .set_power_profile_state = ci_dpm_set_power_profile_state,
>>>>      .reset_power_profile_state = ci_dpm_reset_power_profile_state,
>>>>      .switch_power_profile = ci_dpm_switch_power_profile,
>>>> +    .read_sensor = ci_dpm_read_sensor,
>>>>  };
>>>>
>>>>  static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>>> b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>>> index f5a343cb0010..13f323745729 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c
>>>> @@ -3260,6 +3260,39 @@ static int kv_check_state_equal(struct
>>>> amdgpu_device *adev,
>>>>      return 0;
>>>>  }
>>>>
>>>> +static int kv_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>>> +                  void *value, int *size)
>>>> +{
>>>> +    struct kv_power_info *pi = kv_get_pi(adev);
>>>> +    uint32_t sclk;
>>>> +    u32 pl_index =
>>>> +        (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX) &
>>>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX_MASK) >>
>>>> +        TARGET_AND_CURRENT_PROFILE_INDEX__CURR_SCLK_INDEX__SHIFT;
>>>> +
>>>> +    /* size must be at least 4 bytes for all sensors */
>>>> +    if (*size < 4)
>>>> +        return -EINVAL;
>>>> +
>>>> +    switch (idx) {
>>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>>> +        if (pl_index < SMU__NUM_SCLK_DPM_STATE) {
>>>> +            sclk = be32_to_cpu(
>>>> +                pi->graphics_level[pl_index].SclkFrequency);
>>>> +            *((uint32_t *)value) = sclk;
>>>> +            *size = 4;
>>>> +            return 0;
>>>> +        }
>>>> +        return -EINVAL;
>>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>>> +        *((uint32_t *)value) = kv_dpm_get_temp(adev);
>>>> +        *size = 4;
>>>> +        return 0;
>>>> +    default:
>>>> +        return -EINVAL;
>>>> +    }
>>>> +}
>>>> +
>>>>  const struct amd_ip_funcs kv_dpm_ip_funcs = {
>>>>      .name = "kv_dpm",
>>>>      .early_init = kv_dpm_early_init,
>>>> @@ -3292,6 +3325,7 @@ static const struct amdgpu_dpm_funcs
>>>> kv_dpm_funcs = {
>>>>      .enable_bapm = &kv_dpm_enable_bapm,
>>>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>>>>      .check_state_equal = kv_check_state_equal,
>>>> +    .read_sensor = &kv_dpm_read_sensor,
>>>>  };
>>>>
>>>>  static void kv_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>>> b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>>> index f55e45b52fbc..ded6b9b7153e 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c
>>>> @@ -7972,6 +7972,46 @@ static int si_check_state_equal(struct
>>>> amdgpu_device *adev,
>>>>      return 0;
>>>>  }
>>>>
>>>> +static int si_dpm_read_sensor(struct amdgpu_device *adev, int idx,
>>>> +                  void *value, int *size)
>>>> +{
>>>> +    struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
>>>> +    struct amdgpu_ps *rps = &eg_pi->current_rps;
>>>> +    struct  si_ps *ps = si_get_ps(rps);
>>>> +    uint32_t sclk, mclk;
>>>> +    u32 pl_index =
>>>> +        (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) &
>>>> CURRENT_STATE_INDEX_MASK) >>
>>>> +        CURRENT_STATE_INDEX_SHIFT;
>>>> +
>>>> +    /* size must be at least 4 bytes for all sensors */
>>>> +    if (*size < 4)
>>>> +        return -EINVAL;
>>>> +
>>>> +    switch (idx) {
>>>> +    case AMDGPU_PP_SENSOR_GFX_SCLK:
>>>> +        if (pl_index < ps->performance_level_count) {
>>>> +            sclk = ps->performance_levels[pl_index].sclk;
>>>> +            *((uint32_t *)value) = sclk;
>>>> +            *size = 4;
>>>> +            return 0;
>>>> +        }
>>>> +        return -EINVAL;
>>>> +    case AMDGPU_PP_SENSOR_GFX_MCLK:
>>>> +        if (pl_index < ps->performance_level_count) {
>>>> +            mclk = ps->performance_levels[pl_index].mclk;
>>>> +            *((uint32_t *)value) = mclk;
>>>> +            *size = 4;
>>>> +            return 0;
>>>> +        }
>>>> +        return -EINVAL;
>>>> +    case AMDGPU_PP_SENSOR_GPU_TEMP:
>>>> +        *((uint32_t *)value) = si_dpm_get_temp(adev);
>>>> +        *size = 4;
>>>> +        return 0;
>>>> +    default:
>>>> +        return -EINVAL;
>>>> +    }
>>>> +}
>>>>
>>>>  const struct amd_ip_funcs si_dpm_ip_funcs = {
>>>>      .name = "si_dpm",
>>>> @@ -8008,6 +8048,7 @@ static const struct amdgpu_dpm_funcs
>>>> si_dpm_funcs = {
>>>>      .get_fan_speed_percent = &si_dpm_get_fan_speed_percent,
>>>>      .check_state_equal = &si_check_state_equal,
>>>>      .get_vce_clock_state = amdgpu_get_vce_clock_state,
>>>> +    .read_sensor = &si_dpm_read_sensor,
>>>>  };
>>>>
>>>>  static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev)
>>>>
>>>
>>> _______________________________________________
>>> amd-gfx mailing list
>>> amd-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found]     ` <20170214000126.29947-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-14 15:11       ` Samuel Pitoiset
  2017-02-14 16:31       ` Deucher, Alexander
  1 sibling, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-14 15:11 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 02/14/2017 01:01 AM, Samuel Pitoiset wrote:
> 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@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)) {

This will need sanity checks to avoid oops if read_sensor is NULL.

> +				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;
>  	};
>  };
>
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks
       [not found]     ` <20170214000126.29947-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-14 15:11       ` Samuel Pitoiset
@ 2017-02-14 16:31       ` Deucher, Alexander
  1 sibling, 0 replies; 18+ messages in thread
From: Deucher, Alexander @ 2017-02-14 16:31 UTC (permalink / raw)
  To: 'Samuel Pitoiset', amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces@lists.freedesktop.org] On Behalf
> Of Samuel Pitoiset
> Sent: Monday, February 13, 2017 7:01 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Samuel Pitoiset
> Subject: [PATCH v2 2/2] drm/amdgpu: expose the current temperature and
> shader/memory clocks
> 
> 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@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

Might as well add the other sensor types as well (VDDGFX, GPU_LOAD, etc.).

Alex


> 
>  #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
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v3 2/2] drm/amdgpu: expose GPU sensor related information
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (3 preceding siblings ...)
  2017-02-14  0:01   ` [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
@ 2017-02-15 19:15   ` Samuel Pitoiset
       [not found]     ` <20170215191546.27637-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2017-02-15 21:57   ` [PATCH v4 " Samuel Pitoiset
  5 siblings, 1 reply; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-15 19:15 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

This includes shader/memory clocks, temperature, GPU load, etc.

v2: - add sub-queries for AMDPGU_INFO_GPU_SENSOR_*
    - do not break the ABI
v3: - return -ENOENT when amdgpu_dpm == 0
    - expose more sensor queries

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 75 +++++++++++++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h           | 20 +++++++++
 3 files changed, 97 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..e9d58aeb30fb 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 sensor query info (clocks, temp, etc).
  */
 #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..8de57db99449 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,80 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 			return -EINVAL;
 		}
 	}
+	case AMDGPU_INFO_SENSOR: {
+		struct pp_gpu_power query = {0};
+		int size = sizeof(query);
+
+		if (amdgpu_dpm != 0)
+			return -ENOENT;
+
+		switch (info->sensor_info.type) {
+		case AMDGPU_INFO_SENSOR_GFX_SCLK:
+			/* get sclk in Mhz */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GFX_SCLK,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			ui32 /= 100;
+			break;
+		case AMDGPU_INFO_SENSOR_GFX_MCLK:
+			/* get mclk in Mhz */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GFX_MCLK,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			ui32 /= 100;
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_TEMP:
+			/* get temperature in millidegrees C */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_TEMP,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_LOAD:
+			/* get GPU load */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_LOAD,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_POWER:
+			/* get average GPU power */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_POWER,
+						   (void *)&query, &size)) {
+				return -EINVAL;
+			}
+			ui32 = query.average_gpu_power >> 8;
+			break;
+		case AMDGPU_INFO_SENSOR_VDDNB:
+			/* get VDDNB in millivolts */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_VDDNB,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_VDDGFX:
+			/* get VDDGFX in millivolts */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_VDDGFX,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		default:
+			DRM_DEBUG_KMS("Invalid request %d\n",
+				      info->sensor_info.type);
+			return -EINVAL;
+		}
+		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
+	}
 	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..1a09d4f8cff5 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -534,6 +534,22 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
+/* Query sensor related information */
+#define AMDGPU_INFO_SENSOR			0x1D
+	/* Subquery id: Query GPU shader clock */
+	#define AMDGPU_INFO_SENSOR_GFX_SCLK	0x1
+	/* Subquery id: Query GPU memory clock */
+	#define AMDGPU_INFO_SENSOR_GFX_MCLK	0x2
+	/* Subquery id: Query GPU temperature */
+	#define AMDGPU_INFO_SENSOR_GPU_TEMP	0x3
+	/* Subquery id: Query GPU load */
+	#define AMDGPU_INFO_SENSOR_GPU_LOAD	0x4
+	/* Subquery id: Query average GPU power */
+	#define AMDGPU_INFO_SENSOR_GPU_POWER	0x5
+	/* Subquery id: Query VDDNB */
+	#define AMDGPU_INFO_SENSOR_VDDNB	0x6
+	/* Subquery id: Query VDDGFX */
+	#define AMDGPU_INFO_SENSOR_VDDGFX	0x7
 
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
@@ -597,6 +613,10 @@ struct drm_amdgpu_info {
 			__u32 type;
 			__u32 offset;
 		} vbios_info;
+
+		struct {
+			__u32 type;
+		} sensor_info;
 	};
 };
 
-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH v3 2/2] drm/amdgpu: expose GPU sensor related information
       [not found]     ` <20170215191546.27637-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2017-02-15 19:18       ` Samuel Pitoiset
  0 siblings, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-15 19:18 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW



On 02/15/2017 08:15 PM, Samuel Pitoiset wrote:
> This includes shader/memory clocks, temperature, GPU load, etc.
>
> v2: - add sub-queries for AMDPGU_INFO_GPU_SENSOR_*
>     - do not break the ABI
> v3: - return -ENOENT when amdgpu_dpm == 0
>     - expose more sensor queries
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 75 +++++++++++++++++++++++++++++++++
>  include/uapi/drm/amdgpu_drm.h           | 20 +++++++++
>  3 files changed, 97 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..e9d58aeb30fb 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 sensor query info (clocks, temp, etc).
>   */
>  #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..8de57db99449 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,80 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
>  			return -EINVAL;
>  		}
>  	}
> +	case AMDGPU_INFO_SENSOR: {
> +		struct pp_gpu_power query = {0};
> +		int size = sizeof(query);
> +
> +		if (amdgpu_dpm != 0)

if (amdgpu_dpm == 0)
    return -ENOENT;

Fixed locally.

> +			return -ENOENT;
> +
> +		switch (info->sensor_info.type) {
> +		case AMDGPU_INFO_SENSOR_GFX_SCLK:
> +			/* get sclk in Mhz */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_GFX_SCLK,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			ui32 /= 100;
> +			break;
> +		case AMDGPU_INFO_SENSOR_GFX_MCLK:
> +			/* get mclk in Mhz */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_GFX_MCLK,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			ui32 /= 100;
> +			break;
> +		case AMDGPU_INFO_SENSOR_GPU_TEMP:
> +			/* get temperature in millidegrees C */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_GPU_TEMP,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			break;
> +		case AMDGPU_INFO_SENSOR_GPU_LOAD:
> +			/* get GPU load */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_GPU_LOAD,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			break;
> +		case AMDGPU_INFO_SENSOR_GPU_POWER:
> +			/* get average GPU power */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_GPU_POWER,
> +						   (void *)&query, &size)) {
> +				return -EINVAL;
> +			}
> +			ui32 = query.average_gpu_power >> 8;
> +			break;
> +		case AMDGPU_INFO_SENSOR_VDDNB:
> +			/* get VDDNB in millivolts */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_VDDNB,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			break;
> +		case AMDGPU_INFO_SENSOR_VDDGFX:
> +			/* get VDDGFX in millivolts */
> +			if (amdgpu_dpm_read_sensor(adev,
> +						   AMDGPU_PP_SENSOR_VDDGFX,
> +						   (void *)&ui32, &ui32_size)) {
> +				return -EINVAL;
> +			}
> +			break;
> +		default:
> +			DRM_DEBUG_KMS("Invalid request %d\n",
> +				      info->sensor_info.type);
> +			return -EINVAL;
> +		}
> +		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
> +	}
>  	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..1a09d4f8cff5 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -534,6 +534,22 @@ struct drm_amdgpu_cs_chunk_data {
>  	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
>  /* Query UVD handles */
>  #define AMDGPU_INFO_NUM_HANDLES			0x1C
> +/* Query sensor related information */
> +#define AMDGPU_INFO_SENSOR			0x1D
> +	/* Subquery id: Query GPU shader clock */
> +	#define AMDGPU_INFO_SENSOR_GFX_SCLK	0x1
> +	/* Subquery id: Query GPU memory clock */
> +	#define AMDGPU_INFO_SENSOR_GFX_MCLK	0x2
> +	/* Subquery id: Query GPU temperature */
> +	#define AMDGPU_INFO_SENSOR_GPU_TEMP	0x3
> +	/* Subquery id: Query GPU load */
> +	#define AMDGPU_INFO_SENSOR_GPU_LOAD	0x4
> +	/* Subquery id: Query average GPU power */
> +	#define AMDGPU_INFO_SENSOR_GPU_POWER	0x5
> +	/* Subquery id: Query VDDNB */
> +	#define AMDGPU_INFO_SENSOR_VDDNB	0x6
> +	/* Subquery id: Query VDDGFX */
> +	#define AMDGPU_INFO_SENSOR_VDDGFX	0x7
>
>  #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
>  #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
> @@ -597,6 +613,10 @@ struct drm_amdgpu_info {
>  			__u32 type;
>  			__u32 offset;
>  		} vbios_info;
> +
> +		struct {
> +			__u32 type;
> +		} sensor_info;
>  	};
>  };
>
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 2/2] drm/amdgpu: expose GPU sensor related information
       [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
                     ` (4 preceding siblings ...)
  2017-02-15 19:15   ` [PATCH v3 2/2] drm/amdgpu: expose GPU sensor related information Samuel Pitoiset
@ 2017-02-15 21:57   ` Samuel Pitoiset
  5 siblings, 0 replies; 18+ messages in thread
From: Samuel Pitoiset @ 2017-02-15 21:57 UTC (permalink / raw)
  To: amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW; +Cc: Samuel Pitoiset

This includes shader/memory clocks, temperature, GPU load, etc.

v2: - add sub-queries for AMDPGU_INFO_GPU_SENSOR_*
    - do not break the ABI
v3: - return -ENOENT when amdgpu_dpm == 0
    - expose more sensor queries
v4: - s/GPU_POWER/GPU_AVG_POWER/
    - improve VDDNB/VDDGFX query description
    - fix amdgpu_dpm check

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 75 +++++++++++++++++++++++++++++++++
 include/uapi/drm/amdgpu_drm.h           | 20 +++++++++
 3 files changed, 97 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..e9d58aeb30fb 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 sensor query info (clocks, temp, etc).
  */
 #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..d76fa3bbca1d 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,80 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
 			return -EINVAL;
 		}
 	}
+	case AMDGPU_INFO_SENSOR: {
+		struct pp_gpu_power query = {0};
+		int size = sizeof(query);
+
+		if (amdgpu_dpm == 0)
+			return -ENOENT;
+
+		switch (info->sensor_info.type) {
+		case AMDGPU_INFO_SENSOR_GFX_SCLK:
+			/* get sclk in Mhz */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GFX_SCLK,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			ui32 /= 100;
+			break;
+		case AMDGPU_INFO_SENSOR_GFX_MCLK:
+			/* get mclk in Mhz */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GFX_MCLK,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			ui32 /= 100;
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_TEMP:
+			/* get temperature in millidegrees C */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_TEMP,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_LOAD:
+			/* get GPU load */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_LOAD,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_GPU_AVG_POWER:
+			/* get average GPU power */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_GPU_POWER,
+						   (void *)&query, &size)) {
+				return -EINVAL;
+			}
+			ui32 = query.average_gpu_power >> 8;
+			break;
+		case AMDGPU_INFO_SENSOR_VDDNB:
+			/* get VDDNB in millivolts */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_VDDNB,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		case AMDGPU_INFO_SENSOR_VDDGFX:
+			/* get VDDGFX in millivolts */
+			if (amdgpu_dpm_read_sensor(adev,
+						   AMDGPU_PP_SENSOR_VDDGFX,
+						   (void *)&ui32, &ui32_size)) {
+				return -EINVAL;
+			}
+			break;
+		default:
+			DRM_DEBUG_KMS("Invalid request %d\n",
+				      info->sensor_info.type);
+			return -EINVAL;
+		}
+		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
+	}
 	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..378ad00b0d85 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -534,6 +534,22 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
+/* Query sensor related information */
+#define AMDGPU_INFO_SENSOR			0x1D
+	/* Subquery id: Query GPU shader clock */
+	#define AMDGPU_INFO_SENSOR_GFX_SCLK		0x1
+	/* Subquery id: Query GPU memory clock */
+	#define AMDGPU_INFO_SENSOR_GFX_MCLK		0x2
+	/* Subquery id: Query GPU temperature */
+	#define AMDGPU_INFO_SENSOR_GPU_TEMP		0x3
+	/* Subquery id: Query GPU load */
+	#define AMDGPU_INFO_SENSOR_GPU_LOAD		0x4
+	/* Subquery id: Query average GPU power	*/
+	#define AMDGPU_INFO_SENSOR_GPU_AVG_POWER	0x5
+	/* Subquery id: Query northbridge voltage */
+	#define AMDGPU_INFO_SENSOR_VDDNB		0x6
+	/* Subquery id: Query graphics voltage */
+	#define AMDGPU_INFO_SENSOR_VDDGFX		0x7
 
 #define AMDGPU_INFO_MMR_SE_INDEX_SHIFT	0
 #define AMDGPU_INFO_MMR_SE_INDEX_MASK	0xff
@@ -597,6 +613,10 @@ struct drm_amdgpu_info {
 			__u32 type;
 			__u32 offset;
 		} vbios_info;
+
+		struct {
+			__u32 type;
+		} sensor_info;
 	};
 };
 
-- 
2.11.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-02-15 21:57 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-13 22:01 [PATCH 0/2] drm/amdgpu: expose temp and shader/memory clocks Samuel Pitoiset
     [not found] ` <20170213220132.1033-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-13 22:01   ` [PATCH 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
     [not found]     ` <20170213220132.1033-2-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-13 22:13       ` Deucher, Alexander
     [not found]         ` <BN6PR12MB1652044A168BA6F29943A2C3F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-02-13 22:40           ` Tom St Denis
2017-02-13 23:17       ` Tom St Denis
     [not found]         ` <f07176a7-6bfe-e98e-7f80-d8f2668d3045-5C7GfCeVMHo@public.gmane.org>
2017-02-13 23:40           ` Samuel Pitoiset
     [not found]             ` <924552e4-ed96-af5f-82e9-b1e78b265282-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-13 23:46               ` Tom St Denis
     [not found]                 ` <3ad85db6-0ba2-77c9-6d94-a875efffdabb-5C7GfCeVMHo@public.gmane.org>
2017-02-14  0:13                   ` Samuel Pitoiset
2017-02-13 22:01   ` [PATCH 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
     [not found]     ` <20170213220132.1033-3-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-13 22:20       ` Deucher, Alexander
     [not found]         ` <BN6PR12MB1652B624BD6BA79E9A7F54F1F7590-/b2+HYfkarQqUD6E6FAiowdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-02-13 22:23           ` Samuel Pitoiset
2017-02-14  0:00   ` [PATCH v2 1/2] drm/amdgpu: implement read_sensor() for pre-powerplay chips Samuel Pitoiset
2017-02-14  0:01   ` [PATCH v2 2/2] drm/amdgpu: expose the current temperature and shader/memory clocks Samuel Pitoiset
     [not found]     ` <20170214000126.29947-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-14 15:11       ` Samuel Pitoiset
2017-02-14 16:31       ` Deucher, Alexander
2017-02-15 19:15   ` [PATCH v3 2/2] drm/amdgpu: expose GPU sensor related information Samuel Pitoiset
     [not found]     ` <20170215191546.27637-1-samuel.pitoiset-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-02-15 19:18       ` Samuel Pitoiset
2017-02-15 21:57   ` [PATCH v4 " Samuel Pitoiset

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.