Hello, this series aims at supporting Linux devices with a DRM pipeline whose final components can be hot-plugged and hot-unplugged, including one or more bridges. Use case and overall description ================================ If you don't know the topic, see cover letter for v5: https://lore.kernel.org/all/20241231-hotplug-drm-bridge-v5-0-173065a1ece1@xxxxxxxxxxx/ Roadmap and current status ========================== Up to v4 the design idea was heavily based on a "hotplug bridge driver" to decouple the two sides of the DRM pipeline. After a long discussion during Linux Plumbers Conference 2024, a different strategy was agreed with other DRM developers, which adds: 1. add refcounting to DRM bridges (struct drm_bridge) 2. handle gracefully atomic updates during bridge removal 3. avoid DSI host drivers to have dangling pointers to DSI devices 4. finish the hotplug bridge work, removing the "always-disconnected" connector, moving code to the core and potentially removing the hotplug-bridge itself (this needs to be clarified as points 1-3 are developed) This version implements the first item but in a way more complete form than in v5. Items 2-4 have not yet been developed. This version is sent to allow discussing the bridge refcounting in its latest and greatest shape. The largest change singe v5 is now we always create a panel_bridge when a drm_panel is added. This wight be not strictly needed, but makes panel_bridge creation and lifetime way more straightforward, thusmakeing the bridge refcounting work a tad more linear. Patch series overview ===================== * 2 Preliminary patches (maybe to be removed as this work progresses): - drm/bridge: allow bridges to be informed about added and removed bridges - drm/encoder: add drm_encoder_cleanup_from() * Implement refcounting in the drm_bridge core: - drm/bridge: add support for refcounted DRM bridges - drm/tests: bridge: add KUnit tests for DRM bridges (init and destroy) - drm/bridge: add documentation of refcounted bridges * Adapt some existing bridges to be refcounted and/or to refcount bridges they take a pointer to: - drm/bridge: ti-sn65dsi83: use dynamic lifetime management - drm/bridge: panel: use dynamic lifetime management - drm/bridge: samsung-dsim: use supporting variable for out_bridge - drm/bridge: samsung-dsim: refcount the out_bridge * Add hotplug-bridge (may be removed as this work progresses): - drm/bridge: hotplug-bridge: add driver to support hot-pluggable DSI bridges * Prelimiary, simple cleanups: - drm/debugfs: fix printk format for bridge index - drm: of: drm_of_find_panel_or_bridge: move misplaced comment - drm/bridge: panel: use drm_bridge_is_panel() instead of open code - drm/bridge: panel: drm_panel_bridge_remove: warn when called on non-panel bridge * debugfs improvements to show bridges, part 1: - drm/debugfs: add top-level 'bridges' file showing all added bridges * Restructure panel code to always add a panel_bridge: - drm/panel: move all code into bridge/panel.c - drm/bridge: panel: forbid initializing a panel with unknown connector type - drm/bridge: panel: add a panel_bridge to every panel - drm/bridge: move devm_drm_of_get_bridge and drmm_of_get_bridge to drm_bridge.c * Add new get_bridge variant for drivers supporting non-graph DT: - drm/bridge: add devm_drm_of_get_bridge_by_node() - drm/bridge: samsung-dsim: use devm_drm_of_get_bridge[_by_node] to find the out_bridge * Preliminary patches (maybe to be removed as this work progresses): - drm/bridge: allow bridges to be informed about added and removed bridges - drm/encoder: add drm_encoder_cleanup_from() * Implement refcounting in the drm_bridge core: - drm/bridge: add support for refcounted DRM bridges - drm/bridge: devm_drm_of_get_bridge and drmm_of_get_bridge: automatically put the bridge - drm/bridge: increment refcount in of_drm_find_bridge() - drm/bridge: add devm_drm_put_bridge() and devm_drm_put_and_clear_bridge() - drm/bridge: add documentation of refcounted bridges - drm/tests: bridge: add KUnit tests for DRM bridges (init and destroy) * debugfs improvements to show bridges, part 2: - drm/debugfs: bridges_show: show refcount - drm/bridge: add list of removed refcounted bridges - drm/debugfs: show removed bridges * Adapt some existing bridges to be refcounted and/or to refcount bridges they take a pointer to: - drm/bridge: samsung-dsim: use refcounting for the out_bridge - drm/bridge: panel: use dynamic lifetime management - drm/bridge: ti-sn65dsi83: use dynamic lifetime management * Add hotplug-bridge (may be removed as this work progresses): - drm/bridge: hotplug-bridge: add driver to support hot-pluggable DSI bridges (HEAD -> ge/luca/wip) That's all ========== Thanks for you patience in reading this, and many thanks to Dmitry Baryshkov for the very nice and useful discussion during FOSDEM. Luca Changes in v6: - add drm_bridge_alloc() for safe initial refcount - always create panel bridge when adding a panel - as a prerequisite, move all drm_panel.c code into bridge/panel.c - add devm functions to get bridges (auto put on consumer removal) - add devm_drm_of_get_bridge_by_node() for drivers supporting non-graph DT - debugfs: show refcount and "[removed]" in bridges file - debugfs: add /sys/kernel/debug/dri/bridges showing all bridges (including removed ones) - add preliminary, trivial cleanup patches - Link to v5: https://lore.kernel.org/r/20241231-hotplug-drm-bridge-v5-0-173065a1ece1@xxxxxxxxxxx Changes in v5: - Implemented DRM bridge refcounting - removed the non-DRM patches, now in a separate series - Updated To/Cc list - Link to v4: https://lore.kernel.org/r/20240917-hotplug-drm-bridge-v4-0-bc4dfee61be6@xxxxxxxxxxx Changes in v4: - Replaced DRM bridge notifier with a new callback in struct drm_bridge_funcs - Added patch for missing devlink (LEDs used by backlight) - Various cleanups - Rebased on v6.11 - Link to v3: https://lore.kernel.org/r/20240809-hotplug-drm-bridge-v3-0-b4c178380bc9@xxxxxxxxxxx Changes in v3 (too many changes in v3 to mention them all, but here are the big ones): - Rewrote the DT format to allow fully decoupled overlays and to avoid adding properties (with the NVMEM exception still to be solved) - Implemented device instantiation based on the new DT format: i2c in i2c-core-of.c nobus-devices in the connector driver - DRM: insert/remove an LVDS DRM connector on hot(un)plug events - Added patch for a devlink issue on overlay removal (mostly to start discussion) - Link to v2: https://lore.kernel.org/r/20240510-hotplug-drm-bridge-v2-0-ec32f2c66d56@xxxxxxxxxxx Changes in v2: - Added bindings and driver for ge,sunh-addon-connector - Removed bindings for the hotplug-video-connector, this is now represented in DT as part of the ge,sunh-addon-connector - Various monior improvements to the DRM hotplug-bridge driver - Link to v1: https://lore.kernel.org/r/20240326-hotplug-drm-bridge-v1-0-4b51b5eb75d5@xxxxxxxxxxx Co-developed-by: Paul Kocialkowski <paul.kocialkowski@xxxxxxxxxxx> Signed-off-by: Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx> --- Luca Ceresoli (26): drm/debugfs: fix printk format for bridge index drm: of: drm_of_find_panel_or_bridge: move misplaced comment drm/bridge: panel: use drm_bridge_is_panel() instead of open code drm/bridge: panel: drm_panel_bridge_remove: warn when called on non-panel bridge drm/debugfs: add top-level 'bridges' file showing all added bridges drm/panel: move all code into bridge/panel.c drm/bridge: panel: forbid initializing a panel with unknown connector type drm/bridge: panel: add a panel_bridge to every panel drm/bridge: move devm_drm_of_get_bridge and drmm_of_get_bridge to drm_bridge.c drm/bridge: add devm_drm_of_get_bridge_by_node() drm/bridge: samsung-dsim: use devm_drm_of_get_bridge[_by_node] to find the out_bridge drm/bridge: allow bridges to be informed about added and removed bridges drm/encoder: add drm_encoder_cleanup_from() drm/bridge: add support for refcounted DRM bridges drm/bridge: devm_drm_of_get_bridge and drmm_of_get_bridge: automatically put the bridge drm/bridge: increment refcount in of_drm_find_bridge() drm/bridge: add devm_drm_put_bridge() and devm_drm_put_and_clear_bridge() drm/bridge: add documentation of refcounted bridges drm/tests: bridge: add KUnit tests for DRM bridges (init and destroy) drm/debugfs: bridges_show: show refcount drm/bridge: add list of removed refcounted bridges drm/debugfs: show removed bridges drm/bridge: samsung-dsim: use refcounting for the out_bridge drm/bridge: panel: use dynamic lifetime management drm/bridge: ti-sn65dsi83: use dynamic lifetime management drm/bridge: hotplug-bridge: add driver to support hot-pluggable DSI bridges Documentation/gpu/drm-kms-helpers.rst | 11 +- MAINTAINERS | 6 +- drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/atmel-hlcdc/Kconfig | 2 +- drivers/gpu/drm/bridge/Kconfig | 42 +- drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/hotplug-bridge.c | 666 +++++++++++++++++++++++++++++ drivers/gpu/drm/bridge/panel.c | 716 ++++++++++++++++++++++++++++---- drivers/gpu/drm/bridge/samsung-dsim.c | 65 +-- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 7 +- drivers/gpu/drm/drm_bridge.c | 444 +++++++++++++++++++- drivers/gpu/drm/drm_debugfs.c | 84 +++- drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/drm_encoder.c | 21 + drivers/gpu/drm/drm_internal.h | 10 + drivers/gpu/drm/drm_kms_helper_common.c | 1 + drivers/gpu/drm/drm_of.c | 68 --- drivers/gpu/drm/drm_panel.c | 575 ------------------------- drivers/gpu/drm/tests/Makefile | 1 + drivers/gpu/drm/tests/drm_bridge_test.c | 72 ++++ include/drm/drm_bridge.h | 154 +++++++ include/drm/drm_encoder.h | 1 + include/drm/drm_of.h | 1 + include/drm/drm_panel.h | 8 + 24 files changed, 2131 insertions(+), 827 deletions(-) --- base-commit: 08dbfc84db00b76df96829787bacc734c1c018b9 change-id: 20240319-hotplug-drm-bridge-16b86e67fe92 Best regards, -- Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx>