dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Shankar, Uma" <uma.shankar@intel.com>
To: "Nautiyal, Ankit K" <ankit.k.nautiyal@intel.com>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>
Cc: "airlied@linux.ie" <airlied@linux.ie>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"Sharma, Swati2" <swati2.sharma@intel.com>,
	"Kulkarni, Vandita" <vandita.kulkarni@intel.com>
Subject: RE: [PATCH v4 13/16] drm/i915: Add helper functions for calculating DSC parameters for HDMI2.1
Date: Sun, 13 Dec 2020 07:13:31 +0000	[thread overview]
Message-ID: <ae09590a845d458891819df544a10036@intel.com> (raw)
In-Reply-To: <20201208075145.17389-14-ankit.k.nautiyal@intel.com>



> -----Original Message-----
> From: Nautiyal, Ankit K <ankit.k.nautiyal@intel.com>
> Sent: Tuesday, December 8, 2020 1:22 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org; Shankar, Uma <uma.shankar@intel.com>;
> airlied@linux.ie; jani.nikula@linux.intel.com; ville.syrjala@linux.intel.com;
> Kulkarni, Vandita <vandita.kulkarni@intel.com>; Sharma, Swati2
> <swati2.sharma@intel.com>
> Subject: [PATCH v4 13/16] drm/i915: Add helper functions for calculating DSC
> parameters for HDMI2.1
> 
> The DP-HDMI2.1 PCON spec provides way for a source to set PPS
> parameters: slice height, slice width and bits_per_pixel, based on the HDMI2.1
> sink capabilities. The DSC encoder of the PCON will respect these parameters,
> while preparing the 128 byte PPS.
> 
> This patch adds helper functions to calculate these PPS paremeters as per the
> HDMI2.1 specification.
> 
> v2: Addressed review comments given by Uma Shankar:
> -added documentation for functions
> -fixed typos and errors

Looks good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_hdmi.c | 233 ++++++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_hdmi.h |   7 +
>  2 files changed, 240 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c
> b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index e10fdb369daa..41eb1c175a0e 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -3428,3 +3428,236 @@ void intel_hdmi_init(struct drm_i915_private
> *dev_priv,
>  	dig_port->aux_ch = intel_bios_port_aux_ch(dev_priv, port);
>  	intel_hdmi_init_connector(dig_port, intel_connector);  }
> +
> +/*
> + * intel_hdmi_dsc_get_slice_height - get the dsc slice_height
> + * @vactive: Vactive of a display mode
> + *
> + * @return: appropriate dsc slice height for a given mode.
> + */
> +int intel_hdmi_dsc_get_slice_height(int vactive) {
> +	int slice_height;
> +
> +	/*
> +	 * Slice Height determination : HDMI2.1 Section 7.7.5.2
> +	 * Select smallest slice height >=96, that results in a valid PPS and
> +	 * requires minimum padding lines required for final slice.
> +	 *
> +	 * Assumption : Vactive is even.
> +	 */
> +	for (slice_height = 96; slice_height <= vactive; slice_height += 2)
> +		if (vactive % slice_height == 0)
> +			return slice_height;
> +
> +	return 0;
> +}
> +
> +/*
> + * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc
> +encoder
> + * and dsc decoder capabilites
> + *
> + * @crtc_state: intel crtc_state
> + * @src_max_slices: maximum slices supported by the DSC encoder
> + * @src_max_slice_width: maximum slice width supported by DSC encoder
> + * @hdmi_max_slices: maximum slices supported by sink DSC decoder
> + * @hdmi_throughput: maximum clock per slice (MHz) supported by HDMI
> +sink
> + *
> + * @return: num of dsc slices that can be supported by the dsc encoder
> + * and decoder.
> + */
> +int
> +intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
> +			      int src_max_slices, int src_max_slice_width,
> +			      int hdmi_max_slices, int hdmi_throughput) {
> +/* Pixel rates in KPixels/sec */
> +#define HDMI_DSC_PEAK_PIXEL_RATE		2720000
> +/*
> + * Rates at which the source and sink are required to process pixels in
> +each
> + * slice, can be two levels: either atleast 340000KHz or atleast 40000KHz.
> + */
> +#define HDMI_DSC_MAX_ENC_THROUGHPUT_0		340000
> +#define HDMI_DSC_MAX_ENC_THROUGHPUT_1		400000
> +
> +/* Spec limits the slice width to 2720 pixels */
> +#define MAX_HDMI_SLICE_WIDTH			2720
> +	int kslice_adjust;
> +	int adjusted_clk_khz;
> +	int min_slices;
> +	int target_slices;
> +	int max_throughput; /* max clock freq. in khz per slice */
> +	int max_slice_width;
> +	int slice_width;
> +	int pixel_clock = crtc_state->hw.adjusted_mode.crtc_clock;
> +
> +	if (!hdmi_throughput)
> +		return 0;
> +
> +	/*
> +	 * Slice Width determination : HDMI2.1 Section 7.7.5.1
> +	 * kslice_adjust factor for 4:2:0, and 4:2:2 formats is 0.5, where as
> +	 * for 4:4:4 is 1.0. Multiplying these factors by 10 and later
> +	 * dividing adjusted clock value by 10.
> +	 */
> +	if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
> +	    crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB)
> +		kslice_adjust = 10;
> +	else
> +		kslice_adjust = 5;
> +
> +	/*
> +	 * As per spec, the rate at which the source and the sink process
> +	 * the pixels per slice are at two levels: atleast 340Mhz or 400Mhz.
> +	 * This depends upon the pixel clock rate and output formats
> +	 * (kslice adjust).
> +	 * If pixel clock * kslice adjust >= 2720MHz slices can be processed
> +	 * at max 340MHz, otherwise they can be processed at max 400MHz.
> +	 */
> +
> +	adjusted_clk_khz = DIV_ROUND_UP(kslice_adjust * pixel_clock, 10);
> +
> +	if (adjusted_clk_khz <= HDMI_DSC_PEAK_PIXEL_RATE)
> +		max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_0;
> +	else
> +		max_throughput = HDMI_DSC_MAX_ENC_THROUGHPUT_1;
> +
> +	/*
> +	 * Taking into account the sink's capability for maximum
> +	 * clock per slice (in MHz) as read from HF-VSDB.
> +	 */
> +	max_throughput = min(max_throughput, hdmi_throughput * 1000);
> +
> +	min_slices = DIV_ROUND_UP(adjusted_clk_khz, max_throughput);
> +	max_slice_width = min(MAX_HDMI_SLICE_WIDTH, src_max_slice_width);
> +
> +	/*
> +	 * Keep on increasing the num of slices/line, starting from min_slices
> +	 * per line till we get such a number, for which the slice_width is
> +	 * just less than max_slice_width. The slices/line selected should be
> +	 * less than or equal to the max horizontal slices that the combination
> +	 * of PCON encoder and HDMI decoder can support.
> +	 */
> +	slice_width = max_slice_width;
> +
> +	do {
> +		if (min_slices <= 1 && src_max_slices >= 1 && hdmi_max_slices
> >= 1)
> +		       target_slices = 1;
> +		else if (min_slices <= 2 && src_max_slices >= 2 &&
> hdmi_max_slices >= 2)
> +		       target_slices = 2;
> +		else if (min_slices <= 4 && src_max_slices >= 4 &&
> hdmi_max_slices >= 4)
> +		       target_slices = 4;
> +		else if (min_slices <= 8 && src_max_slices >= 8 &&
> hdmi_max_slices >= 8)
> +		       target_slices = 8;
> +		else if (min_slices <= 12 && src_max_slices >= 12 &&
> hdmi_max_slices >= 12)
> +		       target_slices = 12;
> +		else if (min_slices <= 16 && src_max_slices >= 16 &&
> hdmi_max_slices >= 16)
> +		       target_slices = 16;
> +		else
> +			return 0;
> +
> +		slice_width = DIV_ROUND_UP(crtc_state-
> >hw.adjusted_mode.hdisplay, target_slices);
> +		if (slice_width >= max_slice_width)
> +			min_slices = target_slices + 1;
> +	} while (slice_width >= max_slice_width);
> +
> +	return target_slices;
> +}
> +
> +/*
> + * intel_hdmi_dsc_get_bpp - get the appropriate compressed
> +bits_per_pixel based on
> + * source and sink capabilities.
> + *
> + * @src_fraction_bpp: fractional bpp supported by the source
> + * @slice_width: dsc slice width supported by the source and sink
> + * @num_slices: num of slices supported by the source and sink
> + * @output_format: video output format
> + * @hdmi_all_bpp: sink supports decoding of 1/16th bpp setting
> + * @hdmi_max_chunk_bytes: max bytes in a line of chunks supported by
> +sink
> + *
> + * @return: compressed bits_per_pixel in step of 1/16 of bits_per_pixel
> +*/ int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width,
> +int num_slices,
> +		       int output_format, bool hdmi_all_bpp,
> +		       int hdmi_max_chunk_bytes)
> +{
> +	int max_dsc_bpp, min_dsc_bpp;
> +	int target_bytes;
> +	bool bpp_found = false;
> +	int bpp_decrement_x16;
> +	int bpp_target;
> +	int bpp_target_x16;
> +
> +	/*
> +	 * Get min bpp and max bpp as per Table 7.23, in HDMI2.1 spec
> +	 * Start with the max bpp and keep on decrementing with
> +	 * fractional bpp, if supported by PCON DSC encoder
> +	 *
> +	 * for each bpp we check if no of bytes can be supported by HDMI sink
> +	 */
> +
> +	/* Assuming: bpc as 8*/
> +	if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
> +		min_dsc_bpp = 6;
> +		max_dsc_bpp = 3 * 4; /* 3*bpc/2 */
> +	} else if (output_format == INTEL_OUTPUT_FORMAT_YCBCR444 ||
> +		   output_format == INTEL_OUTPUT_FORMAT_RGB) {
> +		min_dsc_bpp = 8;
> +		max_dsc_bpp = 3 * 8; /* 3*bpc */
> +	} else {
> +		/* Assuming 4:2:2 encoding */
> +		min_dsc_bpp = 7;
> +		max_dsc_bpp = 2 * 8; /* 2*bpc */
> +	}
> +
> +	/*
> +	 * Taking into account if all dsc_all_bpp supported by HDMI2.1 sink
> +	 * Section 7.7.34 : Source shall not enable compressed Video
> +	 * Transport with bpp_target settings above 12 bpp unless
> +	 * DSC_all_bpp is set to 1.
> +	 */
> +	if (!hdmi_all_bpp)
> +		max_dsc_bpp = min(max_dsc_bpp, 12);
> +
> +	/*
> +	 * The Sink has a limit of compressed data in bytes for a scanline,
> +	 * as described in max_chunk_bytes field in HFVSDB block of edid.
> +	 * The no. of bytes depend on the target bits per pixel that the
> +	 * source configures. So we start with the max_bpp and calculate
> +	 * the target_chunk_bytes. We keep on decrementing the target_bpp,
> +	 * till we get the target_chunk_bytes just less than what the sink's
> +	 * max_chunk_bytes, or else till we reach the min_dsc_bpp.
> +	 *
> +	 * The decrement is according to the fractional support from PCON DSC
> +	 * encoder. For fractional BPP we use bpp_target as a multiple of 16.
> +	 *
> +	 * bpp_target_x16 = bpp_target * 16
> +	 * So we need to decrement by {1, 2, 4, 8, 16} for fractional bpps
> +	 * {1/16, 1/8, 1/4, 1/2, 1} respectively.
> +	 */
> +
> +	bpp_target = max_dsc_bpp;
> +
> +	/* src does not support fractional bpp implies decrement by 16 for
> bppx16 */
> +	if (!src_fractional_bpp)
> +		src_fractional_bpp = 1;
> +	bpp_decrement_x16 = DIV_ROUND_UP(16, src_fractional_bpp);
> +	bpp_target_x16 = (bpp_target * 16) - bpp_decrement_x16;
> +
> +	while (bpp_target_x16 > (min_dsc_bpp * 16)) {
> +		int bpp;
> +
> +		bpp = DIV_ROUND_UP(bpp_target_x16, 16);
> +		target_bytes = DIV_ROUND_UP((num_slices * slice_width * bpp),
> 8);
> +		if (target_bytes <= hdmi_max_chunk_bytes) {
> +			bpp_found = true;
> +			break;
> +		}
> +		bpp_target_x16 -= bpp_decrement_x16;
> +	}
> +	if (bpp_found)
> +		return bpp_target_x16;
> +
> +	return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h
> b/drivers/gpu/drm/i915/display/intel_hdmi.h
> index 15eb0ccde76e..fa1a9b030850 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.h
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h
> @@ -50,5 +50,12 @@ bool intel_hdmi_limited_color_range(const struct
> intel_crtc_state *crtc_state,
>  				    const struct drm_connector_state
> *conn_state);  bool intel_hdmi_deep_color_possible(const struct intel_crtc_state
> *crtc_state, int bpc,
>  				    bool has_hdmi_sink, bool ycbcr420_output);
> +int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width,
> +			   int num_slices, int output_format, bool hdmi_all_bpp,
> +			   int hdmi_max_chunk_bytes);
> +int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state,
> +				  int src_max_slices, int src_max_slice_width,
> +				  int hdmi_max_slices, int hdmi_throughput); int
> +intel_hdmi_dsc_get_slice_height(int vactive);
> 
>  #endif /* __INTEL_HDMI_H__ */
> --
> 2.17.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2020-12-13  7:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-08  7:51 [PATCH v4 00/16] Add support for DP-HDMI2.1 PCON Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 01/16] drm/edid: Add additional HFVSDB fields for HDMI2.1 Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 02/16] drm/edid: Parse MAX_FRL field from HFVSDB block Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 03/16] drm/edid: Parse DSC1.2 cap fields " Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 04/16] drm/dp_helper: Add Helpers for FRL Link Training support for DP-HDMI2.1 PCON Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 05/16] drm/dp_helper: Add support for link failure detection Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 06/16] drm/dp_helper: Add support for Configuring DSC for HDMI2.1 Pcon Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 07/16] drm/dp_helper: Add helpers to configure PCONs RGB-YCbCr Conversion Ankit Nautiyal
2020-12-09 17:50   ` Dan Carpenter
2020-12-10 12:20     ` Nautiyal, Ankit K
2020-12-13  7:10   ` Shankar, Uma
2020-12-14 13:17     ` Nautiyal, Ankit K
2020-12-08  7:51 ` [PATCH v4 08/16] drm/i915: Capture max frl rate for PCON in dfp cap structure Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 09/16] drm/i915: Add support for starting FRL training for HDMI2.1 via PCON Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 10/16] drm/i915: Check for FRL training before DP Link training Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 11/16] drm/i915: Add support for enabling link status and recovery Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 12/16] drm/i915: Read DSC capabilities of the HDMI2.1 PCON encoder Ankit Nautiyal
2020-12-08  7:51 ` [PATCH v4 13/16] drm/i915: Add helper functions for calculating DSC parameters for HDMI2.1 Ankit Nautiyal
2020-12-13  7:13   ` Shankar, Uma [this message]
2020-12-08  7:51 ` [PATCH v4 14/16] drm/i915/display: Configure PCON for DSC1.1 to DSC1.2 encoding Ankit Nautiyal
2020-12-13  7:16   ` Shankar, Uma
2020-12-08  7:51 ` [PATCH v4 15/16] drm/i915: Let PCON convert from RGB to YUV if it can Ankit Nautiyal
2020-12-13  7:23   ` Shankar, Uma
2020-12-14 13:27     ` Nautiyal, Ankit K
2020-12-08  7:51 ` [PATCH v4 16/16] drm/i915: Enable PCON configuration for Color Conversion for TGL Ankit Nautiyal
2020-12-13  7:29   ` Shankar, Uma
2020-12-14 13:51     ` Nautiyal, Ankit K
2020-12-08 10:33 ` [PATCH v4 00/16] Add support for DP-HDMI2.1 PCON Jani Nikula

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=ae09590a845d458891819df544a10036@intel.com \
    --to=uma.shankar@intel.com \
    --cc=airlied@linux.ie \
    --cc=ankit.k.nautiyal@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=swati2.sharma@intel.com \
    --cc=vandita.kulkarni@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox