diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 387 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_perf.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_pm.h | 1 |
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 f5700418da3f..a8344c321ab5 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 1cd29c02a7e9..33de77211639 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 ad990553d115..150ff415a172 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 a9a2e367f9d1..4f299f4df71c 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 2f8e14fbcff8..9e7ad33aa091 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 *); |