diff options
Diffstat (limited to 'drivers/gpu/drm')
-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 */ |