summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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: