[Intel-gfx] [PATCH 08/13] drm/i915/dsb: Handle the indexed vs. not inside the DSB code

Manna, Animesh animesh.manna at intel.com
Thu Jan 5 14:43:04 UTC 2023



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces at lists.freedesktop.org> On Behalf Of Ville
> Syrjala
> Sent: Friday, December 16, 2022 6:08 AM
> To: intel-gfx at lists.freedesktop.org
> Subject: [Intel-gfx] [PATCH 08/13] drm/i915/dsb: Handle the indexed vs. not
> inside the DSB code
> 
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> The DSB indexed register write insturction is purely an internal DSB
> implementation detail, no reason why the caller should have to know about
> it. So let's just have the caller emit blind register writes let the DSB code
> convert things to an indexed write if/when multiple writes occur to the same
> register offset in a row.
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>

LGTM.
Reviewed-by: Animesh Manna <animesh.manna at intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_color.c | 45 ++++------
>  drivers/gpu/drm/i915/display/intel_dsb.c   | 96 +++++++++-------------
>  drivers/gpu/drm/i915/display/intel_dsb.h   |  2 -
>  3 files changed, 54 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_color.c
> b/drivers/gpu/drm/i915/display/intel_color.c
> index d57631b0bb9a..76603357252d 100644
> --- a/drivers/gpu/drm/i915/display/intel_color.c
> +++ b/drivers/gpu/drm/i915/display/intel_color.c
> @@ -847,17 +847,6 @@ static void ilk_lut_write(const struct intel_crtc_state
> *crtc_state,
>  		intel_de_write_fw(i915, reg, val);
>  }
> 
> -static void ilk_lut_write_indexed(const struct intel_crtc_state *crtc_state,
> -				  i915_reg_t reg, u32 val)
> -{
> -	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> -
> -	if (crtc_state->dsb)
> -		intel_dsb_indexed_reg_write(crtc_state->dsb, reg, val);
> -	else
> -		intel_de_write_fw(i915, reg, val);
> -}
> -
>  static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
>  			   const struct drm_property_blob *blob)  { @@ -
> 962,8 +951,8 @@ static void bdw_load_lut_10(const struct intel_crtc_state
> *crtc_state,
>  		      prec_index);
> 
>  	for (i = 0; i < lut_size; i++)
> -		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
> -				      ilk_lut_10(&lut[i]));
> +		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
> +			      ilk_lut_10(&lut[i]));
> 
>  	/*
>  	 * Reset the index, otherwise it prevents the legacy palette to be @@
> -1093,13 +1082,13 @@ static void glk_load_degamma_lut(const struct
> intel_crtc_state *crtc_state,
>  		 * ToDo: Extend to max 7.0. Enable 32 bit input value
>  		 * as compared to just 16 to achieve this.
>  		 */
> -		ilk_lut_write_indexed(crtc_state,
> PRE_CSC_GAMC_DATA(pipe),
> -				      lut[i].green);
> +		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
> +			      lut[i].green);
>  	}
> 
>  	/* Clamp values > 1.0. */
>  	while (i++ < glk_degamma_lut_size(i915))
> -		ilk_lut_write_indexed(crtc_state,
> PRE_CSC_GAMC_DATA(pipe), 1 << 16);
> +		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1 <<
> 16);
> 
>  	ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 0);  } @@ -
> 1165,10 +1154,10 @@ icl_program_gamma_superfine_segment(const struct
> intel_crtc_state *crtc_state)
>  	for (i = 0; i < 9; i++) {
>  		const struct drm_color_lut *entry = &lut[i];
> 
> -		ilk_lut_write_indexed(crtc_state,
> PREC_PAL_MULTI_SEG_DATA(pipe),
> -				      ilk_lut_12p4_ldw(entry));
> -		ilk_lut_write_indexed(crtc_state,
> PREC_PAL_MULTI_SEG_DATA(pipe),
> -				      ilk_lut_12p4_udw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
> +			      ilk_lut_12p4_ldw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
> +			      ilk_lut_12p4_udw(entry));
>  	}
> 
>  	ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe), @@ -
> 1204,10 +1193,10 @@ icl_program_gamma_multi_segment(const struct
> intel_crtc_state *crtc_state)
>  	for (i = 1; i < 257; i++) {
>  		entry = &lut[i * 8];
> 
> -		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
> -				      ilk_lut_12p4_ldw(entry));
> -		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
> -				      ilk_lut_12p4_udw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
> +			      ilk_lut_12p4_ldw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
> +			      ilk_lut_12p4_udw(entry));
>  	}
> 
>  	/*
> @@ -1225,10 +1214,10 @@ icl_program_gamma_multi_segment(const
> struct intel_crtc_state *crtc_state)
>  	for (i = 0; i < 256; i++) {
>  		entry = &lut[i * 8 * 128];
> 
> -		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
> -				      ilk_lut_12p4_ldw(entry));
> -		ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe),
> -				      ilk_lut_12p4_udw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
> +			      ilk_lut_12p4_ldw(entry));
> +		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
> +			      ilk_lut_12p4_udw(entry));
>  	}
> 
>  	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), diff --git
> a/drivers/gpu/drm/i915/display/intel_dsb.c
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index fcc3f49c5445..fa4b808a8134 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
> @@ -114,32 +114,28 @@ static bool intel_dsb_prev_ins_is_write(struct
> intel_dsb *dsb,
>  	return prev_opcode == opcode && prev_reg ==
> i915_mmio_reg_offset(reg);  }
> 
> +static bool intel_dsb_prev_ins_is_mmio_write(struct intel_dsb *dsb,
> +i915_reg_t reg) {
> +	return intel_dsb_prev_ins_is_write(dsb,
> DSB_OPCODE_MMIO_WRITE, reg); }
> +
>  static bool intel_dsb_prev_ins_is_indexed_write(struct intel_dsb *dsb,
> i915_reg_t reg)  {
>  	return intel_dsb_prev_ins_is_write(dsb,
> DSB_OPCODE_INDEXED_WRITE, reg);  }
> 
>  /**
> - * intel_dsb_indexed_reg_write() -Write to the DSB context for auto
> - * increment register.
> + * intel_dsb_reg_write() - Emit register wriite to the DSB context
>   * @dsb: DSB context
>   * @reg: register address.
>   * @val: value.
>   *
>   * This function is used for writing register-value pair in command
> - * buffer of DSB for auto-increment register. During command buffer
> overflow,
> - * a warning is thrown and rest all erroneous condition register
> programming
> - * is done through mmio write.
> + * buffer of DSB.
>   */
> -
> -void intel_dsb_indexed_reg_write(struct intel_dsb *dsb,
> -				 i915_reg_t reg, u32 val)
> +void intel_dsb_reg_write(struct intel_dsb *dsb,
> +			 i915_reg_t reg, u32 val)
>  {
> -	u32 *buf = dsb->cmd_buf;
> -
> -	if (!assert_dsb_has_room(dsb))
> -		return;
> -
>  	/*
>  	 * For example the buffer will look like below for 3 dwords for auto
>  	 * increment register:
> @@ -156,57 +152,39 @@ void intel_dsb_indexed_reg_write(struct intel_dsb
> *dsb,
>  	 * we are writing odd no of dwords, Zeros will be added in the end
> for
>  	 * padding.
>  	 */
> -	if (!intel_dsb_prev_ins_is_indexed_write(dsb, reg)) {
> -		/* Every instruction should be 8 byte aligned. */
> -		dsb->free_pos = ALIGN(dsb->free_pos, 2);
> -
> -		dsb->ins_start_offset = dsb->free_pos;
> -
> -		/* Update the size. */
> -		buf[dsb->free_pos++] = 1;
> -
> -		/* Update the opcode and reg. */
> -		buf[dsb->free_pos++] = (DSB_OPCODE_INDEXED_WRITE  <<
> -					DSB_OPCODE_SHIFT) |
> -					i915_mmio_reg_offset(reg);
> -
> -		/* Update the value. */
> -		buf[dsb->free_pos++] = val;
> +	if (!intel_dsb_prev_ins_is_mmio_write(dsb, reg) &&
> +	    !intel_dsb_prev_ins_is_indexed_write(dsb, reg)) {
> +		intel_dsb_emit(dsb, val,
> +			       (DSB_OPCODE_MMIO_WRITE <<
> DSB_OPCODE_SHIFT) |
> +			       (DSB_BYTE_EN << DSB_BYTE_EN_SHIFT) |
> +			       i915_mmio_reg_offset(reg));
>  	} else {
> -		/* Update the new value. */
> +		u32 *buf = dsb->cmd_buf;
> +
> +		if (!assert_dsb_has_room(dsb))
> +			return;
> +
> +		/* convert to indexed write? */
> +		if (intel_dsb_prev_ins_is_mmio_write(dsb, reg)) {
> +			u32 prev_val = buf[dsb->ins_start_offset + 0];
> +
> +			buf[dsb->ins_start_offset + 0] = 1; /* size */
> +			buf[dsb->ins_start_offset + 1] =
> +				(DSB_OPCODE_INDEXED_WRITE <<
> DSB_OPCODE_SHIFT) |
> +				i915_mmio_reg_offset(reg);
> +			buf[dsb->ins_start_offset + 2] = prev_val;
> +
> +			dsb->free_pos++;
> +		}
> +
>  		buf[dsb->free_pos++] = val;
> -
>  		/* Update the size. */
>  		buf[dsb->ins_start_offset]++;
> +
> +		/* if number of data words is odd, then the last dword
> should be 0.*/
> +		if (dsb->free_pos & 0x1)
> +			buf[dsb->free_pos] = 0;
>  	}
> -
> -	/* if number of data words is odd, then the last dword should be
> 0.*/
> -	if (dsb->free_pos & 0x1)
> -		buf[dsb->free_pos] = 0;
> -}
> -
> -/**
> - * intel_dsb_reg_write() -Write to the DSB context for normal
> - * register.
> - * @crtc_state: intel_crtc_state structure
> - * @reg: register address.
> - * @val: value.
> - *
> - * This function is used for writing register-value pair in command
> - * buffer of DSB. During command buffer overflow, a warning  is thrown
> - * and rest all erroneous condition register programming is done
> - * through mmio write.
> - */
> -void intel_dsb_reg_write(struct intel_dsb *dsb,
> -			 i915_reg_t reg, u32 val)
> -{
> -	if (!assert_dsb_has_room(dsb))
> -		return;
> -
> -	intel_dsb_emit(dsb, val,
> -		       (DSB_OPCODE_MMIO_WRITE << DSB_OPCODE_SHIFT) |
> -		       (DSB_BYTE_EN << DSB_BYTE_EN_SHIFT) |
> -		       i915_mmio_reg_offset(reg));
>  }
> 
>  /**
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h
> b/drivers/gpu/drm/i915/display/intel_dsb.h
> index 25f13c4d5389..25d774049cc2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.h
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.h
> @@ -17,8 +17,6 @@ struct intel_dsb *intel_dsb_prepare(struct intel_crtc
> *crtc);  void intel_dsb_cleanup(struct intel_dsb *dsb);  void
> intel_dsb_reg_write(struct intel_dsb *dsb,
>  			 i915_reg_t reg, u32 val);
> -void intel_dsb_indexed_reg_write(struct intel_dsb *dsb,
> -				 i915_reg_t reg, u32 val);
>  void intel_dsb_commit(struct intel_dsb *dsb);
> 
>  #endif
> --
> 2.37.4



More information about the Intel-gfx mailing list