From 88293ee42dd1d80c07cd2746155b1a1f26306700 Mon Sep 17 00:00:00 2001 From: Ramesh Mylavarapu Date: Fri, 27 Aug 2021 13:52:44 +0530 Subject: [PATCH] gpu: nvgpu: read temperature from therm_i2cs_sensor_00_r Currently reading temperature value depeads on therm pstate board objects. In absence of pstate reading temperature from therm get status will be failed which will cause GVS failure in NvRmGpuTest_Device_GetTemperature test. This change will add support to read temperature from therm sensor_00 register but this will have following limitation: - NV_THERM_I2CS_SENSOR_00 doesn't support fractional precision. - It doesn't support negative temperatures. BUG-200736830 Signed-off-by: Ramesh Mylavarapu Change-Id: I25e577dac9029fcd787a6f71957dbeefd6fe43dd Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2584269 Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-misra Reviewed-by: svc-mobile-cert Reviewed-by: svc_kernel_abi Reviewed-by: Vijayakumar Subbu Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/hal/init/hal_tu104.c | 2 ++ drivers/gpu/nvgpu/hal/therm/therm_tu104.c | 10 +++++++++ drivers/gpu/nvgpu/hal/therm/therm_tu104.h | 1 + drivers/gpu/nvgpu/include/nvgpu/gops/therm.h | 1 + .../gpu/nvgpu/os/linux/debug_therm_tu104.c | 22 ++++++++++++++++--- drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 21 +++++++++++++++--- 6 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index ed5924362..acfe96a5b 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1146,6 +1146,8 @@ static const struct gops_therm tu104_ops_therm = { #endif .elcg_init_idle_filters = NULL, #ifdef CONFIG_NVGPU_LS_PMU + .get_internal_sensor_curr_temp = + tu104_get_internal_sensor_curr_temp, .get_internal_sensor_limits = tu104_get_internal_sensor_limits, #endif }; diff --git a/drivers/gpu/nvgpu/hal/therm/therm_tu104.c b/drivers/gpu/nvgpu/hal/therm/therm_tu104.c index b2aa3ad59..b3c934aa0 100644 --- a/drivers/gpu/nvgpu/hal/therm/therm_tu104.c +++ b/drivers/gpu/nvgpu/hal/therm/therm_tu104.c @@ -35,3 +35,13 @@ void tu104_get_internal_sensor_limits(s32 *max_24_8, s32 *min_24_8) *max_24_8 = (0x87 << 8); *min_24_8 = (((u32)-216) << 8); } + +void tu104_get_internal_sensor_curr_temp(struct gk20a *g, u32 *temp_f24_8) +{ + u32 read_val; + + read_val = nvgpu_readl(g, therm_i2cs_sensor_00_r()); + + /* Convert from celsius to f24_8 format*/ + *temp_f24_8 = (read_val << 8); +} diff --git a/drivers/gpu/nvgpu/hal/therm/therm_tu104.h b/drivers/gpu/nvgpu/hal/therm/therm_tu104.h index 64e234d8e..1e036e32d 100644 --- a/drivers/gpu/nvgpu/hal/therm/therm_tu104.h +++ b/drivers/gpu/nvgpu/hal/therm/therm_tu104.h @@ -29,6 +29,7 @@ struct gk20a; +void tu104_get_internal_sensor_curr_temp(struct gk20a *g, u32 *temp_f24_8); void tu104_get_internal_sensor_limits(s32 *max_24_8, s32 *min_24_8); #endif diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/therm.h b/drivers/gpu/nvgpu/include/nvgpu/gops/therm.h index 9484a3101..9cdec4271 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/therm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/therm.h @@ -137,6 +137,7 @@ struct gops_therm { void (*therm_debugfs_init)(struct gk20a *g); #endif u32 (*therm_max_fpdiv_factor)(void); + void (*get_internal_sensor_curr_temp)(struct gk20a *g, u32 *temp_f24_8); /** @endcond DOXYGEN_SHOULD_SKIP_THIS */ }; diff --git a/drivers/gpu/nvgpu/os/linux/debug_therm_tu104.c b/drivers/gpu/nvgpu/os/linux/debug_therm_tu104.c index 276a68b78..eba6e25da 100644 --- a/drivers/gpu/nvgpu/os/linux/debug_therm_tu104.c +++ b/drivers/gpu/nvgpu/os/linux/debug_therm_tu104.c @@ -23,11 +23,27 @@ static int therm_get_internal_sensor_curr_temp(void *data, u64 *val) { struct gk20a *g = (struct gk20a *)data; u32 readval; - int err; + int err = 0; - err = nvgpu_pmu_therm_channel_get_curr_temp(g, &readval); - if (!err) + /* + * If PSTATE is enabled, temp value is taken from THERM_GET_STATUS. + * If PSTATE is disable, temp value is read from NV_THERM_I2CS_SENSOR_00 + * register value. + */ + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + err = nvgpu_pmu_therm_channel_get_curr_temp(g, &readval); + if (!err) { + *val = readval; + } + } else { + if (!g->ops.therm.get_internal_sensor_curr_temp) { + nvgpu_err(g, "reading NV_THERM_I2CS_SENSOR_00 not enabled"); + return -EINVAL; + } + + g->ops.therm.get_internal_sensor_curr_temp(g, &readval); *val = readval; + } return err; } diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index d7eb39107..4d9001b8e 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -1744,9 +1744,24 @@ static int nvgpu_gpu_get_temperature(struct gk20a *g, if (err) return err; - err = nvgpu_pmu_therm_channel_get_curr_temp(g, &temp_f24_8); - if (err) { - return err; + /* + * If PSTATE is enabled, temp value is taken from THERM_GET_STATUS. + * If PSTATE is disable, temp value is read from NV_THERM_I2CS_SENSOR_00 + * register value. + */ + if (nvgpu_is_enabled(g, NVGPU_PMU_PSTATE)) { + err = nvgpu_pmu_therm_channel_get_curr_temp(g, &temp_f24_8); + if (err) { + nvgpu_err(g, "pmu therm channel get status failed"); + return err; + } + } else { + if (!g->ops.therm.get_internal_sensor_curr_temp) { + nvgpu_err(g, "reading NV_THERM_I2CS_SENSOR_00 not enabled"); + return -EINVAL; + } + + g->ops.therm.get_internal_sensor_curr_temp(g, &temp_f24_8); } gk20a_idle(g);