Re: [Intel-gfx] [RFC][PATCH 2/3] drm/i915: Sending AVI infoframe through GMP DIP

2021-01-07 Thread Mun, Gwan-gyeong
On Fri, 2020-12-18 at 16:03 +0530, Swati Sharma wrote:
> DP does not support sending AVI info frame to panel. So we need to
> send AVI info frame to HDMI through some other DIP.
> 
> When DP-to-HDMI protocol converter is present GMP DIP will be used
> to send AVI infoframe instead of static HDR infoframes.
> 
> While VESA spec indicates support within PCON to built AVI IF, it
> gives better control with source sending the infoframe by itself as
> per HDMI/CTA spec. Minimum of version 3 need to be used for VIC >=
> 128
> (i.e. for 8k mode as an example).
> 
> Signed-off-by: Swati Sharma 
> Signed-off-by: Ankit Nautiyal 
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 135 ++--
> 
>  1 file changed, 100 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index a776e7f809b4..d96e69dd2197 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2779,6 +2779,22 @@
> intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp
> *intel_dp,
>   intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_META
> DATA);
>  }
>  
> +static void
> +intel_dp_compute_avi_infoframe_sdp(struct intel_encoder *encoder,
> +struct intel_crtc_state *crtc_state,
> +struct drm_connector_state
> *conn_state)
> +{
> + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +
> + if (!intel_hdmi_compute_avi_infoframe(encoder, crtc_state,
> conn_state)) {
> + drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n");
> + return;
> + }
> +
Because intel_hdmi_compute_avi_infoframe() enables
HDMI_INFOFRAME_TYPE_AVI,
we should not call
intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA) here.
> + crtc_state->infoframes.enable |=
> + intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_META
> DATA);
> +}
> +
>  static void
>  intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
>struct intel_crtc_state *pipe_config,
> @@ -2807,6 +2823,38 @@ intel_dp_drrs_compute_config(struct intel_dp
> *intel_dp,
>  constant_n, pipe_config->fec_enable);
>  }
>  
> +static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
> +{
> + struct intel_connector *intel_connector = intel_dp-
> >attached_connector;
> + struct drm_connector *connector = &intel_connector->base;
> + int max_frl_rate;
> + int max_lanes, rate_per_lane;
> + int max_dsc_lanes, dsc_rate_per_lane;
> +
> + max_lanes = connector->display_info.hdmi.max_lanes;
> + rate_per_lane = connector-
> >display_info.hdmi.max_frl_rate_per_lane;
> + max_frl_rate = max_lanes * rate_per_lane;
> +
> + if (connector->display_info.hdmi.dsc_cap.v_1p2) {
> + max_dsc_lanes = connector-
> >display_info.hdmi.dsc_cap.max_lanes;
> + dsc_rate_per_lane = connector-
> >display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
> + if (max_dsc_lanes && dsc_rate_per_lane)
> + max_frl_rate = min(max_frl_rate, max_dsc_lanes
> * dsc_rate_per_lane);
> + }
> +
> + return max_frl_rate;
> +}
> +
> +static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp)
> +{
> + if (drm_dp_is_branch(intel_dp->dpcd) &&
> + intel_dp->has_hdmi_sink &&
> + intel_dp_hdmi_sink_max_frl(intel_dp) > 0)
> + return true;
> +
> + return false;
> +}
> +
>  int
>  intel_dp_compute_config(struct intel_encoder *encoder,
>   struct intel_crtc_state *pipe_config,
> @@ -2894,7 +2942,13 @@ intel_dp_compute_config(struct intel_encoder
> *encoder,
>   intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
>constant_n);
>   intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
> - intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp,
> pipe_config, conn_state);
> +
> + if (intel_dp_is_hdmi_2_1_sink(intel_dp)) {
> + pipe_config->has_infoframe = true;
> + intel_dp_compute_avi_infoframe_sdp(encoder,
> pipe_config, conn_state);
> + } else {
> + intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp,
> pipe_config, conn_state);
> + }
>  
>   return 0;
>  }
> @@ -4043,28 +4097,6 @@ static int intel_dp_pcon_set_frl_mask(int
> max_frl)
>   return 0;
>  }
>  
> -static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
> -{
> - struct intel_connector *intel_connector = intel_dp-
> >attached_connector;
> - struct drm_connector *connector = &intel_connector->base;
> - int max_frl_rate;
> - int max_lanes, rate_per_lane;
> - int max_dsc_lanes, dsc_rate_per_lane;
> -
> - max_lanes = connector->display_info.hdmi.max_lanes;
> - rate_per_lane = connector-
> >display_info.hdmi.max_frl_rate_per_lane;
> - max_frl_rate = max_lanes * rate_

[Intel-gfx] [RFC][PATCH 2/3] drm/i915: Sending AVI infoframe through GMP DIP

2020-12-18 Thread Swati Sharma
DP does not support sending AVI info frame to panel. So we need to
send AVI info frame to HDMI through some other DIP.

When DP-to-HDMI protocol converter is present GMP DIP will be used
to send AVI infoframe instead of static HDR infoframes.

While VESA spec indicates support within PCON to built AVI IF, it
gives better control with source sending the infoframe by itself as
per HDMI/CTA spec. Minimum of version 3 need to be used for VIC >= 128
(i.e. for 8k mode as an example).

Signed-off-by: Swati Sharma 
Signed-off-by: Ankit Nautiyal 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 135 ++--
 1 file changed, 100 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index a776e7f809b4..d96e69dd2197 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2779,6 +2779,22 @@ intel_dp_compute_hdr_metadata_infoframe_sdp(struct 
intel_dp *intel_dp,
intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
 }
 
+static void
+intel_dp_compute_avi_infoframe_sdp(struct intel_encoder *encoder,
+  struct intel_crtc_state *crtc_state,
+  struct drm_connector_state *conn_state)
+{
+   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+   if (!intel_hdmi_compute_avi_infoframe(encoder, crtc_state, conn_state)) 
{
+   drm_dbg_kms(&dev_priv->drm, "bad AVI infoframe\n");
+   return;
+   }
+
+   crtc_state->infoframes.enable |=
+   intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA);
+}
+
 static void
 intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
 struct intel_crtc_state *pipe_config,
@@ -2807,6 +2823,38 @@ intel_dp_drrs_compute_config(struct intel_dp *intel_dp,
   constant_n, pipe_config->fec_enable);
 }
 
+static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
+{
+   struct intel_connector *intel_connector = intel_dp->attached_connector;
+   struct drm_connector *connector = &intel_connector->base;
+   int max_frl_rate;
+   int max_lanes, rate_per_lane;
+   int max_dsc_lanes, dsc_rate_per_lane;
+
+   max_lanes = connector->display_info.hdmi.max_lanes;
+   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
+   max_frl_rate = max_lanes * rate_per_lane;
+
+   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
+   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
+   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
+   if (max_dsc_lanes && dsc_rate_per_lane)
+   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_rate_per_lane);
+   }
+
+   return max_frl_rate;
+}
+
+static bool intel_dp_is_hdmi_2_1_sink(struct intel_dp *intel_dp)
+{
+   if (drm_dp_is_branch(intel_dp->dpcd) &&
+   intel_dp->has_hdmi_sink &&
+   intel_dp_hdmi_sink_max_frl(intel_dp) > 0)
+   return true;
+
+   return false;
+}
+
 int
 intel_dp_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
@@ -2894,7 +2942,13 @@ intel_dp_compute_config(struct intel_encoder *encoder,
intel_dp_drrs_compute_config(intel_dp, pipe_config, output_bpp,
 constant_n);
intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
-   intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, 
conn_state);
+
+   if (intel_dp_is_hdmi_2_1_sink(intel_dp)) {
+   pipe_config->has_infoframe = true;
+   intel_dp_compute_avi_infoframe_sdp(encoder, pipe_config, 
conn_state);
+   } else {
+   intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, 
pipe_config, conn_state);
+   }
 
return 0;
 }
@@ -4043,28 +4097,6 @@ static int intel_dp_pcon_set_frl_mask(int max_frl)
return 0;
 }
 
-static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp)
-{
-   struct intel_connector *intel_connector = intel_dp->attached_connector;
-   struct drm_connector *connector = &intel_connector->base;
-   int max_frl_rate;
-   int max_lanes, rate_per_lane;
-   int max_dsc_lanes, dsc_rate_per_lane;
-
-   max_lanes = connector->display_info.hdmi.max_lanes;
-   rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane;
-   max_frl_rate = max_lanes * rate_per_lane;
-
-   if (connector->display_info.hdmi.dsc_cap.v_1p2) {
-   max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes;
-   dsc_rate_per_lane = 
connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane;
-   if (max_dsc_lanes && dsc_rate_per_lane)
-   max_frl_rate = min(max_frl_rate, max_dsc_lanes * 
dsc_r