aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 2683377f4131..78f467fe30be 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -552,6 +552,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
552 u8 tRC; /* Byte 9 */ 552 u8 tRC; /* Byte 9 */
553 u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14; 553 u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
554 u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21; 554 u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
555 u8 magic_number = 0; /* Yeah... sorry*/
555 u8 *mem = NULL, *entry; 556 u8 *mem = NULL, *entry;
556 int i, recordlen, entries; 557 int i, recordlen, entries;
557 558
@@ -596,6 +597,12 @@ nouveau_mem_timing_init(struct drm_device *dev)
596 if (!memtimings->timing) 597 if (!memtimings->timing)
597 return; 598 return;
598 599
600 /* Get "some number" from the timing reg for NV_40
601 * Used in calculations later */
602 if(dev_priv->card_type == NV_40) {
603 magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24;
604 }
605
599 entry = mem + mem[1]; 606 entry = mem + mem[1];
600 for (i = 0; i < entries; i++, entry += recordlen) { 607 for (i = 0; i < entries; i++, entry += recordlen) {
601 struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i]; 608 struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
@@ -635,36 +642,51 @@ nouveau_mem_timing_init(struct drm_device *dev)
635 642
636 /* XXX: I don't trust the -1's and +1's... they must come 643 /* XXX: I don't trust the -1's and +1's... they must come
637 * from somewhere! */ 644 * from somewhere! */
638 timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 | 645 timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
639 tUNK_18 << 16 | 646 tUNK_18 << 16 |
640 (tUNK_1 + tUNK_19 + 1) << 8 | 647 (tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
641 (tUNK_2 - 1)); 648 if(dev_priv->chipset == 0xa8) {
649 timing->reg_100224 |= (tUNK_2 - 1);
650 } else {
651 timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
652 }
642 653
643 timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); 654 timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
644 if(recordlen > 19) { 655 if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
645 timing->reg_100228 += (tUNK_19 - 1) << 24; 656 timing->reg_100228 |= (tUNK_19 - 1) << 24;
646 }/* I cannot back-up this else-statement right now 657 }
647 else { 658
648 timing->reg_100228 += tUNK_12 << 24; 659 if(dev_priv->card_type == NV_40) {
649 }*/ 660 /* NV40: don't know what the rest of the regs are..
650 661 * And don't need to know either */
651 /* XXX: reg_10022c */ 662 timing->reg_100228 |= 0x20200000 | magic_number << 24;
652 timing->reg_10022c = tUNK_2 - 1; 663 } else if(dev_priv->card_type >= NV_50) {
653 664 /* XXX: reg_10022c */
654 timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | 665 timing->reg_10022c = tUNK_2 - 1;
655 tUNK_13 << 8 | tUNK_13); 666
656 667 timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
657 /* XXX: +6? */ 668 tUNK_13 << 8 | tUNK_13);
658 timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); 669
659 timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; 670 timing->reg_100234 = (tRAS << 24 | tRC);
660 671 timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
661 /* XXX; reg_100238, reg_10023c 672
662 * reg: 0x00?????? 673 if(dev_priv->chipset < 0xa3) {
663 * reg_10023c: 674 timing->reg_100234 |= (tUNK_2 + 2) << 8;
664 * 0 for pre-NV50 cards 675 } else {
665 * 0x????0202 for NV50+ cards (empirical evidence) */ 676 /* XXX: +6? */
666 if(dev_priv->card_type >= NV_50) { 677 timing->reg_100234 |= (tUNK_19 + 6) << 8;
678 }
679
680 /* XXX; reg_100238, reg_10023c
681 * reg_100238: 0x00??????
682 * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
667 timing->reg_10023c = 0x202; 683 timing->reg_10023c = 0x202;
684 if(dev_priv->chipset < 0xa3) {
685 timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
686 } else {
687 /* currently unknown
688 * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
689 }
668 } 690 }
669 691
670 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, 692 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
@@ -675,7 +697,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
675 timing->reg_100238, timing->reg_10023c); 697 timing->reg_100238, timing->reg_10023c);
676 } 698 }
677 699
678 memtimings->nr_timing = entries; 700 memtimings->nr_timing = entries;
679 memtimings->supported = true; 701 memtimings->supported = true;
680} 702}
681 703