diff options
author | Kevin Huang <kevinh@nvidia.com> | 2013-01-25 11:31:17 -0800 |
---|---|---|
committer | Mrutyunjay Sawant <msawant@nvidia.com> | 2013-04-02 04:06:07 -0700 |
commit | 99c727f3e4a8a6544bdd676ef37fda36f592ed69 (patch) | |
tree | 5314ddb83812a5afc42237cb68de072b1319af8e | |
parent | 1f26035e199eb6058db7f576a0de34cd3a37a2c7 (diff) |
video: tegra: dc: add advanced cursor support
Support advanced display cursor for t11x.
Change-Id: If5ef50401b8a2b2fd22500636d07506983aee0b5
Signed-off-by: Michael I Gold <gold@nvidia.com>
Reviewed-on: http://git-master/r/213743
Reviewed-by: Kevin Huang (Eng-SW) <kevinh@nvidia.com>
Reviewed-by: Robert Morell <rmorell@nvidia.com>
-rw-r--r-- | drivers/video/tegra/Kconfig | 5 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_reg.h | 10 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_sysfs.c | 62 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/cursor.c | 60 | ||||
-rw-r--r-- | include/video/tegra_dc_ext.h | 12 |
5 files changed, 132 insertions, 17 deletions
diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig index 9ee0b5499707..ed50ee467c9f 100644 --- a/drivers/video/tegra/Kconfig +++ b/drivers/video/tegra/Kconfig @@ -42,6 +42,11 @@ config TEGRA_DC_CMU default n if ARCH_TEGRA_2x_SOC || ARCH_TEGRA_3x_SOC default y +config TEGRA_DC_WIN_H + bool + default y if ARCH_TEGRA_14x_SOC + default n + config TEGRA_MIPI_CAL bool default n if ARCH_TEGRA_2x_SOC || ARCH_TEGRA_3x_SOC diff --git a/drivers/video/tegra/dc/dc_reg.h b/drivers/video/tegra/dc/dc_reg.h index 1fdf7e066c1c..7ad07e45a478 100644 --- a/drivers/video/tegra/dc/dc_reg.h +++ b/drivers/video/tegra/dc/dc_reg.h @@ -110,6 +110,8 @@ #define WINDOW_A_SELECT (1 << 4) #define WINDOW_B_SELECT (1 << 5) #define WINDOW_C_SELECT (1 << 6) +#define WINDOW_D_SELECT (1 << 7) +#define WINDOW_H_SELECT (1 << 8) #define DC_CMD_REG_ACT_CONTROL 0x043 @@ -379,7 +381,9 @@ #define DC_DISP_CURSOR_START_ADDR_NS 0x43f #define CURSOR_START_ADDR_MASK (((1 << 22) - 1) << 10) #define CURSOR_START_ADDR(_addr) ((_addr) >> 10) -#define CURSOR_SIZE_64 (1 << 24) +#define CURSOR_SIZE_64 (0x1 << 24) +#define CURSOR_SIZE_128 (0x2 << 24) +#define CURSOR_SIZE_256 (0x3 << 24) #define DC_DISP_CURSOR_POSITION 0x440 #define CURSOR_POSITION(_x, _y) \ @@ -674,4 +678,8 @@ #define NUM_AGG_PRI_LVLS 4 #define SD_AGG_PRI_LVL(x) ((x) >> 3) #define SD_GET_AGG(x) ((x) & 0x7) + +#define DC_DISP_BLEND_CURSOR_CONTROL 0x4f1 +#define CURSOR_MODE_SELECT(x) (((x) & 0x1) << 24) + #endif diff --git a/drivers/video/tegra/dc/dc_sysfs.c b/drivers/video/tegra/dc/dc_sysfs.c index 6b34c4352986..f3dfd682ef5d 100644 --- a/drivers/video/tegra/dc/dc_sysfs.c +++ b/drivers/video/tegra/dc/dc_sysfs.c @@ -136,6 +136,62 @@ static ssize_t enable_store(struct device *dev, static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, enable_show, enable_store); +#ifdef CONFIG_TEGRA_DC_WIN_H +static ssize_t win_h_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct platform_device *ndev = to_platform_device(device); + struct tegra_dc *dc = platform_get_drvdata(ndev); + unsigned long val = 0; + + mutex_lock(&dc->lock); + tegra_dc_io_start(dc); + + val = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); + + tegra_dc_io_end(dc); + mutex_unlock(&dc->lock); + + return snprintf(buf, PAGE_SIZE, "%u\n", !!(val & WINH_CURS_SELECT(1))); +} + +/* win_h sysfs controls hybrid window. + * + * 0 = cursor mode and 1 = window mode (default on T14x) */ +static ssize_t win_h_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct platform_device *ndev = to_platform_device(dev); + struct tegra_dc *dc = platform_get_drvdata(ndev); + unsigned int val = 0; + unsigned long cursor_val = 0; + + if (!dc->enabled) { + dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__); + return -EFAULT; + } + + if (kstrtouint(buf, 10, &val) < 0) + return -EINVAL; + + mutex_lock(&dc->lock); + tegra_dc_io_start(dc); + + cursor_val = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); + cursor_val &= ~WINH_CURS_SELECT(1); + if (val) + cursor_val |= WINH_CURS_SELECT(1); + tegra_dc_writel(dc, cursor_val, DC_DISP_BLEND_CURSOR_CONTROL); + + tegra_dc_io_end(dc); + mutex_unlock(&dc->lock); + + return count; +} + +static DEVICE_ATTR(win_h, S_IRUGO|S_IWUSR, win_h_show, win_h_store); +#endif + static ssize_t crc_checksum_latched_show(struct device *device, struct device_attribute *attr, char *buf) { @@ -458,6 +514,9 @@ void __devexit tegra_dc_remove_sysfs(struct device *dev) device_remove_file(dev, &dev_attr_stats_enable); device_remove_file(dev, &dev_attr_crc_checksum_latched); device_remove_file(dev, &dev_attr_colorbar); +#ifdef CONFIG_TEGRA_DC_WIN_H + device_remove_file(dev, &dev_attr_win_h); +#endif #ifdef CONFIG_TEGRA_DC_CMU device_remove_file(dev, &dev_attr_cmu_enable); #endif @@ -487,6 +546,9 @@ void tegra_dc_create_sysfs(struct device *dev) error |= device_create_file(dev, &dev_attr_stats_enable); error |= device_create_file(dev, &dev_attr_crc_checksum_latched); error |= device_create_file(dev, &dev_attr_colorbar); +#ifdef CONFIG_TEGRA_DC_WIN_H + error |= device_create_file(dev, &dev_attr_win_h); +#endif #ifdef CONFIG_TEGRA_DC_CMU error |= device_create_file(dev, &dev_attr_cmu_enable); #endif diff --git a/drivers/video/tegra/dc/ext/cursor.c b/drivers/video/tegra/dc/ext/cursor.c index ebfa6eb08ffa..17ce70fde35c 100644 --- a/drivers/video/tegra/dc/ext/cursor.c +++ b/drivers/video/tegra/dc/ext/cursor.c @@ -62,6 +62,7 @@ static void set_cursor_image_hw(struct tegra_dc *dc, struct tegra_dc_ext_cursor_image *args, dma_addr_t phys_addr) { + unsigned long val; int clip_win; tegra_dc_writel(dc, @@ -77,15 +78,37 @@ static void set_cursor_image_hw(struct tegra_dc *dc, BUG_ON(phys_addr & ~CURSOR_START_ADDR_MASK); + switch (TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE(args->flags)) { + case TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64: + val = CURSOR_SIZE_64; + break; + case TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_128x128: + val = CURSOR_SIZE_128; + break; + case TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_256x256: + val = CURSOR_SIZE_256; + break; + default: + val = 0; + } + /* Get the cursor clip window number */ clip_win = CURSOR_CLIP_GET_WINDOW(tegra_dc_readl(dc, DC_DISP_CURSOR_START_ADDR)); + val |= clip_win; - 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), + tegra_dc_writel(dc, + val | CURSOR_START_ADDR(((unsigned long) phys_addr)), DC_DISP_CURSOR_START_ADDR); + + if (args->flags & TEGRA_DC_EXT_CURSOR_FLAGS_RGBA_NORMAL) + tegra_dc_writel(dc, + CURSOR_MODE_SELECT(1), + DC_DISP_BLEND_CURSOR_CONTROL); + else + tegra_dc_writel(dc, + CURSOR_MODE_SELECT(0), + DC_DISP_BLEND_CURSOR_CONTROL); } int tegra_dc_ext_set_cursor_image(struct tegra_dc_ext_user *user, @@ -101,12 +124,23 @@ int tegra_dc_ext_set_cursor_image(struct tegra_dc_ext_user *user, if (!user->nvmap) return -EFAULT; - size = args->flags & (TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 | - TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64); - + size = TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE(args->flags); +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) if (size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 && size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64) return -EINVAL; +#else + if (size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 && + size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64 && + size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_128x128 && + size != TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_256x256) + return -EINVAL; +#endif + +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) + if (args->flags && TEGRA_DC_EXT_CURSOR_FLAGS_RGBA_NORMAL) + return -EINVAL; +#endif mutex_lock(&ext->cursor.lock); @@ -163,7 +197,7 @@ int tegra_dc_ext_set_cursor(struct tegra_dc_ext_user *user, { struct tegra_dc_ext *ext = user->ext; struct tegra_dc *dc = ext->dc; - u32 win_options; + u32 val; bool enable; int ret; @@ -185,12 +219,12 @@ int tegra_dc_ext_set_cursor(struct tegra_dc_ext_user *user, tegra_dc_io_start(dc); tegra_dc_hold_dc_out(dc); - win_options = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); - if (!!(win_options & CURSOR_ENABLE) != enable) { - win_options &= ~CURSOR_ENABLE; + val = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); + if (!!(val & CURSOR_ENABLE) != enable) { + val &= ~CURSOR_ENABLE; if (enable) - win_options |= CURSOR_ENABLE; - tegra_dc_writel(dc, win_options, DC_DISP_DISP_WIN_OPTIONS); + val |= CURSOR_ENABLE; + tegra_dc_writel(dc, val, DC_DISP_DISP_WIN_OPTIONS); } tegra_dc_writel(dc, CURSOR_POSITION(args->x, args->y), diff --git a/include/video/tegra_dc_ext.h b/include/video/tegra_dc_ext.h index 52c9f21a5372..1306b2ff06b4 100644 --- a/include/video/tegra_dc_ext.h +++ b/include/video/tegra_dc_ext.h @@ -122,8 +122,14 @@ struct tegra_dc_ext_flip { * 0 1 foreground color * - Exactly one of the SIZE flags must be specified. */ -#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 1 -#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64 2 + +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 ((1 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64 ((2 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_128x128 ((3 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_256x256 ((4 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE(x) (((x) & 0x7) >> 0) +#define TEGRA_DC_EXT_CURSOR_FLAGS_2BIT_LEGACY (0 << 16) +#define TEGRA_DC_EXT_CURSOR_FLAGS_RGBA_NORMAL (1 << 16) struct tegra_dc_ext_cursor_image { struct { __u8 r; @@ -135,7 +141,7 @@ struct tegra_dc_ext_cursor_image { }; /* Possible flags for struct nvdc_cursor's flags field */ -#define TEGRA_DC_EXT_CURSOR_FLAGS_VISIBLE 1 +#define TEGRA_DC_EXT_CURSOR_FLAGS_VISIBLE (1 << 0) struct tegra_dc_ext_cursor { __s16 x; |