Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
			 struct drm_encoder *encoder)
{
	struct msm_drm_private *priv;
	struct drm_bridge *ext_bridge;
	int ret;

	if (WARN_ON(!encoder) || WARN_ON(!msm_dsi) || WARN_ON(!dev))
		return -EINVAL;

	priv = dev->dev_private;
	msm_dsi->dev = dev;

	ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
	if (ret) {
		dev_err(dev->dev, "failed to modeset init host: %d\n", ret);
		goto fail;
	}

	if (!msm_dsi_manager_validate_current_config(msm_dsi->id))
		goto fail;

	msm_dsi->encoder = encoder;

	msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id);
	if (IS_ERR(msm_dsi->bridge)) {
		ret = PTR_ERR(msm_dsi->bridge);
		dev_err(dev->dev, "failed to create dsi bridge: %d\n", ret);
		msm_dsi->bridge = NULL;
		goto fail;
	}

	/*
	 * check if the dsi encoder output is connected to a panel or an
	 * external bridge. We create a connector only if we're connected to a
	 * drm_panel device. When we're connected to an external bridge, we
	 * assume that the drm_bridge driver will create the connector itself.
	 */
	ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host);

	if (ext_bridge)
		msm_dsi->connector =
			msm_dsi_manager_ext_bridge_init(msm_dsi->id);
	else
		msm_dsi->connector =
			msm_dsi_manager_connector_init(msm_dsi->id);

	if (IS_ERR(msm_dsi->connector)) {
		ret = PTR_ERR(msm_dsi->connector);
		dev_err(dev->dev,
			"failed to create dsi connector: %d\n", ret);
		msm_dsi->connector = NULL;
		goto fail;
	}

	priv->bridges[priv->num_bridges++]       = msm_dsi->bridge;
	priv->connectors[priv->num_connectors++] = msm_dsi->connector;

	return 0;
fail:
	/* bridge/connector are normally destroyed by drm: */
	if (msm_dsi->bridge) {
		msm_dsi_manager_bridge_destroy(msm_dsi->bridge);
		msm_dsi->bridge = NULL;
	}

	/* don't destroy connector if we didn't make it */
	if (msm_dsi->connector && !msm_dsi->external_bridge)
		msm_dsi->connector->funcs->destroy(msm_dsi->connector);

	msm_dsi->connector = NULL;

	return ret;
}
Exemplo n.º 3
0
Arquivo: dsi.c Projeto: 020gzh/linux
int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
		struct drm_encoder *encoders[MSM_DSI_ENCODER_NUM])
{
	struct msm_drm_private *priv = dev->dev_private;
	struct drm_bridge *ext_bridge;
	int ret, i;

	if (WARN_ON(!encoders[MSM_DSI_VIDEO_ENCODER_ID] ||
		!encoders[MSM_DSI_CMD_ENCODER_ID]))
		return -EINVAL;

	msm_dsi->dev = dev;

	ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
	if (ret) {
		dev_err(dev->dev, "failed to modeset init host: %d\n", ret);
		goto fail;
	}

	msm_dsi->bridge = msm_dsi_manager_bridge_init(msm_dsi->id);
	if (IS_ERR(msm_dsi->bridge)) {
		ret = PTR_ERR(msm_dsi->bridge);
		dev_err(dev->dev, "failed to create dsi bridge: %d\n", ret);
		msm_dsi->bridge = NULL;
		goto fail;
	}

	for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) {
		encoders[i]->bridge = msm_dsi->bridge;
		msm_dsi->encoders[i] = encoders[i];
	}

	/*
	 * check if the dsi encoder output is connected to a panel or an
	 * external bridge. We create a connector only if we're connected to a
	 * drm_panel device. When we're connected to an external bridge, we
	 * assume that the drm_bridge driver will create the connector itself.
	 */
	ext_bridge = msm_dsi_host_get_bridge(msm_dsi->host);

	if (ext_bridge)
		msm_dsi->connector =
			msm_dsi_manager_ext_bridge_init(msm_dsi->id);
	else
		msm_dsi->connector =
			msm_dsi_manager_connector_init(msm_dsi->id);

	if (IS_ERR(msm_dsi->connector)) {
		ret = PTR_ERR(msm_dsi->connector);
		dev_err(dev->dev,
			"failed to create dsi connector: %d\n", ret);
		msm_dsi->connector = NULL;
		goto fail;
	}

	priv->bridges[priv->num_bridges++]       = msm_dsi->bridge;
	priv->connectors[priv->num_connectors++] = msm_dsi->connector;

	return 0;
fail:
	if (msm_dsi) {
		/* bridge/connector are normally destroyed by drm: */
		if (msm_dsi->bridge) {
			msm_dsi_manager_bridge_destroy(msm_dsi->bridge);
			msm_dsi->bridge = NULL;
		}

		/* don't destroy connector if we didn't make it */
		if (msm_dsi->connector && !msm_dsi->external_bridge)
			msm_dsi->connector->funcs->destroy(msm_dsi->connector);

		msm_dsi->connector = NULL;
	}

	return ret;
}