aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/tegra/dc.c431
-rw-r--r--drivers/gpu/drm/tegra/dc.h12
-rw-r--r--drivers/gpu/drm/tegra/drm.h24
3 files changed, 372 insertions, 95 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index d35ff8be7ae8..52bf63fbf384 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -18,26 +18,143 @@
18#include "drm.h" 18#include "drm.h"
19#include "dc.h" 19#include "dc.h"
20 20
21struct tegra_dc_window { 21struct tegra_plane {
22 fixed20_12 x; 22 struct drm_plane base;
23 fixed20_12 y; 23 unsigned int index;
24 fixed20_12 w;
25 fixed20_12 h;
26 unsigned int outx;
27 unsigned int outy;
28 unsigned int outw;
29 unsigned int outh;
30 unsigned int stride;
31 unsigned int fmt;
32}; 24};
33 25
26static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
27{
28 return container_of(plane, struct tegra_plane, base);
29}
30
31static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
32 struct drm_framebuffer *fb, int crtc_x,
33 int crtc_y, unsigned int crtc_w,
34 unsigned int crtc_h, uint32_t src_x,
35 uint32_t src_y, uint32_t src_w, uint32_t src_h)
36{
37 struct tegra_plane *p = to_tegra_plane(plane);
38 struct tegra_dc *dc = to_tegra_dc(crtc);
39 struct tegra_dc_window window;
40 unsigned int i;
41
42 memset(&window, 0, sizeof(window));
43 window.src.x = src_x >> 16;
44 window.src.y = src_y >> 16;
45 window.src.w = src_w >> 16;
46 window.src.h = src_h >> 16;
47 window.dst.x = crtc_x;
48 window.dst.y = crtc_y;
49 window.dst.w = crtc_w;
50 window.dst.h = crtc_h;
51 window.format = tegra_dc_format(fb->pixel_format);
52 window.bits_per_pixel = fb->bits_per_pixel;
53
54 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
55 struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
56
57 window.base[i] = gem->paddr + fb->offsets[i];
58
59 /*
60 * Tegra doesn't support different strides for U and V planes
61 * so we display a warning if the user tries to display a
62 * framebuffer with such a configuration.
63 */
64 if (i >= 2) {
65 if (fb->pitches[i] != window.stride[1])
66 DRM_ERROR("unsupported UV-plane configuration\n");
67 } else {
68 window.stride[i] = fb->pitches[i];
69 }
70 }
71
72 return tegra_dc_setup_window(dc, p->index, &window);
73}
74
75static int tegra_plane_disable(struct drm_plane *plane)
76{
77 struct tegra_dc *dc = to_tegra_dc(plane->crtc);
78 struct tegra_plane *p = to_tegra_plane(plane);
79 unsigned long value;
80
81 value = WINDOW_A_SELECT << p->index;
82 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
83
84 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS);
85 value &= ~WIN_ENABLE;
86 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
87
88 tegra_dc_writel(dc, WIN_A_UPDATE << p->index, DC_CMD_STATE_CONTROL);
89 tegra_dc_writel(dc, WIN_A_ACT_REQ << p->index, DC_CMD_STATE_CONTROL);
90
91 return 0;
92}
93
94static void tegra_plane_destroy(struct drm_plane *plane)
95{
96 tegra_plane_disable(plane);
97 drm_plane_cleanup(plane);
98}
99
100static const struct drm_plane_funcs tegra_plane_funcs = {
101 .update_plane = tegra_plane_update,
102 .disable_plane = tegra_plane_disable,
103 .destroy = tegra_plane_destroy,
104};
105
106static const uint32_t plane_formats[] = {
107 DRM_FORMAT_XRGB8888,
108 DRM_FORMAT_UYVY,
109 DRM_FORMAT_YUV420,
110 DRM_FORMAT_YUV422,
111};
112
113static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
114{
115 unsigned int i;
116 int err = 0;
117
118 for (i = 0; i < 2; i++) {
119 struct tegra_plane *plane;
120
121 plane = devm_kzalloc(drm->dev, sizeof(*plane), GFP_KERNEL);
122 if (!plane)
123 return -ENOMEM;
124
125 plane->index = 1 + i;
126
127 err = drm_plane_init(drm, &plane->base, 1 << dc->pipe,
128 &tegra_plane_funcs, plane_formats,
129 ARRAY_SIZE(plane_formats), false);
130 if (err < 0)
131 return err;
132 }
133
134 return 0;
135}
136
34static const struct drm_crtc_funcs tegra_crtc_funcs = { 137static const struct drm_crtc_funcs tegra_crtc_funcs = {
35 .set_config = drm_crtc_helper_set_config, 138 .set_config = drm_crtc_helper_set_config,
36 .destroy = drm_crtc_cleanup, 139 .destroy = drm_crtc_cleanup,
37}; 140};
38 141
39static void tegra_crtc_dpms(struct drm_crtc *crtc, int mode) 142static void tegra_crtc_disable(struct drm_crtc *crtc)
40{ 143{
144 struct drm_device *drm = crtc->dev;
145 struct drm_plane *plane;
146
147 list_for_each_entry(plane, &drm->mode_config.plane_list, head) {
148 if (plane->crtc == crtc) {
149 tegra_plane_disable(plane);
150 plane->crtc = NULL;
151
152 if (plane->fb) {
153 drm_framebuffer_unreference(plane->fb);
154 plane->fb = NULL;
155 }
156 }
157 }
41} 158}
42 159
43static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, 160static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -47,10 +164,11 @@ static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
47 return true; 164 return true;
48} 165}
49 166
50static inline u32 compute_dda_inc(fixed20_12 inf, unsigned int out, bool v, 167static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
51 unsigned int bpp) 168 unsigned int bpp)
52{ 169{
53 fixed20_12 outf = dfixed_init(out); 170 fixed20_12 outf = dfixed_init(out);
171 fixed20_12 inf = dfixed_init(in);
54 u32 dda_inc; 172 u32 dda_inc;
55 int max; 173 int max;
56 174
@@ -80,9 +198,10 @@ static inline u32 compute_dda_inc(fixed20_12 inf, unsigned int out, bool v,
80 return dda_inc; 198 return dda_inc;
81} 199}
82 200
83static inline u32 compute_initial_dda(fixed20_12 in) 201static inline u32 compute_initial_dda(unsigned int in)
84{ 202{
85 return dfixed_frac(in); 203 fixed20_12 inf = dfixed_init(in);
204 return dfixed_frac(inf);
86} 205}
87 206
88static int tegra_dc_set_timings(struct tegra_dc *dc, 207static int tegra_dc_set_timings(struct tegra_dc *dc,
@@ -153,6 +272,185 @@ static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
153 return 0; 272 return 0;
154} 273}
155 274
275static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
276{
277 switch (format) {
278 case WIN_COLOR_DEPTH_YCbCr422:
279 case WIN_COLOR_DEPTH_YUV422:
280 if (planar)
281 *planar = false;
282
283 return true;
284
285 case WIN_COLOR_DEPTH_YCbCr420P:
286 case WIN_COLOR_DEPTH_YUV420P:
287 case WIN_COLOR_DEPTH_YCbCr422P:
288 case WIN_COLOR_DEPTH_YUV422P:
289 case WIN_COLOR_DEPTH_YCbCr422R:
290 case WIN_COLOR_DEPTH_YUV422R:
291 case WIN_COLOR_DEPTH_YCbCr422RA:
292 case WIN_COLOR_DEPTH_YUV422RA:
293 if (planar)
294 *planar = true;
295
296 return true;
297 }
298
299 return false;
300}
301
302int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
303 const struct tegra_dc_window *window)
304{
305 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
306 unsigned long value;
307 bool yuv, planar;
308
309 /*
310 * For YUV planar modes, the number of bytes per pixel takes into
311 * account only the luma component and therefore is 1.
312 */
313 yuv = tegra_dc_format_is_yuv(window->format, &planar);
314 if (!yuv)
315 bpp = window->bits_per_pixel / 8;
316 else
317 bpp = planar ? 1 : 2;
318
319 value = WINDOW_A_SELECT << index;
320 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
321
322 tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
323 tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
324
325 value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x);
326 tegra_dc_writel(dc, value, DC_WIN_POSITION);
327
328 value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w);
329 tegra_dc_writel(dc, value, DC_WIN_SIZE);
330
331 h_offset = window->src.x * bpp;
332 v_offset = window->src.y;
333 h_size = window->src.w * bpp;
334 v_size = window->src.h;
335
336 value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
337 tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
338
339 /*
340 * For DDA computations the number of bytes per pixel for YUV planar
341 * modes needs to take into account all Y, U and V components.
342 */
343 if (yuv && planar)
344 bpp = 2;
345
346 h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
347 v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp);
348
349 value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
350 tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
351
352 h_dda = compute_initial_dda(window->src.x);
353 v_dda = compute_initial_dda(window->src.y);
354
355 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
356 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
357
358 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
359 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
360
361 tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR);
362
363 if (yuv && planar) {
364 tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U);
365 tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V);
366 value = window->stride[1] << 16 | window->stride[0];
367 tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE);
368 } else {
369 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
370 }
371
372 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
373 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
374
375 value = WIN_ENABLE;
376
377 if (yuv) {
378 /* setup default colorspace conversion coefficients */
379 tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
380 tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
381 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
382 tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
383 tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
384 tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
385 tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
386 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
387
388 value |= CSC_ENABLE;
389 } else if (bpp < 24) {
390 value |= COLOR_EXPAND;
391 }
392
393 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
394
395 /*
396 * Disable blending and assume Window A is the bottom-most window,
397 * Window C is the top-most window and Window B is in the middle.
398 */
399 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
400 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
401
402 switch (index) {
403 case 0:
404 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
405 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
406 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
407 break;
408
409 case 1:
410 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
411 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
412 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
413 break;
414
415 case 2:
416 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
417 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
418 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
419 break;
420 }
421
422 tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL);
423 tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL);
424
425 return 0;
426}
427
428unsigned int tegra_dc_format(uint32_t format)
429{
430 switch (format) {
431 case DRM_FORMAT_XRGB8888:
432 return WIN_COLOR_DEPTH_B8G8R8A8;
433
434 case DRM_FORMAT_RGB565:
435 return WIN_COLOR_DEPTH_B5G6R5;
436
437 case DRM_FORMAT_UYVY:
438 return WIN_COLOR_DEPTH_YCbCr422;
439
440 case DRM_FORMAT_YUV420:
441 return WIN_COLOR_DEPTH_YCbCr420P;
442
443 case DRM_FORMAT_YUV422:
444 return WIN_COLOR_DEPTH_YCbCr422P;
445
446 default:
447 break;
448 }
449
450 WARN(1, "unsupported pixel format %u, using default\n", format);
451 return WIN_COLOR_DEPTH_B8G8R8A8;
452}
453
156static int tegra_crtc_mode_set(struct drm_crtc *crtc, 454static int tegra_crtc_mode_set(struct drm_crtc *crtc,
157 struct drm_display_mode *mode, 455 struct drm_display_mode *mode,
158 struct drm_display_mode *adjusted, 456 struct drm_display_mode *adjusted,
@@ -160,8 +458,7 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
160{ 458{
161 struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(crtc->fb, 0); 459 struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
162 struct tegra_dc *dc = to_tegra_dc(crtc); 460 struct tegra_dc *dc = to_tegra_dc(crtc);
163 unsigned int h_dda, v_dda, bpp; 461 struct tegra_dc_window window;
164 struct tegra_dc_window win;
165 unsigned long div, value; 462 unsigned long div, value;
166 int err; 463 int err;
167 464
@@ -192,81 +489,23 @@ static int tegra_crtc_mode_set(struct drm_crtc *crtc,
192 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); 489 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
193 490
194 /* setup window parameters */ 491 /* setup window parameters */
195 memset(&win, 0, sizeof(win)); 492 memset(&window, 0, sizeof(window));
196 win.x.full = dfixed_const(0); 493 window.src.x = 0;
197 win.y.full = dfixed_const(0); 494 window.src.y = 0;
198 win.w.full = dfixed_const(mode->hdisplay); 495 window.src.w = mode->hdisplay;
199 win.h.full = dfixed_const(mode->vdisplay); 496 window.src.h = mode->vdisplay;
200 win.outx = 0; 497 window.dst.x = 0;
201 win.outy = 0; 498 window.dst.y = 0;
202 win.outw = mode->hdisplay; 499 window.dst.w = mode->hdisplay;
203 win.outh = mode->vdisplay; 500 window.dst.h = mode->vdisplay;
204 501 window.format = tegra_dc_format(crtc->fb->pixel_format);
205 switch (crtc->fb->pixel_format) { 502 window.bits_per_pixel = crtc->fb->bits_per_pixel;
206 case DRM_FORMAT_XRGB8888: 503 window.stride[0] = crtc->fb->pitches[0];
207 win.fmt = WIN_COLOR_DEPTH_B8G8R8A8; 504 window.base[0] = gem->paddr;
208 break; 505
209 506 err = tegra_dc_setup_window(dc, 0, &window);
210 case DRM_FORMAT_RGB565: 507 if (err < 0)
211 win.fmt = WIN_COLOR_DEPTH_B5G6R5; 508 dev_err(dc->dev, "failed to enable root plane\n");
212 break;
213
214 default:
215 win.fmt = WIN_COLOR_DEPTH_B8G8R8A8;
216 WARN_ON(1);
217 break;
218 }
219
220 bpp = crtc->fb->bits_per_pixel / 8;
221 win.stride = crtc->fb->pitches[0];
222
223 /* program window registers */
224 value = WINDOW_A_SELECT;
225 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
226
227 tegra_dc_writel(dc, win.fmt, DC_WIN_COLOR_DEPTH);
228 tegra_dc_writel(dc, 0, DC_WIN_BYTE_SWAP);
229
230 value = V_POSITION(win.outy) | H_POSITION(win.outx);
231 tegra_dc_writel(dc, value, DC_WIN_POSITION);
232
233 value = V_SIZE(win.outh) | H_SIZE(win.outw);
234 tegra_dc_writel(dc, value, DC_WIN_SIZE);
235
236 value = V_PRESCALED_SIZE(dfixed_trunc(win.h)) |
237 H_PRESCALED_SIZE(dfixed_trunc(win.w) * bpp);
238 tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
239
240 h_dda = compute_dda_inc(win.w, win.outw, false, bpp);
241 v_dda = compute_dda_inc(win.h, win.outh, true, bpp);
242
243 value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
244 tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
245
246 h_dda = compute_initial_dda(win.x);
247 v_dda = compute_initial_dda(win.y);
248
249 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
250 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
251
252 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
253 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
254
255 tegra_dc_writel(dc, fb->obj->paddr, DC_WINBUF_START_ADDR);
256 tegra_dc_writel(dc, win.stride, DC_WIN_LINE_STRIDE);
257 tegra_dc_writel(dc, dfixed_trunc(win.x) * bpp,
258 DC_WINBUF_ADDR_H_OFFSET);
259 tegra_dc_writel(dc, dfixed_trunc(win.y), DC_WINBUF_ADDR_V_OFFSET);
260
261 value = WIN_ENABLE;
262
263 if (bpp < 24)
264 value |= COLOR_EXPAND;
265
266 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
267
268 tegra_dc_writel(dc, 0xff00, DC_WIN_BLEND_NOKEY);
269 tegra_dc_writel(dc, 0xff00, DC_WIN_BLEND_1WIN);
270 509
271 return 0; 510 return 0;
272} 511}
@@ -347,7 +586,7 @@ static void tegra_crtc_load_lut(struct drm_crtc *crtc)
347} 586}
348 587
349static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = { 588static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
350 .dpms = tegra_crtc_dpms, 589 .disable = tegra_crtc_disable,
351 .mode_fixup = tegra_crtc_mode_fixup, 590 .mode_fixup = tegra_crtc_mode_fixup,
352 .mode_set = tegra_crtc_mode_set, 591 .mode_set = tegra_crtc_mode_set,
353 .prepare = tegra_crtc_prepare, 592 .prepare = tegra_crtc_prepare,
@@ -588,7 +827,7 @@ static int tegra_dc_show_regs(struct seq_file *s, void *data)
588 DUMP_REG(DC_WIN_BLEND_1WIN); 827 DUMP_REG(DC_WIN_BLEND_1WIN);
589 DUMP_REG(DC_WIN_BLEND_2WIN_X); 828 DUMP_REG(DC_WIN_BLEND_2WIN_X);
590 DUMP_REG(DC_WIN_BLEND_2WIN_Y); 829 DUMP_REG(DC_WIN_BLEND_2WIN_Y);
591 DUMP_REG(DC_WIN_BLEND32WIN_XY); 830 DUMP_REG(DC_WIN_BLEND_3WIN_XY);
592 DUMP_REG(DC_WIN_HP_FETCH_CONTROL); 831 DUMP_REG(DC_WIN_HP_FETCH_CONTROL);
593 DUMP_REG(DC_WINBUF_START_ADDR); 832 DUMP_REG(DC_WINBUF_START_ADDR);
594 DUMP_REG(DC_WINBUF_START_ADDR_NS); 833 DUMP_REG(DC_WINBUF_START_ADDR_NS);
@@ -690,6 +929,10 @@ static int tegra_dc_drm_init(struct host1x_client *client,
690 return err; 929 return err;
691 } 930 }
692 931
932 err = tegra_dc_add_planes(drm, dc);
933 if (err < 0)
934 return err;
935
693 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 936 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
694 err = tegra_dc_debugfs_init(dc, drm->primary); 937 err = tegra_dc_debugfs_init(dc, drm->primary);
695 if (err < 0) 938 if (err < 0)
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 99977b5d5c36..e2fa328861ca 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -290,8 +290,18 @@
290#define DC_DISP_SD_HW_K_VALUES 0x4dd 290#define DC_DISP_SD_HW_K_VALUES 0x4dd
291#define DC_DISP_SD_MAN_K_VALUES 0x4de 291#define DC_DISP_SD_MAN_K_VALUES 0x4de
292 292
293#define DC_WIN_CSC_YOF 0x611
294#define DC_WIN_CSC_KYRGB 0x612
295#define DC_WIN_CSC_KUR 0x613
296#define DC_WIN_CSC_KVR 0x614
297#define DC_WIN_CSC_KUG 0x615
298#define DC_WIN_CSC_KVG 0x616
299#define DC_WIN_CSC_KUB 0x617
300#define DC_WIN_CSC_KVB 0x618
301
293#define DC_WIN_WIN_OPTIONS 0x700 302#define DC_WIN_WIN_OPTIONS 0x700
294#define COLOR_EXPAND (1 << 6) 303#define COLOR_EXPAND (1 << 6)
304#define CSC_ENABLE (1 << 18)
295#define WIN_ENABLE (1 << 30) 305#define WIN_ENABLE (1 << 30)
296 306
297#define DC_WIN_BYTE_SWAP 0x701 307#define DC_WIN_BYTE_SWAP 0x701
@@ -359,7 +369,7 @@
359#define DC_WIN_BLEND_1WIN 0x710 369#define DC_WIN_BLEND_1WIN 0x710
360#define DC_WIN_BLEND_2WIN_X 0x711 370#define DC_WIN_BLEND_2WIN_X 0x711
361#define DC_WIN_BLEND_2WIN_Y 0x712 371#define DC_WIN_BLEND_2WIN_Y 0x712
362#define DC_WIN_BLEND32WIN_XY 0x713 372#define DC_WIN_BLEND_3WIN_XY 0x713
363 373
364#define DC_WIN_HP_FETCH_CONTROL 0x714 374#define DC_WIN_HP_FETCH_CONTROL 0x714
365 375
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 3c61aab5fcb7..896ff43d32b1 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -107,6 +107,30 @@ static inline unsigned long tegra_dc_readl(struct tegra_dc *dc,
107 return readl(dc->regs + (reg << 2)); 107 return readl(dc->regs + (reg << 2));
108} 108}
109 109
110struct tegra_dc_window {
111 struct {
112 unsigned int x;
113 unsigned int y;
114 unsigned int w;
115 unsigned int h;
116 } src;
117 struct {
118 unsigned int x;
119 unsigned int y;
120 unsigned int w;
121 unsigned int h;
122 } dst;
123 unsigned int bits_per_pixel;
124 unsigned int format;
125 unsigned int stride[2];
126 unsigned long base[3];
127};
128
129/* from dc.c */
130extern unsigned int tegra_dc_format(uint32_t format);
131extern int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
132 const struct tegra_dc_window *window);
133
110struct tegra_output_ops { 134struct tegra_output_ops {
111 int (*enable)(struct tegra_output *output); 135 int (*enable)(struct tegra_output *output);
112 int (*disable)(struct tegra_output *output); 136 int (*disable)(struct tegra_output *output);