Commit Graph

1482481 Commits

Author SHA1 Message Date
Thomas Zimmermann
efb67f52fb drm/panic: Compile KUnit tests as module
Fix dependency of the panic-helper KUnit tests on CONFIG_DRM_KUNIT_TEST=y
and make them build as a module. Export the necessary interfaces from the
panic helpers iff the KUnit framework has been enabled.

Select DRM_PANIC_HELPER from DRM_KUNIT_TEST to meet the dependencies of
the panic-helper tests.

It is now possible to run the tests by modprobe-ing drm_panic_helper_test
at runtime.

v5:
- clear test description with drm_panic_helper_clear_description() (Sashiko)
v3:
- clean up after each test case (Sashiko)
v2:
- fix parameter order in decl of drm_panic_helper_draw_screen_qr()
  (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-15-tzimmermann@suse.de
2026-09-17 09:16:41 +02:00
Thomas Zimmermann
5c3d323984 drm/panic: Move panic display code into helper library
Move drm_plane_helper_display_panic_screen() and the existing panic-
display code into drm_panic_helper.c. Rename symbols accordingly.
Also update the QR-related code and the bindings accordingly.

Link the rsp. object file into drm_kms_helper.ko. Eventually the code
will become a DRM drawing library, together with DRM's format and draw
helpers. This requires more preparation. until then, KMS helpers serve
as a module. All DRM drivers link it anyway.

Add a new section about drawing helpers to the documentation of the KMS
helpers. List format and panic helpers there.

v2:
- fix dependencies on other DRM modules (Randy, Sashiko)
- provide placeholders for drm_panic_helper_{init,exit}() (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-14-tzimmermann@suse.de
2026-09-17 09:16:36 +02:00
Thomas Zimmermann
3ae80dc240 drm/panic: Internalize panic locking in DRM core and helpers
None of the DRM drivers handles panic locking. Declare the interfaces
in an internal header file. Move the trylock required during the panic
into the DRM core's sources.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-13-tzimmermann@suse.de
2026-09-17 09:16:35 +02:00
Thomas Zimmermann
b8bc58515a drm/panic: Display panic screen via per-plane callback
Add display_panic_screen to struct drm_plane_funcs. If set on a plane,
register a panic handler for the plane from the DRM core's panic
handling. Invoke this helper from the core to display a panic screen.

The new callback replaces get_scanout_buffer as signal for panic
support in a plane. Using get_scanout_buffer is now merely a detail
of the implementation. This will also free struct drm_scanout_buffer
for use cases besides panic handling.

With display_panic_screen in place, rename draw_panic_plane() to
drm_plane_helper_display_panic_screen() and make it available to DRM
drivers via drm_panic_helper.h. Do not change the implementation or
functionality of this code. drm_plane_helper_display_panic_screen()
still supports kernel messages, user messages and QR codes on various
color formats.

Then update all drivers that implement panic support. Provide the
initializer macro DRM_PANIC_PLANE_FUNCS that sets display_panic_screen
to drm_plane_helper_display_panic_screen(). If panic handling has
been disabled, it instead clears the callback. There's again no change
in functionality.

This logically splits panic handling into a set of entry points in the
DRM code and a set of helper functions provided by drivers. The core
invokes the driver's helper via callback, while the driver can tailor
the implementation to its needs. Panic handling now works like most
other interfaces in the DRM framework.

Locking and state-handling happens in the DRM core or helpers. Drivers
that receive a call to display_panic_screen can assume that no concurrent
modeset takes place on the plane or its CRTC.

Also update the documentation. Move information about locking and state
guarantees from drm_panic_trylock() to display_panic_screen, where
drivers authors can find it easily. Move information about the features
of the current implementation to drm_panic_helper_display_panic_screen().

v4:
- remove obsolete comment about fbcon interference (Jocelyn)
v2:
- only consider planes with get_scanout_buffer (Sashiko)
- set callback for planes create with drm_crtc_init() (Sashiko)
- return errno code from display_panic_screen

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-12-tzimmermann@suse.de
2026-09-17 09:16:31 +02:00
Thomas Zimmermann
c442e5afc4 drm/panic: Restrict to primary planes
Restrict panic handling to primary displays. Overlays and cursors
should not display panic output. If there are exceptions, they can
be registered by the driver itself.

v3:
- also update drm_panic_is_enabled() (Sashiko)
- still do some testing when unregistering (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-11-tzimmermann@suse.de
2026-09-17 09:16:31 +02:00
Thomas Zimmermann
c2dd7240f5 drm/panic: Split draw_panic_plane()
Move locking and parameters from draw_panic_plane() into the new
helper drm_panic_display_panic_screen(). Call draw_panic_plane() from
there.

The new helper drm_panic_display_panic_screen() is now the DRM core's
interface for displaying a panic screen. The code remaining in
draw_panic_plane() still does all the heavy lifting. It will become a
plane helper for DRM drivers.

v2:
- use panic_type argument in draw_panic_plane() (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-10-tzimmermann@suse.de
2026-09-17 09:16:30 +02:00
Thomas Zimmermann
2384981e42 drm/panic: Retry in dispatch function if panic output fails
On failed output of QR codes and kmsg buffers, fall back to a user
message. QR-code output already did this internally, but now formally
support it in drm_panic_dispatch(). Streamlines the existing logic.

With the implicit fallback removed from QR-code support, the tests
cases fail for thr smallest output size (300x200). This is because the
QR code requires a minimal output size. Increase the size to 494x494,
which is the minimum supported size for QR output.

v3:
- update outdated commit description (Sashiko)
v2:
- fix minimum test size (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-9-tzimmermann@suse.de
2026-09-17 09:16:29 +02:00
Thomas Zimmermann
fbe42fd8cf drm/panic: Return from screen_user if display is too small
Return an error if the display is too small to display at least a
single character. If the panic handler cannot display any message
it does at least not destroy the current output, which might help
with identifying the problem.

v4:
- also check font height against scanout buffer (Jocelyn)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-8-tzimmermann@suse.de
2026-09-17 09:16:29 +02:00
Thomas Zimmermann
f57d778a7a drm/panic: Pass global module parameters to drm_panic_dispatch()
Set the panic type and QR version in draw_panic_plane() as a single
point of truth. Pass the values into the individual drawing functions.

In the test case, always create a QR code with version 40 (i.e., the
highest supported version).

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-7-tzimmermann@suse.de
2026-09-17 09:16:28 +02:00
Thomas Zimmermann
0a8af1f7f9 drm/panic: Pass colors to draw_panic_dispatch()
Set the panic-screen colors in draw_panic_plane() as a single point
of truth. Pass the values into the individual drawing functions.

In the test cases, replace the Kconfig-defined colors with white and
black. Allows for removal of the tests' limitations and dependency on
the exact values. All tests now always verify the generated output.

Hardcoding the test colors will later also allow for building the
test case without having DRM panic handling enabled.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-6-tzimmermann@suse.de
2026-09-17 09:16:28 +02:00
Thomas Zimmermann
36c9735057 drm/panic: Return errno codes if panic output fails
Return errno codes from the panic output helpers to detect invalid
panic handling. Avoid flushing the display if an error ocured. The
unflushed display output might be helpful in debugging.

For now, test the result values in the panic test cases. A later patch
will add support for retrying failed panic output.

v2:
- forward return value of draw_panic_screen_user() (Sashiko)
- forward errno code from drm_panic_get_qr_code

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-5-tzimmermann@suse.de
2026-09-17 09:16:27 +02:00
Thomas Zimmermann
e2b01faedb drm/panic: Return -EINVAL if font is not available
Font lookup does not allocate memory. Hence reporting ENOMEM on
failed lookups is misleading. Report EINVAL instead.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-4-tzimmermann@suse.de
2026-09-17 09:16:26 +02:00
Thomas Zimmermann
6a6304ec3c drm/panic: Test address from kmap op for NULL
Do nothing if kmap_local_page_try_from_panic() returns NULL. This is
not likely to hapen, as the previous page from the same memory area
has been mapped successfully.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 23437509a6 ("drm/panic: Fix 24bit pixel crossing page boundaries")
Cc: Javier Martinez Canillas <javierm@redhat.com>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.18+
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260911124540.279841-3-tzimmermann@suse.de
2026-09-17 09:16:26 +02:00
Thomas Zimmermann
6596aae255 drm/panic: Do not use un-escaped URL as format string
Replace the direct use of DRM_PANIC_SCREEN_QR_CODE_URL in snprintf()
with a %s conversion specifier. Avoids a possible vulnerabilty from
a crafted URL string.

As the attacker needs to control the kernel at the Kconfig level, the
potential for an exploit is likely low.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Fixes: cb5164ac43 ("drm/panic: Add a QR code panic screen")
Cc: Javier Martinez Canillas <javierm@redhat.com>
Cc: Jocelyn Falempe <jfalempe@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.12+
Link: https://patch.msgid.link/20260911124540.279841-2-tzimmermann@suse.de
2026-09-17 09:16:25 +02:00
Maxime Ripard
5589ef09f9
drm/plane: Remove reset
All plane drivers now implement the atomic_create_state hook instead of
the reset hook for initial state creation. The reset hook conflated
initial state allocation at probe time with hardware and software reset
during suspend/resume, making error handling difficult since it is not
fallible.

Remove the reset hook from struct drm_plane_funcs and the associated
call in drm_mode_config_reset().

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-9-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:04 +02:00
Maxime Ripard
18216d5fa8
drm/atomic-state-helper: Remove __drm_atomic_helper_plane_reset()
__drm_atomic_helper_plane_reset() is no longer used: all callers now go
through __drm_atomic_helper_plane_state_init(). Remove it.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-8-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:04 +02:00
Maxime Ripard
e62864df82
drm/atomic-state-helper: Remove drm_atomic_helper_plane_reset()
drm_atomic_helper_plane_reset() is no longer used: all callers now go
through drm_atomic_helper_plane_create_state(). Remove it.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-7-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:03 +02:00
Maxime Ripard
79d498da3e
drm/xen: Switch to drm_atomic_helper_plane_create_state
The xen plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-6-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:03 +02:00
Maxime Ripard
18b4aaafdc
drm/tve200: Switch to drm_atomic_helper_plane_create_state
The tve200 plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-5-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:02 +02:00
Maxime Ripard
896c2267d1
drm/pl111: Switch to drm_atomic_helper_plane_create_state
The pl111 plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-4-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:02 +02:00
Maxime Ripard
d24a400a17
drm/mcde: Switch to drm_atomic_helper_plane_create_state
The mcde plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-3-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:01 +02:00
Maxime Ripard
fbc8f33eeb
drm/aspeed: Switch to drm_atomic_helper_plane_create_state
The aspeed plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-2-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:22:00 +02:00
Maxime Ripard
a88a31a625
drm/arcgpu: Switch to drm_atomic_helper_plane_create_state
The arcgpu plane implementation uses the deprecated
drm_atomic_helper_plane_reset() as its reset hook.

Switch to drm_atomic_helper_plane_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260916-drm-no-more-plane-reset-v5-1-f590d2003f2c@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 17:21:52 +02:00
Luca Ceresoli
acb05c825e drm/tve200: remove unused includes
The drm_panel API is completely unused in this file.

Reviewed-by: Maxime Ripard <mripard@kernel.org>
Link: https://patch.msgid.link/20260903-drm-bridge-every-panel-v2-17-2ab8ee24538e@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
2026-09-16 13:05:45 +02:00
Luca Ceresoli
dd8950786b drm/omap: dsi: remove unused includes
The drm_panel API is completely unused in these two files.

Reviewed-by: Maxime Ripard <mripard@kernel.org>
Link: https://patch.msgid.link/20260903-drm-bridge-every-panel-v2-15-2ab8ee24538e@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
2026-09-16 13:05:45 +02:00
Maxime Ripard
f1bcb90506
drm/crtc: Remove reset
All crtc drivers now implement the atomic_create_state hook instead of
the reset hook for initial state creation. The reset hook conflated
initial state allocation at probe time with hardware and software reset
during suspend/resume, making error handling difficult since it is not
fallible.

Remove the reset hook from struct drm_crtc_funcs and the associated
call in drm_mode_config_reset().

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-11-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:25 +02:00
Maxime Ripard
9ea7393511
drm/atomic-helper: Remove __drm_atomic_helper_crtc_reset
All users of __drm_atomic_helper_crtc_reset() have been converted to use
__drm_atomic_helper_crtc_state_init() and atomic_create_state.

Remove the now unused helper.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-10-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:24 +02:00
Maxime Ripard
5354d1e5fb
drm/atomic-helper: Remove drm_atomic_helper_crtc_reset
All users of drm_atomic_helper_crtc_reset() have been converted to
drm_atomic_helper_crtc_create_state().

Remove the now unused helper.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-9-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:23 +02:00
Maxime Ripard
c4967fd8b4
drm/xen: Switch to drm_atomic_helper_crtc_create_state
The xen crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-8-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:23 +02:00
Maxime Ripard
bfcf0fec17
drm/tve200: Switch to drm_atomic_helper_crtc_create_state
The tve200 crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-7-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:22 +02:00
Maxime Ripard
0d3b9d5604
drm/repaper: Switch to drm_atomic_helper_crtc_create_state
The repaper crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-6-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:22 +02:00
Maxime Ripard
f14ba2463a
drm/pl111: Switch to drm_atomic_helper_crtc_create_state
The pl111 crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-5-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:24:21 +02:00
Maxime Ripard
d7f9bde13c
drm/mcde: Switch to drm_atomic_helper_crtc_create_state
The mcde crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-4-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:23:37 +02:00
Maxime Ripard
85be9cba55
drm/gm12u320: Switch to drm_atomic_helper_crtc_create_state
The tilcdc crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-3-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:23:36 +02:00
Maxime Ripard
0e82728b3f
drm/aspeed: Switch to drm_atomic_helper_crtc_create_state
The aspeed crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-2-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:23:35 +02:00
Maxime Ripard
36323b4a23
drm/arcgpu: Switch to drm_atomic_helper_crtc_create_state
The arcgpu crtc implementation uses the deprecated
drm_atomic_helper_crtc_reset() as its reset hook.

Switch to drm_atomic_helper_crtc_create_state() instead.

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260915-drm-no-more-crtc-reset-v5-1-bda007735748@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-16 09:23:35 +02:00
Chaoyi Chen
5363e01e4f drm/rockchip: dsi: Add dphy_get_timing support for multiple PHY types
Currently, there are generally two types of DPHY for Rockchip. One is
the DPHY used by RK3288/RK3399, whose timing is described by Table A-3
High-Speed Transition Times in the databook. The other is the DPHY used
by PX30 and its successors. If its timing is still described using
RK3288/RK3399, it may not perform correctly on some DSI panel.

Add dphy_get_timing for different D-PHY types to adapt to timing
differences. The configuration details are as follows:

- RK3288/RK3399: Select the corresponding entry from the timing table based
                 on the data rate.
- PX30 and later platforms: Use a fixed timing configuration.

Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260914013331.108-3-kernel@airkyi.com
2026-09-15 18:35:08 +02:00
Chaoyi Chen
3c58af0595 drm/rockchip: dsi: Add maximum per lane bit rate calculation
Different chips have varying support for the maximum bit rate per lane.

Add calculation for the maximum per lane bit rate for various chip
platforms.

Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260914013331.108-2-kernel@airkyi.com
2026-09-15 18:35:08 +02:00
Alessio Belle
109f4e9010 drm/imagination: Avoid initialisation of unused FW trace buffer pointer
This pointer, which is part of struct rogue_fwif_tracebuf_space (a FW
interface structure), was initialised but never used to access the FW
trace buffer - only the source pointer in the initialisation being
removed is used.

Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
Link: https://patch.msgid.link/20260910-b4-avoid-init-of-unused-fw-trace-buffer-pointer-v1-2-7e10274384c2@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:06:07 +01:00
Matt Coster
05cce7f9b6 drm/imagination: Collect KCCB initialisation
There's one FW object attached to KCCB usage (the return buffer) that is
separately initialised in pvr_fw_init(). Move this initialisation to
pvr_kccb_init() alongside the initialisation of rest of the members of
struct pvr_device->kccb.

Signed-off-by: Matt Coster <matt.coster@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260910-b4-avoid-init-of-unused-fw-trace-buffer-pointer-v1-1-7e10274384c2@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:06:07 +01:00
Alessio Belle
6318a8f3cf drm/imagination: Manage FW VM context from its init and fini callbacks
While the MIPS firmware virtual memory context is created and destroyed
from within the MIPS firmware init and fini callbacks, the META and
RISC-V firmware contexts are created and destroyed from within blocks
right before or after those callbacks.

Match the logic for all firmware processors by moving those blocks to
the META and RISC-V init and fini callbacks.

Reviewed-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Link: https://patch.msgid.link/20260915-b4-upstream-manage-fw-vm-context-from-init-and-fini-v2-1-c9cb43667143@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:05:21 +01:00
Alessio Belle
7d56d18131 drm/imagination: Remove duplicated CCB control initialisation
The same is already done by the ccb_ctrl_init() callback.

Reviewed-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Link: https://patch.msgid.link/20260915-b4-upstream-remove-duplicate-ccb-control-init-v2-1-ba0a6ae63a20@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:04:40 +01:00
Matt Coster
8f07803fcf drm/imagination: Move FWCORE_* macros to register defines
Move FWCORE_* macros to pvr_rogue_cr_defs.h where they should have been
from the beginning.

Signed-off-by: Matt Coster <matt.coster@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260810-b4-unify-repeated-reg-defs-and-move-fwcore-macros-v2-2-991ae813fd88@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:01:55 +01:00
Matt Coster
cf43f918de drm/imagination: Unify repeated register defines
Some register definitions are annotated as "Register group: X, with N
repeats". The only difference between all the N copies of those definitions
is the register addresses which can be unified into a BASE/OFFSET pair.

Typical usage patterns of these repeated registers do not involve
hardcoding individual instances, so using any specific defines is
semantically incorrect.

Signed-off-by: Matt Coster <matt.coster@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260810-b4-unify-repeated-reg-defs-and-move-fwcore-macros-v2-1-991ae813fd88@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 16:00:30 +01:00
Matt Coster
bccc174bdf drm/imagination: Explicitly set CACHED flag on META FW
For completeness, OR in the CACHED flags when we're not ORing in the
UNCACHED counterparts. One of these is probably zero, but (a) it isn't
evident just by reading these lines, and (b) the compiler will make it
disappear in that case.

Signed-off-by: Matt Coster <matt.coster@imgtec.com>
Signed-off-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260914-b4-cached-flag-on-meta-fw-v2-1-160b0e4e160f@imgtec.com
Signed-off-by: Alessio Belle <alessio.belle@imgtec.com>
2026-09-15 15:59:31 +01:00
Mika Penttilä
d5c34a3843
drm/tests: hdmi: fix infoframes tests
drm_atomic_commit() calls drm_atomic_check_only() internally. Calling
drm_atomic_check_only() explicitly before the commit leaves the state
marked as checked and triggers drm_WARN_ON(state->checked) when the
commit checks the state again.

Remove the redundant explicit checks.

Fixes: 7436a87db9 ("drm/tests: hdmi: check the infoframes behaviour")
Cc: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Mika Penttilä <mpenttil@redhat.com>
Link: https://patch.msgid.link/20260914040723.2593700-1-mpenttil@redhat.com
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-15 16:13:18 +02:00
Maxime Ripard
87882cd6de
drm/amdgpu_dm: tests: Fix wrong variable declaration after merge conflict
Commit 2bcec01cf1 ("drm/amdgpu_dm: Convert to atomic_create_state")
converted dm_test_plane_create_state_initializes_state() to call
amdgpu_dm_plane_drm_plane_create_state(), which returns a struct
drm_plane_state pointer stored in a new plane_state variable.

However, the merge conflict resolution kept the old declaration
(struct dm_plane_state *old_state) instead of replacing it with
struct drm_plane_state *plane_state, leaving an unused variable with
the wrong type.

Fix the declaration to match what the conversion intended.

Fixes: 2bcec01cf1 ("drm/amdgpu_dm: Convert to atomic_create_state")
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patch.msgid.link/20260915101251.1711103-1-mripard@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-15 16:13:04 +02:00
Maxime Ripard
3a4affc50a
drm/vmwgfx: Convert to atomic_create_state
The plane reset implementation creates a custom state
subclass, but only initializes a pristine state without resetting any
hardware. This is equivalent to what atomic_create_state expects.
Convert to it.

Reviewed-by: Zack Rusin <zack.rusin@broadcom.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260908-drm-no-more-plane-reset-v4-39-a31b3fcfc989@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-15 11:47:03 +02:00
Maxime Ripard
5bdc23522c
drm/sun4i: layer: Convert to atomic_create_state
The plane reset implementation creates a custom state
subclass, but only initializes a pristine state without resetting any
hardware. This is equivalent to what atomic_create_state expects.
Convert to it.

The conversion was done using the following Coccinelle semantic patch:

@@
identifier funcs;
symbol drm_atomic_helper_plane_reset;
symbol drm_atomic_helper_plane_create_state;
@@

struct drm_plane_funcs funcs = {
  ...,
- .reset = drm_atomic_helper_plane_reset,
+ .atomic_create_state = drm_atomic_helper_plane_create_state,
  ...,
};

@match_struct_reset@
identifier funcs, reset_func;
@@
struct drm_plane_funcs funcs = {
    ...,
    .reset = reset_func,
    ...,
};

@reset_uses_helpers depends on match_struct_reset@
identifier match_struct_reset.reset_func;
@@

 void reset_func(...)
 {
 	<+...
(
 	__drm_atomic_helper_plane_reset(...);
|
	__drm_gem_reset_shadow_plane(...);
)
 	...+>
 }

@match_struct_destroy@
identifier funcs, destroy_func;
@@
struct drm_plane_funcs funcs = {
    ...,
    .atomic_destroy_state = destroy_func,
    ...,
};

@script:python renamed_func@
old_name << match_struct_reset.reset_func;
new_name;
@@
if old_name.endswith("_reset"):
    coccinelle.new_name = old_name.replace("_reset", "_create_state")
else:
    coccinelle.new_name = old_name

@update_struct depends on match_struct_reset && reset_uses_helpers@
identifier match_struct_reset.funcs, match_struct_reset.reset_func;
identifier renamed_func.new_name;
@@
struct drm_plane_funcs funcs = {
    ...,
-   .reset = reset_func,
+   .atomic_create_state = new_name,
    ...,
};

@drop_destroy depends on update_struct && match_struct_destroy@
identifier match_struct_reset.reset_func;
identifier match_struct_destroy.destroy_func;
identifier container_func;
identifier P;
symbol drm_atomic_helper_plane_destroy_state;
symbol __drm_atomic_helper_plane_destroy_state;
@@

 void reset_func(struct drm_plane *P)
 {
 	...
(
-	if (P->state) {
- 		<+...
(
-		drm_atomic_helper_plane_destroy_state(P, P->state);
|
-		__drm_atomic_helper_plane_destroy_state(P->state);
|
-		P->funcs->atomic_destroy_state(P, P->state);
|
-		destroy_func(P, P->state);
)
- 		...+>
- 	}
|
-	drm_WARN_ON_ONCE(P->dev, P->state);
|
-	WARN_ON(P->state);
)
 	...
(
-	kfree(P->state);
|
-	kfree(container_func(P->state));
|
 	// kfree is optional
)
(
-	P->state = NULL;
|
 	// plane->state clearing is optional
)
 	...
 }

@drop_destroy_mtk depends on update_struct@
identifier P;
symbol __drm_atomic_helper_plane_destroy_state;
symbol to_mtk_plane_state;
@@

 void mtk_plane_reset(struct drm_plane *P)
 {
 	...
-	if (P->state) {
-		__drm_atomic_helper_plane_destroy_state(P->state);
-		...
-	} else {
 		...
-	}
 	...
 }

@transform_nv50_wndw depends on update_struct@
identifier S;
@@

 void nv50_wndw_reset(...)
 {
 	...
-	if (WARN_ON(!(S = kzalloc_obj(*S))))
+	S = kzalloc_obj(*S);
+	if (WARN_ON(!S))
 		return;
 	...
 }

@transform_kzalloc depends on update_struct@
identifier match_struct_reset.reset_func;
identifier P, S;
statement ST;
statement list STL;
@@

 void reset_func(struct drm_plane *P)
 {
 	<...
 	S = kzalloc_obj(*S);
(
-	if (S)
-	{
-		STL
-	}
+	if (!S) return;
+
+	STL
|
-	if (S) ST
+	if (!S) return;
+
+	ST
)
	...>
 }

@transform_body depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier S, P;
expression PS;
@@
- void reset_func(struct drm_plane *P)
+ struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	S = kzalloc_obj(*S);
	...
(
 	if (!S) {
		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
|
 	if (WARN_ON(!S)) {
		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
|
 	if (S == NULL) {
 		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
)
	...
(
-	__drm_atomic_helper_plane_reset(P, PS);
+	__drm_atomic_helper_plane_state_init(PS, P);
|
-	__drm_gem_reset_shadow_plane(P, PS);
+	__drm_gem_shadow_plane_state_init(P, PS);
)
	...
}

@update_early_return depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	<+...
-	return;
+	return ERR_PTR(-EINVAL);
	...+>
}

@update_return_plane depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	__drm_atomic_helper_plane_state_init(PS, P);
	...
+
+	return PS;
}

@update_return_shadow depends on update_struct@
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	__drm_gem_shadow_plane_state_init(P, PS);
	...
+
+	return &PS->base;
}

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260908-drm-no-more-plane-reset-v4-38-a31b3fcfc989@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-15 11:47:02 +02:00
Maxime Ripard
c2be53c382
drm/shmobile: Convert to atomic_create_state
The plane reset implementation creates a custom state
subclass, but only initializes a pristine state without resetting any
hardware. This is equivalent to what atomic_create_state expects.
Convert to it.

The conversion was done using the following Coccinelle semantic patch:

@@
identifier funcs;
symbol drm_atomic_helper_plane_reset;
symbol drm_atomic_helper_plane_create_state;
@@

struct drm_plane_funcs funcs = {
  ...,
- .reset = drm_atomic_helper_plane_reset,
+ .atomic_create_state = drm_atomic_helper_plane_create_state,
  ...,
};

@match_struct_reset@
identifier funcs, reset_func;
@@
struct drm_plane_funcs funcs = {
    ...,
    .reset = reset_func,
    ...,
};

@reset_uses_helpers depends on match_struct_reset@
identifier match_struct_reset.reset_func;
@@

 void reset_func(...)
 {
 	<+...
(
 	__drm_atomic_helper_plane_reset(...);
|
	__drm_gem_reset_shadow_plane(...);
)
 	...+>
 }

@match_struct_destroy@
identifier funcs, destroy_func;
@@
struct drm_plane_funcs funcs = {
    ...,
    .atomic_destroy_state = destroy_func,
    ...,
};

@script:python renamed_func@
old_name << match_struct_reset.reset_func;
new_name;
@@
if old_name.endswith("_reset"):
    coccinelle.new_name = old_name.replace("_reset", "_create_state")
else:
    coccinelle.new_name = old_name

@update_struct depends on match_struct_reset && reset_uses_helpers@
identifier match_struct_reset.funcs, match_struct_reset.reset_func;
identifier renamed_func.new_name;
@@
struct drm_plane_funcs funcs = {
    ...,
-   .reset = reset_func,
+   .atomic_create_state = new_name,
    ...,
};

@drop_destroy depends on update_struct && match_struct_destroy@
identifier match_struct_reset.reset_func;
identifier match_struct_destroy.destroy_func;
identifier container_func;
identifier P;
symbol drm_atomic_helper_plane_destroy_state;
symbol __drm_atomic_helper_plane_destroy_state;
@@

 void reset_func(struct drm_plane *P)
 {
 	...
(
-	if (P->state) {
- 		<+...
(
-		drm_atomic_helper_plane_destroy_state(P, P->state);
|
-		__drm_atomic_helper_plane_destroy_state(P->state);
|
-		P->funcs->atomic_destroy_state(P, P->state);
|
-		destroy_func(P, P->state);
)
- 		...+>
- 	}
|
-	drm_WARN_ON_ONCE(P->dev, P->state);
|
-	WARN_ON(P->state);
)
 	...
(
-	kfree(P->state);
|
-	kfree(container_func(P->state));
|
 	// kfree is optional
)
(
-	P->state = NULL;
|
 	// plane->state clearing is optional
)
 	...
 }

@drop_destroy_mtk depends on update_struct@
identifier P;
symbol __drm_atomic_helper_plane_destroy_state;
symbol to_mtk_plane_state;
@@

 void mtk_plane_reset(struct drm_plane *P)
 {
 	...
-	if (P->state) {
-		__drm_atomic_helper_plane_destroy_state(P->state);
-		...
-	} else {
 		...
-	}
 	...
 }

@transform_nv50_wndw depends on update_struct@
identifier S;
@@

 void nv50_wndw_reset(...)
 {
 	...
-	if (WARN_ON(!(S = kzalloc_obj(*S))))
+	S = kzalloc_obj(*S);
+	if (WARN_ON(!S))
 		return;
 	...
 }

@transform_kzalloc depends on update_struct@
identifier match_struct_reset.reset_func;
identifier P, S;
statement ST;
statement list STL;
@@

 void reset_func(struct drm_plane *P)
 {
 	<...
 	S = kzalloc_obj(*S);
(
-	if (S)
-	{
-		STL
-	}
+	if (!S) return;
+
+	STL
|
-	if (S) ST
+	if (!S) return;
+
+	ST
)
	...>
 }

@transform_body depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier S, P;
expression PS;
@@
- void reset_func(struct drm_plane *P)
+ struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	S = kzalloc_obj(*S);
	...
(
 	if (!S) {
		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
|
 	if (WARN_ON(!S)) {
		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
|
 	if (S == NULL) {
 		...
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
)
	...
(
-	__drm_atomic_helper_plane_reset(P, PS);
+	__drm_atomic_helper_plane_state_init(PS, P);
|
-	__drm_gem_reset_shadow_plane(P, PS);
+	__drm_gem_shadow_plane_state_init(P, PS);
)
	...
}

@update_early_return depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	<+...
-	return;
+	return ERR_PTR(-EINVAL);
	...+>
}

@update_return_plane depends on update_struct@
identifier match_struct_reset.reset_func;
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	__drm_atomic_helper_plane_state_init(PS, P);
	...
+
+	return PS;
}

@update_return_shadow depends on update_struct@
identifier renamed_func.new_name;
identifier P;
expression PS;
@@
 struct drm_plane_state *new_name(struct drm_plane *P)
{
	...
 	__drm_gem_shadow_plane_state_init(P, PS);
	...
+
+	return &PS->base;
}

Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260908-drm-no-more-plane-reset-v4-37-a31b3fcfc989@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-09-15 11:47:02 +02:00