/* initialize bridge */ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) { struct drm_bridge *bridge = NULL; struct hdmi_bridge *hdmi_bridge; int ret; hdmi_bridge = devm_kzalloc(hdmi->dev->dev, sizeof(*hdmi_bridge), GFP_KERNEL); if (!hdmi_bridge) { ret = -ENOMEM; goto fail; } hdmi_bridge->hdmi = hdmi; bridge = &hdmi_bridge->base; bridge->funcs = &hdmi_bridge_funcs; ret = drm_bridge_attach(hdmi->dev, bridge); if (ret) goto fail; return bridge; fail: if (bridge) hdmi_bridge_destroy(bridge); return ERR_PTR(ret); }
static int analogix_dp_create_bridge(struct drm_device *drm_dev, struct analogix_dp_device *dp) { struct drm_bridge *bridge; int ret; bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); if (!bridge) { DRM_ERROR("failed to allocate for drm bridge\n"); return -ENOMEM; } dp->bridge = bridge; dp->encoder->bridge = bridge; bridge->driver_private = dp; bridge->encoder = dp->encoder; bridge->funcs = &analogix_dp_bridge_funcs; ret = drm_bridge_attach(drm_dev, bridge); if (ret) { DRM_ERROR("failed to attach drm bridge\n"); return -EINVAL; } return 0; }
static int rcar_lvds_attach(struct drm_bridge *bridge) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); struct drm_connector *connector = &lvds->connector; struct drm_encoder *encoder = bridge->encoder; int ret; /* If we have a next bridge just attach it. */ if (lvds->next_bridge) return drm_bridge_attach(bridge->encoder, lvds->next_bridge, bridge); /* Otherwise we have a panel, create a connector. */ ret = drm_connector_init(bridge->dev, connector, &rcar_lvds_conn_funcs, DRM_MODE_CONNECTOR_LVDS); if (ret < 0) return ret; drm_connector_helper_add(connector, &rcar_lvds_conn_helper_funcs); ret = drm_mode_connector_attach_encoder(connector, encoder); if (ret < 0) return ret; return drm_panel_attach(lvds->panel, connector); }
static int tilcdc_attach_bridge(struct drm_device *ddev, struct drm_bridge *bridge) { struct tilcdc_drm_private *priv = ddev->dev_private; struct drm_connector *connector; int ret; priv->external_encoder->possible_crtcs = BIT(0); priv->external_encoder->bridge = bridge; bridge->encoder = priv->external_encoder; ret = drm_bridge_attach(ddev, bridge); if (ret) { dev_err(ddev->dev, "drm_bridge_attach() failed %d\n", ret); return ret; } tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_default); connector = tilcdc_encoder_find_connector(ddev, priv->external_encoder); if (!connector) return -ENODEV; ret = tilcdc_add_external_connector(ddev, connector); return ret; }
struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) { struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct drm_device *dev = msm_dsi->dev; struct drm_encoder *encoder; struct drm_bridge *int_bridge, *ext_bridge; struct drm_connector *connector; struct list_head *connector_list; int_bridge = msm_dsi->bridge; ext_bridge = msm_dsi->external_bridge = msm_dsi_host_get_bridge(msm_dsi->host); encoder = msm_dsi->encoder; /* link the internal dsi bridge to the external bridge */ drm_bridge_attach(encoder, ext_bridge, int_bridge); /* * we need the drm_connector created by the external bridge * driver (or someone else) to feed it to our driver's * priv->connector[] list, mainly for msm_fbdev_init() */ connector_list = &dev->mode_config.connector_list; list_for_each_entry(connector, connector_list, head) { if (drm_connector_has_possible_encoder(connector, encoder)) return connector; } return ERR_PTR(-ENODEV); }
static int exynos_dp_create_connector(struct drm_encoder *encoder) { struct exynos_dp_device *dp = encoder_to_dp(encoder); struct drm_device *drm_dev = dp->drm_dev; struct drm_bridge *bridge; int ret; bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); if (!bridge) { DRM_ERROR("failed to allocate for drm bridge\n"); return -ENOMEM; } dp->bridge = bridge; encoder->bridge = bridge; bridge->driver_private = dp; bridge->encoder = encoder; bridge->funcs = &exynos_dp_bridge_funcs; ret = drm_bridge_attach(drm_dev, bridge); if (ret) { DRM_ERROR("failed to attach drm bridge\n"); return -EINVAL; } return 0; }
/* initialize bridge */ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) { struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct drm_bridge *bridge = NULL; struct dsi_bridge *dsi_bridge; struct drm_encoder *encoder; int ret; dsi_bridge = devm_kzalloc(msm_dsi->dev->dev, sizeof(*dsi_bridge), GFP_KERNEL); if (!dsi_bridge) { ret = -ENOMEM; goto fail; } dsi_bridge->id = id; encoder = msm_dsi->encoder; bridge = &dsi_bridge->base; bridge->funcs = &dsi_mgr_bridge_funcs; ret = drm_bridge_attach(encoder, bridge, NULL); if (ret) goto fail; return bridge; fail: if (bridge) msm_dsi_manager_bridge_destroy(bridge); return ERR_PTR(ret); }
static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, struct drm_bridge *bridge, struct drm_connector *connector) { struct exynos_dp_device *dp = to_dp(plat_data); struct drm_encoder *encoder = &dp->encoder; int ret; drm_connector_register(connector); dp->connector = connector; /* Pre-empt DP connector creation if there's a bridge */ if (dp->ptn_bridge) { bridge->next = dp->ptn_bridge; dp->ptn_bridge->encoder = encoder; ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); if (ret) { DRM_ERROR("Failed to attach bridge to drm\n"); bridge->next = NULL; return ret; } } return 0; }
static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) { struct drm_encoder *encoder = hdmi->encoder; struct drm_bridge *bridge; int ret; bridge = devm_kzalloc(drm->dev, sizeof(*bridge), GFP_KERNEL); if (!bridge) { DRM_ERROR("Failed to allocate drm bridge\n"); return -ENOMEM; } hdmi->bridge = bridge; bridge->driver_private = hdmi; bridge->funcs = &dw_hdmi_bridge_funcs; ret = drm_bridge_attach(drm, bridge); if (ret) { DRM_ERROR("Failed to initialize bridge with drm\n"); return -EINVAL; } encoder->bridge = bridge; hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; drm_connector_helper_add(&hdmi->connector, &dw_hdmi_connector_helper_funcs); drm_connector_init(drm, &hdmi->connector, &dw_hdmi_connector_funcs, DRM_MODE_CONNECTOR_HDMIA); hdmi->connector.encoder = encoder; drm_mode_connector_attach_encoder(&hdmi->connector, encoder); return 0; }
/* returns the number of bridges attached */ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp, struct drm_encoder *encoder) { int ret; encoder->bridge->next = dp->ptn_bridge; dp->ptn_bridge->encoder = encoder; ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); if (ret) { DRM_ERROR("Failed to attach bridge to drm\n"); return ret; } return 0; }
int rcar_du_hdmienc_init(struct rcar_du_device *rcdu, struct rcar_du_encoder *renc, struct device_node *np) { struct drm_encoder *encoder = rcar_encoder_to_drm_encoder(renc); struct drm_bridge *bridge; struct rcar_du_hdmienc *hdmienc; int ret; hdmienc = devm_kzalloc(rcdu->dev, sizeof(*hdmienc), GFP_KERNEL); if (hdmienc == NULL) return -ENOMEM; /* Locate the DRM bridge from the HDMI encoder DT node. */ bridge = of_drm_find_bridge(np); if (!bridge) return -EPROBE_DEFER; ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); if (ret < 0) return ret; drm_encoder_helper_add(encoder, &encoder_helper_funcs); renc->hdmi = hdmienc; hdmienc->renc = renc; /* Link the bridge to the encoder. */ bridge->encoder = encoder; encoder->bridge = bridge; ret = drm_bridge_attach(rcdu->ddev, bridge); if (ret) { drm_encoder_cleanup(encoder); return ret; } return 0; }
static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev, const struct of_endpoint *ep) { struct drm_bridge *bridge; struct device_node *np; np = of_graph_get_remote_port_parent(ep->local_node); fsl_dev->connector.panel = of_drm_find_panel(np); if (fsl_dev->connector.panel) { of_node_put(np); return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel); } bridge = of_drm_find_bridge(np); of_node_put(np); if (!bridge) return -ENODEV; fsl_dev->encoder.bridge = bridge; bridge->encoder = &fsl_dev->encoder; return drm_bridge_attach(fsl_dev->drm, bridge); }
/** * drm_simple_display_pipe_attach_bridge - Attach a bridge to the display pipe * @pipe: simple display pipe object * @bridge: bridge to attach * * Makes it possible to still use the drm_simple_display_pipe helpers when * a DRM bridge has to be used. * * Note that you probably want to initialize the pipe by passing a NULL * connector to drm_simple_display_pipe_init(). * * Returns: * Zero on success, negative error code on failure. */ int drm_simple_display_pipe_attach_bridge(struct drm_simple_display_pipe *pipe, struct drm_bridge *bridge) { return drm_bridge_attach(&pipe->encoder, bridge, NULL); }
struct rockchip_rgb *rockchip_rgb_init(struct device *dev, struct drm_crtc *crtc, struct drm_device *drm_dev) { struct rockchip_rgb *rgb; struct drm_encoder *encoder; struct device_node *port, *endpoint; u32 endpoint_id; int ret = 0, child_count = 0; struct drm_panel *panel; struct drm_bridge *bridge; rgb = devm_kzalloc(dev, sizeof(*rgb), GFP_KERNEL); if (!rgb) return ERR_PTR(-ENOMEM); rgb->dev = dev; rgb->drm_dev = drm_dev; port = of_graph_get_port_by_id(dev->of_node, 0); if (!port) return ERR_PTR(-EINVAL); for_each_child_of_node(port, endpoint) { if (of_property_read_u32(endpoint, "reg", &endpoint_id)) endpoint_id = 0; if (rockchip_drm_endpoint_is_subdriver(endpoint) > 0) continue; child_count++; ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id, &panel, &bridge); if (!ret) { of_node_put(endpoint); break; } } of_node_put(port); /* if the rgb output is not connected to anything, just return */ if (!child_count) return NULL; if (ret < 0) { if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(dev, "failed to find panel or bridge %d\n", ret); return ERR_PTR(ret); } encoder = &rgb->encoder; encoder->possible_crtcs = drm_crtc_mask(crtc); ret = drm_encoder_init(drm_dev, encoder, &rockchip_rgb_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); if (ret < 0) { DRM_DEV_ERROR(drm_dev->dev, "failed to initialize encoder: %d\n", ret); return ERR_PTR(ret); } drm_encoder_helper_add(encoder, &rockchip_rgb_encoder_helper_funcs); if (panel) { bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_LVDS); if (IS_ERR(bridge)) return ERR_CAST(bridge); } rgb->bridge = bridge; ret = drm_bridge_attach(encoder, rgb->bridge, NULL); if (ret) { DRM_DEV_ERROR(drm_dev->dev, "failed to attach bridge: %d\n", ret); goto err_free_encoder; } return rgb; err_free_encoder: drm_encoder_cleanup(encoder); return ERR_PTR(ret); }