From: Ben Skeggs Date: Fri, 16 Sep 2011 16:01:24 +0000 (+1000) Subject: drm/nv50/pm: convert to new fanspeed pwm controller hooks X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=5a4267ab14b392bdf43893c6175b045b5f85d53d;p=deliverable%2Flinux.git drm/nv50/pm: convert to new fanspeed pwm controller hooks Signed-off-by: Ben Skeggs --- diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h index 1b0bcef9ff35..2be384a922b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.h +++ b/drivers/gpu/drm/nouveau/nouveau_pm.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 16195e9a9f91..2028a393a900 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 0cbf538b6e85..8a56880e4e71 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c @@ -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; }