summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Huang <kevinh@nvidia.com>2011-07-27 00:53:35 -0700
committerRyan Wong <ryanw@nvidia.com>2011-08-10 18:37:32 -0700
commit05d46c545304fd7b023123d64c0043c65d3c842a (patch)
treec02dc695f12445c84d3f4f2a1baef93d94d6317a
parent0a7255bd9124cedf7522abda04b9381cb5dfcfbb (diff)
video: tegra: overlay: Modified overlay flipping for DSI one-shot mode.
Change-Id: I547458d0c20d0197c1134e689d0ee98776ab28e8 Reviewed-on: http://git-master/r/46501 Reviewed-by: Karan Jhavar <kjhavar@nvidia.com> Tested-by: Karan Jhavar <kjhavar@nvidia.com> Reviewed-by: Ryan Wong <ryanw@nvidia.com> Tested-by: Ryan Wong <ryanw@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/dc.c159
-rw-r--r--drivers/video/tegra/dc/overlay.c3
2 files changed, 106 insertions, 56 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 7505eef9da90..8a63e49067e3 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -1762,80 +1762,129 @@ static irqreturn_t tegra_dc_irq(int irq, void *ptr)
if (status & WIN_C_UF_INT)
dc->stats.underflows_c++;
}
+ if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE) {
+ int completed = 0;
+ int dirty = 0;
+ if (status & V_BLANK_INT) {
+ /* Schedule any additional bottom-half vblank actvities. */
+ schedule_work(&dc->vblank_work);
+
+ /* Mark the vblank as complete. */
+ complete(&dc->vblank_complete);
+
+ val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
+ for (i = 0; i < DC_N_WINDOWS; i++) {
+ if (!(val & (WIN_A_UPDATE << i))) {
+ dc->windows[i].dirty = 0;
+ completed = 1;
+ } else {
+ dirty = 1;
+ }
+ }
+ wake_up(&dc->wq);
+ }
- if (status & V_BLANK_INT) {
- int i;
-
- /* Check for any underflow reset conditions */
- for (i = 0; i< DC_N_WINDOWS; i++) {
- if (dc->underflow_mask & (WIN_A_UF_INT <<i)) {
- dc->windows[i].underflows++;
+ if (status & FRAME_END_INT) {
+ int i;
+ /* Check for any underflow reset conditions */
+ for (i = 0; i< DC_N_WINDOWS; i++) {
+ if (dc->underflow_mask & (WIN_A_UF_INT <<i)) {
+ dc->windows[i].underflows++;
+
+ #ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ if (dc->windows[i].underflows > 4)
+ schedule_work(&dc->reset_work);
+ #endif
+ } else {
+ dc->windows[i].underflows = 0;
+ }
+ }
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
- if (dc->windows[i].underflows > 4)
- schedule_work(&dc->reset_work);
-#endif
- } else {
- dc->windows[i].underflows = 0;
+ if (!dc->underflow_mask) {
+ /* If we have no underflow to check, go ahead
+ and disable the interrupt */
+ val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
+ val &= ~FRAME_END_INT;
+ tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
}
- }
- if (!dc->underflow_mask) {
- /* If we have no underflow to check, go ahead
- and disable the interrupt */
- val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
- val &= ~V_BLANK_INT;
- tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
+ /* Clear the underflow mask now that we've checked it. */
+ dc->underflow_mask = 0;
}
+ } else {
+ if (status & V_BLANK_INT) {
+ int i;
+
+ /* Check for any underflow reset conditions */
+ for (i = 0; i< DC_N_WINDOWS; i++) {
+ if (dc->underflow_mask & (WIN_A_UF_INT <<i)) {
+ dc->windows[i].underflows++;
+
+ #ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ if (dc->windows[i].underflows > 4)
+ schedule_work(&dc->reset_work);
+ #endif
+ } else {
+ dc->windows[i].underflows = 0;
+ }
+ }
- /* Clear the underflow mask now that we've checked it. */
- dc->underflow_mask = 0;
-
- /* Schedule any additional bottom-half vblank actvities. */
- schedule_work(&dc->vblank_work);
+ if (!dc->underflow_mask) {
+ /* If we have no underflow to check, go ahead
+ and disable the interrupt */
+ val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
+ val &= ~V_BLANK_INT;
+ tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
+ }
- /* Mark the vblank as complete. */
- complete(&dc->vblank_complete);
- }
+ /* Clear the underflow mask now that we've checked it. */
+ dc->underflow_mask = 0;
- if (status & FRAME_END_INT) {
- int completed = 0;
- int dirty = 0;
+ /* Schedule any additional bottom-half vblank actvities. */
+ schedule_work(&dc->vblank_work);
- val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
- for (i = 0; i < DC_N_WINDOWS; i++) {
- if (!(val & (WIN_A_UPDATE << i))) {
- dc->windows[i].dirty = 0;
- completed = 1;
- } else {
- dirty = 1;
- }
+ /* Mark the vblank as complete. */
+ complete(&dc->vblank_complete);
}
- if (!dirty) {
- val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
- val &= ~FRAME_END_INT;
- tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
- }
+ if (status & FRAME_END_INT) {
+ int completed = 0;
+ int dirty = 0;
+
+ val = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
+ for (i = 0; i < DC_N_WINDOWS; i++) {
+ if (!(val & (WIN_A_UPDATE << i))) {
+ dc->windows[i].dirty = 0;
+ completed = 1;
+ } else {
+ dirty = 1;
+ }
+ }
- if (completed) {
if (!dirty) {
- /* With the last completed window, go ahead
- and enable the vblank interrupt for nvsd. */
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;
- tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
}
- /* Wake up the workqueue regardless. */
- wake_up(&dc->wq);
+ if (completed) {
+ if (!dirty) {
+ /* With the last completed window, go ahead
+ and enable the vblank interrupt for nvsd. */
+ val = tegra_dc_readl(dc, DC_CMD_INT_ENABLE);
+ val |= V_BLANK_INT;
+ tegra_dc_writel(dc, val, DC_CMD_INT_ENABLE);
+
+ val = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+ val |= V_BLANK_INT;
+ tegra_dc_writel(dc, val, DC_CMD_INT_MASK);
+ }
+
+ /* Wake up the workqueue regardless. */
+ wake_up(&dc->wq);
+ }
}
}
-
return IRQ_HANDLED;
#else /* CONFIG_TEGRA_SILICON_PLATFORM */
return IRQ_NONE;
diff --git a/drivers/video/tegra/dc/overlay.c b/drivers/video/tegra/dc/overlay.c
index 7879100be8e1..83191a40b8af 100644
--- a/drivers/video/tegra/dc/overlay.c
+++ b/drivers/video/tegra/dc/overlay.c
@@ -318,7 +318,7 @@ static void tegra_overlay_flip_worker(struct work_struct *work)
tegra_dc_sync_windows(wins, nr_win);
}
- tegra_dc_incr_syncpt_min(overlay->dc, data->syncpt_max);
+ tegra_dc_incr_syncpt_min(overlay->dc, data->syncpt_max);
/* unpin and deref previous front buffers */
for (i = 0; i < nr_unpin; i++) {
@@ -779,5 +779,6 @@ void tegra_overlay_disable(struct tegra_overlay_info *overlay_info)
{
mutex_lock(&tegra_flip_lock);
flush_workqueue(overlay_info->flip_wq);
+
mutex_unlock(&tegra_flip_lock);
}