aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-08-15 02:13:34 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-12-21 04:01:11 -0500
commit3f8e11e4b606a050007cd1020d59e7b74c68d088 (patch)
tree4d550be304e3229af2228bcd9469f34057395dbb /drivers
parent11b7d895216f7f954c6cfa0c23b76dccb7a890c1 (diff)
drm/nv50/pm: mostly nailed down fan pwm frequency selection
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-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 {
524struct nouveau_pm_fan { 524struct nouveau_pm_fan {
525 u32 min_duty; 525 u32 min_duty;
526 u32 max_duty; 526 u32 max_duty;
527 u32 pwm_freq;
527}; 528};
528 529
529struct nouveau_pm_engine { 530struct 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)
206 if (version < 0x40) { 206 if (version < 0x40) {
207 recordlen = perf[3] + (perf[4] * perf[5]); 207 recordlen = perf[3] + (perf[4] * perf[5]);
208 entries = perf[2]; 208 entries = perf[2];
209
210 pm->pwm_divisor = ROM16(perf[6]);
209 } else { 211 } else {
210 recordlen = perf[2] + (perf[3] * perf[4]); 212 recordlen = perf[2] + (perf[3] * perf[4]);
211 entries = perf[5]; 213 entries = perf[5];
212 } 214 }
213
214 if (version < 0x30)
215 pm->pwm_divisor = ROM16(perf[6]);
216 } else { 215 } else {
217 if (bios->data[bios->offset + 6] < 0x25) { 216 if (bios->data[bios->offset + 6] < 0x25) {
218 legacy_perf_init(dev); 217 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)
164 pm->fan.min_duty = value & 0xff; 164 pm->fan.min_duty = value & 0xff;
165 pm->fan.max_duty = (value & 0xff00) >> 8; 165 pm->fan.max_duty = (value & 0xff00) >> 8;
166 break; 166 break;
167 case 0x26:
168 pm->fan.pwm_freq = value;
169 break;
167 } 170 }
168 temp += recordlen; 171 temp += recordlen;
169 } 172 }
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)
201int 201int
202nv50_pm_fanspeed_set(struct drm_device *dev, int percent) 202nv50_pm_fanspeed_set(struct drm_device *dev, int percent)
203{ 203{
204 struct drm_nouveau_private *dev_priv = dev->dev_private;
205 struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
204 struct pwm_info pwm; 206 struct pwm_info pwm;
205 u32 divs, duty; 207 u32 divs, duty;
206 int ret; 208 int ret;
@@ -209,12 +211,20 @@ nv50_pm_fanspeed_set(struct drm_device *dev, int percent)
209 if (ret) 211 if (ret)
210 return ret; 212 return ret;
211 213
212 divs = nv_rd32(dev, 0x00e114 + (pwm.id * 8)); 214 divs = pm->pwm_divisor;
215 if (pm->fan.pwm_freq) {
216 /*XXX: PNVIO clock more than likely... */
217 divs = 1350000 / pm->fan.pwm_freq;
218 if (dev_priv->chipset < 0xa3)
219 divs /= 4;
220 }
221
213 duty = ((divs * percent) + 99) / 100; 222 duty = ((divs * percent) + 99) / 100;
214 if (pwm.invert) 223 if (pwm.invert)
215 duty = divs - duty; 224 duty = divs - duty;
216 225
217 nv_mask(dev, pwm.ctrl, 0x00010001 << pwm.line, 0x00000001 << pwm.line); 226 nv_mask(dev, pwm.ctrl, 0x00010001 << pwm.line, 0x00000001 << pwm.line);
227 nv_wr32(dev, 0x00e114 + (pwm.id * 8), divs);
218 nv_wr32(dev, 0x00e118 + (pwm.id * 8), 0x80000000 | duty); 228 nv_wr32(dev, 0x00e118 + (pwm.id * 8), 0x80000000 | duty);
219 return 0; 229 return 0;
220} 230}