To simplify interfacing with the panel, wrap it in a panel-bridge and
let the DRM bridge helpers handle chaining of operations.

This also prepares for support of DRM_BRIDGE_ATTACH_NO_CONNECTOR, which
requires all components in the display pipeline to be represented by
bridges.

Signed-off-by: Laurent Pinchart <[email protected]>
Reviewed-by: Jagan Teki <[email protected]>
---
Changes since v1:

- Drop error message when drm_bridge_attach() fails (now printed by the
  function)
- Return ERR_PTR() directly
- Clarify which bridge is the next bridge
- Drop ti_sn65dsi86.panel field
---
 drivers/gpu/drm/bridge/ti-sn65dsi86.c | 32 +++++++++++++++++----------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 28c1ea370ae4..18b4420cc6b3 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -127,7 +127,7 @@
  * @host_node:    Remote DSI node.
  * @dsi:          Our MIPI DSI source.
  * @refclk:       Our reference clock.
- * @panel:        Our panel.
+ * @next_bridge:  The bridge on the eDP side.
  * @enable_gpio:  The GPIO we toggle to enable the bridge.
  * @supplies:     Data for bulk enabling/disabling our regulators.
  * @dp_lanes:     Count of dp_lanes we're using.
@@ -159,7 +159,7 @@ struct ti_sn65dsi86 {
        struct device_node              *host_node;
        struct mipi_dsi_device          *dsi;
        struct clk                      *refclk;
-       struct drm_panel                *panel;
+       struct drm_bridge               *next_bridge;
        struct gpio_desc                *enable_gpio;
        struct regulator_bulk_data      supplies[SN_REGULATOR_SUPPLY_NUM];
        int                             dp_lanes;
@@ -404,7 +404,8 @@ connector_to_ti_sn65dsi86(struct drm_connector *connector)
 static int ti_sn_bridge_connector_get_modes(struct drm_connector *connector)
 {
        struct ti_sn65dsi86 *pdata = connector_to_ti_sn65dsi86(connector);
-       return drm_panel_get_modes(pdata->panel, connector);
+
+       return drm_bridge_get_modes(pdata->next_bridge, connector);
 }
 
 static enum drm_mode_status
@@ -530,8 +531,16 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge,
        }
        pdata->dsi = dsi;
 
+       /* Attach the next bridge */
+       ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge,
+                               &pdata->bridge, flags);
+       if (ret < 0)
+               goto err_dsi_detach;
+
        return 0;
 
+err_dsi_detach:
+       mipi_dsi_detach(dsi);
 err_dsi_attach:
        mipi_dsi_device_unregister(dsi);
 err_dsi_host:
@@ -550,8 +559,6 @@ static void ti_sn_bridge_disable(struct drm_bridge *bridge)
 {
        struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
 
-       drm_panel_disable(pdata->panel);
-
        /* disable video stream */
        regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 0);
        /* semi auto link training mode OFF */
@@ -878,8 +885,6 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
        /* enable video stream */
        regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE,
                           VSTREAM_ENABLE);
-
-       drm_panel_enable(pdata->panel);
 }
 
 static void ti_sn_bridge_pre_enable(struct drm_bridge *bridge)
@@ -890,16 +895,12 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge 
*bridge)
 
        if (!pdata->refclk)
                ti_sn65dsi86_enable_comms(pdata);
-
-       drm_panel_prepare(pdata->panel);
 }
 
 static void ti_sn_bridge_post_disable(struct drm_bridge *bridge)
 {
        struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
 
-       drm_panel_unprepare(pdata->panel);
-
        if (!pdata->refclk)
                ti_sn65dsi86_disable_comms(pdata);
 
@@ -1304,13 +1305,20 @@ static int ti_sn_bridge_probe(struct auxiliary_device 
*adev,
 {
        struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
        struct device_node *np = pdata->dev->of_node;
+       struct drm_panel *panel;
        int ret;
 
-       ret = drm_of_find_panel_or_bridge(np, 1, 0, &pdata->panel, NULL);
+       ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
        if (ret)
                return dev_err_probe(&adev->dev, ret,
                                     "could not find any panel node\n");
 
+       pdata->next_bridge = devm_drm_panel_bridge_add(pdata->dev, panel);
+       if (IS_ERR(pdata->next_bridge)) {
+               DRM_ERROR("failed to create panel bridge\n");
+               return PTR_ERR(pdata->next_bridge);
+       }
+
        ti_sn_bridge_parse_lanes(pdata, np);
 
        ret = ti_sn_bridge_parse_dsi_host(pdata);
-- 
Regards,

Laurent Pinchart

Reply via email to