aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2012-11-04 15:47:13 -0500
committerThierry Reding <thierry.reding@avionic-design.de>2013-02-22 02:21:12 -0500
commitf34bc78741815d0ad07298a42101a1ee2e2bcdd2 (patch)
tree135f6561469b6536ed8d66caca13583fcb17e665
parent894752bb576a26d3343cf8c674b73899f948da68 (diff)
drm/tegra: Add plane support
Add support for the B and C planes which support RGB and YUV pixel formats and can be used as overlays or hardware cursor. Currently 32-bit XRGB as well as UYVY, YUV420 and YUV422 pixel formats are advertised. Other formats should be easy to add but these are the most common ones and should cover the majority of use-cases. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
-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);