summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2011-12-23 11:55:10 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-30 10:36:23 +0530
commit1ecbd442fa5cee860cc4b241fc436ced8394024f (patch)
tree3f350560813ffb661cc560158981ed5dd549edd6
parent14fe2f9b89b08da4ac7c65b3d751c33a96fe52b7 (diff)
video: tegra: dc: Fix dc stream random failure to stop
Fix dc stream randomly failing to stop. Add stablization delay during dsi interface reset. Bug 913019 Change-Id: I1cf3013659de75d15cb1ff41b27c63abd953d614 Signed-off-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-on: http://git-master/r/71952 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Pavan Kunapuli <pkunapuli@nvidia.com> Reviewed-by: Krishna Yarlagadda <kyarlagadda@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/dc.c4
-rw-r--r--drivers/video/tegra/dc/dsi.c55
2 files changed, 32 insertions, 27 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 04de0ede49c2..1c0ff2a51bea 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -2064,7 +2064,7 @@ static void tegra_dc_one_shot_irq(struct tegra_dc *dc, unsigned long status)
tegra_dc_underflow_handler(dc);
/* Mark the frame_end as complete. */
- if (completion_done(&dc->frame_end_complete))
+ if (!completion_done(&dc->frame_end_complete))
complete(&dc->frame_end_complete);
}
}
@@ -2081,7 +2081,7 @@ static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status)
if (status & FRAME_END_INT) {
/* Mark the frame_end as complete. */
- if (completion_done(&dc->frame_end_complete))
+ if (!completion_done(&dc->frame_end_complete))
complete(&dc->frame_end_complete);
tegra_dc_trigger_windows(dc);
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 45fde648139f..5ee7671a79fa 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -839,14 +839,15 @@ static void tegra_dsi_set_pkt_seq(struct tegra_dc *dc,
static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc,
struct tegra_dc_dsi_data *dsi)
{
+ tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND);
tegra_dc_writel(dc, 0, DC_DISP_DISP_WIN_OPTIONS);
- tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
- tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ , DC_CMD_STATE_CONTROL);
dsi->status.dc_stream = DSI_DC_STREAM_DISABLE;
}
-void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc,
+static void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc,
struct tegra_dc_dsi_data *dsi)
{
int val;
@@ -861,10 +862,13 @@ void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc,
val |= FRAME_END_INT;
tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
- /* wait for frame_end completion */
+ /* wait for frame_end completion.
+ * timeout is 2 frame duration to accomodate for
+ * internal delay.
+ */
timeout = wait_for_completion_interruptible_timeout(
&dc->frame_end_complete,
- msecs_to_jiffies(frame_period));
+ msecs_to_jiffies(2 * frame_period));
/* disable frame end interrupt */
val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
@@ -1002,7 +1006,7 @@ static void tegra_dsi_hs_clk_out_disable(struct tegra_dc *dc,
u32 val;
if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
- tegra_dsi_stop_dc_stream(dc, dsi);
+ tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
val = tegra_dsi_readl(dsi, DSI_CONTROL);
val &= ~DSI_CONTROL_HS_CLK_CTRL(1);
@@ -1120,11 +1124,13 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi)
static int tegra_dsi_init_hw(struct tegra_dc *dc,
struct tegra_dc_dsi_data *dsi)
{
- u32 val;
u32 i;
- val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE);
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
+ tegra_dsi_writel(dsi,
+ DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE),
+ DSI_POWER_CONTROL);
+ /* stabilization delay */
+ udelay(300);
tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz);
if (dsi->info.dsi_instance) {
@@ -1135,7 +1141,7 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc,
tegra_dsi_set_phy_timing(dsi);
if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
- tegra_dsi_stop_dc_stream(dc, dsi);
+ tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
/* Initializing DSI registers */
for (i = 0; i < ARRAY_SIZE(init_reg); i++)
@@ -1145,11 +1151,11 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc,
tegra_dsi_pad_calibration(dsi);
- val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE);
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
-
- while (tegra_dsi_readl(dsi, DSI_POWER_CONTROL) != val)
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
+ tegra_dsi_writel(dsi,
+ DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE),
+ DSI_POWER_CONTROL);
+ /* stabilization delay */
+ udelay(300);
dsi->status.init = DSI_MODULE_INIT;
dsi->status.lphs = DSI_LPHS_NOT_INIT;
@@ -1329,18 +1335,17 @@ static void tegra_dsi_reset_underflow_overflow
static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi)
{
- u32 val;
-
tegra_dsi_writel(dsi,
DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE),
DSI_POWER_CONTROL);
- mdelay(1);
-
- val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE);
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
+ /* stabilization delay */
+ udelay(300);
- while (tegra_dsi_readl(dsi, DSI_POWER_CONTROL) != val)
- tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL);
+ tegra_dsi_writel(dsi,
+ DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE),
+ DSI_POWER_CONTROL);
+ /* stabilization delay */
+ udelay(300);
}
static void tegra_dsi_reset_read_count(struct tegra_dc_dsi_data *dsi)
@@ -2090,7 +2095,7 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc)
* to avoid visible glitches on panel during transition
* from bootloader to kernel driver
*/
- tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
+ tegra_dsi_stop_dc_stream(dc, dsi);
if (dsi->enabled) {
if (dsi->ulpm) {
@@ -2447,7 +2452,7 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc)
/* Disable dc stream */
if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE)
- tegra_dsi_stop_dc_stream(dc, dsi);
+ tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi);
/* Disable dsi phy clock */
if (dsi->status.clk_out == DSI_PHYCLK_OUT_EN)