aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@labri.fr>2012-09-01 22:01:43 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:13:14 -0400
commitcfc732bbc59d8905634fef7d7b02bdac84ea9221 (patch)
tree8761fb1e9cf863f329b9265394f8cba2d5e713a3 /drivers/gpu
parentbf6546b4219d2b188529f3242efda4048f5b1b41 (diff)
drm/nouveau/therm: calculate the pwm divisor on nv50+
v2: Martin Peres <martin.peres@labri.fr> - fixed unintentional use of floating point Signed-off-by: Martin Peres <martin.peres@labri.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/fan.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h1
3 files changed, 37 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
index b7339b52559e..409b95d5b679 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c
@@ -81,10 +81,10 @@ nouveau_therm_fan_set(struct nouveau_therm *therm, int percent)
81 if (ret == 0) { 81 if (ret == 0) {
82 divs = priv->bios_perf_fan.pwm_divisor; 82 divs = priv->bios_perf_fan.pwm_divisor;
83 if (priv->bios_fan.pwm_freq) { 83 if (priv->bios_fan.pwm_freq) {
84 /*XXX: PNVIO clock more than likely... */ 84 divs = 1;
85 divs = 135000 /priv->bios_fan.pwm_freq; 85 if (priv->fan.pwm_clock)
86 if (nv_device(therm)->chipset < 0xa3) 86 divs = priv->fan.pwm_clock(therm);
87 divs /= 4; 87 divs /= priv->bios_fan.pwm_freq;
88 } 88 }
89 89
90 duty = ((divs * percent) + 99) / 100; 90 duty = ((divs * percent) + 99) / 100;
@@ -163,6 +163,11 @@ nouveau_therm_fan_safety_checks(struct nouveau_therm *therm)
163 priv->bios_fan.min_duty = priv->bios_fan.max_duty; 163 priv->bios_fan.min_duty = priv->bios_fan.max_duty;
164} 164}
165 165
166int nouveau_fan_pwm_clock_dummy(struct nouveau_therm *therm)
167{
168 return 1;
169}
170
166int 171int
167nouveau_therm_fan_ctor(struct nouveau_therm *therm) 172nouveau_therm_fan_ctor(struct nouveau_therm *therm)
168{ 173{
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)
80} 80}
81 81
82int 82int
83nv50_fan_pwm_clock(struct nouveau_therm *therm)
84{
85 int chipset = nv_device(therm)->chipset;
86 int crystal = nv_device(therm)->crystal;
87 int pwm_clock;
88
89 /* determine the PWM source clock */
90 if (chipset > 0x50 && chipset < 0x94) {
91 u8 pwm_div = nv_rd32(therm, 0x410c);
92 if (nv_rd32(therm, 0xc040) & 0x800000) {
93 /* Use the HOST clock (100 MHz)
94 * Where does this constant(2.4) comes from? */
95 pwm_clock = (100000000 >> pwm_div) / 10 / 24;
96 } else {
97 /* Where does this constant(20) comes from? */
98 pwm_clock = (crystal * 1000) >> pwm_div;
99 pwm_clock /= 20;
100 }
101 } else {
102 pwm_clock = (crystal * 1000) / 20;
103 }
104
105 return pwm_clock;
106}
107
108int
83nv50_temp_get(struct nouveau_therm *therm) 109nv50_temp_get(struct nouveau_therm *therm)
84{ 110{
85 return nv_rd32(therm, 0x20400); 111 return nv_rd32(therm, 0x20400);
@@ -107,6 +133,7 @@ nv50_therm_ctor(struct nouveau_object *parent,
107 133
108 priv->fan.pwm_get = nv50_fan_pwm_get; 134 priv->fan.pwm_get = nv50_fan_pwm_get;
109 priv->fan.pwm_set = nv50_fan_pwm_set; 135 priv->fan.pwm_set = nv50_fan_pwm_set;
136 priv->fan.pwm_clock = nv50_fan_pwm_clock;
110 137
111 therm->temp_get = nv50_temp_get; 138 therm->temp_get = nv50_temp_get;
112 therm->fan_get = nouveau_therm_fan_get; 139 therm->fan_get = nouveau_therm_fan_get;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
index b7207b4524f6..c53eb5396972 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
@@ -42,6 +42,7 @@ struct nouveau_therm_priv {
42 42
43 int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*); 43 int (*pwm_get)(struct nouveau_therm *, int line, u32*, u32*);
44 int (*pwm_set)(struct nouveau_therm *, int line, u32, u32); 44 int (*pwm_set)(struct nouveau_therm *, int line, u32, u32);
45 int (*pwm_clock)(struct nouveau_therm *);
45 } fan; 46 } fan;
46 47
47 /* ic */ 48 /* ic */