diff options
author | Adam Cheney <acheney@nvidia.com> | 2012-03-15 14:50:00 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-03-29 13:38:18 -0700 |
commit | ba121123068656e007955d090915c8c94a436fd4 (patch) | |
tree | 887b48b897893504229946a176aa12f3294e4f98 /drivers | |
parent | 9471542720db75307e6279f66040bb94b8acf1f9 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/ext/dev.c | 34 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 5 |
2 files changed, 31 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; |