Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e614b2e7 authored by Martin Peres's avatar Martin Peres Committed by Ben Skeggs
Browse files

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: default avatarMartin Peres <martin.peres@ensi-bourges.fr>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent dac55b58
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -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;
+2 −1
Original line number Diff line number Diff line
@@ -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
+19 −0
Original line number Diff line number Diff line
@@ -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;
+9 −5
Original line number Diff line number Diff line
@@ -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);