Am Freitag, dem 18.02.2022 um 02:00 +0100 schrieb Marek Vasut: > 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. > > Signed-off-by: Marek Vasut <marex@xxxxxxx> > Cc: Jonas Karlman <jonas@xxxxxxxxx> > Cc: Laurent Pinchart <Laurent.pinchart@xxxxxxxxxxxxxxxx> > Cc: Maxime Ripard <maxime@xxxxxxxxxx> > Cc: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > Cc: Sam Ravnborg <sam@xxxxxxxxxxxx> Reviewed-by: Lucas Stach <l.stach@xxxxxxxxxxxxxx> > --- > V2: - New patch > --- > drivers/gpu/drm/bridge/tc358767.c | 46 ++++++++++++++++++++++++++++++- > 1 file changed, 45 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c > index 7dae18de76c97..4af0ad5db2148 100644 > --- a/drivers/gpu/drm/bridge/tc358767.c > +++ b/drivers/gpu/drm/bridge/tc358767.c > @@ -1684,6 +1684,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; > @@ -1696,7 +1740,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; >