2019-04-24 14:24:34

by Matt Redfearn

[permalink] [raw]
Subject: [PATCH] drm/bridge/synopsys: dsi: Wait for all active lanes to reach stop

The Synopsys manual states that software should wait for all active
lanes to reach stop state (User manual section 3.1.5). Currently the
driver only waits for / checks that the clock lane is in stop state. Fix
this by waiting for the mask of PHY STATUS bits corresponding to the
active lanes to be set.

Signed-off-by: Matt Redfearn <[email protected]>

---

drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index bd15c21a177..38e88071363 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -189,6 +189,10 @@
#define DSI_PHY_TX_TRIGGERS 0xac

#define DSI_PHY_STATUS 0xb0
+#define PHY_STOP_STATE_LANE_3 BIT(11)
+#define PHY_STOP_STATE_LANE_2 BIT(9)
+#define PHY_STOP_STATE_LANE_1 BIT(7)
+#define PHY_STOP_STATE_LANE_0 BIT(4)
#define PHY_STOP_STATE_CLK_LANE BIT(2)
#define PHY_LOCK BIT(0)

@@ -752,7 +756,7 @@ static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)

static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
{
- u32 val;
+ u32 val, mask;
int ret;

dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
@@ -763,11 +767,16 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
if (ret)
DRM_DEBUG_DRIVER("failed to wait phy lock state\n");

+ mask = PHY_STOP_STATE_CLK_LANE | PHY_STOP_STATE_LANE_0;
+ mask |= (dsi->lanes >= 2) ? PHY_STOP_STATE_LANE_1 : 0;
+ mask |= (dsi->lanes >= 3) ? PHY_STOP_STATE_LANE_2 : 0;
+ mask |= (dsi->lanes == 4) ? PHY_STOP_STATE_LANE_3 : 0;
+
ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
- val, val & PHY_STOP_STATE_CLK_LANE, 1000,
+ val, (val & mask) == mask, 1000,
PHY_STATUS_TIMEOUT_US);
if (ret)
- DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
+ DRM_DEBUG_DRIVER("failed to wait phy stop state\n");
}

static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)
--
2.17.1


2019-04-25 09:21:23

by Laurent Pinchart

[permalink] [raw]
Subject: Re: [PATCH] drm/bridge/synopsys: dsi: Wait for all active lanes to reach stop

Hi Matt,

Thank you for the patch.

On Wed, Apr 24, 2019 at 02:21:40PM +0000, Matt Redfearn wrote:
> The Synopsys manual states that software should wait for all active
> lanes to reach stop state (User manual section 3.1.5). Currently the
> driver only waits for / checks that the clock lane is in stop state. Fix
> this by waiting for the mask of PHY STATUS bits corresponding to the
> active lanes to be set.
>
> Signed-off-by: Matt Redfearn <[email protected]>

I don't have access to the datasheet, but the change makes sense.

Reviewed-by: Laurent Pinchart <[email protected]>

> ---
>
> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index bd15c21a177..38e88071363 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -189,6 +189,10 @@
> #define DSI_PHY_TX_TRIGGERS 0xac
>
> #define DSI_PHY_STATUS 0xb0
> +#define PHY_STOP_STATE_LANE_3 BIT(11)
> +#define PHY_STOP_STATE_LANE_2 BIT(9)
> +#define PHY_STOP_STATE_LANE_1 BIT(7)
> +#define PHY_STOP_STATE_LANE_0 BIT(4)
> #define PHY_STOP_STATE_CLK_LANE BIT(2)
> #define PHY_LOCK BIT(0)
>
> @@ -752,7 +756,7 @@ static void dw_mipi_dsi_dphy_init(struct dw_mipi_dsi *dsi)
>
> static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
> {
> - u32 val;
> + u32 val, mask;
> int ret;
>
> dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
> @@ -763,11 +767,16 @@ static void dw_mipi_dsi_dphy_enable(struct dw_mipi_dsi *dsi)
> if (ret)
> DRM_DEBUG_DRIVER("failed to wait phy lock state\n");
>
> + mask = PHY_STOP_STATE_CLK_LANE | PHY_STOP_STATE_LANE_0;
> + mask |= (dsi->lanes >= 2) ? PHY_STOP_STATE_LANE_1 : 0;
> + mask |= (dsi->lanes >= 3) ? PHY_STOP_STATE_LANE_2 : 0;
> + mask |= (dsi->lanes == 4) ? PHY_STOP_STATE_LANE_3 : 0;
> +
> ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
> - val, val & PHY_STOP_STATE_CLK_LANE, 1000,
> + val, (val & mask) == mask, 1000,
> PHY_STATUS_TIMEOUT_US);
> if (ret)
> - DRM_DEBUG_DRIVER("failed to wait phy clk lane stop state\n");
> + DRM_DEBUG_DRIVER("failed to wait phy stop state\n");
> }
>
> static void dw_mipi_dsi_clear_err(struct dw_mipi_dsi *dsi)

--
Regards,

Laurent Pinchart