diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 76 |
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 | ||