diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_encoders.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 354 |
1 files changed, 239 insertions, 115 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 3c91724457ca..bc926ea0a530 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -53,7 +53,7 @@ static uint32_t radeon_encoder_clones(struct drm_encoder *encoder) | |||
53 | /* DVO requires 2x ppll clocks depending on tmds chip */ | 53 | /* DVO requires 2x ppll clocks depending on tmds chip */ |
54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) | 54 | if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT) |
55 | return index_mask; | 55 | return index_mask; |
56 | 56 | ||
57 | count = -1; | 57 | count = -1; |
58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { | 58 | list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) { |
59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); | 59 | struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder); |
@@ -228,6 +228,32 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
228 | return NULL; | 228 | return NULL; |
229 | } | 229 | } |
230 | 230 | ||
231 | static struct radeon_connector_atom_dig * | ||
232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) | ||
233 | { | ||
234 | struct drm_device *dev = encoder->dev; | ||
235 | struct radeon_device *rdev = dev->dev_private; | ||
236 | struct drm_connector *connector; | ||
237 | struct radeon_connector *radeon_connector; | ||
238 | struct radeon_connector_atom_dig *dig_connector; | ||
239 | |||
240 | if (!rdev->is_atom_bios) | ||
241 | return NULL; | ||
242 | |||
243 | connector = radeon_get_connector_for_encoder(encoder); | ||
244 | if (!connector) | ||
245 | return NULL; | ||
246 | |||
247 | radeon_connector = to_radeon_connector(connector); | ||
248 | |||
249 | if (!radeon_connector->con_priv) | ||
250 | return NULL; | ||
251 | |||
252 | dig_connector = radeon_connector->con_priv; | ||
253 | |||
254 | return dig_connector; | ||
255 | } | ||
256 | |||
231 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 257 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
232 | struct drm_display_mode *mode, | 258 | struct drm_display_mode *mode, |
233 | struct drm_display_mode *adjusted_mode) | 259 | struct drm_display_mode *adjusted_mode) |
@@ -236,6 +262,9 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | |||
236 | struct drm_device *dev = encoder->dev; | 262 | struct drm_device *dev = encoder->dev; |
237 | struct radeon_device *rdev = dev->dev_private; | 263 | struct radeon_device *rdev = dev->dev_private; |
238 | 264 | ||
265 | /* adjust pm to upcoming mode change */ | ||
266 | radeon_pm_compute_clocks(rdev); | ||
267 | |||
239 | /* set the active encoder to connector routing */ | 268 | /* set the active encoder to connector routing */ |
240 | radeon_encoder_set_active_device(encoder); | 269 | radeon_encoder_set_active_device(encoder); |
241 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 270 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
@@ -458,34 +487,20 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
458 | struct drm_device *dev = encoder->dev; | 487 | struct drm_device *dev = encoder->dev; |
459 | struct radeon_device *rdev = dev->dev_private; | 488 | struct radeon_device *rdev = dev->dev_private; |
460 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 489 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
490 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
491 | struct radeon_connector_atom_dig *dig_connector = | ||
492 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
461 | union lvds_encoder_control args; | 493 | union lvds_encoder_control args; |
462 | int index = 0; | 494 | int index = 0; |
463 | int hdmi_detected = 0; | 495 | int hdmi_detected = 0; |
464 | uint8_t frev, crev; | 496 | uint8_t frev, crev; |
465 | struct radeon_encoder_atom_dig *dig; | ||
466 | struct drm_connector *connector; | ||
467 | struct radeon_connector *radeon_connector; | ||
468 | struct radeon_connector_atom_dig *dig_connector; | ||
469 | 497 | ||
470 | connector = radeon_get_connector_for_encoder(encoder); | 498 | if (!dig || !dig_connector) |
471 | if (!connector) | ||
472 | return; | 499 | return; |
473 | 500 | ||
474 | radeon_connector = to_radeon_connector(connector); | 501 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
475 | |||
476 | if (!radeon_encoder->enc_priv) | ||
477 | return; | ||
478 | |||
479 | dig = radeon_encoder->enc_priv; | ||
480 | |||
481 | if (!radeon_connector->con_priv) | ||
482 | return; | ||
483 | |||
484 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | ||
485 | hdmi_detected = 1; | 502 | hdmi_detected = 1; |
486 | 503 | ||
487 | dig_connector = radeon_connector->con_priv; | ||
488 | |||
489 | memset(&args, 0, sizeof(args)); | 504 | memset(&args, 0, sizeof(args)); |
490 | 505 | ||
491 | switch (radeon_encoder->encoder_id) { | 506 | switch (radeon_encoder->encoder_id) { |
@@ -586,7 +601,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
586 | { | 601 | { |
587 | struct drm_connector *connector; | 602 | struct drm_connector *connector; |
588 | struct radeon_connector *radeon_connector; | 603 | struct radeon_connector *radeon_connector; |
589 | struct radeon_connector_atom_dig *radeon_dig_connector; | 604 | struct radeon_connector_atom_dig *dig_connector; |
590 | 605 | ||
591 | connector = radeon_get_connector_for_encoder(encoder); | 606 | connector = radeon_get_connector_for_encoder(encoder); |
592 | if (!connector) | 607 | if (!connector) |
@@ -617,9 +632,9 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
617 | break; | 632 | break; |
618 | case DRM_MODE_CONNECTOR_DisplayPort: | 633 | case DRM_MODE_CONNECTOR_DisplayPort: |
619 | case DRM_MODE_CONNECTOR_eDP: | 634 | case DRM_MODE_CONNECTOR_eDP: |
620 | radeon_dig_connector = radeon_connector->con_priv; | 635 | dig_connector = radeon_connector->con_priv; |
621 | if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 636 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
622 | (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 637 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
623 | return ATOM_ENCODER_MODE_DP; | 638 | return ATOM_ENCODER_MODE_DP; |
624 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 639 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) |
625 | return ATOM_ENCODER_MODE_HDMI; | 640 | return ATOM_ENCODER_MODE_HDMI; |
@@ -656,6 +671,18 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
656 | * - 2 DIG encoder blocks. | 671 | * - 2 DIG encoder blocks. |
657 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B | 672 | * DIG1/2 can drive UNIPHY0/1/2 link A or link B |
658 | * | 673 | * |
674 | * DCE 4.0 | ||
675 | * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). | ||
676 | * Supports up to 6 digital outputs | ||
677 | * - 6 DIG encoder blocks. | ||
678 | * - DIG to PHY mapping is hardcoded | ||
679 | * DIG1 drives UNIPHY0 link A, A+B | ||
680 | * DIG2 drives UNIPHY0 link B | ||
681 | * DIG3 drives UNIPHY1 link A, A+B | ||
682 | * DIG4 drives UNIPHY1 link B | ||
683 | * DIG5 drives UNIPHY2 link A, A+B | ||
684 | * DIG6 drives UNIPHY2 link B | ||
685 | * | ||
659 | * Routing | 686 | * Routing |
660 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) | 687 | * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) |
661 | * Examples: | 688 | * Examples: |
@@ -664,88 +691,78 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
664 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS | 691 | * crtc0 -> dig1 -> UNIPHY2 link A -> LVDS |
665 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI | 692 | * crtc1 -> dig2 -> UNIPHY1 link B+A -> TMDS/HDMI |
666 | */ | 693 | */ |
667 | static void | 694 | |
695 | union dig_encoder_control { | ||
696 | DIG_ENCODER_CONTROL_PS_ALLOCATION v1; | ||
697 | DIG_ENCODER_CONTROL_PARAMETERS_V2 v2; | ||
698 | DIG_ENCODER_CONTROL_PARAMETERS_V3 v3; | ||
699 | }; | ||
700 | |||
701 | void | ||
668 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | 702 | atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) |
669 | { | 703 | { |
670 | struct drm_device *dev = encoder->dev; | 704 | struct drm_device *dev = encoder->dev; |
671 | struct radeon_device *rdev = dev->dev_private; | 705 | struct radeon_device *rdev = dev->dev_private; |
672 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 706 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
673 | DIG_ENCODER_CONTROL_PS_ALLOCATION args; | 707 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
708 | struct radeon_connector_atom_dig *dig_connector = | ||
709 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
710 | union dig_encoder_control args; | ||
674 | int index = 0, num = 0; | 711 | int index = 0, num = 0; |
675 | uint8_t frev, crev; | 712 | uint8_t frev, crev; |
676 | struct radeon_encoder_atom_dig *dig; | ||
677 | struct drm_connector *connector; | ||
678 | struct radeon_connector *radeon_connector; | ||
679 | struct radeon_connector_atom_dig *dig_connector; | ||
680 | 713 | ||
681 | connector = radeon_get_connector_for_encoder(encoder); | 714 | if (!dig || !dig_connector) |
682 | if (!connector) | ||
683 | return; | 715 | return; |
684 | 716 | ||
685 | radeon_connector = to_radeon_connector(connector); | ||
686 | |||
687 | if (!radeon_connector->con_priv) | ||
688 | return; | ||
689 | |||
690 | dig_connector = radeon_connector->con_priv; | ||
691 | |||
692 | if (!radeon_encoder->enc_priv) | ||
693 | return; | ||
694 | |||
695 | dig = radeon_encoder->enc_priv; | ||
696 | |||
697 | memset(&args, 0, sizeof(args)); | 717 | memset(&args, 0, sizeof(args)); |
698 | 718 | ||
699 | if (dig->dig_encoder) | 719 | if (ASIC_IS_DCE4(rdev)) |
700 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | 720 | index = GetIndexIntoMasterTable(COMMAND, DIGxEncoderControl); |
701 | else | 721 | else { |
702 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | 722 | if (dig->dig_encoder) |
723 | index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl); | ||
724 | else | ||
725 | index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl); | ||
726 | } | ||
703 | num = dig->dig_encoder + 1; | 727 | num = dig->dig_encoder + 1; |
704 | 728 | ||
705 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); | 729 | atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev); |
706 | 730 | ||
707 | args.ucAction = action; | 731 | args.v1.ucAction = action; |
708 | args.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 732 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
733 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
709 | 734 | ||
710 | if (ASIC_IS_DCE32(rdev)) { | 735 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
736 | if (dig_connector->dp_clock == 270000) | ||
737 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
738 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | ||
739 | } else if (radeon_encoder->pixel_clock > 165000) | ||
740 | args.v1.ucLaneNum = 8; | ||
741 | else | ||
742 | args.v1.ucLaneNum = 4; | ||
743 | |||
744 | if (ASIC_IS_DCE4(rdev)) { | ||
745 | args.v3.acConfig.ucDigSel = dig->dig_encoder; | ||
746 | args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR; | ||
747 | } else { | ||
711 | switch (radeon_encoder->encoder_id) { | 748 | switch (radeon_encoder->encoder_id) { |
712 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 749 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
713 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; | 750 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1; |
714 | break; | 751 | break; |
715 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 752 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
716 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | 753 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
754 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2; | ||
717 | break; | 755 | break; |
718 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 756 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
719 | args.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 757 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
720 | break; | ||
721 | } | ||
722 | } else { | ||
723 | switch (radeon_encoder->encoder_id) { | ||
724 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
725 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1; | ||
726 | break; | ||
727 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
728 | args.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2; | ||
729 | break; | 758 | break; |
730 | } | 759 | } |
760 | if (dig_connector->linkb) | ||
761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
762 | else | ||
763 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
731 | } | 764 | } |
732 | 765 | ||
733 | args.ucEncoderMode = atombios_get_encoder_mode(encoder); | ||
734 | |||
735 | if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | ||
736 | if (dig_connector->dp_clock == 270000) | ||
737 | args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | ||
738 | args.ucLaneNum = dig_connector->dp_lane_count; | ||
739 | } else if (radeon_encoder->pixel_clock > 165000) | ||
740 | args.ucLaneNum = 8; | ||
741 | else | ||
742 | args.ucLaneNum = 4; | ||
743 | |||
744 | if (dig_connector->linkb) | ||
745 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | ||
746 | else | ||
747 | args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | ||
748 | |||
749 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 766 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
750 | 767 | ||
751 | } | 768 | } |
@@ -753,6 +770,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
753 | union dig_transmitter_control { | 770 | union dig_transmitter_control { |
754 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; | 771 | DIG_TRANSMITTER_CONTROL_PS_ALLOCATION v1; |
755 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; | 772 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V2 v2; |
773 | DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 v3; | ||
756 | }; | 774 | }; |
757 | 775 | ||
758 | void | 776 | void |
@@ -761,37 +779,29 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
761 | struct drm_device *dev = encoder->dev; | 779 | struct drm_device *dev = encoder->dev; |
762 | struct radeon_device *rdev = dev->dev_private; | 780 | struct radeon_device *rdev = dev->dev_private; |
763 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 781 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
782 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
783 | struct radeon_connector_atom_dig *dig_connector = | ||
784 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
785 | struct drm_connector *connector; | ||
786 | struct radeon_connector *radeon_connector; | ||
764 | union dig_transmitter_control args; | 787 | union dig_transmitter_control args; |
765 | int index = 0, num = 0; | 788 | int index = 0, num = 0; |
766 | uint8_t frev, crev; | 789 | uint8_t frev, crev; |
767 | struct radeon_encoder_atom_dig *dig; | ||
768 | struct drm_connector *connector; | ||
769 | struct radeon_connector *radeon_connector; | ||
770 | struct radeon_connector_atom_dig *dig_connector; | ||
771 | bool is_dp = false; | 790 | bool is_dp = false; |
791 | int pll_id = 0; | ||
772 | 792 | ||
773 | connector = radeon_get_connector_for_encoder(encoder); | 793 | if (!dig || !dig_connector) |
774 | if (!connector) | ||
775 | return; | 794 | return; |
776 | 795 | ||
796 | connector = radeon_get_connector_for_encoder(encoder); | ||
777 | radeon_connector = to_radeon_connector(connector); | 797 | radeon_connector = to_radeon_connector(connector); |
778 | 798 | ||
779 | if (!radeon_encoder->enc_priv) | ||
780 | return; | ||
781 | |||
782 | dig = radeon_encoder->enc_priv; | ||
783 | |||
784 | if (!radeon_connector->con_priv) | ||
785 | return; | ||
786 | |||
787 | dig_connector = radeon_connector->con_priv; | ||
788 | |||
789 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | 799 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
790 | is_dp = true; | 800 | is_dp = true; |
791 | 801 | ||
792 | memset(&args, 0, sizeof(args)); | 802 | memset(&args, 0, sizeof(args)); |
793 | 803 | ||
794 | if (ASIC_IS_DCE32(rdev)) | 804 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) |
795 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 805 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
796 | else { | 806 | else { |
797 | switch (radeon_encoder->encoder_id) { | 807 | switch (radeon_encoder->encoder_id) { |
@@ -821,7 +831,54 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
821 | else | 831 | else |
822 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 832 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
823 | } | 833 | } |
824 | if (ASIC_IS_DCE32(rdev)) { | 834 | if (ASIC_IS_DCE4(rdev)) { |
835 | if (is_dp) | ||
836 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | ||
837 | else if (radeon_encoder->pixel_clock > 165000) | ||
838 | args.v3.ucLaneNum = 8; | ||
839 | else | ||
840 | args.v3.ucLaneNum = 4; | ||
841 | |||
842 | if (dig_connector->linkb) { | ||
843 | args.v3.acConfig.ucLinkSel = 1; | ||
844 | args.v3.acConfig.ucEncoderSel = 1; | ||
845 | } | ||
846 | |||
847 | /* Select the PLL for the PHY | ||
848 | * DP PHY should be clocked from external src if there is | ||
849 | * one. | ||
850 | */ | ||
851 | if (encoder->crtc) { | ||
852 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
853 | pll_id = radeon_crtc->pll_id; | ||
854 | } | ||
855 | if (is_dp && rdev->clock.dp_extclk) | ||
856 | args.v3.acConfig.ucRefClkSource = 2; /* external src */ | ||
857 | else | ||
858 | args.v3.acConfig.ucRefClkSource = pll_id; | ||
859 | |||
860 | switch (radeon_encoder->encoder_id) { | ||
861 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
862 | args.v3.acConfig.ucTransmitterSel = 0; | ||
863 | num = 0; | ||
864 | break; | ||
865 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
866 | args.v3.acConfig.ucTransmitterSel = 1; | ||
867 | num = 1; | ||
868 | break; | ||
869 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
870 | args.v3.acConfig.ucTransmitterSel = 2; | ||
871 | num = 2; | ||
872 | break; | ||
873 | } | ||
874 | |||
875 | if (is_dp) | ||
876 | args.v3.acConfig.fCoherentMode = 1; /* DP requires coherent */ | ||
877 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | ||
878 | if (dig->coherent_mode) | ||
879 | args.v3.acConfig.fCoherentMode = 1; | ||
880 | } | ||
881 | } else if (ASIC_IS_DCE32(rdev)) { | ||
825 | if (dig->dig_encoder == 1) | 882 | if (dig->dig_encoder == 1) |
826 | args.v2.acConfig.ucEncoderSel = 1; | 883 | args.v2.acConfig.ucEncoderSel = 1; |
827 | if (dig_connector->linkb) | 884 | if (dig_connector->linkb) |
@@ -849,7 +906,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
849 | args.v2.acConfig.fCoherentMode = 1; | 906 | args.v2.acConfig.fCoherentMode = 1; |
850 | } | 907 | } |
851 | } else { | 908 | } else { |
852 | |||
853 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; | 909 | args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL; |
854 | 910 | ||
855 | if (dig->dig_encoder) | 911 | if (dig->dig_encoder) |
@@ -1024,9 +1080,12 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1024 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 1080 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
1025 | } | 1081 | } |
1026 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); | 1082 | radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); |
1083 | |||
1084 | /* adjust pm to dpms change */ | ||
1085 | radeon_pm_compute_clocks(rdev); | ||
1027 | } | 1086 | } |
1028 | 1087 | ||
1029 | union crtc_sourc_param { | 1088 | union crtc_source_param { |
1030 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; | 1089 | SELECT_CRTC_SOURCE_PS_ALLOCATION v1; |
1031 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; | 1090 | SELECT_CRTC_SOURCE_PARAMETERS_V2 v2; |
1032 | }; | 1091 | }; |
@@ -1038,7 +1097,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1038 | struct radeon_device *rdev = dev->dev_private; | 1097 | struct radeon_device *rdev = dev->dev_private; |
1039 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1098 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1040 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1099 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1041 | union crtc_sourc_param args; | 1100 | union crtc_source_param args; |
1042 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); | 1101 | int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source); |
1043 | uint8_t frev, crev; | 1102 | uint8_t frev, crev; |
1044 | struct radeon_encoder_atom_dig *dig; | 1103 | struct radeon_encoder_atom_dig *dig; |
@@ -1107,10 +1166,26 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) | |||
1107 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1166 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1108 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1167 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1109 | dig = radeon_encoder->enc_priv; | 1168 | dig = radeon_encoder->enc_priv; |
1110 | if (dig->dig_encoder) | 1169 | switch (dig->dig_encoder) { |
1111 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | 1170 | case 0: |
1112 | else | ||
1113 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; | 1171 | args.v2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID; |
1172 | break; | ||
1173 | case 1: | ||
1174 | args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; | ||
1175 | break; | ||
1176 | case 2: | ||
1177 | args.v2.ucEncoderID = ASIC_INT_DIG3_ENCODER_ID; | ||
1178 | break; | ||
1179 | case 3: | ||
1180 | args.v2.ucEncoderID = ASIC_INT_DIG4_ENCODER_ID; | ||
1181 | break; | ||
1182 | case 4: | ||
1183 | args.v2.ucEncoderID = ASIC_INT_DIG5_ENCODER_ID; | ||
1184 | break; | ||
1185 | case 5: | ||
1186 | args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID; | ||
1187 | break; | ||
1188 | } | ||
1114 | break; | 1189 | break; |
1115 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | 1190 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
1116 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; | 1191 | args.v2.ucEncoderID = ASIC_INT_DVO_ENCODER_ID; |
@@ -1167,6 +1242,7 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, | |||
1167 | } | 1242 | } |
1168 | 1243 | ||
1169 | /* set scaler clears this on some chips */ | 1244 | /* set scaler clears this on some chips */ |
1245 | /* XXX check DCE4 */ | ||
1170 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { | 1246 | if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { |
1171 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) | 1247 | if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) |
1172 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, | 1248 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, |
@@ -1183,6 +1259,33 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1183 | struct drm_encoder *test_encoder; | 1259 | struct drm_encoder *test_encoder; |
1184 | struct radeon_encoder_atom_dig *dig; | 1260 | struct radeon_encoder_atom_dig *dig; |
1185 | uint32_t dig_enc_in_use = 0; | 1261 | uint32_t dig_enc_in_use = 0; |
1262 | |||
1263 | if (ASIC_IS_DCE4(rdev)) { | ||
1264 | struct radeon_connector_atom_dig *dig_connector = | ||
1265 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1266 | |||
1267 | switch (radeon_encoder->encoder_id) { | ||
1268 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
1269 | if (dig_connector->linkb) | ||
1270 | return 1; | ||
1271 | else | ||
1272 | return 0; | ||
1273 | break; | ||
1274 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1275 | if (dig_connector->linkb) | ||
1276 | return 3; | ||
1277 | else | ||
1278 | return 2; | ||
1279 | break; | ||
1280 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1281 | if (dig_connector->linkb) | ||
1282 | return 5; | ||
1283 | else | ||
1284 | return 4; | ||
1285 | break; | ||
1286 | } | ||
1287 | } | ||
1288 | |||
1186 | /* on DCE32 and encoder can driver any block so just crtc id */ | 1289 | /* on DCE32 and encoder can driver any block so just crtc id */ |
1187 | if (ASIC_IS_DCE32(rdev)) { | 1290 | if (ASIC_IS_DCE32(rdev)) { |
1188 | return radeon_crtc->crtc_id; | 1291 | return radeon_crtc->crtc_id; |
@@ -1254,15 +1357,26 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1254 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1357 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1255 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1358 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1256 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1359 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1257 | /* disable the encoder and transmitter */ | 1360 | if (ASIC_IS_DCE4(rdev)) { |
1258 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1361 | /* disable the transmitter */ |
1259 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | 1362 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1260 | 1363 | /* setup and enable the encoder */ | |
1261 | /* setup and enable the encoder and transmitter */ | 1364 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP); |
1262 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | 1365 | |
1263 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | 1366 | /* init and enable the transmitter */ |
1264 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | 1367 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); |
1265 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1368 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1369 | } else { | ||
1370 | /* disable the encoder and transmitter */ | ||
1371 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1372 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE); | ||
1373 | |||
1374 | /* setup and enable the encoder and transmitter */ | ||
1375 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE); | ||
1376 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0); | ||
1377 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1378 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1379 | } | ||
1266 | break; | 1380 | break; |
1267 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1381 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1268 | atombios_ddia_setup(encoder, ATOM_ENABLE); | 1382 | atombios_ddia_setup(encoder, ATOM_ENABLE); |
@@ -1282,7 +1396,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1282 | } | 1396 | } |
1283 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1397 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
1284 | 1398 | ||
1285 | r600_hdmi_setmode(encoder, adjusted_mode); | 1399 | /* XXX */ |
1400 | if (!ASIC_IS_DCE4(rdev)) | ||
1401 | r600_hdmi_setmode(encoder, adjusted_mode); | ||
1286 | } | 1402 | } |
1287 | 1403 | ||
1288 | static bool | 1404 | static bool |
@@ -1480,10 +1596,18 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1480 | return; | 1596 | return; |
1481 | 1597 | ||
1482 | encoder = &radeon_encoder->base; | 1598 | encoder = &radeon_encoder->base; |
1483 | if (rdev->flags & RADEON_SINGLE_CRTC) | 1599 | switch (rdev->num_crtc) { |
1600 | case 1: | ||
1484 | encoder->possible_crtcs = 0x1; | 1601 | encoder->possible_crtcs = 0x1; |
1485 | else | 1602 | break; |
1603 | case 2: | ||
1604 | default: | ||
1486 | encoder->possible_crtcs = 0x3; | 1605 | encoder->possible_crtcs = 0x3; |
1606 | break; | ||
1607 | case 6: | ||
1608 | encoder->possible_crtcs = 0x3f; | ||
1609 | break; | ||
1610 | } | ||
1487 | 1611 | ||
1488 | radeon_encoder->enc_priv = NULL; | 1612 | radeon_encoder->enc_priv = NULL; |
1489 | 1613 | ||