Unverified Commit 71f7d9c0 authored by Marek Vasut's avatar Marek Vasut Committed by Robert Foss
Browse files

drm/bridge: tc358767: Detect bridge mode from connected endpoints in DT



The TC358767/TC358867/TC9595 are all capable of operating in multiple
modes, DPI-to-(e)DP, DSI-to-(e)DP, DSI-to-DPI. Only the first mode is
currently supported. It is possible to find out the mode in which the
bridge should be operated by testing connected endpoints in DT.

Port allocation:
port@0 - DSI input
port@1 - DPI input/output
port@2 - eDP output

Possible connections:
DPI -> port@1 -> port@2 -> eDP :: [port@0 is not connected]
DSI -> port@0 -> port@2 -> eDP :: [port@1 is not connected]
DSI -> port@0 -> port@1 -> DPI :: [port@2 is not connected]

Add function to determine the bridge mode based on connected endpoints.

Reviewed-by: default avatarLucas Stach <l.stach@pengutronix.de>
Tested-by: Lucas Stach <l.stach@pengutronix.de> # In both DPI to eDP and DSI to DPI mode.
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Maxime Ripard <maxime@cerno.tech>
Cc: Neil Armstrong <narmstrong@baylibre.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: default avatarRobert Foss <robert.foss@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220329085015.39159-10-marex@denx.de
parent dd1fd5ab
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -1621,6 +1621,50 @@ static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
	return ret;
}

static int tc_probe_bridge_endpoint(struct tc_data *tc)
{
	struct device *dev = tc->dev;
	struct of_endpoint endpoint;
	struct device_node *node = NULL;
	const u8 mode_dpi_to_edp = BIT(1) | BIT(2);
	const u8 mode_dsi_to_edp = BIT(0) | BIT(2);
	const u8 mode_dsi_to_dpi = BIT(0) | BIT(1);
	u8 mode = 0;

	/*
	 * Determine bridge configuration.
	 *
	 * Port allocation:
	 * port@0 - DSI input
	 * port@1 - DPI input/output
	 * port@2 - eDP output
	 *
	 * Possible connections:
	 * DPI -> port@1 -> port@2 -> eDP :: [port@0 is not connected]
	 * DSI -> port@0 -> port@2 -> eDP :: [port@1 is not connected]
	 * DSI -> port@0 -> port@1 -> DPI :: [port@2 is not connected]
	 */

	for_each_endpoint_of_node(dev->of_node, node) {
		of_graph_parse_endpoint(node, &endpoint);
		if (endpoint.port > 2)
			return -EINVAL;

		mode |= BIT(endpoint.port);
	}

	if (mode == mode_dpi_to_edp)
		return tc_probe_edp_bridge_endpoint(tc);
	else if (mode == mode_dsi_to_dpi)
		dev_warn(dev, "The mode DSI-to-DPI is not supported!\n");
	else if (mode == mode_dsi_to_edp)
		dev_warn(dev, "The mode DSI-to-(e)DP is not supported!\n");
	else
		dev_warn(dev, "Invalid mode (0x%x) is not supported!\n", mode);

	return -EINVAL;
}

static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
@@ -1633,7 +1677,7 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)

	tc->dev = dev;

	ret = tc_probe_edp_bridge_endpoint(tc);
	ret = tc_probe_bridge_endpoint(tc);
	if (ret)
		return ret;