#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"
#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"
* 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
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");
}
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)
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,
/* 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,
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;
}
* "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;
}
*/
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)
!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);
/* ~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;
*/
void intel_dsb_cleanup(struct intel_dsb *dsb)
{
- intel_dsb_buffer_cleanup(dsb->dsb_buf);
+ dsb_buffer_cleanup(dsb);
kfree(dsb);
}
+++ /dev/null
-/* 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
#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"
}
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,
* 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 {
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;
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,
+};
--- /dev/null
+/* 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__ */
#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"
};
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,
* 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;
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;
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;
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,
+};
--- /dev/null
+/* 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
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;
/* 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,
* 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;