Message ID | 20191011133939.16551-1-jeffrey.l.hugo@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] drm/msm/dsi: Implement reset correctly | expand |
On Fri, Oct 11, 2019 at 06:39:39AM -0700, Jeffrey Hugo wrote: > On msm8998, vblank timeouts are observed because the DSI controller is not > reset properly, which ends up stalling the MDP. This is because the reset > logic is not correct per the hardware documentation. > > The documentation states that after asserting reset, software should wait > some time (no indication of how long), or poll the status register until it > returns 0 before deasserting reset. > > wmb() is insufficient for this purpose since it just ensures ordering, not > timing between writes. Since asserting and deasserting reset occurs on the > same register, ordering is already guaranteed by the architecture, making > the wmb extraneous. > > Since we would define a timeout for polling the status register to avoid a > possible infinite loop, lets just use a static delay of 20 ms, since 16.666 > ms is the time available to process one frame at 60 fps. > > Fixes: a689554ba6ed (drm/msm: Initial add DSI connector support) > Signed-off-by: Jeffrey Hugo <jeffrey.l.hugo@gmail.com> Pushed to drm-misc-fixes for 5.4 Thanks! Sean > Reviewed-by: Sean Paul <sean@poorly.run> > --- > > v2: > -make a DEFINE for the delay > > drivers/gpu/drm/msm/dsi/dsi_host.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 663ff9f4fac9..9a81705301c6 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -26,6 +26,8 @@ > #include "dsi_cfg.h" > #include "msm_kms.h" > > +#define RESET_DELAY 20 > + > static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) > { > u32 ver; > @@ -986,7 +988,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host) > wmb(); /* clocks need to be enabled before reset */ > > dsi_write(msm_host, REG_DSI_RESET, 1); > - wmb(); /* make sure reset happen */ > + msleep(RESET_DELAY); /* make sure reset happen */ > dsi_write(msm_host, REG_DSI_RESET, 0); > } > > @@ -1396,7 +1398,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) > > /* dsi controller can only be reset while clocks are running */ > dsi_write(msm_host, REG_DSI_RESET, 1); > - wmb(); /* make sure reset happen */ > + msleep(RESET_DELAY); /* make sure reset happen */ > dsi_write(msm_host, REG_DSI_RESET, 0); > wmb(); /* controller out of reset */ > dsi_write(msm_host, REG_DSI_CTRL, data0); > -- > 2.17.1 >
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 663ff9f4fac9..9a81705301c6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -26,6 +26,8 @@ #include "dsi_cfg.h" #include "msm_kms.h" +#define RESET_DELAY 20 + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { u32 ver; @@ -986,7 +988,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host) wmb(); /* clocks need to be enabled before reset */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(RESET_DELAY); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); } @@ -1396,7 +1398,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) /* dsi controller can only be reset while clocks are running */ dsi_write(msm_host, REG_DSI_RESET, 1); - wmb(); /* make sure reset happen */ + msleep(RESET_DELAY); /* make sure reset happen */ dsi_write(msm_host, REG_DSI_RESET, 0); wmb(); /* controller out of reset */ dsi_write(msm_host, REG_DSI_CTRL, data0);