MLK-18177-2: drm/bridge: nwl-dsi: Change init sequence for panel
authorRobert Chiras <robert.chiras@nxp.com>
Thu, 12 Apr 2018 13:30:28 +0000 (16:30 +0300)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
Currently, the DSI panel init sequence is made in the prepare function,
right after the reset pin is asserted. This implies that at this moment,
the DSI host needs to be enabled. If the DSI host is enabled during
panel prepare, there will be DSI signal on the DSI lanes during the
panel reset, which is wrong.

In order to fix this, the init sequence was moved from prepare to
enable, while the reset sequence is made in prepare. Also, the DSI host
intialization has to be updated in such a way that the host won't send
DSI signals on the lanes between the prepare and enable of the panel.

Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
drivers/gpu/drm/bridge/nwl-dsi.c

index b6b669e..a7d9e9c 100644 (file)
@@ -1018,34 +1018,47 @@ static void nwl_dsi_bridge_enable(struct drm_bridge *bridge)
 
        nwl_dsi_enable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
 
-       nwl_dsi_config_host(dsi);
-       nwl_dsi_config_dpi(dsi);
-
        phy_init(dsi->phy);
 
        ret = phy_power_on(dsi->phy);
        if (ret < 0) {
                DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
-               return;
+               goto phy_err;
        }
 
        nwl_dsi_init_interrupts(dsi);
+       nwl_dsi_config_dpi(dsi);
 
        if (dsi->panel && drm_panel_prepare(dsi->panel)) {
                DRM_DEV_ERROR(dev, "Failed to setup panel\n");
-               return;
+               goto prepare_err;
        }
 
-       if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
-               nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
+       nwl_dsi_config_host(dsi);
 
        if (dsi->panel && drm_panel_enable(dsi->panel)) {
                DRM_DEV_ERROR(dev, "Failed to enable panel\n");
                drm_panel_unprepare(dsi->panel);
-               return;
+               goto enable_err;
        }
 
+       if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
+               nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
+
        dsi->enabled = true;
+
+       return;
+
+enable_err:
+       drm_panel_unprepare(dsi->panel);
+
+prepare_err:
+       phy_power_off(dsi->phy);
+
+phy_err:
+       phy_exit(dsi->phy);
+       nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
+       devm_free_irq(dev, dsi->irq, dsi);
 }
 
 static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
@@ -1064,12 +1077,12 @@ static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
                drm_panel_unprepare(dsi->panel);
        }
 
-       nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
-       devm_free_irq(dev, dsi->irq, dsi);
-
        phy_power_off(dsi->phy);
        phy_exit(dsi->phy);
 
+       nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
+       devm_free_irq(dev, dsi->irq, dsi);
+
        dsi->enabled = false;
 }