]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/{i915, xe}/dsb: move DSB buffer to parent interface
authorJani Nikula <jani.nikula@intel.com>
Tue, 20 Jan 2026 15:45:41 +0000 (17:45 +0200)
committerJani Nikula <jani.nikula@intel.com>
Mon, 26 Jan 2026 09:56:41 +0000 (11:56 +0200)
Move the DSB buffer handling to the display parent interface, making
display more independent of i915 and xe driver implementations.

Since the DSB parent interface is only called from intel_dsb.c, add the
wrappers there with smaller visibility instead of the usual
intel_parent.[ch], and using struct intel_dsb as the context parameter
for convenience.

Unfortunately, memset() being a macro in linux/fortify-string.h, we
can't use that as the function pointer name. dsb->memset() would be
using the macro and leading to build failures. Therefore, use .fill()
for the memset() functionality.

v2: s/memset/fill/

Reviewed-by: Michał Grzelak <michal.grzelak@intel.com>
Link: https://patch.msgid.link/df117c862a6d34dae340e4a85c2482b4e29c8884.1768923917.git.jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_dsb.c
drivers/gpu/drm/i915/display/intel_dsb_buffer.h [deleted file]
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/i915/i915_dsb_buffer.c
drivers/gpu/drm/i915/i915_dsb_buffer.h [new file with mode: 0644]
drivers/gpu/drm/xe/display/xe_display.c
drivers/gpu/drm/xe/display/xe_dsb_buffer.c
drivers/gpu/drm/xe/display/xe_dsb_buffer.h [new file with mode: 0644]
include/drm/intel/display_parent_interface.h

index 91060e2a576247844b98ee38eba5b246001447b7..cf5fb30cab8308c74529a919670d85bc7850fb29 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <drm/drm_print.h>
 #include <drm/drm_vblank.h>
+#include <drm/intel/display_parent_interface.h>
 
 #include "intel_crtc.h"
 #include "intel_de.h"
@@ -15,7 +16,6 @@
 #include "intel_display_rpm.h"
 #include "intel_display_types.h"
 #include "intel_dsb.h"
-#include "intel_dsb_buffer.h"
 #include "intel_dsb_regs.h"
 #include "intel_vblank.h"
 #include "intel_vrr.h"
@@ -75,6 +75,57 @@ struct intel_dsb {
  * writes). There are no registers reads possible with DSB HW engine.
  */
 
+/*
+ * DSB buffer parent interface calls are here instead of intel_parent.[ch]
+ * because they're not used outside of intel_dsb.c.
+ */
+static u32 dsb_buffer_ggtt_offset(struct intel_dsb *dsb)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       return display->parent->dsb->ggtt_offset(dsb->dsb_buf);
+}
+
+static void dsb_buffer_write(struct intel_dsb *dsb, u32 idx, u32 val)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       display->parent->dsb->write(dsb->dsb_buf, idx, val);
+}
+
+static u32 dsb_buffer_read(struct intel_dsb *dsb, u32 idx)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       return display->parent->dsb->read(dsb->dsb_buf, idx);
+}
+
+static void dsb_buffer_fill(struct intel_dsb *dsb, u32 idx, u32 val, size_t size)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       display->parent->dsb->fill(dsb->dsb_buf, idx, val, size);
+}
+
+static struct intel_dsb_buffer *dsb_buffer_create(struct intel_display *display, size_t size)
+{
+       return display->parent->dsb->create(display->drm, size);
+}
+
+static void dsb_buffer_cleanup(struct intel_dsb *dsb)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       display->parent->dsb->cleanup(dsb->dsb_buf);
+}
+
+static void dsb_buffer_flush_map(struct intel_dsb *dsb)
+{
+       struct intel_display *display = to_intel_display(dsb->crtc);
+
+       display->parent->dsb->flush_map(dsb->dsb_buf);
+}
+
 /* DSB opcodes. */
 #define DSB_OPCODE_SHIFT               24
 #define DSB_OPCODE_NOOP                        0x0
@@ -211,10 +262,10 @@ static void intel_dsb_dump(struct intel_dsb *dsb)
        for (i = 0; i < ALIGN(dsb->free_pos, 64 / 4); i += 4)
                drm_dbg_kms(display->drm,
                            " 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", i * 4,
-                           intel_dsb_buffer_read(dsb->dsb_buf, i),
-                           intel_dsb_buffer_read(dsb->dsb_buf, i + 1),
-                           intel_dsb_buffer_read(dsb->dsb_buf, i + 2),
-                           intel_dsb_buffer_read(dsb->dsb_buf, i + 3));
+                           dsb_buffer_read(dsb, i),
+                           dsb_buffer_read(dsb, i + 1),
+                           dsb_buffer_read(dsb, i + 2),
+                           dsb_buffer_read(dsb, i + 3));
        drm_dbg_kms(display->drm, "}\n");
 }
 
@@ -231,12 +282,12 @@ unsigned int intel_dsb_size(struct intel_dsb *dsb)
 
 unsigned int intel_dsb_head(struct intel_dsb *dsb)
 {
-       return intel_dsb_buffer_ggtt_offset(dsb->dsb_buf);
+       return dsb_buffer_ggtt_offset(dsb);
 }
 
 static unsigned int intel_dsb_tail(struct intel_dsb *dsb)
 {
-       return intel_dsb_buffer_ggtt_offset(dsb->dsb_buf) + intel_dsb_size(dsb);
+       return dsb_buffer_ggtt_offset(dsb) + intel_dsb_size(dsb);
 }
 
 static void intel_dsb_ins_align(struct intel_dsb *dsb)
@@ -263,8 +314,8 @@ static void intel_dsb_emit(struct intel_dsb *dsb, u32 ldw, u32 udw)
        dsb->ins[0] = ldw;
        dsb->ins[1] = udw;
 
-       intel_dsb_buffer_write(dsb->dsb_buf, dsb->free_pos++, dsb->ins[0]);
-       intel_dsb_buffer_write(dsb->dsb_buf, dsb->free_pos++, dsb->ins[1]);
+       dsb_buffer_write(dsb, dsb->free_pos++, dsb->ins[0]);
+       dsb_buffer_write(dsb, dsb->free_pos++, dsb->ins[1]);
 }
 
 static bool intel_dsb_prev_ins_is_write(struct intel_dsb *dsb,
@@ -335,13 +386,12 @@ void intel_dsb_reg_write_indexed(struct intel_dsb *dsb,
 
        /* Update the count */
        dsb->ins[0]++;
-       intel_dsb_buffer_write(dsb->dsb_buf, dsb->ins_start_offset + 0,
-                              dsb->ins[0]);
+       dsb_buffer_write(dsb, dsb->ins_start_offset + 0, dsb->ins[0]);
 
-       intel_dsb_buffer_write(dsb->dsb_buf, dsb->free_pos++, val);
+       dsb_buffer_write(dsb, dsb->free_pos++, val);
        /* if number of data words is odd, then the last dword should be 0.*/
        if (dsb->free_pos & 0x1)
-               intel_dsb_buffer_write(dsb->dsb_buf, dsb->free_pos, 0);
+               dsb_buffer_write(dsb, dsb->free_pos, 0);
 }
 
 void intel_dsb_reg_write(struct intel_dsb *dsb,
@@ -521,8 +571,7 @@ static void intel_dsb_align_tail(struct intel_dsb *dsb)
        aligned_tail = ALIGN(tail, CACHELINE_BYTES);
 
        if (aligned_tail > tail)
-               intel_dsb_buffer_memset(dsb->dsb_buf, dsb->free_pos, 0,
-                                       aligned_tail - tail);
+               dsb_buffer_fill(dsb, dsb->free_pos, 0, aligned_tail - tail);
 
        dsb->free_pos = aligned_tail / 4;
 }
@@ -541,8 +590,7 @@ static void intel_dsb_gosub_align(struct intel_dsb *dsb)
         * "Ensure GOSUB is not 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_buffer_fill(dsb, dsb->free_pos, 0, aligned_tail - tail);
 
        dsb->free_pos = aligned_tail / 4;
 }
@@ -606,14 +654,14 @@ void intel_dsb_gosub_finish(struct intel_dsb *dsb)
         */
        intel_dsb_noop(dsb, 8);
 
-       intel_dsb_buffer_flush_map(dsb->dsb_buf);
+       dsb_buffer_flush_map(dsb);
 }
 
 void intel_dsb_finish(struct intel_dsb *dsb)
 {
        intel_dsb_align_tail(dsb);
 
-       intel_dsb_buffer_flush_map(dsb->dsb_buf);
+       dsb_buffer_flush_map(dsb);
 }
 
 static u32 dsb_error_int_status(struct intel_display *display)
@@ -917,7 +965,7 @@ void intel_dsb_wait(struct intel_dsb *dsb)
                              !is_busy,
                              100, 1000, false);
        if (ret) {
-               u32 offset = intel_dsb_buffer_ggtt_offset(dsb->dsb_buf);
+               u32 offset = dsb_buffer_ggtt_offset(dsb);
 
                intel_de_write_fw(display, DSB_CTRL(pipe, dsb->id),
                                  DSB_ENABLE | DSB_HALT);
@@ -983,7 +1031,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state,
        /* ~1 qword per instruction, full cachelines */
        size = ALIGN(max_cmds * 8, CACHELINE_BYTES);
 
-       dsb_buf = intel_dsb_buffer_create(display->drm, size);
+       dsb_buf = dsb_buffer_create(display, size);
        if (IS_ERR(dsb_buf))
                goto out_put_rpm;
 
@@ -1021,7 +1069,7 @@ out:
  */
 void intel_dsb_cleanup(struct intel_dsb *dsb)
 {
-       intel_dsb_buffer_cleanup(dsb->dsb_buf);
+       dsb_buffer_cleanup(dsb);
        kfree(dsb);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_dsb_buffer.h b/drivers/gpu/drm/i915/display/intel_dsb_buffer.h
deleted file mode 100644 (file)
index f4577d1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2023 Intel Corporation
- */
-
-#ifndef _INTEL_DSB_BUFFER_H
-#define _INTEL_DSB_BUFFER_H
-
-#include <linux/types.h>
-
-struct drm_device;
-struct intel_dsb_buffer;
-
-u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf);
-void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val);
-u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx);
-void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size);
-struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t size);
-void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf);
-void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf);
-
-#endif
index f0105c5b49a713bbe03ea5894361ee146b48ea56..1e087dfe03d0991b42b672a4fab20d3353c1534f 100644 (file)
@@ -93,6 +93,7 @@
 #include "i915_driver.h"
 #include "i915_drm_client.h"
 #include "i915_drv.h"
+#include "i915_dsb_buffer.h"
 #include "i915_edram.h"
 #include "i915_file_private.h"
 #include "i915_getparam.h"
@@ -764,6 +765,7 @@ static bool vgpu_active(struct drm_device *drm)
 }
 
 static const struct intel_display_parent_interface parent = {
+       .dsb = &i915_display_dsb_interface,
        .hdcp = &i915_display_hdcp_interface,
        .initial_plane = &i915_display_initial_plane_interface,
        .irq = &i915_display_irq_interface,
index de30d3896f4ad53e4dcf9170d97b4e7fa7f300e3..884ccb2bc28384923e7400e83c1d71668d6e5406 100644 (file)
@@ -3,10 +3,12 @@
  * Copyright 2023, Intel Corporation.
  */
 
-#include "display/intel_dsb_buffer.h"
+#include <drm/intel/display_parent_interface.h>
+
 #include "gem/i915_gem_internal.h"
 #include "gem/i915_gem_lmem.h"
 #include "i915_drv.h"
+#include "i915_dsb_buffer.h"
 #include "i915_vma.h"
 
 struct intel_dsb_buffer {
@@ -15,29 +17,29 @@ struct intel_dsb_buffer {
        size_t buf_size;
 };
 
-u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
+static u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
 {
        return i915_ggtt_offset(dsb_buf->vma);
 }
 
-void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
+static void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
 {
        dsb_buf->cmd_buf[idx] = val;
 }
 
-u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
+static u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
 {
        return dsb_buf->cmd_buf[idx];
 }
 
-void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
+static void intel_dsb_buffer_fill(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
 {
        WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf));
 
        memset(&dsb_buf->cmd_buf[idx], val, size);
 }
 
-struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t size)
+static struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t size)
 {
        struct drm_i915_private *i915 = to_i915(drm);
        struct intel_dsb_buffer *dsb_buf;
@@ -93,13 +95,23 @@ err:
        return ERR_PTR(ret);
 }
 
-void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf)
+static void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf)
 {
        i915_vma_unpin_and_release(&dsb_buf->vma, I915_VMA_RELEASE_MAP);
        kfree(dsb_buf);
 }
 
-void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
+static void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
 {
        i915_gem_object_flush_map(dsb_buf->vma->obj);
 }
+
+const struct intel_display_dsb_interface i915_display_dsb_interface = {
+       .ggtt_offset = intel_dsb_buffer_ggtt_offset,
+       .write = intel_dsb_buffer_write,
+       .read = intel_dsb_buffer_read,
+       .fill = intel_dsb_buffer_fill,
+       .create = intel_dsb_buffer_create,
+       .cleanup = intel_dsb_buffer_cleanup,
+       .flush_map = intel_dsb_buffer_flush_map,
+};
diff --git a/drivers/gpu/drm/i915/i915_dsb_buffer.h b/drivers/gpu/drm/i915/i915_dsb_buffer.h
new file mode 100644 (file)
index 0000000..a01b4d8
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2026 Intel Corporation */
+
+#ifndef __I915_DSB_BUFFER_H__
+#define __I915_DSB_BUFFER_H__
+
+extern const struct intel_display_dsb_interface i915_display_dsb_interface;
+
+#endif /* __I915_DSB_BUFFER_H__ */
index f8a831b5dc7d57f673edece001d1102311b0e894..c640fe3d84900d507bd0f36b14af25eb448a1395 100644 (file)
@@ -36,6 +36,7 @@
 #include "intel_opregion.h"
 #include "skl_watermark.h"
 #include "xe_display_rpm.h"
+#include "xe_dsb_buffer.h"
 #include "xe_hdcp_gsc.h"
 #include "xe_initial_plane.h"
 #include "xe_module.h"
@@ -538,6 +539,7 @@ static const struct intel_display_irq_interface xe_display_irq_interface = {
 };
 
 static const struct intel_display_parent_interface parent = {
+       .dsb = &xe_display_dsb_interface,
        .hdcp = &xe_display_hdcp_interface,
        .initial_plane = &xe_display_initial_plane_interface,
        .irq = &xe_display_irq_interface,
index fa0acb11eaad1263a290c9b8b0a418d830ff348c..fdb0e8a937458257d3e29397a879da8a41a15dae 100644 (file)
@@ -3,10 +3,12 @@
  * Copyright 2023, Intel Corporation.
  */
 
-#include "intel_dsb_buffer.h"
+#include <drm/intel/display_parent_interface.h>
+
 #include "xe_bo.h"
 #include "xe_device.h"
 #include "xe_device_types.h"
+#include "xe_dsb_buffer.h"
 
 struct intel_dsb_buffer {
        u32 *cmd_buf;
@@ -14,29 +16,29 @@ struct intel_dsb_buffer {
        size_t buf_size;
 };
 
-u32 intel_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
+static u32 xe_dsb_buffer_ggtt_offset(struct intel_dsb_buffer *dsb_buf)
 {
        return xe_bo_ggtt_addr(dsb_buf->bo);
 }
 
-void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
+static void xe_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val)
 {
        iosys_map_wr(&dsb_buf->bo->vmap, idx * 4, u32, val);
 }
 
-u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
+static u32 xe_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx)
 {
        return iosys_map_rd(&dsb_buf->bo->vmap, idx * 4, u32);
 }
 
-void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
+static void xe_dsb_buffer_fill(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size)
 {
        WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf));
 
        iosys_map_memset(&dsb_buf->bo->vmap, idx * 4, val, size);
 }
 
-struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t size)
+static struct intel_dsb_buffer *xe_dsb_buffer_create(struct drm_device *drm, size_t size)
 {
        struct xe_device *xe = to_xe_device(drm);
        struct intel_dsb_buffer *dsb_buf;
@@ -69,13 +71,13 @@ err_pin_map:
        return ERR_PTR(ret);
 }
 
-void intel_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf)
+static void xe_dsb_buffer_cleanup(struct intel_dsb_buffer *dsb_buf)
 {
        xe_bo_unpin_map_no_vm(dsb_buf->bo);
        kfree(dsb_buf);
 }
 
-void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
+static void xe_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
 {
        struct xe_device *xe = dsb_buf->bo->tile->xe;
 
@@ -86,3 +88,13 @@ void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf)
        xe_device_wmb(xe);
        xe_device_l2_flush(xe);
 }
+
+const struct intel_display_dsb_interface xe_display_dsb_interface = {
+       .ggtt_offset = xe_dsb_buffer_ggtt_offset,
+       .write = xe_dsb_buffer_write,
+       .read = xe_dsb_buffer_read,
+       .fill = xe_dsb_buffer_fill,
+       .create = xe_dsb_buffer_create,
+       .cleanup = xe_dsb_buffer_cleanup,
+       .flush_map = xe_dsb_buffer_flush_map,
+};
diff --git a/drivers/gpu/drm/xe/display/xe_dsb_buffer.h b/drivers/gpu/drm/xe/display/xe_dsb_buffer.h
new file mode 100644 (file)
index 0000000..2e47721
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2026 Intel Corporation */
+
+#ifndef __XE_DSB_BUFFER_H__
+#define __XE_DSB_BUFFER_H__
+
+extern const struct intel_display_dsb_interface xe_display_dsb_interface;
+
+#endif
index ce946859a3a97f47d3b5f06d5ecf15dac3ca1d3e..cd091120731c98321848fa80b1551d7ac5f51107 100644 (file)
@@ -14,6 +14,7 @@ struct drm_gem_object;
 struct drm_plane_state;
 struct drm_scanout_buffer;
 struct i915_vma;
+struct intel_dsb_buffer;
 struct intel_hdcp_gsc_context;
 struct intel_initial_plane_config;
 struct intel_panic;
@@ -22,6 +23,16 @@ struct ref_tracker;
 
 /* Keep struct definitions sorted */
 
+struct intel_display_dsb_interface {
+       u32 (*ggtt_offset)(struct intel_dsb_buffer *dsb_buf);
+       void (*write)(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val);
+       u32 (*read)(struct intel_dsb_buffer *dsb_buf, u32 idx);
+       void (*fill)(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size);
+       struct intel_dsb_buffer *(*create)(struct drm_device *drm, size_t size);
+       void (*cleanup)(struct intel_dsb_buffer *dsb_buf);
+       void (*flush_map)(struct intel_dsb_buffer *dsb_buf);
+};
+
 struct intel_display_hdcp_interface {
        ssize_t (*gsc_msg_send)(struct intel_hdcp_gsc_context *gsc_context,
                                void *msg_in, size_t msg_in_len,
@@ -106,6 +117,9 @@ struct intel_display_stolen_interface {
  * check the optional pointers.
  */
 struct intel_display_parent_interface {
+       /** @dsb: DSB buffer interface */
+       const struct intel_display_dsb_interface *dsb;
+
        /** @hdcp: HDCP GSC interface */
        const struct intel_display_hdcp_interface *hdcp;