>From 8c806fd49d87ecf57e98713537a7d23d1f7712d9 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Wed, 14 Aug 2013 22:00:48 -0400 Subject: [PATCH] drm/nv40/therm: set default calibration values if needed Some vbios expose a thermal sensor but do not set default calibration values. As they are almost always the same, let's set some default ones. v2: - the nv43 requires a different offset numerator - cosmetic changes Signed-off-by: Martin Peres --- .../drm/nouveau/core/include/subdev/bios/therm.h | 1 + drivers/gpu/drm/nouveau/core/subdev/bios/therm.c | 1 + drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 43 +++++++++++++++++++--- drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 5 +-- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h index 083541d..11b7993 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h @@ -10,6 +10,7 @@ struct nvbios_therm_threshold { struct nvbios_therm_sensor { /* diode */ + int has_sensor; s16 slope_mult; s16 slope_div; s16 offset_num; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c index 22a2057..16b763d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c @@ -95,6 +95,7 @@ nvbios_therm_sensor_parse(struct nouveau_bios *bios, sensor_section++; if (sensor_section == 0) { offset = ((s8) nv_ro08(bios, entry + 2)) / 2; + sensor->has_sensor = 1; sensor->offset_constant = offset; } break; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index 002e51b..72b91d7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -57,11 +57,47 @@ nv40_sensor_style(struct nouveau_therm *therm) } } +static void +nv40_therm_temp_safety_checks(struct nouveau_therm *therm) +{ + struct nouveau_therm_priv *priv = (void *)therm; + struct nvbios_therm_sensor *sensor = &priv->bios_sensor; + enum nv40_sensor_style style = nv40_sensor_style(therm); + struct nouveau_device *device = nv_device(therm); + + /* if the slope or the offset is unset, do no use the sensor */ + if (sensor->has_sensor && (!sensor->slope_div || !sensor->slope_mult || + !sensor->offset_num || !sensor->offset_den)) { + + nv_info(therm, "Invalid sensor calibration values. " + "Set default calibration values\n"); + + if (style == NEW_STYLE) { + sensor->slope_div = 10000; + sensor->slope_mult = 450; + sensor->offset_num = -25000; + sensor->offset_den = 100; + } else if (style == OLD_STYLE) { + sensor->slope_div = 1000; + sensor->slope_mult = 792; + if (device->chipset == 0x43) + sensor->offset_num = 1806; + else + sensor->offset_num = 2306; + sensor->offset_den = 100; + } + } +} + + static int nv40_sensor_setup(struct nouveau_therm *therm) { enum nv40_sensor_style style = nv40_sensor_style(therm); + /* set default values for the temperature if needed */ + nv40_therm_temp_safety_checks(therm); + /* enable ADC readout and disable the ALARM threshold */ if (style == NEW_STYLE) { nv_mask(therm, 0x15b8, 0x80000000, 0); @@ -93,11 +129,6 @@ nv40_temp_get(struct nouveau_therm *therm) } else return -ENODEV; - /* if the slope or the offset is unset, do no use the sensor */ - if (!sensor->slope_div || !sensor->slope_mult || - !sensor->offset_num || !sensor->offset_den) - return -ENODEV; - core_temp = core_temp * sensor->slope_mult / sensor->slope_div; core_temp = core_temp + sensor->offset_num / sensor->offset_den; core_temp = core_temp + sensor->offset_constant - 8; @@ -171,7 +202,7 @@ nv40_therm_intr(struct nouveau_subdev *subdev) struct nouveau_therm *therm = nouveau_therm(subdev); uint32_t stat = nv_rd32(therm, 0x1100); - /* traitement */ + /* TODO: do something? Need more RE first */ /* ack all IRQs */ nv_wr32(therm, 0x1100, 0x70000); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index dde746c..053034e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -49,9 +49,8 @@ nouveau_therm_temp_set_defaults(struct nouveau_therm *therm) priv->bios_sensor.thrs_shutdown.hysteresis = 5; /*not that it matters */ } - static void -nouveau_therm_temp_safety_checks(struct nouveau_therm *therm) +nouveau_therm_sensor_safety_checks(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; struct nvbios_therm_sensor *s = &priv->bios_sensor; @@ -239,7 +238,7 @@ nouveau_therm_sensor_ctor(struct nouveau_therm *therm) if (nvbios_therm_sensor_parse(bios, NVBIOS_THERM_DOMAIN_CORE, &priv->bios_sensor)) nv_error(therm, "nvbios_therm_sensor_parse failed\n"); - nouveau_therm_temp_safety_checks(therm); + nouveau_therm_sensor_safety_checks(therm); return 0; } -- 1.8.3.4