@@ -580,6 +580,44 @@ void drm_bridge_chain_mode_set(struct drm_bridge *bridge,
}
EXPORT_SYMBOL(drm_bridge_chain_mode_set);
+/**
+ * drm_bridge_chain_setup_connector - call all bridges to perform additional setup
+ * of the attached drm_connector
+ * @bridge: bridge control structure
+ * @connector: connector that is used at the end of the bridge chain
+ *
+ * Calls &drm_bridge_funcs.setup_connector for all the bridges in the encoder
+ * chain, starting from the first bridge to the last. If at least one bridge
+ * does not accept the connector the function returns the error code.
+ *
+ * Note: the bridge passed should be the one closest to the encoder.
+ *
+ * RETURNS:
+ * Zero on success, error code on failure
+ */
+int drm_bridge_chain_setup_connector(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+ struct drm_encoder *encoder;
+ int ret;
+
+ if (!bridge)
+ return 0;
+
+ encoder = bridge->encoder;
+ list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
+ if (!bridge->funcs->setup_connector)
+ continue;
+
+ ret = bridge->funcs->setup_connector(bridge, connector);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_bridge_chain_setup_connector);
+
/**
* drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain
* @bridge: bridge control structure
@@ -402,6 +402,14 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
if (panel_bridge)
drm_panel_bridge_set_orientation(connector, panel_bridge);
+ ret = drm_bridge_chain_setup_connector(drm_bridge_chain_get_first_bridge(encoder),
+ connector);
+ if (ret) {
+ drm_connector_cleanup(connector);
+ kfree(bridge_connector);
+ return ERR_PTR(ret);
+ }
+
return connector;
}
EXPORT_SYMBOL_GPL(drm_bridge_connector_init);
@@ -84,6 +84,19 @@ struct drm_bridge_funcs {
*/
void (*detach)(struct drm_bridge *bridge);
+ /**
+ * @setup_connector:
+ *
+ * Perform additional setup of the connector once it is created.
+ *
+ * The @setup_connector callback is optional.
+ *
+ * RETURNS:
+ *
+ * Zero on success, error code on failure.
+ */
+ int (*setup_connector)(struct drm_bridge *bridge, struct drm_connector *connector);
+
/**
* @mode_valid:
*
@@ -877,6 +890,8 @@ void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state);
+int drm_bridge_chain_setup_connector(struct drm_bridge *bridge,
+ struct drm_connector *connector);
u32 *
drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
Add a callback to be called by the drivers when the drm_connector is created at the end of the drm_bridge chain. This allows bridges to perform additional setup, like setting up the HDMI connector properties. Note, for now only drm_bridge_connector uses this callback. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/gpu/drm/drm_bridge.c | 38 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_bridge_connector.c | 8 +++++++ include/drm/drm_bridge.h | 15 ++++++++++++++ 3 files changed, 61 insertions(+)