aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-03-14 04:54:58 -0400
committerThierry Reding <treding@nvidia.com>2014-06-05 17:09:18 -0400
commit10288eea885bc32d2c856cd620aeeb83b5f3dd98 (patch)
treeba5d811fdd648895bda0790b5f219814869dec1b
parenteba66501ac41b717d60bebc6f9ae0f3195c6c422 (diff)
drm/tegra: dc - Reshuffle code to get rid of prototypes
The tegra_dc_format() and tegra_dc_setup_window() functions are only used internally by the display controller driver. Move them upwards in order to make them static and get rid of the function prototypes. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c496
-rw-r--r--drivers/gpu/drm/tegra/drm.h3
2 files changed, 248 insertions, 251 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 2571082a46eb..8b21e204a3ae 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -29,6 +29,254 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
29 return container_of(plane, struct tegra_plane, base); 29 return container_of(plane, struct tegra_plane, base);
30} 30}
31 31
32static unsigned int tegra_dc_format(uint32_t format, uint32_t *swap)
33{
34 /* assume no swapping of fetched data */
35 if (swap)
36 *swap = BYTE_SWAP_NOSWAP;
37
38 switch (format) {
39 case DRM_FORMAT_XBGR8888:
40 return WIN_COLOR_DEPTH_R8G8B8A8;
41
42 case DRM_FORMAT_XRGB8888:
43 return WIN_COLOR_DEPTH_B8G8R8A8;
44
45 case DRM_FORMAT_RGB565:
46 return WIN_COLOR_DEPTH_B5G6R5;
47
48 case DRM_FORMAT_UYVY:
49 return WIN_COLOR_DEPTH_YCbCr422;
50
51 case DRM_FORMAT_YUYV:
52 if (swap)
53 *swap = BYTE_SWAP_SWAP2;
54
55 return WIN_COLOR_DEPTH_YCbCr422;
56
57 case DRM_FORMAT_YUV420:
58 return WIN_COLOR_DEPTH_YCbCr420P;
59
60 case DRM_FORMAT_YUV422:
61 return WIN_COLOR_DEPTH_YCbCr422P;
62
63 default:
64 break;
65 }
66
67 WARN(1, "unsupported pixel format %u, using default\n", format);
68 return WIN_COLOR_DEPTH_B8G8R8A8;
69}
70
71static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
72{
73 switch (format) {
74 case WIN_COLOR_DEPTH_YCbCr422:
75 case WIN_COLOR_DEPTH_YUV422:
76 if (planar)
77 *planar = false;
78
79 return true;
80
81 case WIN_COLOR_DEPTH_YCbCr420P:
82 case WIN_COLOR_DEPTH_YUV420P:
83 case WIN_COLOR_DEPTH_YCbCr422P:
84 case WIN_COLOR_DEPTH_YUV422P:
85 case WIN_COLOR_DEPTH_YCbCr422R:
86 case WIN_COLOR_DEPTH_YUV422R:
87 case WIN_COLOR_DEPTH_YCbCr422RA:
88 case WIN_COLOR_DEPTH_YUV422RA:
89 if (planar)
90 *planar = true;
91
92 return true;
93 }
94
95 return false;
96}
97
98static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
99 unsigned int bpp)
100{
101 fixed20_12 outf = dfixed_init(out);
102 fixed20_12 inf = dfixed_init(in);
103 u32 dda_inc;
104 int max;
105
106 if (v)
107 max = 15;
108 else {
109 switch (bpp) {
110 case 2:
111 max = 8;
112 break;
113
114 default:
115 WARN_ON_ONCE(1);
116 /* fallthrough */
117 case 4:
118 max = 4;
119 break;
120 }
121 }
122
123 outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
124 inf.full -= dfixed_const(1);
125
126 dda_inc = dfixed_div(inf, outf);
127 dda_inc = min_t(u32, dda_inc, dfixed_const(max));
128
129 return dda_inc;
130}
131
132static inline u32 compute_initial_dda(unsigned int in)
133{
134 fixed20_12 inf = dfixed_init(in);
135 return dfixed_frac(inf);
136}
137
138static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
139 const struct tegra_dc_window *window)
140{
141 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
142 unsigned long value;
143 bool yuv, planar;
144
145 /*
146 * For YUV planar modes, the number of bytes per pixel takes into
147 * account only the luma component and therefore is 1.
148 */
149 yuv = tegra_dc_format_is_yuv(window->format, &planar);
150 if (!yuv)
151 bpp = window->bits_per_pixel / 8;
152 else
153 bpp = planar ? 1 : 2;
154
155 value = WINDOW_A_SELECT << index;
156 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
157
158 tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
159 tegra_dc_writel(dc, window->swap, DC_WIN_BYTE_SWAP);
160
161 value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x);
162 tegra_dc_writel(dc, value, DC_WIN_POSITION);
163
164 value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w);
165 tegra_dc_writel(dc, value, DC_WIN_SIZE);
166
167 h_offset = window->src.x * bpp;
168 v_offset = window->src.y;
169 h_size = window->src.w * bpp;
170 v_size = window->src.h;
171
172 value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
173 tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
174
175 /*
176 * For DDA computations the number of bytes per pixel for YUV planar
177 * modes needs to take into account all Y, U and V components.
178 */
179 if (yuv && planar)
180 bpp = 2;
181
182 h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
183 v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp);
184
185 value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
186 tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
187
188 h_dda = compute_initial_dda(window->src.x);
189 v_dda = compute_initial_dda(window->src.y);
190
191 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
192 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
193
194 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
195 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
196
197 tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR);
198
199 if (yuv && planar) {
200 tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U);
201 tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V);
202 value = window->stride[1] << 16 | window->stride[0];
203 tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE);
204 } else {
205 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
206 }
207
208 if (window->bottom_up)
209 v_offset += window->src.h - 1;
210
211 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
212 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
213
214 if (window->tiled) {
215 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
216 DC_WIN_BUFFER_ADDR_MODE_TILE;
217 } else {
218 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
219 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
220 }
221
222 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
223
224 value = WIN_ENABLE;
225
226 if (yuv) {
227 /* setup default colorspace conversion coefficients */
228 tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
229 tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
230 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
231 tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
232 tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
233 tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
234 tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
235 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
236
237 value |= CSC_ENABLE;
238 } else if (window->bits_per_pixel < 24) {
239 value |= COLOR_EXPAND;
240 }
241
242 if (window->bottom_up)
243 value |= V_DIRECTION;
244
245 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
246
247 /*
248 * Disable blending and assume Window A is the bottom-most window,
249 * Window C is the top-most window and Window B is in the middle.
250 */
251 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
252 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
253
254 switch (index) {
255 case 0:
256 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
257 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
258 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
259 break;
260
261 case 1:
262 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
263 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
264 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
265 break;
266
267 case 2:
268 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
269 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
270 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
271 break;
272 }
273
274 tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL);
275 tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL);
276
277 return 0;
278}
279
32static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, 280static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
33 struct drm_framebuffer *fb, int crtc_x, 281 struct drm_framebuffer *fb, int crtc_x,
34 int crtc_y, unsigned int crtc_w, 282 int crtc_y, unsigned int crtc_w,
@@ -338,46 +586,6 @@ static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
338 return true; 586 return true;
339} 587}
340 588
341static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v,
342 unsigned int bpp)
343{
344 fixed20_12 outf = dfixed_init(out);
345 fixed20_12 inf = dfixed_init(in);
346 u32 dda_inc;
347 int max;
348
349 if (v)
350 max = 15;
351 else {
352 switch (bpp) {
353 case 2:
354 max = 8;
355 break;
356
357 default:
358 WARN_ON_ONCE(1);
359 /* fallthrough */
360 case 4:
361 max = 4;
362 break;
363 }
364 }
365
366 outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
367 inf.full -= dfixed_const(1);
368
369 dda_inc = dfixed_div(inf, outf);
370 dda_inc = min_t(u32, dda_inc, dfixed_const(max));
371
372 return dda_inc;
373}
374
375static inline u32 compute_initial_dda(unsigned int in)
376{
377 fixed20_12 inf = dfixed_init(in);
378 return dfixed_frac(inf);
379}
380
381static int tegra_dc_set_timings(struct tegra_dc *dc, 589static int tegra_dc_set_timings(struct tegra_dc *dc,
382 struct drm_display_mode *mode) 590 struct drm_display_mode *mode)
383{ 591{
@@ -446,214 +654,6 @@ static int tegra_crtc_setup_clk(struct drm_crtc *crtc,
446 return 0; 654 return 0;
447} 655}
448 656
449static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar)
450{
451 switch (format) {
452 case WIN_COLOR_DEPTH_YCbCr422:
453 case WIN_COLOR_DEPTH_YUV422:
454 if (planar)
455 *planar = false;
456
457 return true;
458
459 case WIN_COLOR_DEPTH_YCbCr420P:
460 case WIN_COLOR_DEPTH_YUV420P:
461 case WIN_COLOR_DEPTH_YCbCr422P:
462 case WIN_COLOR_DEPTH_YUV422P:
463 case WIN_COLOR_DEPTH_YCbCr422R:
464 case WIN_COLOR_DEPTH_YUV422R:
465 case WIN_COLOR_DEPTH_YCbCr422RA:
466 case WIN_COLOR_DEPTH_YUV422RA:
467 if (planar)
468 *planar = true;
469
470 return true;
471 }
472
473 return false;
474}
475
476int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
477 const struct tegra_dc_window *window)
478{
479 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
480 unsigned long value;
481 bool yuv, planar;
482
483 /*
484 * For YUV planar modes, the number of bytes per pixel takes into
485 * account only the luma component and therefore is 1.
486 */
487 yuv = tegra_dc_format_is_yuv(window->format, &planar);
488 if (!yuv)
489 bpp = window->bits_per_pixel / 8;
490 else
491 bpp = planar ? 1 : 2;
492
493 value = WINDOW_A_SELECT << index;
494 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
495
496 tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
497 tegra_dc_writel(dc, window->swap, DC_WIN_BYTE_SWAP);
498
499 value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x);
500 tegra_dc_writel(dc, value, DC_WIN_POSITION);
501
502 value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w);
503 tegra_dc_writel(dc, value, DC_WIN_SIZE);
504
505 h_offset = window->src.x * bpp;
506 v_offset = window->src.y;
507 h_size = window->src.w * bpp;
508 v_size = window->src.h;
509
510 value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
511 tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE);
512
513 /*
514 * For DDA computations the number of bytes per pixel for YUV planar
515 * modes needs to take into account all Y, U and V components.
516 */
517 if (yuv && planar)
518 bpp = 2;
519
520 h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp);
521 v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp);
522
523 value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda);
524 tegra_dc_writel(dc, value, DC_WIN_DDA_INC);
525
526 h_dda = compute_initial_dda(window->src.x);
527 v_dda = compute_initial_dda(window->src.y);
528
529 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA);
530 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA);
531
532 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE);
533 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE);
534
535 tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR);
536
537 if (yuv && planar) {
538 tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U);
539 tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V);
540 value = window->stride[1] << 16 | window->stride[0];
541 tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE);
542 } else {
543 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE);
544 }
545
546 if (window->bottom_up)
547 v_offset += window->src.h - 1;
548
549 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET);
550 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET);
551
552 if (window->tiled) {
553 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV |
554 DC_WIN_BUFFER_ADDR_MODE_TILE;
555 } else {
556 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV |
557 DC_WIN_BUFFER_ADDR_MODE_LINEAR;
558 }
559
560 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE);
561
562 value = WIN_ENABLE;
563
564 if (yuv) {
565 /* setup default colorspace conversion coefficients */
566 tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF);
567 tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB);
568 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR);
569 tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR);
570 tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG);
571 tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG);
572 tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB);
573 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB);
574
575 value |= CSC_ENABLE;
576 } else if (window->bits_per_pixel < 24) {
577 value |= COLOR_EXPAND;
578 }
579
580 if (window->bottom_up)
581 value |= V_DIRECTION;
582
583 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS);
584
585 /*
586 * Disable blending and assume Window A is the bottom-most window,
587 * Window C is the top-most window and Window B is in the middle.
588 */
589 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY);
590 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN);
591
592 switch (index) {
593 case 0:
594 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X);
595 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
596 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
597 break;
598
599 case 1:
600 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
601 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y);
602 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY);
603 break;
604
605 case 2:
606 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X);
607 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y);
608 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY);
609 break;
610 }
611
612 tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL);
613 tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL);
614
615 return 0;
616}
617
618unsigned int tegra_dc_format(uint32_t format, uint32_t *swap)
619{
620 /* assume no swapping of fetched data */
621 if (swap)
622 *swap = BYTE_SWAP_NOSWAP;
623
624 switch (format) {
625 case DRM_FORMAT_XBGR8888:
626 return WIN_COLOR_DEPTH_R8G8B8A8;
627
628 case DRM_FORMAT_XRGB8888:
629 return WIN_COLOR_DEPTH_B8G8R8A8;
630
631 case DRM_FORMAT_RGB565:
632 return WIN_COLOR_DEPTH_B5G6R5;
633
634 case DRM_FORMAT_UYVY:
635 return WIN_COLOR_DEPTH_YCbCr422;
636
637 case DRM_FORMAT_YUYV:
638 if (swap)
639 *swap = BYTE_SWAP_SWAP2;
640
641 return WIN_COLOR_DEPTH_YCbCr422;
642
643 case DRM_FORMAT_YUV420:
644 return WIN_COLOR_DEPTH_YCbCr420P;
645
646 case DRM_FORMAT_YUV422:
647 return WIN_COLOR_DEPTH_YCbCr422P;
648
649 default:
650 break;
651 }
652
653 WARN(1, "unsupported pixel format %u, using default\n", format);
654 return WIN_COLOR_DEPTH_B8G8R8A8;
655}
656
657static int tegra_crtc_mode_set(struct drm_crtc *crtc, 657static int tegra_crtc_mode_set(struct drm_crtc *crtc,
658 struct drm_display_mode *mode, 658 struct drm_display_mode *mode,
659 struct drm_display_mode *adjusted, 659 struct drm_display_mode *adjusted,
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 302bfee83f0a..ded44b29dc1d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -164,9 +164,6 @@ struct tegra_dc_window {
164}; 164};
165 165
166/* from dc.c */ 166/* from dc.c */
167unsigned int tegra_dc_format(uint32_t format, unsigned int *swap);
168int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
169 const struct tegra_dc_window *window);
170void tegra_dc_enable_vblank(struct tegra_dc *dc); 167void tegra_dc_enable_vblank(struct tegra_dc *dc);
171void tegra_dc_disable_vblank(struct tegra_dc *dc); 168void tegra_dc_disable_vblank(struct tegra_dc *dc);
172void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); 169void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);