diff options
-rw-r--r-- | arch/arm/mach-tegra/include/mach/dc.h | 5 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 27 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv_defs.h | 2 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dsi.c | 2 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/dev.c | 54 | ||||
-rw-r--r-- | drivers/video/tegra/fb.c | 4 |
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: |