summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-09-17 02:11:39 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 19:01:13 +1000
commit693461801464eb65eb779261b3d9d80dc9131f81 (patch)
treee5da9ddcfc093b4dbeb07cbc47b9faffc913c23e
parent5a4267ab14b392bdf43893c6175b045b5f85d53d (diff)
drm/nv40/pm: convert to new pwm hooks, also fixing pwm type detection
A NV49 appeared a while back that was using the "nv41 style" pwm registers, rather than the "nv40 style" ones my board is using. This disproves the previous theory that the pwm controller choice is chipset-specific. So, after looking at a bunch of vbios images it appears that the next viable theory is that we should select the pwm controller to use based on the gpio line the fan is tied to, just like we do on nv50. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c18
-rw-r--r--drivers/gpu/drm/nouveau/nv40_pm.c72
3 files changed, 36 insertions, 60 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 2be384a922b..5c87afde82d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -56,10 +56,8 @@ void nv04_pm_clock_set(struct drm_device *, void *);
int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
void nv40_pm_clocks_set(struct drm_device *, void *);
-int nv40_pm_fanspeed_get(struct drm_device *);
-int nv40_pm_fanspeed_set(struct drm_device *, int percent);
-int nv41_pm_fanspeed_get(struct drm_device *);
-int nv41_pm_fanspeed_set(struct drm_device *, int percent);
+int nv40_pm_pwm_get(struct drm_device *, struct dcb_gpio_entry *, u32*, u32*);
+int nv40_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);
/* nv50_pm.c */
int nv50_pm_clock_get(struct drm_device *, u32 id);
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 2028a393a90..3d5cf6bb1c7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -292,22 +292,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set;
engine->pm.temp_get = nv40_temp_get;
- switch (dev_priv->chipset) {
- case 0x40:
- case 0x49:
- engine->pm.fanspeed_get = nv40_pm_fanspeed_get;
- engine->pm.fanspeed_set = nv40_pm_fanspeed_set;
- break;
- case 0x42:
- case 0x43:
- case 0x47:
- case 0x4b:
- engine->pm.fanspeed_get = nv41_pm_fanspeed_get;
- engine->pm.fanspeed_set = nv41_pm_fanspeed_set;
- break;
- default:
- break;
- }
+ engine->pm.pwm_get = nv40_pm_pwm_get;
+ engine->pm.pwm_set = nv40_pm_pwm_set;
engine->vram.init = nouveau_mem_detect;
engine->vram.takedown = nouveau_stub_takedown;
engine->vram.flags_valid = nouveau_mem_flags_valid;
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
index e7660b175de..02d5be8bff1 100644
--- a/drivers/gpu/drm/nouveau/nv40_pm.c
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
@@ -348,54 +348,46 @@ resume:
}
int
-nv40_pm_fanspeed_get(struct drm_device *dev)
+nv40_pm_pwm_get(struct drm_device *dev, struct dcb_gpio_entry *gpio,
+ u32 *divs, u32 *duty)
{
- u32 reg = nv_rd32(dev, 0x0010f0);
- if (reg & 0x80000000) {
- u32 duty = (reg & 0x7fff0000) >> 16;
- u32 divs = (reg & 0x00007fff);
- if (divs && divs >= duty)
- return ((divs - duty) * 100) / divs;
+ if (gpio->line == 2) {
+ u32 reg = nv_rd32(dev, 0x0010f0);
+ if (reg & 0x80000000) {
+ *duty = (reg & 0x7fff0000) >> 16;
+ *divs = (reg & 0x00007fff);
+ return 0;
+ }
+ } else
+ if (gpio->line == 9) {
+ u32 reg = nv_rd32(dev, 0x0015f4);
+ if (reg & 0x80000000) {
+ *divs = nv_rd32(dev, 0x0015f8);
+ *duty = (reg & 0x7fffffff);
+ return 0;
+ }
+ } else {
+ NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", gpio->line);
+ return -ENODEV;
}
- return 100;
+ return -EINVAL;
}
int
-nv40_pm_fanspeed_set(struct drm_device *dev, int percent)
+nv40_pm_pwm_set(struct drm_device *dev, struct dcb_gpio_entry *gpio,
+ u32 divs, u32 duty)
{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- u32 divs = pm->pwm_divisor;
- u32 duty = ((100 - percent) * divs) / 100;
-
- nv_wr32(dev, 0x0010f0, 0x80000000 | (duty << 16) | divs);
- return 0;
-}
-
-int
-nv41_pm_fanspeed_get(struct drm_device *dev)
-{
- u32 reg = nv_rd32(dev, 0x0015f4);
- if (reg & 0x80000000) {
- u32 divs = nv_rd32(dev, 0x0015f8);
- u32 duty = (reg & 0x7fffffff);
- if (divs && divs >= duty)
- return ((divs - duty) * 100) / divs;
+ if (gpio->line == 2) {
+ nv_wr32(dev, 0x0010f0, 0x80000000 | (duty << 16) | divs);
+ } else
+ if (gpio->line == 9) {
+ nv_wr32(dev, 0x0015f8, divs);
+ nv_wr32(dev, 0x0015f4, duty | 0x80000000);
+ } else {
+ NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", gpio->line);
+ return -ENODEV;
}
- return 100;
-}
-
-int
-nv41_pm_fanspeed_set(struct drm_device *dev, int percent)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- u32 divs = pm->pwm_divisor;
- u32 duty = ((100 - percent) * divs) / 100;
-
- nv_wr32(dev, 0x0015f8, divs);
- nv_wr32(dev, 0x0015f4, duty | 0x80000000);
return 0;
}