diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-07-05 18:54:34 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-07-12 20:13:31 -0400 |
commit | 87c0e0e5133e252a6d3d561dd0caeec0244ea9a5 (patch) | |
tree | 4135bfa3848b0433e71e40c23534d3e8651b2d70 /drivers | |
parent | 835aadbef3b762bc43eceddfec90c9a5a312d3c1 (diff) |
drm/nv50: rewrite display irq handler
The previous handler basically worked correctly for a full-blown mode
change. However, it did nothing at all when a partial (encoder only)
reconfiguation was necessary, leading to the display hanging on certain
types of mode switch.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 328 |
2 files changed, 190 insertions, 143 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 565981dfd69b..4de342f54fd2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -610,6 +610,11 @@ struct drm_nouveau_private { | |||
610 | struct backlight_device *backlight; | 610 | struct backlight_device *backlight; |
611 | 611 | ||
612 | struct nouveau_channel *evo; | 612 | struct nouveau_channel *evo; |
613 | struct { | ||
614 | struct dcb_entry *dcb; | ||
615 | u16 script; | ||
616 | u32 pclk; | ||
617 | } evo_irq; | ||
613 | 618 | ||
614 | struct { | 619 | struct { |
615 | struct dentry *channel_root; | 620 | struct dentry *channel_root; |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 0c762049cb68..711128c42de8 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -559,131 +559,28 @@ int nv50_display_destroy(struct drm_device *dev) | |||
559 | return 0; | 559 | return 0; |
560 | } | 560 | } |
561 | 561 | ||
562 | static inline uint32_t | 562 | static u16 |
563 | nv50_display_mode_ctrl(struct drm_device *dev, bool sor, int or) | 563 | nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcb, |
564 | { | 564 | u32 mc, int pxclk) |
565 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
566 | uint32_t mc; | ||
567 | |||
568 | if (sor) { | ||
569 | if (dev_priv->chipset < 0x90 || | ||
570 | dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0) | ||
571 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(or)); | ||
572 | else | ||
573 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(or)); | ||
574 | } else { | ||
575 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(or)); | ||
576 | } | ||
577 | |||
578 | return mc; | ||
579 | } | ||
580 | |||
581 | static int | ||
582 | nv50_display_irq_head(struct drm_device *dev, int *phead, | ||
583 | struct dcb_entry **pdcbent) | ||
584 | { | ||
585 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
586 | uint32_t unk30 = nv_rd32(dev, NV50_PDISPLAY_UNK30_CTRL); | ||
587 | uint32_t dac = 0, sor = 0; | ||
588 | int head, i, or = 0, type = OUTPUT_ANY; | ||
589 | |||
590 | /* We're assuming that head 0 *or* head 1 will be active here, | ||
591 | * and not both. I'm not sure if the hw will even signal both | ||
592 | * ever, but it definitely shouldn't for us as we commit each | ||
593 | * CRTC separately, and submission will be blocked by the GPU | ||
594 | * until we handle each in turn. | ||
595 | */ | ||
596 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); | ||
597 | head = ffs((unk30 >> 9) & 3) - 1; | ||
598 | if (head < 0) | ||
599 | return -EINVAL; | ||
600 | |||
601 | /* This assumes CRTCs are never bound to multiple encoders, which | ||
602 | * should be the case. | ||
603 | */ | ||
604 | for (i = 0; i < 3 && type == OUTPUT_ANY; i++) { | ||
605 | uint32_t mc = nv50_display_mode_ctrl(dev, false, i); | ||
606 | if (!(mc & (1 << head))) | ||
607 | continue; | ||
608 | |||
609 | switch ((mc >> 8) & 0xf) { | ||
610 | case 0: type = OUTPUT_ANALOG; break; | ||
611 | case 1: type = OUTPUT_TV; break; | ||
612 | default: | ||
613 | NV_ERROR(dev, "unknown dac mode_ctrl: 0x%08x\n", dac); | ||
614 | return -1; | ||
615 | } | ||
616 | |||
617 | or = i; | ||
618 | } | ||
619 | |||
620 | for (i = 0; i < 4 && type == OUTPUT_ANY; i++) { | ||
621 | uint32_t mc = nv50_display_mode_ctrl(dev, true, i); | ||
622 | if (!(mc & (1 << head))) | ||
623 | continue; | ||
624 | |||
625 | switch ((mc >> 8) & 0xf) { | ||
626 | case 0: type = OUTPUT_LVDS; break; | ||
627 | case 1: type = OUTPUT_TMDS; break; | ||
628 | case 2: type = OUTPUT_TMDS; break; | ||
629 | case 5: type = OUTPUT_TMDS; break; | ||
630 | case 8: type = OUTPUT_DP; break; | ||
631 | case 9: type = OUTPUT_DP; break; | ||
632 | default: | ||
633 | NV_ERROR(dev, "unknown sor mode_ctrl: 0x%08x\n", sor); | ||
634 | return -1; | ||
635 | } | ||
636 | |||
637 | or = i; | ||
638 | } | ||
639 | |||
640 | NV_DEBUG_KMS(dev, "type %d, or %d\n", type, or); | ||
641 | if (type == OUTPUT_ANY) { | ||
642 | NV_ERROR(dev, "unknown encoder!!\n"); | ||
643 | return -1; | ||
644 | } | ||
645 | |||
646 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | ||
647 | struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i]; | ||
648 | |||
649 | if (dcbent->type != type) | ||
650 | continue; | ||
651 | |||
652 | if (!(dcbent->or & (1 << or))) | ||
653 | continue; | ||
654 | |||
655 | *phead = head; | ||
656 | *pdcbent = dcbent; | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | NV_ERROR(dev, "no DCB entry for %d %d\n", dac != 0, or); | ||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static uint32_t | ||
665 | nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | ||
666 | int pxclk) | ||
667 | { | 565 | { |
668 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 566 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
669 | struct nouveau_connector *nv_connector = NULL; | 567 | struct nouveau_connector *nv_connector = NULL; |
670 | struct drm_encoder *encoder; | 568 | struct drm_encoder *encoder; |
671 | struct nvbios *bios = &dev_priv->vbios; | 569 | struct nvbios *bios = &dev_priv->vbios; |
672 | uint32_t mc, script = 0, or; | 570 | u32 script = 0, or; |
673 | 571 | ||
674 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 572 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
675 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 573 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
676 | 574 | ||
677 | if (nv_encoder->dcb != dcbent) | 575 | if (nv_encoder->dcb != dcb) |
678 | continue; | 576 | continue; |
679 | 577 | ||
680 | nv_connector = nouveau_encoder_connector_get(nv_encoder); | 578 | nv_connector = nouveau_encoder_connector_get(nv_encoder); |
681 | break; | 579 | break; |
682 | } | 580 | } |
683 | 581 | ||
684 | or = ffs(dcbent->or) - 1; | 582 | or = ffs(dcb->or) - 1; |
685 | mc = nv50_display_mode_ctrl(dev, dcbent->type != OUTPUT_ANALOG, or); | 583 | switch (dcb->type) { |
686 | switch (dcbent->type) { | ||
687 | case OUTPUT_LVDS: | 584 | case OUTPUT_LVDS: |
688 | script = (mc >> 8) & 0xf; | 585 | script = (mc >> 8) & 0xf; |
689 | if (bios->fp_no_ddc) { | 586 | if (bios->fp_no_ddc) { |
@@ -774,17 +671,88 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) | |||
774 | static void | 671 | static void |
775 | nv50_display_unk10_handler(struct drm_device *dev) | 672 | nv50_display_unk10_handler(struct drm_device *dev) |
776 | { | 673 | { |
777 | struct dcb_entry *dcbent; | 674 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
778 | int head, ret; | 675 | u32 unk30 = nv_rd32(dev, 0x610030), mc; |
676 | int i, crtc, or, type = OUTPUT_ANY; | ||
779 | 677 | ||
780 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 678 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
781 | if (ret) | 679 | dev_priv->evo_irq.dcb = NULL; |
782 | goto ack; | ||
783 | 680 | ||
784 | nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); | 681 | nv_wr32(dev, 0x619494, nv_rd32(dev, 0x619494) & ~8); |
785 | 682 | ||
786 | nouveau_bios_run_display_table(dev, dcbent, 0, -1); | 683 | /* Determine which CRTC we're dealing with, only 1 ever will be |
684 | * signalled at the same time with the current nouveau code. | ||
685 | */ | ||
686 | crtc = ffs((unk30 & 0x00000060) >> 5) - 1; | ||
687 | if (crtc < 0) | ||
688 | goto ack; | ||
689 | |||
690 | /* Nothing needs to be done for the encoder */ | ||
691 | crtc = ffs((unk30 & 0x00000180) >> 7) - 1; | ||
692 | if (crtc < 0) | ||
693 | goto ack; | ||
787 | 694 | ||
695 | /* Find which encoder was connected to the CRTC */ | ||
696 | for (i = 0; type == OUTPUT_ANY && i < 3; i++) { | ||
697 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_C(i)); | ||
698 | NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); | ||
699 | if (!(mc & (1 << crtc))) | ||
700 | continue; | ||
701 | |||
702 | switch ((mc & 0x00000f00) >> 8) { | ||
703 | case 0: type = OUTPUT_ANALOG; break; | ||
704 | case 1: type = OUTPUT_TV; break; | ||
705 | default: | ||
706 | NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); | ||
707 | goto ack; | ||
708 | } | ||
709 | |||
710 | or = i; | ||
711 | } | ||
712 | |||
713 | for (i = 0; type == OUTPUT_ANY && i < 4; i++) { | ||
714 | if (dev_priv->chipset < 0x90 || | ||
715 | dev_priv->chipset == 0x92 || | ||
716 | dev_priv->chipset == 0xa0) | ||
717 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(i)); | ||
718 | else | ||
719 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(i)); | ||
720 | |||
721 | NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); | ||
722 | if (!(mc & (1 << crtc))) | ||
723 | continue; | ||
724 | |||
725 | switch ((mc & 0x00000f00) >> 8) { | ||
726 | case 0: type = OUTPUT_LVDS; break; | ||
727 | case 1: type = OUTPUT_TMDS; break; | ||
728 | case 2: type = OUTPUT_TMDS; break; | ||
729 | case 5: type = OUTPUT_TMDS; break; | ||
730 | case 8: type = OUTPUT_DP; break; | ||
731 | case 9: type = OUTPUT_DP; break; | ||
732 | default: | ||
733 | NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); | ||
734 | goto ack; | ||
735 | } | ||
736 | |||
737 | or = i; | ||
738 | } | ||
739 | |||
740 | /* There was no encoder to disable */ | ||
741 | if (type == OUTPUT_ANY) | ||
742 | goto ack; | ||
743 | |||
744 | /* Disable the encoder */ | ||
745 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { | ||
746 | struct dcb_entry *dcb = &dev_priv->vbios.dcb.entry[i]; | ||
747 | |||
748 | if (dcb->type == type && (dcb->or & (1 << or))) { | ||
749 | nouveau_bios_run_display_table(dev, dcb, 0, -1); | ||
750 | dev_priv->evo_irq.dcb = dcb; | ||
751 | goto ack; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); | ||
788 | ack: | 756 | ack: |
789 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); | 757 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK10); |
790 | nv_wr32(dev, 0x610030, 0x80000000); | 758 | nv_wr32(dev, 0x610030, 0x80000000); |
@@ -854,34 +822,104 @@ nv50_display_unk20_dp_set_tmds(struct drm_device *dev, struct dcb_entry *dcb) | |||
854 | static void | 822 | static void |
855 | nv50_display_unk20_handler(struct drm_device *dev) | 823 | nv50_display_unk20_handler(struct drm_device *dev) |
856 | { | 824 | { |
857 | struct dcb_entry *dcbent; | 825 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
858 | uint32_t tmp, pclk, script; | 826 | u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc; |
859 | int head, or, ret; | 827 | struct dcb_entry *dcb; |
828 | int i, crtc, or, type = OUTPUT_ANY; | ||
860 | 829 | ||
861 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 830 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
862 | if (ret) | 831 | dcb = dev_priv->evo_irq.dcb; |
832 | if (dcb) { | ||
833 | nouveau_bios_run_display_table(dev, dcb, 0, -2); | ||
834 | dev_priv->evo_irq.dcb = NULL; | ||
835 | } | ||
836 | |||
837 | /* CRTC clock change requested? */ | ||
838 | crtc = ffs((unk30 & 0x00000600) >> 9) - 1; | ||
839 | if (crtc >= 0) { | ||
840 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)); | ||
841 | pclk &= 0x003fffff; | ||
842 | |||
843 | nv50_crtc_set_clock(dev, crtc, pclk); | ||
844 | |||
845 | tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc)); | ||
846 | tmp &= ~0x000000f; | ||
847 | nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(crtc), tmp); | ||
848 | } | ||
849 | |||
850 | /* Nothing needs to be done for the encoder */ | ||
851 | crtc = ffs((unk30 & 0x00000180) >> 7) - 1; | ||
852 | if (crtc < 0) | ||
863 | goto ack; | 853 | goto ack; |
864 | or = ffs(dcbent->or) - 1; | 854 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(crtc, CLOCK)) & 0x003fffff; |
865 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; | ||
866 | script = nv50_display_script_select(dev, dcbent, pclk); | ||
867 | 855 | ||
868 | NV_DEBUG_KMS(dev, "head %d pxclk: %dKHz\n", head, pclk); | 856 | /* Find which encoder is connected to the CRTC */ |
857 | for (i = 0; type == OUTPUT_ANY && i < 3; i++) { | ||
858 | mc = nv_rd32(dev, NV50_PDISPLAY_DAC_MODE_CTRL_P(i)); | ||
859 | NV_DEBUG_KMS(dev, "DAC-%d mc: 0x%08x\n", i, mc); | ||
860 | if (!(mc & (1 << crtc))) | ||
861 | continue; | ||
869 | 862 | ||
870 | if (dcbent->type != OUTPUT_DP) | 863 | switch ((mc & 0x00000f00) >> 8) { |
871 | nouveau_bios_run_display_table(dev, dcbent, 0, -2); | 864 | case 0: type = OUTPUT_ANALOG; break; |
865 | case 1: type = OUTPUT_TV; break; | ||
866 | default: | ||
867 | NV_ERROR(dev, "invalid mc, DAC-%d: 0x%08x\n", i, mc); | ||
868 | goto ack; | ||
869 | } | ||
870 | |||
871 | or = i; | ||
872 | } | ||
873 | |||
874 | for (i = 0; type == OUTPUT_ANY && i < 4; i++) { | ||
875 | if (dev_priv->chipset < 0x90 || | ||
876 | dev_priv->chipset == 0x92 || | ||
877 | dev_priv->chipset == 0xa0) | ||
878 | mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_P(i)); | ||
879 | else | ||
880 | mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_P(i)); | ||
881 | |||
882 | NV_DEBUG_KMS(dev, "SOR-%d mc: 0x%08x\n", i, mc); | ||
883 | if (!(mc & (1 << crtc))) | ||
884 | continue; | ||
885 | |||
886 | switch ((mc & 0x00000f00) >> 8) { | ||
887 | case 0: type = OUTPUT_LVDS; break; | ||
888 | case 1: type = OUTPUT_TMDS; break; | ||
889 | case 2: type = OUTPUT_TMDS; break; | ||
890 | case 5: type = OUTPUT_TMDS; break; | ||
891 | case 8: type = OUTPUT_DP; break; | ||
892 | case 9: type = OUTPUT_DP; break; | ||
893 | default: | ||
894 | NV_ERROR(dev, "invalid mc, SOR-%d: 0x%08x\n", i, mc); | ||
895 | goto ack; | ||
896 | } | ||
872 | 897 | ||
873 | nv50_crtc_set_clock(dev, head, pclk); | 898 | or = i; |
899 | } | ||
874 | 900 | ||
875 | nouveau_bios_run_display_table(dev, dcbent, script, pclk); | 901 | if (type == OUTPUT_ANY) |
902 | goto ack; | ||
876 | 903 | ||
877 | nv50_display_unk20_dp_hack(dev, dcbent); | 904 | /* Enable the encoder */ |
878 | nv50_display_unk20_dp_set_tmds(dev, dcbent); | 905 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { |
906 | dcb = &dev_priv->vbios.dcb.entry[i]; | ||
907 | if (dcb->type == type && (dcb->or & (1 << or))) | ||
908 | break; | ||
909 | } | ||
879 | 910 | ||
880 | tmp = nv_rd32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head)); | 911 | if (i == dev_priv->vbios.dcb.entries) { |
881 | tmp &= ~0x000000f; | 912 | NV_ERROR(dev, "no dcb for %d %d 0x%08x\n", or, type, mc); |
882 | nv_wr32(dev, NV50_PDISPLAY_CRTC_CLK_CTRL2(head), tmp); | 913 | goto ack; |
914 | } | ||
915 | |||
916 | script = nv50_display_script_select(dev, dcb, mc, pclk); | ||
917 | nouveau_bios_run_display_table(dev, dcb, script, pclk); | ||
883 | 918 | ||
884 | if (dcbent->type != OUTPUT_ANALOG) { | 919 | nv50_display_unk20_dp_hack(dev, dcb); |
920 | nv50_display_unk20_dp_set_tmds(dev, dcb); | ||
921 | |||
922 | if (dcb->type != OUTPUT_ANALOG) { | ||
885 | tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); | 923 | tmp = nv_rd32(dev, NV50_PDISPLAY_SOR_CLK_CTRL2(or)); |
886 | tmp &= ~0x00000f0f; | 924 | tmp &= ~0x00000f0f; |
887 | if (script & 0x0100) | 925 | if (script & 0x0100) |
@@ -891,6 +929,10 @@ nv50_display_unk20_handler(struct drm_device *dev) | |||
891 | nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); | 929 | nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL2(or), 0); |
892 | } | 930 | } |
893 | 931 | ||
932 | dev_priv->evo_irq.dcb = dcb; | ||
933 | dev_priv->evo_irq.pclk = pclk; | ||
934 | dev_priv->evo_irq.script = script; | ||
935 | |||
894 | ack: | 936 | ack: |
895 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); | 937 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK20); |
896 | nv_wr32(dev, 0x610030, 0x80000000); | 938 | nv_wr32(dev, 0x610030, 0x80000000); |
@@ -899,17 +941,17 @@ ack: | |||
899 | static void | 941 | static void |
900 | nv50_display_unk40_handler(struct drm_device *dev) | 942 | nv50_display_unk40_handler(struct drm_device *dev) |
901 | { | 943 | { |
902 | struct dcb_entry *dcbent; | 944 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
903 | int head, pclk, script, ret; | 945 | struct dcb_entry *dcb = dev_priv->evo_irq.dcb; |
946 | u16 script = dev_priv->evo_irq.script; | ||
947 | u32 unk30 = nv_rd32(dev, 0x610030), pclk = dev_priv->evo_irq.pclk; | ||
904 | 948 | ||
905 | ret = nv50_display_irq_head(dev, &head, &dcbent); | 949 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
906 | if (ret) | 950 | dev_priv->evo_irq.dcb = NULL; |
951 | if (!dcb) | ||
907 | goto ack; | 952 | goto ack; |
908 | pclk = nv_rd32(dev, NV50_PDISPLAY_CRTC_P(head, CLOCK)) & 0x3fffff; | ||
909 | script = nv50_display_script_select(dev, dcbent, pclk); | ||
910 | |||
911 | nouveau_bios_run_display_table(dev, dcbent, script, -pclk); | ||
912 | 953 | ||
954 | nouveau_bios_run_display_table(dev, dcb, script, -pclk); | ||
913 | ack: | 955 | ack: |
914 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); | 956 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_CLK_UNK40); |
915 | nv_wr32(dev, 0x610030, 0x80000000); | 957 | nv_wr32(dev, 0x610030, 0x80000000); |