All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH v11 03/11] drm/i915/dp: Replace intel_dp.dfp members with the new crtc_state sink_format
Date: Fri, 17 Mar 2023 01:46:35 +0200	[thread overview]
Message-ID: <ZBOqW3MselbJN93w@intel.com> (raw)
In-Reply-To: <20230314110415.2882484-4-ankit.k.nautiyal@intel.com>

On Tue, Mar 14, 2023 at 04:34:07PM +0530, Ankit Nautiyal wrote:
> The decision to use DFP output format conversion capabilities should be
> during compute_config phase.
> 
> This patch uses the members of intel_dp->dfp to only store the
> format conversion capabilities of the DP device and uses the crtc_state
> sink_format member, to program the protocol-converter for
> colorspace/format conversion.
> 
> v2: Use sink_format to determine the color conversion config for the
> pcon (Ville).
> 
> v3: Fix typo: missing 'break' in switch case (lkp kernel test robot).
> 
> v4: Add helper to check if DP supports YCBCR420.
> 
> v5: Simplify logic for computing output_format, based on the given
> sink_format. (Ville).
> Added scaler constraint for YCbCr420 output.
> 
> v6: Split the patch for Scaler constraint for Ycbcr420.
> 
> v7: Simplify the policy for selecting output_format:
> Always try for RGB first, followed by YCBCR444, and finally by YCBCR420.
> 
> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 182 +++++++++++++++++-------
>  1 file changed, 129 insertions(+), 53 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index e52e2ffc355c..c31ec9c91c64 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -817,24 +817,82 @@ u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +static bool source_can_output(struct intel_dp *intel_dp,
> +			      enum intel_output_format format)
> +{
> +	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	bool is_branch = drm_dp_is_branch(intel_dp->dpcd);
> +
> +	if (format == INTEL_OUTPUT_FORMAT_RGB)
> +		return true;
> +
> +	/*
> +	 * No YCbCr output support on gmch platforms.
> +	 * Also, ILK doesn't seem capable of DP YCbCr output.
> +	 * The displayed image is severly corrupted. SNB+ is fine.
> +	 */
> +	if (HAS_GMCH(i915) || IS_IRONLAKE(i915))
> +		return false;
> +
> +	if (format == INTEL_OUTPUT_FORMAT_YCBCR444)
> +		return true;
> +
> +	/* Platform < Gen 11 cannot output YCbCr420 format */
> +	if (DISPLAY_VER(i915) < 11)
> +		return false;
> +
> +	/* If branch device then PCONs should support YCbCr420 Passthrough */
> +	if (format == INTEL_OUTPUT_FORMAT_YCBCR420)
> +		return !is_branch || intel_dp->dfp.ycbcr420_passthrough;

This part isn't really about the source capabilities.
I think it would be more appropriate to do these checks
in the caller.

> +
> +	return false;
> +}
> +
> +static bool
> +dfp_can_convert_from_rgb(struct intel_dp *intel_dp,
> +			 enum intel_output_format sink_format)
> +{
> +	if (!drm_dp_is_branch(intel_dp->dpcd))
> +		return false;
> +
> +	if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR444)
> +		return intel_dp->dfp.rgb_to_ycbcr;
> +
> +	if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
> +		return intel_dp->dfp.rgb_to_ycbcr &&
> +			intel_dp->dfp.ycbcr_444_to_420;
> +
> +	return false;
> +}
> +
> +static bool
> +dfp_can_convert_from_ycbcr444(struct intel_dp *intel_dp,
> +			      enum intel_output_format sink_format)
> +{
> +	if (!drm_dp_is_branch(intel_dp->dpcd))
> +		return false;
> +
> +	if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
> +		return intel_dp->dfp.ycbcr_444_to_420;
> +
> +	return false;
> +}
> +
>  static enum intel_output_format
>  intel_dp_output_format(struct intel_connector *connector,
>  		       enum intel_output_format sink_format)
>  {
>  	struct intel_dp *intel_dp = intel_attached_dp(connector);
>  
> -	if (!connector->base.ycbcr_420_allowed ||
> -	    sink_format != INTEL_OUTPUT_FORMAT_YCBCR420)
> -		return INTEL_OUTPUT_FORMAT_RGB;
> -
> -	if (intel_dp->dfp.rgb_to_ycbcr &&
> -	    intel_dp->dfp.ycbcr_444_to_420)
> +	if (sink_format == INTEL_OUTPUT_FORMAT_RGB ||
> +	    dfp_can_convert_from_rgb(intel_dp, sink_format))
>  		return INTEL_OUTPUT_FORMAT_RGB;
>  
> -	if (intel_dp->dfp.ycbcr_444_to_420)
> +	if (sink_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
> +	    dfp_can_convert_from_ycbcr444(intel_dp, sink_format))
>  		return INTEL_OUTPUT_FORMAT_YCBCR444;
> -	else
> -		return INTEL_OUTPUT_FORMAT_YCBCR420;
> +
> +	return INTEL_OUTPUT_FORMAT_YCBCR420;
>  }

I'm thinking the caller of intel_dp_output_format() might want
to do a drm_WARN_ON(!source_can_output(output_format))
just to make sure we didn't screw things up too badly.

Or maybe we want to have that assert in intel_dp_output_format()
itself in case there are many callers.

>  
>  int intel_dp_min_bpp(enum intel_output_format output_format)
> @@ -2751,6 +2809,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
>  					   const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> +	bool ycbcr444_to_420 = false;
> +	bool rgb_to_ycbcr = false;
>  	u8 tmp;
>  
>  	if (intel_dp->dpcd[DP_DPCD_REV] < 0x13)
> @@ -2767,8 +2827,35 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
>  		drm_dbg_kms(&i915->drm, "Failed to %s protocol converter HDMI mode\n",
>  			    str_enable_disable(intel_dp->has_hdmi_sink));
>  
> -	tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
> -		intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
> +	if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420) {

I was wondering where YCBCR444 went here, but then I
remembered that we don't have uapi for it. 

But even so, we could consider making this code already
handle it. Would make it that much easier to test
YCbCr 4:4:4 output. Should just take a one line hack
to intel_dp_sink_format() at that point. Could be
a followup patch though.

> +		switch (crtc_state->output_format) {
> +		case INTEL_OUTPUT_FORMAT_YCBCR420:
> +			/*
> +			 * sink_format is YCbCr420, output_format is also YCbCr420:
> +			 * Passthrough.
> +			 */

These comments seem a bit redundant.

> +			break;
> +		case INTEL_OUTPUT_FORMAT_YCBCR444:
> +			/*
> +			 * sink_format is YCbCr420, output_format is YCbCr444:
> +			 * Downsample.
> +			 */
> +			ycbcr444_to_420 = true;
> +			break;
> +		case INTEL_OUTPUT_FORMAT_RGB:
> +			/*
> +			 * sink_format is YCbCr420, output_format is RGB:
> +			 * Convert to YCbCr444 and Downsample.
> +			 */
> +			rgb_to_ycbcr = true;
> +			ycbcr444_to_420 = true;
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	tmp = ycbcr444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
>  
>  	if (drm_dp_dpcd_writeb(&intel_dp->aux,
>  			       DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
> @@ -2776,13 +2863,12 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
>  			    "Failed to %s protocol converter YCbCr 4:2:0 conversion mode\n",
>  			    str_enable_disable(intel_dp->dfp.ycbcr_444_to_420));
>  
> -	tmp = intel_dp->dfp.rgb_to_ycbcr ?
> -		DP_CONVERSION_BT709_RGB_YCBCR_ENABLE : 0;
> +	tmp = rgb_to_ycbcr ? DP_CONVERSION_BT709_RGB_YCBCR_ENABLE : 0;
>  
>  	if (drm_dp_pcon_convert_rgb_to_ycbcr(&intel_dp->aux, tmp) < 0)
>  		drm_dbg_kms(&i915->drm,
> -			   "Failed to %s protocol converter RGB->YCbCr conversion mode\n",
> -			   str_enable_disable(tmp));
> +			    "Failed to %s protocol converter RGB->YCbCr conversion mode\n",
> +			    str_enable_disable(tmp));
>  }
>  
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
> @@ -4572,57 +4658,47 @@ intel_dp_update_dfp(struct intel_dp *intel_dp,
>  	intel_dp_get_pcon_dsc_cap(intel_dp);
>  }
>  
> +static bool
> +intel_dp_can_ycbcr420(struct intel_dp *intel_dp)
> +{
> +	if (source_can_output(intel_dp, INTEL_OUTPUT_FORMAT_YCBCR420))
> +		return true;

Should have an empty line here.

> +	/*
> +	 * If source cannot support YCbCr420, and PCON has color conv. support:
> +	 * Source sends YCbCr444, PCON converts YCbCr444->420 Or
> +	 * Source sends RGB444, PCON converts RGB->YCbCr444 + YCbCr444->YCbCr420)
> +	 */

I think the code already explains that pretty well. Comment seems
a bit redundant.

> +	if (source_can_output(intel_dp, INTEL_OUTPUT_FORMAT_RGB) &&
> +	    dfp_can_convert_from_rgb(intel_dp, INTEL_OUTPUT_FORMAT_YCBCR420))
> +		return true;
> +
> +	if (source_can_output(intel_dp, INTEL_OUTPUT_FORMAT_YCBCR444) &&
> +	    dfp_can_convert_from_ycbcr444(intel_dp, INTEL_OUTPUT_FORMAT_YCBCR420))
> +		return INTEL_OUTPUT_FORMAT_YCBCR444;
> +
> +	return false;
> +}
> +
>  static void
>  intel_dp_update_420(struct intel_dp *intel_dp)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	struct intel_connector *connector = intel_dp->attached_connector;
> -	bool is_branch, ycbcr_420_passthrough, ycbcr_444_to_420, rgb_to_ycbcr;
> -
> -	/* No YCbCr output support on gmch platforms */
> -	if (HAS_GMCH(i915))
> -		return;
>  
> -	/*
> -	 * ILK doesn't seem capable of DP YCbCr output. The
> -	 * displayed image is severly corrupted. SNB+ is fine.
> -	 */
> -	if (IS_IRONLAKE(i915))
> -		return;
> -
> -	is_branch = drm_dp_is_branch(intel_dp->dpcd);
> -	ycbcr_420_passthrough =
> +	intel_dp->dfp.ycbcr420_passthrough =
>  		drm_dp_downstream_420_passthrough(intel_dp->dpcd,
>  						  intel_dp->downstream_ports);
>  	/* on-board LSPCON always assumed to support 4:4:4->4:2:0 conversion */
> -	ycbcr_444_to_420 =
> +	intel_dp->dfp.ycbcr_444_to_420 =
>  		dp_to_dig_port(intel_dp)->lspcon.active ||
>  		drm_dp_downstream_444_to_420_conversion(intel_dp->dpcd,
>  							intel_dp->downstream_ports);
> -	rgb_to_ycbcr = drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
> -								 intel_dp->downstream_ports,
> -								 DP_DS_HDMI_BT709_RGB_YCBCR_CONV);
> -
> -	if (DISPLAY_VER(i915) >= 11) {
> -		/* Let PCON convert from RGB->YCbCr if possible */
> -		if (is_branch && rgb_to_ycbcr && ycbcr_444_to_420) {
> -			intel_dp->dfp.rgb_to_ycbcr = true;
> -			intel_dp->dfp.ycbcr_444_to_420 = true;
> -			connector->base.ycbcr_420_allowed = true;
> -		} else {
> -		/* Prefer 4:2:0 passthrough over 4:4:4->4:2:0 conversion */
> -			intel_dp->dfp.ycbcr_444_to_420 =
> -				ycbcr_444_to_420 && !ycbcr_420_passthrough;
> +	intel_dp->dfp.rgb_to_ycbcr =
> +		drm_dp_downstream_rgb_to_ycbcr_conversion(intel_dp->dpcd,
> +							  intel_dp->downstream_ports,
> +							  DP_DS_HDMI_BT709_RGB_YCBCR_CONV);
>  
> -			connector->base.ycbcr_420_allowed =
> -				!is_branch || ycbcr_444_to_420 || ycbcr_420_passthrough;
> -		}
> -	} else {
> -		/* 4:4:4->4:2:0 conversion is the only way */
> -		intel_dp->dfp.ycbcr_444_to_420 = ycbcr_444_to_420;
> -
> -		connector->base.ycbcr_420_allowed = ycbcr_444_to_420;
> -	}
> +	connector->base.ycbcr_420_allowed = intel_dp_can_ycbcr420(intel_dp);

Looks good. With the minor issues sorted this is
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  
>  	drm_dbg_kms(&i915->drm,
>  		    "[CONNECTOR:%d:%s] RGB->YcbCr conversion? %s, YCbCr 4:2:0 allowed? %s, YCbCr 4:4:4->4:2:0 conversion? %s\n",
> -- 
> 2.25.1

-- 
Ville Syrjälä
Intel

  reply	other threads:[~2023-03-16 23:46 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-14 11:04 [Intel-gfx] [PATCH v11 00/11] Handle BPC for HDMI2.1 PCON without DSC1.2 sink and other fixes Ankit Nautiyal
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 01/11] drm/i915/display: Add new member to configure PCON color conversion Ankit Nautiyal
2023-03-17  0:24   ` Ville Syrjälä
2023-03-17 10:07     ` Nautiyal, Ankit K
2023-03-17 11:39       ` Ville Syrjälä
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 02/11] drm/i915/display: Add new member in intel_dp to store ycbcr420 passthrough cap Ankit Nautiyal
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 03/11] drm/i915/dp: Replace intel_dp.dfp members with the new crtc_state sink_format Ankit Nautiyal
2023-03-16 23:46   ` Ville Syrjälä [this message]
2023-03-17 10:48     ` Nautiyal, Ankit K
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 04/11] drm/i915/display: Use sink_format instead of ycbcr420_output flag Ankit Nautiyal
2023-03-17  0:25   ` Ville Syrjälä
2023-03-17 11:10     ` Nautiyal, Ankit K
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 05/11] drm/i915/dp: Rearrange check for illegal mode and comments in mode_valid Ankit Nautiyal
2023-03-17  0:28   ` Ville Syrjälä
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 06/11] drm/i915/dp: Consider output_format while computing dsc bpp for mode_valid Ankit Nautiyal
2023-03-17  1:00   ` Ville Syrjälä
2023-03-20  3:36     ` Nautiyal, Ankit K
2023-03-20  8:26       ` Ville Syrjälä
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 07/11] drm/i915/display: Add helper function to check if sink_format is 420 Ankit Nautiyal
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 08/11] drm/i915/dp: Avoid DSC with output_format YCBCR420 Ankit Nautiyal
2023-03-14 17:33   ` Manasi Navare
2023-03-16 11:20     ` Nautiyal, Ankit K
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 09/11] drm/i915/dp: Handle BPP where HDMI2.1 DFP doesn't support DSC Ankit Nautiyal
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 10/11] drm/i915/dp: Fix FRL BW check for HDMI2.1 DFP Ankit Nautiyal
2023-03-14 11:04 ` [Intel-gfx] [PATCH v11 11/11] drm/i915/dp: Add a wrapper to check frl/tmds downstream constraints Ankit Nautiyal
2023-03-14 15:41 ` [Intel-gfx] ✓ Fi.CI.BAT: success for Handle BPC for HDMI2.1 PCON without DSC1.2 sink and other fixes (rev12) Patchwork
2023-03-15 19:31 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZBOqW3MselbJN93w@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=ankit.k.nautiyal@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.