Commit fd99fd61 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/pm: calculate memory timings at perflvl creation time

Statically generating the PFB register and MR values for each timing set
turns out to be insufficient.  There's at least one (so far) known piece
of information which effects MR values which is stored in the perflvl
entry on some chipsets (and in another table on later ones), which is
disconnected from the timing table entries.

After this change we will generate a timing set based on an input clock
frequency instead, and have this data stored in the performance level
data.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Signed-off-by: default avatarMartin Peres <martin.peres@labri.fr>
parent 68a64cad
...@@ -526,14 +526,6 @@ struct nouveau_pm_threshold_temp { ...@@ -526,14 +526,6 @@ struct nouveau_pm_threshold_temp {
s16 fan_boost; s16 fan_boost;
}; };
struct nouveau_pm_memtimings {
bool supported;
struct nouveau_pm_memtiming boot;
struct nouveau_pm_memtiming *timing;
int nr_timing;
int nr_timing_valid;
};
struct nouveau_pm_fan { struct nouveau_pm_fan {
u32 percent; u32 percent;
u32 min_duty; u32 min_duty;
...@@ -546,11 +538,11 @@ struct nouveau_pm_engine { ...@@ -546,11 +538,11 @@ struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage; struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL]; struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
int nr_perflvl; int nr_perflvl;
struct nouveau_pm_memtimings memtimings;
struct nouveau_pm_temp_sensor_constants sensor_constants; struct nouveau_pm_temp_sensor_constants sensor_constants;
struct nouveau_pm_threshold_temp threshold_temp; struct nouveau_pm_threshold_temp threshold_temp;
struct nouveau_pm_fan fan; struct nouveau_pm_fan fan;
struct nouveau_pm_memtiming boot_timing;
struct nouveau_pm_level boot; struct nouveau_pm_level boot;
struct nouveau_pm_level *cur; struct nouveau_pm_level *cur;
...@@ -922,6 +914,10 @@ extern int nouveau_mem_init_agp(struct drm_device *); ...@@ -922,6 +914,10 @@ extern int nouveau_mem_init_agp(struct drm_device *);
extern int nouveau_mem_reset_agp(struct drm_device *); extern int nouveau_mem_reset_agp(struct drm_device *);
extern void nouveau_mem_close(struct drm_device *); extern void nouveau_mem_close(struct drm_device *);
extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags); extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags);
extern void nouveau_mem_timing_read(struct drm_device *,
struct nouveau_pm_memtiming *);
extern struct nouveau_pm_memtiming *
nouveau_mem_timing(struct drm_device *, u32 freq);
extern int nouveau_mem_vbios_type(struct drm_device *); extern int nouveau_mem_vbios_type(struct drm_device *);
extern struct nouveau_tile_reg *nv10_mem_set_tiling( extern struct nouveau_tile_reg *nv10_mem_set_tiling(
struct drm_device *dev, uint32_t addr, uint32_t size, struct drm_device *dev, uint32_t addr, uint32_t size,
......
This diff is collapsed.
...@@ -89,7 +89,7 @@ nouveau_perf_rammap(struct drm_device *dev, u32 freq, ...@@ -89,7 +89,7 @@ nouveau_perf_rammap(struct drm_device *dev, u32 freq,
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct bit_entry P; struct bit_entry P;
u8 *perf, i; u8 *perf, i = 0;
if (!bit_table(dev, 'P', &P) && P.version == 2) { if (!bit_table(dev, 'P', &P) && P.version == 2) {
u8 *rammap = ROMPTR(dev, P.data[4]); u8 *rammap = ROMPTR(dev, P.data[4]);
...@@ -158,7 +158,7 @@ nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) ...@@ -158,7 +158,7 @@ nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
return NULL; return NULL;
} }
static u8 * u8 *
nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
...@@ -384,24 +384,7 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -384,24 +384,7 @@ nouveau_perf_init(struct drm_device *dev)
} }
/* get the corresponding memory timings */ /* get the corresponding memory timings */
#if 0 perflvl->timing = nouveau_mem_timing(dev, perflvl->memory);
if (version == 0x15) {
memtimings->timing[i].id = i;
nv30_mem_timing_entry(dev, &mt_hdr,
(struct nouveau_pm_tbl_entry *) &entry[41],
0, &memtimings->timing[i]);
perflvl->timing = &memtimings->timing[i];
} else if (version > 0x15) {
/* last 3 args are for < 0x40, ignored for >= 0x40 */
perflvl->timing =
nouveau_perf_timing(dev, &P,
perflvl->memory / 1000,
entry + perf[3],
perf[5], perf[4]);
}
#else
perflvl->timing = NULL;
#endif
snprintf(perflvl->name, sizeof(perflvl->name), snprintf(perflvl->name, sizeof(perflvl->name),
"performance_level_%d", i); "performance_level_%d", i);
......
...@@ -238,6 +238,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) ...@@ -238,6 +238,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
if (ret > 0) if (ret > 0)
perflvl->fanspeed = ret; perflvl->fanspeed = ret;
nouveau_mem_timing_read(dev, &perflvl->timing);
return 0; return 0;
} }
...@@ -793,8 +794,6 @@ nouveau_pm_init(struct drm_device *dev) ...@@ -793,8 +794,6 @@ nouveau_pm_init(struct drm_device *dev)
char info[256]; char info[256];
int ret, i; int ret, i;
nouveau_mem_timing_init(dev);
/* parse aux tables from vbios */ /* parse aux tables from vbios */
nouveau_volt_init(dev); nouveau_volt_init(dev);
nouveau_temp_init(dev); nouveau_temp_init(dev);
...@@ -807,7 +806,6 @@ nouveau_pm_init(struct drm_device *dev) ...@@ -807,7 +806,6 @@ nouveau_pm_init(struct drm_device *dev)
} }
strncpy(pm->boot.name, "boot", 4); strncpy(pm->boot.name, "boot", 4);
pm->boot.timing = &pm->memtimings.boot;
pm->cur = &pm->boot; pm->cur = &pm->boot;
/* add performance levels from vbios */ /* add performance levels from vbios */
...@@ -857,7 +855,6 @@ nouveau_pm_fini(struct drm_device *dev) ...@@ -857,7 +855,6 @@ nouveau_pm_fini(struct drm_device *dev)
nouveau_temp_fini(dev); nouveau_temp_fini(dev);
nouveau_perf_fini(dev); nouveau_perf_fini(dev);
nouveau_volt_fini(dev); nouveau_volt_fini(dev);
nouveau_mem_timing_fini(dev);
#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) #if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
unregister_acpi_notifier(&pm->acpi_nb); unregister_acpi_notifier(&pm->acpi_nb);
......
...@@ -41,6 +41,7 @@ int nouveau_voltage_gpio_set(struct drm_device *, int voltage); ...@@ -41,6 +41,7 @@ int nouveau_voltage_gpio_set(struct drm_device *, int voltage);
/* nouveau_perf.c */ /* nouveau_perf.c */
void nouveau_perf_init(struct drm_device *); void nouveau_perf_init(struct drm_device *);
void nouveau_perf_fini(struct drm_device *); void nouveau_perf_fini(struct drm_device *);
u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len);
/* nouveau_mem.c */ /* nouveau_mem.c */
void nouveau_mem_timing_init(struct drm_device *); void nouveau_mem_timing_init(struct drm_device *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment