Lines Matching +full:vga +full:- +full:connector

1 // SPDX-License-Identifier: GPL-2.0+
24 * The DRM bridge connector helper object provides a DRM connector
25 * implementation that wraps a chain of &struct drm_bridge. The connector
30 * To use the helper, display controller drivers create a bridge connector with
32 * connector with the chain of bridges passed to the function and registers it
33 * with the DRM device. At that point the connector becomes fully usable, no
36 * The DRM bridge connector operations are implemented based on the operations
37 * provided by the bridges in the chain. Each connector operation is delegated
38 * to the bridge closest to the connector (at the end of the chain) that
42 * operation flags (&drm_bridge->ops) and bridge output type
43 * (&drm_bridge->type), as well as the DRM_BRIDGE_ATTACH_NO_CONNECTOR attach
44 * flag (none of the bridges shall create a DRM connector directly).
48 * struct drm_bridge_connector - A connector backed by a chain of bridges
52 * @base: The base DRM connector
64 * The last bridge in the chain (closest to the connector) that provides
71 * The last bridge in the chain (closest to the connector) that provides
72 * hot-plug detection notification, if any (see &DRM_BRIDGE_OP_HPD).
78 * The last bridge in the chain (closest to the connector) that provides
79 * connector detection, if any (see &DRM_BRIDGE_OP_DETECT).
85 * The last bridge in the chain (closest to the connector) that provides
86 * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES).
94 /* -----------------------------------------------------------------------------
95 * Bridge Connector Hot-Plug Handling
98 static void drm_bridge_connector_hpd_notify(struct drm_connector *connector, in drm_bridge_connector_hpd_notify() argument
102 to_drm_bridge_connector(connector); in drm_bridge_connector_hpd_notify()
106 drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) { in drm_bridge_connector_hpd_notify()
107 if (bridge->funcs->hpd_notify) in drm_bridge_connector_hpd_notify()
108 bridge->funcs->hpd_notify(bridge, status); in drm_bridge_connector_hpd_notify()
115 struct drm_connector *connector = &drm_bridge_connector->base; in drm_bridge_connector_handle_hpd() local
116 struct drm_device *dev = connector->dev; in drm_bridge_connector_handle_hpd()
118 mutex_lock(&dev->mode_config.mutex); in drm_bridge_connector_handle_hpd()
119 connector->status = status; in drm_bridge_connector_handle_hpd()
120 mutex_unlock(&dev->mode_config.mutex); in drm_bridge_connector_handle_hpd()
122 drm_bridge_connector_hpd_notify(connector, status); in drm_bridge_connector_handle_hpd()
124 drm_kms_helper_connector_hotplug_event(connector); in drm_bridge_connector_handle_hpd()
133 static void drm_bridge_connector_oob_hotplug_event(struct drm_connector *connector, in drm_bridge_connector_oob_hotplug_event() argument
137 to_drm_bridge_connector(connector); in drm_bridge_connector_oob_hotplug_event()
142 static void drm_bridge_connector_enable_hpd(struct drm_connector *connector) in drm_bridge_connector_enable_hpd() argument
145 to_drm_bridge_connector(connector); in drm_bridge_connector_enable_hpd()
146 struct drm_bridge *hpd = bridge_connector->bridge_hpd; in drm_bridge_connector_enable_hpd()
153 static void drm_bridge_connector_disable_hpd(struct drm_connector *connector) in drm_bridge_connector_disable_hpd() argument
156 to_drm_bridge_connector(connector); in drm_bridge_connector_disable_hpd()
157 struct drm_bridge *hpd = bridge_connector->bridge_hpd; in drm_bridge_connector_disable_hpd()
163 /* -----------------------------------------------------------------------------
164 * Bridge Connector Functions
168 drm_bridge_connector_detect(struct drm_connector *connector, bool force) in drm_bridge_connector_detect() argument
171 to_drm_bridge_connector(connector); in drm_bridge_connector_detect()
172 struct drm_bridge *detect = bridge_connector->bridge_detect; in drm_bridge_connector_detect()
176 status = detect->funcs->detect(detect); in drm_bridge_connector_detect()
178 drm_bridge_connector_hpd_notify(connector, status); in drm_bridge_connector_detect()
180 switch (connector->connector_type) { in drm_bridge_connector_detect()
196 static void drm_bridge_connector_destroy(struct drm_connector *connector) in drm_bridge_connector_destroy() argument
199 to_drm_bridge_connector(connector); in drm_bridge_connector_destroy()
201 drm_connector_unregister(connector); in drm_bridge_connector_destroy()
202 drm_connector_cleanup(connector); in drm_bridge_connector_destroy()
204 fwnode_handle_put(connector->fwnode); in drm_bridge_connector_destroy()
209 static void drm_bridge_connector_debugfs_init(struct drm_connector *connector, in drm_bridge_connector_debugfs_init() argument
213 to_drm_bridge_connector(connector); in drm_bridge_connector_debugfs_init()
214 struct drm_encoder *encoder = bridge_connector->encoder; in drm_bridge_connector_debugfs_init()
217 list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) { in drm_bridge_connector_debugfs_init()
218 if (bridge->funcs->debugfs_init) in drm_bridge_connector_debugfs_init()
219 bridge->funcs->debugfs_init(bridge, root); in drm_bridge_connector_debugfs_init()
234 /* -----------------------------------------------------------------------------
235 * Bridge Connector Helper Functions
238 static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector, in drm_bridge_connector_get_modes_edid() argument
245 status = drm_bridge_connector_detect(connector, false); in drm_bridge_connector_get_modes_edid()
249 edid = drm_bridge_get_edid(bridge, connector); in drm_bridge_connector_get_modes_edid()
255 drm_connector_update_edid_property(connector, edid); in drm_bridge_connector_get_modes_edid()
256 n = drm_add_edid_modes(connector, edid); in drm_bridge_connector_get_modes_edid()
262 drm_connector_update_edid_property(connector, NULL); in drm_bridge_connector_get_modes_edid()
266 static int drm_bridge_connector_get_modes(struct drm_connector *connector) in drm_bridge_connector_get_modes() argument
269 to_drm_bridge_connector(connector); in drm_bridge_connector_get_modes()
276 bridge = bridge_connector->bridge_edid; in drm_bridge_connector_get_modes()
278 return drm_bridge_connector_get_modes_edid(connector, bridge); in drm_bridge_connector_get_modes()
284 bridge = bridge_connector->bridge_modes; in drm_bridge_connector_get_modes()
286 return bridge->funcs->get_modes(bridge, connector); in drm_bridge_connector_get_modes()
290 * VGA output with the DDC bus unconnected. The KMS core will add the in drm_bridge_connector_get_modes()
303 /* -----------------------------------------------------------------------------
304 * Bridge Connector Initialisation
308 * drm_bridge_connector_init - Initialise a connector for a chain of bridges
313 * device. The connector is associated with a chain of bridges that starts at
315 * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none of
316 * them may create a DRM connector directly.
318 * Returns a pointer to the new connector on success, or a negative error
325 struct drm_connector *connector; in drm_bridge_connector_init() local
333 return ERR_PTR(-ENOMEM); in drm_bridge_connector_init()
335 bridge_connector->encoder = encoder; in drm_bridge_connector_init()
341 connector = &bridge_connector->base; in drm_bridge_connector_init()
342 connector->interlace_allowed = true; in drm_bridge_connector_init()
345 * Initialise connector status handling. First locate the furthest in drm_bridge_connector_init()
347 * initialise the connector polling mode, using HPD if available and in drm_bridge_connector_init()
353 if (!bridge->interlace_allowed) in drm_bridge_connector_init()
354 connector->interlace_allowed = false; in drm_bridge_connector_init()
356 if (bridge->ops & DRM_BRIDGE_OP_EDID) in drm_bridge_connector_init()
357 bridge_connector->bridge_edid = bridge; in drm_bridge_connector_init()
358 if (bridge->ops & DRM_BRIDGE_OP_HPD) in drm_bridge_connector_init()
359 bridge_connector->bridge_hpd = bridge; in drm_bridge_connector_init()
360 if (bridge->ops & DRM_BRIDGE_OP_DETECT) in drm_bridge_connector_init()
361 bridge_connector->bridge_detect = bridge; in drm_bridge_connector_init()
362 if (bridge->ops & DRM_BRIDGE_OP_MODES) in drm_bridge_connector_init()
363 bridge_connector->bridge_modes = bridge; in drm_bridge_connector_init()
366 connector_type = bridge->type; in drm_bridge_connector_init()
370 bridge->of_node) in drm_bridge_connector_init()
371 connector->fwnode = fwnode_handle_get(of_fwnode_handle(bridge->of_node)); in drm_bridge_connector_init()
374 if (bridge->ddc) in drm_bridge_connector_init()
375 ddc = bridge->ddc; in drm_bridge_connector_init()
383 return ERR_PTR(-EINVAL); in drm_bridge_connector_init()
386 ret = drm_connector_init_with_ddc(drm, connector, in drm_bridge_connector_init()
394 drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs); in drm_bridge_connector_init()
396 if (bridge_connector->bridge_hpd) in drm_bridge_connector_init()
397 connector->polled = DRM_CONNECTOR_POLL_HPD; in drm_bridge_connector_init()
398 else if (bridge_connector->bridge_detect) in drm_bridge_connector_init()
399 connector->polled = DRM_CONNECTOR_POLL_CONNECT in drm_bridge_connector_init()
403 drm_panel_bridge_set_orientation(connector, panel_bridge); in drm_bridge_connector_init()
405 return connector; in drm_bridge_connector_init()