diff options
author | ankishore <ankishore@nvidia.com> | 2011-05-18 11:18:13 +0530 |
---|---|---|
committer | Niket Sirsi <nsirsi@nvidia.com> | 2011-05-23 17:28:01 -0700 |
commit | df49f87271b01240c95aca925c6b13a549336967 (patch) | |
tree | 2e7f4eda52964f0e53111bdf5ebaf8f830ba82f8 /drivers/video | |
parent | 746353ff117f42830a5ff48d792cf0e0ea06d51e (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')
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 59 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi_regs.h | 6 |
2 files changed, 60 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; } diff --git a/drivers/video/tegra/dc/dsi_regs.h b/drivers/video/tegra/dc/dsi_regs.h index 7625f93c40d3..1f7aba6958d4 100644 --- a/drivers/video/tegra/dc/dsi_regs.h +++ b/drivers/video/tegra/dc/dsi_regs.h @@ -23,7 +23,13 @@ enum { }; /* These are word offsets from base (not byte offsets) */ +enum { + OP_DONE = 1, +}; #define DSI_INCR_SYNCPT 0x00 +#define DSI_INCR_SYNCPT_COND(x) (((x) & 0xff) << 8) +#define DSI_INCR_SYNCPT_INDX(x) (((x) & 0xff) << 0) + #define DSI_INCR_SYNCPT_CNTRL 0x01 #define DSI_INCR_SYNCPT_ERROR 0x02 #define DSI_CTXSW 0x08 |