summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_temp.c3
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c12
4 files changed, 17 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 432be658060d..251eaf87fa28 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -524,6 +524,7 @@ struct nouveau_pm_memtimings {
struct nouveau_pm_fan {
u32 min_duty;
u32 max_duty;
+ u32 pwm_freq;
};
struct nouveau_pm_engine {
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 3d20dca08fe8..6ea57c91162b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -206,13 +206,12 @@ nouveau_perf_init(struct drm_device *dev)
if (version < 0x40) {
recordlen = perf[3] + (perf[4] * perf[5]);
entries = perf[2];
+
+ pm->pwm_divisor = ROM16(perf[6]);
} else {
recordlen = perf[2] + (perf[3] * perf[4]);
entries = perf[5];
}
-
- if (version < 0x30)
- pm->pwm_divisor = ROM16(perf[6]);
} else {
if (bios->data[bios->offset + 6] < 0x25) {
legacy_perf_init(dev);
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c
index 97c172cae3bc..6364e4c46124 100644
--- a/drivers/gpu/drm/nouveau/nouveau_temp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c
@@ -164,6 +164,9 @@ nouveau_temp_vbios_parse(struct drm_device *dev, u8 *temp)
pm->fan.min_duty = value & 0xff;
pm->fan.max_duty = (value & 0xff00) >> 8;
break;
+ case 0x26:
+ pm->fan.pwm_freq = value;
+ break;
}
temp += recordlen;
}
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index 713c718206e3..0cbf538b6e85 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -201,6 +201,8 @@ nv50_pm_fanspeed_get(struct drm_device *dev)
int
nv50_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;
struct pwm_info pwm;
u32 divs, duty;
int ret;
@@ -209,12 +211,20 @@ nv50_pm_fanspeed_set(struct drm_device *dev, int percent)
if (ret)
return ret;
- divs = nv_rd32(dev, 0x00e114 + (pwm.id * 8));
+ 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);
return 0;
}
OpenPOWER on IntegriCloud