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_