summaryrefslogtreecommitdiff
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
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>
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h5
-rw-r--r--drivers/video/tegra/dc/dc.c27
-rw-r--r--drivers/video/tegra/dc/dc_priv_defs.h2
-rw-r--r--drivers/video/tegra/dc/dsi.c2
-rw-r--r--drivers/video/tegra/dc/ext/dev.c54
-rw-r--r--drivers/video/tegra/fb.c4
6 files changed, 73 insertions, 21 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index b5abc2400558..2edd7e6dbd53 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -6,7 +6,7 @@
* Author:
* Erik Gilling <konkers@google.com>
*
- * Copyright (C) 2010-2011 NVIDIA Corporation
+ * Copyright (C) 2010-2014 NVIDIA Corporation
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -31,6 +31,7 @@
#define DC_N_WINDOWS 3
#define DEFAULT_FPGA_FREQ_KHZ 160000
+#define TEGRA_DC_BLANK_ALL (~0)
/* DSI pixel data format */
enum {
@@ -685,7 +686,7 @@ bool tegra_dc_hpd(struct tegra_dc *dc);
void tegra_dc_get_fbvblank(struct tegra_dc *dc, struct fb_vblank *vblank);
int tegra_dc_wait_for_vsync(struct tegra_dc *dc);
-void tegra_dc_blank(struct tegra_dc *dc);
+void tegra_dc_blank(struct tegra_dc *dc, unsigned windows);
void tegra_dc_enable(struct tegra_dc *dc);
void tegra_dc_disable(struct tegra_dc *dc);
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 728fb555344f..f56c007d5dab 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -4,7 +4,7 @@
* Copyright (C) 2010 Google, Inc.
* Author: Erik Gilling <konkers@android.com>
*
- * Copyright (c) 2010-2013, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2014, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -2261,19 +2261,28 @@ bool tegra_dc_stats_get(struct tegra_dc *dc)
return true;
}
-/* make the screen blank by disabling all windows */
-void tegra_dc_blank(struct tegra_dc *dc)
+/* blank selected windows by disabling them */
+void tegra_dc_blank(struct tegra_dc *dc, unsigned windows)
{
struct tegra_dc_win *dcwins[DC_N_WINDOWS];
unsigned i;
+ unsigned long int blank_windows;
+ int nr_win = 0;
- for (i = 0; i < DC_N_WINDOWS; i++) {
- dcwins[i] = tegra_dc_get_window(dc, i);
- dcwins[i]->flags &= ~TEGRA_WIN_FLAG_ENABLED;
+ if (!windows)
+ return;
+
+ blank_windows = windows;
+ for_each_set_bit(i, &blank_windows, DC_N_WINDOWS) {
+ dcwins[nr_win] = tegra_dc_get_window(dc, i);
+ if (!dcwins[nr_win])
+ continue;
+ dcwins[nr_win++]->flags &= ~TEGRA_WIN_FLAG_ENABLED;
}
- tegra_dc_update_windows(dcwins, DC_N_WINDOWS);
- tegra_dc_sync_windows(dcwins, DC_N_WINDOWS);
+ tegra_dc_update_windows(dcwins, nr_win);
+ tegra_dc_sync_windows(dcwins, nr_win);
+ tegra_dc_program_bandwidth(dc, true);
}
static void _tegra_dc_disable(struct tegra_dc *dc)
@@ -2854,7 +2863,7 @@ static void tegra_dc_shutdown(struct platform_device *ndev)
if (!dc || !dc->enabled)
return;
- tegra_dc_blank(dc);
+ tegra_dc_blank(dc, BLANK_ALL);
tegra_dc_disable(dc);
}
diff --git a/drivers/video/tegra/dc/dc_priv_defs.h b/drivers/video/tegra/dc/dc_priv_defs.h
index 408c2bb56993..ac9b2f0c4dd0 100644
--- a/drivers/video/tegra/dc/dc_priv_defs.h
+++ b/drivers/video/tegra/dc/dc_priv_defs.h
@@ -46,6 +46,8 @@
#define CURSOR_CLIP_SHIFT_BITS(win) (win << 29)
#define CURSOR_CLIP_GET_WINDOW(reg) ((reg >> 29) & 3)
+#define BLANK_ALL (~0)
+
#ifndef CONFIG_TEGRA_FPGA_PLATFORM
#define ALL_UF_INT (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)
#else
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 848bbadca948..3e79d5d880e0 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -1,7 +1,7 @@
/*
* drivers/video/tegra/dc/dsi.c
*
- * Copyright (c) 2011-2013, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2011-2014, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
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);
diff --git a/drivers/video/tegra/fb.c b/drivers/video/tegra/fb.c
index 5b8eca3a0321..df99434574ea 100644
--- a/drivers/video/tegra/fb.c
+++ b/drivers/video/tegra/fb.c
@@ -6,7 +6,7 @@
* Colin Cross <ccross@android.com>
* Travis Geiselbrecht <travis@palm.com>
*
- * Copyright (c) 2010-2012, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2010-2014, NVIDIA CORPORATION, All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -287,7 +287,7 @@ static int tegra_fb_blank(int blank, struct fb_info *info)
case FB_BLANK_NORMAL:
dev_dbg(&tegra_fb->ndev->dev, "blank - normal\n");
- tegra_dc_blank(tegra_fb->win->dc);
+ tegra_dc_blank(tegra_fb->win->dc, TEGRA_DC_BLANK_ALL);
return 0;
case FB_BLANK_VSYNC_SUSPEND: