Panel orientation describes how the panel is mounted and comes from the common "rotation" DT property, yet each driver has to parse it and hand it back through get_orientation(). 24 drivers carry an identical copy of that code and the rest silently ignore the property.
Parse it once in devm_drm_panel_alloc(). The callback still takes precedence until the drivers are converted. An invalid value fails the allocation, just as it fails probe in those drivers today. As a side effect all panels honour "rotation" now. Among the in-tree DTs this only changes the Motorola Mapphone panel (panel-dsi-cm, rotation = <90>). Assisted-by: LLM Signed-off-by: Dmitry Baryshkov <[email protected]> --- drivers/gpu/drm/drm_connector.c | 5 ++++- drivers/gpu/drm/drm_panel.c | 9 +++++++++ include/drm/drm_panel.h | 10 ++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 893716a9e489..efcf1ce979a9 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -3397,7 +3397,8 @@ EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk); * @panel: panel that can provide orientation information. * * Drm drivers should call this function before drm_dev_register(). - * Orientation is obtained from panel's .get_orientation() callback. + * Orientation is obtained from panel's .get_orientation() callback, falling + * back to &drm_panel.orientation if the panel doesn't implement it. * * Returns: * Zero on success, negative errno on failure. @@ -3410,6 +3411,8 @@ int drm_connector_set_orientation_from_panel( if (panel && panel->funcs && panel->funcs->get_orientation) orientation = panel->funcs->get_orientation(panel); + else if (panel) + orientation = panel->orientation; else orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c index 5bc97166bcb8..1b7ff0bea68e 100644 --- a/drivers/gpu/drm/drm_panel.c +++ b/drivers/gpu/drm/drm_panel.c @@ -925,6 +925,15 @@ void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset, drm_panel_init(panel, dev, funcs, connector_type); + panel->orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; + if (dev->of_node) { + err = drm_of_get_panel_orientation(dev->of_node, + &panel->orientation); + if (err) + return ERR_PTR(dev_err_probe(dev, err, + "failed to get orientation\n")); + } + return container; } EXPORT_SYMBOL(__devm_drm_panel_alloc); diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 579b6be855c7..dc4fbeac796b 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -236,6 +236,16 @@ struct drm_panel { */ struct drm_connector connector; + /** + * @orientation: + * + * Orientation of the panel, used to set the panel orientation property + * of the connector. It is read from the "rotation" property of the + * panel's device tree node by devm_drm_panel_alloc(). Drivers can + * override it before calling drm_panel_add(). + */ + enum drm_panel_orientation orientation; + /** * @list: * -- 2.47.3
