Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282563
b: refs/heads/master
c: cb9fa62
h: refs/heads/master
i:
  282561: aa21439
  282559: 6f9c302
v: v3
  • Loading branch information
Ben Skeggs committed Dec 21, 2011
1 parent b8fc9a2 commit 6ffd593
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f27c54342dffbfbafbddd6e43f011e6cb16d285
refs/heads/master: cb9fa62671ace5ac40b9924e9014cebf04b78228
7 changes: 5 additions & 2 deletions trunk/drivers/gpu/drm/nouveau/nouveau_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,11 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
}
}

if (pm->fanspeed_get)
perflvl->fanspeed = pm->fanspeed_get(dev);
if (pm->fanspeed_get) {
ret = pm->fanspeed_get(dev);
if (ret > 0)
perflvl->fanspeed = ret;
}

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +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);

/* nva3_pm.c */
int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +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->vram.init = nv50_vram_init;
engine->vram.takedown = nv50_vram_fini;
engine->vram.get = nv50_vram_new;
Expand Down Expand Up @@ -441,6 +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;
break;
case 0xd0:
engine->instmem.init = nvc0_instmem_init;
Expand Down
74 changes: 74 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nv50_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,77 @@ 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)
{
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;
}

return -ENOENT;
}

int
nv50_pm_fanspeed_get(struct drm_device *dev)
{
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);
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;
}

return 0;
}

return pgpio->get(dev, pwm.tag) * 100;
}

int
nv50_pm_fanspeed_set(struct drm_device *dev, int percent)
{
struct pwm_info pwm;
u32 divs, duty;
int ret;

ret = nv50_pm_fanspeed_pwm(dev, &pwm);
if (ret)
return ret;

divs = nv_rd32(dev, 0x00e114 + (pwm.id * 8));
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, 0x00e118 + (pwm.id * 8), 0x80000000 | duty);
return 0;
}

0 comments on commit 6ffd593

Please sign in to comment.