[PATCH 06/10] drm/i915/display: Add DSC pixel replication

Kandpal, Suraj suraj.kandpal at intel.com
Thu Oct 17 09:33:16 UTC 2024



> -----Original Message-----
> From: Nautiyal, Ankit K <ankit.k.nautiyal at intel.com>
> Sent: Thursday, October 17, 2024 1:54 PM
> To: intel-gfx at lists.freedesktop.org
> Cc: intel-xe at lists.freedesktop.org; Kandpal, Suraj
> <suraj.kandpal at intel.com>
> Subject: [PATCH 06/10] drm/i915/display: Add DSC pixel replication
> 
> With 3 VDSC engines and Ultrajoiner, we may encounter a situation where
> hdisplay is not a multiple of slice count. In this case we need to add extra
> pixels to the last slice to distribute pixels evenly across slices.
> 
> Add member to store DSC pixel replication when hdisplay is not divisible by
> slice_width. Fill DSS_CTL3 register with the pixel replication count.
> 
> Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |  1 +
>  .../drm/i915/display/intel_display_types.h    |  1 +
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 25 +++++++++++++++++--
>  .../gpu/drm/i915/display/intel_vdsc_regs.h    |  8 ++++++
>  4 files changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 9e2f0fd0558f..20bb27aa880b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -5743,6 +5743,7 @@ intel_pipe_config_compare(const struct
> intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
>  	PIPE_CONF_CHECK_I(dsc.dsc_split);
>  	PIPE_CONF_CHECK_I(dsc.compressed_bpp_x16);
> +	PIPE_CONF_CHECK_I(dsc.pixel_replication_count);
> 
>  	PIPE_CONF_CHECK_BOOL(splitter.enable);
>  	PIPE_CONF_CHECK_I(splitter.link_count);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index e6d37d28c5c1..41a4e062e047 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1245,6 +1245,7 @@ struct intel_crtc_state {
>  		/* Compressed Bpp in U6.4 format (first 4 bits for fractional
> part) */
>  		u16 compressed_bpp_x16;
>  		u8 slice_count;
> +		int pixel_replication_count;
>  		struct drm_dsc_config config;
>  	} dsc;
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c
> b/drivers/gpu/drm/i915/display/intel_vdsc.c
> index 718e1b400af5..df5285d3e4b2 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -774,6 +774,7 @@ void intel_dsc_enable(const struct intel_crtc_state
> *crtc_state)
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 dss_ctl1_val = 0;
>  	u32 dss_ctl2_val = 0;
> +	u32 dss_ctl3_val = 0;
>  	int vdsc_instances_per_pipe =
> intel_dsc_get_vdsc_per_pipe(crtc_state);
> 
>  	if (!crtc_state->dsc.compression_enable)
> @@ -804,8 +805,16 @@ void intel_dsc_enable(const struct intel_crtc_state
> *crtc_state)
>  		if (intel_crtc_is_bigjoiner_primary(crtc_state))
>  			dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE;
>  	}
> +
> +	if (crtc_state->dsc.pixel_replication_count)
> +		dss_ctl3_val =
> +DSC_PIXEL_REPLICATION(crtc_state->dsc.pixel_replication_count);
> +
>  	intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state-
> >cpu_transcoder), dss_ctl1_val);
>  	intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state-
> >cpu_transcoder), dss_ctl2_val);
> +
> +	if (IS_BATTLEMAGE(dev_priv) && dss_ctl3_val)

Use of IS_BATTLEMAGE macro is discouraged maybe try using DISPLAY_VER_FULL (14.1) for BMG
Same for other uses of BMG as well

> +		intel_de_write(dev_priv,
> +			       BMG_PIPE_DSS_CTL3(crtc_state-
> >cpu_transcoder), dss_ctl3_val);
>  }
> 
>  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) @@ -
> 818,6 +827,10 @@ void intel_dsc_disable(const struct intel_crtc_state
> *old_crtc_state)
>  	    old_crtc_state->joiner_pipes) {
>  		intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state-
> >cpu_transcoder), 0);
>  		intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state-
> >cpu_transcoder), 0);
> +
> +		if (IS_BATTLEMAGE(dev_priv))
> +			intel_de_write(dev_priv,
> +				       BMG_PIPE_DSS_CTL3(old_crtc_state-
> >cpu_transcoder), 0);
>  	}
>  }
> 
> @@ -975,7 +988,7 @@ void intel_dsc_get_config(struct intel_crtc_state
> *crtc_state)
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	enum intel_display_power_domain power_domain;
>  	intel_wakeref_t wakeref;
> -	u32 dss_ctl1, dss_ctl2;
> +	u32 dss_ctl1, dss_ctl2, dss_ctl3 = 0;
> 
>  	if (!intel_dsc_source_support(crtc_state))
>  		return;
> @@ -989,6 +1002,9 @@ void intel_dsc_get_config(struct intel_crtc_state
> *crtc_state)
>  	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc,
> cpu_transcoder));
>  	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc,
> cpu_transcoder));
> 
> +	if (IS_BATTLEMAGE(dev_priv))
> +		dss_ctl3 = intel_de_read(dev_priv,
> +BMG_PIPE_DSS_CTL3(crtc_state->cpu_transcoder));
> +
>  	crtc_state->dsc.compression_enable = dss_ctl2 & VDSC0_ENABLE;
>  	if (!crtc_state->dsc.compression_enable)
>  		goto out;
> @@ -1003,6 +1019,10 @@ void intel_dsc_get_config(struct intel_crtc_state
> *crtc_state)
>  		crtc_state->dsc.dsc_split = INTEL_DSC_SPLIT_DISABLED;
>  	}
> 
> +	if (dss_ctl3 & DSC_PIXEL_REPLICATION_MASK)
> +		crtc_state->dsc.pixel_replication_count =
> +			dss_ctl3 & DSC_PIXEL_REPLICATION_MASK;
> +
>  	intel_dsc_get_pps_config(crtc_state);
>  out:
>  	intel_display_power_put(dev_priv, power_domain, wakeref); @@ -
> 1025,9 +1045,10 @@ static void intel_vdsc_dump_state(struct drm_printer
> *p, int indent,
>  				  const struct intel_crtc_state *crtc_state)  {
>  	drm_printf_indent(p, indent,
> -			  "dsc-dss: compressed-bpp:" FXP_Q4_FMT ", slice-
> count: %d, split: %s\n",
> +			  "dsc-dss: compressed-bpp:" FXP_Q4_FMT ", slice-
> count: %d,
> +replicated pixels: %d split: %s\n",
>  			  FXP_Q4_ARGS(crtc_state-
> >dsc.compressed_bpp_x16),
>  			  crtc_state->dsc.slice_count,
> +			  crtc_state->dsc.pixel_replication_count,
>  			  dsc_split_name(crtc_state->dsc.dsc_split));
>  }
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
> b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
> index efaeb5e0aea3..f9807796f07e 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h
> @@ -52,6 +52,14 @@
> 
> _ICL_PIPE_DSS_CTL2_PB, \
> 
> _ICL_PIPE_DSS_CTL2_PC)
> 
> +#define _BMG_PIPE_DSS_CTL3_PB			0x782f0
> +#define _BMG_PIPE_DSS_CTL3_PC			0x784f0
> +#define BMG_PIPE_DSS_CTL3(pipe)			_MMIO_PIPE((pipe) -
> PIPE_B, \
> +
> _BMG_PIPE_DSS_CTL3_PB, \
> +
> _BMG_PIPE_DSS_CTL3_PC)
> +#define  DSC_PIXEL_REPLICATION_MASK		REG_GENMASK(15, 0)
> +#define  DSC_PIXEL_REPLICATION(count)		((count) << 0)

I would have expected a REG_FIELD_PREP here instead of the count << 0 gives the same result
But the former is the convention we follow and since you have already defined the mask

Regards,
Suraj Kandpal

> +
>  /* Icelake Display Stream Compression Registers */
>  #define DSCA_PICTURE_PARAMETER_SET_0		_MMIO(0x6B200)
>  #define DSCC_PICTURE_PARAMETER_SET_0		_MMIO(0x6BA00)
> --
> 2.45.2



More information about the Intel-gfx mailing list