summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/dc/dc_priv.h4
-rw-r--r--drivers/video/tegra/dc/ext/cursor.c47
-rw-r--r--drivers/video/tegra/dc/ext/dev.c9
-rw-r--r--drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h2
4 files changed, 61 insertions, 1 deletions
diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h
index 78da706bdc4e..242615f4d1c1 100644
--- a/drivers/video/tegra/dc/dc_priv.h
+++ b/drivers/video/tegra/dc/dc_priv.h
@@ -44,6 +44,10 @@
/* DDR: 8 bytes transfer per clock */
#define DDR_BW_TO_FREQ(bw) ((bw) / 8)
+/* 29 bit offset for window clip number */
+#define CURSOR_CLIP_SHIFT_BITS(win) (win << 29)
+#define CURSOR_CLIP_GET_WINDOW(reg) ((reg >> 29) & 3)
+
#if defined(CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
#define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
#else
diff --git a/drivers/video/tegra/dc/ext/cursor.c b/drivers/video/tegra/dc/ext/cursor.c
index 970f38f5ac09..6320c56dc353 100644
--- a/drivers/video/tegra/dc/ext/cursor.c
+++ b/drivers/video/tegra/dc/ext/cursor.c
@@ -62,6 +62,8 @@ static void set_cursor_image_hw(struct tegra_dc *dc,
struct tegra_dc_ext_cursor_image *args,
dma_addr_t phys_addr)
{
+ int clip_win;
+
tegra_dc_writel(dc,
CURSOR_COLOR(args->foreground.r,
args->foreground.g,
@@ -75,7 +77,11 @@ static void set_cursor_image_hw(struct tegra_dc *dc,
BUG_ON(phys_addr & ~CURSOR_START_ADDR_MASK);
- tegra_dc_writel(dc,
+ /* Get the cursor clip window number */
+ clip_win = CURSOR_CLIP_GET_WINDOW(tegra_dc_readl(dc,
+ DC_DISP_CURSOR_START_ADDR));
+
+ tegra_dc_writel(dc, CURSOR_CLIP_SHIFT_BITS(clip_win) |
CURSOR_START_ADDR(((unsigned long) phys_addr)) |
((args->flags & TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64) ?
CURSOR_SIZE_64 : 0),
@@ -201,3 +207,42 @@ unlock:
return ret;
}
+
+int tegra_dc_ext_cursor_clip(struct tegra_dc_ext_user *user,
+ int *args)
+{
+ struct tegra_dc_ext *ext = user->ext;
+ struct tegra_dc *dc = ext->dc;
+ int ret;
+ unsigned long reg_val;
+
+ mutex_lock(&ext->cursor.lock);
+
+ if (ext->cursor.user != user) {
+ ret = -EACCES;
+ goto unlock;
+ }
+
+ if (!ext->enabled) {
+ ret = -ENXIO;
+ goto unlock;
+ }
+
+ mutex_lock(&dc->lock);
+
+ reg_val = tegra_dc_readl(dc, DC_DISP_CURSOR_START_ADDR);
+ reg_val &= ~CURSOR_CLIP_SHIFT_BITS(3); /* Clear out the old value */
+ tegra_dc_writel(dc, reg_val | CURSOR_CLIP_SHIFT_BITS(*args),
+ DC_DISP_CURSOR_START_ADDR);
+
+ mutex_unlock(&dc->lock);
+
+ mutex_unlock(&ext->cursor.lock);
+
+ return 0;
+
+unlock:
+ mutex_unlock(&ext->cursor.lock);
+
+ return ret;
+}
diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c
index 436d92464086..2302372ad663 100644
--- a/drivers/video/tegra/dc/ext/dev.c
+++ b/drivers/video/tegra/dc/ext/dev.c
@@ -937,6 +937,15 @@ static long tegra_dc_ioctl(struct file *filp, unsigned int cmd,
return ret;
}
+ case TEGRA_DC_EXT_CURSOR_CLIP:
+ {
+ int args;
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ return tegra_dc_ext_cursor_clip(user, &args);
+ }
+
default:
return -EINVAL;
}
diff --git a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
index ef7361d1d933..459181e62ef3 100644
--- a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
+++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h
@@ -137,6 +137,8 @@ extern int tegra_dc_ext_set_cursor_image(struct tegra_dc_ext_user *user,
struct tegra_dc_ext_cursor_image *);
extern int tegra_dc_ext_set_cursor(struct tegra_dc_ext_user *user,
struct tegra_dc_ext_cursor *);
+extern int tegra_dc_ext_cursor_clip(struct tegra_dc_ext_user *user,
+ int *args);
extern int tegra_dc_ext_control_init(void);