Commit 5a4267ab authored by Ben Skeggs's avatar Ben Skeggs

drm/nv50/pm: convert to new fanspeed pwm controller hooks

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent a175094c
...@@ -66,8 +66,8 @@ int nv50_pm_clock_get(struct drm_device *, u32 id); ...@@ -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 *, void *nv50_pm_clock_pre(struct drm_device *, struct nouveau_pm_level *,
u32 id, int khz); u32 id, int khz);
void nv50_pm_clock_set(struct drm_device *, void *); void nv50_pm_clock_set(struct drm_device *, void *);
int nv50_pm_fanspeed_get(struct drm_device *); int nv50_pm_pwm_get(struct drm_device *, struct dcb_gpio_entry *, u32*, u32*);
int nv50_pm_fanspeed_set(struct drm_device *, int percent); int nv50_pm_pwm_set(struct drm_device *, struct dcb_gpio_entry *, u32, u32);
/* nva3_pm.c */ /* nva3_pm.c */
int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
......
...@@ -386,8 +386,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -386,8 +386,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.temp_get = nv84_temp_get; engine->pm.temp_get = nv84_temp_get;
else else
engine->pm.temp_get = nv40_temp_get; engine->pm.temp_get = nv40_temp_get;
engine->pm.fanspeed_get = nv50_pm_fanspeed_get; engine->pm.pwm_get = nv50_pm_pwm_get;
engine->pm.fanspeed_set = nv50_pm_fanspeed_set; engine->pm.pwm_set = nv50_pm_pwm_set;
engine->vram.init = nv50_vram_init; engine->vram.init = nv50_vram_init;
engine->vram.takedown = nv50_vram_fini; engine->vram.takedown = nv50_vram_fini;
engine->vram.get = nv50_vram_new; engine->vram.get = nv50_vram_new;
...@@ -443,8 +443,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -443,8 +443,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->pm.clocks_get = nvc0_pm_clocks_get; engine->pm.clocks_get = nvc0_pm_clocks_get;
engine->pm.voltage_get = nouveau_voltage_gpio_get; engine->pm.voltage_get = nouveau_voltage_gpio_get;
engine->pm.voltage_set = nouveau_voltage_gpio_set; engine->pm.voltage_set = nouveau_voltage_gpio_set;
engine->pm.fanspeed_get = nv50_pm_fanspeed_get; engine->pm.pwm_get = nv50_pm_pwm_get;
engine->pm.fanspeed_set = nv50_pm_fanspeed_set; engine->pm.pwm_set = nv50_pm_pwm_set;
break; break;
case 0xd0: case 0xd0:
engine->instmem.init = nvc0_instmem_init; engine->instmem.init = nvc0_instmem_init;
......
...@@ -144,87 +144,59 @@ nv50_pm_clock_set(struct drm_device *dev, void *pre_state) ...@@ -144,87 +144,59 @@ nv50_pm_clock_set(struct drm_device *dev, void *pre_state)
kfree(state); kfree(state);
} }
struct pwm_info {
int id;
int invert;
u8 tag;
u32 ctrl;
int line;
};
static int 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; if (gpio->line == 0x04) {
*ctrl = 0x00e100;
gpio = nouveau_bios_gpio_entry(dev, 0x09); *line = 4;
if (gpio) { *indx = 0;
pwm->tag = gpio->tag; } else
pwm->id = (gpio->line == 9) ? 1 : 0; if (gpio->line == 0x09) {
pwm->invert = gpio->state[0] & 1; *ctrl = 0x00e100;
pwm->ctrl = (gpio->line < 16) ? 0xe100 : 0xe28c; *line = 9;
pwm->line = (gpio->line & 0xf); *indx = 1;
return 0; } 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 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; int ctrl, line, id, ret = pwm_info(dev, gpio, &ctrl, &line, &id);
struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
struct pwm_info pwm;
int ret;
ret = nv50_pm_fanspeed_pwm(dev, &pwm);
if (ret) if (ret)
return ret; return ret;
if (nv_rd32(dev, pwm.ctrl) & (0x00000001 << pwm.line)) { if (nv_rd32(dev, ctrl) & (1 << line)) {
u32 divs = nv_rd32(dev, 0x00e114 + (pwm.id * 8)); *divs = nv_rd32(dev, 0x00e114 + (id * 8));
u32 duty = nv_rd32(dev, 0x00e118 + (pwm.id * 8)); *duty = nv_rd32(dev, 0x00e118 + (id * 8));
if (divs) {
divs = max(divs, duty);
if (pwm.invert)
duty = divs - duty;
return (duty * 100) / divs;
}
return 0; return 0;
} }
return pgpio->get(dev, pwm.tag) * 100; return -EINVAL;
} }
int 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; int ctrl, line, id, ret = pwm_info(dev, gpio, &ctrl, &line, &id);
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);
if (ret) if (ret)
return ret; return ret;
divs = pm->pwm_divisor; nv_mask(dev, ctrl, 0x00010001 << line, 0x00000001 << line);
if (pm->fan.pwm_freq) { nv_wr32(dev, 0x00e114 + (id * 8), divs);
/*XXX: PNVIO clock more than likely... */ nv_wr32(dev, 0x00e118 + (id * 8), duty | 0x80000000);
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);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment