aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_temp.c50
5 files changed, 43 insertions, 39 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 3fc5596df36..799cd149745 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -411,6 +411,8 @@ struct nouveau_pm_engine {
411 struct nouveau_pm_level boot; 411 struct nouveau_pm_level boot;
412 struct nouveau_pm_level *cur; 412 struct nouveau_pm_level *cur;
413 413
414 struct device *hwmon;
415
414 int (*clock_get)(struct drm_device *, u32 id); 416 int (*clock_get)(struct drm_device *, u32 id);
415 void *(*clock_pre)(struct drm_device *, u32 id, int khz); 417 void *(*clock_pre)(struct drm_device *, u32 id, int khz);
416 void (*clock_set)(struct drm_device *, void *); 418 void (*clock_set)(struct drm_device *, void *);
@@ -418,6 +420,7 @@ struct nouveau_pm_engine {
418 int (*voltage_set)(struct drm_device *, int voltage); 420 int (*voltage_set)(struct drm_device *, int voltage);
419 int (*fanspeed_get)(struct drm_device *); 421 int (*fanspeed_get)(struct drm_device *);
420 int (*fanspeed_set)(struct drm_device *, int fanspeed); 422 int (*fanspeed_set)(struct drm_device *, int fanspeed);
423 int (*temp_get)(struct drm_device *);
421}; 424};
422 425
423struct nouveau_engine { 426struct nouveau_engine {
@@ -679,8 +682,6 @@ struct drm_nouveau_private {
679 682
680 struct nouveau_fbdev *nfbdev; 683 struct nouveau_fbdev *nfbdev;
681 struct apertures_struct *apertures; 684 struct apertures_struct *apertures;
682
683 struct device *int_hwmon_dev;
684}; 685};
685 686
686static inline struct drm_nouveau_private * 687static inline struct drm_nouveau_private *
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index 09b638435f8..85a56dea0ef 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -289,8 +289,10 @@ static ssize_t
289nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) 289nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
290{ 290{
291 struct drm_device *dev = dev_get_drvdata(d); 291 struct drm_device *dev = dev_get_drvdata(d);
292 struct drm_nouveau_private *dev_priv = dev->dev_private;
293 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
292 294
293 return snprintf(buf, PAGE_SIZE, "%d\n", nouveau_temp_get(dev)*1000); 295 return snprintf(buf, PAGE_SIZE, "%d\n", pm->temp_get(dev)*1000);
294} 296}
295static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, 297static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
296 NULL, 0); 298 NULL, 0);
@@ -399,10 +401,12 @@ static int
399nouveau_hwmon_init(struct drm_device *dev) 401nouveau_hwmon_init(struct drm_device *dev)
400{ 402{
401 struct drm_nouveau_private *dev_priv = dev->dev_private; 403 struct drm_nouveau_private *dev_priv = dev->dev_private;
404 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
402 struct device *hwmon_dev; 405 struct device *hwmon_dev;
403 int ret; 406 int ret;
404 407
405 dev_priv->int_hwmon_dev = NULL; 408 if (!pm->temp_get)
409 return -ENODEV;
406 410
407 hwmon_dev = hwmon_device_register(&dev->pdev->dev); 411 hwmon_dev = hwmon_device_register(&dev->pdev->dev);
408 if (IS_ERR(hwmon_dev)) { 412 if (IS_ERR(hwmon_dev)) {
@@ -421,7 +425,7 @@ nouveau_hwmon_init(struct drm_device *dev)
421 return ret; 425 return ret;
422 } 426 }
423 427
424 dev_priv->int_hwmon_dev = hwmon_dev; 428 pm->hwmon = hwmon_dev;
425 429
426 return 0; 430 return 0;
427} 431}
@@ -430,15 +434,14 @@ static void
430nouveau_hwmon_fini(struct drm_device *dev) 434nouveau_hwmon_fini(struct drm_device *dev)
431{ 435{
432 struct drm_nouveau_private *dev_priv = dev->dev_private; 436 struct drm_nouveau_private *dev_priv = dev->dev_private;
437 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
433 438
434 if (dev_priv->int_hwmon_dev) { 439 if (pm->hwmon) {
435 sysfs_remove_group(&dev_priv->int_hwmon_dev->kobj, 440 sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup);
436 &hwmon_attrgroup); 441 hwmon_device_unregister(pm->hwmon);
437 hwmon_device_unregister(dev_priv->int_hwmon_dev);
438 } 442 }
439} 443}
440 444
441
442int 445int
443nouveau_pm_init(struct drm_device *dev) 446nouveau_pm_init(struct drm_device *dev)
444{ 447{
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index d048b7516b1..6ad0ca9db88 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -56,6 +56,7 @@ void nv50_pm_clock_set(struct drm_device *, void *);
56void nouveau_temp_init(struct drm_device *dev); 56void nouveau_temp_init(struct drm_device *dev);
57void nouveau_temp_fini(struct drm_device *dev); 57void nouveau_temp_fini(struct drm_device *dev);
58void nouveau_temp_safety_checks(struct drm_device *dev); 58void nouveau_temp_safety_checks(struct drm_device *dev);
59int16_t nouveau_temp_get(struct drm_device *dev); 59int nv40_temp_get(struct drm_device *dev);
60int nv84_temp_get(struct drm_device *dev);
60 61
61#endif 62#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index f9f77de6bbc..affcfc2fae1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -320,6 +320,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
320 engine->pm.clock_set = nv04_pm_clock_set; 320 engine->pm.clock_set = nv04_pm_clock_set;
321 engine->pm.voltage_get = nouveau_voltage_gpio_get; 321 engine->pm.voltage_get = nouveau_voltage_gpio_get;
322 engine->pm.voltage_set = nouveau_voltage_gpio_set; 322 engine->pm.voltage_set = nouveau_voltage_gpio_set;
323 engine->pm.temp_get = nv40_temp_get;
323 break; 324 break;
324 case 0x50: 325 case 0x50:
325 case 0x80: /* gotta love NVIDIA's consistency.. */ 326 case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -379,6 +380,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
379 engine->pm.clock_set = nv50_pm_clock_set; 380 engine->pm.clock_set = nv50_pm_clock_set;
380 engine->pm.voltage_get = nouveau_voltage_gpio_get; 381 engine->pm.voltage_get = nouveau_voltage_gpio_get;
381 engine->pm.voltage_set = nouveau_voltage_gpio_set; 382 engine->pm.voltage_set = nouveau_voltage_gpio_set;
383 if (dev_priv->chipset >= 0x84)
384 engine->pm.temp_get = nv84_temp_get;
385 else
386 engine->pm.temp_get = nv40_temp_get;
382 break; 387 break;
383 case 0xC0: 388 case 0xC0:
384 engine->instmem.init = nvc0_instmem_init; 389 engine->instmem.init = nvc0_instmem_init;
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c
index 86b170a851b..2f7785ca4e4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_temp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c
@@ -154,8 +154,8 @@ nouveau_temp_vbios_parse(struct drm_device *dev, u8 *temp)
154 nouveau_temp_safety_checks(dev); 154 nouveau_temp_safety_checks(dev);
155} 155}
156 156
157static s16 157static int
158nouveau_nv40_sensor_setup(struct drm_device *dev) 158nv40_sensor_setup(struct drm_device *dev)
159{ 159{
160 struct drm_nouveau_private *dev_priv = dev->dev_private; 160 struct drm_nouveau_private *dev_priv = dev->dev_private;
161 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 161 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
@@ -182,40 +182,34 @@ nouveau_nv40_sensor_setup(struct drm_device *dev)
182 return nv_rd32(dev, 0x0015b4) & 0x1fff; 182 return nv_rd32(dev, 0x0015b4) & 0x1fff;
183} 183}
184 184
185s16 185int
186nouveau_temp_get(struct drm_device *dev) 186nv40_temp_get(struct drm_device *dev)
187{ 187{
188 struct drm_nouveau_private *dev_priv = dev->dev_private; 188 struct drm_nouveau_private *dev_priv = dev->dev_private;
189 struct nouveau_pm_engine *pm = &dev_priv->engine.pm; 189 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
190 struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants; 190 struct nouveau_pm_temp_sensor_constants *sensor = &pm->sensor_constants;
191 int offset = sensor->offset_mult / sensor->offset_div;
192 int core_temp;
191 193
192 if (dev_priv->chipset >= 0x84) { 194 if (dev_priv->chipset >= 0x50) {
193 return nv_rd32(dev, 0x20400); 195 core_temp = nv_rd32(dev, 0x20008);
194 } else if (dev_priv->chipset >= 0x40) {
195 u32 offset = sensor->offset_mult / sensor->offset_div;
196 u32 core_temp;
197
198 if (dev_priv->chipset >= 0x50) {
199 core_temp = nv_rd32(dev, 0x20008);
200 } else {
201 core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
202 /* Setup the sensor if the temperature is 0 */
203 if (core_temp == 0)
204 core_temp = nouveau_nv40_sensor_setup(dev);
205 }
206
207 core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
208 core_temp = core_temp + offset + sensor->offset_constant;
209
210 return core_temp;
211 } else { 196 } else {
212 NV_ERROR(dev, 197 core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff;
213 "Temperature cannot be retrieved from an nv%x card\n", 198 /* Setup the sensor if the temperature is 0 */
214 dev_priv->chipset); 199 if (core_temp == 0)
215 return 0; 200 core_temp = nv40_sensor_setup(dev);
216 } 201 }
217 202
218 return 0; 203 core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
204 core_temp = core_temp + offset + sensor->offset_constant;
205
206 return core_temp;
207}
208
209int
210nv84_temp_get(struct drm_device *dev)
211{
212 return nv_rd32(dev, 0x20400);
219} 213}
220 214
221void 215void