summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2012-03-13 20:32:41 +0530
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-03-15 09:34:10 -0700
commitde0a72abe36ee351552ee7472ba16ea7bd701cca (patch)
tree02fc352c7f7c55409b0adef9ab5c373a2eeb28e2 /drivers/video/tegra/dc/dsi.c
parent58789b1e6c2cd3163193df26bd0d1e48437e24a7 (diff)
video: tegra: dsi: Add phy timing check for hblank
Horizontal blank must be greater than phy timing for HS transmission. Bug 938043 Change-Id: I5afe68ec04341f7b83c2897c586d4618bd518222 Signed-off-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-on: http://git-master/r/89789 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Jon Mayo <jmayo@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 482493cdeb96..8b64ea6d4888 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -798,6 +798,74 @@ fail:
return err;
}
+static int tegra_dsi_hs_phy_len(struct tegra_dc_dsi_data *dsi,
+ struct dsi_phy_timing_inclk *phy_timing,
+ u32 clk_ns, u8 lphs)
+{
+ u32 hs_t_phy_ns;
+ u32 clk_t_phy_ns;
+ u32 t_phy_ns;
+ u32 h_blank_ns;
+ struct tegra_dc_mode *modes;
+ u32 t_pix_ns;
+ int err = 0;
+
+ if (!(lphs == DSI_LPHS_IN_HS_MODE))
+ goto fail;
+
+ modes = dsi->dc->out->modes;
+ t_pix_ns = clk_ns * BITS_PER_BYTE *
+ dsi->pixel_scaler_mul / dsi->pixel_scaler_div;
+
+ hs_t_phy_ns =
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_tlpx, clk_ns, T_TLPX_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_hsprepare, clk_ns, T_HSPREPARE_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_datzero, clk_ns, T_DATZERO_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_hstrail, clk_ns, T_HSTRAIL_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_hsdexit, clk_ns, T_HSEXIT_HW_INC);
+
+ clk_t_phy_ns =
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_clkpost, clk_ns, T_CLKPOST_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_clktrail, clk_ns, T_CLKTRAIL_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_hsdexit, clk_ns, T_HSEXIT_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_tlpx, clk_ns, T_TLPX_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_clkprepare, clk_ns, T_CLKPREPARE_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_clkzero, clk_ns, T_CLKZERO_HW_INC) +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_clkpre, clk_ns, T_CLKPRE_HW_INC);
+
+ h_blank_ns = t_pix_ns * (modes->h_sync_width + modes->h_back_porch +
+ modes->h_front_porch);
+
+ /* Extra tlpx and byte cycle required by dsi HW */
+ t_phy_ns = dsi->info.n_data_lanes * (hs_t_phy_ns + clk_t_phy_ns +
+ DSI_CONVERT_T_PHY_TO_T_PHY_NS(
+ phy_timing->t_tlpx, clk_ns, T_TLPX_HW_INC) +
+ clk_ns * BITS_PER_BYTE);
+
+ if (h_blank_ns < t_phy_ns) {
+ err = -EINVAL;
+ dev_err(&dsi->dc->ndev->dev,
+ "dsi: Hblank is smaller than HS trans phy timing\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ return err;
+}
+
static int tegra_dsi_constraint_phy_timing(struct tegra_dc_dsi_data *dsi,
struct dsi_phy_timing_inclk *phy_timing,
u32 clk_ns, u8 lphs)
@@ -810,6 +878,12 @@ static int tegra_dsi_constraint_phy_timing(struct tegra_dc_dsi_data *dsi,
goto fail;
}
+ err = tegra_dsi_hs_phy_len(dsi, phy_timing, clk_ns, lphs);
+ if (err < 0) {
+ dev_err(&dsi->dc->ndev->dev, "dsi: Hblank too short\n");
+ goto fail;
+ }
+
/* TODO: add more contraints */
fail:
return err;