From e3f4bdaf2c5bfebcfb483a8caa1fb989ec042e5b Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 11 Sep 2025 18:57:38 -0400 Subject: drm/gem/shmem: Extract drm_gem_shmem_init() from drm_gem_shmem_create() With gem objects in rust, the most ideal way for us to be able to handle gem shmem object creation is to be able to handle the memory allocation of a gem object ourselves - and then have the DRM gem shmem helpers initialize the object we've allocated afterwards. So, let's split out drm_gem_shmem_init() from drm_gem_shmem_create() to allow for doing this. Signed-off-by: Lyude Paul Reviewed-by: Daniel Almeida Link: https://lore.kernel.org/r/20250911230147.650077-2-lyude@redhat.com --- include/drm/drm_gem_shmem_helper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h index 92f5db84b9c2..235dc33127b9 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -107,6 +107,7 @@ struct drm_gem_shmem_object { #define to_drm_gem_shmem_obj(obj) \ container_of(obj, struct drm_gem_shmem_object, base) +int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size); struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size); struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev, size_t size, -- cgit v1.2.3 From c08c931060c7e44452e635e115913dd88214848c Mon Sep 17 00:00:00 2001 From: Lyude Paul Date: Thu, 11 Sep 2025 18:57:39 -0400 Subject: drm/gem/shmem: Extract drm_gem_shmem_release() from drm_gem_shmem_free() At the moment, the way that we currently free gem shmem objects is not ideal for rust bindings. drm_gem_shmem_free() releases all of the associated memory with a gem shmem object with kfree(), which means that for us to correctly release a gem shmem object in rust we have to manually drop all of the contents of our gem object structure in-place by hand before finally calling drm_gem_shmem_free() to release the shmem resources and the allocation for the gem object. Since the only reason this is an issue is because of drm_gem_shmem_free() calling kfree(), we can fix this by splitting drm_gem_shmem_free() out into itself and drm_gem_shmem_release(), where drm_gem_shmem_release() releases the various gem shmem resources without freeing the structure itself. With this, we can safely re-acquire the KBox for the gem object's memory allocation and let rust handle cleaning up all of the other struct members automatically. Signed-off-by: Lyude Paul Reviewed-by: Daniel Almeida Link: https://lore.kernel.org/r/20250911230147.650077-3-lyude@redhat.com --- include/drm/drm_gem_shmem_helper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h index 235dc33127b9..589f7bfe7506 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -112,6 +112,7 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev, size_t size, struct vfsmount *gemfs); +void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem); void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem); -- cgit v1.2.3 From d8c4bddcd8bcb41885d3db2ba18c840c411564c2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 29 Aug 2025 11:13:45 +0200 Subject: drm/fb-helper: Synchronize dirty worker with vblank Before updating the display from the console's shadow buffer, the dirty worker now waits for a vblank. This allows several screen updates to pile up and acts as a rate limiter. If a DRM master is present, it could interfere with the vblank. Don't wait in this case. v4: * share code with WAITFORVSYNC ioctl (Emil) * use lock guard v3: * add back helper->lock * acquire DRM master status while waiting for vblank v2: * don't hold helper->lock while waiting for vblank Signed-off-by: Thomas Zimmermann Acked-by: Sam Ravnborg Link: https://lore.kernel.org/r/20250829091447.46719-1-tzimmermann@suse.de --- include/drm/drm_client.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 146ca80e35db..bdd845e383ef 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -220,6 +220,7 @@ int drm_client_modeset_check(struct drm_client_dev *client); int drm_client_modeset_commit_locked(struct drm_client_dev *client); int drm_client_modeset_commit(struct drm_client_dev *client); int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); +int drm_client_modeset_wait_for_vblank(struct drm_client_dev *client, unsigned int crtc_index); /** * drm_client_for_each_modeset() - Iterate over client modesets -- cgit v1.2.3 From e46efc6a7d288830c4aeaf3c65c7e913a8ca35d7 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 8 Aug 2025 16:49:10 +0200 Subject: drm/bridge: add drm_for_each_bridge_in_chain_scoped() drm_for_each_bridge_in_chain() iterates ofer the bridges in an encoder chain without protecting the lifetime of the bridges using drm_bridge_get/put(). This creates a risk window where the bridge could be freed while iterating on it. Users of drm_for_each_bridge_in_chain() cannot solve this reliably. Add variant of drm_for_each_bridge_in_chain() that gets/puts the bridge reference at the beginning/end of each iteration, and puts it if breaking ot of the loop. Note that this requires adding a new drm_bridge_get_next_bridge_and_put() function because, unlike similar functions as __of_get_next_child(), drm_bridge_get_next_bridge() gets the "next" pointer but does not put the "prev" pointer. Unfortunately drm_bridge_get_next_bridge() cannot be modified to put the "prev" pointer because some of its users rely on this, such as drm_atomic_bridge_propagate_bus_flags(). Also deprecate drm_for_each_bridge_in_chain(), in preparation for removing it after converting all users to the scoped version. Reviewed-by: Maxime Ripard Link: https://lore.kernel.org/r/20250808-drm-bridge-alloc-getput-for_each_bridge-v2-3-edb6ee81edf1@bootlin.com Signed-off-by: Luca Ceresoli --- include/drm/drm_bridge.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 76e05930f50e..57a3d3cd08e7 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1440,10 +1440,51 @@ drm_bridge_chain_get_last_bridge(struct drm_encoder *encoder) * iteration * * Iterate over all bridges present in the bridge chain attached to @encoder. + * + * This is deprecated, do not use! + * New drivers shall use drm_for_each_bridge_in_chain_scoped(). */ #define drm_for_each_bridge_in_chain(encoder, bridge) \ list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node) +/** + * drm_bridge_get_next_bridge_and_put - Get the next bridge in the chain + * and put the previous + * @bridge: bridge object + * + * Same as drm_bridge_get_next_bridge() but additionally puts the @bridge. + * + * RETURNS: + * the next bridge in the chain after @bridge, or NULL if @bridge is the last. + */ +static inline struct drm_bridge * +drm_bridge_get_next_bridge_and_put(struct drm_bridge *bridge) +{ + struct drm_bridge *next = drm_bridge_get_next_bridge(bridge); + + drm_bridge_put(bridge); + + return next; +} + +/** + * drm_for_each_bridge_in_chain_scoped - iterate over all bridges attached + * to an encoder + * @encoder: the encoder to iterate bridges on + * @bridge: a bridge pointer updated to point to the current bridge at each + * iteration + * + * Iterate over all bridges present in the bridge chain attached to @encoder. + * + * Automatically gets/puts the bridge reference while iterating, and puts + * the reference even if returning or breaking in the middle of the loop. + */ +#define drm_for_each_bridge_in_chain_scoped(encoder, bridge) \ + for (struct drm_bridge *bridge __free(drm_bridge_put) = \ + drm_bridge_chain_get_first_bridge(encoder); \ + bridge; \ + bridge = drm_bridge_get_next_bridge_and_put(bridge)) + enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, -- cgit v1.2.3 From 2f08387a444c4fb2e983305356f030d50978d21d Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 8 Aug 2025 16:49:14 +0200 Subject: drm/bridge: remove drm_for_each_bridge_in_chain() All users have been replaced by drm_for_each_bridge_in_chain_scoped(). Reviewed-by: Maxime Ripard Link: https://lore.kernel.org/r/20250808-drm-bridge-alloc-getput-for_each_bridge-v2-7-edb6ee81edf1@bootlin.com Signed-off-by: Luca Ceresoli --- include/drm/drm_bridge.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 57a3d3cd08e7..c45dece368ad 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1433,20 +1433,6 @@ drm_bridge_chain_get_last_bridge(struct drm_encoder *encoder) struct drm_bridge, chain_node)); } -/** - * drm_for_each_bridge_in_chain() - Iterate over all bridges present in a chain - * @encoder: the encoder to iterate bridges on - * @bridge: a bridge pointer updated to point to the current bridge at each - * iteration - * - * Iterate over all bridges present in the bridge chain attached to @encoder. - * - * This is deprecated, do not use! - * New drivers shall use drm_for_each_bridge_in_chain_scoped(). - */ -#define drm_for_each_bridge_in_chain(encoder, bridge) \ - list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node) - /** * drm_bridge_get_next_bridge_and_put - Get the next bridge in the chain * and put the previous -- cgit v1.2.3 From 78f4eec62097754fed1b910544ff60ef10a76554 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 8 Aug 2025 16:49:15 +0200 Subject: drm/bridge: add drm_for_each_bridge_in_chain_from() Add variant of drm_for_each_bridge_in_chain_scoped() that iterates on the encoder bridge from a given bridge until the end of the chain. Reviewed-by: Maxime Ripard Link: https://lore.kernel.org/r/20250808-drm-bridge-alloc-getput-for_each_bridge-v2-8-edb6ee81edf1@bootlin.com Signed-off-by: Luca Ceresoli --- include/drm/drm_bridge.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index c45dece368ad..d1aba4e25d35 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1471,6 +1471,25 @@ drm_bridge_get_next_bridge_and_put(struct drm_bridge *bridge) bridge; \ bridge = drm_bridge_get_next_bridge_and_put(bridge)) +/** + * drm_for_each_bridge_in_chain_from - iterate over all bridges starting + * from the given bridge + * @first_bridge: the bridge to start from + * @bridge: a bridge pointer updated to point to the current bridge at each + * iteration + * + * Iterate over all bridges in the encoder chain starting from + * @first_bridge, included. + * + * Automatically gets/puts the bridge reference while iterating, and puts + * the reference even if returning or breaking in the middle of the loop. + */ +#define drm_for_each_bridge_in_chain_from(first_bridge, bridge) \ + for (struct drm_bridge *bridge __free(drm_bridge_put) = \ + drm_bridge_get(first_bridge); \ + bridge; \ + bridge = drm_bridge_get_next_bridge_and_put(bridge)) + enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, -- cgit v1.2.3 From 61aa4f7a600871f9ad96a0ad355b483b0ac4b67d Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 1 Aug 2025 19:05:29 +0200 Subject: drm/bridge: get the bridge returned by drm_bridge_get_next_bridge() drm_bridge_get_next_bridge() returns a bridge pointer that the caller could hold for a long time. Increment the refcount of the returned bridge and document it must be put by the caller. Reviewed-by: Maxime Ripard Link: https://lore.kernel.org/r/20250801-drm-bridge-alloc-getput-drm_bridge_get_next_bridge-v2-7-888912b0be13@bootlin.com Signed-off-by: Luca Ceresoli --- include/drm/drm_bridge.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index d1aba4e25d35..0ff7ab4aa868 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -1362,6 +1362,13 @@ drm_bridge_get_current_state(struct drm_bridge *bridge) * drm_bridge_get_next_bridge() - Get the next bridge in the chain * @bridge: bridge object * + * The caller is responsible of having a reference to @bridge via + * drm_bridge_get() or equivalent. This function leaves the refcount of + * @bridge unmodified. + * + * The refcount of the returned bridge is incremented. Use drm_bridge_put() + * when done with it. + * * RETURNS: * the next bridge in the chain after @bridge, or NULL if @bridge is the last. */ @@ -1371,7 +1378,7 @@ drm_bridge_get_next_bridge(struct drm_bridge *bridge) if (list_is_last(&bridge->chain_node, &bridge->encoder->bridge_chain)) return NULL; - return list_next_entry(bridge, chain_node); + return drm_bridge_get(list_next_entry(bridge, chain_node)); } /** -- cgit v1.2.3 From ed7a4397f55bfacf2c4c3e466940ed4961707094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 13 Jun 2025 14:09:08 +0200 Subject: drm/ttm: rename ttm_bo_put to _fini v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Give TTM BOs a separate cleanup function. No funktional change, but the next step in removing the TTM BO reference counting and replacing it with the GEM object reference counting. v2: move the code around a bit to make it clearer what's happening v3: fix nouveau_bo_fini as well Signed-off-by: Christian König Acked-by: Thomas Hellström Acked-by: Joonas Lahtinen Link: https://lore.kernel.org/r/20250909144311.1927-1-christian.koenig@amd.com --- include/drm/ttm/ttm_bo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index e664a96540eb..bca3a8849d47 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -391,7 +391,7 @@ int ttm_bo_wait_ctx(struct ttm_buffer_object *bo, int ttm_bo_validate(struct ttm_buffer_object *bo, struct ttm_placement *placement, struct ttm_operation_ctx *ctx); -void ttm_bo_put(struct ttm_buffer_object *bo); +void ttm_bo_fini(struct ttm_buffer_object *bo); void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo, struct ttm_lru_bulk_move *bulk); bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, -- cgit v1.2.3 From 091767ee7510765886b8475c44fd81b2e6e9da87 Mon Sep 17 00:00:00 2001 From: Luc Ma Date: Mon, 15 Sep 2025 21:23:26 +0800 Subject: drm/sched: backend_ops doc fix Function drm_sched_entity_do_release() has been renamed in commit 180fc134d712 ("drm/scheduler: Rename cleanup functions v2."). Refer to the correct function in the documentation. Signed-off-by: Luc Ma [phasta: commit message] Signed-off-by: Philipp Stanner Link: https://lore.kernel.org/r/20250915132327.6293-1-onion0709@gmail.com --- include/drm/gpu_scheduler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 323a505e6e6a..fb88301b3c45 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -546,7 +546,7 @@ struct drm_sched_backend_ops { * @num_rqs: Number of run-queues. This is at most DRM_SCHED_PRIORITY_COUNT, * as there's usually one run-queue per priority, but could be less. * @sched_rq: An allocated array of run-queues of size @num_rqs; - * @job_scheduled: once @drm_sched_entity_do_release is called the scheduler + * @job_scheduled: once drm_sched_entity_flush() is called the scheduler * waits on this wait queue until all the scheduled jobs are * finished. * @job_id_count: used to assign unique id to the each job. -- cgit v1.2.3 From 0bf37f45d5c472aebdf32da64775cac1110c085c Mon Sep 17 00:00:00 2001 From: Andrzej Kacprowski Date: Mon, 15 Sep 2025 12:34:37 +0200 Subject: accel/ivpu: Add support for user-managed preemption buffer Allow user mode drivers to manage preemption buffers, enabling memory savings by sharing a single buffer across multiple command queues within the same memory context. Introduce DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE to report the required preemption buffer size as specified by the firmware. The preemption buffer is now passed from user space as an entry in the BO list of DRM_IVPU_CMDQ_SUBMIT. The buffer must be non-mappable and large enough to hold preemption data. For backward compatibility, the kernel will allocate an internal preemption buffer if user space does not provide one. User space can only provide a single preemption buffer, simplifying the ioctl interface and parameter validation. A separate secondary preemption buffer is only needed to save below 4GB address space on 37xx and only if preemption buffers are not shared. Signed-off-by: Andrzej Kacprowski Reviewed-by: Lizhi Hou Signed-off-by: Karol Wachowski Link: https://lore.kernel.org/r/20250915103437.830086-1-karol.wachowski@linux.intel.com --- include/uapi/drm/ivpu_accel.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 160ee1411d4a..e470b0221e02 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -90,6 +90,7 @@ extern "C" { #define DRM_IVPU_PARAM_TILE_CONFIG 11 #define DRM_IVPU_PARAM_SKU 12 #define DRM_IVPU_PARAM_CAPABILITIES 13 +#define DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE 14 #define DRM_IVPU_PLATFORM_TYPE_SILICON 0 @@ -176,6 +177,9 @@ struct drm_ivpu_param { * * %DRM_IVPU_PARAM_CAPABILITIES: * Supported capabilities (read-only) + * + * %DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE: + * Size of the preemption buffer (read-only) */ __u32 param; @@ -371,6 +375,13 @@ struct drm_ivpu_cmdq_submit { * to be executed. The offset has to be 8-byte aligned. */ __u32 commands_offset; + /** + * @preempt_buffer_index: + * + * Index of the preemption buffer in the buffers_ptr array. + */ + __u32 preempt_buffer_index; + __u32 reserved; }; /* drm_ivpu_bo_wait job status codes */ -- cgit v1.2.3 From b060004f06ae0a3064bddb87a3f8ad13f859fcf3 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 17 Sep 2025 20:18:37 +0100 Subject: drm/panfrost: Introduce uAPI for JM context creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new uAPI lets user space query the KM driver for the available priorities a job can be given at submit time. These are managed through the notion of a context, for which we also provide new creation and destruction ioctls. Reviewed-by: Steven Price Signed-off-by: Boris Brezillon Signed-off-by: Adrián Larumbe Signed-off-by: Steven Price Link: https://lore.kernel.org/r/20250917191859.500279-2-adrian.larumbe@collabora.com --- include/uapi/drm/panfrost_drm.h | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index ed67510395bd..e8b47c9f6976 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -22,6 +22,8 @@ extern "C" { #define DRM_PANFROST_PERFCNT_DUMP 0x07 #define DRM_PANFROST_MADVISE 0x08 #define DRM_PANFROST_SET_LABEL_BO 0x09 +#define DRM_PANFROST_JM_CTX_CREATE 0x0a +#define DRM_PANFROST_JM_CTX_DESTROY 0x0b #define DRM_IOCTL_PANFROST_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_SUBMIT, struct drm_panfrost_submit) #define DRM_IOCTL_PANFROST_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo) @@ -31,6 +33,8 @@ extern "C" { #define DRM_IOCTL_PANFROST_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_GET_BO_OFFSET, struct drm_panfrost_get_bo_offset) #define DRM_IOCTL_PANFROST_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_MADVISE, struct drm_panfrost_madvise) #define DRM_IOCTL_PANFROST_SET_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_SET_LABEL_BO, struct drm_panfrost_set_label_bo) +#define DRM_IOCTL_PANFROST_JM_CTX_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_JM_CTX_CREATE, struct drm_panfrost_jm_ctx_create) +#define DRM_IOCTL_PANFROST_JM_CTX_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_JM_CTX_DESTROY, struct drm_panfrost_jm_ctx_destroy) /* * Unstable ioctl(s): only exposed when the unsafe unstable_ioctls module @@ -71,6 +75,12 @@ struct drm_panfrost_submit { /** A combination of PANFROST_JD_REQ_* */ __u32 requirements; + + /** JM context handle. Zero if you want to use the default context. */ + __u32 jm_ctx_handle; + + /** Padding field. MBZ. */ + __u32 pad; }; /** @@ -177,6 +187,7 @@ enum drm_panfrost_param { DRM_PANFROST_PARAM_AFBC_FEATURES, DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP, DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP_FREQUENCY, + DRM_PANFROST_PARAM_ALLOWED_JM_CTX_PRIORITIES, }; struct drm_panfrost_get_param { @@ -299,6 +310,45 @@ struct panfrost_dump_registers { __u32 value; }; +enum drm_panfrost_jm_ctx_priority { + /** + * @PANFROST_JM_CTX_PRIORITY_LOW: Low priority context. + */ + PANFROST_JM_CTX_PRIORITY_LOW = 0, + + /** + * @PANFROST_JM_CTX_PRIORITY_MEDIUM: Medium priority context. + */ + PANFROST_JM_CTX_PRIORITY_MEDIUM, + + /** + * @PANFROST_JM_CTX_PRIORITY_HIGH: High priority context. + * + * Requires CAP_SYS_NICE or DRM_MASTER. + */ + PANFROST_JM_CTX_PRIORITY_HIGH, +}; + +struct drm_panfrost_jm_ctx_create { + /** @handle: Handle of the created JM context */ + __u32 handle; + + /** @priority: Context priority (see enum drm_panfrost_jm_ctx_priority). */ + __u32 priority; +}; + +struct drm_panfrost_jm_ctx_destroy { + /** + * @handle: Handle of the JM context to destroy. + * + * Must be a valid context handle returned by DRM_IOCTL_PANTHOR_JM_CTX_CREATE. + */ + __u32 handle; + + /** @pad: Padding field, MBZ. */ + __u32 pad; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From 2b8e4b94c1b6cea1b4d3f989b3dfe4301d0d3a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 18 Jul 2025 15:01:51 +0300 Subject: drm/dp: Add definitions for POST_LT_ADJ training sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the bit definitions needed for POST_LT_ADJ sequence. v2: DP_POST_LT_ADJ_REQ_IN_PROGRESS is bit 1 not 5 (Jani) Tested-by: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250718120154.15492-2-ville.syrjala@linux.intel.com --- include/drm/display/drm_dp.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 811e9238a77c..cf318e3ddb5c 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -115,6 +115,7 @@ #define DP_MAX_LANE_COUNT 0x002 # define DP_MAX_LANE_COUNT_MASK 0x1f +# define DP_POST_LT_ADJ_REQ_SUPPORTED (1 << 5) /* 1.3 */ # define DP_TPS3_SUPPORTED (1 << 6) /* 1.2 */ # define DP_ENHANCED_FRAME_CAP (1 << 7) @@ -583,6 +584,7 @@ #define DP_LANE_COUNT_SET 0x101 # define DP_LANE_COUNT_MASK 0x0f +# define DP_POST_LT_ADJ_REQ_GRANTED (1 << 5) /* 1.3 */ # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) #define DP_TRAINING_PATTERN_SET 0x102 @@ -800,6 +802,7 @@ #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 #define DP_INTERLANE_ALIGN_DONE (1 << 0) +#define DP_POST_LT_ADJ_REQ_IN_PROGRESS (1 << 1) /* 1.3 */ #define DP_128B132B_DPRX_EQ_INTERLANE_ALIGN_DONE (1 << 2) /* 2.0 E11 */ #define DP_128B132B_DPRX_CDS_INTERLANE_ALIGN_DONE (1 << 3) /* 2.0 E11 */ #define DP_128B132B_LT_FAILED (1 << 4) /* 2.0 E11 */ -- cgit v1.2.3 From 3a9cf301794c1a49d95eeb13119ff490fb5cfe88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 18 Jul 2025 15:01:52 +0300 Subject: drm/dp: Add POST_LT_ADJ_REQ helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add small helpers (drm_dp_post_lt_adj_req_supported() and drm_dp_post_lt_adj_req_in_progress()) to help with implementing the POST_LT_ADJ_REQ sequence. Tested-by: Imre Deak Reviewed-by: Imre Deak Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20250718120154.15492-3-ville.syrjala@linux.intel.com --- include/drm/display/drm_dp_helper.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 87caa4f1fdb8..52ce28097015 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -37,6 +37,7 @@ bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count); bool drm_dp_clock_recovery_ok(const u8 link_status[DP_LINK_STATUS_SIZE], int lane_count); +bool drm_dp_post_lt_adj_req_in_progress(const u8 link_status[DP_LINK_STATUS_SIZE]); u8 drm_dp_get_adjust_request_voltage(const u8 link_status[DP_LINK_STATUS_SIZE], int lane); u8 drm_dp_get_adjust_request_pre_emphasis(const u8 link_status[DP_LINK_STATUS_SIZE], @@ -155,6 +156,13 @@ drm_dp_enhanced_frame_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) (dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP); } +static inline bool +drm_dp_post_lt_adj_req_supported(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) +{ + return dpcd[DP_DPCD_REV] >= 0x13 && + (dpcd[DP_MAX_LANE_COUNT] & DP_POST_LT_ADJ_REQ_SUPPORTED); +} + static inline bool drm_dp_fast_training_cap(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) { -- cgit v1.2.3 From 3a33c48876bc437d149cc15e0c4b96efb14912a1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 18 Sep 2025 17:39:51 +0200 Subject: drm/format-helper: Remove drm_fb_blit() The function is unused; remove it. Instead of relying on a general blit helper, drivers should pick a blit function by themselves from their list of supported color formats. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20250918154207.84714-4-tzimmermann@suse.de --- include/drm/drm_format_helper.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 32d57d6c5327..2b5c1aef80b0 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -128,10 +128,6 @@ void drm_fb_argb8888_to_argb4444(struct iosys_map *dst, const unsigned int *dst_ const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state); -int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format, - const struct iosys_map *src, const struct drm_framebuffer *fb, - const struct drm_rect *clip, struct drm_format_conv_state *state); - void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip, struct drm_format_conv_state *state); -- cgit v1.2.3 From 32620e176443bf23ec81bfe8f177c6721a904864 Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Bhadane Date: Mon, 22 Sep 2025 20:33:15 +0530 Subject: drm/pcids: Split PTL pciids group to make wcl subplatform To form the WCL platform as a subplatform of PTL in definition, WCL pci ids are splited into saparate group from PTL. So update the pciidlist struct to cover all the pci ids. v2: - Squash wcl description in single patch for display and xe.(jani,gustavo) Signed-off-by: Dnyaneshwar Bhadane Reviewed-by: Gustavo Sousa Signed-off-by: Suraj Kandpal Link: https://lore.kernel.org/r/20250922150317.2334680-2-dnyaneshwar.bhadane@intel.com --- include/drm/intel/pciids.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index da6301a6fcea..69d4ae92d822 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -877,7 +877,10 @@ MACRO__(0xB08F, ## __VA_ARGS__), \ MACRO__(0xB090, ## __VA_ARGS__), \ MACRO__(0xB0A0, ## __VA_ARGS__), \ - MACRO__(0xB0B0, ## __VA_ARGS__), \ + MACRO__(0xB0B0, ## __VA_ARGS__) + +/* WCL */ +#define INTEL_WCL_IDS(MACRO__, ...) \ MACRO__(0xFD80, ## __VA_ARGS__), \ MACRO__(0xFD81, ## __VA_ARGS__) -- cgit v1.2.3 From be0bd958cedd4adaaaa4c5aa1e0361de01e208e3 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 23 Sep 2025 13:29:56 +0800 Subject: ALSA: Add definitions for the bits in IEC958 subframe The IEC958 subframe format SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE are used in HDMI and DisplayPort to describe the audio stream, but hardware device may need to reorder the IEC958 bits for internal transmission, so need these standard bits definitions for IEC958 subframe format. Signed-off-by: Shengjiu Wang Reviewed-by: Takashi Iwai Tested-by: Alexander Stein Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20250923053001.2678596-3-shengjiu.wang@nxp.com --- include/sound/asoundef.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/sound/asoundef.h b/include/sound/asoundef.h index 09b2c3dffb30..c4a929d4fd51 100644 --- a/include/sound/asoundef.h +++ b/include/sound/asoundef.h @@ -12,6 +12,15 @@ * Digital audio interface * * * ****************************************************************************/ +/* IEC958 subframe format */ +#define IEC958_SUBFRAME_PREAMBLE_MASK (0xfU) +#define IEC958_SUBFRAME_AUXILIARY_MASK (0xfU << 4) +#define IEC958_SUBFRAME_SAMPLE_24_MASK (0xffffffU << 4) +#define IEC958_SUBFRAME_SAMPLE_20_MASK (0xfffffU << 8) +#define IEC958_SUBFRAME_VALIDITY (0x1U << 28) +#define IEC958_SUBFRAME_USER_DATA (0x1U << 29) +#define IEC958_SUBFRAME_CHANNEL_STATUS (0x1U << 30) +#define IEC958_SUBFRAME_PARITY (0x1U << 31) /* AES/IEC958 channel status bits */ #define IEC958_AES0_PROFESSIONAL (1<<0) /* 0 = consumer, 1 = professional */ -- cgit v1.2.3 From 21d4c95e4b06e6f2d981f476bbbd934451a2edcd Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 23 Sep 2025 13:29:57 +0800 Subject: drm/bridge: dw-hdmi: Add API dw_hdmi_to_plat_data() to get plat_data Add API dw_hdmi_to_plat_data() to fetch plat_data because audio device driver needs it to enable(disable)_audio(). Signed-off-by: Shengjiu Wang Acked-by: Liu Ying Tested-by: Alexander Stein Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20250923053001.2678596-4-shengjiu.wang@nxp.com --- include/drm/bridge/dw_hdmi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 6a46baa0737c..b8fc4fdf5a21 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -208,4 +208,6 @@ void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data); bool dw_hdmi_bus_fmt_is_420(struct dw_hdmi *hdmi); +const struct dw_hdmi_plat_data *dw_hdmi_to_plat_data(struct dw_hdmi *hdmi); + #endif /* __IMX_HDMI_H__ */ -- cgit v1.2.3 From 80c5d14434c94074fcf89016f89c65c209475268 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 23 Sep 2025 13:29:58 +0800 Subject: drm/bridge: dw-hdmi: Add API dw_hdmi_set_sample_iec958() for iec958 format Add API dw_hdmi_set_sample_iec958() for IEC958 format because audio device driver needs IEC958 information to configure this specific setting. Signed-off-by: Shengjiu Wang Acked-by: Liu Ying Tested-by: Alexander Stein Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20250923053001.2678596-5-shengjiu.wang@nxp.com --- include/drm/bridge/dw_hdmi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index b8fc4fdf5a21..095cdd9b7424 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -145,7 +145,7 @@ struct dw_hdmi_plat_data { /* Platform-specific audio enable/disable (optional) */ void (*enable_audio)(struct dw_hdmi *hdmi, int channel, - int width, int rate, int non_pcm); + int width, int rate, int non_pcm, int iec958); void (*disable_audio)(struct dw_hdmi *hdmi); /* Vendor PHY support */ @@ -179,6 +179,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense); int dw_hdmi_set_plugged_cb(struct dw_hdmi *hdmi, hdmi_codec_plugged_cb fn, struct device *codec_dev); void dw_hdmi_set_sample_non_pcm(struct dw_hdmi *hdmi, unsigned int non_pcm); +void dw_hdmi_set_sample_iec958(struct dw_hdmi *hdmi, unsigned int iec958); void dw_hdmi_set_sample_width(struct dw_hdmi *hdmi, unsigned int width); void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt); -- cgit v1.2.3 From 0205fae6327a4ef6bdb9b6dd9722c17613c422cb Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 23 Sep 2025 13:29:59 +0800 Subject: drm/bridge: imx: add driver for HDMI TX Parallel Audio Interface The HDMI TX Parallel Audio Interface (HTX_PAI) is a digital module that acts as the bridge between the Audio Subsystem to the HDMI TX Controller. This IP block is found in the HDMI subsystem of the i.MX8MP SoC. Data received from the audio subsystem can have an arbitrary component ordering. The HTX_PAI block has integrated muxing options to select which sections of the 32-bit input data word will be mapped to each IEC60958 field. The HTX_PAI_FIELD_CTRL register contains mux selects to individually select P,C,U,V,Data, and Preamble. Use component helper so that imx8mp-hdmi-tx will be aggregate driver, imx8mp-hdmi-pai will be component driver, then imx8mp-hdmi-pai can use bind() ops to get the plat_data from imx8mp-hdmi-tx device. Signed-off-by: Shengjiu Wang Reviewed-by: Liu Ying Tested-by: Alexander Stein Signed-off-by: Liu Ying Link: https://lore.kernel.org/r/20250923053001.2678596-6-shengjiu.wang@nxp.com --- include/drm/bridge/dw_hdmi.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 095cdd9b7424..336f062e1f9d 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -143,6 +143,12 @@ struct dw_hdmi_plat_data { const struct drm_display_info *info, const struct drm_display_mode *mode); + /* + * priv_audio is specially used for additional audio device to get + * driver data through this dw_hdmi_plat_data. + */ + void *priv_audio; + /* Platform-specific audio enable/disable (optional) */ void (*enable_audio)(struct dw_hdmi *hdmi, int channel, int width, int rate, int non_pcm, int iec958); -- cgit v1.2.3 From 97825e1c6de7315cba9acb6c1371f1a87dedd904 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 26 Sep 2025 14:10:32 +0300 Subject: drm/{i915,xe}: driver agnostic drm to display pointer chase 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 Cc: Rodrigo Vivi Cc: Ville Syrjala Suggested-by: Simona Vetter Reviewed-by: Lucas De Marchi Link: https://lore.kernel.org/r/20250926111032.1188876-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/intel/display_member.h | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 include/drm/intel/display_member.h (limited to 'include') diff --git a/include/drm/intel/display_member.h b/include/drm/intel/display_member.h new file mode 100644 index 000000000000..0319ea560b60 --- /dev/null +++ b/include/drm/intel/display_member.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __DRM_INTEL_DISPLAY_H__ +#define __DRM_INTEL_DISPLAY_H__ + +#include +#include +#include + +#include + +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 -- cgit v1.2.3 From fb24aaf5415cc686fb0473eb782a7c8a7bab0469 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 21 Aug 2025 10:17:09 +0200 Subject: drm/dumb-buffers: Provide helper to set pitch and size Add drm_modes_size_dumb(), a helper to calculate the dumb-buffer scanline pitch and allocation size. Implementations of struct drm_driver.dumb_create can call the new helper for their size computations. There is currently quite a bit of code duplication among DRM's memory managers. Each calculates scanline pitch and buffer size from the given arguments, but the implementations are inconsistent in how they treat alignment and format support. Later patches will unify this code on top of drm_mode_size_dumb() as much as possible. drm_mode_size_dumb() uses existing 4CC format helpers to interpret the given color mode. This makes the dumb-buffer interface behave similar the kernel's video= parameter. Current per-driver implementations again likely have subtle differences or bugs in how they support color modes. The dumb-buffer UAPI is only specified for known color modes. These values describe linear, single-plane RGB color formats or legacy index formats. Other values should not be specified. But some user space still does. So for unknown color modes, there are a number of known exceptions for which drm_mode_size_dumb() calculates the pitch from the bpp value, as before. All other values work the same but print an error. v6: - document additional use cases for DUMB_CREATE2 in TODO list (Tomi) - fix typos in documentation (Tomi) v5: - check for overflows with check_mul_overflow() (Tomi) v4: - use %u conversion specifier (Geert) - list DRM_FORMAT_Dn in UAPI docs (Geert) - avoid dmesg spamming with drm_warn_once() (Sima) - add more information about bpp special case (Sima) - clarify parameters for hardware alignment - add a TODO item for DUMB_CREATE2 v3: - document the UAPI semantics - compute scanline pitch from for unknown color modes (Andy, Tomi) Signed-off-by: Thomas Zimmermann Reviewed-by: Tomi Valkeinen Reviewed-by: Tomi Valkeinen Link: https://lore.kernel.org/r/20250821081918.79786-3-tzimmermann@suse.de --- include/drm/drm_dumb_buffers.h | 14 ++++++++++++ include/uapi/drm/drm_mode.h | 50 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 include/drm/drm_dumb_buffers.h (limited to 'include') diff --git a/include/drm/drm_dumb_buffers.h b/include/drm/drm_dumb_buffers.h new file mode 100644 index 000000000000..1f3a8236fb3d --- /dev/null +++ b/include/drm/drm_dumb_buffers.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __DRM_DUMB_BUFFERS_H__ +#define __DRM_DUMB_BUFFERS_H__ + +struct drm_device; +struct drm_mode_create_dumb; + +int drm_mode_size_dumb(struct drm_device *dev, + struct drm_mode_create_dumb *args, + unsigned long hw_pitch_align, + unsigned long hw_size_align); + +#endif diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index a122bea25593..1e0e02a79b5c 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -1066,7 +1066,7 @@ struct drm_mode_crtc_page_flip_target { * struct drm_mode_create_dumb - Create a KMS dumb buffer for scanout. * @height: buffer height in pixels * @width: buffer width in pixels - * @bpp: bits per pixel + * @bpp: color mode * @flags: must be zero * @handle: buffer object handle * @pitch: number of bytes between two consecutive lines @@ -1074,6 +1074,54 @@ struct drm_mode_crtc_page_flip_target { * * User-space fills @height, @width, @bpp and @flags. If the IOCTL succeeds, * the kernel fills @handle, @pitch and @size. + * + * The value of @bpp is a color-mode number describing a specific format + * or a variant thereof. The value often corresponds to the number of bits + * per pixel for most modes, although there are exceptions. Each color mode + * maps to a DRM format plus a number of modes with similar pixel layout. + * Framebuffer layout is always linear. + * + * Support for all modes and formats is optional. Even if dumb-buffer + * creation with a certain color mode succeeds, it is not guaranteed that + * the DRM driver supports any of the related formats. Most drivers support + * a color mode of 32 with a format of DRM_FORMAT_XRGB8888 on their primary + * plane. + * + * +------------+------------------------+------------------------+ + * | Color mode | Framebuffer format | Compatible formats | + * +============+========================+========================+ + * | 32 | * DRM_FORMAT_XRGB8888 | * DRM_FORMAT_BGRX8888 | + * | | | * DRM_FORMAT_RGBX8888 | + * | | | * DRM_FORMAT_XBGR8888 | + * +------------+------------------------+------------------------+ + * | 24 | * DRM_FORMAT_RGB888 | * DRM_FORMAT_BGR888 | + * +------------+------------------------+------------------------+ + * | 16 | * DRM_FORMAT_RGB565 | * DRM_FORMAT_BGR565 | + * +------------+------------------------+------------------------+ + * | 15 | * DRM_FORMAT_XRGB1555 | * DRM_FORMAT_BGRX1555 | + * | | | * DRM_FORMAT_RGBX1555 | + * | | | * DRM_FORMAT_XBGR1555 | + * +------------+------------------------+------------------------+ + * | 8 | * DRM_FORMAT_C8 | * DRM_FORMAT_D8 | + * | | | * DRM_FORMAT_R8 | + * +------------+------------------------+------------------------+ + * | 4 | * DRM_FORMAT_C4 | * DRM_FORMAT_D4 | + * | | | * DRM_FORMAT_R4 | + * +------------+------------------------+------------------------+ + * | 2 | * DRM_FORMAT_C2 | * DRM_FORMAT_D2 | + * | | | * DRM_FORMAT_R2 | + * +------------+------------------------+------------------------+ + * | 1 | * DRM_FORMAT_C1 | * DRM_FORMAT_D1 | + * | | | * DRM_FORMAT_R1 | + * +------------+------------------------+------------------------+ + * + * Color modes of 10, 12, 15, 30 and 64 are only supported for use by + * legacy user space. Please don't use them in new code. Other modes + * are not support. + * + * Do not attempt to allocate anything but linear framebuffer memory + * with single-plane RGB data. Allocation of other framebuffer + * layouts requires dedicated ioctls in the respective DRM driver. */ struct drm_mode_create_dumb { __u32 height; -- cgit v1.2.3 From 0359a849f4e7d6f41249e0741ab8cf7babdfaa41 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 2 Sep 2025 10:32:39 +0200 Subject: drm/crtc: Drop no_vblank bit field The no_vblank field in drm_crtc_state is defined as a bit-field with a single bit. This will create a syntax issue with the macros we'll introduce next, and most other booleans but the *_changed ones in drm_crtc_state do not use a bit field anyway. Let's drop it. Reviewed-by: Thomas Zimmermann Link: https://lore.kernel.org/r/20250902-drm-state-readout-v1-11-14ad5315da3f@kernel.org Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20250902-drm-state-readout-v1-11-14ad5315da3f@kernel.org --- include/drm/drm_crtc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index caa56e039da2..2d2a0bd526cf 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -186,7 +186,7 @@ struct drm_crtc_state { * this case the driver will send the VBLANK event on its own when the * writeback job is complete. */ - bool no_vblank : 1; + bool no_vblank; /** * @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to -- cgit v1.2.3 From 74afeb8128502a529041a2566febd26053a7be11 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 16 Sep 2025 10:36:19 +0200 Subject: drm/vblank: Add vblank timer The vblank timer simulates a vblank interrupt for hardware without support. Rate-limits the display update frequency. DRM drivers for hardware without vblank support apply display updates ASAP. A vblank event informs DRM clients of the completed update. Userspace compositors immediately schedule the next update, which creates significant load on virtualization outputs. Display updates are usually fast on virtualization outputs, as their framebuffers are in regular system memory and there's no hardware vblank interrupt to throttle the update rate. The vblank timer is a HR timer that signals the vblank in software. It limits the update frequency of a DRM driver similar to a hardware vblank interrupt. The timer is not synchronized to the actual vblank interval of the display. The code has been adopted from vkms, which added the funtionality in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by hrtimers"). The new implementation is part of the existing vblank support, which sets up the timer automatically. Drivers only have to start and cancel the vblank timer as part of enabling and disabling the CRTC. The new vblank helper library provides callbacks for struct drm_crtc_funcs. The standard way for handling vblank is to call drm_crtc_handle_vblank(). Drivers that require additional processing, such as vkms, can init handle_vblank_timeout in struct drm_crtc_helper_funcs to refer to their timeout handler. There's a possible deadlock between drm_crtc_handle_vblank() and hrtimer_cancel(). [1] The implementation avoids to call hrtimer_cancel() directly and instead signals to the timer function to not restart itself. v4: - fix possible race condition between timeout and atomic commit (Michael) v3: - avoid deadlock when cancelling timer (Ville, Lyude) v2: - implement vblank timer entirely in vblank helpers - downgrade overrun warning to debug - fix docs Signed-off-by: Thomas Zimmermann Tested-by: Louis Chauvet Reviewed-by: Louis Chauvet Reviewed-by: Javier Martinez Canillas Tested-by: Michael Kelley Link: https://lore.kernel.org/all/20250510094757.4174662-1-zengheng4@huawei.com/ # [1] Link: https://lore.kernel.org/r/20250916083816.30275-2-tzimmermann@suse.de --- include/drm/drm_modeset_helper_vtables.h | 12 ++++++++++++ include/drm/drm_vblank.h | 32 +++++++++++++++++++++++++++++++ include/drm/drm_vblank_helper.h | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 include/drm/drm_vblank_helper.h (limited to 'include') diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index ce7c7aeac887..fe32854b7ffe 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -490,6 +490,18 @@ struct drm_crtc_helper_funcs { bool in_vblank_irq, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime, const struct drm_display_mode *mode); + + /** + * @handle_vblank_timeout: Handles timeouts of the vblank timer. + * + * Called by CRTC's the vblank timer on each timeout. Semantics is + * equivalient to drm_crtc_handle_vblank(). Implementations should + * invoke drm_crtc_handle_vblank() as part of processing the timeout. + * + * This callback is optional. If unset, the vblank timer invokes + * drm_crtc_handle_vblank() directly. + */ + bool (*handle_vblank_timeout)(struct drm_crtc *crtc); }; /** diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 151ab1e85b1b..ffa564d79638 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -25,6 +25,7 @@ #define _DRM_VBLANK_H_ #include +#include #include #include #include @@ -103,6 +104,28 @@ struct drm_vblank_crtc_config { bool disable_immediate; }; +/** + * struct drm_vblank_crtc_timer - vblank timer for a CRTC + */ +struct drm_vblank_crtc_timer { + /** + * @timer: The vblank's high-resolution timer + */ + struct hrtimer timer; + /** + * @interval_lock: Protects @interval + */ + spinlock_t interval_lock; + /** + * @interval: Duration between two vblanks + */ + ktime_t interval; + /** + * @crtc: The timer's CRTC + */ + struct drm_crtc *crtc; +}; + /** * struct drm_vblank_crtc - vblank tracking for a CRTC * @@ -254,6 +277,11 @@ struct drm_vblank_crtc { * cancelled. */ wait_queue_head_t work_wait_queue; + + /** + * @vblank_timer: Holds the state of the vblank timer + */ + struct drm_vblank_crtc_timer vblank_timer; }; struct drm_vblank_crtc *drm_crtc_vblank_crtc(struct drm_crtc *crtc); @@ -290,6 +318,10 @@ wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc); void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, u32 max_vblank_count); +int drm_crtc_vblank_start_timer(struct drm_crtc *crtc); +void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc); +void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time); + /* * Helpers for struct drm_crtc_funcs */ diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h new file mode 100644 index 000000000000..74a971d0cfba --- /dev/null +++ b/include/drm/drm_vblank_helper.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _DRM_VBLANK_HELPER_H_ +#define _DRM_VBLANK_HELPER_H_ + +#include +#include + +struct drm_crtc; + +/* + * VBLANK timer + */ + +int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc); +void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc); +bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc, + int *max_error, + ktime_t *vblank_time, + bool in_vblank_irq); + +/** + * DRM_CRTC_VBLANK_TIMER_FUNCS - Default implementation for VBLANK timers + * + * This macro initializes struct &drm_crtc_funcs to default helpers for + * VBLANK timers. + */ +#define DRM_CRTC_VBLANK_TIMER_FUNCS \ + .enable_vblank = drm_crtc_vblank_helper_enable_vblank_timer, \ + .disable_vblank = drm_crtc_vblank_helper_disable_vblank_timer, \ + .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp_from_timer + +#endif -- cgit v1.2.3 From d54dbb5963bdbdf8559903fe2b2343e871adcb30 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 16 Sep 2025 10:36:20 +0200 Subject: drm/vblank: Add CRTC helpers for simple use cases Implement atomic_flush, atomic_enable and atomic_disable of struct drm_crtc_helper_funcs for vblank handling. Driver with no further requirements can use these functions instead of adding their own. Also simplifies the use of vblank timers. The code has been adopted from vkms, which added the funtionality in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by hrtimers"). v3: - mention vkms (Javier) v2: - fix docs Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Tested-by: Michael Kelley Link: https://lore.kernel.org/r/20250916083816.30275-3-tzimmermann@suse.de --- include/drm/drm_vblank_helper.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h index 74a971d0cfba..fcd8a9b35846 100644 --- a/include/drm/drm_vblank_helper.h +++ b/include/drm/drm_vblank_helper.h @@ -6,8 +6,31 @@ #include #include +struct drm_atomic_state; struct drm_crtc; +/* + * VBLANK helpers + */ + +void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_state *state); +void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state); +void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_state *crtc_state); + +/** + * DRM_CRTC_HELPER_VBLANK_FUNCS - Default implementation for VBLANK helpers + * + * This macro initializes struct &drm_crtc_helper_funcs to default helpers + * for VBLANK handling. + */ +#define DRM_CRTC_HELPER_VBLANK_FUNCS \ + .atomic_flush = drm_crtc_vblank_atomic_flush, \ + .atomic_enable = drm_crtc_vblank_atomic_enable, \ + .atomic_disable = drm_crtc_vblank_atomic_disable + /* * VBLANK timer */ -- cgit v1.2.3 From ad298d9ec957414dbf3d51f3c8bca4b6d2416c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Date: Tue, 30 Sep 2025 14:27:52 +0200 Subject: drm/gpusvm, drm/xe: Fix userptr to not allow device private pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When userptr is used on SVM-enabled VMs, a non-NULL hmm_range::dev_private_owner value might mean that hmm_range_fault() attempts to return device private pages. Either that will fail, or the userptr code will not know how to handle those. Use NULL for hmm_range::dev_private_owner to migrate such pages to system. In order to do that, move the struct drm_gpusvm::device_private_page_owner field to struct drm_gpusvm_ctx::device_private_page_owner so that it doesn't remain immutable over the drm_gpusvm lifetime. v2: - Don't conditionally compile xe_svm_devm_owner(). - Kerneldoc xe_svm_devm_owner(). Fixes: 9e9787414882 ("drm/xe/userptr: replace xe_hmm with gpusvm") Cc: Matthew Auld Cc: Himal Prasad Ghimiray Cc: Matthew Brost Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld Reviewed-by: Matthew Brost Acked-by: Maarten Lankhorst Link: https://lore.kernel.org/r/20250930122752.96034-1-thomas.hellstrom@linux.intel.com --- include/drm/drm_gpusvm.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h index 5434048a2ca4..b92faa9a26b2 100644 --- a/include/drm/drm_gpusvm.h +++ b/include/drm/drm_gpusvm.h @@ -179,7 +179,6 @@ struct drm_gpusvm_range { * @name: Name of the GPU SVM * @drm: Pointer to the DRM device structure * @mm: Pointer to the mm_struct for the address space - * @device_private_page_owner: Device private pages owner * @mm_start: Start address of GPU SVM * @mm_range: Range of the GPU SVM * @notifier_size: Size of individual notifiers @@ -204,7 +203,6 @@ struct drm_gpusvm { const char *name; struct drm_device *drm; struct mm_struct *mm; - void *device_private_page_owner; unsigned long mm_start; unsigned long mm_range; unsigned long notifier_size; @@ -226,6 +224,8 @@ struct drm_gpusvm { /** * struct drm_gpusvm_ctx - DRM GPU SVM context * + * @device_private_page_owner: The device-private page owner to use for + * this operation * @check_pages_threshold: Check CPU pages for present if chunk is less than or * equal to threshold. If not present, reduce chunk * size. @@ -239,6 +239,7 @@ struct drm_gpusvm { * Context that is DRM GPUSVM is operating in (i.e. user arguments). */ struct drm_gpusvm_ctx { + void *device_private_page_owner; unsigned long check_pages_threshold; unsigned long timeslice_ms; unsigned int in_notifier :1; @@ -249,7 +250,7 @@ struct drm_gpusvm_ctx { int drm_gpusvm_init(struct drm_gpusvm *gpusvm, const char *name, struct drm_device *drm, - struct mm_struct *mm, void *device_private_page_owner, + struct mm_struct *mm, unsigned long mm_start, unsigned long mm_range, unsigned long notifier_size, const struct drm_gpusvm_ops *ops, -- cgit v1.2.3 From fcf6bddebfe03574041d7bb5f7e3f18e6b46a426 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 30 Sep 2025 21:24:45 +0300 Subject: drm/dp: Add quirk for Synaptics DSC throughput link-bpp limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some Synaptics MST branch devices have a problem decompressing a stream with a compressed link-bpp higher than 12, if the pixel clock is higher than ~50 % of the maximum throughput capability reported by the branch device. The screen remains blank, or for some - mostly black content - gets enabled, but may stil have jitter artifacts. At least the following docking stations are affected, based on testing both with any Intel devices or the UCD-500 reference device as a source: - DELL WD19DCS, DELL WD19TB3, DELL WD22TB4 - ThinkPad 40AN - HP G2 At least the following docking stations are free from this problem, based on tests with a source/sink/mode etc. configuration matching the test cases used above: - DELL Dual Charge HD22Q, DELL WD25TB5 - ThinkPad 40B0 - Anker 565 All the affected devices have an older version of the Synaptics MST branch device (Panamera), whereas all the non-affected docking stations have a newer branch device (at least Synaptics Panamera with a higher HW revision number and Synaptics Cayenne models). Add the required quirk entries accordingly. The quirk will be handled by the i915/xe drivers in a follow-up change. The latest firmware version of the Synaptics branch device for all the affected devices tested above is 5.7 (as reported at DPCD address 0x50a/0x50b). For the DELL devices this corresponds to the latest 01.00.14.01.A03 firmware package version of the docking station. v2: - Document the DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT enum. - Describe the quirk in more detail in the dpcd_quirk_list. v3: - s/Panarema/Panamera in the commit log. Cc: dri-devel@lists.freedesktop.org Reported-by: Vidya Srinivas Reported-and-tested-by: Swati Sharma Reviewed-by: Ville Syrjälä Acked-by: Maarten Lankhorst Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250930182450.563016-2-imre.deak@intel.com --- include/drm/display/drm_dp_helper.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 87caa4f1fdb8..558f5ce924ac 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -820,6 +820,15 @@ enum drm_dp_quirk { * requires enabling DSC. */ DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC, + /** + * @DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT: + * + * The device doesn't support DSC decompression at the maximum DSC + * pixel throughput and compressed bpp it indicates via its DPCD DSC + * capabilities. The compressed bpp must be limited above a device + * specific DSC pixel throughput. + */ + DP_DPCD_QUIRK_DSC_THROUGHPUT_BPP_LIMIT, }; /** -- cgit v1.2.3 From 1f95871207db4439a3116e9a86f5b5658a5157c4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 30 Sep 2025 21:24:46 +0300 Subject: drm/dp: Add helpers to query the branch DSC max throughput/line-width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to query the DP DSC sink device's per-slice throughput as well as a DSC branch device's overall throughput and line-width capabilities. v2 (Ville): - Rename pixel_clock to peak_pixel_rate, document what the value means in case of MST tiled displays. - Fix name of drm_dp_dsc_branch_max_slice_throughput() to drm_dp_dsc_sink_max_slice_throughput(). v3: - Fix the DSC branch device minimum valid line width value from 2560 to 5120 pixels. - Fix drm_dp_dsc_sink_max_slice_throughput()'s pixel_clock parameter name to peak_pixel_rate in header file. - Add handling for throughput mode 0 granular delta, defined by DP Standard v2.1a. v4: - Remove the default switch case in drm_dp_dsc_sink_max_slice_throughput(), which is unreachable in the current code. (Ville) Cc: dri-devel@lists.freedesktop.org Suggested-by: Ville Syrjälä Reported-and-tested-by: Swati Sharma Reviewed-by: Ville Syrjälä Reviewed-by: Dmitry Baryshkov Acked-by: Maarten Lankhorst Signed-off-by: Imre Deak Link: https://lore.kernel.org/r/20250930182450.563016-3-imre.deak@intel.com --- include/drm/display/drm_dp.h | 3 +++ include/drm/display/drm_dp_helper.h | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 811e9238a77c..600bca40249b 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -257,6 +257,8 @@ # define DP_DSC_RC_BUF_BLK_SIZE_4 0x1 # define DP_DSC_RC_BUF_BLK_SIZE_16 0x2 # define DP_DSC_RC_BUF_BLK_SIZE_64 0x3 +# define DP_DSC_THROUGHPUT_MODE_0_DELTA_SHIFT 3 /* DP 2.1a, in units of 2 MPixels/sec */ +# define DP_DSC_THROUGHPUT_MODE_0_DELTA_MASK (0x1f << DP_DSC_THROUGHPUT_MODE_0_DELTA_SHIFT) #define DP_DSC_RC_BUF_SIZE 0x063 @@ -1683,6 +1685,7 @@ enum drm_dp_phy { #define DP_BRANCH_OUI_HEADER_SIZE 0xc #define DP_RECEIVER_CAP_SIZE 0xf #define DP_DSC_RECEIVER_CAP_SIZE 0x10 /* DSC Capabilities 0x60 through 0x6F */ +#define DP_DSC_BRANCH_CAP_SIZE 3 #define EDP_PSR_RECEIVER_CAP_SIZE 2 #define EDP_DISPLAY_CTL_CAP_SIZE 5 #define DP_LTTPR_COMMON_CAP_SIZE 8 diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 558f5ce924ac..fc02eb888be8 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -203,6 +203,11 @@ u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]); int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE], u8 dsc_bpc[3]); +int drm_dp_dsc_sink_max_slice_throughput(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE], + int peak_pixel_rate, bool is_rgb_yuv444); +int drm_dp_dsc_branch_max_overall_throughput(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE], + bool is_rgb_yuv444); +int drm_dp_dsc_branch_max_line_width(const u8 dsc_branch_dpcd[DP_DSC_BRANCH_CAP_SIZE]); static inline bool drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) -- cgit v1.2.3 From 54cea7e655fe3d031c9e7eaaf127bffe0496e7cd Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:17 +0200 Subject: drm/atomic: Remove unused drm_atomic_get_existing_connector_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drm_atomic_get_existing_connector_state() function is deprecated and isn't used anymore, so let's remove it. Reviewed-by: Dmitry Baryshkov Reviewed-by: Luca Ceresoli Tested-by: Luca Ceresoli Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-2-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 38636a593c9d..321c866d5b0a 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -731,29 +731,6 @@ drm_atomic_get_new_plane_state(const struct drm_atomic_state *state, return state->planes[drm_plane_index(plane)].new_state; } -/** - * drm_atomic_get_existing_connector_state - get connector state, if it exists - * @state: global atomic state object - * @connector: connector to grab - * - * This function returns the connector state for the given connector, - * or NULL if the connector is not part of the global atomic state. - * - * This function is deprecated, @drm_atomic_get_old_connector_state or - * @drm_atomic_get_new_connector_state should be used instead. - */ -static inline struct drm_connector_state * -drm_atomic_get_existing_connector_state(const struct drm_atomic_state *state, - struct drm_connector *connector) -{ - int index = drm_connector_index(connector); - - if (index >= state->num_connector) - return NULL; - - return state->connectors[index].state; -} - /** * drm_atomic_get_old_connector_state - get connector state, if it exists * @state: global atomic state object -- cgit v1.2.3 From 9525f537ce00143f77e4208812cce3aa1d1d1f56 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:18 +0200 Subject: drm/atomic: Document __drm_connectors_state state pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the old and new state pointers are somewhat self-explanatory, the state pointer and its relation to the other two really isn't. Now that we've cleaned up everything and it isn't used in any modesetting path, we can document what it's still useful for: to free the right state when we free the global state. Reviewed-by: Luca Ceresoli Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-3-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 321c866d5b0a..fe47715c31e4 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -182,7 +182,24 @@ struct __drm_crtcs_state { struct __drm_connnectors_state { struct drm_connector *ptr; - struct drm_connector_state *state, *old_state, *new_state; + + /** + * @state: + * + * Used to track the @drm_connector_state we will need to free + * when tearing down the associated &drm_atomic_state in + * $drm_mode_config_funcs.atomic_state_clear or + * drm_atomic_state_default_clear(). + * + * Before a commit, and the call to + * drm_atomic_helper_swap_state() in particular, it points to + * the same state than @new_state. After a commit, it points to + * the same state than @old_state. + */ + struct drm_connector_state *state; + + struct drm_connector_state *old_state, *new_state; + /** * @out_fence_ptr: * -- cgit v1.2.3 From 6b592431c5b07f4fd2fa3ea123eda3ae92d8a2a0 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:19 +0200 Subject: drm/atomic: Convert __drm_atomic_get_current_plane_state() to modern accessor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The __drm_atomic_get_current_plane_state() function tries to get and return the existing plane state, and if it doesn't exist returns the one stored in the drm_plane->state field. Using the current nomenclature, it tries to get the existing plane state with an ad-hoc implementation of drm_atomic_get_existing_plane_state(), and falls back to either the old or new plane state, depending on whether it is called before or after drm_atomic_helper_swap_state(). The existing plane state itself is deprecated, because it also changes when swapping states from the new state to the old state. Fortunately for us, we can simplify things. Indeed, __drm_atomic_get_current_plane_state() is only used in two macros: intel_atomic_crtc_state_for_each_plane_state and drm_atomic_crtc_state_for_each_plane_state(). The intel variant is only used through the intel_wm_compute() function that is only ever called in intel_crtc_atomic_check(). The generic variant is more widely used, and can be found in the malidp, msm, tegra and vc4 drivers. All of these call sites though are during atomic_check(), so we end up in the same situation than Intel's. Thus, we only ever use the existing state as the new state, and plane->state is always going to be the old state. Any plane isn't guaranteed to be part of the state though, so we can't rely on drm_atomic_get_old_plane_state() and we still need to use plane->state. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-4-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index fe47715c31e4..c8b88990506e 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -793,11 +793,11 @@ drm_atomic_get_new_connector_state(const struct drm_atomic_state *state, * @state: global atomic state object * @plane: plane to grab * - * This function returns the plane state for the given plane, either from - * @state, or if the plane isn't part of the atomic state update, from @plane. - * This is useful in atomic check callbacks, when drivers need to peek at, but - * not change, state of other planes, since it avoids threading an error code - * back up the call chain. + * This function returns the plane state for the given plane, either the + * new plane state from @state, or if the plane isn't part of the atomic + * state update, from @plane. This is useful in atomic check callbacks, + * when drivers need to peek at, but not change, state of other planes, + * since it avoids threading an error code back up the call chain. * * WARNING: * @@ -818,9 +818,15 @@ static inline const struct drm_plane_state * __drm_atomic_get_current_plane_state(const struct drm_atomic_state *state, struct drm_plane *plane) { - if (state->planes[drm_plane_index(plane)].state) - return state->planes[drm_plane_index(plane)].state; + struct drm_plane_state *plane_state; + plane_state = drm_atomic_get_new_plane_state(state, plane); + if (plane_state) + return plane_state; + + /* + * If the plane isn't part of the state, fallback to the currently active one. + */ return plane->state; } -- cgit v1.2.3 From 93d851281755f0a279402e1b88d29584ed8244e9 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:23 +0200 Subject: drm/atomic: Remove unused drm_atomic_get_existing_plane_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drm_atomic_get_existing_plane_state() function is deprecated and isn't used anymore, so let's remove it. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-8-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index c8b88990506e..b2cc9c4a9beb 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -700,24 +700,6 @@ drm_atomic_get_new_crtc_state(const struct drm_atomic_state *state, return state->crtcs[drm_crtc_index(crtc)].new_state; } -/** - * drm_atomic_get_existing_plane_state - get plane state, if it exists - * @state: global atomic state object - * @plane: plane to grab - * - * This function returns the plane state for the given plane, or NULL - * if the plane is not part of the global atomic state. - * - * This function is deprecated, @drm_atomic_get_old_plane_state or - * @drm_atomic_get_new_plane_state should be used instead. - */ -static inline struct drm_plane_state * -drm_atomic_get_existing_plane_state(const struct drm_atomic_state *state, - struct drm_plane *plane) -{ - return state->planes[drm_plane_index(plane)].state; -} - /** * drm_atomic_get_old_plane_state - get plane state, if it exists * @state: global atomic state object -- cgit v1.2.3 From 7ca4e7fa4d57ce6eac4842e925ea1f98ea54a365 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:24 +0200 Subject: drm/atomic: Document __drm_planes_state state pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the old and new state pointers are somewhat self-explanatory, the state pointer and its relation to the other two really isn't. Now that we've cleaned up everything and it isn't used in any modesetting path, we can document what it's still useful for: to free the right state when we free the global state. Reviewed-by: Luca Ceresoli Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-9-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index b2cc9c4a9beb..a05012adcf94 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -159,7 +159,23 @@ struct drm_crtc_commit { struct __drm_planes_state { struct drm_plane *ptr; - struct drm_plane_state *state, *old_state, *new_state; + + /** + * @state: + * + * Used to track the @drm_plane_state we will need to free when + * tearing down the associated &drm_atomic_state in + * $drm_mode_config_funcs.atomic_state_clear or + * drm_atomic_state_default_clear(). + * + * Before a commit, and the call to + * drm_atomic_helper_swap_state() in particular, it points to + * the same state than @new_state. After a commit, it points to + * the same state than @old_state. + */ + struct drm_plane_state *state; + + struct drm_plane_state *old_state, *new_state; }; struct __drm_crtcs_state { -- cgit v1.2.3 From 3c2b2136debfc200b8ebcd8e5302348b6c86158d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:50 +0200 Subject: drm/atomic: Remove unused drm_atomic_get_existing_crtc_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The drm_atomic_get_existing_crtc_state() function is deprecated and isn't used anymore, so let's remove it. Reviewed-by: Dmitry Baryshkov Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-35-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index a05012adcf94..f53a32688b33 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -669,24 +669,6 @@ struct drm_crtc * drm_atomic_get_new_crtc_for_encoder(struct drm_atomic_state *state, struct drm_encoder *encoder); -/** - * drm_atomic_get_existing_crtc_state - get CRTC state, if it exists - * @state: global atomic state object - * @crtc: CRTC to grab - * - * This function returns the CRTC state for the given CRTC, or NULL - * if the CRTC is not part of the global atomic state. - * - * This function is deprecated, @drm_atomic_get_old_crtc_state or - * @drm_atomic_get_new_crtc_state should be used instead. - */ -static inline struct drm_crtc_state * -drm_atomic_get_existing_crtc_state(const struct drm_atomic_state *state, - struct drm_crtc *crtc) -{ - return state->crtcs[drm_crtc_index(crtc)].state; -} - /** * drm_atomic_get_old_crtc_state - get old CRTC state, if it exists * @state: global atomic state object -- cgit v1.2.3 From 4ae41729a658aee3e68a609cc0275658b724ebc4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:51 +0200 Subject: drm/atomic: Document __drm_crtcs_state state pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the old and new state pointers are somewhat self-explanatory, the state pointer and its relation to the other two really isn't. Now that we've cleaned up everything and it isn't used in any modesetting path, we can document what it's still useful for: to free the right state when we free the global state. Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-36-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index f53a32688b33..6b634b747490 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -180,7 +180,23 @@ struct __drm_planes_state { struct __drm_crtcs_state { struct drm_crtc *ptr; - struct drm_crtc_state *state, *old_state, *new_state; + + /** + * @state: + * + * Used to track the @drm_crtc_state we will need to free when + * tearing down the associated &drm_atomic_state in + * $drm_mode_config_funcs.atomic_state_clear or + * drm_atomic_state_default_clear(). + * + * Before a commit, and the call to + * drm_atomic_helper_swap_state() in particular, it points to + * the same state than @new_state. After a commit, it points to + * the same state than @old_state. + */ + struct drm_crtc_state *state; + + struct drm_crtc_state *old_state, *new_state; /** * @commit: -- cgit v1.2.3 From 7a031e8d3528ba0860d282ffd3c88fbda4bf8c4c Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 30 Sep 2025 12:59:54 +0200 Subject: drm/atomic: Document __drm_private_objs_state state pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the old and new state pointers are somewhat self-explanatory, the state pointer and its relation to the other two really isn't. Now that we've cleaned up everything and it isn't used in any modesetting path, we can document what it's still useful for: to free the right state when we free the global state. Reviewed-by: Luca Ceresoli Reviewed-by: Ville Syrjälä Link: https://lore.kernel.org/r/20250930-drm-no-more-existing-state-v5-39-eeb9e1287907@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 6b634b747490..c8ab2163bf65 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -391,7 +391,23 @@ struct drm_private_state { struct __drm_private_objs_state { struct drm_private_obj *ptr; - struct drm_private_state *state, *old_state, *new_state; + + /** + * @state: + * + * Used to track the @drm_private_state we will need to free + * when tearing down the associated &drm_atomic_state in + * $drm_mode_config_funcs.atomic_state_clear or + * drm_atomic_state_default_clear(). + * + * Before a commit, and the call to + * drm_atomic_helper_swap_state() in particular, it points to + * the same state than @new_state. After a commit, it points to + * the same state than @old_state. + */ + struct drm_private_state *state; + + struct drm_private_state *old_state, *new_state; }; /** -- cgit v1.2.3 From c178e534fff1d5a74da80ea03b20e2b948a00113 Mon Sep 17 00:00:00 2001 From: Arunpravin Paneer Selvam Date: Mon, 6 Oct 2025 15:21:22 +0530 Subject: drm/buddy: Optimize free block management with RB tree Replace the freelist (O(n)) used for free block management with a red-black tree, providing more efficient O(log n) search, insert, and delete operations. This improves scalability and performance when managing large numbers of free blocks per order (e.g., hundreds or thousands). In the VK-CTS memory stress subtest, the buddy manager merges fragmented memory and inserts freed blocks into the freelist. Since freelist insertion is O(n), this becomes a bottleneck as fragmentation increases. Benchmarking shows list_insert_sorted() consumes ~52.69% CPU with the freelist, compared to just 0.03% with the RB tree (rbtree_insert.isra.0), despite performing the same sorted insert. This also improves performance in heavily fragmented workloads, such as games or graphics tests that stress memory. As the buddy allocator evolves with new features such as clear-page tracking, the resulting fragmentation and complexity have grown. These RB-tree based design changes are introduced to address that growth and ensure the allocator continues to perform efficiently under fragmented conditions. The RB tree implementation with separate clear/dirty trees provides: - O(n log n) aggregate complexity for all operations instead of O(n^2) - Elimination of soft lockups and system instability - Improved code maintainability and clarity - Better scalability for large memory systems - Predictable performance under fragmentation v3(Matthew): - Remove RB_EMPTY_NODE check in force_merge function. - Rename rb for loop macros to have less generic names and move to .c file. - Make the rb node rb and link field as union. v4(Jani Nikula): - The kernel-doc comment should be "/**" - Move all the rbtree macros to rbtree.h and add parens to ensure correct precedence. v5: - Remove the inline in a .c file (Jani Nikula). v6(Peter Zijlstra): - Add rb_add() function replacing the existing rbtree_insert() code. v7: - A full walk iteration in rbtree is slower than the list (Peter Zijlstra). - The existing rbtree_postorder_for_each_entry_safe macro should be used in scenarios where traversal order is not a critical factor (Christian). v8(Matthew): - Remove the rbtree_is_empty() check in this patch as well. Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Signed-off-by: Arunpravin Paneer Selvam Reviewed-by: Matthew Auld Link: https://lore.kernel.org/r/20251006095124.1663-1-Arunpravin.PaneerSelvam@amd.com --- include/drm/drm_buddy.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 513837632b7d..9ee105d4309f 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -53,7 +54,11 @@ struct drm_buddy_block { * a list, if so desired. As soon as the block is freed with * drm_buddy_free* ownership is given back to the mm. */ - struct list_head link; + union { + struct rb_node rb; + struct list_head link; + }; + struct list_head tmp_link; }; @@ -68,7 +73,7 @@ struct drm_buddy_block { */ struct drm_buddy { /* Maintain a free list for each order. */ - struct list_head *free_list; + struct rb_root *free_tree; /* * Maintain explicit binary tree(s) to track the allocation of the @@ -94,7 +99,7 @@ struct drm_buddy { }; static inline u64 -drm_buddy_block_offset(struct drm_buddy_block *block) +drm_buddy_block_offset(const struct drm_buddy_block *block) { return block->header & DRM_BUDDY_HEADER_OFFSET; } -- cgit v1.2.3 From d4cd665c98c144dd6ad5d66d30396e13d23118c9 Mon Sep 17 00:00:00 2001 From: Arunpravin Paneer Selvam Date: Mon, 6 Oct 2025 15:21:23 +0530 Subject: drm/buddy: Separate clear and dirty free block trees Maintain two separate RB trees per order - one for clear (zeroed) blocks and another for dirty (uncleared) blocks. This separation improves code clarity and makes it more obvious which tree is being searched during allocation. It also improves scalability and efficiency when searching for a specific type of block, avoiding unnecessary checks and making the allocator more predictable under fragmentation. The changes have been validated using the existing drm_buddy_test KUnit test cases, along with selected graphics workloads, to ensure correctness and avoid regressions. v2: Missed adding the suggested-by tag. Added it in v2. v3(Matthew): - Remove the double underscores from the internal functions. - Rename the internal functions to have less generic names. - Fix the error handling code. - Pass tree argument for the tree macro. - Use the existing dirty/free bit instead of new tree field. - Make free_trees[] instead of clear_tree and dirty_tree for more cleaner approach. v4: - A bug was reported by Intel CI and it is fixed by Matthew Auld. - Replace the get_root function with &mm->free_trees[tree][order] (Matthew) - Remove the unnecessary rbtree_is_empty() check (Matthew) - Remove the unnecessary get_tree_for_flags() function. - Rename get_tree_for_block() name with get_block_tree() for more clarity. v5(Jani Nikula): - Don't use static inline in .c files. - enum free_tree and enumerator names are quite generic for a header and usage and the whole enum should be an implementation detail. v6: - Rewrite the __force_merge() function using the rb_last() and rb_prev(). v7(Matthew): - Replace the open-coded tree iteration for loops with the for_each_free_tree() macro throughout the code. - Fixed out_free_roots to prevent double decrement of i, addressing potential crash. - Replaced enum drm_buddy_free_tree with unsigned int in for_each_free_tree loops. Cc: stable@vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Signed-off-by: Arunpravin Paneer Selvam Suggested-by: Matthew Auld Reviewed-by: Matthew Auld Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4260 Link: https://lore.kernel.org/r/20251006095124.1663-2-Arunpravin.PaneerSelvam@amd.com --- include/drm/drm_buddy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9ee105d4309f..d7891d08f67a 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -73,7 +73,7 @@ struct drm_buddy_block { */ struct drm_buddy { /* Maintain a free list for each order. */ - struct rb_root *free_tree; + struct rb_root **free_trees; /* * Maintain explicit binary tree(s) to track the allocation of the -- cgit v1.2.3 From 1226cd7c7686aee9363ec39a8a80292e27216c6b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 8 Oct 2025 15:11:42 +0200 Subject: drm/atomic: Change state pointers to a more meaningful name The state pointer found in the struct drm_atomic_state internals for most object is a bit ambiguous, and confusing when those internals also have old state and new state. After the recent cleanups, the state pointer only use is to point to the state we need to free when destroying the atomic state. We can thus rename it something less ambiguous, and hopefully more meaningful. Acked-by: Thomas Zimmermann Link: https://lore.kernel.org/r/20251008-drm-rename-state-v2-1-49b490b2676a@kernel.org Signed-off-by: Maxime Ripard --- include/drm/drm_atomic.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index c8ab2163bf65..155e82f87e4d 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -161,7 +161,7 @@ struct __drm_planes_state { struct drm_plane *ptr; /** - * @state: + * @state_to_destroy: * * Used to track the @drm_plane_state we will need to free when * tearing down the associated &drm_atomic_state in @@ -173,7 +173,7 @@ struct __drm_planes_state { * the same state than @new_state. After a commit, it points to * the same state than @old_state. */ - struct drm_plane_state *state; + struct drm_plane_state *state_to_destroy; struct drm_plane_state *old_state, *new_state; }; @@ -182,7 +182,7 @@ struct __drm_crtcs_state { struct drm_crtc *ptr; /** - * @state: + * @state_to_destroy: * * Used to track the @drm_crtc_state we will need to free when * tearing down the associated &drm_atomic_state in @@ -194,7 +194,7 @@ struct __drm_crtcs_state { * the same state than @new_state. After a commit, it points to * the same state than @old_state. */ - struct drm_crtc_state *state; + struct drm_crtc_state *state_to_destroy; struct drm_crtc_state *old_state, *new_state; @@ -216,7 +216,7 @@ struct __drm_connnectors_state { struct drm_connector *ptr; /** - * @state: + * @state_to_destroy: * * Used to track the @drm_connector_state we will need to free * when tearing down the associated &drm_atomic_state in @@ -228,7 +228,7 @@ struct __drm_connnectors_state { * the same state than @new_state. After a commit, it points to * the same state than @old_state. */ - struct drm_connector_state *state; + struct drm_connector_state *state_to_destroy; struct drm_connector_state *old_state, *new_state; @@ -393,7 +393,7 @@ struct __drm_private_objs_state { struct drm_private_obj *ptr; /** - * @state: + * @state_to_destroy: * * Used to track the @drm_private_state we will need to free * when tearing down the associated &drm_atomic_state in @@ -405,7 +405,7 @@ struct __drm_private_objs_state { * the same state than @new_state. After a commit, it points to * the same state than @old_state. */ - struct drm_private_state *state; + struct drm_private_state *state_to_destroy; struct drm_private_state *old_state, *new_state; }; -- cgit v1.2.3 From 78de8f87668334a3bfadad52e5142fc19dad1807 Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 13 Oct 2025 13:09:58 -0700 Subject: drm/xe: Handle Wa_22010954014 and Wa_14022085890 as device workarounds When Wa_22010954014 and Wa_14022085890 were first implemented, we didn't have a device workaround infrastructure so we hacked them into the GT workaround list. Now that we have proper device workaround support, move them to the proper place. Note that Wa_14022085890 specifically applies to BMG-G21 platforms, so this requires defining a BMG subplatform to capture the correct subset of device IDs. Reviewed-by: Gustavo Sousa Link: https://lore.kernel.org/r/20251013200944.2499947-40-matthew.d.roper@intel.com Signed-off-by: Matt Roper --- include/drm/intel/pciids.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index da6301a6fcea..0cd12616d621 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -849,7 +849,7 @@ MACRO__(0x64B0, ## __VA_ARGS__) /* BMG */ -#define INTEL_BMG_IDS(MACRO__, ...) \ +#define INTEL_BMG_G21_IDS(MACRO__, ...) \ MACRO__(0xE202, ## __VA_ARGS__), \ MACRO__(0xE209, ## __VA_ARGS__), \ MACRO__(0xE20B, ## __VA_ARGS__), \ @@ -858,7 +858,10 @@ MACRO__(0xE210, ## __VA_ARGS__), \ MACRO__(0xE211, ## __VA_ARGS__), \ MACRO__(0xE212, ## __VA_ARGS__), \ - MACRO__(0xE216, ## __VA_ARGS__), \ + MACRO__(0xE216, ## __VA_ARGS__) + +#define INTEL_BMG_IDS(MACRO__, ...) \ + INTEL_BMG_G21_IDS(MACRO__, __VA_ARGS__), \ MACRO__(0xE220, ## __VA_ARGS__), \ MACRO__(0xE221, ## __VA_ARGS__), \ MACRO__(0xE222, ## __VA_ARGS__), \ -- cgit v1.2.3 From 409b9499099b4ad14ca60b59c6edfebfaf74f907 Mon Sep 17 00:00:00 2001 From: Sanjay Yadav Date: Tue, 14 Oct 2025 19:58:24 +0530 Subject: drm/xe/uapi: Add documentation for DRM_XE_GEM_CREATE_FLAG_SCANOUT Add documentation for drm_xe_gem_create structure flag DRM_XE_GEM_CREATE_FLAG_SCANOUT. Signed-off-by: Sanjay Yadav Reviewed-by: Matthew Auld Signed-off-by: Matthew Auld Link: https://lore.kernel.org/r/20251014142823.3701228-2-sanjay.kumar.yadav@intel.com --- include/uapi/drm/xe_drm.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 40ff19f52a8d..2d7945cda739 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -771,7 +771,11 @@ struct drm_xe_device_query { * until the object is either bound to a virtual memory region via * VM_BIND or accessed by the CPU. As a result, no backing memory is * reserved at the time of GEM object creation. - * - %DRM_XE_GEM_CREATE_FLAG_SCANOUT + * - %DRM_XE_GEM_CREATE_FLAG_SCANOUT - Indicates that the GEM object is + * intended for scanout via the display engine. When set, kernel ensures + * that the allocation is placed in a memory region compatible with the + * display engine requirements. This may impose restrictions on tiling, + * alignment, and memory placement to guarantee proper display functionality. * - %DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM - When using VRAM as a * possible placement, ensure that the corresponding VRAM allocation * will always use the CPU accessible part of VRAM. This is important -- cgit v1.2.3 From e4a2d54a2f1a9c9a1971651832c8f0ad9d3782c4 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:50:59 +0300 Subject: drm/bridge: dw-hdmi-qp: Add CEC support Add support for the CEC interface of the Synopsys DesignWare HDMI QP TX controller. This is based on the downstream implementation, but rewritten on top of the CEC helpers added recently to the DRM HDMI connector framework. Also note struct dw_hdmi_qp_plat_data has been extended to include the CEC IRQ number to be provided by the platform driver. Co-developed-by: Algea Cao Signed-off-by: Algea Cao Co-developed-by: Derek Foreman Signed-off-by: Derek Foreman Reviewed-by: Dmitry Baryshkov Signed-off-by: Cristian Ciocaltea Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250903-rk3588-hdmi-cec-v4-1-fa25163c4b08@collabora.com --- include/drm/bridge/dw_hdmi_qp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h index e9be6d507ad9..b4a9b739734e 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -23,6 +23,7 @@ struct dw_hdmi_qp_plat_data { const struct dw_hdmi_qp_phy_ops *phy_ops; void *phy_data; int main_irq; + int cec_irq; }; struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- cgit v1.2.3 From f7a1de0d86221000dc0699a8b48ad3a848e766d9 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 3 Sep 2025 21:51:00 +0300 Subject: drm/bridge: dw-hdmi-qp: Fixup timer base setup Currently the TIMER_BASE_CONFIG0 register gets initialized to a fixed value as initially found in vendor driver code supporting the RK3588 SoC. As a matter of fact the value matches the rate of the HDMI TX reference clock, which is roughly 428.57 MHz. However, on RK3576 SoC that rate is slightly lower, i.e. 396.00 MHz, and the incorrect register configuration breaks CEC functionality. Set the timer base according to the actual reference clock rate that shall be provided by the platform driver. Otherwise fallback to the vendor default. While at it, also drop the unnecessary empty lines in dw_hdmi_qp_init_hw(). Signed-off-by: Cristian Ciocaltea Reviewed-by: Daniel Stone Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20250903-rk3588-hdmi-cec-v4-2-fa25163c4b08@collabora.com --- include/drm/bridge/dw_hdmi_qp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h index b4a9b739734e..76ecf3130199 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -24,6 +24,7 @@ struct dw_hdmi_qp_plat_data { void *phy_data; int main_irq; int cec_irq; + unsigned long ref_clk_rate; }; struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- cgit v1.2.3 From b291e4f1a4951204ce858cd01801291d34962a33 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 14 Oct 2025 16:41:19 -0700 Subject: accel/amdxdna: Support getting last hardware error Add new parameter DRM_AMDXDNA_HW_LAST_ASYNC_ERR to get array IOCTL. When hardware reports an error, the driver save the error information and timestamp. This new get array parameter retrieves the last error. Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://lore.kernel.org/r/20251014234119.628453-1-lizhi.hou@amd.com --- include/uapi/drm/amdxdna_accel.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/amdxdna_accel.h b/include/uapi/drm/amdxdna_accel.h index a1fb9785db77..c7eec9ceb2ae 100644 --- a/include/uapi/drm/amdxdna_accel.h +++ b/include/uapi/drm/amdxdna_accel.h @@ -523,7 +523,20 @@ struct amdxdna_drm_hwctx_entry { __u32 pad; }; +/** + * struct amdxdna_async_error - XDNA async error structure + */ +struct amdxdna_async_error { + /** @err_code: Error code. */ + __u64 err_code; + /** @ts_us: Timestamp. */ + __u64 ts_us; + /** @ex_err_code: Extra error code */ + __u64 ex_err_code; +}; + #define DRM_AMDXDNA_HW_CONTEXT_ALL 0 +#define DRM_AMDXDNA_HW_LAST_ASYNC_ERR 2 /** * struct amdxdna_drm_get_array - Get information array. -- cgit v1.2.3 From bce13d6ecd6c0e6c3376ac53617b30d19ce2a5c6 Mon Sep 17 00:00:00 2001 From: Matthew Brost Date: Wed, 15 Oct 2025 14:03:20 +0200 Subject: drm/gpusvm, drm/xe: Allow mixed mappings for userptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compute kernels often issue memory copies immediately after completion. If the memory being copied is an SVM pointer that was faulted into the device and then bound via userptr, it is undesirable to move that memory. Worse, if userptr is mixed between system and device memory, the bind operation may be rejected. Xe already has the necessary plumbing to support userptr with mixed mappings. This update modifies GPUSVM's get_pages to correctly locate pages in such mixed mapping scenarios. v2: - Rebase (Thomas Hellström) v3: - Remove Fixes tag. v4: - Break out from series since the other patch was merged. - Update patch subject, ensure dri-devel and Maarten are CC'd. Cc: Maarten Lankhorst Cc: dri-devel@lists.freedesktop.org Signed-off-by: Matthew Brost Reviewed-by: Thomas Hellström Reviewed-by: Matthew Auld Reviewed-by: Himal Prasad Ghimiray Link: https://lore.kernel.org/r/20251015120320.176338-1-thomas.hellstrom@linux.intel.com Acked-by: Maarten Lankhorst Signed-off-by: Thomas Hellström --- include/drm/drm_gpusvm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h index b92faa9a26b2..632e100e6efb 100644 --- a/include/drm/drm_gpusvm.h +++ b/include/drm/drm_gpusvm.h @@ -235,6 +235,9 @@ struct drm_gpusvm { * @read_only: operating on read-only memory * @devmem_possible: possible to use device memory * @devmem_only: use only device memory + * @allow_mixed: Allow mixed mappings in get pages. Mixing between system and + * single dpagemap is supported, mixing between multiple dpagemap + * is unsupported. * * Context that is DRM GPUSVM is operating in (i.e. user arguments). */ @@ -246,6 +249,7 @@ struct drm_gpusvm_ctx { unsigned int read_only :1; unsigned int devmem_possible :1; unsigned int devmem_only :1; + unsigned int allow_mixed :1; }; int drm_gpusvm_init(struct drm_gpusvm *gpusvm, -- cgit v1.2.3 From 59a2d3f38ab23cce4cd9f0c4a5e08fdfe9e67ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Date: Wed, 15 Oct 2025 19:07:26 +0200 Subject: drm/xe/uapi: Hide the madvise autoreset behind a VM_BIND flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The madvise implementation currently resets the SVM madvise if the underlying CPU map is unmapped. This is in an attempt to mimic the CPU madvise behaviour. However, it's not clear that this is a desired behaviour since if the end app user relies on it for malloc()ed objects or stack objects, it may not work as intended. Instead of having the autoreset functionality being a direct application-facing implicit UAPI, make the UMD explicitly choose this behaviour if it wants to expose it by introducing DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET, and add a semantics description. v2: - Kerneldoc fixes. Fix a commit log message. Fixes: a2eb8aec3ebe ("drm/xe: Reset VMA attributes to default in SVM garbage collector") Cc: Matthew Brost Cc: Himal Prasad Ghimiray Cc: "Falkowski, John" Cc: "Mrozek, Michal" Signed-off-by: Thomas Hellström Reviewed-by: Himal Prasad Ghimiray Link: https://lore.kernel.org/r/20251015170726.178685-2-thomas.hellstrom@linux.intel.com --- include/uapi/drm/xe_drm.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 2d7945cda739..47853659a705 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1017,6 +1017,20 @@ struct drm_xe_vm_destroy { * valid on VMs with DRM_XE_VM_CREATE_FLAG_FAULT_MODE set. The CPU address * mirror flag are only valid for DRM_XE_VM_BIND_OP_MAP operations, the BO * handle MBZ, and the BO offset MBZ. + * - %DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET - Can be used in combination with + * %DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR to reset madvises when the underlying + * CPU address space range is unmapped (typically with munmap(2) or brk(2)). + * The madvise values set with &DRM_IOCTL_XE_MADVISE are reset to the values + * that were present immediately after the &DRM_IOCTL_XE_VM_BIND. + * The reset GPU virtual address range is the intersection of the range bound + * using &DRM_IOCTL_XE_VM_BIND and the virtual CPU address space range + * unmapped. + * This functionality is present to mimic the behaviour of CPU address space + * madvises set using madvise(2), which are typically reset on unmap. + * Note: free(3) may or may not call munmap(2) and/or brk(2), and may thus + * not invoke autoreset. Neither will stack variables going out of scope. + * Therefore it's recommended to always explicitly reset the madvises when + * freeing the memory backing a region used in a &DRM_IOCTL_XE_MADVISE call. * * The @prefetch_mem_region_instance for %DRM_XE_VM_BIND_OP_PREFETCH can also be: * - %DRM_XE_CONSULT_MEM_ADVISE_PREF_LOC, which ensures prefetching occurs in @@ -1123,6 +1137,7 @@ struct drm_xe_vm_bind_op { #define DRM_XE_VM_BIND_FLAG_DUMPABLE (1 << 3) #define DRM_XE_VM_BIND_FLAG_CHECK_PXP (1 << 4) #define DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR (1 << 5) +#define DRM_XE_VM_BIND_FLAG_MADVISE_AUTORESET (1 << 6) /** @flags: Bind flags */ __u32 flags; -- cgit v1.2.3 From c002b1764e7b0ffd181f32d5103d9d0ac283beeb Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Thu, 16 Oct 2025 19:26:30 -0700 Subject: drm/xe/nvl: Define NVL-S platform Provide the basic platform definitions and PCI IDs for NVL-S. Signed-off-by: Matt Roper Reviewed-by: Shekhar Chauhan Reviewed-by: Gustavo Sousa Link: https://lore.kernel.org/r/20251016-xe3p-v3-11-3dd173a3097a@intel.com Signed-off-by: Lucas De Marchi --- include/drm/intel/pciids.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index 0cd12616d621..9f095a99d6c9 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -884,4 +884,13 @@ MACRO__(0xFD80, ## __VA_ARGS__), \ MACRO__(0xFD81, ## __VA_ARGS__) +/* NVL-S */ +#define INTEL_NVLS_IDS(MACRO__, ...) \ + MACRO__(0xD740, ## __VA_ARGS__), \ + MACRO__(0xD741, ## __VA_ARGS__), \ + MACRO__(0xD742, ## __VA_ARGS__), \ + MACRO__(0xD743, ## __VA_ARGS__), \ + MACRO__(0xD744, ## __VA_ARGS__), \ + MACRO__(0xD745, ## __VA_ARGS__) + #endif /* __PCIIDS_H__ */ -- cgit v1.2.3 From 7910d69376cde30e5871970d97d1a2e360568474 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 1 Oct 2025 16:37:03 +0200 Subject: drm/client: Remove holds_console_lock parameter from suspend/resume No caller of the client resume/suspend helpers holds the console lock. The last such cases were removed from radeon in the patch series at [1]. Now remove the related parameter and the TODO items. v2: - update placeholders for CONFIG_DRM_CLIENT=n Signed-off-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/series/151624/ # [1] Reviewed-by: Rodrigo Vivi Acked-by: Rodrigo Vivi Reviewed-by: Petr Vorel Reviewed-by: Andi Shyti Acked-by: Danilo Krummrich Reviewed-by: Lyude Paul Reviewed-by: Jocelyn Falempe Link: https://lore.kernel.org/r/20251001143709.419736-1-tzimmermann@suse.de --- include/drm/drm_client.h | 14 ++------------ include/drm/drm_client_event.h | 8 ++++---- 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index bdd845e383ef..3556928d3938 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -70,13 +70,8 @@ struct drm_client_funcs { * Called when suspending the device. * * This callback is optional. - * - * FIXME: Some callers hold the console lock when invoking this - * function. This interferes with fbdev emulation, which - * also tries to acquire the lock. Push the console lock - * into the callback and remove 'holds_console_lock'. */ - int (*suspend)(struct drm_client_dev *client, bool holds_console_lock); + int (*suspend)(struct drm_client_dev *client); /** * @resume: @@ -84,13 +79,8 @@ struct drm_client_funcs { * Called when resuming the device from suspend. * * This callback is optional. - * - * FIXME: Some callers hold the console lock when invoking this - * function. This interferes with fbdev emulation, which - * also tries to acquire the lock. Push the console lock - * into the callback and remove 'holds_console_lock'. */ - int (*resume)(struct drm_client_dev *client, bool holds_console_lock); + int (*resume)(struct drm_client_dev *client); }; /** diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h index 1d544d3a3228..985d6f02a4c4 100644 --- a/include/drm/drm_client_event.h +++ b/include/drm/drm_client_event.h @@ -11,8 +11,8 @@ struct drm_device; void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev); void drm_client_dev_restore(struct drm_device *dev); -void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock); -void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock); +void drm_client_dev_suspend(struct drm_device *dev); +void drm_client_dev_resume(struct drm_device *dev); #else static inline void drm_client_dev_unregister(struct drm_device *dev) { } @@ -20,9 +20,9 @@ static inline void drm_client_dev_hotplug(struct drm_device *dev) { } static inline void drm_client_dev_restore(struct drm_device *dev) { } -static inline void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock) +static inline void drm_client_dev_suspend(struct drm_device *dev) { } -static inline void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock) +static inline void drm_client_dev_resume(struct drm_device *dev) { } #endif -- cgit v1.2.3 From 8b5690d5c942a80535f095c8965028262d4ab0f7 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 13 Oct 2025 10:35:17 +0200 Subject: dma-buf: heaps: cma: Register list of CMA regions at boot In order to create a CMA heap instance for each CMA region found in the system, we need to register each of these instances. While it would appear trivial, the CMA regions are created super early in the kernel boot process, before most of the subsystems are initialized. Thus, we can't just create an exported function to create a heap from the CMA region being initialized. What we can do however is create a two-step process, where we collect all the CMA regions into an array early on, and then when we initialize the heaps we iterate over that array and create the heaps from the CMA regions we collected. Reviewed-by: T.J. Mercier Signed-off-by: Maxime Ripard Signed-off-by: Sumit Semwal Link: https://lore.kernel.org/r/20251013-dma-buf-ecc-heap-v8-2-04ce150ea3d9@kernel.org --- include/linux/dma-buf/heaps/cma.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/linux/dma-buf/heaps/cma.h (limited to 'include') diff --git a/include/linux/dma-buf/heaps/cma.h b/include/linux/dma-buf/heaps/cma.h new file mode 100644 index 000000000000..e751479e21e7 --- /dev/null +++ b/include/linux/dma-buf/heaps/cma.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef DMA_BUF_HEAP_CMA_H_ +#define DMA_BUF_HEAP_CMA_H_ + +struct cma; + +#ifdef CONFIG_DMABUF_HEAPS_CMA +int dma_heap_cma_register_heap(struct cma *cma); +#else +static inline int dma_heap_cma_register_heap(struct cma *cma) +{ + return 0; +} +#endif // CONFIG_DMABUF_HEAPS_CMA + +#endif // DMA_BUF_HEAP_CMA_H_ -- cgit v1.2.3 From 8e4865faf7a97de2a0fd797556a62b31528b42bc Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 6 Oct 2025 12:05:55 +0000 Subject: drm/gpuvm: add deferred vm_bo cleanup When using GPUVM in immediate mode, it is necessary to call drm_gpuvm_unlink() from the fence signalling critical path. However, unlink may call drm_gpuvm_bo_put(), which causes some challenges: 1. drm_gpuvm_bo_put() often requires you to take resv locks, which you can't do from the fence signalling critical path. 2. drm_gpuvm_bo_put() calls drm_gem_object_put(), which is often going to be unsafe to call from the fence signalling critical path. To solve these issues, add a deferred version of drm_gpuvm_unlink() that adds the vm_bo to a deferred cleanup list, and then clean it up later. The new methods take the GEMs GPUVA lock internally rather than letting the caller do it because it also needs to perform an operation after releasing the mutex again. This is to prevent freeing the GEM while holding the mutex (more info as comments in the patch). This means that the new methods can only be used with DRM_GPUVM_IMMEDIATE_MODE. Reviewed-by: Boris Brezillon Acked-by: Danilo Krummrich Link: https://lore.kernel.org/r/20251006-vmbo-defer-v4-1-30cbd2c05adb@google.com [aliceryhl: fix formatting of vm_bo = llist_entry(...) line] Signed-off-by: Alice Ryhl --- include/drm/drm_gpuvm.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 8890ded1d907..81cc7672cf2d 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -152,6 +153,7 @@ void drm_gpuva_remove(struct drm_gpuva *va); void drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo); void drm_gpuva_unlink(struct drm_gpuva *va); +void drm_gpuva_unlink_defer(struct drm_gpuva *va); struct drm_gpuva *drm_gpuva_find(struct drm_gpuvm *gpuvm, u64 addr, u64 range); @@ -331,6 +333,11 @@ struct drm_gpuvm { */ spinlock_t lock; } evict; + + /** + * @bo_defer: structure holding vm_bos that need to be destroyed + */ + struct llist_head bo_defer; }; void drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name, @@ -714,6 +721,12 @@ struct drm_gpuvm_bo { * &drm_gpuvms evict list. */ struct list_head evict; + + /** + * @list.entry.bo_defer: List entry to attach to + * the &drm_gpuvms bo_defer list. + */ + struct llist_node bo_defer; } entry; } list; }; @@ -746,6 +759,9 @@ drm_gpuvm_bo_get(struct drm_gpuvm_bo *vm_bo) bool drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo); +bool drm_gpuvm_bo_put_deferred(struct drm_gpuvm_bo *vm_bo); +void drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm); + struct drm_gpuvm_bo * drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm, struct drm_gem_object *obj); -- cgit v1.2.3 From 5e0de2dfbc1bddbd47fbcc9dabb4917000b0ca27 Mon Sep 17 00:00:00 2001 From: Balasubramani Vivekanandan Date: Tue, 21 Oct 2025 22:17:33 -0700 Subject: drm/xe/cri: Add CRI platform definition Add platform definition and PCI IDs for Crescent Island. Other platforms use INTEL_VGA_DEVICE since they have a PCI_BASE_CLASS_DISPLAY class. This is not the case for CRI, so just match on devid, which should be sufficient. Signed-off-by: Balasubramani Vivekanandan Reviewed-by: Shekhar Chauhan Link: https://lore.kernel.org/r/20251021-cri-v1-1-bf11e61d9f49@intel.com Signed-off-by: Lucas De Marchi --- include/drm/intel/pciids.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index 9f095a99d6c9..6e53fb4cdd37 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -893,4 +893,8 @@ MACRO__(0xD744, ## __VA_ARGS__), \ MACRO__(0xD745, ## __VA_ARGS__) +/* CRI */ +#define INTEL_CRI_IDS(MACRO__, ...) \ + MACRO__(0x674C, ## __VA_ARGS__) + #endif /* __PCIIDS_H__ */ -- cgit v1.2.3 From a16f6ba43d9d19996ace3aa08218fa399009f4b7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Thu, 9 Oct 2025 15:16:28 +0200 Subject: drm/client: Add client free callback to unprepare fb_helper Add free callback to struct drm_client_funcs. Invoke function to free the client memory as part of the release process. Implement free for fbdev emulation. Fbdev emulation allocates and prepares client memory in drm_fbdev_client_setup(). The release happens in fb_destroy from struct fb_ops. Multiple implementations of this callback exist in the various drivers that provide an fbdev implementation. Each of them needs to follow the implementation details of the fbdev setup code. Adding a free callback for the client puts the unprepare and release of the fbdev client in a single place. Signed-off-by: Thomas Zimmermann Reviewed-by: Dmitry Baryshkov # core, msm Acked-by: Tomi Valkeinen # omapdrm Acked-by: Patrik Jakobsson # gma500 Acked-by: Alex Deucher Link: https://lore.kernel.org/r/20251009132006.45834-2-tzimmermann@suse.de --- include/drm/drm_client.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 3556928d3938..715b422952ee 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -28,6 +28,16 @@ struct drm_client_funcs { */ struct module *owner; + /** + * @free: + * + * Called when the client gets unregistered. Implementations should + * release all client-specific data and free the memory. + * + * This callback is optional. + */ + void (*free)(struct drm_client_dev *client); + /** * @unregister: * -- cgit v1.2.3 From 5a5e9c0228e613f0ef2a58b9782d7c0ea8f1e58b Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Mon, 20 Oct 2025 14:33:28 -0500 Subject: accel: Add Arm Ethos-U NPU driver Add a driver for Arm Ethos-U65/U85 NPUs. The Ethos-U NPU has a relatively simple interface with single command stream to describe buffers, operation settings, and network operations. It supports up to 8 memory regions (though no h/w bounds on a region). The Ethos NPUs are designed to use an SRAM for scratch memory. Region 2 is reserved for SRAM (like the downstream driver stack and compiler). Userspace doesn't need access to the SRAM. The h/w has no MMU nor external IOMMU and is a DMA engine which can read and write anywhere in memory without h/w bounds checks. The user submitted command streams must be validated against the bounds of the GEM BOs. This is similar to the VC4 design which validates shaders. The job submit is based on the rocket driver for the Rockchip NPU utilizing the GPU scheduler. It is simpler as there's only 1 core rather than 3. Tested on i.MX93 platform (U65) and FVP (U85) with Mesa Teflon support. Acked-by: Thomas Zimmermann Acked-by: Tomeu Vizoso Reviewed-by: Frank Li Link: https://patch.msgid.link/20251020-ethos-v6-2-ecebc383c4b7@kernel.org Signed-off-by: Rob Herring (Arm) --- include/uapi/drm/ethosu_accel.h | 261 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 include/uapi/drm/ethosu_accel.h (limited to 'include') diff --git a/include/uapi/drm/ethosu_accel.h b/include/uapi/drm/ethosu_accel.h new file mode 100644 index 000000000000..af78bb4686d7 --- /dev/null +++ b/include/uapi/drm/ethosu_accel.h @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (C) 2025 Arm, Ltd. */ +#ifndef _ETHOSU_DRM_H_ +#define _ETHOSU_DRM_H_ + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * DOC: IOCTL IDs + * + * enum drm_ethosu_ioctl_id - IOCTL IDs + * + * Place new ioctls at the end, don't re-order, don't replace or remove entries. + * + * These IDs are not meant to be used directly. Use the DRM_IOCTL_ETHOSU_xxx + * definitions instead. + */ +enum drm_ethosu_ioctl_id { + /** @DRM_ETHOSU_DEV_QUERY: Query device information. */ + DRM_ETHOSU_DEV_QUERY = 0, + + /** @DRM_ETHOSU_BO_CREATE: Create a buffer object. */ + DRM_ETHOSU_BO_CREATE, + + /** @DRM_ETHOSU_BO_WAIT: Wait on a buffer object's fence. */ + DRM_ETHOSU_BO_WAIT, + + /** + * @DRM_ETHOSU_BO_MMAP_OFFSET: Get the file offset to pass to + * mmap to map a GEM object. + */ + DRM_ETHOSU_BO_MMAP_OFFSET, + + /** + * @DRM_ETHOSU_CMDSTREAM_BO_CREATE: Create a command stream buffer + * object. + */ + DRM_ETHOSU_CMDSTREAM_BO_CREATE, + + /** @DRM_ETHOSU_SUBMIT: Submit a job and BOs to run. */ + DRM_ETHOSU_SUBMIT, +}; + +/** + * DOC: IOCTL arguments + */ + +/** + * enum drm_ethosu_dev_query_type - Query type + * + * Place new types at the end, don't re-order, don't remove or replace. + */ +enum drm_ethosu_dev_query_type { + /** @DRM_ETHOSU_DEV_QUERY_NPU_INFO: Query NPU information. */ + DRM_ETHOSU_DEV_QUERY_NPU_INFO = 0, +}; + +/** + * struct drm_ethosu_gpu_info - NPU information + * + * Structure grouping all queryable information relating to the NPU. + */ +struct drm_ethosu_npu_info { + /** @id : NPU ID. */ + __u32 id; +#define DRM_ETHOSU_ARCH_MAJOR(x) ((x) >> 28) +#define DRM_ETHOSU_ARCH_MINOR(x) (((x) >> 20) & 0xff) +#define DRM_ETHOSU_ARCH_PATCH(x) (((x) >> 16) & 0xf) +#define DRM_ETHOSU_PRODUCT_MAJOR(x) (((x) >> 12) & 0xf) +#define DRM_ETHOSU_VERSION_MAJOR(x) (((x) >> 8) & 0xf) +#define DRM_ETHOSU_VERSION_MINOR(x) (((x) >> 4) & 0xff) +#define DRM_ETHOSU_VERSION_STATUS(x) ((x) & 0xf) + + /** @gpu_rev: GPU revision. */ + __u32 config; + + __u32 sram_size; +}; + +/** + * struct drm_ethosu_dev_query - Arguments passed to DRM_ETHOSU_IOCTL_DEV_QUERY + */ +struct drm_ethosu_dev_query { + /** @type: the query type (see drm_ethosu_dev_query_type). */ + __u32 type; + + /** + * @size: size of the type being queried. + * + * If pointer is NULL, size is updated by the driver to provide the + * output structure size. If pointer is not NULL, the driver will + * only copy min(size, actual_structure_size) bytes to the pointer, + * and update the size accordingly. This allows us to extend query + * types without breaking userspace. + */ + __u32 size; + + /** + * @pointer: user pointer to a query type struct. + * + * Pointer can be NULL, in which case, nothing is copied, but the + * actual structure size is returned. If not NULL, it must point to + * a location that's large enough to hold size bytes. + */ + __u64 pointer; +}; + +/** + * enum drm_ethosu_bo_flags - Buffer object flags, passed at creation time. + */ +enum drm_ethosu_bo_flags { + /** + * @DRM_ETHOSU_BO_NO_MMAP: The buffer object will never be CPU-mapped + * in userspace. + */ + DRM_ETHOSU_BO_NO_MMAP = (1 << 0), +}; + +/** + * struct drm_ethosu_bo_create - Arguments passed to DRM_IOCTL_ETHOSU_BO_CREATE. + */ +struct drm_ethosu_bo_create { + /** + * @size: Requested size for the object + * + * The (page-aligned) allocated size for the object will be returned. + */ + __u64 size; + + /** + * @flags: Flags. Must be a combination of drm_ethosu_bo_flags flags. + */ + __u32 flags; + + /** + * @handle: Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; +}; + +/** + * struct drm_ethosu_bo_mmap_offset - Arguments passed to DRM_IOCTL_ETHOSU_BO_MMAP_OFFSET. + */ +struct drm_ethosu_bo_mmap_offset { + /** @handle: Handle of the object we want an mmap offset for. */ + __u32 handle; + + /** @pad: MBZ. */ + __u32 pad; + + /** @offset: The fake offset to use for subsequent mmap calls. */ + __u64 offset; +}; + +/** + * struct drm_ethosu_wait_bo - ioctl argument for waiting for + * completion of the last DRM_ETHOSU_SUBMIT on a BO. + * + * This is useful for cases where multiple processes might be + * rendering to a BO and you want to wait for all rendering to be + * completed. + */ +struct drm_ethosu_bo_wait { + __u32 handle; + __u32 pad; + __s64 timeout_ns; /* absolute */ +}; + +struct drm_ethosu_cmdstream_bo_create { + /* Size of the data argument. */ + __u32 size; + + /* Flags, currently must be 0. */ + __u32 flags; + + /* Pointer to the data. */ + __u64 data; + + /** Returned GEM handle for the BO. */ + __u32 handle; + + /* Pad, must be 0. */ + __u32 pad; +}; + +/** + * struct drm_ethosu_job - A job to be run on the NPU + * + * The kernel will schedule the execution of this job taking into account its + * dependencies with other jobs. All tasks in the same job will be executed + * sequentially on the same core, to benefit from memory residency in SRAM. + */ +struct drm_ethosu_job { + /** Input: BO handle for cmdstream. */ + __u32 cmd_bo; + + /** Input: Amount of SRAM to use. */ + __u32 sram_size; + +#define ETHOSU_MAX_REGIONS 8 + /** Input: Array of BO handles for each region. */ + __u32 region_bo_handles[ETHOSU_MAX_REGIONS]; +}; + +/** + * struct drm_ethosu_submit - ioctl argument for submitting commands to the NPU. + * + * The kernel will schedule the execution of these jobs in dependency order. + */ +struct drm_ethosu_submit { + /** Input: Pointer to an array of struct drm_ethosu_job. */ + __u64 jobs; + + /** Input: Number of jobs passed in. */ + __u32 job_count; + + /** Reserved, must be zero. */ + __u32 pad; +}; + +/** + * DRM_IOCTL_ETHOSU() - Build a ethosu IOCTL number + * @__access: Access type. Must be R, W or RW. + * @__id: One of the DRM_ETHOSU_xxx id. + * @__type: Suffix of the type being passed to the IOCTL. + * + * Don't use this macro directly, use the DRM_IOCTL_ETHOSU_xxx + * values instead. + * + * Return: An IOCTL number to be passed to ioctl() from userspace. + */ +#define DRM_IOCTL_ETHOSU(__access, __id, __type) \ + DRM_IO ## __access(DRM_COMMAND_BASE + DRM_ETHOSU_ ## __id, \ + struct drm_ethosu_ ## __type) + +enum { + DRM_IOCTL_ETHOSU_DEV_QUERY = + DRM_IOCTL_ETHOSU(WR, DEV_QUERY, dev_query), + DRM_IOCTL_ETHOSU_BO_CREATE = + DRM_IOCTL_ETHOSU(WR, BO_CREATE, bo_create), + DRM_IOCTL_ETHOSU_BO_WAIT = + DRM_IOCTL_ETHOSU(WR, BO_WAIT, bo_wait), + DRM_IOCTL_ETHOSU_BO_MMAP_OFFSET = + DRM_IOCTL_ETHOSU(WR, BO_MMAP_OFFSET, bo_mmap_offset), + DRM_IOCTL_ETHOSU_CMDSTREAM_BO_CREATE = + DRM_IOCTL_ETHOSU(WR, CMDSTREAM_BO_CREATE, cmdstream_bo_create), + DRM_IOCTL_ETHOSU_SUBMIT = + DRM_IOCTL_ETHOSU(WR, SUBMIT, submit), +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* _ETHOSU_DRM_H_ */ -- cgit v1.2.3 From 0a0e79a2d9ed846fc3c3f5ef92b691e81bc9721a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 17 Oct 2025 19:33:27 +0300 Subject: drm/atomic: WARN about invalid drm_foo_get_state() usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_{crtc,plane,connector,private_obj}_get_state() must not be called after the atomic check phase. At that point the commit has been carved in stone and no new objects must be introduced into it. WARN if anyone attempts to violate this rule. Cc: Maxime Ripard Cc: Dan Carpenter Signed-off-by: Ville Syrjälä Link: https://patch.msgid.link/20251017163327.9074-2-ville.syrjala@linux.intel.com Reviewed-by: Maxime Ripard --- include/drm/drm_atomic.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 155e82f87e4d..2e433d44658d 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -523,6 +523,14 @@ struct drm_atomic_state { */ bool duplicated : 1; + /** + * @checked: + * + * Indicates the state has been checked and thus must no longer + * be mutated. For internal use only, do not consult from drivers. + */ + bool checked : 1; + /** * @planes: * -- cgit v1.2.3 From 57557964b582238d5ee4b8538d1c4694f91c2186 Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Wed, 29 Oct 2025 10:17:52 +0100 Subject: accel/ivpu: Add support for userptr buffer objects Introduce a new ioctl `drm_ivpu_bo_create_from_userptr` that allows users to create GEM buffer objects from user pointers to memory regions. The user pointer must be page-aligned and the memory region must remain valid for the buffer object's lifetime. Userptr buffers enable direct use of mmapped files (e.g. inference weights) in NPU workloads without copying data to NPU buffer objects. This reduces memory usage and provides better flexibility for NPU applications. Signed-off-by: Jacek Lawrynowicz Reviewed-by: Jeff Hugo Signed-off-by: Karol Wachowski Link: https://patch.msgid.link/20251029091752.203198-1-karol.wachowski@linux.intel.com --- include/uapi/drm/ivpu_accel.h | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index e470b0221e02..264505d54f93 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -25,6 +25,7 @@ extern "C" { #define DRM_IVPU_CMDQ_CREATE 0x0b #define DRM_IVPU_CMDQ_DESTROY 0x0c #define DRM_IVPU_CMDQ_SUBMIT 0x0d +#define DRM_IVPU_BO_CREATE_FROM_USERPTR 0x0e #define DRM_IOCTL_IVPU_GET_PARAM \ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param) @@ -69,6 +70,10 @@ extern "C" { #define DRM_IOCTL_IVPU_CMDQ_SUBMIT \ DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_CMDQ_SUBMIT, struct drm_ivpu_cmdq_submit) +#define DRM_IOCTL_IVPU_BO_CREATE_FROM_USERPTR \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_CREATE_FROM_USERPTR, \ + struct drm_ivpu_bo_create_from_userptr) + /** * DOC: contexts * @@ -127,6 +132,13 @@ extern "C" { * command queue destroy and submit job on specific command queue. */ #define DRM_IVPU_CAP_MANAGE_CMDQ 3 +/** + * DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR + * + * Driver supports creating buffer objects from user space memory pointers. + * This allows creating GEM buffers from existing user memory regions. + */ +#define DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR 4 /** * struct drm_ivpu_param - Get/Set VPU parameters @@ -194,6 +206,7 @@ struct drm_ivpu_param { #define DRM_IVPU_BO_HIGH_MEM DRM_IVPU_BO_SHAVE_MEM #define DRM_IVPU_BO_MAPPABLE 0x00000002 #define DRM_IVPU_BO_DMA_MEM 0x00000004 +#define DRM_IVPU_BO_READ_ONLY 0x00000008 #define DRM_IVPU_BO_CACHED 0x00000000 #define DRM_IVPU_BO_UNCACHED 0x00010000 @@ -204,6 +217,7 @@ struct drm_ivpu_param { (DRM_IVPU_BO_HIGH_MEM | \ DRM_IVPU_BO_MAPPABLE | \ DRM_IVPU_BO_DMA_MEM | \ + DRM_IVPU_BO_READ_ONLY | \ DRM_IVPU_BO_CACHE_MASK) /** @@ -255,6 +269,44 @@ struct drm_ivpu_bo_create { __u64 vpu_addr; }; +/** + * struct drm_ivpu_bo_create_from_userptr - Create dma-buf from user pointer + * + * Create a GEM buffer object from a user pointer to a memory region. + */ +struct drm_ivpu_bo_create_from_userptr { + /** @user_ptr: User pointer to memory region (must be page aligned) */ + __u64 user_ptr; + + /** @size: Size of the memory region in bytes (must be page aligned) */ + __u64 size; + + /** + * @flags: + * + * Supported flags: + * + * %DRM_IVPU_BO_HIGH_MEM: + * + * Allocate VPU address from >4GB range. + * + * %DRM_IVPU_BO_DMA_MEM: + * + * Allocate from DMA memory range accessible by hardware DMA. + * + * %DRM_IVPU_BO_READ_ONLY: + * + * Allocate as a read-only buffer object. + */ + __u32 flags; + + /** @handle: Returned GEM object handle */ + __u32 handle; + + /** @vpu_addr: Returned VPU virtual address */ + __u64 vpu_addr; +}; + /** * struct drm_ivpu_bo_info - Query buffer object info */ -- cgit v1.2.3 From d1ac2573f0085a5aab6f5d4cfa7b2818d703e5fe Mon Sep 17 00:00:00 2001 From: Nemesa Garg Date: Tue, 28 Oct 2025 17:37:37 +0530 Subject: drm/drm_crtc: Introduce sharpness strength property Introduce a new crtc property "SHARPNESS_STRENGTH" that allows the user to set the intensity so as to get the sharpness effect. The value of this property can be set from 0-255. It is useful in scenario when the output is blurry and user want to sharpen the pixels. User can increase/decrease the sharpness level depending on the content displayed. v2: Rename crtc property variable [Arun] Add modeset detail in uapi doc[Uma] v3: Fix build issue v4: Modify the subject line[Ankit] Signed-off-by: Nemesa Garg Reviewed-by: Ankit Nautiyal Tested-by: Adarsh G M Acked-by: Simona Vetter Link: https://invent.kde.org/plasma/kwin/-/merge_requests/7689 Link: https://patch.msgid.link/20251028120747.3027332-2-ankit.k.nautiyal@intel.com Signed-off-by: Jani Nikula --- include/drm/drm_crtc.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index caa56e039da2..bcdbde681986 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -317,6 +317,17 @@ struct drm_crtc_state { */ enum drm_scaling_filter scaling_filter; + /** + * @sharpness_strength: + * + * Used by the user to set the sharpness intensity. + * The value ranges from 0-255. + * Default value is 0 which disable the sharpness feature. + * Any value greater than 0 enables sharpening with the + * specified strength. + */ + u8 sharpness_strength; + /** * @event: * @@ -1088,6 +1099,12 @@ struct drm_crtc { */ struct drm_property *scaling_filter_property; + /** + * @sharpness_strength_property: property to apply + * the intensity of the sharpness requested. + */ + struct drm_property *sharpness_strength_property; + /** * @state: * @@ -1324,4 +1341,5 @@ static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev, int drm_crtc_create_scaling_filter_property(struct drm_crtc *crtc, unsigned int supported_filters); bool drm_crtc_in_clone_mode(struct drm_crtc_state *crtc_state); +int drm_crtc_create_sharpness_strength_property(struct drm_crtc *crtc); #endif /* __DRM_CRTC_H__ */ -- cgit v1.2.3 From dce4657ff526b65007fe8d5c92968a933cc7c9da Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 13:09:12 +0100 Subject: drm/client: Remove pitch from struct drm_client_buffer Only the client-buffer setup uses the pitch field from struct drm_client_buffer. Remove the field and pass the value among setup helpers. Clients that need the pitch should rather look at the framebuffer's pitches[0] directly. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Tested-by: Francesco Valla Link: https://patch.msgid.link/20251027121042.143588-2-tzimmermann@suse.de --- include/drm/drm_client.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 715b422952ee..c674464f7e74 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -173,11 +173,6 @@ struct drm_client_buffer { */ struct drm_client_dev *client; - /** - * @pitch: Buffer pitch - */ - u32 pitch; - /** * @gem: GEM object backing this buffer * -- cgit v1.2.3 From ea39f2e66e61035e203530977a3df428345d03e2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 13:09:15 +0100 Subject: drm/client: Deprecate struct drm_client_buffer.gem The client buffer's framebuffer holds a reference and pointer on each of its GEM buffer objects. Thus the field gem in the client- buffer struct is not necessary. Deprecated the field and convert the client-buffer helpers to use the framebuffer's objects. In drm_client_buffer_delete(), do a possible vunmap before releasing the framebuffer. Otherwise we'd eventually release the framebuffer before unmaping its buffer objects. v2: - avoid dependency on CONFIG_DRM_KMS_HELPER Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Tested-by: Francesco Valla Link: https://patch.msgid.link/20251027121042.143588-5-tzimmermann@suse.de --- include/drm/drm_client.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index c674464f7e74..b01fc2a21f09 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -176,12 +176,9 @@ struct drm_client_buffer { /** * @gem: GEM object backing this buffer * - * FIXME: The dependency on GEM here isn't required, we could - * convert the driver handle to a dma-buf instead and use the - * backend-agnostic dma-buf vmap support instead. This would - * require that the handle2fd prime ioctl is reworked to pull the - * fd_install step out of the driver backend hooks, to make that - * final step optional for internal users. + * FIXME: The DRM framebuffer holds a reference on its GEM + * buffer objects. Do not use this field in new code and + * update existing users. */ struct drm_gem_object *gem; -- cgit v1.2.3 From 3e3153325fd3693d0f9fe235c4afbcd68ef102e1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 13:09:16 +0100 Subject: drm/client: Remove drm_client_framebuffer_delete() Release client buffers with drm_client_buffer_delete() instead of drm_client_framebuffer_delete(). The latter is just a tiny wrapper around the former. Move the test for !buffer into drm_client_buffer_delete(), although all callers appear to always have a valid pointer. v2: - test for !buffer before deref-ing pointer (Jocelyn, Dan) Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Tested-by: Francesco Valla Link: https://patch.msgid.link/20251027121042.143588-6-tzimmermann@suse.de --- include/drm/drm_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index b01fc2a21f09..ffc4013b2e18 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -195,7 +195,7 @@ struct drm_client_buffer { struct drm_client_buffer * drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format); -void drm_client_framebuffer_delete(struct drm_client_buffer *buffer); +void drm_client_buffer_delete(struct drm_client_buffer *buffer); int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect); int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer, struct iosys_map *map_copy); -- cgit v1.2.3 From c2707e0f8322607b65e5eb8362ba94a2aeb299b9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 13:09:17 +0100 Subject: drm/client: Create client buffers with drm_client_buffer_create_dumb() Rename drm_client_framebuffer_create() to drm_client_buffer_create_dump() and adapt callers. The new name reflects the function's purpose. Using dumb buffers is the easiest way for creating a GEM buffer in a drivers- independent way. There's also drm_client_buffer_create(), which creates the client buffer from a preexisting buffer object. This helper can be exported for drivers that create their own GEM buffer object. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Tested-by: Francesco Valla Link: https://patch.msgid.link/20251027121042.143588-7-tzimmermann@suse.de --- include/drm/drm_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index ffc4013b2e18..690ef04fccce 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -194,7 +194,7 @@ struct drm_client_buffer { }; struct drm_client_buffer * -drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format); +drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 height, u32 format); void drm_client_buffer_delete(struct drm_client_buffer *buffer); int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect); int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer, -- cgit v1.2.3 From 231668043d4ffebda28630b120cddcba384a3318 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 13:09:18 +0100 Subject: drm/client: Flush client buffers with drm_client_buffer_sync() Rename drm_client_framebuffer_flush() to drm_cient_buffer_flush() and adapt its callers. The old name was left over from previous naming conventions. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe > Tested-by: Francesco Valla Link: https://patch.msgid.link/20251027121042.143588-8-tzimmermann@suse.de --- include/drm/drm_client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 690ef04fccce..5ecde0f6f591 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -196,7 +196,7 @@ struct drm_client_buffer { struct drm_client_buffer * drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 height, u32 format); void drm_client_buffer_delete(struct drm_client_buffer *buffer); -int drm_client_framebuffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect); +int drm_client_buffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect); int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer, struct iosys_map *map_copy); void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer); -- cgit v1.2.3 From 9695c143b72a7faa2dbbb2a5881269f82e6f9783 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Oct 2025 12:39:46 +0200 Subject: drm/buddy: replace drm_print.h include with a forward declaration The drm_buddy.h header does not really need anything from drm_print.h. A simple forward declaration for struct drm_printer is sufficient. An explicit drm_print.h include has previously been added to all the files that indirectly depended on this include. v3: Only remove the include here (Thomas) Cc: Thomas Zimmermann Reviewed-by: Thomas Zimmermann Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/b303996b407fcbe2c7357bea036f79c45d6dae49.1761734313.git.jani.nikula@intel.com --- include/drm/drm_buddy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index c2e05a281252..b909fa8f810a 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -12,7 +12,7 @@ #include #include -#include +struct drm_printer; #define DRM_BUDDY_RANGE_ALLOCATION BIT(0) #define DRM_BUDDY_TOPDOWN_ALLOCATION BIT(1) -- cgit v1.2.3 From ea722522d505fa8fb3533a386adeb400607e5072 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Oct 2025 12:39:47 +0200 Subject: drm/mm: replace drm_print.h include with a forward declaration The drm_mm.h header does not really need anything from drm_print.h. A simple forward declaration for struct drm_printer is sufficient. An explicit drm_print.h include has previously been added to all the files that indirectly depended on this include. v3: Only remove the include here (Thomas) Cc: Thomas Zimmermann Reviewed-by: Thomas Zimmermann Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/7d570ed1f0f0f14cac346bea50bce9ef02ddd166.1761734313.git.jani.nikula@intel.com --- include/drm/drm_mm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index f654874c4ce6..16ce0e8f36a6 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -48,7 +48,7 @@ #endif #include -#include +struct drm_printer; #ifdef CONFIG_DRM_DEBUG_MM #define DRM_MM_BUG_ON(expr) BUG_ON(expr) -- cgit v1.2.3 From d7a849d126d0a75b2c5101f82d0c9693e04a43fd Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 29 Oct 2025 12:39:48 +0200 Subject: drm/ttm: replace drm_print.h include with a forward declaration The ttm/ttm_resource.h header does not really need anything from drm_print.h. A simple forward declaration for struct drm_printer is sufficient. An explicit drm_print.h include has previously been added to all the files that indirectly depended on this include. v3: Only remove the include here (Thomas) Cc: Thomas Zimmermann Reviewed-by: Thomas Zimmermann Signed-off-by: Jani Nikula Link: https://lore.kernel.org/r/cfdb1095033112c2a7e58767481c98929984a33c.1761734313.git.jani.nikula@intel.com --- include/drm/ttm/ttm_resource.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index f49daa504c36..68bf010d8b40 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -31,14 +31,15 @@ #include #include -#include #include #include #define TTM_MAX_BO_PRIORITY 4U #define TTM_NUM_MEM_TYPES 9 +struct dentry; struct dmem_cgroup_device; +struct drm_printer; struct ttm_device; struct ttm_resource_manager; struct ttm_resource; -- cgit v1.2.3 From 0af5b6a8f8dd41fd801bb0f2af3295d69ba8b7fe Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 20 Oct 2025 12:54:07 +0100 Subject: drm/ttm: Replace multiple booleans with flags in pool init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple consecutive boolean function arguments are usually not very readable. Replace the ones in ttm_pool_init() with flags with the additional benefit of soon being able to pass in more data with just this one code base churning cost. Signed-off-by: Tvrtko Ursulin Cc: Alex Deucher Cc: Christian König Cc: Thomas Hellström Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20251020115411.36818-3-tvrtko.ursulin@igalia.com --- include/drm/ttm/ttm_allocation.h | 10 ++++++++++ include/drm/ttm/ttm_pool.h | 8 +++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 include/drm/ttm/ttm_allocation.h (limited to 'include') diff --git a/include/drm/ttm/ttm_allocation.h b/include/drm/ttm/ttm_allocation.h new file mode 100644 index 000000000000..7869dc32bd91 --- /dev/null +++ b/include/drm/ttm/ttm_allocation.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2025 Valve Corporation */ + +#ifndef _TTM_ALLOCATION_H_ +#define _TTM_ALLOCATION_H_ + +#define TTM_ALLOCATION_POOL_USE_DMA_ALLOC BIT(0) /* Use coherent DMA allocations. */ +#define TTM_ALLOCATION_POOL_USE_DMA32 BIT(1) /* Use GFP_DMA32 allocations. */ + +#endif diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h index 54cd34a6e4c0..67c72de913bb 100644 --- a/include/drm/ttm/ttm_pool.h +++ b/include/drm/ttm/ttm_pool.h @@ -64,16 +64,14 @@ struct ttm_pool_type { * * @dev: the device we allocate pages for * @nid: which numa node to use - * @use_dma_alloc: if coherent DMA allocations should be used - * @use_dma32: if GFP_DMA32 should be used + * @alloc_flags: TTM_ALLOCATION_POOL_ flags * @caching: pools for each caching/order */ struct ttm_pool { struct device *dev; int nid; - bool use_dma_alloc; - bool use_dma32; + unsigned int alloc_flags; struct { struct ttm_pool_type orders[NR_PAGE_ORDERS]; @@ -85,7 +83,7 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt, void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt); void ttm_pool_init(struct ttm_pool *pool, struct device *dev, - int nid, bool use_dma_alloc, bool use_dma32); + int nid, unsigned int alloc_flags); void ttm_pool_fini(struct ttm_pool *pool); int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m); -- cgit v1.2.3 From 77e19f8d32979f00b7c2cbcb35dbbf6f2116518e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 20 Oct 2025 12:54:08 +0100 Subject: drm/ttm: Replace multiple booleans with flags in device init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple consecutive boolean function arguments are usually not very readable. Replace the ones in ttm_device_init() with flags with the additional benefit of soon being able to pass in more data with just a one off code base churning cost. Signed-off-by: Tvrtko Ursulin Cc: Alex Deucher Cc: Christian König Cc: Danilo Krummrich Cc: Dave Airlie Cc: Gerd Hoffmann Cc: Joonas Lahtinen Cc: Lucas De Marchi Cc: Lyude Paul Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Rodrigo Vivi Cc: Sui Jingfeng Cc: Thomas Hellström Cc: Thomas Zimmermann Cc: Zack Rusin Acked-by: Christian König Acked-by: Zack Rusin Acked-by: Thomas Hellström # For xe Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20251020115411.36818-4-tvrtko.ursulin@igalia.com [tursulin: fixup checkpatch while applying] --- include/drm/ttm/ttm_device.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 592b5f802859..074b98572275 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -292,7 +293,7 @@ static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type, int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs, struct device *dev, struct address_space *mapping, struct drm_vma_offset_manager *vma_manager, - bool use_dma_alloc, bool use_dma32); + unsigned int alloc_flags); void ttm_device_fini(struct ttm_device *bdev); void ttm_device_clear_dma_mappings(struct ttm_device *bdev); -- cgit v1.2.3 From 7e9c548d3709c76601c953834bed9c888f3e17b2 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 20 Oct 2025 12:54:09 +0100 Subject: drm/ttm: Allow drivers to specify maximum beneficial TTM pool size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GPUs typically benefit from contiguous memory via reduced TLB pressure and improved caching performance, where the maximum size of contiguous block which adds a performance benefit is related to hardware design. TTM pool allocator by default tries (hard) to allocate up to the system MAX_PAGE_ORDER blocks. This varies by the CPU platform and can also be configured via Kconfig. If that limit was set to be higher than the GPU can make an extra use of, lets allow the individual drivers to let TTM know over which allocation order can the pool allocator afford to make a little bit less effort with. We implement this by disabling direct reclaim for those allocations, which reduces the allocation latency and lowers the demands on the page allocator, in cases where expending this effort is not critical for the GPU in question. Signed-off-by: Tvrtko Ursulin Cc: Christian König Cc: Thadeu Lima de Souza Cascardo Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20251020115411.36818-5-tvrtko.ursulin@igalia.com --- include/drm/ttm/ttm_allocation.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_allocation.h b/include/drm/ttm/ttm_allocation.h index 7869dc32bd91..8f8544760306 100644 --- a/include/drm/ttm/ttm_allocation.h +++ b/include/drm/ttm/ttm_allocation.h @@ -4,7 +4,8 @@ #ifndef _TTM_ALLOCATION_H_ #define _TTM_ALLOCATION_H_ -#define TTM_ALLOCATION_POOL_USE_DMA_ALLOC BIT(0) /* Use coherent DMA allocations. */ -#define TTM_ALLOCATION_POOL_USE_DMA32 BIT(1) /* Use GFP_DMA32 allocations. */ +#define TTM_ALLOCATION_POOL_BENEFICIAL_ORDER(n) ((n) & 0xff) /* Max order which caller can benefit from */ +#define TTM_ALLOCATION_POOL_USE_DMA_ALLOC BIT(8) /* Use coherent DMA allocations. */ +#define TTM_ALLOCATION_POOL_USE_DMA32 BIT(9) /* Use GFP_DMA32 allocations. */ #endif -- cgit v1.2.3 From 402b3a865090578f9245115e17ee230e01daf60e Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 20 Oct 2025 12:54:11 +0100 Subject: drm/ttm: Add an allocation flag to propagate -ENOSPC on OOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some graphics APIs differentiate between out-of-graphics-memory and out-of-host-memory (system memory). Add a device init flag to have -ENOSPC propagated from the resource managers instead of being converted to -ENOMEM, to aid driver stacks in determining what error code to return or whether corrective action can be taken at the driver level. Co-developed-by: Thomas Hellström Cc: Christian König Cc: Matthew Brost Signed-off-by: Tvrtko Ursulin Reviewed-by: Thomas Hellström Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20251020115411.36818-7-tvrtko.ursulin@igalia.com --- include/drm/ttm/ttm_allocation.h | 1 + include/drm/ttm/ttm_device.h | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/ttm/ttm_allocation.h b/include/drm/ttm/ttm_allocation.h index 8f8544760306..655d1e44aba7 100644 --- a/include/drm/ttm/ttm_allocation.h +++ b/include/drm/ttm/ttm_allocation.h @@ -7,5 +7,6 @@ #define TTM_ALLOCATION_POOL_BENEFICIAL_ORDER(n) ((n) & 0xff) /* Max order which caller can benefit from */ #define TTM_ALLOCATION_POOL_USE_DMA_ALLOC BIT(8) /* Use coherent DMA allocations. */ #define TTM_ALLOCATION_POOL_USE_DMA32 BIT(9) /* Use GFP_DMA32 allocations. */ +#define TTM_ALLOCATION_PROPAGATE_ENOSPC BIT(10) /* Do not convert ENOSPC from resource managers to ENOMEM. */ #endif diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index 074b98572275..d016360e5ceb 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -220,6 +220,11 @@ struct ttm_device { */ struct list_head device_list; + /** + * @alloc_flags: TTM_ALLOCATION_ flags. + */ + unsigned int alloc_flags; + /** * @funcs: Function table for the device. * Constant after bo device init -- cgit v1.2.3 From b3c8fa0d9c2650ab9bdc7ccc980a6826c4f9021d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 Oct 2025 22:28:31 +0200 Subject: drm/{i915, xe}/display: pass parent interface to display probe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's gradually start calling i915 and xe parent, or core, drivers from display via function pointers passed at display probe. Going forward, the struct intel_display_parent_interface is expected to include const pointers to sub-structs by functionality, for example: struct intel_display_rpm { struct ref_tracker *(*get)(struct drm_device *drm); /* ... */ }; struct intel_display_parent_interface { /* ... */ const struct intel_display_rpm *rpm; }; This is a baby step towards not building display as part of both i915 and xe drivers, but rather making it an independent driver interfacing with the two. v3: useless include additions dropped v2: unrelated include removal dropped Cc: Jouni Högander Cc: Lucas De Marchi Cc: Rodrigo Vivi Cc: Ville Syrjälä Signed-off-by: Jani Nikula Signed-off-by: Jouni Högander Link: https://patch.msgid.link/20251030202836.1815680-2-jouni.hogander@intel.com --- include/drm/intel/display_parent_interface.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/drm/intel/display_parent_interface.h (limited to 'include') diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h new file mode 100644 index 000000000000..28c976815327 --- /dev/null +++ b/include/drm/intel/display_parent_interface.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation x*/ + +#ifndef __DISPLAY_PARENT_INTERFACE_H__ +#define __DISPLAY_PARENT_INTERFACE_H__ + +#include + +struct drm_device; + +/** + * struct intel_display_parent_interface - services parent driver provides to display + * + * The parent, or core, driver provides a pointer to this structure to display + * driver when calling intel_display_device_probe(). The display driver uses it + * to access services provided by the parent driver. The structure may contain + * sub-struct pointers to group function pointers by functionality. + * + * All function and sub-struct pointers must be initialized and callable unless + * explicitly marked as "optional" below. The display driver will only NULL + * check the optional pointers. + */ +struct intel_display_parent_interface { +}; + +#endif -- cgit v1.2.3 From 1914d6861b594dde7cbb359ab1ba43f2e3a82f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jouni=20H=C3=B6gander?= Date: Thu, 30 Oct 2025 22:28:32 +0200 Subject: drm/{i915, xe}/display: Add display runtime pm parent interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have differing implementations for display runtime pm in i915 and xe drivers. Add struct of function pointers into display_parent_interface which will contain used implementation of runtime pm. v2: - add _interface suffix to rpm function pointer struct - add struct ref_tracker forward declaration - use kernel-doc comments Reviewed-by: Jani Nikula Signed-off-by: Jouni Högander Link: https://patch.msgid.link/20251030202836.1815680-3-jouni.hogander@intel.com --- include/drm/intel/display_parent_interface.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include') diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h index 28c976815327..26bedc360044 100644 --- a/include/drm/intel/display_parent_interface.h +++ b/include/drm/intel/display_parent_interface.h @@ -7,6 +7,23 @@ #include struct drm_device; +struct ref_tracker; + +struct intel_display_rpm_interface { + struct ref_tracker *(*get)(const struct drm_device *drm); + struct ref_tracker *(*get_raw)(const struct drm_device *drm); + struct ref_tracker *(*get_if_in_use)(const struct drm_device *drm); + struct ref_tracker *(*get_noresume)(const struct drm_device *drm); + + void (*put)(const struct drm_device *drm, struct ref_tracker *wakeref); + void (*put_raw)(const struct drm_device *drm, struct ref_tracker *wakeref); + void (*put_unchecked)(const struct drm_device *drm); + + bool (*suspended)(const struct drm_device *drm); + void (*assert_held)(const struct drm_device *drm); + void (*assert_block)(const struct drm_device *drm); + void (*assert_unblock)(const struct drm_device *drm); +}; /** * struct intel_display_parent_interface - services parent driver provides to display @@ -21,6 +38,8 @@ struct drm_device; * check the optional pointers. */ struct intel_display_parent_interface { + /** @rpm: Runtime PM functions */ + const struct intel_display_rpm_interface *rpm; }; #endif -- cgit v1.2.3 From 8b61583f993589a64c061aa91b44f5bd350d90a5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 28 Oct 2025 22:07:26 +0200 Subject: drm/edid: add DRM_EDID_IDENT_INIT() to initialize struct drm_edid_ident MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a convenience helper for initializing struct drm_edid_ident. Cc: Tiago Martins Araújo Acked-by: Alex Deucher Tested-by: Tiago Martins Araújo Cc: stable@vger.kernel.org Link: https://patch.msgid.link/710b2ac6a211606ec1f90afa57b79e8c7375a27e.1761681968.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/drm_edid.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 3d1aecfec9b2..04f7a7f1f108 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -340,6 +340,12 @@ struct drm_edid_ident { const char *name; }; +#define DRM_EDID_IDENT_INIT(_vend_chr_0, _vend_chr_1, _vend_chr_2, _product_id, _name) \ +{ \ + .panel_id = drm_edid_encode_panel_id(_vend_chr_0, _vend_chr_1, _vend_chr_2, _product_id), \ + .name = _name, \ +} + #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) /* Short Audio Descriptor */ -- cgit v1.2.3 From 1556c170d2f78344a9eee567fbfcee4651689813 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Mon, 3 Nov 2025 22:25:44 -0800 Subject: accel/amdxdna: Add IOCTL parameter for resource data Extend DRM_IOCTL_AMDXDNA_GET_INFO to include additional parameters that allow collection of resource data. Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20251104062546.833771-2-lizhi.hou@amd.com --- include/uapi/drm/amdxdna_accel.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/amdxdna_accel.h b/include/uapi/drm/amdxdna_accel.h index c7eec9ceb2ae..8b679c38d308 100644 --- a/include/uapi/drm/amdxdna_accel.h +++ b/include/uapi/drm/amdxdna_accel.h @@ -442,6 +442,23 @@ enum amdxdna_drm_get_param { DRM_AMDXDNA_QUERY_HW_CONTEXTS, DRM_AMDXDNA_QUERY_FIRMWARE_VERSION = 8, DRM_AMDXDNA_GET_POWER_MODE, + DRM_AMDXDNA_QUERY_RESOURCE_INFO = 12, +}; + +/** + * struct amdxdna_drm_get_resource_info - Get resource information + */ +struct amdxdna_drm_get_resource_info { + /** @npu_clk_max: max H-Clocks */ + __u64 npu_clk_max; + /** @npu_tops_max: max TOPs */ + __u64 npu_tops_max; + /** @npu_task_max: max number of tasks */ + __u64 npu_task_max; + /** @npu_tops_curr: current TOPs */ + __u64 npu_tops_curr; + /** @npu_task_curr: current number of tasks */ + __u64 npu_task_curr; }; /** -- cgit v1.2.3 From e568dc3e625d818f199bd085005213cce3271453 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Mon, 3 Nov 2025 22:25:45 -0800 Subject: accel/amdxdna: Add IOCTL parameter for telemetry data Extend DRM_IOCTL_AMDXDNA_GET_INFO to include additional parameters that allow collection of telemetry data. Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20251104062546.833771-3-lizhi.hou@amd.com --- include/uapi/drm/amdxdna_accel.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/amdxdna_accel.h b/include/uapi/drm/amdxdna_accel.h index 8b679c38d308..8ad254bc35a5 100644 --- a/include/uapi/drm/amdxdna_accel.h +++ b/include/uapi/drm/amdxdna_accel.h @@ -442,6 +442,7 @@ enum amdxdna_drm_get_param { DRM_AMDXDNA_QUERY_HW_CONTEXTS, DRM_AMDXDNA_QUERY_FIRMWARE_VERSION = 8, DRM_AMDXDNA_GET_POWER_MODE, + DRM_AMDXDNA_QUERY_TELEMETRY, DRM_AMDXDNA_QUERY_RESOURCE_INFO = 12, }; @@ -461,6 +462,22 @@ struct amdxdna_drm_get_resource_info { __u64 npu_task_curr; }; +/** + * struct amdxdna_drm_query_telemetry_header - Telemetry data header + */ +struct amdxdna_drm_query_telemetry_header { + /** @major: Firmware telemetry interface major version number */ + __u32 major; + /** @minor: Firmware telemetry interface minor version number */ + __u32 minor; + /** @type: Telemetry query type */ + __u32 type; + /** @map_num_elements: Total number of elements in the map table */ + __u32 map_num_elements; + /** @map: Element map */ + __u32 map[]; +}; + /** * struct amdxdna_drm_get_info - Get some information from the AIE hardware. * @param: Value in enum amdxdna_drm_get_param. Specifies the structure passed in the buffer. -- cgit v1.2.3 From 3a0ff7b98af4a5de1b995dfb57e65843f9b7b628 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 4 Nov 2025 10:53:39 -0800 Subject: accel/amdxdna: Support preemption requests The driver checks the firmware version during initialization.If preemption is supported, the driver configures preemption accordingly and handles userspace preemption requests. Otherwise, the driver returns an error for userspace preemption requests. Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Lizhi Hou Link: https://patch.msgid.link/20251104185340.897560-1-lizhi.hou@amd.com --- include/uapi/drm/amdxdna_accel.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/drm/amdxdna_accel.h b/include/uapi/drm/amdxdna_accel.h index 8ad254bc35a5..62c917fd4f7b 100644 --- a/include/uapi/drm/amdxdna_accel.h +++ b/include/uapi/drm/amdxdna_accel.h @@ -443,7 +443,9 @@ enum amdxdna_drm_get_param { DRM_AMDXDNA_QUERY_FIRMWARE_VERSION = 8, DRM_AMDXDNA_GET_POWER_MODE, DRM_AMDXDNA_QUERY_TELEMETRY, - DRM_AMDXDNA_QUERY_RESOURCE_INFO = 12, + DRM_AMDXDNA_GET_FORCE_PREEMPT_STATE, + DRM_AMDXDNA_QUERY_RESOURCE_INFO, + DRM_AMDXDNA_GET_FRAME_BOUNDARY_PREEMPT_STATE, }; /** @@ -462,6 +464,16 @@ struct amdxdna_drm_get_resource_info { __u64 npu_task_curr; }; +/** + * struct amdxdna_drm_attribute_state - State of an attribute + */ +struct amdxdna_drm_attribute_state { + /** @state: enabled or disabled */ + __u8 state; + /** @pad: MBZ */ + __u8 pad[7]; +}; + /** * struct amdxdna_drm_query_telemetry_header - Telemetry data header */ @@ -613,6 +625,8 @@ enum amdxdna_drm_set_param { DRM_AMDXDNA_SET_POWER_MODE, DRM_AMDXDNA_WRITE_AIE_MEM, DRM_AMDXDNA_WRITE_AIE_REG, + DRM_AMDXDNA_SET_FORCE_PREEMPT, + DRM_AMDXDNA_SET_FRAME_BOUNDARY_PREEMPT, }; /** -- cgit v1.2.3 From b6fa6100cec0287856ec1b363b0a962a9be90e6c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 30 Oct 2025 22:41:51 -0700 Subject: drm/panfrost: fix UAPI kernel-doc warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix all kernel-doc warnings in include/uapi/drm/panfrost_drm.h. This mostly means modifying existing comments to conform to kernel-doc format, but there also some additions of missing kernel-doc comments and changing non-kernel-doc comments to use "/*" to begin them. Warning: panfrost_drm.h:83 struct member 'jc' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'in_syncs' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'in_sync_count' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'out_sync' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'bo_handles' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'bo_handle_count' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'requirements' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'jm_ctx_handle' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:83 struct member 'pad' not described in 'drm_panfrost_submit' Warning: panfrost_drm.h:116 Incorrect use of kernel-doc format: * Returned offset for the BO in the GPU address space. This offset Warning: panfrost_drm.h:124 struct member 'size' not described in 'drm_panfrost_create_bo' Warning: panfrost_drm.h:124 struct member 'flags' not described in 'drm_panfrost_create_bo' Warning: panfrost_drm.h:124 struct member 'handle' not described in 'drm_panfrost_create_bo' Warning: panfrost_drm.h:124 struct member 'pad' not described in 'drm_panfrost_create_bo' Warning: panfrost_drm.h:124 struct member 'nonzero' not described in 'drm_panfrost_create_bo' Warning: panfrost_drm.h:143 struct member 'handle' not described in 'drm_panfrost_mmap_bo' Warning: panfrost_drm.h:143 struct member 'flags' not described in 'drm_panfrost_mmap_bo' Warning: panfrost_drm.h:143 struct member 'offset' not described in 'drm_panfrost_mmap_bo' Signed-off-by: Randy Dunlap Reviewed-by: Steven Price Reviewed-by: Adrián Larumbe Signed-off-by: Steven Price Link: https://patch.msgid.link/20251031054152.1406764-1-rdunlap@infradead.org --- include/uapi/drm/panfrost_drm.h | 118 ++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/include/uapi/drm/panfrost_drm.h b/include/uapi/drm/panfrost_drm.h index e8b47c9f6976..1956431bb391 100644 --- a/include/uapi/drm/panfrost_drm.h +++ b/include/uapi/drm/panfrost_drm.h @@ -54,32 +54,46 @@ extern "C" { * This asks the kernel to have the GPU execute a render command list. */ struct drm_panfrost_submit { - - /** Address to GPU mapping of job descriptor */ + /** + * @jc: Address to GPU mapping of job descriptor + */ __u64 jc; - - /** An optional array of sync objects to wait on before starting this job. */ + /** + * @in_syncs: An optional array of sync objects to wait on + * before starting this job. + */ __u64 in_syncs; - - /** Number of sync objects to wait on before starting this job. */ + /** + * @in_sync_count: Number of sync objects to wait on before + * starting this job. + */ __u32 in_sync_count; - - /** An optional sync object to place the completion fence in. */ + /** + * @out_sync: An optional sync object to place the completion fence in. + */ __u32 out_sync; - - /** Pointer to a u32 array of the BOs that are referenced by the job. */ + /** + * @bo_handles: Pointer to a u32 array of the BOs that are + * referenced by the job. + */ __u64 bo_handles; - - /** Number of BO handles passed in (size is that times 4). */ + /** + * @bo_handle_count: Number of BO handles passed in (size is + * that times 4). + */ __u32 bo_handle_count; - - /** A combination of PANFROST_JD_REQ_* */ + /** + * @requirements: A combination of PANFROST_JD_REQ_* + */ __u32 requirements; - - /** JM context handle. Zero if you want to use the default context. */ + /** + * @jm_ctx_handle: JM context handle. Zero if you want to use the + * default context. + */ __u32 jm_ctx_handle; - - /** Padding field. MBZ. */ + /** + * @pad: Padding field. Must be zero. + */ __u32 pad; }; @@ -92,9 +106,18 @@ struct drm_panfrost_submit { * completed. */ struct drm_panfrost_wait_bo { + /** + * @handle: Handle for the object to wait for. + */ __u32 handle; + /** + * @pad: Padding, must be zero-filled. + */ __u32 pad; - __s64 timeout_ns; /* absolute */ + /** + * @timeout_ns: absolute number of nanoseconds to wait. + */ + __s64 timeout_ns; }; /* Valid flags to pass to drm_panfrost_create_bo */ @@ -107,16 +130,26 @@ struct drm_panfrost_wait_bo { * The flags argument is a bit mask of PANFROST_BO_* flags. */ struct drm_panfrost_create_bo { + /** + * @size: size of shmem/BO area to create (bytes) + */ __u32 size; + /** + * @flags: see PANFROST_BO_* flags + */ __u32 flags; - /** Returned GEM handle for the BO. */ + /** + * @handle: Returned GEM handle for the BO. + */ __u32 handle; - /* Pad, must be zero-filled. */ + /** + * @pad: Padding, must be zero-filled. + */ __u32 pad; /** - * Returned offset for the BO in the GPU address space. This offset - * is private to the DRM fd and is valid for the lifetime of the GEM - * handle. + * @offset: Returned offset for the BO in the GPU address space. + * This offset is private to the DRM fd and is valid for the + * lifetime of the GEM handle. * * This offset value will always be nonzero, since various HW * units treat 0 specially. @@ -136,10 +169,17 @@ struct drm_panfrost_create_bo { * used in a future extension. */ struct drm_panfrost_mmap_bo { - /** Handle for the object being mapped. */ + /** + * @handle: Handle for the object being mapped. + */ __u32 handle; + /** + * @flags: currently not used (should be zero) + */ __u32 flags; - /** offset into the drm node to use for subsequent mmap call. */ + /** + * @offset: offset into the drm node to use for subsequent mmap call. + */ __u64 offset; }; @@ -196,7 +236,7 @@ struct drm_panfrost_get_param { __u64 value; }; -/** +/* * Returns the offset for the BO in the GPU address space for this DRM fd. * This is the same value returned by drm_panfrost_create_bo, if that was called * from this DRM fd. @@ -244,12 +284,14 @@ struct drm_panfrost_madvise { * struct drm_panfrost_set_label_bo - ioctl argument for labelling Panfrost BOs. */ struct drm_panfrost_set_label_bo { - /** @handle: Handle of the buffer object to label. */ + /** + * @handle: Handle of the buffer object to label. + */ __u32 handle; - - /** @pad: MBZ. */ + /** + * @pad: Must be zero. + */ __u32 pad; - /** * @label: User pointer to a NUL-terminated string * @@ -330,10 +372,13 @@ enum drm_panfrost_jm_ctx_priority { }; struct drm_panfrost_jm_ctx_create { - /** @handle: Handle of the created JM context */ + /** + * @handle: Handle of the created JM context + */ __u32 handle; - - /** @priority: Context priority (see enum drm_panfrost_jm_ctx_priority). */ + /** + * @priority: Context priority (see enum drm_panfrost_jm_ctx_priority). + */ __u32 priority; }; @@ -344,8 +389,9 @@ struct drm_panfrost_jm_ctx_destroy { * Must be a valid context handle returned by DRM_IOCTL_PANTHOR_JM_CTX_CREATE. */ __u32 handle; - - /** @pad: Padding field, MBZ. */ + /** + * @pad: Padding field, must be zero. + */ __u32 pad; }; -- cgit v1.2.3 From 3ca8b2668ca5a410c23a7a7932cc406ebbb89ab2 Mon Sep 17 00:00:00 2001 From: Bagas Sanjaya Date: Thu, 6 Nov 2025 07:52:17 +0700 Subject: drm/ttm: Fix @alloc_flags description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stephen Rothwell reports htmldocs warnings when merging drm-misc tree: Documentation/gpu/drm-mm:40: include/drm/ttm/ttm_device.h:225: ERROR: Unknown target name: "ttm_allocation". [docutils] Documentation/gpu/drm-mm:43: drivers/gpu/drm/ttm/ttm_device.c:202: ERROR: Unknown target name: "ttm_allocation". [docutils] Documentation/gpu/drm-mm:73: include/drm/ttm/ttm_pool.h:68: ERROR: Unknown target name: "ttm_allocation_pool". [docutils] Documentation/gpu/drm-mm:76: drivers/gpu/drm/ttm/ttm_pool.c:1070: ERROR: Unknown target name: "ttm_allocation_pool". [docutils] Fix these by adding missing wildcard on TTM_ALLOCATION_* and TTM_ALLOCATION_POOL_* in @alloc_flags description. Fixes: 0af5b6a8f8dd ("drm/ttm: Replace multiple booleans with flags in pool init") Fixes: 77e19f8d3297 ("drm/ttm: Replace multiple booleans with flags in device init") Fixes: 402b3a865090 ("drm/ttm: Add an allocation flag to propagate -ENOSPC on OOM") Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/linux-next/20251105161838.55b962a3@canb.auug.org.au/ Signed-off-by: Bagas Sanjaya Acked-by: Tvrtko Ursulin Reviewed-by: Christian König Signed-off-by: Tvrtko Ursulin Link: https://lore.kernel.org/r/20251106005217.14026-1-bagasdotme@gmail.com --- include/drm/ttm/ttm_device.h | 2 +- include/drm/ttm/ttm_pool.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h index d016360e5ceb..5618aef462f2 100644 --- a/include/drm/ttm/ttm_device.h +++ b/include/drm/ttm/ttm_device.h @@ -221,7 +221,7 @@ struct ttm_device { struct list_head device_list; /** - * @alloc_flags: TTM_ALLOCATION_ flags. + * @alloc_flags: TTM_ALLOCATION_* flags. */ unsigned int alloc_flags; diff --git a/include/drm/ttm/ttm_pool.h b/include/drm/ttm/ttm_pool.h index 67c72de913bb..233581670e78 100644 --- a/include/drm/ttm/ttm_pool.h +++ b/include/drm/ttm/ttm_pool.h @@ -64,7 +64,7 @@ struct ttm_pool_type { * * @dev: the device we allocate pages for * @nid: which numa node to use - * @alloc_flags: TTM_ALLOCATION_POOL_ flags + * @alloc_flags: TTM_ALLOCATION_POOL_* flags * @caching: pools for each caching/order */ struct ttm_pool { -- cgit v1.2.3 From aaecfadc22cca4c7ad381b1df457e8857c01fe14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Winiarski?= Date: Wed, 12 Nov 2025 14:22:20 +0100 Subject: drm/intel/bmg: Allow device ID usage with single-argument macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When INTEL_BMG_G21_IDS were added as a subplatform, token concatenation operator usage was omitted, making INTEL_BMG_IDS not usable with single-argument macros. Fix that by adding the missing operator. Fixes: 78de8f876683 ("drm/xe: Handle Wa_22010954014 and Wa_14022085890 as device workarounds") Reviewed-by: Lucas De Marchi Link: https://patch.msgid.link/20251112132220.516975-25-michal.winiarski@intel.com Signed-off-by: Michał Winiarski --- include/drm/intel/pciids.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/intel/pciids.h b/include/drm/intel/pciids.h index 6e53fb4cdd37..286e580b2bd6 100644 --- a/include/drm/intel/pciids.h +++ b/include/drm/intel/pciids.h @@ -861,7 +861,7 @@ MACRO__(0xE216, ## __VA_ARGS__) #define INTEL_BMG_IDS(MACRO__, ...) \ - INTEL_BMG_G21_IDS(MACRO__, __VA_ARGS__), \ + INTEL_BMG_G21_IDS(MACRO__, ## __VA_ARGS__), \ MACRO__(0xE220, ## __VA_ARGS__), \ MACRO__(0xE221, ## __VA_ARGS__), \ MACRO__(0xE222, ## __VA_ARGS__), \ -- cgit v1.2.3 From 1ff27c5929ab0f5e34d5062637369ca542a6d385 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Tue, 21 Oct 2025 13:19:15 +0300 Subject: drm/bridge: dw-hdmi-qp: Handle platform supported formats and color depth Extend struct dw_hdmi_qp_plat_data to include the supported display output formats and maximum bits per color channel. When provided by the platform driver, use them to setup the HDMI bridge accordingly. Additionally, improve debug logging in dw_hdmi_qp_bridge_atomic_enable() to also show the current HDMI output format and bpc. Acked-by: Daniel Stone Signed-off-by: Cristian Ciocaltea Signed-off-by: Heiko Stuebner Link: https://lore.kernel.org/r/20251021-rk3588-10bpc-v3-2-3d3eed00a6db@collabora.com --- include/drm/bridge/dw_hdmi_qp.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h index 76ecf3130199..3f461f6b9bbf 100644 --- a/include/drm/bridge/dw_hdmi_qp.h +++ b/include/drm/bridge/dw_hdmi_qp.h @@ -25,6 +25,10 @@ struct dw_hdmi_qp_plat_data { int main_irq; int cec_irq; unsigned long ref_clk_rate; + /* Supported output formats: bitmask of @hdmi_colorspace */ + unsigned int supported_formats; + /* Maximum bits per color channel: 8, 10 or 12 */ + unsigned int max_bpc; }; struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, -- cgit v1.2.3 From 943240d342f148896733eb6c7b223a08aa1f520a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 10 Nov 2025 16:44:21 +0100 Subject: drm/client: Pass force parameter to client restore Add force parameter to client restore and pass value through the layers. The only currently used value is false. If force is true, the client should restore its display even if it does not hold the DRM master lock. This is be required for emergency output, such as sysrq. While at it, inline drm_fb_helper_lastclose(), which is a trivial wrapper around drm_fb_helper_restore_fbdev_mode_unlocked(). Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patch.msgid.link/20251110154616.539328-2-tzimmermann@suse.de --- include/drm/drm_client.h | 8 +++++--- include/drm/drm_client_event.h | 4 ++-- include/drm/drm_fb_helper.h | 8 ++------ 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index 5ecde0f6f591..c972a8a3385b 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -57,12 +57,14 @@ struct drm_client_funcs { * * Note that the core does not guarantee exclusion against concurrent * drm_open(). Clients need to ensure this themselves, for example by - * using drm_master_internal_acquire() and - * drm_master_internal_release(). + * using drm_master_internal_acquire() and drm_master_internal_release(). + * + * If the caller passes force, the client should ignore any present DRM + * master and restore the display anyway. * * This callback is optional. */ - int (*restore)(struct drm_client_dev *client); + int (*restore)(struct drm_client_dev *client, bool force); /** * @hotplug: diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h index 985d6f02a4c4..79369c755bc9 100644 --- a/include/drm/drm_client_event.h +++ b/include/drm/drm_client_event.h @@ -10,7 +10,7 @@ struct drm_device; #if defined(CONFIG_DRM_CLIENT) void drm_client_dev_unregister(struct drm_device *dev); void drm_client_dev_hotplug(struct drm_device *dev); -void drm_client_dev_restore(struct drm_device *dev); +void drm_client_dev_restore(struct drm_device *dev, bool force); void drm_client_dev_suspend(struct drm_device *dev); void drm_client_dev_resume(struct drm_device *dev); #else @@ -18,7 +18,7 @@ static inline void drm_client_dev_unregister(struct drm_device *dev) { } static inline void drm_client_dev_hotplug(struct drm_device *dev) { } -static inline void drm_client_dev_restore(struct drm_device *dev) +static inline void drm_client_dev_restore(struct drm_device *dev, bool force) { } static inline void drm_client_dev_suspend(struct drm_device *dev) { } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index c1d38d54a112..63e3af8dd5ed 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -254,7 +254,8 @@ int drm_fb_helper_set_par(struct fb_info *info); int drm_fb_helper_check_var(struct fb_var_screeninfo *var, struct fb_info *info); -int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper); +int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, + bool force); struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper); @@ -283,7 +284,6 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper); int drm_fb_helper_debug_enter(struct fb_info *info); int drm_fb_helper_debug_leave(struct fb_info *info); -void drm_fb_helper_lastclose(struct drm_device *dev); #else static inline void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, @@ -409,10 +409,6 @@ static inline int drm_fb_helper_debug_leave(struct fb_info *info) { return 0; } - -static inline void drm_fb_helper_lastclose(struct drm_device *dev) -{ -} #endif #endif -- cgit v1.2.3 From 6915190a50e8f7cf13dcbe534b02845be533b60a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 10 Nov 2025 16:44:22 +0100 Subject: drm/client: Support emergency restore via sysrq for all clients Move the sysrq functionality from DRM fbdev helpers to the DRM device and in-kernel clients, so that it becomes available on all clients. DRM fbdev helpers support emergency restoration of the console output via a special key combination. Press SysRq+v to replace the current compositor with the kernel's output on the framebuffer console. This allows users to see the log messages during system emergencies. By moving the functionality from fbdev helpers to the DRM device, any in-kernel client can serve as emergency output. This can be used to bring up drm_log, for example. Each DRM device registers itself to the list of possible sysrq handlers. On receiving SysRq+v, the DRM core goes over all registered devices and restores an in-kernel DRM client for each of them. See Documentation/admin-guide/sysrq.rst on how to invoke SysRq. Switch VTs to bring back the user-space compositor. v2: - declare placeholders as 'static inline' (kernel test robot) - fix grammar in commit description Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patch.msgid.link/20251110154616.539328-3-tzimmermann@suse.de --- include/drm/drm_device.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 778b2cca6c49..5af49c5c3778 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -238,6 +238,14 @@ struct drm_device { */ struct list_head clientlist; + /** + * @client_sysrq_list: + * + * Entry into list of devices registered for sysrq. Allows in-kernel + * clients on this device to handle sysrq keys. + */ + struct list_head client_sysrq_list; + /** * @vblank_disable_immediate: * -- cgit v1.2.3 From 63c971af40365ee706c7e24f6a7900d693518f09 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 27 Oct 2025 09:12:17 +0100 Subject: drm/fb-helper: Allocate and release fb_info in single place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the calls to drm_fb_helper_alloc_info() from drivers into a single place in fbdev helpers. Allocates struct fb_info for a new framebuffer device. Then call drm_fb_helper_single_fb_probe() to create an fbdev screen buffer. Also release the instance on errors by calling drm_fb_helper_release_info(). Simplifies the code and fixes the error cleanup for some of the drivers. Regular release of the struct fb_info instance still happens in drm_fb_helper_fini() as before. v2: - remove error rollback in driver implementations (kernel test robot) - initialize info in TTM implementation (kernel test robot) Signed-off-by: Thomas Zimmermann Acked-by: Christian König # radeon Acked-by: Dmitry Baryshkov # msm Acked-by: Javier Martinez Canillas Link: https://patch.msgid.link/20251027081245.80262-1-tzimmermann@suse.de --- include/drm/drm_fb_helper.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include') diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 63e3af8dd5ed..dd9a18f8de5a 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -257,8 +257,6 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, bool force); -struct fb_info *drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper); -void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper); void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper); void drm_fb_helper_fill_info(struct fb_info *info, struct drm_fb_helper *fb_helper, @@ -340,16 +338,6 @@ drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) return 0; } -static inline struct fb_info * -drm_fb_helper_alloc_info(struct drm_fb_helper *fb_helper) -{ - return NULL; -} - -static inline void drm_fb_helper_release_info(struct drm_fb_helper *fb_helper) -{ -} - static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper) { } -- cgit v1.2.3 From ddf055b80a544d6f36f77be5f0c6d3c80177d57c Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 21 Nov 2025 11:12:29 +0100 Subject: drm/ttm: rework pipelined eviction fence handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now ttm stored a single pipelined eviction fence which means drivers had to use a single entity for these evictions. To lift this requirement, this commit allows up to 8 entities to be used. Ideally a dma_resv object would have been used as a container of the eviction fences, but the locking rules makes it complex. dma_resv all have the same ww_class, which means "Attempting to lock more mutexes after ww_acquire_done." is an error. One alternative considered was to introduced a 2nd ww_class for specific resv to hold a single "transient" lock (= the resv lock would only be held for a short period, without taking any other locks). The other option, is to statically reserve a fence array, and extend the existing code to deal with N fences, instead of 1. The driver is still responsible to reserve the correct number of fence slots. Signed-off-by: Pierre-Eric Pelloux-Prayer Link: https://lore.kernel.org/r/20251121101315.3585-20-pierre-eric.pelloux-prayer@amd.com Reviewed-by: Christian König Signed-off-by: Christian König --- include/drm/ttm/ttm_resource.h | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 68bf010d8b40..33e80f30b8b8 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -51,6 +51,15 @@ struct io_mapping; struct sg_table; struct scatterlist; +/** + * define TTM_NUM_MOVE_FENCES - How many entities can be used for evictions + * + * Pipelined evictions can be spread on multiple entities. This + * is the max number of entities that can be used by the driver + * for that purpose. + */ +#define TTM_NUM_MOVE_FENCES 8 + /** * enum ttm_lru_item_type - enumerate ttm_lru_item subclasses */ @@ -181,8 +190,8 @@ struct ttm_resource_manager_func { * @size: Size of the managed region. * @bdev: ttm device this manager belongs to * @func: structure pointer implementing the range manager. See above - * @move_lock: lock for move fence - * @move: The fence of the last pipelined move operation. + * @eviction_lock: lock for eviction fences + * @eviction_fences: The fences of the last pipelined move operation. * @lru: The lru list for this memory type. * * This structure is used to identify and manage memory types for a device. @@ -196,12 +205,12 @@ struct ttm_resource_manager { struct ttm_device *bdev; uint64_t size; const struct ttm_resource_manager_func *func; - spinlock_t move_lock; - /* - * Protected by @move_lock. + /* This is very similar to a dma_resv object, but locking rules make + * it difficult to use one in this context. */ - struct dma_fence *move; + spinlock_t eviction_lock; + struct dma_fence *eviction_fences[TTM_NUM_MOVE_FENCES]; /* * Protected by the bdev->lru_lock. @@ -422,8 +431,12 @@ static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man) static inline void ttm_resource_manager_cleanup(struct ttm_resource_manager *man) { - dma_fence_put(man->move); - man->move = NULL; + int i; + + for (i = 0; i < TTM_NUM_MOVE_FENCES; i++) { + dma_fence_put(man->eviction_fences[i]); + man->eviction_fences[i] = NULL; + } } void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk); -- cgit v1.2.3 From 4fc183828b050c1d7d94347c876c04a5b680b4fc Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:26 -0700 Subject: drm: Add helper for conversion from signed-magnitude CTM values are defined as signed-magnitude values. Add a helper that converts from CTM signed-magnitude fixed point value to the twos-complement value used by drm_fixed. Reviewed-by: Sebastian Wick Reviewed-by: Louis Chauvet Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-2-alex.hung@amd.com --- include/drm/drm_fixed.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 1922188f00e8..33de514a5221 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -78,6 +78,23 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B) #define DRM_FIXED_EPSILON 1LL #define DRM_FIXED_ALMOST_ONE (DRM_FIXED_ONE - DRM_FIXED_EPSILON) +/** + * @drm_sm2fixp + * + * Convert a 1.31.32 signed-magnitude fixed point to 32.32 + * 2s-complement fixed point + * + * @return s64 2s-complement fixed point + */ +static inline s64 drm_sm2fixp(__u64 a) +{ + if ((a & (1LL << 63))) { + return -(a & 0x7fffffffffffffffll); + } else { + return a; + } +} + static inline s64 drm_int2fixp(int a) { return ((s64)a) << DRM_FIXED_POINT; -- cgit v1.2.3 From cfc27680ee208cdf7a61cda817b4158c4142595f Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:29 -0700 Subject: drm/colorop: Introduce new drm_colorop mode object This patches introduces a new drm_colorop mode object. This object represents color transformations and can be used to define color pipelines. We also introduce the drm_colorop_state here, as well as various helpers and state tracking bits. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-5-alex.hung@amd.com --- include/drm/drm_atomic.h | 70 +++++++++++++++++ include/drm/drm_atomic_uapi.h | 1 + include/drm/drm_colorop.h | 169 ++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_mode_config.h | 18 +++++ include/drm/drm_plane.h | 8 ++ include/uapi/drm/drm_mode.h | 1 + 6 files changed, 267 insertions(+) create mode 100644 include/drm/drm_colorop.h (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 2e433d44658d..895529337d7e 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -30,6 +30,7 @@ #include #include +#include /** * struct drm_crtc_commit - track modeset commits on a CRTC @@ -157,6 +158,11 @@ struct drm_crtc_commit { bool abort_completion; }; +struct __drm_colorops_state { + struct drm_colorop *ptr; + struct drm_colorop_state *state, *old_state, *new_state; +}; + struct __drm_planes_state { struct drm_plane *ptr; @@ -531,6 +537,14 @@ struct drm_atomic_state { */ bool checked : 1; + /** + * @colorops: + * + * Pointer to array of @drm_colorop and @drm_colorop_state part of this + * update. + */ + struct __drm_colorops_state *colorops; + /** * @planes: * @@ -672,6 +686,9 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state, struct drm_plane_state * __must_check drm_atomic_get_plane_state(struct drm_atomic_state *state, struct drm_plane *plane); +struct drm_colorop_state * +drm_atomic_get_colorop_state(struct drm_atomic_state *state, + struct drm_colorop *colorop); struct drm_connector_state * __must_check drm_atomic_get_connector_state(struct drm_atomic_state *state, struct drm_connector *connector); @@ -768,6 +785,36 @@ drm_atomic_get_new_plane_state(const struct drm_atomic_state *state, return state->planes[drm_plane_index(plane)].new_state; } +/** + * drm_atomic_get_old_colorop_state - get colorop state, if it exists + * @state: global atomic state object + * @colorop: colorop to grab + * + * This function returns the old colorop state for the given colorop, or + * NULL if the colorop is not part of the global atomic state. + */ +static inline struct drm_colorop_state * +drm_atomic_get_old_colorop_state(struct drm_atomic_state *state, + struct drm_colorop *colorop) +{ + return state->colorops[drm_colorop_index(colorop)].old_state; +} + +/** + * drm_atomic_get_new_colorop_state - get colorop state, if it exists + * @state: global atomic state object + * @colorop: colorop to grab + * + * This function returns the new colorop state for the given colorop, or + * NULL if the colorop is not part of the global atomic state. + */ +static inline struct drm_colorop_state * +drm_atomic_get_new_colorop_state(struct drm_atomic_state *state, + struct drm_colorop *colorop) +{ + return state->colorops[drm_colorop_index(colorop)].new_state; +} + /** * drm_atomic_get_old_connector_state - get connector state, if it exists * @state: global atomic state object @@ -998,6 +1045,29 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (new_crtc_state) = (__state)->crtcs[__i].new_state, \ (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) +/** + * for_each_oldnew_colorop_in_state - iterate over all colorops in an atomic update + * @__state: &struct drm_atomic_state pointer + * @colorop: &struct drm_colorop iteration cursor + * @old_colorop_state: &struct drm_colorop_state iteration cursor for the old state + * @new_colorop_state: &struct drm_colorop_state iteration cursor for the new state + * @__i: int iteration cursor, for macro-internal use + * + * This iterates over all colorops in an atomic update, tracking both old and + * new state. This is useful in places where the state delta needs to be + * considered, for example in atomic check functions. + */ +#define for_each_oldnew_colorop_in_state(__state, colorop, old_colorop_state, \ + new_colorop_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_colorop; \ + (__i)++) \ + for_each_if ((__state)->colorops[__i].ptr && \ + ((colorop) = (__state)->colorops[__i].ptr, \ + (void)(colorop) /* Only to avoid unused-but-set-variable warning */, \ + (old_colorop_state) = (__state)->colorops[__i].old_state,\ + (new_colorop_state) = (__state)->colorops[__i].new_state, 1)) + /** * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update * @__state: &struct drm_atomic_state pointer diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h index 4c6d39d7bdb2..70a115d523cd 100644 --- a/include/drm/drm_atomic_uapi.h +++ b/include/drm/drm_atomic_uapi.h @@ -37,6 +37,7 @@ struct drm_crtc; struct drm_connector_state; struct dma_fence; struct drm_framebuffer; +struct drm_colorop; int __must_check drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state, diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h new file mode 100644 index 000000000000..28bb7091ef1f --- /dev/null +++ b/include/drm/drm_colorop.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __DRM_COLOROP_H__ +#define __DRM_COLOROP_H__ + +#include +#include +#include + +/** + * struct drm_colorop_state - mutable colorop state + */ +struct drm_colorop_state { + /** @colorop: backpointer to the colorop */ + struct drm_colorop *colorop; + + /* + * Color properties + * + * The following fields are not always valid, their usage depends + * on the colorop type. See their associated comment for more + * information. + */ + + /** @state: backpointer to global drm_atomic_state */ + struct drm_atomic_state *state; +}; + +/** + * struct drm_colorop - DRM color operation control structure + * + * A colorop represents one color operation. They can be chained via + * the 'next' pointer to build a color pipeline. + * + * Since colorops cannot stand-alone and are used to describe colorop + * operations on a plane they don't have their own locking mechanism but + * are locked and programmed along with their associated &drm_plane. + * + */ +struct drm_colorop { + /** @dev: parent DRM device */ + struct drm_device *dev; + + /** + * @head: + * + * List of all colorops on @dev, linked from &drm_mode_config.colorop_list. + * Invariant over the lifetime of @dev and therefore does not need + * locking. + */ + struct list_head head; + + /** + * @index: Position inside the mode_config.list, can be used as an array + * index. It is invariant over the lifetime of the colorop. + */ + unsigned int index; + + /** @base: base mode object */ + struct drm_mode_object base; + + /** + * @plane: + * + * The plane on which the colorop sits. A drm_colorop is always unique + * to a plane. + */ + struct drm_plane *plane; + + /** + * @state: + * + * Current atomic state for this colorop. + * + * This is protected by @mutex. Note that nonblocking atomic commits + * access the current colorop state without taking locks. + */ + struct drm_colorop_state *state; + + /* + * Color properties + * + * The following fields are not always valid, their usage depends + * on the colorop type. See their associated comment for more + * information. + */ + + /** @properties: property tracking for this colorop */ + struct drm_object_properties properties; + +}; + +#define obj_to_colorop(x) container_of(x, struct drm_colorop, base) + +/** + * drm_colorop_find - look up a Colorop object from its ID + * @dev: DRM device + * @file_priv: drm file to check for lease against. + * @id: &drm_mode_object ID + * + * This can be used to look up a Colorop from its userspace ID. Only used by + * drivers for legacy IOCTLs and interface, nowadays extensions to the KMS + * userspace interface should be done using &drm_property. + */ +static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev, + struct drm_file *file_priv, + uint32_t id) +{ + struct drm_mode_object *mo; + + mo = drm_mode_object_find(dev, file_priv, id, DRM_MODE_OBJECT_COLOROP); + return mo ? obj_to_colorop(mo) : NULL; +} + +struct drm_colorop_state * +drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); + +void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop, + struct drm_colorop_state *state); + +/** + * drm_colorop_reset - reset colorop atomic state + * @colorop: drm colorop + * + * Resets the atomic state for @colorop by freeing the state pointer (which might + * be NULL, e.g. at driver load time) and allocating a new empty state object. + */ +void drm_colorop_reset(struct drm_colorop *colorop); + +/** + * drm_colorop_index - find the index of a registered colorop + * @colorop: colorop to find index for + * + * Given a registered colorop, return the index of that colorop within a DRM + * device's list of colorops. + */ +static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) +{ + return colorop->index; +} + +#define drm_for_each_colorop(colorop, dev) \ + list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) + +#endif /* __DRM_COLOROP_H__ */ diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 2e848b816218..895fb820dba0 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -500,6 +500,24 @@ struct drm_mode_config { */ struct raw_spinlock panic_lock; + /** + * @num_colorop: + * + * Number of colorop objects on this device. + * This is invariant over the lifetime of a device and hence doesn't + * need any locks. + */ + int num_colorop; + + /** + * @colorop_list: + * + * List of colorop objects linked with &drm_colorop.head. This is + * invariant over the lifetime of a device and hence doesn't need any + * locks. + */ + struct list_head colorop_list; + /** * @num_crtc: * diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 01479dd94e76..61fedd4e253c 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -243,6 +243,14 @@ struct drm_plane_state { */ enum drm_scaling_filter scaling_filter; + /** + * @color_pipeline: + * + * The first colorop of the active color pipeline, or NULL, if no + * color pipeline is active. + */ + struct drm_colorop *color_pipeline; + /** * @commit: Tracks the pending commit to prevent use-after-free conditions, * and for async plane updates. diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 1e0e02a79b5c..ec27125c2928 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -629,6 +629,7 @@ struct drm_mode_connector_set_property { #define DRM_MODE_OBJECT_FB 0xfbfbfbfb #define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb #define DRM_MODE_OBJECT_PLANE 0xeeeeeeee +#define DRM_MODE_OBJECT_COLOROP 0xfafafafa #define DRM_MODE_OBJECT_ANY 0 struct drm_mode_obj_get_properties { -- cgit v1.2.3 From 84423e561208054f872b3ca66e3e99a10d06c0ac Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:30 -0700 Subject: drm/colorop: Add TYPE property Add a read-only TYPE property. The TYPE specifies the colorop type, such as enumerated curve, 1D LUT, CTM, 3D LUT, PWL LUT, etc. For now we're only introducing an enumerated 1D LUT type to illustrate the concept. Reviewed-by: Simon Ser Reviewed-by: Louis Chauvet Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-6-alex.hung@amd.com --- include/drm/drm_colorop.h | 24 ++++++++++++++++++++++++ include/uapi/drm/drm_mode.h | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 28bb7091ef1f..0bda70f4e82a 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -112,6 +112,21 @@ struct drm_colorop { /** @properties: property tracking for this colorop */ struct drm_object_properties properties; + /** + * @type: + * + * Read-only + * Type of color operation + */ + enum drm_colorop_type type; + + /** + * @type_property: + * + * Read-only "TYPE" property for specifying the type of + * this color operation. The type is enum drm_colorop_type. + */ + struct drm_property *type_property; }; #define obj_to_colorop(x) container_of(x, struct drm_colorop, base) @@ -166,4 +181,13 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) #define drm_for_each_colorop(colorop, dev) \ list_for_each_entry(colorop, &(dev)->mode_config.colorop_list, head) +/** + * drm_get_colorop_type_name - return a string for colorop type + * @type: colorop type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_type_name(enum drm_colorop_type type); + #endif /* __DRM_COLOROP_H__ */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index ec27125c2928..c419f93eb94d 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -858,6 +858,25 @@ struct drm_color_lut { __u16 reserved; }; +/** + * enum drm_colorop_type - Type of color operation + * + * drm_colorops can be of many different types. Each type behaves differently + * and defines a different set of properties. This enum defines all types and + * gives a high-level description. + */ +enum drm_colorop_type { + /** + * @DRM_COLOROP_1D_CURVE: + * + * enum string "1D Curve" + * + * A 1D curve that is being applied to all color channels. The + * curve is specified via the CURVE_1D_TYPE colorop property. + */ + DRM_COLOROP_1D_CURVE +}; + /** * struct drm_plane_size_hint - Plane size hints * @width: The width of the plane in pixel -- cgit v1.2.3 From 41651f9d42eb24186a38a11be0a75dbc148d2991 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:31 -0700 Subject: drm/colorop: Add 1D Curve subtype Add a new drm_colorop with DRM_COLOROP_1D_CURVE with two subtypes: DRM_COLOROP_1D_CURVE_SRGB_EOTF and DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF. Reviewed-by: Simon Ser Reviewed-by: Louis Chauvet Signed-off-by: Harry Wentland Co-developed-by: Alex Hung Signed-off-by: Alex Hung Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-7-alex.hung@amd.com --- include/drm/drm_colorop.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 0bda70f4e82a..3594e50cfd68 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -31,6 +31,41 @@ #include #include +/** + * enum drm_colorop_curve_1d_type - type of 1D curve + * + * Describes a 1D curve to be applied by the DRM_COLOROP_1D_CURVE colorop. + */ +enum drm_colorop_curve_1d_type { + /** + * @DRM_COLOROP_1D_CURVE_SRGB_EOTF: + * + * enum string "sRGB EOTF" + * + * sRGB piece-wise electro-optical transfer function. Transfer + * characteristics as defined by IEC 61966-2-1 sRGB. Equivalent + * to H.273 TransferCharacteristics code point 13 with + * MatrixCoefficients set to 0. + */ + DRM_COLOROP_1D_CURVE_SRGB_EOTF, + + /** + * @DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF: + * + * enum string "sRGB Inverse EOTF" + * + * The inverse of &DRM_COLOROP_1D_CURVE_SRGB_EOTF + */ + DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF, + + /** + * @DRM_COLOROP_1D_CURVE_COUNT: + * + * enum value denoting the size of the enum + */ + DRM_COLOROP_1D_CURVE_COUNT +}; + /** * struct drm_colorop_state - mutable colorop state */ @@ -46,6 +81,13 @@ struct drm_colorop_state { * information. */ + /** + * @curve_1d_type: + * + * Type of 1D curve. + */ + enum drm_colorop_curve_1d_type curve_1d_type; + /** @state: backpointer to global drm_atomic_state */ struct drm_atomic_state *state; }; @@ -127,6 +169,14 @@ struct drm_colorop { * this color operation. The type is enum drm_colorop_type. */ struct drm_property *type_property; + + /** + * @curve_1d_type_property: + * + * Sub-type for DRM_COLOROP_1D_CURVE type. + */ + struct drm_property *curve_1d_type_property; + }; #define obj_to_colorop(x) container_of(x, struct drm_colorop, base) @@ -151,6 +201,9 @@ static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev, return mo ? obj_to_colorop(mo) : NULL; } +int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane, u64 supported_tfs); + struct drm_colorop_state * drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); @@ -190,4 +243,13 @@ static inline unsigned int drm_colorop_index(const struct drm_colorop *colorop) */ const char *drm_get_colorop_type_name(enum drm_colorop_type type); +/** + * drm_get_colorop_curve_1d_type_name - return a string for 1D curve type + * @type: 1d curve type to compute name of + * + * In contrast to the other drm_get_*_name functions this one here returns a + * const pointer and hence is threadsafe. + */ +const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); + #endif /* __DRM_COLOROP_H__ */ -- cgit v1.2.3 From 8c5ea1745f4c89576bc6d213ea7f9a7068ada4ad Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:32 -0700 Subject: drm/colorop: Add BYPASS property We want to be able to bypass each colorop at all times. Introduce a new BYPASS boolean property for this. Reviewed-by: Simon Ser Reviewed-by: Louis Chauvet Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-8-alex.hung@amd.com --- include/drm/drm_colorop.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 3594e50cfd68..2d24f7248831 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -81,6 +81,15 @@ struct drm_colorop_state { * information. */ + /** + * @bypass: + * + * When the property BYPASS exists on this colorop, this stores + * the requested bypass state: true if colorop shall be bypassed, + * false if colorop is enabled. + */ + bool bypass; + /** * @curve_1d_type: * @@ -170,6 +179,18 @@ struct drm_colorop { */ struct drm_property *type_property; + /** + * @bypass_property: + * + * Boolean property to control enablement of the color + * operation. Setting bypass to "true" shall always be supported + * in order to allow compositors to quickly fall back to + * alternate methods of color processing. This is important + * since setting color operations can fail due to unique + * HW constraints. + */ + struct drm_property *bypass_property; + /** * @curve_1d_type_property: * -- cgit v1.2.3 From 78a5add824186da775be4a10ac0a95cca239718c Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:33 -0700 Subject: drm/colorop: Add NEXT property We'll construct color pipelines out of drm_colorop by chaining them via the NEXT pointer. NEXT will point to the next drm_colorop in the pipeline, or by 0 if we're at the end of the pipeline. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-9-alex.hung@amd.com --- include/drm/drm_colorop.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 2d24f7248831..d8c17c537586 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -171,6 +171,14 @@ struct drm_colorop { */ enum drm_colorop_type type; + /** + * @next: + * + * Read-only + * Pointer to next drm_colorop in pipeline + */ + struct drm_colorop *next; + /** * @type_property: * @@ -198,6 +206,13 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** + * @next_property: + * + * Read-only property to next colorop in the pipeline + */ + struct drm_property *next_property; + }; #define obj_to_colorop(x) container_of(x, struct drm_colorop, base) @@ -273,4 +288,6 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type); */ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); +void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); + #endif /* __DRM_COLOROP_H__ */ -- cgit v1.2.3 From 2afc3184f3b3f05de05ee1d8fede76d3c20802be Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:35 -0700 Subject: drm/plane: Add COLOR PIPELINE property We're adding a new enum COLOR PIPELINE property. This property will have entries for each COLOR PIPELINE by referencing the DRM object ID of the first drm_colorop of the pipeline. 0 disables the entire COLOR PIPELINE. Userspace can use this to discover the available color pipelines, as well as set the desired one. The color pipelines are programmed via properties on the actual drm_colorop objects. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-11-alex.hung@amd.com --- include/drm/drm_atomic.h | 3 +++ include/drm/drm_atomic_uapi.h | 2 ++ include/drm/drm_plane.h | 11 +++++++++++ 3 files changed, 16 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 895529337d7e..faeb5de74d50 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -906,6 +906,9 @@ drm_atomic_add_affected_connectors(struct drm_atomic_state *state, int __must_check drm_atomic_add_affected_planes(struct drm_atomic_state *state, struct drm_crtc *crtc); +int __must_check +drm_atomic_add_affected_colorops(struct drm_atomic_state *state, + struct drm_plane *plane); int __must_check drm_atomic_check_only(struct drm_atomic_state *state); int __must_check drm_atomic_commit(struct drm_atomic_state *state); diff --git a/include/drm/drm_atomic_uapi.h b/include/drm/drm_atomic_uapi.h index 70a115d523cd..436315523326 100644 --- a/include/drm/drm_atomic_uapi.h +++ b/include/drm/drm_atomic_uapi.h @@ -50,6 +50,8 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, struct drm_crtc *crtc); void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, struct drm_framebuffer *fb); +void drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state, + struct drm_colorop *colorop); int __must_check drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, struct drm_crtc *crtc); diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 61fedd4e253c..703ef4d1bbbc 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -791,6 +791,14 @@ struct drm_plane { */ struct drm_property *color_range_property; + /** + * @color_pipeline_property: + * + * Optional "COLOR_PIPELINE" enum property for specifying + * a color pipeline to use on the plane. + */ + struct drm_property *color_pipeline_property; + /** * @scaling_filter_property: property to apply a particular filter while * scaling. @@ -1014,4 +1022,7 @@ int drm_plane_add_size_hints_property(struct drm_plane *plane, const struct drm_plane_size_hint *hints, int num_hints); +int drm_plane_create_color_pipeline_property(struct drm_plane *plane, + const struct drm_prop_enum_list *pipelines, + int num_pipelines); #endif -- cgit v1.2.3 From 179ab8e7d7b378f1cd3ff10113458133b73dc52e Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:36 -0700 Subject: drm/colorop: Introduce DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE With the introduction of the pre-blending color pipeline we can no longer have color operations that don't have a clear position in the color pipeline. We deprecate all existing plane properties. For upstream drivers those are: - COLOR_ENCODING - COLOR_RANGE Drivers are expected to ignore these properties when programming the HW. DRM clients that register with DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE will not be allowed to set the COLOR_ENCODING and COLOR_RANGE properties. Setting of the COLOR_PIPELINE plane property or drm_colorop properties is only allowed for userspace that sets this client cap. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-12-alex.hung@amd.com --- include/drm/drm_file.h | 7 +++++++ include/uapi/drm/drm.h | 15 +++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'include') diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h index 115763799625..1a3018e4a537 100644 --- a/include/drm/drm_file.h +++ b/include/drm/drm_file.h @@ -206,6 +206,13 @@ struct drm_file { */ bool writeback_connectors; + /** + * @plane_color_pipeline: + * + * True if client understands plane color pipelines + */ + bool plane_color_pipeline; + /** * @was_master: * diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 3cd5cf15e3c9..27cc159c1d27 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -906,6 +906,21 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT 6 +/** + * DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE + * + * If set to 1 the DRM core will allow setting the COLOR_PIPELINE + * property on a &drm_plane, as well as drm_colorop properties. + * + * Setting of these plane properties will be rejected when this client + * cap is set: + * - COLOR_ENCODING + * - COLOR_RANGE + * + * The client must enable &DRM_CLIENT_CAP_ATOMIC first. + */ +#define DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE 7 + /* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; -- cgit v1.2.3 From 9cf87f864d8328b06060ce11c4f6d04a12c3047f Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:01:38 -0700 Subject: drm/colorop: Add destroy functions for color pipeline The functions are to clean up color pipeline when a device driver fails to create its color pipeline. Signed-off-by: Alex Hung Reviewed-by: Daniel Stone Reviewed-by: Simon Ser Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-14-alex.hung@amd.com --- include/drm/drm_colorop.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index d8c17c537586..ba03b35454da 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -237,6 +237,9 @@ static inline struct drm_colorop *drm_colorop_find(struct drm_device *dev, return mo ? obj_to_colorop(mo) : NULL; } +void drm_colorop_pipeline_destroy(struct drm_device *dev); +void drm_colorop_cleanup(struct drm_colorop *colorop); + int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, u64 supported_tfs); -- cgit v1.2.3 From e5719e7f19009d4fbedf685fc22eec9cd8de154f Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:43 -0700 Subject: drm/colorop: Add 3x4 CTM type This type is used to support a 3x4 matrix in colorops. A 3x4 matrix uses the last column as a "bias" column. Some HW exposes support for 3x4. The calculation looks like: out matrix in |R| |0 1 2 3 | | R | |G| = |4 5 6 7 | x | G | |B| |8 9 10 11| | B | |1.0| This is also the first colorop where we need a blob property to program the property. For that we'll introduce a new DATA property that can be used by all colorop TYPEs requiring a blob. The way a DATA blob is read depends on the TYPE of the colorop. We only create the DATA property for property types that need it. Reviewed-by: Simon Ser Reviewed-by: Louis Chauvet Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-19-alex.hung@amd.com --- include/drm/drm_colorop.h | 24 ++++++++++++++++++++++++ include/uapi/drm/amdgpu_drm.h | 9 --------- include/uapi/drm/drm_mode.h | 32 +++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index ba03b35454da..8b5f8aaac2f4 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -97,6 +97,17 @@ struct drm_colorop_state { */ enum drm_colorop_curve_1d_type curve_1d_type; + /** + * @data: + * + * Data blob for any TYPE that requires such a blob. The + * interpretation of the blob is TYPE-specific. + * + * See the &drm_colorop_type documentation for how blob is laid + * out. + */ + struct drm_property_blob *data; + /** @state: backpointer to global drm_atomic_state */ struct drm_atomic_state *state; }; @@ -206,6 +217,17 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** + * @data_property: + * + * blob property for any TYPE that requires a blob of data, + * such as 1DLUT, CTM, 3DLUT, etc. + * + * The way this blob is interpreted depends on the TYPE of + * this + */ + struct drm_property *data_property; + /** * @next_property: * @@ -242,6 +264,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, u64 supported_tfs); +int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane); struct drm_colorop_state * drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 406a42be429b..f80aa4c9d88f 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1656,15 +1656,6 @@ struct drm_amdgpu_info_uq_metadata { #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ -/* FIXME wrong namespace! */ -struct drm_color_ctm_3x4 { - /* - * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude - * (not two's complement!) format. - */ - __u64 matrix[12]; -}; - #if defined(__cplusplus) } #endif diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index c419f93eb94d..054561022953 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -847,6 +847,20 @@ struct drm_color_ctm { __u64 matrix[9]; }; +struct drm_color_ctm_3x4 { + /* + * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude + * (not two's complement!) format. + * + * out matrix in + * |R| |0 1 2 3 | | R | + * |G| = |4 5 6 7 | x | G | + * |B| |8 9 10 11| | B | + * |1.0| + */ + __u64 matrix[12]; +}; + struct drm_color_lut { /* * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and @@ -874,7 +888,23 @@ enum drm_colorop_type { * A 1D curve that is being applied to all color channels. The * curve is specified via the CURVE_1D_TYPE colorop property. */ - DRM_COLOROP_1D_CURVE + DRM_COLOROP_1D_CURVE, + + /** + * @DRM_COLOROP_CTM_3X4: + * + * enum string "3x4 Matrix" + * + * A 3x4 matrix. Its values are specified via the + * &drm_color_ctm_3x4 struct provided via the DATA property. + * + * The DATA blob is a float[12]: + * out matrix in + * | R | | 0 1 2 3 | | R | + * | G | = | 4 5 6 7 | x | G | + * | B | | 8 9 10 12 | | B | + */ + DRM_COLOROP_CTM_3X4, }; /** -- cgit v1.2.3 From dabeebae4ab7b4372e17310aa7a2168d32268833 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:48 -0700 Subject: drm/colorop: pass plane_color_pipeline client cap to atomic check Drivers will need to know whether an atomic check/commit originated from a client with DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE so they can ignore deprecated properties, like COLOR_ENCODING and COLOR_RANGE. Pass the plane_color_pipeline bit to drm_atomic_state. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-24-alex.hung@amd.com --- include/drm/drm_atomic.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index faeb5de74d50..e65ea288cb8b 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -537,6 +537,24 @@ struct drm_atomic_state { */ bool checked : 1; + /** + * @plane_color_pipeline: + * + * Indicates whether this atomic state originated with a client that + * set the DRM_CLIENT_CAP_PLANE_COLOR_PIPELINE. + * + * Drivers and helper functions should use this to ignore legacy + * properties that are incompatible with the drm_plane COLOR_PIPELINE + * behavior, such as: + * + * - COLOR_RANGE + * - COLOR_ENCODING + * + * or any other driver-specific properties that might affect pixel + * values. + */ + bool plane_color_pipeline : 1; + /** * @colorops: * -- cgit v1.2.3 From e341cc6e85df7ab413471f8c1a3a10f076b2dfcc Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:01:49 -0700 Subject: drm/colorop: define a new macro for_each_new_colorop_in_state Create a new macro for_each_new_colorop_in_state to access new drm_colorop_state updated from uapi. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-25-alex.hung@amd.com --- include/drm/drm_atomic.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include') diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index e65ea288cb8b..43783891d359 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -1089,6 +1089,26 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p); (old_colorop_state) = (__state)->colorops[__i].old_state,\ (new_colorop_state) = (__state)->colorops[__i].new_state, 1)) +/** + * for_each_new_colorop_in_state - iterate over all colorops in an atomic update + * @__state: &struct drm_atomic_state pointer + * @colorop: &struct drm_colorop iteration cursor + * @new_colorop_state: &struct drm_colorop_state iteration cursor for the new state + * @__i: int iteration cursor, for macro-internal use + * + * This iterates over all colorops in an atomic update, tracking new state. This is + * useful in places where the state delta needs to be considered, for example in + * atomic check functions. + */ +#define for_each_new_colorop_in_state(__state, colorop, new_colorop_state, __i) \ + for ((__i) = 0; \ + (__i) < (__state)->dev->mode_config.num_colorop; \ + (__i)++) \ + for_each_if ((__state)->colorops[__i].ptr && \ + ((colorop) = (__state)->colorops[__i].ptr, \ + (void)(colorop) /* Only to avoid unused-but-set-variable warning */, \ + (new_colorop_state) = (__state)->colorops[__i].new_state, 1)) + /** * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update * @__state: &struct drm_atomic_state pointer -- cgit v1.2.3 From 1b75447412d6e29948c9b687a60352748945c917 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:56 -0700 Subject: drm/colorop: Add PQ 125 EOTF and its inverse The PQ function defines a mapping of code values to nits (cd/m^2). The max code value maps to 10,000 nits. Windows DWM's canonical composition color space (CCCS) defaults to composing SDR contents to 80 nits and uses a float value of 1.0 to represent this. For this reason AMD HW hard-codes a PQ function that is scaled by 125, yielding 80 nit PQ values for 1.0 and 10,000 nits at 125.0. This patch introduces this scaled PQ EOTF and its inverse as 1D curve types. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-32-alex.hung@amd.com --- include/drm/drm_colorop.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 8b5f8aaac2f4..139c9cb38b67 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -58,6 +58,30 @@ enum drm_colorop_curve_1d_type { */ DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF, + /** + * @DRM_COLOROP_1D_CURVE_PQ_125_EOTF: + * + * enum string "PQ 125 EOTF" + * + * The PQ transfer function, scaled by 125.0f, so that 10,000 + * nits correspond to 125.0f. + * + * Transfer characteristics of the PQ function as defined by + * SMPTE ST 2084 (2014) for 10-, 12-, 14-, and 16-bit systems + * and Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system, + * represented by H.273 TransferCharacteristics code point 16. + */ + DRM_COLOROP_1D_CURVE_PQ_125_EOTF, + + /** + * @DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF: + * + * enum string "PQ 125 Inverse EOTF" + * + * The inverse of DRM_COLOROP_1D_CURVE_PQ_125_EOTF. + */ + DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF, + /** * @DRM_COLOROP_1D_CURVE_COUNT: * -- cgit v1.2.3 From a355b3d6a46e42b05fafa587cebe76039ed388c6 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:01:58 -0700 Subject: drm/colorop: add BT2020/BT709 OETF and Inverse OETF The BT.709 and BT.2020 OETFs are the same, the only difference being that the BT.2020 variant is defined with more precision for 10 and 12-bit per color encodings. Both are used as encoding functions for video content, and are therefore defined as OETF (opto-electronic transfer function) instead of as EOTF (electro-optical transfer function). Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Simon Ser Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-34-alex.hung@amd.com --- include/drm/drm_colorop.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 139c9cb38b67..067805276b15 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -82,6 +82,29 @@ enum drm_colorop_curve_1d_type { */ DRM_COLOROP_1D_CURVE_PQ_125_INV_EOTF, + /** + * @DRM_COLOROP_1D_CURVE_BT2020_INV_OETF: + * + * enum string "BT.2020 Inverse OETF" + * + * The inverse of &DRM_COLOROP_1D_CURVE_BT2020_OETF + */ + DRM_COLOROP_1D_CURVE_BT2020_INV_OETF, + + /** + * @DRM_COLOROP_1D_CURVE_BT2020_OETF: + * + * enum string "BT.2020 OETF" + * + * The BT.2020/BT.709 transfer function. The BT.709 and BT.2020 + * transfer functions are the same, the only difference is that + * BT.2020 is defined with more precision for 10 and 12-bit + * encodings. + * + * + */ + DRM_COLOROP_1D_CURVE_BT2020_OETF, + /** * @DRM_COLOROP_1D_CURVE_COUNT: * -- cgit v1.2.3 From 621c45ca12ed9bd5a8ef434925fe51c319c6e28d Mon Sep 17 00:00:00 2001 From: Uma Shankar Date: Fri, 14 Nov 2025 17:02:00 -0700 Subject: drm: Add Enhanced LUT precision structure Existing LUT precision structure drm_color_lut has only 16 bit precision. This is not enough for upcoming enhanced hardwares and advance usecases like HDR processing. Hence added a new structure with 32 bit precision values. Signed-off-by: Alex Hung Signed-off-by: Uma Shankar Signed-off-by: Chaitanya Kumar Borah Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-36-alex.hung@amd.com --- include/drm/drm_color_mgmt.h | 13 +++++++++++++ include/uapi/drm/drm_mode.h | 12 ++++++++++++ 2 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index eccb71ab335a..527582c20885 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -72,6 +72,18 @@ static inline int drm_color_lut_size(const struct drm_property_blob *blob) return blob->length / sizeof(struct drm_color_lut); } +/** + * drm_color_lut32_size - calculate the number of entries in the extended LUT + * @blob: blob containing the LUT + * + * Returns: + * The number of entries in the color LUT stored in @blob. + */ +static inline int drm_color_lut32_size(const struct drm_property_blob *blob) +{ + return blob->length / sizeof(struct drm_color_lut32); +} + enum drm_color_encoding { DRM_COLOR_YCBCR_BT601, DRM_COLOR_YCBCR_BT709, @@ -146,4 +158,5 @@ void drm_crtc_load_palette_8(struct drm_crtc *crtc, const struct drm_color_lut * void drm_crtc_fill_palette_332(struct drm_crtc *crtc, drm_crtc_set_lut_func set_palette); void drm_crtc_fill_palette_8(struct drm_crtc *crtc, drm_crtc_set_lut_func set_palette); +int drm_color_lut32_check(const struct drm_property_blob *lut, u32 tests); #endif diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 054561022953..5e637ec7b64c 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -872,6 +872,18 @@ struct drm_color_lut { __u16 reserved; }; +/* + * struct drm_color_lut32 + * + * 32-bit per channel color LUT entry, similar to drm_color_lut. + */ +struct drm_color_lut32 { + __u32 red; + __u32 green; + __u32 blue; + __u32 reserved; +}; + /** * enum drm_colorop_type - Type of color operation * -- cgit v1.2.3 From 94529775135c301efff78373310102f47f3c8671 Mon Sep 17 00:00:00 2001 From: Chaitanya Kumar Borah Date: Fri, 14 Nov 2025 17:02:01 -0700 Subject: drm: Add helper to extract lut from struct drm_color_lut32 Add helper to extract lut values in 32-bit precision needed by hardware. Signed-off-by: Alex Hung Signed-off-by: Uma Shankar Signed-off-by: Chaitanya Kumar Borah Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-37-alex.hung@amd.com --- include/drm/drm_color_mgmt.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 527582c20885..5140691f476a 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -50,6 +50,22 @@ static inline u32 drm_color_lut_extract(u32 user_input, int bit_precision) (1 << 16) - 1); } +/** + * drm_color_lut32_extract - clamp and round LUT entries + * @user_input: input value + * @bit_precision: number of bits the hw LUT supports + * + * Extract U0.bit_precision from a U0.32 LUT value. + * + */ +static inline u32 drm_color_lut32_extract(u32 user_input, int bit_precision) +{ + u64 max = (bit_precision >= 64) ? ~0ULL : (1ULL << bit_precision) - 1; + + return DIV_ROUND_CLOSEST_ULL((u64)user_input * max, + (1ULL << 32) - 1); +} + u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n); void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, -- cgit v1.2.3 From 99a4e4f08abe253a7812e4872882a75cecd87703 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:02:02 -0700 Subject: drm/colorop: Add 1D Curve Custom LUT type We've previously introduced DRM_COLOROP_1D_CURVE for pre-defined 1D curves. But we also have HW that supports custom curves and userspace needs the ability to pass custom curves, aka LUTs. This patch introduces a new colorop type, called DRM_COLOROP_1D_LUT that provides a SIZE property which is used by a driver to advertise the supported SIZE of the LUT, as well as a DATA property which userspace uses to set the LUT. DATA and size function in the same way as current drm_crtc GAMMA and DEGAMMA LUTs. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Co-developed-by: Harry Wentland Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-38-alex.hung@amd.com --- include/drm/drm_colorop.h | 16 ++++++++++++++++ include/uapi/drm/drm_mode.h | 14 ++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 067805276b15..529af9f8266d 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -257,6 +257,13 @@ struct drm_colorop { */ struct drm_property *bypass_property; + /** + * @size: + * + * Number of entries of the custom LUT. This should be read-only. + */ + uint32_t size; + /** * @curve_1d_type_property: * @@ -264,6 +271,13 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** + * @size_property: + * + * Size property for custom LUT from userspace. + */ + struct drm_property *size_property; + /** * @data_property: * @@ -311,6 +325,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, u64 supported_tfs); +int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane, uint32_t lut_size); int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 5e637ec7b64c..bec524e2fa32 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -902,6 +902,20 @@ enum drm_colorop_type { */ DRM_COLOROP_1D_CURVE, + /** + * @DRM_COLOROP_1D_LUT: + * + * enum string "1D LUT" + * + * A simple 1D LUT of uniformly spaced &drm_color_lut32 entries, + * packed into a blob via the DATA property. The driver's + * expected LUT size is advertised via the SIZE property. + * + * The DATA blob is an array of struct drm_color_lut32 with size + * of "size". + */ + DRM_COLOROP_1D_LUT, + /** * @DRM_COLOROP_CTM_3X4: * -- cgit v1.2.3 From 3410108037d5b01fb35d2e4e92c17c3abdf89186 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:02:05 -0700 Subject: drm/colorop: Add multiplier type This introduces a new drm_colorop_type: DRM_COLOROP_MULTIPLIER. It's a simple multiplier to all pixel values. The value is specified via a S31.32 fixed point provided via the "MULTIPLIER" property. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-41-alex.hung@amd.com --- include/drm/drm_colorop.h | 16 ++++++++++++++++ include/uapi/drm/drm_mode.h | 11 +++++++++++ 2 files changed, 27 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 529af9f8266d..a4f6a22fa1f9 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -144,6 +144,13 @@ struct drm_colorop_state { */ enum drm_colorop_curve_1d_type curve_1d_type; + /** + * @multiplier: + * + * Multiplier to 'gain' the plane. Format is S31.32 sign-magnitude. + */ + uint64_t multiplier; + /** * @data: * @@ -271,6 +278,13 @@ struct drm_colorop { */ struct drm_property *curve_1d_type_property; + /** + * @multiplier_property: + * + * Multiplier property for plane gain + */ + struct drm_property *multiplier_property; + /** * @size_property: * @@ -329,6 +343,8 @@ int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_color struct drm_plane *plane, uint32_t lut_size); int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane); +int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane); struct drm_colorop_state * drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index bec524e2fa32..cac25c0ca37b 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -931,6 +931,17 @@ enum drm_colorop_type { * | B | | 8 9 10 12 | | B | */ DRM_COLOROP_CTM_3X4, + + /** + * @DRM_COLOROP_MULTIPLIER: + * + * enum string "Multiplier" + * + * A simple multiplier, applied to all color values. The + * multiplier is specified as a S31.32 via the MULTIPLIER + * property. + */ + DRM_COLOROP_MULTIPLIER, }; /** -- cgit v1.2.3 From 7fa3ee8c0a79b7a8b5fae422ca29da2fde6821ba Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:02:08 -0700 Subject: drm/colorop: Define LUT_1D interpolation We want to make sure userspace is aware of the 1D LUT interpolation. While linear interpolation is common it might not be supported on all HW. Give driver implementers a way to specify their interpolation. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-44-alex.hung@amd.com --- include/drm/drm_colorop.h | 21 ++++++++++++++++++++- include/uapi/drm/drm_mode.h | 13 +++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index a4f6a22fa1f9..0e1a5e9d26f3 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -271,6 +271,21 @@ struct drm_colorop { */ uint32_t size; + /** + * @lut1d_interpolation: + * + * Read-only + * Interpolation for DRM_COLOROP_1D_LUT + */ + enum drm_colorop_lut1d_interpolation_type lut1d_interpolation; + + /** + * @lut1d_interpolation_property: + * + * Read-only property for DRM_COLOROP_1D_LUT interpolation + */ + struct drm_property *lut1d_interpolation_property; + /** * @curve_1d_type_property: * @@ -340,7 +355,8 @@ void drm_colorop_cleanup(struct drm_colorop *colorop); int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, u64 supported_tfs); int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane, uint32_t lut_size); + struct drm_plane *plane, uint32_t lut_size, + enum drm_colorop_lut1d_interpolation_type interpolation); int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane); int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, @@ -394,6 +410,9 @@ const char *drm_get_colorop_type_name(enum drm_colorop_type type); */ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type type); +const char * +drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type); + void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); #endif /* __DRM_COLOROP_H__ */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index cac25c0ca37b..4b38da880fc7 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -944,6 +944,19 @@ enum drm_colorop_type { DRM_COLOROP_MULTIPLIER, }; +/** + * enum drm_colorop_lut1d_interpolation_type - type of interpolation for 1D LUTs + */ +enum drm_colorop_lut1d_interpolation_type { + /** + * @DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR: + * + * Linear interpolation. Values between points of the LUT will be + * linearly interpolated. + */ + DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, +}; + /** * struct drm_plane_size_hint - Plane size hints * @width: The width of the plane in pixel -- cgit v1.2.3 From 2468963482d844f0657a52f791f15ceb953e5880 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Fri, 14 Nov 2025 17:02:09 -0700 Subject: drm/colorop: allow non-bypass colorops Not all HW will be able to do bypass on all color operations. Introduce an 32 bits 'flags' for all colorop init functions and DRM_COLOROP_FLAG_ALLOW_BYPASS for creating the BYPASS property when it's true. Signed-off-by: Alex Hung Signed-off-by: Harry Wentland Reviewed-by: Daniel Stone Reviewed-by: Simon Ser Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-45-alex.hung@amd.com --- include/drm/drm_colorop.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 0e1a5e9d26f3..828888861ad9 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -31,6 +31,9 @@ #include #include +/* DRM colorop flags */ +#define DRM_COLOROP_FLAG_ALLOW_BYPASS (1<<0) /* Allow bypass on the drm_colorop */ + /** * enum drm_colorop_curve_1d_type - type of 1D curve * @@ -256,11 +259,12 @@ struct drm_colorop { * @bypass_property: * * Boolean property to control enablement of the color - * operation. Setting bypass to "true" shall always be supported - * in order to allow compositors to quickly fall back to - * alternate methods of color processing. This is important - * since setting color operations can fail due to unique - * HW constraints. + * operation. Only present if DRM_COLOROP_FLAG_ALLOW_BYPASS + * flag is set. When present, setting bypass to "true" shall + * always be supported to allow compositors to quickly fall + * back to alternate methods of color processing. This is + * important since setting color operations can fail due to + * unique HW constraints. */ struct drm_property *bypass_property; @@ -353,14 +357,15 @@ void drm_colorop_pipeline_destroy(struct drm_device *dev); void drm_colorop_cleanup(struct drm_colorop *colorop); int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane, u64 supported_tfs); + struct drm_plane *plane, u64 supported_tfs, uint32_t flags); int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, uint32_t lut_size, - enum drm_colorop_lut1d_interpolation_type interpolation); + enum drm_colorop_lut1d_interpolation_type interpolation, + uint32_t flags); int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane); + struct drm_plane *plane, uint32_t flags); int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, - struct drm_plane *plane); + struct drm_plane *plane, uint32_t flags); struct drm_colorop_state * drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); -- cgit v1.2.3 From db971856bbe0263d0ba78d641ea66d4fcdfc8fc3 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:02:10 -0700 Subject: drm/colorop: Add 3D LUT support to color pipeline It is to be used to enable HDR by allowing userpace to create and pass 3D LUTs to kernel and hardware. new drm_colorop_type: DRM_COLOROP_3D_LUT. Reviewed-by: Simon Ser Signed-off-by: Alex Hung Reviewed-by: Daniel Stone Reviewed-by: Melissa Wen Reviewed-by: Sebastian Wick Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-46-alex.hung@amd.com --- include/drm/drm_colorop.h | 23 +++++++++++++++++++++++ include/uapi/drm/drm_mode.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 828888861ad9..9773e30e15ae 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -283,6 +283,14 @@ struct drm_colorop { */ enum drm_colorop_lut1d_interpolation_type lut1d_interpolation; + /** + * @lut3d_interpolation: + * + * Read-only + * Interpolation for DRM_COLOROP_3D_LUT + */ + enum drm_colorop_lut3d_interpolation_type lut3d_interpolation; + /** * @lut1d_interpolation_property: * @@ -311,6 +319,13 @@ struct drm_colorop { */ struct drm_property *size_property; + /** + * @lut3d_interpolation_property: + * + * Read-only property for DRM_COLOROP_3D_LUT interpolation + */ + struct drm_property *lut3d_interpolation_property; + /** * @data_property: * @@ -366,6 +381,11 @@ int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *c struct drm_plane *plane, uint32_t flags); int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop, struct drm_plane *plane, uint32_t flags); +int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop, + struct drm_plane *plane, + uint32_t lut_size, + enum drm_colorop_lut3d_interpolation_type interpolation, + uint32_t flags); struct drm_colorop_state * drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop); @@ -418,6 +438,9 @@ const char *drm_get_colorop_curve_1d_type_name(enum drm_colorop_curve_1d_type ty const char * drm_get_colorop_lut1d_interpolation_name(enum drm_colorop_lut1d_interpolation_type type); +const char * +drm_get_colorop_lut3d_interpolation_name(enum drm_colorop_lut3d_interpolation_type type); + void drm_colorop_set_next_property(struct drm_colorop *colorop, struct drm_colorop *next); #endif /* __DRM_COLOROP_H__ */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 4b38da880fc7..cbbbfc1dfe2b 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -942,6 +942,40 @@ enum drm_colorop_type { * property. */ DRM_COLOROP_MULTIPLIER, + + /** + * @DRM_COLOROP_3D_LUT: + * + * enum string "3D LUT" + * + * A 3D LUT of &drm_color_lut32 entries, + * packed into a blob via the DATA property. The driver's expected + * LUT size is advertised via the SIZE property, i.e., a 3D LUT with + * 17x17x17 entries will have SIZE set to 17. + * + * The DATA blob is a 3D array of struct drm_color_lut32 with dimension + * length of "size". + * The LUT elements are traversed like so: + * + * for B in range 0..n + * for G in range 0..n + * for R in range 0..n + * index = R + n * (G + n * B) + * color = lut3d[index] + */ + DRM_COLOROP_3D_LUT, +}; + +/** + * enum drm_colorop_lut3d_interpolation_type - type of 3DLUT interpolation + */ +enum drm_colorop_lut3d_interpolation_type { + /** + * @DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL: + * + * Tetrahedral 3DLUT interpolation + */ + DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, }; /** -- cgit v1.2.3 From 8e304a45116a567a33cfbd9f104356622c6aefbc Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Fri, 14 Nov 2025 17:02:15 -0700 Subject: drm/colorop: Add DRM_COLOROP_1D_CURVE_GAMMA22 to 1D Curve Add "DRM_COLOROP_1D_CURVE_GAMMA22" and DRM_COLOROP_1D_CURVE_GAMMA22_INV subtypes to drm_colorop of DRM_COLOROP_1D_CURVE. Reviewed-by: Harry Wentland Signed-off-by: Alex Hung Signed-off-by: Simon Ser Link: https://patch.msgid.link/20251115000237.3561250-51-alex.hung@amd.com --- include/drm/drm_colorop.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h index 9773e30e15ae..a3a32f9f918c 100644 --- a/include/drm/drm_colorop.h +++ b/include/drm/drm_colorop.h @@ -108,6 +108,24 @@ enum drm_colorop_curve_1d_type { */ DRM_COLOROP_1D_CURVE_BT2020_OETF, + /** + * @DRM_COLOROP_1D_CURVE_GAMMA22: + * + * enum string "Gamma 2.2" + * + * A gamma 2.2 power function. This applies a power curve with + * gamma value of 2.2 to the input values. + */ + DRM_COLOROP_1D_CURVE_GAMMA22, + + /** + * @DRM_COLOROP_1D_CURVE_GAMMA22_INV: + * + * enum string "Gamma 2.2 Inverse" + * + * The inverse of &DRM_COLOROP_1D_CURVE_GAMMA22 + */ + DRM_COLOROP_1D_CURVE_GAMMA22_INV, /** * @DRM_COLOROP_1D_CURVE_COUNT: * -- cgit v1.2.3