summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c387
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_perf.c23
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_pm.h1
5 files changed, 132 insertions, 298 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index f570041..a8344c3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -526,14 +526,6 @@ struct nouveau_pm_threshold_temp {
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 {
u32 percent;
u32 min_duty;
@@ -546,11 +538,11 @@ struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
int nr_perflvl;
- struct nouveau_pm_memtimings memtimings;
struct nouveau_pm_temp_sensor_constants sensor_constants;
struct nouveau_pm_threshold_temp threshold_temp;
struct nouveau_pm_fan fan;
+ struct nouveau_pm_memtiming boot_timing;
struct nouveau_pm_level boot;
struct nouveau_pm_level *cur;
@@ -922,6 +914,10 @@ extern int nouveau_mem_init_agp(struct drm_device *);
extern int nouveau_mem_reset_agp(struct drm_device *);
extern void nouveau_mem_close(struct drm_device *);
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 struct nouveau_tile_reg *nv10_mem_set_tiling(
struct drm_device *dev, uint32_t addr, uint32_t size,
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 1cd29c0..33de772 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -471,13 +471,12 @@ nouveau_mem_gart_init(struct drm_device *dev)
return 0;
}
-static void
-nv40_mem_timing_entry(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
-
t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
/* XXX: I don't trust the -1's and +1's... they must come
@@ -495,19 +494,23 @@ nv40_mem_timing_entry(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x\n", t->id,
t->reg[0], t->reg[1], t->reg[2]);
+ return 0;
}
-static void
-nv50_mem_timing_entry(struct drm_device *dev, struct bit_entry *P,
- struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct bit_entry P;
uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
- switch (min(hdr->entry_len, (u8) 22)) {
+ if (bit_table(dev, 'P', &P))
+ return -EINVAL;
+
+ switch (min(len, (u8) 22)) {
case 22:
unk21 = e->tUNK_21;
case 21:
@@ -537,7 +540,7 @@ nv50_mem_timing_entry(struct drm_device *dev, struct bit_entry *P,
t->reg[8] = boot->reg[8] & 0xffffff00;
- if (P->version == 1) {
+ if (P.version == 1) {
t->reg[1] |= (e->tCL + 2 - (t->tCWL - 1));
t->reg[3] = (0x14 + e->tCL) << 24 |
@@ -592,13 +595,14 @@ nv50_mem_timing_entry(struct drm_device *dev, struct bit_entry *P,
NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n",
t->reg[4], t->reg[5], t->reg[6], t->reg[7]);
NV_DEBUG(dev, " 240: %08x\n", t->reg[8]);
+ return 0;
}
-static void
-nvc0_mem_timing_entry(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nvc0_mem_timing_calc(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
if (e->tCWL > 0)
t->tCWL = e->tCWL;
@@ -625,20 +629,21 @@ nvc0_mem_timing_entry(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
NV_DEBUG(dev, "Entry %d: 290: %08x %08x %08x %08x\n", t->id,
t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
NV_DEBUG(dev, " 2a0: %08x\n", t->reg[4]);
+ return 0;
}
/**
* MR generation methods
*/
-static bool
-nouveau_mem_ddr2_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
t->drive_strength = 0;
- if (hdr->entry_len < 15) {
+ if (len < 15) {
t->odt = boot->odt;
} else {
t->odt = e->RAM_FT1 & 0x07;
@@ -646,12 +651,12 @@ nouveau_mem_ddr2_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
if (e->tCL >= NV_MEM_CL_DDR2_MAX) {
NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
- return false;
+ return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_DDR2_MAX) {
NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
- return false;
+ return -ERANGE;
}
if (t->odt > 3) {
@@ -668,22 +673,22 @@ nouveau_mem_ddr2_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
(t->odt & 0x2) << 5;
NV_DEBUG(dev, "(%u) MR: %08x", t->id, t->mr[0]);
- return true;
+ return 0;
}
uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = {
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
-static bool
-nouveau_mem_ddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
u8 cl = e->tCL - 4;
t->drive_strength = 0;
- if (hdr->entry_len < 15) {
+ if (len < 15) {
t->odt = boot->odt;
} else {
t->odt = e->RAM_FT1 & 0x07;
@@ -691,17 +696,17 @@ nouveau_mem_ddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) {
NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
- return false;
+ return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) {
NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
- return false;
+ return -ERANGE;
}
if (e->tCWL < 5) {
NV_WARN(dev, "(%u) Invalid tCWL: %u", t->id, e->tCWL);
- return false;
+ return -ERANGE;
}
t->mr[0] = (boot->mr[0] & 0x180b) |
@@ -716,7 +721,7 @@ nouveau_mem_ddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3;
NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]);
- return true;
+ return 0;
}
uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
@@ -724,13 +729,13 @@ uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = {
0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3};
-static bool
-nouveau_mem_gddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
- if (hdr->entry_len < 15) {
+ if (len < 15) {
t->drive_strength = boot->drive_strength;
t->odt = boot->odt;
} else {
@@ -740,12 +745,12 @@ nouveau_mem_gddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
if (e->tCL >= NV_MEM_CL_GDDR3_MAX) {
NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
- return false;
+ return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_GDDR3_MAX) {
NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
- return false;
+ return -ERANGE;
}
if (t->odt > 3) {
@@ -763,16 +768,16 @@ nouveau_mem_gddr3_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
(nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4;
NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
- return true;
+ return 0;
}
-static bool
-nouveau_mem_gddr5_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
- struct nouveau_pm_tbl_entry *e,
- struct nouveau_pm_memtiming *t,
- struct nouveau_pm_memtiming *boot)
+static int
+nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
+ struct nouveau_pm_tbl_entry *e, u8 len,
+ struct nouveau_pm_memtiming *boot,
+ struct nouveau_pm_memtiming *t)
{
- if (hdr->entry_len < 15) {
+ if (len < 15) {
t->drive_strength = boot->drive_strength;
t->odt = boot->odt;
} else {
@@ -782,12 +787,12 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
if (e->tCL >= NV_MEM_CL_GDDR5_MAX) {
NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
- return false;
+ return -ERANGE;
}
if (e->tWR >= NV_MEM_WR_GDDR5_MAX) {
NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
- return false;
+ return -ERANGE;
}
if (t->odt > 3) {
@@ -804,12 +809,70 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
(t->odt << 2);
NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
- return true;
+ return 0;
}
-static void
-nouveau_mem_copy_current_timings(struct drm_device *dev,
- struct nouveau_pm_memtiming *t)
+struct nouveau_pm_memtiming *
+nouveau_mem_timing(struct drm_device *dev, u32 freq)
+{
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+ struct nouveau_pm_memtiming *boot = &pm->boot_timing;
+ struct nouveau_pm_memtiming *t;
+ struct nouveau_pm_tbl_entry *e;
+ u8 ver, len, *ptr;
+ int ret;
+
+ ptr = nouveau_perf_timing(dev, freq, &ver, &len);
+ if (!ptr || ptr[0] == 0x00)
+ return boot;
+ e = (struct nouveau_pm_tbl_entry *)ptr;
+
+ t = kzalloc(sizeof(*t), GFP_KERNEL);
+ 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) {
+ case NV_MEM_TYPE_GDDR3:
+ 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;
+ }
+
+ if (ret) {
+ kfree(t);
+ t = NULL;
+ }
+ }
+
+ return t;
+}
+
+void
+nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
u32 timing_base, timing_regs, mr_base;
@@ -874,212 +937,6 @@ nouveau_mem_copy_current_timings(struct drm_device *dev,
}
}
-static bool
-nouveau_mem_compare_timings(struct drm_device *dev,
- struct nouveau_pm_memtiming *t1,
- struct nouveau_pm_memtiming *t2)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
-
- switch (dev_priv->card_type) {
- case 0x50:
- if (t1->reg[8] != t2->reg[8] ||
- t1->reg[7] != t2->reg[7] ||
- t1->reg[6] != t2->reg[6] ||
- t1->reg[5] != t2->reg[5])
- return false;
- case 0xC0:
- if (t1->reg[4] != t2->reg[4] ||
- t1->reg[3] != t2->reg[3])
- return false;
- case 0x40:
- if (t1->reg[2] != t2->reg[2] ||
- t1->reg[1] != t2->reg[1] ||
- t1->reg[0] != t2->reg[0])
- return false;
- break;
- default:
- return false;
- }
-
- /* RSpliet: may generate many false negatives */
- switch (dev_priv->vram_type) {
- case NV_MEM_TYPE_GDDR3:
- case NV_MEM_TYPE_GDDR5:
- if (t1->mr[0] == t2->mr[0] ||
- t1->mr[1] != t2->mr[1])
- return true;
- break;
- case NV_MEM_TYPE_DDR3:
- if (t1->mr[2] == t2->mr[2])
- return true;
- case NV_MEM_TYPE_DDR2:
- if (t1->mr[0] == t2->mr[0])
- return true;
- break;
- default:
- return false;
- }
-
- return false;
-}
-
-/**
- * Processes the Memory Timing BIOS table, stores generated
- * register values
- * @pre init scripts were run, memtiming regs are initialized
- */
-void
-nouveau_mem_timing_init(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
- struct nouveau_pm_memtimings *memtimings = &pm->memtimings;
- struct nvbios *bios = &dev_priv->vbios;
- struct bit_entry P;
- struct nouveau_pm_tbl_header *hdr = NULL;
- bool valid_generation = false;
- u8 *entry;
- int i;
-
- memtimings->nr_timing = 0;
- memtimings->nr_timing_valid = 0;
- memtimings->supported = 0;
-
- if (dev_priv->card_type < NV_40) {
- NV_ERROR(dev, "Timing entry format unknown for card_type %x. "
- "please contact nouveau developers",
- dev_priv->card_type);
- return;
- }
-
- /* Copy the current timings */
- nouveau_mem_copy_current_timings(dev, &memtimings->boot);
-
- if (bios->type == NVBIOS_BIT) {
- if (bit_table(dev, 'P', &P))
- return;
-
- if (P.version == 1)
- hdr = (struct nouveau_pm_tbl_header *) ROMPTR(dev,
- P.data[4]);
- else if (P.version == 2)
- hdr = (struct nouveau_pm_tbl_header *) ROMPTR(dev,
- P.data[8]);
- else
- NV_WARN(dev, "unknown mem for BIT P %d\n", P.version);
- } else {
- NV_DEBUG(dev, "BMP version too old for memory\n");
- return;
- }
-
- if (!hdr) {
- NV_DEBUG(dev, "memory timing table pointer invalid\n");
- return;
- }
-
- if (hdr->version != 0x10) {
- NV_WARN(dev, "memory timing table 0x%02x unknown\n",
- hdr->version);
- return;
- }
-
- /* validate record length */
- if (hdr->entry_len < 15) {
- NV_ERROR(dev, "mem timing table length unknown: %d\n",
- hdr->entry_len);
- return;
- }
-
- /* parse vbios entries into common format */
- memtimings->timing = kcalloc(hdr->entry_cnt,
- sizeof(*memtimings->timing), GFP_KERNEL);
- if (!memtimings->timing)
- return;
-
- entry = (u8 *) hdr + hdr->header_len;
- for (i = 0; i < hdr->entry_cnt; i++, entry += hdr->entry_len) {
- struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
- struct nouveau_pm_tbl_entry *entry_struct =
- (struct nouveau_pm_tbl_entry *) entry;
- if (entry[0] == 0)
- continue;
- memtimings->nr_timing_valid++;
-
- timing->id = i;
- timing->tCWL = memtimings->boot.tCWL;
-
- /* generate the timngs */
- if (dev_priv->card_type == NV_40) {
- nv40_mem_timing_entry(dev, hdr, entry_struct,
- &pm->memtimings.timing[i],
- &memtimings->boot);
- } else if (dev_priv->card_type == NV_50) {
- nv50_mem_timing_entry(dev, &P, hdr, entry_struct,
- &pm->memtimings.timing[i],
- &memtimings->boot);
- } else if (dev_priv->card_type == NV_C0) {
- nvc0_mem_timing_entry(dev, hdr, entry_struct,
- &pm->memtimings.timing[i],
- &memtimings->boot);
- }
-
- /* generate the MR/EMR/... */
- switch (dev_priv->vram_type) {
- case NV_MEM_TYPE_GDDR3:
- nouveau_mem_gddr3_mr(dev, hdr, entry_struct, timing,
- &memtimings->boot);
- break;
- case NV_MEM_TYPE_GDDR5:
- nouveau_mem_gddr5_mr(dev, hdr, entry_struct, timing,
- &memtimings->boot);
- break;
- case NV_MEM_TYPE_DDR2:
- nouveau_mem_ddr2_mr(dev, hdr, entry_struct, timing,
- &memtimings->boot);
- break;
- case NV_MEM_TYPE_DDR3:
- nouveau_mem_ddr3_mr(dev, hdr, entry_struct, timing,
- &memtimings->boot);
- break;
- default:
- valid_generation = false;
- break;
- }
-
- /* some kind of validation */
- if (nouveau_mem_compare_timings(dev, timing,
- &memtimings->boot)) {
- NV_DEBUG(dev, "Copy boot timings from entry %d\n",
- timing->id);
- memtimings->boot = *timing;
- valid_generation = true;
- }
- }
-
- memtimings->nr_timing = hdr->entry_cnt;
- memtimings->supported = (P.version == 1) && valid_generation;
-
- /* if there are no timing entries that cannot
- * re-generate the current timings
- */
- if (memtimings->nr_timing_valid > 0 && !valid_generation) {
- NV_INFO(dev,
- "Memory timings management may not be working."
- " please report to nouveau devs\n");
- }
-}
-
-void
-nouveau_mem_timing_fini(struct drm_device *dev)
-{
- struct drm_nouveau_private *dev_priv = dev->dev_private;
- struct nouveau_pm_memtimings *mem = &dev_priv->engine.pm.memtimings;
-
- kfree(mem->timing);
- mem->timing = NULL;
-}
-
int
nouveau_mem_vbios_type(struct drm_device *dev)
{
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c
index ad99055..150ff41 100644
--- a/drivers/gpu/drm/nouveau/nouveau_perf.c
+++ b/drivers/gpu/drm/nouveau/nouveau_perf.c
@@ -89,7 +89,7 @@ nouveau_perf_rammap(struct drm_device *dev, u32 freq,
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct bit_entry P;
- u8 *perf, i;
+ u8 *perf, i = 0;
if (!bit_table(dev, 'P', &P) && P.version == 2) {
u8 *rammap = ROMPTR(dev, P.data[4]);
@@ -158,7 +158,7 @@ nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
return NULL;
}
-static u8 *
+u8 *
nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -384,24 +384,7 @@ nouveau_perf_init(struct drm_device *dev)
}
/* get the corresponding memory timings */
-#if 0
- 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
+ perflvl->timing = nouveau_mem_timing(dev, perflvl->memory);
snprintf(perflvl->name, sizeof(perflvl->name),
"performance_level_%d", i);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c
index a9a2e36..4f299f4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.c
@@ -238,6 +238,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
if (ret > 0)
perflvl->fanspeed = ret;
+ nouveau_mem_timing_read(dev, &perflvl->timing);
return 0;
}
@@ -793,8 +794,6 @@ nouveau_pm_init(struct drm_device *dev)
char info[256];
int ret, i;
- nouveau_mem_timing_init(dev);
-
/* parse aux tables from vbios */
nouveau_volt_init(dev);
nouveau_temp_init(dev);
@@ -807,7 +806,6 @@ nouveau_pm_init(struct drm_device *dev)
}
strncpy(pm->boot.name, "boot", 4);
- pm->boot.timing = &pm->memtimings.boot;
pm->cur = &pm->boot;
/* add performance levels from vbios */
@@ -857,7 +855,6 @@ nouveau_pm_fini(struct drm_device *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);
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h
index 2f8e14f..9e7ad33 100644
--- a/drivers/gpu/drm/nouveau/nouveau_pm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_pm.h
@@ -41,6 +41,7 @@ int nouveau_voltage_gpio_set(struct drm_device *, int voltage);
/* nouveau_perf.c */
void nouveau_perf_init(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 */
void nouveau_mem_timing_init(struct drm_device *);