diff options
author | Animesh Kishore <ankishore@nvidia.com> | 2011-12-23 01:25:10 -0500 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:02:00 -0400 |
commit | 16723def517bfc2bc3d05ad0bab75cd07f0ea25a (patch) | |
tree | 9166dbbf2373b185f9c34a0eb18f635405230a0e /drivers/video/tegra/dc/dsi.c | |
parent | e12abc4123676faa6dafd5567d546dea39fa2e51 (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>
Rebase-Id: Rb7fdbfad3a56b26763afd2ac2f47d15267bf314f
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index 92a77e313..613ee8ea2 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c | |||
@@ -841,14 +841,15 @@ static void tegra_dsi_set_pkt_seq(struct tegra_dc *dc, | |||
841 | static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc, | 841 | static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc, |
842 | struct tegra_dc_dsi_data *dsi) | 842 | struct tegra_dc_dsi_data *dsi) |
843 | { | 843 | { |
844 | tegra_dc_writel(dc, DISP_CTRL_MODE_STOP, DC_CMD_DISPLAY_COMMAND); | ||
844 | tegra_dc_writel(dc, 0, DC_DISP_DISP_WIN_OPTIONS); | 845 | tegra_dc_writel(dc, 0, DC_DISP_DISP_WIN_OPTIONS); |
845 | tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); | 846 | tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL); |
846 | tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); | 847 | tegra_dc_writel(dc, GENERAL_ACT_REQ , DC_CMD_STATE_CONTROL); |
847 | 848 | ||
848 | dsi->status.dc_stream = DSI_DC_STREAM_DISABLE; | 849 | dsi->status.dc_stream = DSI_DC_STREAM_DISABLE; |
849 | } | 850 | } |
850 | 851 | ||
851 | void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, | 852 | static void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, |
852 | struct tegra_dc_dsi_data *dsi) | 853 | struct tegra_dc_dsi_data *dsi) |
853 | { | 854 | { |
854 | int val; | 855 | int val; |
@@ -863,10 +864,13 @@ void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, | |||
863 | val |= FRAME_END_INT; | 864 | val |= FRAME_END_INT; |
864 | tegra_dc_writel(dc, val, DC_CMD_INT_MASK); | 865 | tegra_dc_writel(dc, val, DC_CMD_INT_MASK); |
865 | 866 | ||
866 | /* wait for frame_end completion */ | 867 | /* wait for frame_end completion. |
868 | * timeout is 2 frame duration to accomodate for | ||
869 | * internal delay. | ||
870 | */ | ||
867 | timeout = wait_for_completion_interruptible_timeout( | 871 | timeout = wait_for_completion_interruptible_timeout( |
868 | &dc->frame_end_complete, | 872 | &dc->frame_end_complete, |
869 | msecs_to_jiffies(frame_period)); | 873 | msecs_to_jiffies(2 * frame_period)); |
870 | 874 | ||
871 | /* disable frame end interrupt */ | 875 | /* disable frame end interrupt */ |
872 | val = tegra_dc_readl(dc, DC_CMD_INT_MASK); | 876 | val = tegra_dc_readl(dc, DC_CMD_INT_MASK); |
@@ -1004,7 +1008,7 @@ static void tegra_dsi_hs_clk_out_disable(struct tegra_dc *dc, | |||
1004 | u32 val; | 1008 | u32 val; |
1005 | 1009 | ||
1006 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) | 1010 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) |
1007 | tegra_dsi_stop_dc_stream(dc, dsi); | 1011 | tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi); |
1008 | 1012 | ||
1009 | val = tegra_dsi_readl(dsi, DSI_CONTROL); | 1013 | val = tegra_dsi_readl(dsi, DSI_CONTROL); |
1010 | val &= ~DSI_CONTROL_HS_CLK_CTRL(1); | 1014 | val &= ~DSI_CONTROL_HS_CLK_CTRL(1); |
@@ -1122,11 +1126,13 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) | |||
1122 | static int tegra_dsi_init_hw(struct tegra_dc *dc, | 1126 | static int tegra_dsi_init_hw(struct tegra_dc *dc, |
1123 | struct tegra_dc_dsi_data *dsi) | 1127 | struct tegra_dc_dsi_data *dsi) |
1124 | { | 1128 | { |
1125 | u32 val; | ||
1126 | u32 i; | 1129 | u32 i; |
1127 | 1130 | ||
1128 | val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE); | 1131 | tegra_dsi_writel(dsi, |
1129 | tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL); | 1132 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE), |
1133 | DSI_POWER_CONTROL); | ||
1134 | /* stabilization delay */ | ||
1135 | udelay(300); | ||
1130 | 1136 | ||
1131 | tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz); | 1137 | tegra_dsi_set_dsi_clk(dc, dsi, dsi->target_lp_clk_khz); |
1132 | if (dsi->info.dsi_instance) { | 1138 | if (dsi->info.dsi_instance) { |
@@ -1137,7 +1143,7 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, | |||
1137 | tegra_dsi_set_phy_timing(dsi); | 1143 | tegra_dsi_set_phy_timing(dsi); |
1138 | 1144 | ||
1139 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) | 1145 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) |
1140 | tegra_dsi_stop_dc_stream(dc, dsi); | 1146 | tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi); |
1141 | 1147 | ||
1142 | /* Initializing DSI registers */ | 1148 | /* Initializing DSI registers */ |
1143 | for (i = 0; i < ARRAY_SIZE(init_reg); i++) | 1149 | for (i = 0; i < ARRAY_SIZE(init_reg); i++) |
@@ -1147,11 +1153,11 @@ static int tegra_dsi_init_hw(struct tegra_dc *dc, | |||
1147 | 1153 | ||
1148 | tegra_dsi_pad_calibration(dsi); | 1154 | tegra_dsi_pad_calibration(dsi); |
1149 | 1155 | ||
1150 | val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE); | 1156 | tegra_dsi_writel(dsi, |
1151 | tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL); | 1157 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE), |
1152 | 1158 | DSI_POWER_CONTROL); | |
1153 | while (tegra_dsi_readl(dsi, DSI_POWER_CONTROL) != val) | 1159 | /* stabilization delay */ |
1154 | tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL); | 1160 | udelay(300); |
1155 | 1161 | ||
1156 | dsi->status.init = DSI_MODULE_INIT; | 1162 | dsi->status.init = DSI_MODULE_INIT; |
1157 | dsi->status.lphs = DSI_LPHS_NOT_INIT; | 1163 | dsi->status.lphs = DSI_LPHS_NOT_INIT; |
@@ -1331,18 +1337,17 @@ static void tegra_dsi_reset_underflow_overflow | |||
1331 | 1337 | ||
1332 | static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) | 1338 | static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) |
1333 | { | 1339 | { |
1334 | u32 val; | ||
1335 | |||
1336 | tegra_dsi_writel(dsi, | 1340 | tegra_dsi_writel(dsi, |
1337 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE), | 1341 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_DISABLE), |
1338 | DSI_POWER_CONTROL); | 1342 | DSI_POWER_CONTROL); |
1339 | mdelay(1); | 1343 | /* stabilization delay */ |
1340 | 1344 | udelay(300); | |
1341 | val = DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE); | ||
1342 | tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL); | ||
1343 | 1345 | ||
1344 | while (tegra_dsi_readl(dsi, DSI_POWER_CONTROL) != val) | 1346 | tegra_dsi_writel(dsi, |
1345 | tegra_dsi_writel(dsi, val, DSI_POWER_CONTROL); | 1347 | DSI_POWER_CONTROL_LEG_DSI_ENABLE(TEGRA_DSI_ENABLE), |
1348 | DSI_POWER_CONTROL); | ||
1349 | /* stabilization delay */ | ||
1350 | udelay(300); | ||
1346 | } | 1351 | } |
1347 | 1352 | ||
1348 | static void tegra_dsi_reset_read_count(struct tegra_dc_dsi_data *dsi) | 1353 | static void tegra_dsi_reset_read_count(struct tegra_dc_dsi_data *dsi) |
@@ -2092,7 +2097,7 @@ static void tegra_dc_dsi_enable(struct tegra_dc *dc) | |||
2092 | * to avoid visible glitches on panel during transition | 2097 | * to avoid visible glitches on panel during transition |
2093 | * from bootloader to kernel driver | 2098 | * from bootloader to kernel driver |
2094 | */ | 2099 | */ |
2095 | tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi); | 2100 | tegra_dsi_stop_dc_stream(dc, dsi); |
2096 | 2101 | ||
2097 | if (dsi->enabled) { | 2102 | if (dsi->enabled) { |
2098 | if (dsi->ulpm) { | 2103 | if (dsi->ulpm) { |
@@ -2449,7 +2454,7 @@ static void tegra_dc_dsi_destroy(struct tegra_dc *dc) | |||
2449 | 2454 | ||
2450 | /* Disable dc stream */ | 2455 | /* Disable dc stream */ |
2451 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) | 2456 | if (dsi->status.dc_stream == DSI_DC_STREAM_ENABLE) |
2452 | tegra_dsi_stop_dc_stream(dc, dsi); | 2457 | tegra_dsi_stop_dc_stream_at_frame_end(dc, dsi); |
2453 | 2458 | ||
2454 | /* Disable dsi phy clock */ | 2459 | /* Disable dsi phy clock */ |
2455 | if (dsi->status.clk_out == DSI_PHYCLK_OUT_EN) | 2460 | if (dsi->status.clk_out == DSI_PHYCLK_OUT_EN) |