diff options
author | Animesh Kishore <ankishore@nvidia.com> | 2012-03-01 10:54:19 -0500 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2015-03-18 15:02:09 -0400 |
commit | 42f51a40bd2eb5afe0d0c5cf570f9e5ee157a24b (patch) | |
tree | 19d398ac5821cf318fb50cd9e81e40bd33761449 /drivers/video/tegra/dc/dsi.c | |
parent | 770174511b9bed06adb3cd27bacf14ad4cc474da (diff) |
video: tegra: dsi: Fix syncpt hang during early suspend cycle
Fixing dsi syncpt hang issue after multiple cycles of
early suspend-late resume.
Bug 943096
Change-Id: Iefc0530a6e514b7733819dd1df35cde8f5c3dd47
Signed-off-by: Animesh Kishore <ankishore@nvidia.com>
Reviewed-on: http://git-master/r/86946
Reviewed-by: Sang-Hun Lee <sanlee@nvidia.com>
Tested-by: Sang-Hun Lee <sanlee@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com>
Rebase-Id: Rbbb2293678d63752421db3c1896583290eaf566a
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index 42bec9f69..fb197c9bb 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c | |||
@@ -897,8 +897,10 @@ static void tegra_dsi_set_sol_delay(struct tegra_dc *dc, | |||
897 | if (dsi->info.video_burst_mode == TEGRA_DSI_VIDEO_NONE_BURST_MODE || | 897 | if (dsi->info.video_burst_mode == TEGRA_DSI_VIDEO_NONE_BURST_MODE || |
898 | dsi->info.video_burst_mode == | 898 | dsi->info.video_burst_mode == |
899 | TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END) { | 899 | TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END) { |
900 | sol_delay = NUMOF_BIT_PER_BYTE * dsi->pixel_scaler_mul / | 900 | #define VIDEO_FIFO_LATENCY_PIXEL_CLK 8 |
901 | (dsi->pixel_scaler_div * dsi->info.n_data_lanes); | 901 | sol_delay = VIDEO_FIFO_LATENCY_PIXEL_CLK * |
902 | dsi->pixel_scaler_mul / dsi->pixel_scaler_div; | ||
903 | #undef VIDEO_FIFO_LATENCY_PIXEL_CLK | ||
902 | dsi->status.clk_burst = DSI_CLK_BURST_NONE_BURST; | 904 | dsi->status.clk_burst = DSI_CLK_BURST_NONE_BURST; |
903 | } else { | 905 | } else { |
904 | sol_delay = tegra_dsi_sol_delay_burst(dc, dsi); | 906 | sol_delay = tegra_dsi_sol_delay_burst(dc, dsi); |
@@ -1091,6 +1093,27 @@ static void tegra_dsi_set_pkt_seq(struct tegra_dc *dc, | |||
1091 | } | 1093 | } |
1092 | } | 1094 | } |
1093 | 1095 | ||
1096 | static void tegra_dsi_reset_underflow_overflow | ||
1097 | (struct tegra_dc_dsi_data *dsi) | ||
1098 | { | ||
1099 | u32 val; | ||
1100 | |||
1101 | val = tegra_dsi_readl(dsi, DSI_STATUS); | ||
1102 | val &= (DSI_STATUS_LB_OVERFLOW(0x1) | DSI_STATUS_LB_UNDERFLOW(0x1)); | ||
1103 | if (val) { | ||
1104 | if (val & DSI_STATUS_LB_OVERFLOW(0x1)) | ||
1105 | dev_warn(&dsi->dc->ndev->dev, | ||
1106 | "dsi: video fifo overflow. Resetting flag\n"); | ||
1107 | if (val & DSI_STATUS_LB_UNDERFLOW(0x1)) | ||
1108 | dev_warn(&dsi->dc->ndev->dev, | ||
1109 | "dsi: video fifo underflow. Resetting flag\n"); | ||
1110 | val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL); | ||
1111 | val |= DSI_HOST_CONTROL_FIFO_STAT_RESET(0x1); | ||
1112 | tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL); | ||
1113 | udelay(5); | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1094 | static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc, | 1117 | static void tegra_dsi_stop_dc_stream(struct tegra_dc *dc, |
1095 | struct tegra_dc_dsi_data *dsi) | 1118 | struct tegra_dc_dsi_data *dsi) |
1096 | { | 1119 | { |
@@ -1133,6 +1156,8 @@ static void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, | |||
1133 | if (timeout == 0) | 1156 | if (timeout == 0) |
1134 | dev_warn(&dc->ndev->dev, | 1157 | dev_warn(&dc->ndev->dev, |
1135 | "DC doesn't stop at end of frame.\n"); | 1158 | "DC doesn't stop at end of frame.\n"); |
1159 | |||
1160 | tegra_dsi_reset_underflow_overflow(dsi); | ||
1136 | } | 1161 | } |
1137 | 1162 | ||
1138 | static void tegra_dsi_start_dc_stream(struct tegra_dc *dc, | 1163 | static void tegra_dsi_start_dc_stream(struct tegra_dc *dc, |
@@ -1586,22 +1611,6 @@ fail: | |||
1586 | return (err < 0 ? true : false); | 1611 | return (err < 0 ? true : false); |
1587 | } | 1612 | } |
1588 | 1613 | ||
1589 | static void tegra_dsi_reset_underflow_overflow | ||
1590 | (struct tegra_dc_dsi_data *dsi) | ||
1591 | { | ||
1592 | u32 val; | ||
1593 | |||
1594 | val = tegra_dsi_readl(dsi, DSI_STATUS); | ||
1595 | val &= (DSI_STATUS_LB_OVERFLOW(0x1) | DSI_STATUS_LB_UNDERFLOW(0x1)); | ||
1596 | if (val) { | ||
1597 | dev_warn(&dsi->dc->ndev->dev, "Reset overflow/underflow\n"); | ||
1598 | val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL); | ||
1599 | val |= DSI_HOST_CONTROL_FIFO_STAT_RESET(0x1); | ||
1600 | tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL); | ||
1601 | ndelay(200); | ||
1602 | } | ||
1603 | } | ||
1604 | |||
1605 | static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) | 1614 | static void tegra_dsi_soft_reset(struct tegra_dc_dsi_data *dsi) |
1606 | { | 1615 | { |
1607 | tegra_dsi_writel(dsi, | 1616 | tegra_dsi_writel(dsi, |
@@ -1707,8 +1716,6 @@ static struct dsi_status *tegra_dsi_prepare_host_transmission( | |||
1707 | } | 1716 | } |
1708 | } | 1717 | } |
1709 | 1718 | ||
1710 | tegra_dsi_reset_underflow_overflow(dsi); | ||
1711 | |||
1712 | if (lp_op == DSI_LP_OP_READ) | 1719 | if (lp_op == DSI_LP_OP_READ) |
1713 | tegra_dsi_reset_read_count(dsi); | 1720 | tegra_dsi_reset_read_count(dsi); |
1714 | 1721 | ||