2 * drivers/video/tegra/dc/cursor.c
4 * Copyright (c) 2011-2016, NVIDIA CORPORATION, All rights reserved.
7 * Robert Morell <rmorell@nvidia.com>
8 * Jon Mayo <jmayo@nvidia.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 #include <linux/module.h>
22 #include <linux/kernel.h>
23 #include <linux/errno.h>
24 #include <linux/mutex.h>
29 /* modify val with cursor field set for a given size.
30 * ignore val if it is NULL.
31 * return non-zero on error, and clear val. */
32 static inline int cursor_size_value(enum tegra_dc_cursor_size size, u32 *val)
38 case TEGRA_DC_CURSOR_SIZE_32X32:
39 *val |= CURSOR_SIZE_32;
41 case TEGRA_DC_CURSOR_SIZE_64X64:
42 *val |= CURSOR_SIZE_64;
44 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
45 case TEGRA_DC_CURSOR_SIZE_128X128:
46 *val |= CURSOR_SIZE_128;
48 case TEGRA_DC_CURSOR_SIZE_256X256:
49 *val |= CURSOR_SIZE_256;
57 /* modify val with cursor format.
58 * ignore val if it is NULL.
59 * return non-zero on error, and clear val. */
60 static inline u32 cursor_format_value(enum tegra_dc_cursor_format format,
67 case TEGRA_DC_CURSOR_FORMAT_2BIT_LEGACY:
68 /* MODE_SELECT_LEGACY */
69 *val |= CURSOR_MODE_SELECT(0);
71 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
72 !defined(CONFIG_ARCH_TEGRA_3x_SOC)
73 case TEGRA_DC_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA:
74 # if !defined(CONFIG_TEGRA_NVDISPLAY)
75 /* MODE_SELECT_NORMAL */
76 *val |= CURSOR_MODE_SELECT(1);
78 # if !defined(CONFIG_ARCH_TEGRA_11x_SOC)
79 /* CURSOR_ALPHA, K1_TIMES_SRC, NEG_K1_TIMES_SRC */
80 *val |= CURSOR_ALPHA(255) | CURSOR_DST_BLEND_FACTOR_SELECT(2);
81 *val |= CURSOR_SRC_BLEND_FACTOR_SELECT(1);
85 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
86 !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \
87 !defined(CONFIG_ARCH_TEGRA_11x_SOC)
88 case TEGRA_DC_CURSOR_FORMAT_RGBA_PREMULT_ALPHA:
89 *val |= CURSOR_MODE_SELECT(1);
90 *val |= CURSOR_ALPHA(255) | CURSOR_DST_BLEND_FACTOR_SELECT(2);
91 *val |= CURSOR_SRC_BLEND_FACTOR_SELECT(0);
94 #if defined(CONFIG_TEGRA_NVDISPLAY)
95 case TEGRA_DC_CURSOR_FORMAT_RGBA_XOR:
96 /* MODE_SELECT_NORMAL */
97 *val |= CURSOR_COMP_MODE(1);
98 /* CURSOR_ALPHA, K1, NEG_K1_TIMES_SRC */
99 *val |= CURSOR_ALPHA(255) | CURSOR_DST_BLEND_FACTOR_SELECT(1);
100 *val |= CURSOR_SRC_BLEND_FACTOR_SELECT(1);
104 pr_err("%s: invalid format 0x%x\n", __func__, format);
111 static unsigned int set_cursor_start_addr(struct tegra_dc *dc,
112 enum tegra_dc_cursor_size size, dma_addr_t phys_addr)
117 BUG_ON(phys_addr & ~CURSOR_START_ADDR_MASK);
119 dc->cursor.phys_addr = phys_addr;
120 dc->cursor.size = size;
121 /* this should not fail, as tegra_dc_cursor_image() checks the size */
122 if (WARN(cursor_size_value(size, &val), "invalid cursor size."))
125 clip_win = dc->cursor.clip_win;
126 val |= CURSOR_CLIP_SHIFT_BITS(clip_win);
127 #if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) || \
128 defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
129 tegra_dc_writel(dc, val | CURSOR_START_ADDR(((unsigned long)phys_addr)),
130 DC_DISP_CURSOR_START_ADDR);
132 /* TODO: check calculation with HW */
133 tegra_dc_writel(dc, (u32)(CURSOR_START_ADDR_HI(phys_addr)),
134 DC_DISP_CURSOR_START_ADDR_HI);
135 tegra_dc_writel(dc, (u32)(val | CURSOR_START_ADDR_LOW(phys_addr)),
136 DC_DISP_CURSOR_START_ADDR);
139 #if defined(CONFIG_TEGRA_NVDISPLAY)
140 WARN_ON((phys_addr & 0x3FF) != 0);
143 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
144 !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \
145 !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \
146 !defined(CONFIG_ARCH_TEGRA_14x_SOC)
147 tegra_dc_writel(dc, CURSOR_UPDATE, DC_CMD_STATE_CONTROL);
148 tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL);
155 static int set_cursor_position(struct tegra_dc *dc, s16 x, s16 y)
157 #if defined(CONFIG_TEGRA_NVDISPLAY)
158 nvdisp_set_cursor_position(dc, x, y);
160 tegra_dc_writel(dc, CURSOR_POSITION(x, y), DC_DISP_CURSOR_POSITION);
163 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
164 !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \
165 !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \
166 !defined(CONFIG_ARCH_TEGRA_14x_SOC)
167 tegra_dc_writel(dc, CURSOR_UPDATE, DC_CMD_STATE_CONTROL);
168 tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL);
175 static int set_cursor_activation_control(struct tegra_dc *dc)
177 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
178 !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \
179 !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \
180 !defined(CONFIG_ARCH_TEGRA_14x_SOC) && \
181 !defined(CONFIG_TEGRA_NVDISPLAY)
182 u32 reg = tegra_dc_readl(dc, DC_CMD_REG_ACT_CONTROL);
184 if ((reg & (1 << CURSOR_ACT_CNTR_SEL)) ==
185 (CURSOR_ACT_CNTR_SEL_V << CURSOR_ACT_CNTR_SEL)) {
186 reg &= ~(1 << CURSOR_ACT_CNTR_SEL);
187 reg |= (CURSOR_ACT_CNTR_SEL_V << CURSOR_ACT_CNTR_SEL);
188 tegra_dc_writel(dc, reg, DC_CMD_REG_ACT_CONTROL);
195 static int set_cursor_enable(struct tegra_dc *dc, bool enable)
197 u32 val = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
198 if (!!(val & CURSOR_ENABLE) != enable) {
199 val &= ~CURSOR_ENABLE;
201 val |= CURSOR_ENABLE;
202 tegra_dc_writel(dc, val, DC_DISP_DISP_WIN_OPTIONS);
205 dc->cursor.enabled = enable;
209 static int set_cursor_blend(struct tegra_dc *dc, u32 format)
211 u32 val = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL);
213 u32 newval = WINH_CURS_SELECT(0);
215 /* this should not fail, as tegra_dc_cursor_image() checks the format */
216 if (WARN(cursor_format_value(format, &newval), "invalid cursor format"))
220 tegra_dc_writel(dc, newval, DC_DISP_BLEND_CURSOR_CONTROL);
223 dc->cursor.format = format;
228 static int set_cursor_fg_bg(struct tegra_dc *dc, u32 fg, u32 bg)
230 int general_update_needed = 0;
232 #if !defined(CONFIG_TEGRA_NVDISPLAY)
233 /* TODO: check fg/bg against data structure, don't read the HW */
234 if (fg != tegra_dc_readl(dc, DC_DISP_CURSOR_FOREGROUND)) {
235 tegra_dc_writel(dc, fg, DC_DISP_CURSOR_FOREGROUND);
236 general_update_needed |= 1;
239 if (bg != tegra_dc_readl(dc, DC_DISP_CURSOR_BACKGROUND)) {
240 tegra_dc_writel(dc, bg, DC_DISP_CURSOR_BACKGROUND);
241 general_update_needed |= 1;
247 return general_update_needed;
250 static void tegra_dc_cursor_do_update(struct tegra_dc *dc,
251 bool need_general_update)
253 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
254 !defined(CONFIG_ARCH_TEGRA_3x_SOC) && \
255 !defined(CONFIG_ARCH_TEGRA_11x_SOC) && \
256 !defined(CONFIG_ARCH_TEGRA_14x_SOC)
257 tegra_dc_writel(dc, CURSOR_UPDATE, DC_CMD_STATE_CONTROL);
258 tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL);
260 need_general_update = true;
262 if (need_general_update) {
263 tegra_dc_writel(dc, GENERAL_UPDATE, DC_CMD_STATE_CONTROL);
264 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
268 static int tegra_dc_cursor_program(struct tegra_dc *dc)
270 bool need_general_update = false;
274 /* these checks are redundant */
275 if (cursor_size_value(dc->cursor.size, NULL))
277 if (cursor_format_value(dc->cursor.format, NULL))
280 mutex_lock(&dc->lock);
281 if (!dc->cursor.dirty) {
282 mutex_unlock(&dc->lock);
287 need_general_update |= set_cursor_start_addr(dc, dc->cursor.size,
288 dc->cursor.phys_addr);
290 need_general_update |= set_cursor_fg_bg(dc,
291 dc->cursor.fg, dc->cursor.bg);
293 need_general_update |= set_cursor_blend(dc, dc->cursor.format);
295 need_general_update |= set_cursor_enable(dc, dc->cursor.enabled);
297 need_general_update |= set_cursor_position(dc,
298 dc->cursor.x, dc->cursor.y);
300 need_general_update |= set_cursor_activation_control(dc);
302 tegra_dc_cursor_do_update(dc, need_general_update);
305 dc->cursor.dirty = false;
306 mutex_unlock(&dc->lock);
311 int tegra_dc_cursor_image(struct tegra_dc *dc,
312 enum tegra_dc_cursor_format format, enum tegra_dc_cursor_size size,
313 u32 fg, u32 bg, dma_addr_t phys_addr)
315 if (cursor_size_value(size, NULL))
318 if (cursor_format_value(format, NULL))
321 mutex_lock(&dc->lock);
324 dc->cursor.size = size;
325 dc->cursor.format = format;
326 dc->cursor.phys_addr = phys_addr;
327 dc->cursor.dirty = true;
328 mutex_unlock(&dc->lock);
330 return tegra_dc_cursor_program(dc);
333 int tegra_dc_cursor_set(struct tegra_dc *dc, bool enable, int x, int y)
335 mutex_lock(&dc->lock);
338 dc->cursor.enabled = enable;
339 dc->cursor.dirty = true;
340 mutex_unlock(&dc->lock);
342 return tegra_dc_cursor_program(dc);
351 int tegra_dc_cursor_clip(struct tegra_dc *dc, unsigned clip)
353 mutex_lock(&dc->lock);
354 dc->cursor.clip_win = clip;
355 dc->cursor.dirty = true;
356 mutex_unlock(&dc->lock);
358 return tegra_dc_cursor_program(dc);
361 /* disable the cursor on suspend. but leave the state unmodified */
362 int tegra_dc_cursor_suspend(struct tegra_dc *dc)
366 mutex_lock(&dc->lock);
368 set_cursor_enable(dc, false);
369 tegra_dc_cursor_do_update(dc, true);
370 dc->cursor.dirty = true;
372 mutex_unlock(&dc->lock);
376 /* restore the state */
377 int tegra_dc_cursor_resume(struct tegra_dc *dc)
379 return tegra_dc_cursor_program(dc);