diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/cursor.c | 47 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/dev.c | 9 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 2 |
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); |