aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_mem.c
diff options
context:
space:
mode:
authorRoy Spliet <r.spliet@student.tudelft.nl>2011-03-27 12:13:11 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-05-15 20:47:43 -0400
commit50066f8117d79163b96d3bf778c41961be1fe5cd (patch)
treea3425c1d9108768fac80d3e2fc508d3babeb2023 /drivers/gpu/drm/nouveau/nouveau_mem.c
parent7795bee0c437aff7fb188afe750fe79a7a971a2c (diff)
drm/nouveau: improve memtiming table parsing
Improves the parsing of the memory timing table on NV50-NV98revA1 chipsets. Added stepping to drm_nouveau_private to make sure newer NV98 (105M) is zero rather than incorrect. Signed-off-by: Roy Spliet <r.spliet@student.tudelft.nl> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index e177a62967e0..cf1731bbb032 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -597,9 +597,9 @@ nouveau_mem_timing_init(struct drm_device *dev)
597 if (!memtimings->timing) 597 if (!memtimings->timing)
598 return; 598 return;
599 599
600 /* Get "some number" from the timing reg for NV_40 600 /* Get "some number" from the timing reg for NV_40 and NV_50
601 * Used in calculations later */ 601 * Used in calculations later */
602 if (dev_priv->card_type == NV_40) { 602 if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) {
603 magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24; 603 magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24;
604 } 604 }
605 605
@@ -643,7 +643,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
643 /* 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
644 * from somewhere! */ 644 * from somewhere! */
645 timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 | 645 timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
646 tUNK_18 << 16 | 646 max(tUNK_18, (u8) 1) << 16 |
647 (tUNK_1 + tUNK_19 + 1 + magic_number) << 8; 647 (tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
648 if (dev_priv->chipset == 0xa8) { 648 if (dev_priv->chipset == 0xa8) {
649 timing->reg_100224 |= (tUNK_2 - 1); 649 timing->reg_100224 |= (tUNK_2 - 1);
@@ -652,17 +652,27 @@ nouveau_mem_timing_init(struct drm_device *dev)
652 } 652 }
653 653
654 timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); 654 timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
655 if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) { 655 if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa)
656 timing->reg_100228 |= (tUNK_19 - 1) << 24; 656 timing->reg_100228 |= (tUNK_19 - 1) << 24;
657 } 657 else
658 timing->reg_100228 |= magic_number << 24;
658 659
659 if (dev_priv->card_type == NV_40) { 660 if (dev_priv->card_type == NV_40) {
660 /* NV40: don't know what the rest of the regs are.. 661 /* NV40: don't know what the rest of the regs are..
661 * And don't need to know either */ 662 * And don't need to know either */
662 timing->reg_100228 |= 0x20200000 | magic_number << 24; 663 timing->reg_100228 |= 0x20200000;
663 } else if (dev_priv->card_type >= NV_50) { 664 } else if (dev_priv->card_type >= NV_50) {
664 /* XXX: reg_10022c */ 665 if (dev_priv->chipset < 0x98 ||
665 timing->reg_10022c = tUNK_2 - 1; 666 (dev_priv->chipset == 0x98 &&
667 dev_priv->stepping <= 0xa1)) {
668 timing->reg_10022c = (0x14 + tUNK_2) << 24 |
669 0x16 << 16 |
670 (tUNK_2 - 1) << 8 |
671 (tUNK_2 - 1);
672 } else {
673 /* XXX: reg_10022c for recentish cards */
674 timing->reg_10022c = tUNK_2 - 1;
675 }
666 676
667 timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | 677 timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
668 tUNK_13 << 8 | tUNK_13); 678 tUNK_13 << 8 | tUNK_13);
@@ -670,23 +680,29 @@ nouveau_mem_timing_init(struct drm_device *dev)
670 timing->reg_100234 = (tRAS << 24 | tRC); 680 timing->reg_100234 = (tRAS << 24 | tRC);
671 timing->reg_100234 += max(tUNK_10, tUNK_11) << 16; 681 timing->reg_100234 += max(tUNK_10, tUNK_11) << 16;
672 682
673 if (dev_priv->chipset < 0xa3) { 683 if (dev_priv->chipset < 0x98 ||
684 (dev_priv->chipset == 0x98 &&
685 dev_priv->stepping <= 0xa1)) {
674 timing->reg_100234 |= (tUNK_2 + 2) << 8; 686 timing->reg_100234 |= (tUNK_2 + 2) << 8;
675 } else { 687 } else {
676 /* XXX: +6? */ 688 /* XXX: +6? */
677 timing->reg_100234 |= (tUNK_19 + 6) << 8; 689 timing->reg_100234 |= (tUNK_19 + 6) << 8;
678 } 690 }
679 691
680 /* XXX; reg_100238, reg_10023c 692 /* XXX; reg_100238
681 * reg_100238: 0x00?????? 693 * reg_100238: 0x00?????? */
682 * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
683 timing->reg_10023c = 0x202; 694 timing->reg_10023c = 0x202;
684 if (dev_priv->chipset < 0xa3) { 695 if (dev_priv->chipset < 0x98 ||
696 (dev_priv->chipset == 0x98 &&
697 dev_priv->stepping <= 0xa1)) {
685 timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16; 698 timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
686 } else { 699 } else {
687 /* currently unknown 700 /* XXX: reg_10023c
701 * currently unknown
688 * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */ 702 * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
689 } 703 }
704
705 /* XXX: reg_100240? */
690 } 706 }
691 707
692 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, 708 NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
@@ -695,6 +711,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
695 NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n", 711 NV_DEBUG(dev, " 230: %08x %08x %08x %08x\n",
696 timing->reg_100230, timing->reg_100234, 712 timing->reg_100230, timing->reg_100234,
697 timing->reg_100238, timing->reg_10023c); 713 timing->reg_100238, timing->reg_10023c);
714 NV_DEBUG(dev, " 240: %08x\n", timing->reg_100240);
698 } 715 }
699 716
700 memtimings->nr_timing = entries; 717 memtimings->nr_timing = entries;