diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 23 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 2 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 19 |
3 files changed, 24 insertions, 20 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index da439b935683..a08cd189234c 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -2061,15 +2061,16 @@ static void tegra_dc_one_shot_irq(struct tegra_dc *dc, unsigned long status) /* Schedule any additional bottom-half vblank actvities. */ schedule_work(&dc->vblank_work); - - /* Mark the vblank as complete. */ - complete(&dc->vblank_complete); - } /* Check underflow at frame end */ - if (status & FRAME_END_INT) + if (status & FRAME_END_INT) { tegra_dc_underflow_handler(dc); + + /* Mark the frame_end as complete. */ + if (completion_done(&dc->frame_end_complete)) + complete(&dc->frame_end_complete); + } } static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status) @@ -2080,13 +2081,15 @@ static void tegra_dc_continuous_irq(struct tegra_dc *dc, unsigned long status) /* Schedule any additional bottom-half vblank actvities. */ schedule_work(&dc->vblank_work); - - /* Mark the vblank as complete. */ - complete(&dc->vblank_complete); } - if (status & FRAME_END_INT) + if (status & FRAME_END_INT) { + /* Mark the frame_end as complete. */ + if (completion_done(&dc->frame_end_complete)) + complete(&dc->frame_end_complete); + tegra_dc_trigger_windows(dc); + } } #endif @@ -2682,7 +2685,7 @@ static int tegra_dc_probe(struct nvhost_device *ndev) dc->enabled = true; mutex_init(&dc->lock); - init_completion(&dc->vblank_complete); + init_completion(&dc->frame_end_complete); init_waitqueue_head(&dc->wq); #ifdef CONFIG_ARCH_TEGRA_2x_SOC INIT_WORK(&dc->reset_work, tegra_dc_reset_worker); diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h index 83f26b8dd543..fcc333fa63d3 100644 --- a/drivers/video/tegra/dc/dc_priv.h +++ b/drivers/video/tegra/dc/dc_priv.h @@ -116,7 +116,7 @@ struct tegra_dc { unsigned long underflow_mask; struct work_struct reset_work; - struct completion vblank_complete; + struct completion frame_end_complete; struct work_struct vblank_work; diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c index b2318f43cebb..2c2cb78d3488 100644 --- a/drivers/video/tegra/dc/dsi.c +++ b/drivers/video/tegra/dc/dsi.c @@ -38,8 +38,7 @@ #include "dsi.h" #define DSI_USE_SYNC_POINTS 1 - -#define DSI_STOP_DC_DURATION_MSEC 1000 +#define S_TO_MS(x) (1000 * (x)) #define DSI_MODULE_NOT_INIT 0x0 #define DSI_MODULE_INIT 0x1 @@ -843,26 +842,28 @@ void tegra_dsi_stop_dc_stream_at_frame_end(struct tegra_dc *dc, { int val; long timeout; + u32 frame_period = DIV_ROUND_UP(S_TO_MS(1), dsi->info.refresh_rate); /* stop dc */ tegra_dsi_stop_dc_stream(dc, dsi); - /* enable vblank interrupt */ + /* enable frame end interrupt */ val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val |= V_BLANK_INT; + val |= FRAME_END_INT; tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); val = tegra_dc_readl(dc, DC_CMD_INT_MASK); - val |= V_BLANK_INT; + val |= FRAME_END_INT; tegra_dc_writel(dc, val, DC_CMD_INT_MASK); - /* wait for vblank completion */ + /* wait for frame_end completion */ timeout = wait_for_completion_interruptible_timeout( - &dc->vblank_complete, DSI_STOP_DC_DURATION_MSEC); + &dc->frame_end_complete, + msecs_to_jiffies(frame_period)); - /* disable vblank interrupt */ + /* disable frame end interrupt */ val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE); - val &= ~V_BLANK_INT; + val &= ~FRAME_END_INT; tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE); if (timeout == 0) |