Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: Config orientation property if panel provides it

Panel orientation property should be set before drm_dev_register().
Some drm driver calls drm_dev_register() in .bind(). However, most
panels sets orientation property relatively late, mostly in .get_modes()
callback, since this is when they are able to get the connector and
binds the orientation property to it, though the value should be known
when the panel is probed.

In drm_bridge_connector_init(), if a bridge is a panel bridge, use it to
set the connector's panel orientation property.

Suggested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
[dianders: fixed space vs. tab indentation]
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220609072722.3488207-9-hsinyi@chromium.org

authored by

Hsin-Yi Wang and committed by
Douglas Anderson
15b9ca16 a64af136

+55 -1
+34
drivers/gpu/drm/bridge/panel.c
··· 171 171 }; 172 172 173 173 /** 174 + * drm_bridge_is_panel - Checks if a drm_bridge is a panel_bridge. 175 + * 176 + * @bridge: The drm_bridge to be checked. 177 + * 178 + * Returns true if the bridge is a panel bridge, or false otherwise. 179 + */ 180 + bool drm_bridge_is_panel(const struct drm_bridge *bridge) 181 + { 182 + return bridge->funcs == &panel_bridge_bridge_funcs; 183 + } 184 + EXPORT_SYMBOL(drm_bridge_is_panel); 185 + 186 + /** 174 187 * drm_panel_bridge_add - Creates a &drm_bridge and &drm_connector that 175 188 * just calls the appropriate functions from &drm_panel. 176 189 * ··· 281 268 devm_kfree(panel_bridge->panel->dev, bridge); 282 269 } 283 270 EXPORT_SYMBOL(drm_panel_bridge_remove); 271 + 272 + /** 273 + * drm_panel_bridge_set_orientation - Set the connector's panel orientation 274 + * from the bridge that can be transformed to panel bridge. 275 + * 276 + * @connector: The connector to be set panel orientation. 277 + * @bridge: The drm_bridge to be transformed to panel bridge. 278 + * 279 + * Returns 0 on success, negative errno on failure. 280 + */ 281 + int drm_panel_bridge_set_orientation(struct drm_connector *connector, 282 + struct drm_bridge *bridge) 283 + { 284 + struct panel_bridge *panel_bridge; 285 + 286 + panel_bridge = drm_bridge_to_panel_bridge(bridge); 287 + 288 + return drm_connector_set_orientation_from_panel(connector, 289 + panel_bridge->panel); 290 + } 291 + EXPORT_SYMBOL(drm_panel_bridge_set_orientation); 284 292 285 293 static void devm_drm_panel_bridge_release(struct device *dev, void *res) 286 294 {
+7 -1
drivers/gpu/drm/drm_bridge_connector.c
··· 331 331 struct drm_bridge_connector *bridge_connector; 332 332 struct drm_connector *connector; 333 333 struct i2c_adapter *ddc = NULL; 334 - struct drm_bridge *bridge; 334 + struct drm_bridge *bridge, *panel_bridge = NULL; 335 335 int connector_type; 336 336 337 337 bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL); ··· 373 373 374 374 if (bridge->ddc) 375 375 ddc = bridge->ddc; 376 + 377 + if (drm_bridge_is_panel(bridge)) 378 + panel_bridge = bridge; 376 379 } 377 380 378 381 if (connector_type == DRM_MODE_CONNECTOR_Unknown) { ··· 394 391 else if (bridge_connector->bridge_detect) 395 392 connector->polled = DRM_CONNECTOR_POLL_CONNECT 396 393 | DRM_CONNECTOR_POLL_DISCONNECT; 394 + 395 + if (panel_bridge) 396 + drm_panel_bridge_set_orientation(connector, panel_bridge); 397 397 398 398 return connector; 399 399 }
+14
include/drm/drm_bridge.h
··· 918 918 enum drm_connector_status status); 919 919 920 920 #ifdef CONFIG_DRM_PANEL_BRIDGE 921 + bool drm_bridge_is_panel(const struct drm_bridge *bridge); 921 922 struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel); 922 923 struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, 923 924 u32 connector_type); 924 925 void drm_panel_bridge_remove(struct drm_bridge *bridge); 926 + int drm_panel_bridge_set_orientation(struct drm_connector *connector, 927 + struct drm_bridge *bridge); 925 928 struct drm_bridge *devm_drm_panel_bridge_add(struct device *dev, 926 929 struct drm_panel *panel); 927 930 struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, 928 931 struct drm_panel *panel, 929 932 u32 connector_type); 930 933 struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge); 934 + #else 935 + static inline bool drm_bridge_is_panel(const struct drm_bridge *bridge) 936 + { 937 + return false; 938 + } 939 + 940 + static inline int drm_panel_bridge_set_orientation(struct drm_connector *connector, 941 + struct drm_bridge *bridge) 942 + { 943 + return -EINVAL; 944 + } 931 945 #endif 932 946 933 947 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE)