[v9,2/8] drm/i915/dp: Add support of BT.2020 Colorimetry to DP MSA

Submitted by Mun, Gwan-gyeong on Sept. 19, 2019, 7:53 p.m.

Details

Message ID 20190919195311.13972-3-gwan-gyeong.mun@intel.com
State New
Headers show
Series "drm/i915/dp: Support for DP HDR outputs" ( rev: 9 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Mun, Gwan-gyeong Sept. 19, 2019, 7:53 p.m.
When BT.2020 Colorimetry output is used for DP, we should program BT.2020
Colorimetry to MSA and VSC SDP. In order to handle colorspace of
drm_connector_state, it moves a calling of intel_ddi_set_pipe_settings()
function into intel_ddi_pre_enable_dp(). And it also rename
intel_ddi_set_pipe_settings() to intel_ddi_set_dp_msa().

As per DP 1.4a spec section 2.2.4 [MSA Data Transport]
The MSA data that the DP Source device transports for reproducing the main
video stream. Attribute data is sent once per frame during the main video
stream’s vertical blanking period.

In order to distinguish needed colorimetry for VSC SDP, it adds
intel_dp_needs_vsc_sdp function.
If the output colorspace requires vsc sdp or output format is YCbCr 4:2:0,
it uses MSA with VSC SDP.

As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication of
Color Encoding Format and Content Color Gamut] while sending
BT.2020 Colorimetry signals we should program MSA MISC1 fields which
indicate VSC SDP for the Pixel Encoding/Colorimetry Format.

v2: Remove useless parentheses
v3: Addressed review comments from Ville
    - In order to checking output format and output colorspace on
      intel_dp_needs_vsc_sdp(), it passes entire intel_crtc_state struct
      value.
    - Remove a pointless variable.
v9: Addressed review comments from Ville
    - Remove a duplicated output color space from intel_crtc_state.
    - In order to handle colorspace of drm_connector_state, it moves a
      calling of intel_ddi_set_pipe_settings() function into
      intel_ddi_pre_enable_dp().

Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     | 14 ++++++----
 drivers/gpu/drm/i915/display/intel_ddi.h     |  3 +-
 drivers/gpu/drm/i915/display/intel_display.c |  1 -
 drivers/gpu/drm/i915/display/intel_dp.c      | 29 +++++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_dp.h      |  2 ++
 5 files changed, 41 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 98d69febd8e3..d2a1bfa6a259 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1692,7 +1692,8 @@  static void intel_ddi_clock_get(struct intel_encoder *encoder,
 		hsw_ddi_clock_get(encoder, pipe_config);
 }
 
-void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
+void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
+			  const struct drm_connector_state *conn_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -1737,11 +1738,12 @@  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
 	/*
 	 * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication
 	 * of Color Encoding Format and Content Color Gamut] while sending
-	 * YCBCR 420 signals we should program MSA MISC1 fields which
-	 * indicate VSC SDP for the Pixel Encoding/Colorimetry Format.
+	 * YCBCR 420, HDR BT.2020 signals we should program MSA MISC1 fields
+	 * which indicate VSC SDP for the Pixel Encoding/Colorimetry Format.
 	 */
-	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+	if (intel_dp_needs_vsc_sdp(crtc_state, conn_state))
 		temp |= TRANS_MSA_USE_VSC_SDP;
+
 	I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
 }
 
@@ -3370,6 +3372,8 @@  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
 		tgl_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
 	else
 		hsw_ddi_pre_enable_dp(encoder, crtc_state, conn_state);
+
+	intel_ddi_set_dp_msa(crtc_state, conn_state);
 }
 
 static void intel_ddi_pre_enable_hdmi(struct intel_encoder *encoder,
@@ -3781,7 +3785,7 @@  static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
 {
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 
-	intel_ddi_set_pipe_settings(crtc_state);
+	intel_ddi_set_dp_msa(crtc_state, conn_state);
 
 	intel_psr_update(intel_dp, crtc_state);
 	intel_edp_drrs_enable(intel_dp, crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index a08365da2643..19aeab1246ee 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -30,7 +30,8 @@  void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
 void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state);
 void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state);
 void intel_ddi_disable_pipe_clock(const  struct intel_crtc_state *crtc_state);
-void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state);
+void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state,
+			  const struct drm_connector_state *conn_state);
 bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector);
 void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index fbbf14c5bee8..cf3da329394f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6527,7 +6527,6 @@  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_set_pipe_chicken(intel_crtc);
 
-	intel_ddi_set_pipe_settings(pipe_config);
 	if (!transcoder_is_dsi(cpu_transcoder))
 		intel_ddi_enable_transcoder_func(pipe_config);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 9023609c5dcb..f13892deafbb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2187,6 +2187,7 @@  intel_dp_compute_config(struct intel_encoder *encoder,
 		pipe_config->has_pch_encoder = true;
 
 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+
 	if (lspcon->active)
 		lspcon_ycbcr420_config(&intel_connector->base, pipe_config);
 	else
@@ -4448,6 +4449,32 @@  u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
 	return 0;
 }
 
+bool
+intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
+		       const struct drm_connector_state *conn_state)
+{
+	/*
+	 * As per DP 1.4a spec section 2.2.4.3 [MSA Field for Indication
+	 * of Color Encoding Format and Content Color Gamut], in order to
+	 * sending YCBCR 420 or HDR BT.2020 signals we should use DP VSC SDP.
+	 */
+	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+		return true;
+
+	switch (conn_state->colorspace) {
+	case DRM_MODE_COLORIMETRY_SYCC_601:
+	case DRM_MODE_COLORIMETRY_OPYCC_601:
+	case DRM_MODE_COLORIMETRY_BT2020_YCC:
+	case DRM_MODE_COLORIMETRY_BT2020_RGB:
+	case DRM_MODE_COLORIMETRY_BT2020_CYCC:
+		return true;
+	default:
+		break;
+	}
+
+	return false;
+}
+
 static void
 intel_dp_setup_vsc_sdp(struct intel_dp *intel_dp,
 		       const struct intel_crtc_state *crtc_state,
@@ -4576,7 +4603,7 @@  void intel_dp_vsc_enable(struct intel_dp *intel_dp,
 			 const struct intel_crtc_state *crtc_state,
 			 const struct drm_connector_state *conn_state)
 {
-	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_YCBCR420)
+	if (!intel_dp_needs_vsc_sdp(crtc_state, conn_state))
 		return;
 
 	intel_dp_setup_vsc_sdp(intel_dp, crtc_state, conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index be13cb395ef8..d1197ed09cfc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -112,6 +112,8 @@  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
 int intel_dp_link_required(int pixel_clock, int bpp);
 int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
+bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
+			    const struct drm_connector_state *conn_state);
 void intel_dp_vsc_enable(struct intel_dp *intel_dp,
 			 const struct intel_crtc_state *crtc_state,
 			 const struct drm_connector_state *conn_state);