Commit 085028ce authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/pm: embed timings into perflvl structs

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Signed-off-by: default avatarMartin Peres <martin.peres@labri.fr>
parent fd99fd61
...@@ -491,8 +491,11 @@ struct nouveau_pm_level { ...@@ -491,8 +491,11 @@ struct nouveau_pm_level {
char name[32]; char name[32];
int id; int id;
u32 core;
u32 memory; u32 memory;
u16 memscript;
struct nouveau_pm_memtiming timing;
u32 core;
u32 shader; u32 shader;
u32 rop; u32 rop;
u32 copy; u32 copy;
...@@ -507,9 +510,6 @@ struct nouveau_pm_level { ...@@ -507,9 +510,6 @@ struct nouveau_pm_level {
u32 volt_min; /* microvolts */ u32 volt_min; /* microvolts */
u32 volt_max; u32 volt_max;
u8 fanspeed; u8 fanspeed;
u16 memscript;
struct nouveau_pm_memtiming *timing;
}; };
struct nouveau_pm_temp_sensor_constants { struct nouveau_pm_temp_sensor_constants {
...@@ -542,7 +542,6 @@ struct nouveau_pm_engine { ...@@ -542,7 +542,6 @@ struct nouveau_pm_engine {
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;
...@@ -914,10 +913,10 @@ extern int nouveau_mem_init_agp(struct drm_device *); ...@@ -914,10 +913,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 int nouveau_mem_timing_calc(struct drm_device *, u32 freq,
struct nouveau_pm_memtiming *);
extern void nouveau_mem_timing_read(struct drm_device *, extern void nouveau_mem_timing_read(struct drm_device *,
struct nouveau_pm_memtiming *); 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,
......
...@@ -812,63 +812,59 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq, ...@@ -812,63 +812,59 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
return 0; return 0;
} }
struct nouveau_pm_memtiming * int
nouveau_mem_timing(struct drm_device *dev, u32 freq) nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
struct nouveau_pm_memtiming *t)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct nouveau_pm_memtiming *boot = &pm->boot_timing; struct nouveau_pm_memtiming *boot = &pm->boot.timing;
struct nouveau_pm_memtiming *t;
struct nouveau_pm_tbl_entry *e; struct nouveau_pm_tbl_entry *e;
u8 ver, len, *ptr; u8 ver, len, *ptr;
int ret; int ret;
ptr = nouveau_perf_timing(dev, freq, &ver, &len); ptr = nouveau_perf_timing(dev, freq, &ver, &len);
if (!ptr || ptr[0] == 0x00) if (!ptr || ptr[0] == 0x00) {
return boot; *t = *boot;
return 0;
}
e = (struct nouveau_pm_tbl_entry *)ptr; e = (struct nouveau_pm_tbl_entry *)ptr;
t = kzalloc(sizeof(*t), GFP_KERNEL); t->tCWL = boot->tCWL;
if (t) {
t->tCWL = boot->tCWL;
switch (dev_priv->card_type) {
case NV_40:
ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
break;
case NV_50:
ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
break;
case NV_C0:
ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
break;
default:
ret = -ENODEV;
break;
}
switch (dev_priv->vram_type * !ret) { switch (dev_priv->card_type) {
case NV_MEM_TYPE_GDDR3: case NV_40:
ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
break; break;
case NV_MEM_TYPE_GDDR5: case NV_50:
ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t); ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
break; break;
case NV_MEM_TYPE_DDR2: case NV_C0:
ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t); ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
break; break;
case NV_MEM_TYPE_DDR3: default:
ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t); ret = -ENODEV;
break; break;
} }
if (ret) { switch (dev_priv->vram_type * !ret) {
kfree(t); case NV_MEM_TYPE_GDDR3:
t = NULL; ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
} break;
case NV_MEM_TYPE_GDDR5:
ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t);
break;
case NV_MEM_TYPE_DDR2:
ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t);
break;
case NV_MEM_TYPE_DDR3:
ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t);
break;
default:
ret = -EINVAL;
} }
return t; return ret;
} }
void void
......
...@@ -293,7 +293,7 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -293,7 +293,7 @@ nouveau_perf_init(struct drm_device *dev)
struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct nvbios *bios = &dev_priv->vbios; struct nvbios *bios = &dev_priv->vbios;
u8 *perf, ver, hdr, cnt, len; u8 *perf, ver, hdr, cnt, len;
int vid, i = -1; int ret, vid, i = -1;
if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) { if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) {
legacy_perf_init(dev); legacy_perf_init(dev);
...@@ -384,7 +384,12 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -384,7 +384,12 @@ nouveau_perf_init(struct drm_device *dev)
} }
/* get the corresponding memory timings */ /* get the corresponding memory timings */
perflvl->timing = nouveau_mem_timing(dev, perflvl->memory); ret = nouveau_mem_timing_calc(dev, perflvl->memory,
&perflvl->timing);
if (ret) {
NV_DEBUG(dev, "perflvl %d, bad timing: %d\n", i, ret);
continue;
}
snprintf(perflvl->name, sizeof(perflvl->name), snprintf(perflvl->name, sizeof(perflvl->name),
"performance_level_%d", i); "performance_level_%d", i);
......
...@@ -245,7 +245,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) ...@@ -245,7 +245,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
static void static void
nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
{ {
char c[16], s[16], v[32], f[16], t[16], m[16]; char c[16], s[16], v[32], f[16], m[16];
c[0] = '\0'; c[0] = '\0';
if (perflvl->core) if (perflvl->core)
...@@ -273,11 +273,7 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) ...@@ -273,11 +273,7 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
if (perflvl->fanspeed) if (perflvl->fanspeed)
snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
t[0] = '\0'; snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m, v, f);
if (perflvl->timing)
snprintf(t, sizeof(t), " timing %d", perflvl->timing->id);
snprintf(ptr, len, "%s%s%s%s%s%s\n", c, s, m, t, v, f);
} }
static ssize_t static ssize_t
......
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