diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/fan.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c | 27 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | 1 |
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 | ||
| 166 | int nouveau_fan_pwm_clock_dummy(struct nouveau_therm *therm) | ||
| 167 | { | ||
| 168 | return 1; | ||
| 169 | } | ||
| 170 | |||
| 166 | int | 171 | int |
| 167 | nouveau_therm_fan_ctor(struct nouveau_therm *therm) | 172 | nouveau_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 | ||
| 82 | int | 82 | int |
| 83 | nv50_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 | |||
| 108 | int | ||
| 83 | nv50_temp_get(struct nouveau_therm *therm) | 109 | nv50_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 */ |
