aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c45
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c2
3 files changed, 35 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 711ee0d9627d..0f5f797e500c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -466,6 +466,7 @@ struct nouveau_pm_memtiming {
466 u32 reg_100234; 466 u32 reg_100234;
467 u32 reg_100238; 467 u32 reg_100238;
468 u32 reg_10023c; 468 u32 reg_10023c;
469 u32 reg_100240;
469}; 470};
470 471
471struct nouveau_pm_memtimings { 472struct nouveau_pm_memtimings {
@@ -637,6 +638,7 @@ struct drm_nouveau_private {
637 enum nouveau_card_type card_type; 638 enum nouveau_card_type card_type;
638 /* exact chipset, derived from NV_PMC_BOOT_0 */ 639 /* exact chipset, derived from NV_PMC_BOOT_0 */
639 int chipset; 640 int chipset;
641 int stepping;
640 int flags; 642 int flags;
641 643
642 void __iomem *mmio; 644 void __iomem *mmio;
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;
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index e04c4b651955..4b4992824bbf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -913,11 +913,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
913 913
914 /* Time to determine the card architecture */ 914 /* Time to determine the card architecture */
915 reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); 915 reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
916 dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
916 917
917 /* We're dealing with >=NV10 */ 918 /* We're dealing with >=NV10 */
918 if ((reg0 & 0x0f000000) > 0) { 919 if ((reg0 & 0x0f000000) > 0) {
919 /* Bit 27-20 contain the architecture in hex */ 920 /* Bit 27-20 contain the architecture in hex */
920 dev_priv->chipset = (reg0 & 0xff00000) >> 20; 921 dev_priv->chipset = (reg0 & 0xff00000) >> 20;
922 dev_priv->stepping = (reg0 & 0xff);
921 /* NV04 or NV05 */ 923 /* NV04 or NV05 */
922 } else if ((reg0 & 0xff00fff0) == 0x20004000) { 924 } else if ((reg0 & 0xff00fff0) == 0x20004000) {
923 if (reg0 & 0x00f00000) 925 if (reg0 & 0x00f00000)