aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hdmi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c221
1 files changed, 136 insertions, 85 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 025be7dd2a27..9ba0aaed7ee8 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -150,6 +150,9 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
150 I915_WRITE(VIDEO_DIP_DATA, *data); 150 I915_WRITE(VIDEO_DIP_DATA, *data);
151 data++; 151 data++;
152 } 152 }
153 /* Write every possible data byte to force correct ECC calculation. */
154 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
155 I915_WRITE(VIDEO_DIP_DATA, 0);
153 mmiowb(); 156 mmiowb();
154 157
155 val |= g4x_infoframe_enable(frame); 158 val |= g4x_infoframe_enable(frame);
@@ -185,6 +188,9 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
185 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); 188 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
186 data++; 189 data++;
187 } 190 }
191 /* Write every possible data byte to force correct ECC calculation. */
192 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
193 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
188 mmiowb(); 194 mmiowb();
189 195
190 val |= g4x_infoframe_enable(frame); 196 val |= g4x_infoframe_enable(frame);
@@ -223,6 +229,9 @@ static void cpt_write_infoframe(struct drm_encoder *encoder,
223 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); 229 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
224 data++; 230 data++;
225 } 231 }
232 /* Write every possible data byte to force correct ECC calculation. */
233 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
234 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
226 mmiowb(); 235 mmiowb();
227 236
228 val |= g4x_infoframe_enable(frame); 237 val |= g4x_infoframe_enable(frame);
@@ -258,6 +267,9 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
258 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data); 267 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
259 data++; 268 data++;
260 } 269 }
270 /* Write every possible data byte to force correct ECC calculation. */
271 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
272 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
261 mmiowb(); 273 mmiowb();
262 274
263 val |= g4x_infoframe_enable(frame); 275 val |= g4x_infoframe_enable(frame);
@@ -291,6 +303,9 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
291 I915_WRITE(data_reg + i, *data); 303 I915_WRITE(data_reg + i, *data);
292 data++; 304 data++;
293 } 305 }
306 /* Write every possible data byte to force correct ECC calculation. */
307 for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
308 I915_WRITE(data_reg + i, 0);
294 mmiowb(); 309 mmiowb();
295 310
296 val |= hsw_infoframe_enable(frame); 311 val |= hsw_infoframe_enable(frame);
@@ -376,6 +391,7 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
376 port = VIDEO_DIP_PORT_C; 391 port = VIDEO_DIP_PORT_C;
377 break; 392 break;
378 default: 393 default:
394 BUG();
379 return; 395 return;
380 } 396 }
381 397
@@ -434,6 +450,7 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
434 port = VIDEO_DIP_PORT_D; 450 port = VIDEO_DIP_PORT_D;
435 break; 451 break;
436 default: 452 default:
453 BUG();
437 return; 454 return;
438 } 455 }
439 456
@@ -600,15 +617,36 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
600 intel_hdmi->set_infoframes(encoder, adjusted_mode); 617 intel_hdmi->set_infoframes(encoder, adjusted_mode);
601} 618}
602 619
603static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) 620static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
621 enum pipe *pipe)
604{ 622{
605 struct drm_device *dev = encoder->dev; 623 struct drm_device *dev = encoder->base.dev;
606 struct drm_i915_private *dev_priv = dev->dev_private; 624 struct drm_i915_private *dev_priv = dev->dev_private;
607 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); 625 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
626 u32 tmp;
627
628 tmp = I915_READ(intel_hdmi->sdvox_reg);
629
630 if (!(tmp & SDVO_ENABLE))
631 return false;
632
633 if (HAS_PCH_CPT(dev))
634 *pipe = PORT_TO_PIPE_CPT(tmp);
635 else
636 *pipe = PORT_TO_PIPE(tmp);
637
638 return true;
639}
640
641static void intel_enable_hdmi(struct intel_encoder *encoder)
642{
643 struct drm_device *dev = encoder->base.dev;
644 struct drm_i915_private *dev_priv = dev->dev_private;
645 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
608 u32 temp; 646 u32 temp;
609 u32 enable_bits = SDVO_ENABLE; 647 u32 enable_bits = SDVO_ENABLE;
610 648
611 if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON) 649 if (intel_hdmi->has_audio)
612 enable_bits |= SDVO_AUDIO_ENABLE; 650 enable_bits |= SDVO_AUDIO_ENABLE;
613 651
614 temp = I915_READ(intel_hdmi->sdvox_reg); 652 temp = I915_READ(intel_hdmi->sdvox_reg);
@@ -616,31 +654,12 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
616 /* HW workaround for IBX, we need to move the port to transcoder A 654 /* HW workaround for IBX, we need to move the port to transcoder A
617 * before disabling it. */ 655 * before disabling it. */
618 if (HAS_PCH_IBX(dev)) { 656 if (HAS_PCH_IBX(dev)) {
619 struct drm_crtc *crtc = encoder->crtc; 657 struct drm_crtc *crtc = encoder->base.crtc;
620 int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; 658 int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
621 659
622 if (mode != DRM_MODE_DPMS_ON) { 660 /* Restore the transcoder select bit. */
623 if (temp & SDVO_PIPE_B_SELECT) { 661 if (pipe == PIPE_B)
624 temp &= ~SDVO_PIPE_B_SELECT; 662 enable_bits |= SDVO_PIPE_B_SELECT;
625 I915_WRITE(intel_hdmi->sdvox_reg, temp);
626 POSTING_READ(intel_hdmi->sdvox_reg);
627
628 /* Again we need to write this twice. */
629 I915_WRITE(intel_hdmi->sdvox_reg, temp);
630 POSTING_READ(intel_hdmi->sdvox_reg);
631
632 /* Transcoder selection bits only update
633 * effectively on vblank. */
634 if (crtc)
635 intel_wait_for_vblank(dev, pipe);
636 else
637 msleep(50);
638 }
639 } else {
640 /* Restore the transcoder select bit. */
641 if (pipe == PIPE_B)
642 enable_bits |= SDVO_PIPE_B_SELECT;
643 }
644 } 663 }
645 664
646 /* HW workaround, need to toggle enable bit off and on for 12bpc, but 665 /* HW workaround, need to toggle enable bit off and on for 12bpc, but
@@ -651,12 +670,64 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
651 POSTING_READ(intel_hdmi->sdvox_reg); 670 POSTING_READ(intel_hdmi->sdvox_reg);
652 } 671 }
653 672
654 if (mode != DRM_MODE_DPMS_ON) { 673 temp |= enable_bits;
655 temp &= ~enable_bits; 674
656 } else { 675 I915_WRITE(intel_hdmi->sdvox_reg, temp);
657 temp |= enable_bits; 676 POSTING_READ(intel_hdmi->sdvox_reg);
677
678 /* HW workaround, need to write this twice for issue that may result
679 * in first write getting masked.
680 */
681 if (HAS_PCH_SPLIT(dev)) {
682 I915_WRITE(intel_hdmi->sdvox_reg, temp);
683 POSTING_READ(intel_hdmi->sdvox_reg);
684 }
685}
686
687static void intel_disable_hdmi(struct intel_encoder *encoder)
688{
689 struct drm_device *dev = encoder->base.dev;
690 struct drm_i915_private *dev_priv = dev->dev_private;
691 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
692 u32 temp;
693 u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE;
694
695 temp = I915_READ(intel_hdmi->sdvox_reg);
696
697 /* HW workaround for IBX, we need to move the port to transcoder A
698 * before disabling it. */
699 if (HAS_PCH_IBX(dev)) {
700 struct drm_crtc *crtc = encoder->base.crtc;
701 int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;
702
703 if (temp & SDVO_PIPE_B_SELECT) {
704 temp &= ~SDVO_PIPE_B_SELECT;
705 I915_WRITE(intel_hdmi->sdvox_reg, temp);
706 POSTING_READ(intel_hdmi->sdvox_reg);
707
708 /* Again we need to write this twice. */
709 I915_WRITE(intel_hdmi->sdvox_reg, temp);
710 POSTING_READ(intel_hdmi->sdvox_reg);
711
712 /* Transcoder selection bits only update
713 * effectively on vblank. */
714 if (crtc)
715 intel_wait_for_vblank(dev, pipe);
716 else
717 msleep(50);
718 }
719 }
720
721 /* HW workaround, need to toggle enable bit off and on for 12bpc, but
722 * we do this anyway which shows more stable in testing.
723 */
724 if (HAS_PCH_SPLIT(dev)) {
725 I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE);
726 POSTING_READ(intel_hdmi->sdvox_reg);
658 } 727 }
659 728
729 temp &= ~enable_bits;
730
660 I915_WRITE(intel_hdmi->sdvox_reg, temp); 731 I915_WRITE(intel_hdmi->sdvox_reg, temp);
661 POSTING_READ(intel_hdmi->sdvox_reg); 732 POSTING_READ(intel_hdmi->sdvox_reg);
662 733
@@ -736,7 +807,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force)
736 drm_detect_hdmi_monitor(edid); 807 drm_detect_hdmi_monitor(edid);
737 intel_hdmi->has_audio = drm_detect_monitor_audio(edid); 808 intel_hdmi->has_audio = drm_detect_monitor_audio(edid);
738 } 809 }
739 connector->display_info.raw_edid = NULL;
740 kfree(edid); 810 kfree(edid);
741 } 811 }
742 812
@@ -777,8 +847,6 @@ intel_hdmi_detect_audio(struct drm_connector *connector)
777 if (edid) { 847 if (edid) {
778 if (edid->input & DRM_EDID_INPUT_DIGITAL) 848 if (edid->input & DRM_EDID_INPUT_DIGITAL)
779 has_audio = drm_detect_monitor_audio(edid); 849 has_audio = drm_detect_monitor_audio(edid);
780
781 connector->display_info.raw_edid = NULL;
782 kfree(edid); 850 kfree(edid);
783 } 851 }
784 852
@@ -832,9 +900,8 @@ intel_hdmi_set_property(struct drm_connector *connector,
832done: 900done:
833 if (intel_hdmi->base.base.crtc) { 901 if (intel_hdmi->base.base.crtc) {
834 struct drm_crtc *crtc = intel_hdmi->base.base.crtc; 902 struct drm_crtc *crtc = intel_hdmi->base.base.crtc;
835 drm_crtc_helper_set_mode(crtc, &crtc->mode, 903 intel_set_mode(crtc, &crtc->mode,
836 crtc->x, crtc->y, 904 crtc->x, crtc->y, crtc->fb);
837 crtc->fb);
838 } 905 }
839 906
840 return 0; 907 return 0;
@@ -848,23 +915,19 @@ static void intel_hdmi_destroy(struct drm_connector *connector)
848} 915}
849 916
850static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = { 917static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = {
851 .dpms = intel_ddi_dpms,
852 .mode_fixup = intel_hdmi_mode_fixup, 918 .mode_fixup = intel_hdmi_mode_fixup,
853 .prepare = intel_encoder_prepare,
854 .mode_set = intel_ddi_mode_set, 919 .mode_set = intel_ddi_mode_set,
855 .commit = intel_encoder_commit, 920 .disable = intel_encoder_noop,
856}; 921};
857 922
858static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { 923static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
859 .dpms = intel_hdmi_dpms,
860 .mode_fixup = intel_hdmi_mode_fixup, 924 .mode_fixup = intel_hdmi_mode_fixup,
861 .prepare = intel_encoder_prepare,
862 .mode_set = intel_hdmi_mode_set, 925 .mode_set = intel_hdmi_mode_set,
863 .commit = intel_encoder_commit, 926 .disable = intel_encoder_noop,
864}; 927};
865 928
866static const struct drm_connector_funcs intel_hdmi_connector_funcs = { 929static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
867 .dpms = drm_helper_connector_dpms, 930 .dpms = intel_connector_dpms,
868 .detect = intel_hdmi_detect, 931 .detect = intel_hdmi_detect,
869 .fill_modes = drm_helper_probe_single_connector_modes, 932 .fill_modes = drm_helper_probe_single_connector_modes,
870 .set_property = intel_hdmi_set_property, 933 .set_property = intel_hdmi_set_property,
@@ -888,7 +951,7 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
888 intel_attach_broadcast_rgb_property(connector); 951 intel_attach_broadcast_rgb_property(connector);
889} 952}
890 953
891void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) 954void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port)
892{ 955{
893 struct drm_i915_private *dev_priv = dev->dev_private; 956 struct drm_i915_private *dev_priv = dev->dev_private;
894 struct drm_connector *connector; 957 struct drm_connector *connector;
@@ -922,48 +985,25 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
922 connector->doublescan_allowed = 0; 985 connector->doublescan_allowed = 0;
923 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); 986 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
924 987
925 /* Set up the DDC bus. */ 988 intel_encoder->cloneable = false;
926 if (sdvox_reg == SDVOB) { 989
927 intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); 990 intel_hdmi->ddi_port = port;
928 intel_hdmi->ddc_bus = GMBUS_PORT_DPB; 991 switch (port) {
929 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; 992 case PORT_B:
930 } else if (sdvox_reg == SDVOC) {
931 intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
932 intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
933 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
934 } else if (sdvox_reg == HDMIB) {
935 intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
936 intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
937 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
938 } else if (sdvox_reg == HDMIC) {
939 intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
940 intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
941 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
942 } else if (sdvox_reg == HDMID) {
943 intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
944 intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
945 dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
946 } else if (sdvox_reg == DDI_BUF_CTL(PORT_B)) {
947 DRM_DEBUG_DRIVER("LPT: detected output on DDI B\n");
948 intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
949 intel_hdmi->ddc_bus = GMBUS_PORT_DPB; 993 intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
950 intel_hdmi->ddi_port = PORT_B;
951 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; 994 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
952 } else if (sdvox_reg == DDI_BUF_CTL(PORT_C)) { 995 break;
953 DRM_DEBUG_DRIVER("LPT: detected output on DDI C\n"); 996 case PORT_C:
954 intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
955 intel_hdmi->ddc_bus = GMBUS_PORT_DPC; 997 intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
956 intel_hdmi->ddi_port = PORT_C;
957 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; 998 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
958 } else if (sdvox_reg == DDI_BUF_CTL(PORT_D)) { 999 break;
959 DRM_DEBUG_DRIVER("LPT: detected output on DDI D\n"); 1000 case PORT_D:
960 intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
961 intel_hdmi->ddc_bus = GMBUS_PORT_DPD; 1001 intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
962 intel_hdmi->ddi_port = PORT_D;
963 dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; 1002 dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
964 } else { 1003 break;
965 /* If we got an unknown sdvox_reg, things are pretty much broken 1004 case PORT_A:
966 * in a way that we should let the kernel know about it */ 1005 /* Internal port only for eDP. */
1006 default:
967 BUG(); 1007 BUG();
968 } 1008 }
969 1009
@@ -986,10 +1026,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
986 intel_hdmi->set_infoframes = cpt_set_infoframes; 1026 intel_hdmi->set_infoframes = cpt_set_infoframes;
987 } 1027 }
988 1028
989 if (IS_HASWELL(dev)) 1029 if (IS_HASWELL(dev)) {
990 drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs_hsw); 1030 intel_encoder->enable = intel_enable_ddi;
991 else 1031 intel_encoder->disable = intel_disable_ddi;
992 drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); 1032 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
1033 drm_encoder_helper_add(&intel_encoder->base,
1034 &intel_hdmi_helper_funcs_hsw);
1035 } else {
1036 intel_encoder->enable = intel_enable_hdmi;
1037 intel_encoder->disable = intel_disable_hdmi;
1038 intel_encoder->get_hw_state = intel_hdmi_get_hw_state;
1039 drm_encoder_helper_add(&intel_encoder->base,
1040 &intel_hdmi_helper_funcs);
1041 }
1042 intel_connector->get_hw_state = intel_connector_get_hw_state;
1043
993 1044
994 intel_hdmi_add_properties(intel_hdmi, connector); 1045 intel_hdmi_add_properties(intel_hdmi, connector);
995 1046