Hi Dmitry,

On Tue Oct 27, 2026 at 1:02 PM CET, Dmitry Baryshkov wrote:
> On Mon, Oct 26, 2026 at 01:09:49PM +0200, Dmitry Baryshkov wrote:
>> The panel is the only element of the display pipeline which never sees
>> the atomic commit. Its prepare() and enable() callbacks get nothing but
>> the panel, so a panel which has to be programmed differently depending
>> on the mode can only guess it. The NT35950 driver, for example, saves
>> the connector in get_modes() and reads connector->state->crtc->state
>> while being prepared: without the locks, from the current state rather
>> than from the one being committed, and with no way to reject a mode it
>> doesn't know.
>>
>> Every panel has a struct drm_bridge embedded into it, and the bridge
>> already has all the missing parts: atomic_check(), a state object which
>> can be subclassed and the commit passed to the callbacks. Rather than
>> growing struct drm_panel_funcs into a copy of that, let the panel driver
>> provide struct drm_bridge_funcs for the embedded bridge. This is opt-in:
>> the panels which have no use for the atomic state keep using struct
>> drm_panel_funcs and are not touched by it.
>>
>> To get there the bridge callbacks become the entry point to the panel,
>> with drm_panel_prepare() and friends calling them rather than the other
>> way around. The panel core still has to track the panel state, notify
>> the panel followers and handle the backlight, so the driver doesn't fill
>> in the power callbacks directly, it wraps its functions with the macros
>> doing that part. NT35950 is converted as the first user.
>>
>> The bulk of the series is the cleanup of what the panel core and the
>> bridge need from the panel driver, so that a panel providing the bridge
>> callbacks doesn't need struct drm_panel_funcs for anything:
>>
>> - get_timings() had no callers.
>>
>> - The connector type was stored both in the panel and in its bridge, and
>>   the display drivers could override it while creating the panel bridge.
>>
>> - The orientation was read from the DT, stored and returned by nearly
>>   identical code in more than twenty panel drivers, and some of them
>>   also had to set it on the connector from get_modes(), with a TODO
>>   asking for a better place. The core reads it now. It is applied to the
>>   connector from the new connector_init() bridge callback, which is not
>>   specific to the panels: other bridges have properties to set up on the
>>   connector being created too (HDCP, DP link properties), and currently
>>   have nowhere to do it.
>>
>> - disable() and unprepare() returned an error which nobody could act on.
>>   Worse, a failed unprepare() left the panel marked as prepared, so it
>>   was never initialised again.
>>
>> Behaviour changes worth knowing about:
>>
>> - Panels with the rotation property whose driver ignored it now get the
>>   orientation property. In the tree this is the Motorola Mapphone panel
>>   (panel-dsi-cm).
>>
>> - sun6i_mipi_dsi, sti_dvo and the Tegra DSI get their panel after the
>>   DRM device has been registered, which is too late to create the
>>   property, so they lose the orientation which the panel drivers used to
>>   set from get_modes(). None of the rotated panels in the tree are used
>>   with them.
>>
>> - A panel implementing atomic_check() can only be driven through the
>>   bridge chain. The display drivers calling drm_panel_prepare() directly
>>   have no commit to pass.
>>
>> Signed-off-by: Dmitry Baryshkov <[email protected]>
>> ---
>> Dmitry Baryshkov (35):
>>       drm/panel: remove the get_timings() callback
>>       drm/panel: remove the unused struct panel_bridge
>>       drm/tidss: get the panel type from the embedded bridge
>>       drm/bridge: lvds-codec: use devm_drm_panel_bridge_add()
>>       drm/ingenic: use devm_drm_panel_bridge_add()
>>       drm: mxsfb: use devm_drm_panel_bridge_add()
>>       drm: rcar-du: use devm_drm_panel_bridge_add()
>>       drm: rz-du: use devm_drm_panel_bridge_add()
>>       drm/mcde: use drm_panel_bridge_add()
>>       drm/pl111: use drm_panel_bridge_add()
>>       drm/rockchip: lvds: use drm_panel_bridge_add()
>>       drm/rockchip: rgb: use drm_panel_bridge_add()
>>       drm/panel: remove the _typed() panel bridge functions
>
> Gmail barked at me for sending too many emails for too many recipients
> in the middle of the series. I guess, I'll have to split the series into
> smaller parts. Please consider reviewing the posted patches, letting me
> split / land the series in parts.

The first 13~14 patches are nice and fairly independent cleanups. I guess
they can be sent separately, or just be applied. However I'd still want to
review patch 14 and do some testing next week before I consider them ready
for applying.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

Reply via email to