diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 2 |
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 | ||
471 | struct nouveau_pm_memtimings { | 472 | struct 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) |