]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/{i915,xe}: driver agnostic drm to display pointer chase
authorJani Nikula <jani.nikula@intel.com>
Fri, 26 Sep 2025 11:10:32 +0000 (14:10 +0300)
committerJani Nikula <jani.nikula@intel.com>
Mon, 29 Sep 2025 09:55:50 +0000 (12:55 +0300)
The display driver needs to get from the struct drm_device pointer to
the struct intel_display pointer. Currently, this depends on knowledge
of the struct drm_i915_private and struct xe_device definitions, but
we'd like to hide those definitions from display.

Require the struct drm_device and struct intel_display * members within
struct drm_i915_private and struct xe_device to be placed next to each
other, to be able to figure out the display pointer without knowledge of
the structures.

Use a generic dummy device structure to define the relative offsets of
the drm and display members, and add static assertions to ensure this
holds for both i915 and xe. Use the dummy structure to do the pointer
chase from struct drm_device * to struct intel_display *.

This requires moving the display member in struct xe_device after the
drm member.

Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Suggested-by: Simona Vetter <simona.vetter@ffwll.ch>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://lore.kernel.org/r/20250926111032.1188876-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_display_conversion.c
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/xe/display/xe_display.c
drivers/gpu/drm/xe/xe_device_types.h
include/drm/intel/display_member.h [new file with mode: 0644]

index d56065f22655426d975fffc9f544d8b8847fa074..9a47aa38cf8246f9f1dba8080d438f47c42c70e0 100644 (file)
@@ -1,15 +1,21 @@
 // SPDX-License-Identifier: MIT
 /* Copyright © 2024 Intel Corporation */
 
-#include "i915_drv.h"
-#include "intel_display_conversion.h"
+#include <drm/intel/display_member.h>
 
-static struct intel_display *__i915_to_display(struct drm_i915_private *i915)
-{
-       return i915->display;
-}
+#include "intel_display_conversion.h"
 
 struct intel_display *__drm_to_display(struct drm_device *drm)
 {
-       return __i915_to_display(to_i915(drm));
+       /*
+        * Note: This relies on both struct drm_i915_private and struct
+        * xe_device having the struct drm_device and struct intel_display *
+        * members at the same relative offsets, as defined by struct
+        * __intel_generic_device.
+        *
+        * See also INTEL_DISPLAY_MEMBER_STATIC_ASSERT().
+        */
+       struct __intel_generic_device *d = container_of(drm, struct __intel_generic_device, drm);
+
+       return d->display;
 }
index 95165e45de745e3407c8486abe7fbc18b5d8cb1d..b46cb54ef5dc3516d14b48909bb89d16a0cec4d0 100644 (file)
@@ -46,6 +46,7 @@
 #include <drm/drm_ioctl.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/intel/display_member.h>
 
 #include "display/i9xx_display_sr.h"
 #include "display/intel_bw.h"
@@ -737,6 +738,9 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv)
                         "DRM_I915_DEBUG_RUNTIME_PM enabled\n");
 }
 
+/* Ensure drm and display members are placed properly. */
+INTEL_DISPLAY_MEMBER_STATIC_ASSERT(struct drm_i915_private, drm, display);
+
 static struct drm_i915_private *
 i915_driver_create(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
index 03e497d2081e45474e9f1574d3327711a0b3e87c..6e159bb8ad2fe9da95f0218ab5d7446c3d370982 100644 (file)
@@ -174,6 +174,7 @@ struct i915_selftest_stash {
 struct drm_i915_private {
        struct drm_device drm;
 
+       /* display device data, must be placed after drm device member */
        struct intel_display *display;
 
        /* FIXME: Device release actions should all be moved to drmm_ */
index 19e691fccf8ce8866cb2ea4e2139a8e5cb3e8bc9..5f4044e6318523ca860e57971b9452135766db9c 100644 (file)
@@ -13,6 +13,7 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/intel/display_member.h>
 #include <uapi/drm/xe_drm.h>
 
 #include "soc/intel_dram.h"
@@ -35,6 +36,9 @@
 #include "skl_watermark.h"
 #include "xe_module.h"
 
+/* Ensure drm and display members are placed properly. */
+INTEL_DISPLAY_MEMBER_STATIC_ASSERT(struct xe_device, drm, display);
+
 /* Xe device functions */
 
 /**
index a6c361db11d967a9cb9f646f1ce560abeb418f87..53264b2bb83240db24d217e1a9ab38940a40b6a9 100644 (file)
@@ -217,6 +217,11 @@ struct xe_device {
        /** @drm: drm device */
        struct drm_device drm;
 
+#if IS_ENABLED(CONFIG_DRM_XE_DISPLAY)
+       /** @display: display device data, must be placed after drm device member */
+       struct intel_display *display;
+#endif
+
        /** @devcoredump: device coredump */
        struct xe_devcoredump devcoredump;
 
@@ -617,8 +622,6 @@ struct xe_device {
         * drm_i915_private during build. After cleanup these should go away,
         * migrating to the right sub-structs
         */
-       struct intel_display *display;
-
        const struct dram_info *dram_info;
 
        /*
diff --git a/include/drm/intel/display_member.h b/include/drm/intel/display_member.h
new file mode 100644 (file)
index 0000000..0319ea5
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2025 Intel Corporation */
+
+#ifndef __DRM_INTEL_DISPLAY_H__
+#define __DRM_INTEL_DISPLAY_H__
+
+#include <linux/build_bug.h>
+#include <linux/stddef.h>
+#include <linux/stringify.h>
+
+#include <drm/drm_device.h>
+
+struct intel_display;
+
+/*
+ * A dummy device struct to define the relative offsets of drm and display
+ * members. With the members identically placed in struct drm_i915_private and
+ * struct xe_device, this allows figuring out the struct intel_display pointer
+ * without the definition of either driver specific structure.
+ */
+struct __intel_generic_device {
+       struct drm_device drm;
+       struct intel_display *display;
+};
+
+/**
+ * INTEL_DISPLAY_MEMBER_STATIC_ASSERT() - ensure correct placing of drm and display members
+ * @type: The struct to check
+ * @drm_member: Name of the struct drm_device member
+ * @display_member: Name of the struct intel_display * member.
+ *
+ * Use this static assert macro to ensure the struct drm_i915_private and struct
+ * xe_device struct drm_device and struct intel_display * members are at the
+ * same relative offsets.
+ */
+#define INTEL_DISPLAY_MEMBER_STATIC_ASSERT(type, drm_member, display_member) \
+       static_assert( \
+               offsetof(struct __intel_generic_device, display) - offsetof(struct __intel_generic_device, drm) == \
+               offsetof(type, display_member) - offsetof(type, drm_member), \
+               __stringify(type) " " __stringify(drm_member) " and " __stringify(display_member) " members at invalid offsets")
+
+#endif