Message ID | 1457455195-1938-4-git-send-email-sre@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 08/03/16 18:39, Sebastian Reichel wrote: > From: Tomi Valkeinen <tomi.valkeinen@ti.com> > > The Nokia N950's bootloader leaves the DSI module > in a non-working state. Work around this by resetting > the DSI module before using it. > > Signed-off-By: Tomi Valkeinen <tomi.valkeinen@ti.com> > Reviewed-By: Sebastian Reichel <sre@kernel.org> > Tested-By: Sebastian Reichel <sre@kernel.org> > --- > drivers/gpu/drm/omapdrm/dss/dsi.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c > index 43be4b2a7b05..363a61e6aca7 100644 > --- a/drivers/gpu/drm/omapdrm/dss/dsi.c > +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c > @@ -5274,6 +5274,28 @@ static int dsi_init_pll_data(struct platform_device *dsidev) > return 0; > } > > +static int _dsi_wait_reset(struct platform_device *dsidev) > +{ > + int t = 0; > + > + while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) { > + if (++t > 5) { > + DSSERR("soft reset failed\n"); > + return -ENODEV; > + } > + udelay(1); > + } > + > + return 0; > +} > + > +static int _dsi_reset(struct platform_device *dsidev) > +{ > + /* Soft reset */ > + dsi_write_reg(dsidev, DSI_SYSCONFIG, 0x2); > + return _dsi_wait_reset(dsidev); > +} > + > /* DSI1 HW IP initialisation */ > static int dsi_bind(struct device *dev, struct device *master, void *data) > { > @@ -5432,6 +5454,8 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) > if (r) > goto err_runtime_get; > > + _dsi_reset(dsidev); > + > rev = dsi_read_reg(dsidev, DSI_REVISION); > dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", > FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); > This is good as a prototype, but unfortunately we're not supposed to reset the IP from the driver. I haven't followed if there's a proper reset framework yet available, but if not, I think we should do the reset at the platform code at boot time. Which actually makes me wonder... We should be doing that reset already there, in mach-omap2/display.c. I wonder why that's not working... Tomi
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 43be4b2a7b05..363a61e6aca7 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5274,6 +5274,28 @@ static int dsi_init_pll_data(struct platform_device *dsidev) return 0; } +static int _dsi_wait_reset(struct platform_device *dsidev) +{ + int t = 0; + + while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) { + if (++t > 5) { + DSSERR("soft reset failed\n"); + return -ENODEV; + } + udelay(1); + } + + return 0; +} + +static int _dsi_reset(struct platform_device *dsidev) +{ + /* Soft reset */ + dsi_write_reg(dsidev, DSI_SYSCONFIG, 0x2); + return _dsi_wait_reset(dsidev); +} + /* DSI1 HW IP initialisation */ static int dsi_bind(struct device *dev, struct device *master, void *data) { @@ -5432,6 +5454,8 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) if (r) goto err_runtime_get; + _dsi_reset(dsidev); + rev = dsi_read_reg(dsidev, DSI_REVISION); dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));