summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dc.c
diff options
context:
space:
mode:
authorDavid Schalig <dschalig@nvidia.com>2011-10-13 12:50:14 +0900
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:49:23 -0800
commitf064889bba674399ee981762a5ed9ef10c667a60 (patch)
treed6dea9eeedfac4e1c10d107e9f58dcb1df87ee58 /drivers/video/tegra/dc/dc.c
parent601e1d16240cbe24c6d4fa72c6afacfbde13022e (diff)
video: tegra: dc: ioctl for setting gamma lut
- enable gamma look-up hardware only when needed to save power - add flags field to ioctl TEGRA_DC_EXT_SET_LUT for forward compatibility Bug 868060 Change-Id: I690f8b8856e0b1acd6215907ca8bd78ecaf30b17 Reviewed-on: http://git-master/r/57736 Reviewed-by: David Schalig <dschalig@nvidia.com> Tested-by: David Schalig <dschalig@nvidia.com> Reviewed-by: Jon Mayo <jmayo@nvidia.com> Reviewed-by: Robert Morell <rmorell@nvidia.com> Rebase-Id: Rf6081a9372ba7d6e53a66b9b58a50a62ad409d9a
Diffstat (limited to 'drivers/video/tegra/dc/dc.c')
-rw-r--r--drivers/video/tegra/dc/dc.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 57bdab2b2224..1825d2177ad1 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -668,27 +668,46 @@ EXPORT_SYMBOL(tegra_dc_update_csc);
static void tegra_dc_init_lut_defaults(struct tegra_dc_lut *lut)
{
int i;
- for(i=0; i<256; i++) {
+ for (i = 0; i < 256; i++)
lut->r[i] = lut->g[i] = lut->b[i] = (u8)i;
- }
}
-static void tegra_dc_set_lut(struct tegra_dc *dc,
- struct tegra_dc_lut *lut,
- int start,
- int len)
+static int tegra_dc_lut_is_defaults(struct tegra_dc_lut *lut)
{
- int i;
- for (i = start, len += start; i < len; i++) {
+ unsigned int i;
+ for (i = 0; i < 256; i++)
+ if ((lut->r[i] != i) || (lut->g[i] != i) || (lut->b[i] != i))
+ return 0;
+ return 1;
+}
+
+static void tegra_dc_set_lut(struct tegra_dc *dc, struct tegra_dc_win* win)
+{
+ unsigned int i;
+ unsigned long val;
+ struct tegra_dc_lut *lut = &win->lut;
+
+ for (i = 0; i < 256; i++) {
u32 rgb = ((u32)lut->r[i]) |
((u32)lut->g[i]<<8) |
((u32)lut->b[i]<<16);
tegra_dc_writel(dc, rgb, DC_WIN_COLOR_PALETTE(i));
}
+
+ val = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
+
+ if (win->ppflags & TEGRA_WIN_PPFLAG_CP_ENABLE)
+ val |= CP_ENABLE;
+ else
+ val &= ~CP_ENABLE;
+
+ tegra_dc_writel(dc, val, DC_WIN_WIN_OPTIONS);
}
-int tegra_dc_update_lut(struct tegra_dc *dc, int win_idx, int start, int len)
+int tegra_dc_update_lut(struct tegra_dc *dc, int win_idx, int fboveride)
{
+ struct tegra_dc_win *win = &dc->windows[win_idx];
+
mutex_lock(&dc->lock);
if (!dc->enabled) {
@@ -696,10 +715,20 @@ int tegra_dc_update_lut(struct tegra_dc *dc, int win_idx, int start, int len)
return -EFAULT;
}
+ if (!tegra_dc_lut_is_defaults(&win->lut))
+ win->ppflags |= TEGRA_WIN_PPFLAG_CP_ENABLE;
+ else
+ win->ppflags &= ~TEGRA_WIN_PPFLAG_CP_ENABLE;
+
+ if (fboveride)
+ win->ppflags |= TEGRA_WIN_PPFLAG_CP_FBOVERRIDE;
+ else
+ win->ppflags &= ~TEGRA_WIN_PPFLAG_CP_FBOVERRIDE;
+
tegra_dc_writel(dc, WINDOW_A_SELECT << win_idx,
DC_CMD_DISPLAY_WINDOW_HEADER);
- tegra_dc_set_lut(dc, &dc->windows[win_idx].lut, start, len);
+ tegra_dc_set_lut(dc, win);
mutex_unlock(&dc->lock);
@@ -1117,12 +1146,15 @@ int tegra_dc_update_windows(struct tegra_dc_win *windows[], int n)
DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV,
DC_WIN_BUFFER_ADDR_MODE);
- val = WIN_ENABLE | CP_ENABLE;
+ val = WIN_ENABLE;
if (yuvp)
val |= CSC_ENABLE;
else if (tegra_dc_fmt_bpp(win->fmt) < 24)
val |= COLOR_EXPAND;
+ if (win->ppflags & TEGRA_WIN_PPFLAG_CP_ENABLE)
+ val |= CP_ENABLE;
+
if (filter_h)
val |= H_FILTER_ENABLE;
if (filter_v)
@@ -2221,12 +2253,13 @@ static void tegra_dc_init(struct tegra_dc *dc)
tegra_dc_set_color_control(dc);
for (i = 0; i < DC_N_WINDOWS; i++) {
+ struct tegra_dc_win *win = &dc->windows[i];
tegra_dc_writel(dc, WINDOW_A_SELECT << i,
DC_CMD_DISPLAY_WINDOW_HEADER);
- tegra_dc_init_csc_defaults(&dc->windows[i].csc);
- tegra_dc_set_csc(dc, &dc->windows[i].csc);
- tegra_dc_init_lut_defaults(&dc->windows[i].lut);
- tegra_dc_set_lut(dc, &dc->windows[i].lut, 0, 256);
+ tegra_dc_init_csc_defaults(&win->csc);
+ tegra_dc_set_csc(dc, &win->csc);
+ tegra_dc_init_lut_defaults(&win->lut);
+ tegra_dc_set_lut(dc, win);
tegra_dc_set_scaling_filter(dc);
}