|
@@ -79,6 +79,32 @@ nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+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)
|
|
|
{
|
|
@@ -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;
|