[v5 10/10] drm/i915/lspcon: Create separate infoframe_enabled helper for lspcon

Uma Shankar uma.shankar at intel.com
Wed Jun 17 21:43:35 UTC 2020


Lspcon has Infoframes as well as DIP for HDR metadata(DRM Infoframe).
Create a separate mechanism for lspcon compared to HDMI in order to
address the same.

Suggested-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Signed-off-by: Uma Shankar <uma.shankar at intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c    | 10 ++--
 drivers/gpu/drm/i915/display/intel_hdmi.h   |  2 +
 drivers/gpu/drm/i915/display/intel_lspcon.c | 54 ++++++++++++++++++---
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 1d7b91f823d9..8f3888274358 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4191,6 +4191,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 	u32 temp, flags = 0;
 
 	/* XXX: DSI transcoder paranoia */
@@ -4281,9 +4282,12 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 				    pipe_config->fec_enable);
 		}
 
-		pipe_config->infoframes.enable |=
-			intel_hdmi_infoframes_enabled(encoder, pipe_config);
-
+		if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
+			pipe_config->infoframes.enable |=
+				intel_lspcon_infoframes_enabled(encoder, pipe_config);
+		else
+			pipe_config->infoframes.enable |=
+				intel_hdmi_infoframes_enabled(encoder, pipe_config);
 		break;
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h
index 8ff1f76a63df..c89b03e336a1 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.h
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
@@ -39,6 +39,8 @@ void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
 void intel_infoframe_init(struct intel_digital_port *intel_dig_port);
 u32 intel_hdmi_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state);
+u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder,
+				    const struct intel_crtc_state *crtc_state);
 u32 intel_hdmi_infoframe_enable(unsigned int type);
 void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
 				   struct intel_crtc_state *crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index 8d1bd2da1e73..300992ef92b8 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -623,8 +623,8 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder,
 	struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	bool infoframes_enabled;
-	u32 mask = 0;
-	u32 val;
+	u32 val = 0;
+	u32 mask, tmp;
 
 	if (lspcon->vendor == LSPCON_VENDOR_MCA)
 		infoframes_enabled = _lspcon_read_avi_infoframe_enabled_mca(&intel_dp->aux);
@@ -632,18 +632,56 @@ u32 lspcon_infoframes_enabled(struct intel_encoder *encoder,
 		infoframes_enabled = _lspcon_read_avi_infoframe_enabled_parade(&intel_dp->aux);
 
 	if (infoframes_enabled)
-		return true;
+		val |= VIDEO_DIP_ENABLE_AVI_HSW;
 
 	if (lspcon->hdr_supported) {
-		val = intel_de_read(dev_priv,
+		tmp = intel_de_read(dev_priv,
 				    HSW_TVIDEO_DIP_CTL(pipe_config->cpu_transcoder));
-		mask |= VIDEO_DIP_ENABLE_GMP_HSW;
+		mask = VIDEO_DIP_ENABLE_GMP_HSW;
 
-		if (val & mask)
-			return val & mask;
+		if (tmp & mask)
+			val |= mask;
 	}
 
-	return false;
+	return val;
+}
+
+static const u8 lspcon_infoframe_type_to_idx[] = {
+	HDMI_PACKET_TYPE_GAMUT_METADATA,
+	HDMI_INFOFRAME_TYPE_AVI,
+};
+
+static u32 lspcon_infoframe_enable(unsigned int type)
+{
+	switch (type) {
+	case HDMI_PACKET_TYPE_GAMUT_METADATA:
+		return VIDEO_DIP_ENABLE_GMP_HSW;
+	case HDMI_INFOFRAME_TYPE_AVI:
+		return VIDEO_DIP_ENABLE_AVI_HSW;
+	default:
+		MISSING_CASE(type);
+		return 0;
+	}
+}
+
+u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder,
+				    const struct intel_crtc_state *crtc_state)
+{
+	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+	u32 val, ret = 0;
+	int i;
+
+	val = dig_port->infoframes_enabled(encoder, crtc_state);
+
+	/* map from hardware bits to dip idx */
+	for (i = 0; i < ARRAY_SIZE(lspcon_infoframe_type_to_idx); i++) {
+		unsigned int type = lspcon_infoframe_type_to_idx[i];
+
+		if (val & lspcon_infoframe_enable(type))
+			ret |= BIT(i);
+	}
+
+	return ret;
 }
 
 void lspcon_resume(struct intel_lspcon *lspcon)
-- 
2.22.0



More information about the Intel-gfx-trybot mailing list