From 849c5317e8509b390da626bcb607e66cc5ef847f Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Fri, 21 Oct 2016 16:43:39 -0700 Subject: gpu: nvgpu: get voltage, current, power and temperature Add ioctls to retrieve voltage, current, power and temperature. Add flags in GPU characteristics to indicate if feature is supported. Jira DNVGPU-166 Change-Id: Ifaafe2efdb6b09d7b28215b641814f28e894151e Signed-off-by: David Martinez Nieto Reviewed-on: http://git-master/r/1241861 Tested-by: Thomas Fleury GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: Vijayakumar Subbu Reviewed-on: http://git-master/r/1267122 --- drivers/gpu/nvgpu/gp106/hal_gp106.c | 20 ++++++++++++- drivers/gpu/nvgpu/gp106/therm_gp106.c | 21 +++++++++++--- drivers/gpu/nvgpu/pmgr/pmgr.c | 53 ++++++++++++++++++++++++++++------- drivers/gpu/nvgpu/pmgr/pmgr.h | 3 ++ drivers/gpu/nvgpu/volt/volt_pmu.c | 14 ++------- drivers/gpu/nvgpu/volt/volt_pmu.h | 2 +- 6 files changed, 85 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index dc27cdae..ee361953 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c @@ -187,6 +187,24 @@ static int gp106_get_litter_value(struct gk20a *g, int value) return ret; } +int gp106_init_gpu_characteristics(struct gk20a *g) +{ + struct nvgpu_gpu_characteristics *gpu = &g->gpu_characteristics; + + int err; + + err = gk20a_init_gpu_characteristics(g); + if (err) + return err; + + gpu->flags |= NVGPU_GPU_FLAGS_SUPPORT_GET_VOLTAGE | + NVGPU_GPU_FLAGS_SUPPORT_GET_CURRENT | + NVGPU_GPU_FLAGS_SUPPORT_GET_POWER | + NVGPU_GPU_FLAGS_SUPPORT_GET_TEMPERATURE; + + return 0; +} + int gp106_init_hal(struct gk20a *g) { struct gpu_ops *gops = &g->ops; @@ -224,7 +242,7 @@ int gp106_init_hal(struct gk20a *g) gops->name = "gp10x"; gops->get_litter_value = gp106_get_litter_value; - gops->chip_init_gpu_characteristics = gk20a_init_gpu_characteristics; + gops->chip_init_gpu_characteristics = gp106_init_gpu_characteristics; gops->gr_ctx.use_dma_for_fw_bootstrap = true; gops->read_ptimer = gk20a_read_ptimer; diff --git a/drivers/gpu/nvgpu/gp106/therm_gp106.c b/drivers/gpu/nvgpu/gp106/therm_gp106.c index a3aa3636..15aff89c 100644 --- a/drivers/gpu/nvgpu/gp106/therm_gp106.c +++ b/drivers/gpu/nvgpu/gp106/therm_gp106.c @@ -15,10 +15,8 @@ #include #include "hw_therm_gp106.h" -#ifdef CONFIG_DEBUG_FS -static int therm_get_internal_sensor_curr_temp(void *data, u64 *val) +static int gp106_get_internal_sensor_curr_temp(struct gk20a *g, u32 *temp_f24_8) { - struct gk20a *g = (struct gk20a *)data; int err = 0; u32 readval; @@ -38,7 +36,21 @@ static int therm_get_internal_sensor_curr_temp(void *data, u64 *val) // Convert from F9.5 -> F27.5 -> F24.8. readval &= therm_temp_sensor_tsense_fixed_point_m(); - *val = readval; + *temp_f24_8 = readval; + + return err; +} + +#ifdef CONFIG_DEBUG_FS +static int therm_get_internal_sensor_curr_temp(void *data, u64 *val) +{ + struct gk20a *g = (struct gk20a *)data; + u32 readval; + int err; + + err = gp106_get_internal_sensor_curr_temp(g, &readval); + if (!err) + *val = readval; return err; } @@ -104,4 +116,5 @@ void gp106_init_therm_ops(struct gpu_ops *gops) { gops->therm.therm_debugfs_init = gp106_therm_debugfs_init; #endif gops->therm.elcg_init_idle_filters = gp106_elcg_init_idle_filters; + gops->therm.get_internal_sensor_curr_temp = gp106_get_internal_sensor_curr_temp; } diff --git a/drivers/gpu/nvgpu/pmgr/pmgr.c b/drivers/gpu/nvgpu/pmgr/pmgr.c index f625e37d..e101aba8 100644 --- a/drivers/gpu/nvgpu/pmgr/pmgr.c +++ b/drivers/gpu/nvgpu/pmgr/pmgr.c @@ -16,12 +16,10 @@ #include "pmgrpmu.h" #include -#ifdef CONFIG_DEBUG_FS -static int pmgr_pwr_devices_get_current_power(void *data, u64 *val) +int pmgr_pwr_devices_get_power(struct gk20a *g, u32 *val) { struct nv_pmu_pmgr_pwr_devices_query_payload payload; int status; - struct gk20a *g = (struct gk20a *)data; status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); if (status) @@ -34,11 +32,10 @@ static int pmgr_pwr_devices_get_current_power(void *data, u64 *val) return status; } -static int pmgr_pwr_devices_get_current(void *data, u64 *val) +int pmgr_pwr_devices_get_current(struct gk20a *g, u32 *val) { struct nv_pmu_pmgr_pwr_devices_query_payload payload; int status; - struct gk20a *g = (struct gk20a *)data; status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); if (status) @@ -51,11 +48,10 @@ static int pmgr_pwr_devices_get_current(void *data, u64 *val) return status; } -static int pmgr_pwr_devices_get_current_voltage(void *data, u64 *val) +int pmgr_pwr_devices_get_voltage(struct gk20a *g, u32 *val) { struct nv_pmu_pmgr_pwr_devices_query_payload payload; int status; - struct gk20a *g = (struct gk20a *)data; status = pmgr_pmu_pwr_devices_query_blocking(g, 1, &payload); if (status) @@ -68,14 +64,51 @@ static int pmgr_pwr_devices_get_current_voltage(void *data, u64 *val) return status; } +#ifdef CONFIG_DEBUG_FS +int pmgr_pwr_devices_get_power_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_power(g, &val); + *p = val; + + return err; +} + +int pmgr_pwr_devices_get_current_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_current(g, &val); + *p = val; + + return err; +} + +int pmgr_pwr_devices_get_voltage_u64(void *data, u64 *p) +{ + struct gk20a *g = (struct gk20a *)data; + int err; + u32 val; + + err = pmgr_pwr_devices_get_voltage(g, &val); + *p = val; + + return err; +} + DEFINE_SIMPLE_ATTRIBUTE( - pmgr_power_ctrl_fops, pmgr_pwr_devices_get_current_power, NULL, "%llu\n"); + pmgr_power_ctrl_fops, pmgr_pwr_devices_get_power_u64, NULL, "%llu\n"); DEFINE_SIMPLE_ATTRIBUTE( - pmgr_current_ctrl_fops, pmgr_pwr_devices_get_current, NULL, "%llu\n"); + pmgr_current_ctrl_fops, pmgr_pwr_devices_get_current_u64, NULL, "%llu\n"); DEFINE_SIMPLE_ATTRIBUTE( - pmgr_voltage_ctrl_fops, pmgr_pwr_devices_get_current_voltage, NULL, "%llu\n"); + pmgr_voltage_ctrl_fops, pmgr_pwr_devices_get_voltage_u64, NULL, "%llu\n"); static void pmgr_debugfs_init(struct gk20a *g) { struct gk20a_platform *platform = dev_get_drvdata(g->dev); diff --git a/drivers/gpu/nvgpu/pmgr/pmgr.h b/drivers/gpu/nvgpu/pmgr/pmgr.h index 97e7b609..cf511fd1 100644 --- a/drivers/gpu/nvgpu/pmgr/pmgr.h +++ b/drivers/gpu/nvgpu/pmgr/pmgr.h @@ -27,5 +27,8 @@ struct pmgr_pmupstate { u32 pmgr_domain_sw_setup(struct gk20a *g); u32 pmgr_domain_pmu_setup(struct gk20a *g); +int pmgr_pwr_devices_get_current(struct gk20a *g, u32 *val); +int pmgr_pwr_devices_get_voltage(struct gk20a *g, u32 *val); +int pmgr_pwr_devices_get_power(struct gk20a *g, u32 *val); #endif diff --git a/drivers/gpu/nvgpu/volt/volt_pmu.c b/drivers/gpu/nvgpu/volt/volt_pmu.c index 4d451b65..a92eb777 100644 --- a/drivers/gpu/nvgpu/volt/volt_pmu.c +++ b/drivers/gpu/nvgpu/volt/volt_pmu.c @@ -227,17 +227,7 @@ u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv) } -u32 volt_get_voltage(struct gk20a *g, u32 volt_domain) +u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv) { - u32 status = 0; - u32 voltage_uv = 0; - - status = volt_rail_get_voltage(g, volt_domain, &voltage_uv); - if (status) { - gk20a_err(dev_from_gk20a(g), - "CTRL_VOLT_DOMAIN_LOGIC get voltage failed"); - return 0; - } - - return voltage_uv; + return volt_rail_get_voltage(g, volt_domain, voltage_uv); } diff --git a/drivers/gpu/nvgpu/volt/volt_pmu.h b/drivers/gpu/nvgpu/volt/volt_pmu.h index c98ba321..9af3fb68 100644 --- a/drivers/gpu/nvgpu/volt/volt_pmu.h +++ b/drivers/gpu/nvgpu/volt/volt_pmu.h @@ -17,6 +17,6 @@ u32 volt_pmu_send_load_cmd_to_pmu(struct gk20a *g); u32 volt_set_voltage(struct gk20a *g, u32 logic_voltage_uv, u32 sram_voltage_uv); -u32 volt_get_voltage(struct gk20a *g, u32 volt_domain); +u32 volt_get_voltage(struct gk20a *g, u32 volt_domain, u32 *voltage_uv); #endif -- cgit v1.2.2