> -----Original Message----- > From: Nautiyal, Ankit K <ankit.k.nautiyal@xxxxxxxxx> > Sent: Thursday, October 17, 2024 1:54 PM > To: intel-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: intel-xe@xxxxxxxxxxxxxxxxxxxxx; Kandpal, Suraj > <suraj.kandpal@xxxxxxxxx> > 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@xxxxxxxxx> > --- > 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