summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorankishore <ankishore@nvidia.com>2011-05-18 11:18:13 +0530
committerNiket Sirsi <nsirsi@nvidia.com>2011-05-23 17:28:01 -0700
commitdf49f87271b01240c95aca925c6b13a549336967 (patch)
tree2e7f4eda52964f0e53111bdf5ebaf8f830ba82f8 /drivers/video/tegra/dc/dsi.c
parent746353ff117f42830a5ff48d792cf0e0ea06d51e (diff)
video: dsi: tegra: Support for sync point
Adding support for sync point in dsi kernel driver Bug 807903 Change-Id: Id0520be9896bdb7f96718e38d548bc2f7e52fa3e Reviewed-on: http://git-master/r/31939 Reviewed-by: Niket Sirsi <nsirsi@nvidia.com> Tested-by: Niket Sirsi <nsirsi@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index e337328c611b..b73c002e2b67 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -38,7 +38,7 @@
#include "dsi_regs.h"
#include "dsi.h"
-#define DSI_USE_SYNC_POINTS 0
+#define DSI_USE_SYNC_POINTS 1
#define DSI_STOP_DC_DURATION_MSEC 1000
@@ -119,6 +119,9 @@ struct tegra_dc_dsi_data {
u32 target_hs_clk_khz;
u32 target_lp_clk_khz;
+ u32 syncpt_id;
+ u32 syncpt_val;
+
u16 current_bit_clk_ns;
u32 current_dsi_clk_khz;
@@ -386,6 +389,10 @@ static void tegra_dsi_init_sw(struct tegra_dc *dc,
dsi->target_lp_clk_khz = tegra_dsi_get_lp_clk_rate(dsi);
dsi->target_hs_clk_khz = tegra_dsi_get_hs_clk_rate(dsi);
+#if DSI_USE_SYNC_POINTS
+ dsi->syncpt_id = NVSYNCPT_DSI;
+#endif
+
/*
* Force video clock to be continuous mode if
* enable_hs_clock_on_lp_cmd_mode is set
@@ -1121,17 +1128,37 @@ static bool tegra_dsi_is_controller_idle(struct tegra_dc_dsi_data *dsi)
static bool tegra_dsi_host_trigger(struct tegra_dc_dsi_data *dsi)
{
bool status;
+ u32 val;
status = false;
+
if (tegra_dsi_readl(dsi, DSI_TRIGGER))
goto fail;
- tegra_dsi_writel(dsi, DSI_TRIGGER_HOST_TRIGGER(TEGRA_DSI_ENABLE),
- DSI_TRIGGER);
-
#if DSI_USE_SYNC_POINTS
- /* TODO: Implement sync point */
+ val = DSI_INCR_SYNCPT_COND(OP_DONE) |
+ DSI_INCR_SYNCPT_INDX(dsi->syncpt_id);
+ tegra_dsi_writel(dsi, val, DSI_INCR_SYNCPT);
+
+ dsi->syncpt_val = nvhost_syncpt_read(
+ &dsi->dc->ndev->host->syncpt, dsi->syncpt_id);
+
+ tegra_dsi_writel(dsi,
+ DSI_TRIGGER_HOST_TRIGGER(TEGRA_DSI_ENABLE), DSI_TRIGGER);
+
+ /* TODO: Use interrupt rather than polling */
+ if (nvhost_syncpt_wait(&dsi->dc->ndev->host->syncpt,
+ dsi->syncpt_id, dsi->syncpt_val + 1) < 0) {
+ printk(KERN_ERR "DSI sync point failure\n");
+ status = false;
+ goto fail;
+ }
+
+ (dsi->syncpt_val)++;
+ status = true;
#else
+ tegra_dsi_writel(dsi,
+ DSI_TRIGGER_HOST_TRIGGER(TEGRA_DSI_ENABLE), DSI_TRIGGER);
status = tegra_dsi_is_controller_idle(dsi);
#endif
@@ -1266,6 +1293,27 @@ static int tegra_dsi_bta(struct tegra_dc_dsi_data *dsi)
poll_time = 0;
err = 0;
+#if DSI_USE_SYNC_POINTS
+ val = DSI_INCR_SYNCPT_COND(OP_DONE) |
+ DSI_INCR_SYNCPT_INDX(dsi->syncpt_id);
+ tegra_dsi_writel(dsi, val, DSI_INCR_SYNCPT);
+
+ /* FIXME: Workaround for nvhost_syncpt_read */
+ dsi->syncpt_val = nvhost_syncpt_update_min(
+ &dsi->dc->ndev->host->syncpt, dsi->syncpt_id);
+
+ val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
+ val |= DSI_HOST_DSI_CONTROL_IMM_BTA(TEGRA_DSI_ENABLE);
+ tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
+
+ /* TODO: Use interrupt rather than polling */
+ err = nvhost_syncpt_wait(&dsi->dc->ndev->host->syncpt,
+ dsi->syncpt_id, dsi->syncpt_val + 1);
+ if (err < 0)
+ printk(KERN_ERR "DSI sync point failure\n");
+ else
+ (dsi->syncpt_val)++;
+#else
val = tegra_dsi_readl(dsi, DSI_HOST_DSI_CONTROL);
val |= DSI_HOST_DSI_CONTROL_IMM_BTA(TEGRA_DSI_ENABLE);
tegra_dsi_writel(dsi, val, DSI_HOST_DSI_CONTROL);
@@ -1280,6 +1328,7 @@ static int tegra_dsi_bta(struct tegra_dc_dsi_data *dsi)
}
if (poll_time > DSI_STATUS_POLLING_DURATION_USEC)
err = -EBUSY;
+#endif
return err;
}