]> Pileus Git - ~andy/linux/blob - drivers/gpu/drm/nouveau/nouveau_mem.c
drm/nouveau: port all engines to new engine module format
[~andy/linux] / drivers / gpu / drm / nouveau / nouveau_mem.c
1 /*
2  * Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3  * Copyright 2005 Stephane Marchesin
4  *
5  * The Weather Channel (TM) funded Tungsten Graphics to develop the
6  * initial release of the Radeon 8500 driver under the XFree86 license.
7  * This notice must be preserved.
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a
10  * copy of this software and associated documentation files (the "Software"),
11  * to deal in the Software without restriction, including without limitation
12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  * and/or sell copies of the Software, and to permit persons to whom the
14  * Software is furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice (including the next
17  * paragraph) shall be included in all copies or substantial portions of the
18  * Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * THE AUTHORS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  *
28  * Authors:
29  *    Ben Skeggs <bskeggs@redhat.com>
30  *    Roy Spliet <r.spliet@student.tudelft.nl>
31  */
32
33
34 #include "drmP.h"
35 #include "drm.h"
36 #include "drm_sarea.h"
37
38 #include "nouveau_drv.h"
39 #include "nouveau_pm.h"
40
41 static int
42 nv40_mem_timing_calc(struct drm_device *dev, u32 freq,
43                      struct nouveau_pm_tbl_entry *e, u8 len,
44                      struct nouveau_pm_memtiming *boot,
45                      struct nouveau_pm_memtiming *t)
46 {
47         t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
48
49         /* XXX: I don't trust the -1's and +1's... they must come
50          *      from somewhere! */
51         t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 |
52                     1 << 16 |
53                     (e->tWTR + 2 + (t->tCWL - 1)) << 8 |
54                     (e->tCL + 2 - (t->tCWL - 1));
55
56         t->reg[2] = 0x20200000 |
57                     ((t->tCWL - 1) << 24 |
58                      e->tRRD << 16 |
59                      e->tRCDWR << 8 |
60                      e->tRCDRD);
61
62         NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x\n", t->id,
63                  t->reg[0], t->reg[1], t->reg[2]);
64         return 0;
65 }
66
67 static int
68 nv50_mem_timing_calc(struct drm_device *dev, u32 freq,
69                      struct nouveau_pm_tbl_entry *e, u8 len,
70                      struct nouveau_pm_memtiming *boot,
71                      struct nouveau_pm_memtiming *t)
72 {
73         struct bit_entry P;
74         uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3;
75
76         if (bit_table(dev, 'P', &P))
77                 return -EINVAL;
78
79         switch (min(len, (u8) 22)) {
80         case 22:
81                 unk21 = e->tUNK_21;
82         case 21:
83                 unk20 = e->tUNK_20;
84         case 20:
85                 if (e->tCWL > 0)
86                         t->tCWL = e->tCWL;
87         case 19:
88                 unk18 = e->tUNK_18;
89                 break;
90         }
91
92         t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC);
93
94         t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 |
95                                 max(unk18, (u8) 1) << 16 |
96                                 (e->tWTR + 2 + (t->tCWL - 1)) << 8;
97
98         t->reg[2] = ((t->tCWL - 1) << 24 |
99                     e->tRRD << 16 |
100                     e->tRCDWR << 8 |
101                     e->tRCDRD);
102
103         t->reg[4] = e->tUNK_13 << 8  | e->tUNK_13;
104
105         t->reg[5] = (e->tRFC << 24 | max(e->tRCDRD, e->tRCDWR) << 16 | e->tRP);
106
107         t->reg[8] = boot->reg[8] & 0xffffff00;
108
109         if (P.version == 1) {
110                 t->reg[1] |= (e->tCL + 2 - (t->tCWL - 1));
111
112                 t->reg[3] = (0x14 + e->tCL) << 24 |
113                             0x16 << 16 |
114                             (e->tCL - 1) << 8 |
115                             (e->tCL - 1);
116
117                 t->reg[4] |= boot->reg[4] & 0xffff0000;
118
119                 t->reg[6] = (0x33 - t->tCWL) << 16 |
120                             t->tCWL << 8 |
121                             (0x2e + e->tCL - t->tCWL);
122
123                 t->reg[7] = 0x4000202 | (e->tCL - 1) << 16;
124
125                 /* XXX: P.version == 1 only has DDR2 and GDDR3? */
126                 if (nvfb_vram_type(dev) == NV_MEM_TYPE_DDR2) {
127                         t->reg[5] |= (e->tCL + 3) << 8;
128                         t->reg[6] |= (t->tCWL - 2) << 8;
129                         t->reg[8] |= (e->tCL - 4);
130                 } else {
131                         t->reg[5] |= (e->tCL + 2) << 8;
132                         t->reg[6] |= t->tCWL << 8;
133                         t->reg[8] |= (e->tCL - 2);
134                 }
135         } else {
136                 t->reg[1] |= (5 + e->tCL - (t->tCWL));
137
138                 /* XXX: 0xb? 0x30? */
139                 t->reg[3] = (0x30 + e->tCL) << 24 |
140                             (boot->reg[3] & 0x00ff0000)|
141                             (0xb + e->tCL) << 8 |
142                             (e->tCL - 1);
143
144                 t->reg[4] |= (unk20 << 24 | unk21 << 16);
145
146                 /* XXX: +6? */
147                 t->reg[5] |= (t->tCWL + 6) << 8;
148
149                 t->reg[6] = (0x5a + e->tCL) << 16 |
150                             (6 - e->tCL + t->tCWL) << 8 |
151                             (0x50 + e->tCL - t->tCWL);
152
153                 tmp7_3 = (boot->reg[7] & 0xff000000) >> 24;
154                 t->reg[7] = (tmp7_3 << 24) |
155                             ((tmp7_3 - 6 + e->tCL) << 16) |
156                             0x202;
157         }
158
159         NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", t->id,
160                  t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
161         NV_DEBUG(dev, "         230: %08x %08x %08x %08x\n",
162                  t->reg[4], t->reg[5], t->reg[6], t->reg[7]);
163         NV_DEBUG(dev, "         240: %08x\n", t->reg[8]);
164         return 0;
165 }
166
167 static int
168 nvc0_mem_timing_calc(struct drm_device *dev, u32 freq,
169                      struct nouveau_pm_tbl_entry *e, u8 len,
170                      struct nouveau_pm_memtiming *boot,
171                      struct nouveau_pm_memtiming *t)
172 {
173         if (e->tCWL > 0)
174                 t->tCWL = e->tCWL;
175
176         t->reg[0] = (e->tRP << 24 | (e->tRAS & 0x7f) << 17 |
177                      e->tRFC << 8 | e->tRC);
178
179         t->reg[1] = (boot->reg[1] & 0xff000000) |
180                     (e->tRCDWR & 0x0f) << 20 |
181                     (e->tRCDRD & 0x0f) << 14 |
182                     (t->tCWL << 7) |
183                     (e->tCL & 0x0f);
184
185         t->reg[2] = (boot->reg[2] & 0xff0000ff) |
186                     e->tWR << 16 | e->tWTR << 8;
187
188         t->reg[3] = (e->tUNK_20 & 0x1f) << 9 |
189                     (e->tUNK_21 & 0xf) << 5 |
190                     (e->tUNK_13 & 0x1f);
191
192         t->reg[4] = (boot->reg[4] & 0xfff00fff) |
193                     (e->tRRD&0x1f) << 15;
194
195         NV_DEBUG(dev, "Entry %d: 290: %08x %08x %08x %08x\n", t->id,
196                  t->reg[0], t->reg[1], t->reg[2], t->reg[3]);
197         NV_DEBUG(dev, "         2a0: %08x\n", t->reg[4]);
198         return 0;
199 }
200
201 /**
202  * MR generation methods
203  */
204
205 static int
206 nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq,
207                     struct nouveau_pm_tbl_entry *e, u8 len,
208                     struct nouveau_pm_memtiming *boot,
209                     struct nouveau_pm_memtiming *t)
210 {
211         t->drive_strength = 0;
212         if (len < 15) {
213                 t->odt = boot->odt;
214         } else {
215                 t->odt = e->RAM_FT1 & 0x07;
216         }
217
218         if (e->tCL >= NV_MEM_CL_DDR2_MAX) {
219                 NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
220                 return -ERANGE;
221         }
222
223         if (e->tWR >= NV_MEM_WR_DDR2_MAX) {
224                 NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
225                 return -ERANGE;
226         }
227
228         if (t->odt > 3) {
229                 NV_WARN(dev, "(%u) Invalid odt value, assuming disabled: %x",
230                         t->id, t->odt);
231                 t->odt = 0;
232         }
233
234         t->mr[0] = (boot->mr[0] & 0x100f) |
235                    (e->tCL) << 4 |
236                    (e->tWR - 1) << 9;
237         t->mr[1] = (boot->mr[1] & 0x101fbb) |
238                    (t->odt & 0x1) << 2 |
239                    (t->odt & 0x2) << 5;
240
241         NV_DEBUG(dev, "(%u) MR: %08x", t->id, t->mr[0]);
242         return 0;
243 }
244
245 uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = {
246         0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0};
247
248 static int
249 nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq,
250                     struct nouveau_pm_tbl_entry *e, u8 len,
251                     struct nouveau_pm_memtiming *boot,
252                     struct nouveau_pm_memtiming *t)
253 {
254         u8 cl = e->tCL - 4;
255
256         t->drive_strength = 0;
257         if (len < 15) {
258                 t->odt = boot->odt;
259         } else {
260                 t->odt = e->RAM_FT1 & 0x07;
261         }
262
263         if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) {
264                 NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
265                 return -ERANGE;
266         }
267
268         if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) {
269                 NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
270                 return -ERANGE;
271         }
272
273         if (e->tCWL < 5) {
274                 NV_WARN(dev, "(%u) Invalid tCWL: %u", t->id, e->tCWL);
275                 return -ERANGE;
276         }
277
278         t->mr[0] = (boot->mr[0] & 0x180b) |
279                    /* CAS */
280                    (cl & 0x7) << 4 |
281                    (cl & 0x8) >> 1 |
282                    (nv_mem_wr_lut_ddr3[e->tWR]) << 9;
283         t->mr[1] = (boot->mr[1] & 0x101dbb) |
284                    (t->odt & 0x1) << 2 |
285                    (t->odt & 0x2) << 5 |
286                    (t->odt & 0x4) << 7;
287         t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3;
288
289         NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]);
290         return 0;
291 }
292
293 uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = {
294         0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11};
295 uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = {
296         0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3};
297
298 static int
299 nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq,
300                      struct nouveau_pm_tbl_entry *e, u8 len,
301                      struct nouveau_pm_memtiming *boot,
302                      struct nouveau_pm_memtiming *t)
303 {
304         if (len < 15) {
305                 t->drive_strength = boot->drive_strength;
306                 t->odt = boot->odt;
307         } else {
308                 t->drive_strength = (e->RAM_FT1 & 0x30) >> 4;
309                 t->odt = e->RAM_FT1 & 0x07;
310         }
311
312         if (e->tCL >= NV_MEM_CL_GDDR3_MAX) {
313                 NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
314                 return -ERANGE;
315         }
316
317         if (e->tWR >= NV_MEM_WR_GDDR3_MAX) {
318                 NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
319                 return -ERANGE;
320         }
321
322         if (t->odt > 3) {
323                 NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x",
324                         t->id, t->odt);
325                 t->odt = 0;
326         }
327
328         t->mr[0] = (boot->mr[0] & 0xe0b) |
329                    /* CAS */
330                    ((nv_mem_cl_lut_gddr3[e->tCL] & 0x7) << 4) |
331                    ((nv_mem_cl_lut_gddr3[e->tCL] & 0x8) >> 2);
332         t->mr[1] = (boot->mr[1] & 0x100f40) | t->drive_strength |
333                    (t->odt << 2) |
334                    (nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4;
335         t->mr[2] = boot->mr[2];
336
337         NV_DEBUG(dev, "(%u) MR: %08x %08x %08x", t->id,
338                       t->mr[0], t->mr[1], t->mr[2]);
339         return 0;
340 }
341
342 static int
343 nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
344                      struct nouveau_pm_tbl_entry *e, u8 len,
345                      struct nouveau_pm_memtiming *boot,
346                      struct nouveau_pm_memtiming *t)
347 {
348         if (len < 15) {
349                 t->drive_strength = boot->drive_strength;
350                 t->odt = boot->odt;
351         } else {
352                 t->drive_strength = (e->RAM_FT1 & 0x30) >> 4;
353                 t->odt = e->RAM_FT1 & 0x03;
354         }
355
356         if (e->tCL >= NV_MEM_CL_GDDR5_MAX) {
357                 NV_WARN(dev, "(%u) Invalid tCL: %u", t->id, e->tCL);
358                 return -ERANGE;
359         }
360
361         if (e->tWR >= NV_MEM_WR_GDDR5_MAX) {
362                 NV_WARN(dev, "(%u) Invalid tWR: %u", t->id, e->tWR);
363                 return -ERANGE;
364         }
365
366         if (t->odt > 3) {
367                 NV_WARN(dev, "(%u) Invalid odt value, assuming autocal: %x",
368                         t->id, t->odt);
369                 t->odt = 0;
370         }
371
372         t->mr[0] = (boot->mr[0] & 0x007) |
373                    ((e->tCL - 5) << 3) |
374                    ((e->tWR - 4) << 8);
375         t->mr[1] = (boot->mr[1] & 0x1007f0) |
376                    t->drive_strength |
377                    (t->odt << 2);
378
379         NV_DEBUG(dev, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]);
380         return 0;
381 }
382
383 int
384 nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
385                         struct nouveau_pm_memtiming *t)
386 {
387         struct drm_nouveau_private *dev_priv = dev->dev_private;
388         struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
389         struct nouveau_pm_memtiming *boot = &pm->boot.timing;
390         struct nouveau_pm_tbl_entry *e;
391         u8 ver, len, *ptr, *ramcfg;
392         int ret;
393
394         ptr = nouveau_perf_timing(dev, freq, &ver, &len);
395         if (!ptr || ptr[0] == 0x00) {
396                 *t = *boot;
397                 return 0;
398         }
399         e = (struct nouveau_pm_tbl_entry *)ptr;
400
401         t->tCWL = boot->tCWL;
402
403         switch (dev_priv->card_type) {
404         case NV_40:
405                 ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
406                 break;
407         case NV_50:
408                 ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
409                 break;
410         case NV_C0:
411         case NV_D0:
412                 ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
413                 break;
414         default:
415                 ret = -ENODEV;
416                 break;
417         }
418
419         switch (nvfb_vram_type(dev) * !ret) {
420         case NV_MEM_TYPE_GDDR3:
421                 ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
422                 break;
423         case NV_MEM_TYPE_GDDR5:
424                 ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t);
425                 break;
426         case NV_MEM_TYPE_DDR2:
427                 ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t);
428                 break;
429         case NV_MEM_TYPE_DDR3:
430                 ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t);
431                 break;
432         default:
433                 ret = -EINVAL;
434                 break;
435         }
436
437         ramcfg = nouveau_perf_ramcfg(dev, freq, &ver, &len);
438         if (ramcfg) {
439                 int dll_off;
440
441                 if (ver == 0x00)
442                         dll_off = !!(ramcfg[3] & 0x04);
443                 else
444                         dll_off = !!(ramcfg[2] & 0x40);
445
446                 switch (nvfb_vram_type(dev)) {
447                 case NV_MEM_TYPE_GDDR3:
448                         t->mr[1] &= ~0x00000040;
449                         t->mr[1] |=  0x00000040 * dll_off;
450                         break;
451                 default:
452                         t->mr[1] &= ~0x00000001;
453                         t->mr[1] |=  0x00000001 * dll_off;
454                         break;
455                 }
456         }
457
458         return ret;
459 }
460
461 void
462 nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t)
463 {
464         struct drm_nouveau_private *dev_priv = dev->dev_private;
465         u32 timing_base, timing_regs, mr_base;
466         int i;
467
468         if (dev_priv->card_type >= 0xC0) {
469                 timing_base = 0x10f290;
470                 mr_base = 0x10f300;
471         } else {
472                 timing_base = 0x100220;
473                 mr_base = 0x1002c0;
474         }
475
476         t->id = -1;
477
478         switch (dev_priv->card_type) {
479         case NV_50:
480                 timing_regs = 9;
481                 break;
482         case NV_C0:
483         case NV_D0:
484                 timing_regs = 5;
485                 break;
486         case NV_30:
487         case NV_40:
488                 timing_regs = 3;
489                 break;
490         default:
491                 timing_regs = 0;
492                 return;
493         }
494         for(i = 0; i < timing_regs; i++)
495                 t->reg[i] = nv_rd32(dev, timing_base + (0x04 * i));
496
497         t->tCWL = 0;
498         if (dev_priv->card_type < NV_C0) {
499                 t->tCWL = ((nv_rd32(dev, 0x100228) & 0x0f000000) >> 24) + 1;
500         } else if (dev_priv->card_type <= NV_D0) {
501                 t->tCWL = ((nv_rd32(dev, 0x10f294) & 0x00000f80) >> 7);
502         }
503
504         t->mr[0] = nv_rd32(dev, mr_base);
505         t->mr[1] = nv_rd32(dev, mr_base + 0x04);
506         t->mr[2] = nv_rd32(dev, mr_base + 0x20);
507         t->mr[3] = nv_rd32(dev, mr_base + 0x24);
508
509         t->odt = 0;
510         t->drive_strength = 0;
511
512         switch (nvfb_vram_type(dev)) {
513         case NV_MEM_TYPE_DDR3:
514                 t->odt |= (t->mr[1] & 0x200) >> 7;
515         case NV_MEM_TYPE_DDR2:
516                 t->odt |= (t->mr[1] & 0x04) >> 2 |
517                           (t->mr[1] & 0x40) >> 5;
518                 break;
519         case NV_MEM_TYPE_GDDR3:
520         case NV_MEM_TYPE_GDDR5:
521                 t->drive_strength = t->mr[1] & 0x03;
522                 t->odt = (t->mr[1] & 0x0c) >> 2;
523                 break;
524         default:
525                 break;
526         }
527 }
528
529 int
530 nouveau_mem_exec(struct nouveau_mem_exec_func *exec,
531                  struct nouveau_pm_level *perflvl)
532 {
533         struct drm_nouveau_private *dev_priv = exec->dev->dev_private;
534         struct nouveau_pm_memtiming *info = &perflvl->timing;
535         u32 tMRD = 1000, tCKSRE = 0, tCKSRX = 0, tXS = 0, tDLLK = 0;
536         u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] };
537         u32 mr1_dlloff;
538
539         switch (nvfb_vram_type(dev_priv->dev)) {
540         case NV_MEM_TYPE_DDR2:
541                 tDLLK = 2000;
542                 mr1_dlloff = 0x00000001;
543                 break;
544         case NV_MEM_TYPE_DDR3:
545                 tDLLK = 12000;
546                 tCKSRE = 2000;
547                 tXS = 1000;
548                 mr1_dlloff = 0x00000001;
549                 break;
550         case NV_MEM_TYPE_GDDR3:
551                 tDLLK = 40000;
552                 mr1_dlloff = 0x00000040;
553                 break;
554         default:
555                 NV_ERROR(exec->dev, "cannot reclock unsupported memtype\n");
556                 return -ENODEV;
557         }
558
559         /* fetch current MRs */
560         switch (nvfb_vram_type(dev_priv->dev)) {
561         case NV_MEM_TYPE_GDDR3:
562         case NV_MEM_TYPE_DDR3:
563                 mr[2] = exec->mrg(exec, 2);
564         default:
565                 mr[1] = exec->mrg(exec, 1);
566                 mr[0] = exec->mrg(exec, 0);
567                 break;
568         }
569
570         /* DLL 'on' -> DLL 'off' mode, disable before entering self-refresh  */
571         if (!(mr[1] & mr1_dlloff) && (info->mr[1] & mr1_dlloff)) {
572                 exec->precharge(exec);
573                 exec->mrs (exec, 1, mr[1] | mr1_dlloff);
574                 exec->wait(exec, tMRD);
575         }
576
577         /* enter self-refresh mode */
578         exec->precharge(exec);
579         exec->refresh(exec);
580         exec->refresh(exec);
581         exec->refresh_auto(exec, false);
582         exec->refresh_self(exec, true);
583         exec->wait(exec, tCKSRE);
584
585         /* modify input clock frequency */
586         exec->clock_set(exec);
587
588         /* exit self-refresh mode */
589         exec->wait(exec, tCKSRX);
590         exec->precharge(exec);
591         exec->refresh_self(exec, false);
592         exec->refresh_auto(exec, true);
593         exec->wait(exec, tXS);
594         exec->wait(exec, tXS);
595
596         /* update MRs */
597         if (mr[2] != info->mr[2]) {
598                 exec->mrs (exec, 2, info->mr[2]);
599                 exec->wait(exec, tMRD);
600         }
601
602         if (mr[1] != info->mr[1]) {
603                 /* need to keep DLL off until later, at least on GDDR3 */
604                 exec->mrs (exec, 1, info->mr[1] | (mr[1] & mr1_dlloff));
605                 exec->wait(exec, tMRD);
606         }
607
608         if (mr[0] != info->mr[0]) {
609                 exec->mrs (exec, 0, info->mr[0]);
610                 exec->wait(exec, tMRD);
611         }
612
613         /* update PFB timing registers */
614         exec->timing_set(exec);
615
616         /* DLL (enable + ) reset */
617         if (!(info->mr[1] & mr1_dlloff)) {
618                 if (mr[1] & mr1_dlloff) {
619                         exec->mrs (exec, 1, info->mr[1]);
620                         exec->wait(exec, tMRD);
621                 }
622                 exec->mrs (exec, 0, info->mr[0] | 0x00000100);
623                 exec->wait(exec, tMRD);
624                 exec->mrs (exec, 0, info->mr[0] | 0x00000000);
625                 exec->wait(exec, tMRD);
626                 exec->wait(exec, tDLLK);
627                 if (nvfb_vram_type(dev_priv->dev) == NV_MEM_TYPE_GDDR3)
628                         exec->precharge(exec);
629         }
630
631         return 0;
632 }
633
634 int
635 nouveau_mem_vbios_type(struct drm_device *dev)
636 {
637         struct bit_entry M;
638         u8 ramcfg = (nv_rd32(dev, 0x101000) & 0x0000003c) >> 2;
639         if (!bit_table(dev, 'M', &M) || M.version != 2 || M.length < 5) {
640                 u8 *table = ROMPTR(dev, M.data[3]);
641                 if (table && table[0] == 0x10 && ramcfg < table[3]) {
642                         u8 *entry = table + table[1] + (ramcfg * table[2]);
643                         switch (entry[0] & 0x0f) {
644                         case 0: return NV_MEM_TYPE_DDR2;
645                         case 1: return NV_MEM_TYPE_DDR3;
646                         case 2: return NV_MEM_TYPE_GDDR3;
647                         case 3: return NV_MEM_TYPE_GDDR5;
648                         default:
649                                 break;
650                         }
651
652                 }
653         }
654         return NV_MEM_TYPE_UNKNOWN;
655 }