aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_hdmi.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2015-05-05 10:06:20 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-06-15 05:27:59 -0400
commit6d67415f40b1f166212f37ecc9c23b9f380dfebc (patch)
treede375437bc6232f273781acda97d7d251c230817 /drivers/gpu/drm/i915/intel_hdmi.c
parentd1b1589c4800678a8a2beba83845366b2dff5d70 (diff)
drm/i915: Send GCP infoframes for deep color HDMI sinks
GCP infoframes are required to inform the HDMI sink about the color depth. Send the GCP infoframe whenever the sink supports any deep color modes since such sinks must anyway be capable of receiving them. For sinks that don't support deep color let's skip the GCP in case it might confuse the sink, although HDMI 1.4 spec does say all sinks must be capable of reciving them. In theory we could skip the GCP infoframe for deep color sinks in 8bpc mode as well since sinks must fall back to 8bpc whenever GCP isn't received for some time. BSpec says we should disable GCP after disabling the port, so do that as well. v2: s/intel_set_gcp_infoframe/intel_hdmi_set_gcp_infoframe/ Rebased due to crtc->config changes Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> [danvet: Resolve conflict with lack of chv phy patches and fixup typo Chandra spotted.] Reviewed-by: Chandra Konduru <Chandra.konduru@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hdmi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 9ee6176a5f27..a422d83b6efb 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -541,6 +541,66 @@ static void g4x_set_infoframes(struct drm_encoder *encoder,
541 intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode); 541 intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
542} 542}
543 543
544static bool hdmi_sink_is_deep_color(struct drm_encoder *encoder)
545{
546 struct drm_device *dev = encoder->dev;
547 struct drm_connector *connector;
548
549 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
550
551 /*
552 * HDMI cloning is only supported on g4x which doesn't
553 * support deep color or GCP infoframes anyway so no
554 * need to worry about multiple HDMI sinks here.
555 */
556 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
557 if (connector->encoder == encoder)
558 return connector->display_info.bpc > 8;
559
560 return false;
561}
562
563static bool intel_hdmi_set_gcp_infoframe(struct drm_encoder *encoder)
564{
565 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
566 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
567 u32 reg, val = 0;
568
569 if (HAS_DDI(dev_priv))
570 reg = HSW_TVIDEO_DIP_GCP(crtc->config->cpu_transcoder);
571 else if (IS_VALLEYVIEW(dev_priv))
572 reg = VLV_TVIDEO_DIP_GCP(crtc->pipe);
573 else if (HAS_PCH_SPLIT(dev_priv->dev))
574 reg = TVIDEO_DIP_GCP(crtc->pipe);
575 else
576 return false;
577
578 /* Indicate color depth whenever the sink supports deep color */
579 if (hdmi_sink_is_deep_color(encoder))
580 val |= GCP_COLOR_INDICATION;
581
582 I915_WRITE(reg, val);
583
584 return val != 0;
585}
586
587static void intel_disable_gcp_infoframe(struct intel_crtc *crtc)
588{
589 struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
590 u32 reg;
591
592 if (HAS_DDI(dev_priv))
593 reg = HSW_TVIDEO_DIP_CTL(crtc->config->cpu_transcoder);
594 else if (IS_VALLEYVIEW(dev_priv))
595 reg = VLV_TVIDEO_DIP_CTL(crtc->pipe);
596 else if (HAS_PCH_SPLIT(dev_priv->dev))
597 reg = TVIDEO_DIP_CTL(crtc->pipe);
598 else
599 return;
600
601 I915_WRITE(reg, I915_READ(reg) & ~VIDEO_DIP_ENABLE_GCP);
602}
603
544static void ibx_set_infoframes(struct drm_encoder *encoder, 604static void ibx_set_infoframes(struct drm_encoder *encoder,
545 bool enable, 605 bool enable,
546 struct drm_display_mode *adjusted_mode) 606 struct drm_display_mode *adjusted_mode)
@@ -581,6 +641,9 @@ static void ibx_set_infoframes(struct drm_encoder *encoder,
581 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | 641 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
582 VIDEO_DIP_ENABLE_GCP); 642 VIDEO_DIP_ENABLE_GCP);
583 643
644 if (intel_hdmi_set_gcp_infoframe(encoder))
645 val |= VIDEO_DIP_ENABLE_GCP;
646
584 I915_WRITE(reg, val); 647 I915_WRITE(reg, val);
585 POSTING_READ(reg); 648 POSTING_READ(reg);
586 649
@@ -618,6 +681,9 @@ static void cpt_set_infoframes(struct drm_encoder *encoder,
618 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT | 681 val &= ~(VIDEO_DIP_ENABLE_VENDOR | VIDEO_DIP_ENABLE_GAMUT |
619 VIDEO_DIP_ENABLE_GCP); 682 VIDEO_DIP_ENABLE_GCP);
620 683
684 if (intel_hdmi_set_gcp_infoframe(encoder))
685 val |= VIDEO_DIP_ENABLE_GCP;
686
621 I915_WRITE(reg, val); 687 I915_WRITE(reg, val);
622 POSTING_READ(reg); 688 POSTING_READ(reg);
623 689
@@ -666,6 +732,9 @@ static void vlv_set_infoframes(struct drm_encoder *encoder,
666 val &= ~(VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_ENABLE_VENDOR | 732 val &= ~(VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_ENABLE_VENDOR |
667 VIDEO_DIP_ENABLE_GAMUT | VIDEO_DIP_ENABLE_GCP); 733 VIDEO_DIP_ENABLE_GAMUT | VIDEO_DIP_ENABLE_GCP);
668 734
735 if (intel_hdmi_set_gcp_infoframe(encoder))
736 val |= VIDEO_DIP_ENABLE_GCP;
737
669 I915_WRITE(reg, val); 738 I915_WRITE(reg, val);
670 POSTING_READ(reg); 739 POSTING_READ(reg);
671 740
@@ -695,6 +764,9 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
695 val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW | 764 val &= ~(VIDEO_DIP_ENABLE_VSC_HSW | VIDEO_DIP_ENABLE_GCP_HSW |
696 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW); 765 VIDEO_DIP_ENABLE_VS_HSW | VIDEO_DIP_ENABLE_GMP_HSW);
697 766
767 if (intel_hdmi_set_gcp_infoframe(encoder))
768 val |= VIDEO_DIP_ENABLE_GCP_HSW;
769
698 I915_WRITE(reg, val); 770 I915_WRITE(reg, val);
699 POSTING_READ(reg); 771 POSTING_READ(reg);
700 772
@@ -960,6 +1032,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
960 I915_WRITE(intel_hdmi->hdmi_reg, temp); 1032 I915_WRITE(intel_hdmi->hdmi_reg, temp);
961 POSTING_READ(intel_hdmi->hdmi_reg); 1033 POSTING_READ(intel_hdmi->hdmi_reg);
962 } 1034 }
1035
1036 intel_disable_gcp_infoframe(to_intel_crtc(encoder->base.crtc));
963} 1037}
964 1038
965static void g4x_disable_hdmi(struct intel_encoder *encoder) 1039static void g4x_disable_hdmi(struct intel_encoder *encoder)