summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2011-12-23 01:25:10 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:02:00 -0400
commit16723def517bfc2bc3d05ad0bab75cd07f0ea25a (patch)
tree9166dbbf2373b185f9c34a0eb18f635405230a0e /drivers/video/tegra/dc/dsi.c
parente12abc4123676faa6dafd5567d546dea39fa2e51 (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.c55
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,
841static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc, 841static 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
851void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, 852static 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)
1122static int tegra_dsi_init_hw(struct tegra_dc *dc, 1126static 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
1332static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) 1338static 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
1348static void tegra_dsi_reset_read_count(struct tegra_dc_dsi_data *dsi) 1353static 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)