mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 01:54:09 +08:00
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>
This commit is contained in:
parent
dac55b5825
commit
e614b2e7ca
@ -410,6 +410,19 @@ struct nouveau_pm_voltage {
|
||||
int nr_level;
|
||||
};
|
||||
|
||||
struct nouveau_pm_memtiming {
|
||||
int id;
|
||||
u32 reg_100220;
|
||||
u32 reg_100224;
|
||||
u32 reg_100228;
|
||||
u32 reg_10022c;
|
||||
u32 reg_100230;
|
||||
u32 reg_100234;
|
||||
u32 reg_100238;
|
||||
u32 reg_10023c;
|
||||
u32 reg_100240;
|
||||
};
|
||||
|
||||
#define NOUVEAU_PM_MAX_LEVEL 8
|
||||
struct nouveau_pm_level {
|
||||
struct device_attribute dev_attr;
|
||||
@ -425,6 +438,7 @@ struct nouveau_pm_level {
|
||||
u8 fanspeed;
|
||||
|
||||
u16 memscript;
|
||||
struct nouveau_pm_memtiming *timing;
|
||||
};
|
||||
|
||||
struct nouveau_pm_temp_sensor_constants {
|
||||
@ -441,18 +455,6 @@ struct nouveau_pm_threshold_temp {
|
||||
s16 fan_boost;
|
||||
};
|
||||
|
||||
struct nouveau_pm_memtiming {
|
||||
u32 reg_100220;
|
||||
u32 reg_100224;
|
||||
u32 reg_100228;
|
||||
u32 reg_10022c;
|
||||
u32 reg_100230;
|
||||
u32 reg_100234;
|
||||
u32 reg_100238;
|
||||
u32 reg_10023c;
|
||||
u32 reg_100240;
|
||||
};
|
||||
|
||||
struct nouveau_pm_memtimings {
|
||||
bool supported;
|
||||
struct nouveau_pm_memtiming *timing;
|
||||
|
@ -704,6 +704,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
|
||||
/* XXX: reg_100240? */
|
||||
}
|
||||
timing->id = i;
|
||||
|
||||
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
||||
timing->reg_100220, timing->reg_100224,
|
||||
@ -715,7 +716,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
}
|
||||
|
||||
memtimings->nr_timing = entries;
|
||||
memtimings->supported = true;
|
||||
memtimings->supported = (dev_priv->chipset <= 0x98);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -82,6 +82,7 @@ nouveau_perf_init(struct drm_device *dev)
|
||||
u8 version, headerlen, recordlen, entries;
|
||||
u8 *perf, *entry;
|
||||
int vid, i;
|
||||
u8 ramcfg = (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x3c) >> 2;
|
||||
|
||||
if (bios->type == NVBIOS_BIT) {
|
||||
if (bit_table(dev, 'P', &P))
|
||||
@ -124,6 +125,8 @@ nouveau_perf_init(struct drm_device *dev)
|
||||
for (i = 0; i < entries; i++) {
|
||||
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
|
||||
|
||||
perflvl->timing = NULL;
|
||||
|
||||
if (entry[0] == 0xff) {
|
||||
entry += recordlen;
|
||||
continue;
|
||||
@ -190,6 +193,22 @@ nouveau_perf_init(struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* get the corresponding memory timings */
|
||||
if (pm->memtimings.supported) {
|
||||
u8 timing_id = 0xff;
|
||||
u16 extra_data;
|
||||
|
||||
if (version > 0x15 && version < 0x40 &&
|
||||
ramcfg < perf[4]) {
|
||||
extra_data = perf[3] + (ramcfg * perf[5]);
|
||||
timing_id = entry[extra_data + 1];
|
||||
}
|
||||
|
||||
if (pm->memtimings.nr_timing > timing_id)
|
||||
perflvl->timing =
|
||||
&pm->memtimings.timing[timing_id];
|
||||
}
|
||||
|
||||
snprintf(perflvl->name, sizeof(perflvl->name),
|
||||
"performance_level_%d", i);
|
||||
perflvl->id = i;
|
||||
|
@ -156,7 +156,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
|
||||
static void
|
||||
nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
|
||||
{
|
||||
char c[16], s[16], v[16], f[16];
|
||||
char c[16], s[16], v[16], f[16], t[16];
|
||||
|
||||
c[0] = '\0';
|
||||
if (perflvl->core)
|
||||
@ -174,8 +174,12 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
|
||||
if (perflvl->fanspeed)
|
||||
snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
|
||||
|
||||
snprintf(ptr, len, "memory %dMHz%s%s%s%s\n", perflvl->memory / 1000,
|
||||
c, s, v, f);
|
||||
t[0] = '\0';
|
||||
if (perflvl->timing)
|
||||
snprintf(t, sizeof(t), " timing %d", perflvl->timing->id);
|
||||
|
||||
snprintf(ptr, len, "memory %dMHz%s%s%s%s%s\n", perflvl->memory / 1000,
|
||||
c, s, v, f, t);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@ -476,10 +480,10 @@ nouveau_pm_init(struct drm_device *dev)
|
||||
char info[256];
|
||||
int ret, i;
|
||||
|
||||
nouveau_mem_timing_init(dev);
|
||||
nouveau_volt_init(dev);
|
||||
nouveau_perf_init(dev);
|
||||
nouveau_temp_init(dev);
|
||||
nouveau_mem_timing_init(dev);
|
||||
|
||||
NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl);
|
||||
for (i = 0; i < pm->nr_perflvl; i++) {
|
||||
@ -525,10 +529,10 @@ nouveau_pm_fini(struct drm_device *dev)
|
||||
if (pm->cur != &pm->boot)
|
||||
nouveau_pm_perflvl_set(dev, &pm->boot);
|
||||
|
||||
nouveau_mem_timing_fini(dev);
|
||||
nouveau_temp_fini(dev);
|
||||
nouveau_perf_fini(dev);
|
||||
nouveau_volt_fini(dev);
|
||||
nouveau_mem_timing_fini(dev);
|
||||
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
|
||||
unregister_acpi_notifier(&pm->acpi_nb);
|
||||
|
Loading…
Reference in New Issue
Block a user