summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cheney <acheney@nvidia.com>2012-03-15 14:50:00 -0700
committerSimone Willett <swillett@nvidia.com>2012-03-29 13:38:18 -0700
commitba121123068656e007955d090915c8c94a436fd4 (patch)
tree887b48b897893504229946a176aa12f3294e4f98
parent9471542720db75307e6279f66040bb94b8acf1f9 (diff)
video: tegra: add cursor mode flipping
This change adds a flag to flip windows in cursor mode. Cursor mode will cause flips to be skipped over if there are newer flip requests waiting in the workqueue. Add CURSOR_MODE to caps bitfield. bug 942762 Change-Id: Ib52a0a5565f961cdd9650e4204cd65b86f96fee1 Signed-off-by: Adam Cheney <acheney@nvidia.com> Reviewed-on: http://git-master/r/90418 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Robert Morell <rmorell@nvidia.com>
-rw-r--r--drivers/video/tegra/dc/ext/dev.c34
-rw-r--r--drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h5
-rw-r--r--include/video/tegra_dc_ext.h1
3 files changed, 32 insertions, 8 deletions
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
index 24e62ca15a72..04553e778390 100644
--- a/drivers/video/tegra/dc/ext/dev.c
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -243,7 +243,9 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work)
struct tegra_dc_win *wins[DC_N_WINDOWS];
struct nvmap_handle_ref *unpin_handles[DC_N_WINDOWS *
TEGRA_DC_NUM_PLANES];
+ struct nvmap_handle_ref *old_handle;
int i, nr_unpin = 0, nr_win = 0;
+ bool skip_flip = false;
for (i = 0; i < DC_N_WINDOWS; i++) {
struct tegra_dc_ext_flip_win *flip_win = &data->win[i];
@@ -257,25 +259,36 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work)
win = tegra_dc_get_window(ext->dc, index);
ext_win = &ext->win[index];
+ if (!(atomic_dec_and_test(&ext_win->nr_pending_flips)) &&
+ (flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_CURSOR))
+ skip_flip = true;
+
if (win->flags & TEGRA_WIN_FLAG_ENABLED) {
int j;
for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
- if (!ext_win->cur_handle[j])
+ if (skip_flip)
+ old_handle = flip_win->handle[j];
+ else
+ old_handle = ext_win->cur_handle[j];
+
+ if (!old_handle)
continue;
- unpin_handles[nr_unpin++] =
- ext_win->cur_handle[j];
+ unpin_handles[nr_unpin++] = old_handle;
}
}
- tegra_dc_ext_set_windowattr(ext, win, &data->win[i]);
+ if (!skip_flip)
+ tegra_dc_ext_set_windowattr(ext, win, &data->win[i]);
wins[nr_win++] = win;
}
- tegra_dc_update_windows(wins, nr_win);
- /* TODO: implement swapinterval here */
- tegra_dc_sync_windows(wins, nr_win);
+ if (!skip_flip) {
+ tegra_dc_update_windows(wins, nr_win);
+ /* TODO: implement swapinterval here */
+ tegra_dc_sync_windows(wins, nr_win);
+ }
for (i = 0; i < DC_N_WINDOWS; i++) {
struct tegra_dc_ext_flip_win *flip_win = &data->win[i];
@@ -484,10 +497,15 @@ static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
for (i = 0; i < DC_N_WINDOWS; i++) {
u32 syncpt_max;
int index = args->win[i].index;
+ struct tegra_dc_win *win;
+ struct tegra_dc_ext_win *ext_win;
if (index < 0)
continue;
+ win = tegra_dc_get_window(ext->dc, index);
+ ext_win = &ext->win[index];
+
syncpt_max = tegra_dc_incr_syncpt_max(ext->dc, index);
data->win[i].syncpt_max = syncpt_max;
@@ -499,6 +517,8 @@ static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
args->post_syncpt_val = syncpt_max;
args->post_syncpt_id = tegra_dc_get_syncpt_id(ext->dc, index);
work_index = index;
+
+ atomic_inc(&ext->win[work_index].nr_pending_flips);
}
queue_work(ext->win[work_index].flip_wq, &data->work);
diff --git a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
index abebd5970ecb..95a637d5a52a 100644
--- a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
+++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
@@ -56,6 +56,8 @@ struct tegra_dc_ext_win {
struct nvmap_handle_ref *cur_handle[TEGRA_DC_NUM_PLANES];
struct workqueue_struct *flip_wq;
+
+ atomic_t nr_pending_flips;
};
struct tegra_dc_ext {
@@ -90,7 +92,8 @@ struct tegra_dc_ext_event_list {
struct list_head list;
};
-#define TEGRA_DC_EXT_CAPABILITIES 0
+#define TEGRA_DC_EXT_CAPABILITIES \
+ TEGRA_DC_EXT_CAPABILITIES_CURSOR_MODE
struct tegra_dc_ext_control_user {
struct tegra_dc_ext_control *control;
diff --git a/include/video/tegra_dc_ext.h b/include/video/tegra_dc_ext.h
index 8c51c70858ed..f46074b1e559 100644
--- a/include/video/tegra_dc_ext.h
+++ b/include/video/tegra_dc_ext.h
@@ -58,6 +58,7 @@
#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_H (1 << 0)
#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_V (1 << 1)
#define TEGRA_DC_EXT_FLIP_FLAG_TILED (1 << 2)
+#define TEGRA_DC_EXT_FLIP_FLAG_CURSOR (1 << 3)
struct tegra_dc_ext_flip_windowattr {
__s32 index;