summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
index f7f51f35d18b..de7dc20ed436 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
@@ -80,6 +80,32 @@ nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
}
int
+nv50_fan_pwm_clock(struct nouveau_therm *therm)
+{
+ int chipset = nv_device(therm)->chipset;
+ int crystal = nv_device(therm)->crystal;
+ int pwm_clock;
+
+ /* determine the PWM source clock */
+ if (chipset > 0x50 && chipset < 0x94) {
+ u8 pwm_div = nv_rd32(therm, 0x410c);
+ if (nv_rd32(therm, 0xc040) & 0x800000) {
+ /* Use the HOST clock (100 MHz)
+ * Where does this constant(2.4) comes from? */
+ pwm_clock = (100000000 >> pwm_div) / 10 / 24;
+ } else {
+ /* Where does this constant(20) comes from? */
+ pwm_clock = (crystal * 1000) >> pwm_div;
+ pwm_clock /= 20;
+ }
+ } else {
+ pwm_clock = (crystal * 1000) / 20;
+ }
+
+ return pwm_clock;
+}
+
+int
nv50_temp_get(struct nouveau_therm *therm)
{
return nv_rd32(therm, 0x20400);
@@ -107,6 +133,7 @@ nv50_therm_ctor(struct nouveau_object *parent,
priv->fan.pwm_get = nv50_fan_pwm_get;
priv->fan.pwm_set = nv50_fan_pwm_set;
+ priv->fan.pwm_clock = nv50_fan_pwm_clock;
therm->temp_get = nv50_temp_get;
therm->fan_get = nouveau_therm_fan_get;