summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tegra/dsi.c
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-11-24 16:29:40 +0100
committerThierry Reding <treding@nvidia.com>2015-01-27 10:14:39 +0100
commit92f0e073ed213a1af673a9ee414339feb9738809 (patch)
treed5513b8ee708a285e20b78a691af238f65a8a45b /drivers/gpu/drm/tegra/dsi.c
parent9c0b4ca1123e5b05daeabaa1879ff1fcebd5f9e1 (diff)
drm/tegra: dsi: Soft-reset controller on ->disable
This reset is necessary to properly clean up the internal state of the controller. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dsi.c')
-rw-r--r--drivers/gpu/drm/tegra/dsi.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index e967ae1d6ca6..60b802205546 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -724,6 +724,30 @@ static void tegra_dsi_disable(struct tegra_dsi *dsi)
usleep_range(5000, 10000);
}
+static void tegra_dsi_soft_reset(struct tegra_dsi *dsi)
+{
+ u32 value;
+
+ value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
+ value &= ~DSI_POWER_CONTROL_ENABLE;
+ tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
+
+ usleep_range(300, 1000);
+
+ value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
+ value |= DSI_POWER_CONTROL_ENABLE;
+ tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);
+
+ usleep_range(300, 1000);
+
+ value = tegra_dsi_readl(dsi, DSI_TRIGGER);
+ if (value)
+ tegra_dsi_writel(dsi, 0, DSI_TRIGGER);
+
+ if (dsi->slave)
+ tegra_dsi_soft_reset(dsi->slave);
+}
+
static int tegra_output_dsi_disable(struct tegra_output *output)
{
struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
@@ -762,6 +786,7 @@ static int tegra_output_dsi_disable(struct tegra_output *output)
if (err < 0)
dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err);
+ tegra_dsi_soft_reset(dsi);
tegra_dsi_disable(dsi);
dsi->enabled = false;