[v2,4/6] drm/i915/display: Set HDR Infoframe for HDR capable LSPCON devices
diff mbox series

Message ID 20191022143404.30442-5-uma.shankar@intel.com
State New
Headers show
Series
  • Enable HDR on MCA LSPCON based Gen9 devices
Related show

Commit Message

Shankar, Uma Oct. 22, 2019, 2:34 p.m. UTC
Send Dynamic Range and Mastering Infoframe (DRM for HDR metadata)
as SDP packet to LSPCON following the DP spec. LSPCON receives the
same and sends it to HDMI sink.

v2: Suppressed some warnings. No functional change.

Signed-off-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/gpu/drm/drm_atomic_state_helper.c   | 1 +
 drivers/gpu/drm/drm_atomic_uapi.c           | 1 +
 drivers/gpu/drm/i915/display/intel_ddi.c    | 8 ++++++++
 drivers/gpu/drm/i915/display/intel_dp.c     | 2 +-
 drivers/gpu/drm/i915/display/intel_lspcon.h | 4 ++++
 include/drm/drm_connector.h                 | 1 +
 6 files changed, 16 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index d0a937fb0c56..e78b3a1626fd 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -416,6 +416,7 @@  __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
 
 	if (state->hdr_output_metadata)
 		drm_property_blob_get(state->hdr_output_metadata);
+	state->hdr_metadata_changed = false;
 
 	/* Don't copy over a writeback job, they are used only once */
 	state->writeback_job = NULL;
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 0d466d3b0809..5beabcd42d30 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -734,6 +734,7 @@  static int drm_atomic_connector_set_property(struct drm_connector *connector,
 				val,
 				sizeof(struct hdr_output_metadata), -1,
 				&replaced);
+		state->hdr_metadata_changed |= replaced;
 		return ret;
 	} else if (property == config->aspect_ratio_property) {
 		state->picture_aspect_ratio = val;
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 9ba794cb9b4f..dee3a593564c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3851,6 +3851,8 @@  static void intel_enable_ddi_dp(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+	struct intel_lspcon *lspcon =
+				enc_to_intel_lspcon(&encoder->base);
 	enum port port = encoder->port;
 
 	if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
@@ -3860,6 +3862,12 @@  static void intel_enable_ddi_dp(struct intel_encoder *encoder,
 	intel_psr_enable(intel_dp, crtc_state);
 	intel_dp_vsc_enable(intel_dp, crtc_state, conn_state);
 	intel_dp_hdr_metadata_enable(intel_dp, crtc_state, conn_state);
+
+	/* Set the infoframe for NON modeset cases as well */
+	if (lspcon->active && lspcon->hdr_supported &&
+	    conn_state->hdr_metadata_changed)
+		intel_dp_setup_hdr_metadata_infoframe_sdp(intel_dp, crtc_state,
+							  conn_state);
 	intel_edp_drrs_enable(intel_dp, crtc_state);
 
 	if (crtc_state->has_audio)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5eeafa45831a..cc616fd31d8b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4651,7 +4651,7 @@  intel_dp_setup_vsc_sdp(struct intel_dp *intel_dp,
 			crtc_state, DP_SDP_VSC, &vsc_sdp, sizeof(vsc_sdp));
 }
 
-static void
+void
 intel_dp_setup_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
 					  const struct intel_crtc_state *crtc_state,
 					  const struct drm_connector_state *conn_state)
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.h b/drivers/gpu/drm/i915/display/intel_lspcon.h
index 65878904f672..3404cff8c337 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.h
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.h
@@ -14,6 +14,7 @@  struct intel_crtc_state;
 struct intel_digital_port;
 struct intel_encoder;
 struct intel_lspcon;
+struct intel_dp;
 
 bool lspcon_init(struct intel_digital_port *intel_dig_port);
 void lspcon_resume(struct intel_lspcon *lspcon);
@@ -39,4 +40,7 @@  void lspcon_drm_write_infoframe(struct intel_encoder *encoder,
 				const struct intel_crtc_state *crtc_state,
 				unsigned int type,
 				const void *frame, ssize_t len);
+void intel_dp_setup_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
+					       const struct intel_crtc_state *crtc_state,
+					       const struct drm_connector_state *conn_state);
 #endif /* __INTEL_LSPCON_H__ */
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 5f8c3389d46f..1f0b4fcf0bd3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -661,6 +661,7 @@  struct drm_connector_state {
 	 * DRM blob property for HDR output metadata
 	 */
 	struct drm_property_blob *hdr_output_metadata;
+	u8 hdr_metadata_changed : 1;
 };
 
 /**