drm/nv50/pm: convert to new fanspeed pwm controller hooks
authorBen Skeggs <bskeggs@redhat.com>
Fri, 16 Sep 2011 16:01:24 +0000 (02:01 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 21 Dec 2011 09:01:12 +0000 (19:01 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_pm.h
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv50_pm.c

index 1b0bcef9ff35dc3fb435212e6562303774ad4782..2be384a922b3a2d3231c9e39b66d109f686d6c2d 100644 (file)
@@ -66,8 +66,8 @@ int nv50_pm_clock_get(struct drm_device *, u32 id);
 void *nv50_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
                        u32 id, int khz);
 void nv50_pm_clock_set(struct drm_device *, void *);
-int nv50_pm_fanspeed_get(struct drm_device *);
-int nv50_pm_fanspeed_set(struct drm_device *, int percent);
+int nv50_pm_pwm_get(struct drm_device *, struct dcb_gpio_entry *, u32*, u32*);
+int nv50_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);
 
 /* nva3_pm.c */
 int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
index 16195e9a9f91d4da7eb60477923e4ac2a52161e3..2028a393a900b38efafe6f0c8e4fc51fe1f4075c 100644 (file)
@@ -386,8 +386,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->pm.temp_get     = nv84_temp_get;
                else
                        engine->pm.temp_get     = nv40_temp_get;
-               engine->pm.fanspeed_get         = nv50_pm_fanspeed_get;
-               engine->pm.fanspeed_set         = nv50_pm_fanspeed_set;
+               engine->pm.pwm_get              = nv50_pm_pwm_get;
+               engine->pm.pwm_set              = nv50_pm_pwm_set;
                engine->vram.init               = nv50_vram_init;
                engine->vram.takedown           = nv50_vram_fini;
                engine->vram.get                = nv50_vram_new;
@@ -443,8 +443,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->pm.clocks_get           = nvc0_pm_clocks_get;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
-               engine->pm.fanspeed_get         = nv50_pm_fanspeed_get;
-               engine->pm.fanspeed_set         = nv50_pm_fanspeed_set;
+               engine->pm.pwm_get              = nv50_pm_pwm_get;
+               engine->pm.pwm_set              = nv50_pm_pwm_set;
                break;
        case 0xd0:
                engine->instmem.init            = nvc0_instmem_init;
index 0cbf538b6e8548f77ec65632fd2e8f8194da1133..8a56880e4e71bcf6c111874ddd992d245b80249d 100644 (file)
@@ -144,87 +144,59 @@ nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
        kfree(state);
 }
 
-struct pwm_info {
-       int id;
-       int invert;
-       u8  tag;
-       u32 ctrl;
-       int line;
-};
-
 static int
-nv50_pm_fanspeed_pwm(struct drm_device *dev, struct pwm_info *pwm)
+pwm_info(struct drm_device *dev, struct dcb_gpio_entry *gpio,
+        int *ctrl, int *line, int *indx)
 {
-       struct dcb_gpio_entry *gpio;
-
-       gpio = nouveau_bios_gpio_entry(dev, 0x09);
-       if (gpio) {
-               pwm->tag = gpio->tag;
-               pwm->id = (gpio->line == 9) ? 1 : 0;
-               pwm->invert = gpio->state[0] & 1;
-               pwm->ctrl = (gpio->line < 16) ? 0xe100 : 0xe28c;
-               pwm->line = (gpio->line & 0xf);
-               return 0;
+       if (gpio->line == 0x04) {
+               *ctrl = 0x00e100;
+               *line = 4;
+               *indx = 0;
+       } else
+       if (gpio->line == 0x09) {
+               *ctrl = 0x00e100;
+               *line = 9;
+               *indx = 1;
+       } else
+       if (gpio->line == 0x10) {
+               *ctrl = 0x00e28c;
+               *line = 0;
+               *indx = 0;
+       } else {
+               NV_ERROR(dev, "unknown pwm ctrl for gpio %d\n", gpio->line);
+               return -ENODEV;
        }
 
-       return -ENOENT;
+       return 0;
 }
 
 int
-nv50_pm_fanspeed_get(struct drm_device *dev)
+nv50_pm_pwm_get(struct drm_device *dev, struct dcb_gpio_entry *gpio,
+               u32 *divs, u32 *duty)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
-       struct pwm_info pwm;
-       int ret;
-
-       ret = nv50_pm_fanspeed_pwm(dev, &pwm);
+       int ctrl, line, id, ret = pwm_info(dev, gpio, &ctrl, &line, &id);
        if (ret)
                return ret;
 
-       if (nv_rd32(dev, pwm.ctrl) & (0x00000001 << pwm.line)) {
-               u32 divs = nv_rd32(dev, 0x00e114 + (pwm.id * 8));
-               u32 duty = nv_rd32(dev, 0x00e118 + (pwm.id * 8));
-               if (divs) {
-                       divs = max(divs, duty);
-                       if (pwm.invert)
-                               duty = divs - duty;
-                       return (duty * 100) / divs;
-               }
-
+       if (nv_rd32(dev, ctrl) & (1 << line)) {
+               *divs = nv_rd32(dev, 0x00e114 + (id * 8));
+               *duty = nv_rd32(dev, 0x00e118 + (id * 8));
                return 0;
        }
 
-       return pgpio->get(dev, pwm.tag) * 100;
+       return -EINVAL;
 }
 
 int
-nv50_pm_fanspeed_set(struct drm_device *dev, int percent)
+nv50_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;
-       struct pwm_info pwm;
-       u32 divs, duty;
-       int ret;
-
-       ret = nv50_pm_fanspeed_pwm(dev, &pwm);
+       int ctrl, line, id, ret = pwm_info(dev, gpio, &ctrl, &line, &id);
        if (ret)
                return ret;
 
-       divs = pm->pwm_divisor;
-       if (pm->fan.pwm_freq) {
-               /*XXX: PNVIO clock more than likely... */
-               divs = 1350000 / pm->fan.pwm_freq;
-               if (dev_priv->chipset < 0xa3)
-                       divs /= 4;
-       }
-
-       duty = ((divs * percent) + 99) / 100;
-       if (pwm.invert)
-               duty = divs - duty;
-
-       nv_mask(dev, pwm.ctrl, 0x00010001 << pwm.line, 0x00000001 << pwm.line);
-       nv_wr32(dev, 0x00e114 + (pwm.id * 8), divs);
-       nv_wr32(dev, 0x00e118 + (pwm.id * 8), 0x80000000 | duty);
+       nv_mask(dev, ctrl, 0x00010001 << line, 0x00000001 << line);
+       nv_wr32(dev, 0x00e114 + (id * 8), divs);
+       nv_wr32(dev, 0x00e118 + (id * 8), duty | 0x80000000);
        return 0;
 }