[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