summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/ext/dev.c
diff options
context:
space:
mode:
authorMichael Frydrych <mfrydrych@nvidia.com>2014-04-23 09:15:07 +0300
committerRaghunandan Bayes <rbayes@nvidia.com>2014-04-25 00:07:37 -0700
commit73896aaf41ac24c5d5b31cdbcf8aff4f8f659a3e (patch)
tree6d825a7181e8578b2c820467b85fc7bfe21f9ab8 /drivers/video/tegra/dc/ext/dev.c
parent458c26866f9e0db96a154e0a8c0a0b4b097d55b3 (diff)
video: tegra: blank dc windows during dc releasedaily-2014.05.06.0_rel-roth-r4-partner
Window owned by a process should be blanked when the process releases dc or any individual window it has owned. The buffers lastly displayed on those windows will be unpinned. bug 1490686 bug 1467689 Change-Id: I3b3614a99b9598b7d432f08c4a95d8050a4ef99e Signed-off-by: Michael Frydrych <mfrydrych@nvidia.com> Reviewed-on: http://git-master/r/400894 GVS: Gerrit_Virtual_Submit Reviewed-by: David Dastous St Hilaire <ddastoussthi@nvidia.com> Tested-by: David Dastous St Hilaire <ddastoussthi@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/ext/dev.c')
-rw-r--r--drivers/video/tegra/dc/ext/dev.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
index 203f1a478190..273b31755643 100644
--- a/drivers/video/tegra/dc/ext/dev.c
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -1,7 +1,7 @@
/*
* drivers/video/tegra/dc/dev.c
*
- * Copyright (c) 2011-2012, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2011-2014, NVIDIA CORPORATION, All rights reserved.
*
* Author: Robert Morell <rmorell@nvidia.com>
* Some code based on fbdev extensions written by:
@@ -327,6 +327,18 @@ int tegra_dc_unset_flip_callback()
}
EXPORT_SYMBOL(tegra_dc_unset_flip_callback);
+static void tegra_dc_ext_unpin_handles(struct tegra_dc_ext *ext,
+ struct nvmap_handle_ref *unpin_handles[],
+ int nr_unpin)
+{
+ int i;
+
+ for (i = 0; i < nr_unpin; i++) {
+ nvmap_unpin(ext->nvmap, unpin_handles[i]);
+ nvmap_free(ext->nvmap, unpin_handles[i]);
+ }
+}
+
static void tegra_dc_ext_flip_worker(struct work_struct *work)
{
struct tegra_dc_ext_flip_data *data =
@@ -432,10 +444,7 @@ static void tegra_dc_ext_flip_worker(struct work_struct *work)
}
/* unpin and deref previous front buffers */
- for (i = 0; i < nr_unpin; i++) {
- nvmap_unpin(ext->nvmap, unpin_handles[i]);
- nvmap_free(ext->nvmap, unpin_handles[i]);
- }
+ tegra_dc_ext_unpin_handles(ext, unpin_handles, nr_unpin);
kfree(data);
}
@@ -533,6 +542,23 @@ static int sanitize_flip_args(struct tegra_dc_ext_user *user,
return 0;
}
+static void tegra_dc_ext_unpin_window(struct tegra_dc_ext_win *win)
+{
+ struct nvmap_handle_ref *unpin_handles[TEGRA_DC_NUM_PLANES];
+ int nr_unpin = 0;
+
+ if (win->cur_handle[TEGRA_DC_Y]) {
+ int j;
+ for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
+ if (win->cur_handle[j])
+ unpin_handles[nr_unpin++] = win->cur_handle[j];
+ }
+ memset(win->cur_handle, 0, sizeof(win->cur_handle));
+ }
+
+ tegra_dc_ext_unpin_handles(win->ext, unpin_handles, nr_unpin);
+}
+
static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
struct tegra_dc_ext_flip *args)
{
@@ -865,6 +891,7 @@ static long tegra_dc_ioctl(struct file *filp, unsigned int cmd,
{
void __user *user_arg = (void __user *)arg;
struct tegra_dc_ext_user *user = filp->private_data;
+ int ret;
switch (cmd) {
case TEGRA_DC_EXT_SET_NVMAP_FD:
@@ -873,7 +900,12 @@ static long tegra_dc_ioctl(struct file *filp, unsigned int cmd,
case TEGRA_DC_EXT_GET_WINDOW:
return tegra_dc_ext_get_window(user, arg);
case TEGRA_DC_EXT_PUT_WINDOW:
- return tegra_dc_ext_put_window(user, arg);
+ ret = tegra_dc_ext_put_window(user, arg);
+ if (!ret) {
+ tegra_dc_blank(user->ext->dc, BIT(arg));
+ tegra_dc_ext_unpin_window(&user->ext->win[arg]);
+ }
+ return ret;
case TEGRA_DC_EXT_FLIP:
{
@@ -1032,11 +1064,19 @@ static int tegra_dc_release(struct inode *inode, struct file *filp)
struct tegra_dc_ext_user *user = filp->private_data;
struct tegra_dc_ext *ext = user->ext;
unsigned int i;
+ unsigned long int windows = 0;
for (i = 0; i < DC_N_WINDOWS; i++) {
- if (ext->win[i].user == user)
+ if (ext->win[i].user == user) {
tegra_dc_ext_put_window(user, i);
+ windows |= BIT(i);
+ }
}
+
+ tegra_dc_blank(ext->dc, windows);
+ for_each_set_bit(i, &windows, DC_N_WINDOWS)
+ tegra_dc_ext_unpin_window(&ext->win[i]);
+
if (ext->cursor.user == user)
tegra_dc_ext_put_cursor(user);