diff options
author | Animesh Kishore <ankishore@nvidia.com> | 2011-12-23 11:55:10 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-30 10:36:23 +0530 |
commit | 1ecbd442fa5cee860cc4b241fc436ced8394024f (patch) | |
tree | 3f350560813ffb661cc560158981ed5dd549edd6 | |
parent | 14fe2f9b89b08da4ac7c65b3d751c33a96fe52b7 (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.c | 4 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 55 |
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) |