aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@free.fr>2011-04-13 18:46:19 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-05-15 20:50:30 -0400
commite614b2e7ca9f9946cede13b34c950b92af6fa7ef (patch)
treed721917f2a547fd6f9471deb36bb23aceb569b70 /drivers/gpu
parentdac55b58253fe4ced44979543bde35d25eaf56dc (diff)
drm/nouveau: Associate memtimings with performance levels on cards <= nv98
v2 (Ben Skeggs): fix ramcfg strap, and remove bogus handling of perf 0x40 Signed-off-by: Martin Peres <martin.peres@ensi-bourges.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h26
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c14
4 files changed, 44 insertions, 18 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index e4c26a2df02a..224d3a1ce6ec 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -410,6 +410,19 @@ struct nouveau_pm_voltage {
410 int nr_level; 410 int nr_level;
411}; 411};
412 412
413struct nouveau_pm_memtiming {
414 int id;
415 u32 reg_100220;
416 u32 reg_100224;
417 u32 reg_100228;
418 u32 reg_10022c;
419 u32 reg_100230;
420 u32 reg_100234;
421 u32 reg_100238;
422 u32 reg_10023c;
423 u32 reg_100240;
424};
425
413#define NOUVEAU_PM_MAX_LEVEL 8 426#define NOUVEAU_PM_MAX_LEVEL 8
414struct nouveau_pm_level { 427struct nouveau_pm_level {
415 struct device_attribute dev_attr; 428 struct device_attribute dev_attr;
@@ -425,6 +438,7 @@ struct nouveau_pm_level {
425 u8 fanspeed; 438 u8 fanspeed;
426 439
427 u16 memscript; 440 u16 memscript;
441 struct nouveau_pm_memtiming *timing;
428}; 442};
429 443
430struct nouveau_pm_temp_sensor_constants { 444struct nouveau_pm_temp_sensor_constants {
@@ -441,18 +455,6 @@ struct nouveau_pm_threshold_temp {
441 s16 fan_boost; 455 s16 fan_boost;
442}; 456};
443 457
444struct nouveau_pm_memtiming {
445 u32 reg_100220;
446 u32 reg_100224;
447 u32 reg_100228;
448 u32 reg_10022c;
449 u32 reg_100230;
450 u32 reg_100234;
451 u32 reg_100238;
452 u32 reg_10023c;
453 u32 reg_100240;
454};
455
456struct nouveau_pm_memtimings { 458struct nouveau_pm_memtimings {
457 bool supported; 459 bool supported;
458 struct nouveau_pm_memtiming *timing; 460 struct nouveau_pm_memtiming *timing;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index ce3cb5eb33d0..2960f583dc38 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -704,6 +704,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
704 704
705 /* XXX: reg_100240? */ 705 /* XXX: reg_100240? */
706 } 706 }
707 timing->id = i;
707 708
708 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, 709 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
709 timing->reg_100220, timing->reg_100224, 710 timing->reg_100220, timing->reg_100224,
@@ -715,7 +716,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
715 } 716 }
716 717
717 memtimings->nr_timing = entries; 718 memtimings->nr_timing = entries;
718 memtimings->supported = true; 719 memtimings->supported = (dev_priv->chipset <= 0x98);
719} 720}
720 721
721void 722void
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
index 670e3cb697ec..5b87e68b00ae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
82 u8 version, headerlen, recordlen, entries; 82 u8 version, headerlen, recordlen, entries;
83 u8 *perf, *entry; 83 u8 *perf, *entry;
84 int vid, i; 84 int vid, i;
85 u8 ramcfg = (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x3c) >> 2;
85 86
86 if (bios->type == NVBIOS_BIT) { 87 if (bios->type == NVBIOS_BIT) {
87 if (bit_table(dev, 'P', &P)) 88 if (bit_table(dev, 'P', &P))
@@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
124 for (i = 0; i < entries; i++) { 125 for (i = 0; i < entries; i++) {
125 struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; 126 struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
126 127
128 perflvl->timing = NULL;
129
127 if (entry[0] == 0xff) { 130 if (entry[0] == 0xff) {
128 entry += recordlen; 131 entry += recordlen;
129 continue; 132 continue;
@@ -190,6 +193,22 @@ nouveau_perf_init(struct drm_device *dev)
190 } 193 }
191 } 194 }
192 195
196 /* get the corresponding memory timings */
197 if (pm->memtimings.supported) {
198 u8 timing_id = 0xff;
199 u16 extra_data;
200
201 if (version > 0x15 && version < 0x40 &&
202 ramcfg < perf[4]) {
203 extra_data = perf[3] + (ramcfg * perf[5]);
204 timing_id = entry[extra_data + 1];
205 }
206
207 if (pm->memtimings.nr_timing > timing_id)
208 perflvl->timing =
209 &pm->memtimings.timing[timing_id];
210 }
211
193 snprintf(perflvl->name, sizeof(perflvl->name), 212 snprintf(perflvl->name, sizeof(perflvl->name),
194 "performance_level_%d", i); 213 "performance_level_%d", i);
195 perflvl->id = i; 214 perflvl->id = i;
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index dc8a0cc8e5dc..da8d994d5e8a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
156static void 156static void
157nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) 157nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
158{ 158{
159 char c[16], s[16], v[16], f[16]; 159 char c[16], s[16], v[16], f[16], t[16];
160 160
161 c[0] = '\0'; 161 c[0] = '\0';
162 if (perflvl->core) 162 if (perflvl->core)
@@ -174,8 +174,12 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
174 if (perflvl->fanspeed) 174 if (perflvl->fanspeed)
175 snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); 175 snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
176 176
177 snprintf(ptr, len, "memory %dMHz%s%s%s%s\n", perflvl->memory / 1000, 177 t[0] = '\0';
178 c, s, v, f); 178 if (perflvl->timing)
179 snprintf(t, sizeof(t), " timing %d", perflvl->timing->id);
180
181 snprintf(ptr, len, "memory %dMHz%s%s%s%s%s\n", perflvl->memory / 1000,
182 c, s, v, f, t);
179} 183}
180 184
181static ssize_t 185static ssize_t
@@ -476,10 +480,10 @@ nouveau_pm_init(struct drm_device *dev)
476 char info[256]; 480 char info[256];
477 int ret, i; 481 int ret, i;
478 482
483 nouveau_mem_timing_init(dev);
479 nouveau_volt_init(dev); 484 nouveau_volt_init(dev);
480 nouveau_perf_init(dev); 485 nouveau_perf_init(dev);
481 nouveau_temp_init(dev); 486 nouveau_temp_init(dev);
482 nouveau_mem_timing_init(dev);
483 487
484 NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl); 488 NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl);
485 for (i = 0; i < pm->nr_perflvl; i++) { 489 for (i = 0; i < pm->nr_perflvl; i++) {
@@ -525,10 +529,10 @@ nouveau_pm_fini(struct drm_device *dev)
525 if (pm->cur != &pm->boot) 529 if (pm->cur != &pm->boot)
526 nouveau_pm_perflvl_set(dev, &pm->boot); 530 nouveau_pm_perflvl_set(dev, &pm->boot);
527 531
528 nouveau_mem_timing_fini(dev);
529 nouveau_temp_fini(dev); 532 nouveau_temp_fini(dev);
530 nouveau_perf_fini(dev); 533 nouveau_perf_fini(dev);
531 nouveau_volt_fini(dev); 534 nouveau_volt_fini(dev);
535 nouveau_mem_timing_fini(dev);
532 536
533#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) 537#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
534 unregister_acpi_notifier(&pm->acpi_nb); 538 unregister_acpi_notifier(&pm->acpi_nb);