[PATCH 04/11] drm/i915/dsb: Implement intel_dsb_gosub()

Manna, Animesh animesh.manna at intel.com
Wed Apr 16 07:28:01 UTC 2025



> -----Original Message-----
> From: Borah, Chaitanya Kumar <chaitanya.kumar.borah at intel.com>
> Sent: Tuesday, April 8, 2025 4:30 PM
> To: intel-xe at lists.freedesktop.org; intel-gfx at lists.freedesktop.org
> Cc: ville.syrjala at linux.intel.com; Shankar, Uma <uma.shankar at intel.com>;
> Borah, Chaitanya Kumar <chaitanya.kumar.borah at intel.com>; Manna,
> Animesh <animesh.manna at intel.com>
> Subject: [PATCH 04/11] drm/i915/dsb: Implement intel_dsb_gosub()
> 
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> Add support for the new GOSUB DSB instruction (available on ptl+), which
> instructs the DSB to jump to a different buffer, executie the commands there,
> and then return execution to the next instruction in the original buffer.
> 
> There are a few alignment related workarounds that need to be dealt with
> when emitting GOSUB instruction.
> 
> v2: Right shift head and tail pointer passed to gosub command (chaitanya)
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dsb.c | 52 ++++++++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_dsb.h |  2 +
>  2 files changed, 54 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c
> b/drivers/gpu/drm/i915/display/intel_dsb.c
> index 0de15e3a9a56..2cda6fc7857b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.c
> @@ -93,6 +93,9 @@ struct intel_dsb {
>  /* see DSB_REG_VALUE_MASK */
>  #define DSB_OPCODE_POLL			0xA
>  /* see DSB_REG_VALUE_MASK */
> +#define DSB_OPCODE_GOSUB		0xC /* ptl+ */
> +#define   DSB_GOSUB_HEAD_SHIFT		26
> +#define   DSB_GOSUB_TAIL_SHIFT		0
> 
>  static bool pre_commit_is_vrr_active(struct intel_atomic_state *state,
>  				     struct intel_crtc *crtc)
> @@ -533,6 +536,55 @@ static void intel_dsb_align_tail(struct intel_dsb
> *dsb)
>  	dsb->free_pos = aligned_tail / 4;
>  }
> 
> +static void intel_dsb_gosub_align(struct intel_dsb *dsb) {
> +	u32 aligned_tail, tail;
> +
> +	intel_dsb_ins_align(dsb);
> +
> +	tail = dsb->free_pos * 4;
> +	aligned_tail = ALIGN(tail, CACHELINE_BYTES);
> +
> +	/*
> +	 * "The GOSUB instruction cannot be placed in
> +	 *  cacheline QW slot 6 or 7 (numbered 0-7)"
> +	 */
> +	if (aligned_tail - tail <= 2 * 8)
> +		intel_dsb_buffer_memset(&dsb->dsb_buf, dsb->free_pos, 0,
> +					aligned_tail - tail);
> +
> +	dsb->free_pos = aligned_tail / 4;
> +}
> +
> +void intel_dsb_gosub(struct intel_dsb *dsb,
> +		     struct intel_dsb *sub_dsb)
> +{
> +	struct intel_crtc *crtc = dsb->crtc;
> +	struct intel_display *display = to_intel_display(crtc->base.dev);
> +	u64 head_tail;
> +
> +	if (drm_WARN_ON(display->drm, dsb->id != sub_dsb->id))
> +		return;
> +
> +	if (!assert_dsb_tail_is_aligned(sub_dsb))
> +		return;
> +
> +	intel_dsb_gosub_align(dsb);
> +
> +	head_tail = ((u64)(intel_dsb_head(sub_dsb) >> 6) <<
> DSB_GOSUB_HEAD_SHIFT) |
> +		((u64)(intel_dsb_tail(sub_dsb) >> 6) <<
> DSB_GOSUB_TAIL_SHIFT);

Better to add a code comment explaining why right shift needed by 6.
Instead of directly using a magic number in the code a macro can be added like below,
CONVERT_GOSUB_ADDR(x)	(x >> 6)

Regards,
Animesh 
> +
> +	intel_dsb_emit(dsb, lower_32_bits(head_tail),
> +		       (DSB_OPCODE_GOSUB << DSB_OPCODE_SHIFT) |
> +		       upper_32_bits(head_tail));
> +
> +	/*
> +	 * "NOTE: the instructions within the cacheline
> +	 *  FOLLOWING the GOSUB instruction must be NOPs."
> +	 */
> +	intel_dsb_align_tail(dsb);
> +}
> +
>  void intel_dsb_finish(struct intel_dsb *dsb)  {
>  	struct intel_crtc *crtc = dsb->crtc;
> diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h
> b/drivers/gpu/drm/i915/display/intel_dsb.h
> index e843c52bf97c..8b2cf0a7b7e6 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsb.h
> +++ b/drivers/gpu/drm/i915/display/intel_dsb.h
> @@ -57,6 +57,8 @@ void intel_dsb_vblank_evade(struct intel_atomic_state
> *state,  void intel_dsb_poll(struct intel_dsb *dsb,
>  		    i915_reg_t reg, u32 mask, u32 val,
>  		    int wait_us, int count);
> +void intel_dsb_gosub(struct intel_dsb *dsb,
> +		     struct intel_dsb *sub_dsb);
>  void intel_dsb_chain(struct intel_atomic_state *state,
>  		     struct intel_dsb *dsb,
>  		     struct intel_dsb *chained_dsb,
> --
> 2.25.1



More information about the Intel-xe mailing list