1 /*-
2 * Copyright (c) 2015 Michal Meloun
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/bus.h>
31 #include <sys/gpio.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.h>
35 #include <sys/rman.h>
36 #include <sys/sysctl.h>
37
38 #include <machine/bus.h>
39
40 #include <dev/extres/clk/clk.h>
41 #include <dev/extres/hwreset/hwreset.h>
42 #include <dev/drm2/drmP.h>
43 #include <dev/drm2/drm_crtc_helper.h>
44 #include <dev/drm2/drm_fb_helper.h>
45 #include <dev/drm2/drm_fixed.h>
46 #include <dev/ofw/ofw_bus.h>
47 #include <dev/ofw/ofw_bus_subr.h>
48
49 #include <arm/nvidia/drm2/tegra_dc_reg.h>
50 #include <arm/nvidia/drm2/tegra_drm.h>
51 #include <arm/nvidia/tegra_pmc.h>
52
53 #include "tegra_drm_if.h"
54 #include "tegra_dc_if.h"
55
56 #define WR4(_sc, _r, _v) bus_write_4((_sc)->mem_res, 4 * (_r), (_v))
57 #define RD4(_sc, _r) bus_read_4((_sc)->mem_res, 4 * (_r))
58
59 #define LOCK(_sc) mtx_lock(&(_sc)->mtx)
60 #define UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
61 #define SLEEP(_sc, timeout) \
62 mtx_sleep(sc, &sc->mtx, 0, "tegra_dc_wait", timeout);
63 #define LOCK_INIT(_sc) \
64 mtx_init(&_sc->mtx, device_get_nameunit(_sc->dev), "tegra_dc", MTX_DEF)
65 #define LOCK_DESTROY(_sc) mtx_destroy(&_sc->mtx)
66 #define ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED)
67 #define ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->mtx, MA_NOTOWNED)
68
69 #define SYNCPT_VBLANK0 26
70 #define SYNCPT_VBLANK1 27
71
72 #define DC_MAX_PLANES 2 /* Maximum planes */
73
74 /* DRM Formats supported by DC */
75 /* XXXX expand me */
76 static uint32_t dc_plane_formats[] = {
77 DRM_FORMAT_XBGR8888,
78 DRM_FORMAT_XRGB8888,
79 DRM_FORMAT_RGB565,
80 DRM_FORMAT_UYVY,
81 DRM_FORMAT_YUYV,
82 DRM_FORMAT_YUV420,
83 DRM_FORMAT_YUV422,
84 };
85
86 /* Complete description of one window (plane) */
87 struct dc_window {
88 /* Source (in framebuffer) rectangle, in pixels */
89 u_int src_x;
90 u_int src_y;
91 u_int src_w;
92 u_int src_h;
93
94 /* Destination (on display) rectangle, in pixels */
95 u_int dst_x;
96 u_int dst_y;
97 u_int dst_w;
98 u_int dst_h;
99
100 /* Parsed pixel format */
101 u_int bits_per_pixel;
102 bool is_yuv; /* any YUV mode */
103 bool is_yuv_planar; /* planar YUV mode */
104 uint32_t color_mode; /* DC_WIN_COLOR_DEPTH */
105 uint32_t swap; /* DC_WIN_BYTE_SWAP */
106 uint32_t surface_kind; /* DC_WINBUF_SURFACE_KIND */
107 uint32_t block_height; /* DC_WINBUF_SURFACE_KIND */
108
109 /* Parsed flipping, rotation is not supported for pitched modes */
110 bool flip_x; /* inverted X-axis */
111 bool flip_y; /* inverted Y-axis */
112 bool transpose_xy; /* swap X and Y-axis */
113
114 /* Color planes base addresses and strides */
115 bus_size_t base[3];
116 uint32_t stride[3]; /* stride[2] isn't used by HW */
117 };
118
119 struct dc_softc {
120 device_t dev;
121 struct resource *mem_res;
122 struct resource *irq_res;
123 void *irq_ih;
124 struct mtx mtx;
125
126 clk_t clk_parent;
127 clk_t clk_dc;
128 hwreset_t hwreset_dc;
129
130 int pitch_align;
131
132 struct tegra_crtc tegra_crtc;
133 struct drm_pending_vblank_event *event;
134 struct drm_gem_object *cursor_gem;
135 };
136
137 static struct ofw_compat_data compat_data[] = {
138 {"nvidia,tegra124-dc", 1},
139 {NULL, 0},
140 };
141
142 /* Convert standard drm pixel format to tegra windows parameters. */
143 static int
dc_parse_drm_format(struct tegra_fb * fb,struct dc_window * win)144 dc_parse_drm_format(struct tegra_fb *fb, struct dc_window *win)
145 {
146 struct tegra_bo *bo;
147 uint32_t cm;
148 uint32_t sw;
149 bool is_yuv, is_yuv_planar;
150 int nplanes, i;
151
152 switch (fb->drm_fb.pixel_format) {
153 case DRM_FORMAT_XBGR8888:
154 sw = BYTE_SWAP(NOSWAP);
155 cm = WIN_COLOR_DEPTH_R8G8B8A8;
156 is_yuv = false;
157 is_yuv_planar = false;
158 break;
159
160 case DRM_FORMAT_XRGB8888:
161 sw = BYTE_SWAP(NOSWAP);
162 cm = WIN_COLOR_DEPTH_B8G8R8A8;
163 is_yuv = false;
164 is_yuv_planar = false;
165 break;
166
167 case DRM_FORMAT_RGB565:
168 sw = BYTE_SWAP(NOSWAP);
169 cm = WIN_COLOR_DEPTH_B5G6R5;
170 is_yuv = false;
171 is_yuv_planar = false;
172 break;
173
174 case DRM_FORMAT_UYVY:
175 sw = BYTE_SWAP(NOSWAP);
176 cm = WIN_COLOR_DEPTH_YCbCr422;
177 is_yuv = true;
178 is_yuv_planar = false;
179 break;
180
181 case DRM_FORMAT_YUYV:
182 sw = BYTE_SWAP(SWAP2);
183 cm = WIN_COLOR_DEPTH_YCbCr422;
184 is_yuv = true;
185 is_yuv_planar = false;
186 break;
187
188 case DRM_FORMAT_YUV420:
189 sw = BYTE_SWAP(NOSWAP);
190 cm = WIN_COLOR_DEPTH_YCbCr420P;
191 is_yuv = true;
192 is_yuv_planar = true;
193 break;
194
195 case DRM_FORMAT_YUV422:
196 sw = BYTE_SWAP(NOSWAP);
197 cm = WIN_COLOR_DEPTH_YCbCr422P;
198 is_yuv = true;
199 is_yuv_planar = true;
200 break;
201
202 default:
203 /* Unsupported format */
204 return (-EINVAL);
205 }
206
207 /* Basic check of arguments. */
208 switch (fb->rotation) {
209 case 0:
210 case 180:
211 break;
212
213 case 90: /* Rotation is supported only */
214 case 270: /* for block linear surfaces */
215 if (!fb->block_linear)
216 return (-EINVAL);
217 break;
218
219 default:
220 return (-EINVAL);
221 }
222 /* XXX Add more checks (sizes, scaling...) */
223
224 if (win == NULL)
225 return (0);
226
227 win->surface_kind =
228 fb->block_linear ? SURFACE_KIND_BL_16B2: SURFACE_KIND_PITCH;
229 win->block_height = fb->block_height;
230 switch (fb->rotation) {
231 case 0: /* (0,0,0) */
232 win->transpose_xy = false;
233 win->flip_x = false;
234 win->flip_y = false;
235 break;
236
237 case 90: /* (1,0,1) */
238 win->transpose_xy = true;
239 win->flip_x = false;
240 win->flip_y = true;
241 break;
242
243 case 180: /* (0,1,1) */
244 win->transpose_xy = false;
245 win->flip_x = true;
246 win->flip_y = true;
247 break;
248
249 case 270: /* (1,1,0) */
250 win->transpose_xy = true;
251 win->flip_x = true;
252 win->flip_y = false;
253 break;
254 }
255 win->flip_x ^= fb->flip_x;
256 win->flip_y ^= fb->flip_y;
257
258 win->color_mode = cm;
259 win->swap = sw;
260 win->bits_per_pixel = fb->drm_fb.bits_per_pixel;
261 win->is_yuv = is_yuv;
262 win->is_yuv_planar = is_yuv_planar;
263
264 nplanes = drm_format_num_planes(fb->drm_fb.pixel_format);
265 for (i = 0; i < nplanes; i++) {
266 bo = fb->planes[i];
267 win->base[i] = bo->pbase + fb->drm_fb.offsets[i];
268 win->stride[i] = fb->drm_fb.pitches[i];
269 }
270 return (0);
271 }
272
273 /*
274 * Scaling functions.
275 *
276 * It's unclear if we want/must program the fractional portion
277 * (aka bias) of init_dda registers, mainly when mirrored axis
278 * modes are used.
279 * For now, we use 1.0 as recommended by TRM.
280 */
281 static inline uint32_t
dc_scaling_init(uint32_t start)282 dc_scaling_init(uint32_t start)
283 {
284
285 return (1 << 12);
286 }
287
288 static inline uint32_t
dc_scaling_incr(uint32_t src,uint32_t dst,uint32_t maxscale)289 dc_scaling_incr(uint32_t src, uint32_t dst, uint32_t maxscale)
290 {
291 uint32_t val;
292
293 val = (src - 1) << 12 ; /* 4.12 fixed float */
294 val /= (dst - 1);
295 if (val > (maxscale << 12))
296 val = maxscale << 12;
297 return val;
298 }
299
300 /* -------------------------------------------------------------------
301 *
302 * HW Access.
303 *
304 */
305
306 /*
307 * Setup pixel clock.
308 * Minimal frequency is pixel clock, but output is free to select
309 * any higher.
310 */
311 static int
dc_setup_clk(struct dc_softc * sc,struct drm_crtc * crtc,struct drm_display_mode * mode,uint32_t * div)312 dc_setup_clk(struct dc_softc *sc, struct drm_crtc *crtc,
313 struct drm_display_mode *mode, uint32_t *div)
314 {
315 uint64_t pclk, freq;
316 struct tegra_drm_encoder *output;
317 struct drm_encoder *encoder;
318 long rv;
319
320 pclk = mode->clock * 1000;
321
322 /* Find attached encoder */
323 output = NULL;
324 list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list,
325 head) {
326 if (encoder->crtc == crtc) {
327 output = container_of(encoder, struct tegra_drm_encoder,
328 encoder);
329 break;
330 }
331 }
332 if (output == NULL)
333 return (-ENODEV);
334
335 if (output->setup_clock == NULL)
336 panic("Output have not setup_clock function.\n");
337 rv = output->setup_clock(output, sc->clk_dc, pclk);
338 if (rv != 0) {
339 device_printf(sc->dev, "Cannot setup pixel clock: %llu\n",
340 pclk);
341 return (rv);
342 }
343
344 rv = clk_get_freq(sc->clk_dc, &freq);
345 *div = (freq * 2 / pclk) - 2;
346
347 DRM_DEBUG_KMS("frequency: %llu, DC divider: %u\n", freq, *div);
348
349 return 0;
350 }
351
352 static void
dc_setup_window(struct dc_softc * sc,unsigned int index,struct dc_window * win)353 dc_setup_window(struct dc_softc *sc, unsigned int index, struct dc_window *win)
354 {
355 uint32_t h_offset, v_offset, h_size, v_size, bpp;
356 uint32_t h_init_dda, v_init_dda, h_incr_dda, v_incr_dda;
357 uint32_t val;
358
359 #ifdef DMR_DEBUG_WINDOW
360 printf("%s window: %d\n", __func__, index);
361 printf(" src: x: %d, y: %d, w: %d, h: %d\n",
362 win->src_x, win->src_y, win->src_w, win->src_h);
363 printf(" dst: x: %d, y: %d, w: %d, h: %d\n",
364 win->dst_x, win->dst_y, win->dst_w, win->dst_h);
365 printf(" bpp: %d, color_mode: %d, swap: %d\n",
366 win->bits_per_pixel, win->color_mode, win->swap);
367 #endif
368
369 if (win->is_yuv)
370 bpp = win->is_yuv_planar ? 1 : 2;
371 else
372 bpp = (win->bits_per_pixel + 7) / 8;
373
374 if (!win->transpose_xy) {
375 h_size = win->src_w * bpp;
376 v_size = win->src_h;
377 } else {
378 h_size = win->src_h * bpp;
379 v_size = win->src_w;
380 }
381
382 h_offset = win->src_x * bpp;
383 v_offset = win->src_y;
384 if (win->flip_x) {
385 h_offset += win->src_w * bpp - 1;
386 }
387 if (win->flip_y)
388 v_offset += win->src_h - 1;
389
390 /* Adjust offsets for planar yuv modes */
391 if (win->is_yuv_planar) {
392 h_offset &= ~1;
393 if (win->flip_x )
394 h_offset |= 1;
395 v_offset &= ~1;
396 if (win->flip_y )
397 v_offset |= 1;
398 }
399
400 /* Setup scaling. */
401 if (!win->transpose_xy) {
402 h_init_dda = dc_scaling_init(win->src_x);
403 v_init_dda = dc_scaling_init(win->src_y);
404 h_incr_dda = dc_scaling_incr(win->src_w, win->dst_w, 4);
405 v_incr_dda = dc_scaling_incr(win->src_h, win->dst_h, 15);
406 } else {
407 h_init_dda = dc_scaling_init(win->src_y);
408 v_init_dda = dc_scaling_init(win->src_x);
409 h_incr_dda = dc_scaling_incr(win->src_h, win->dst_h, 4);
410 v_incr_dda = dc_scaling_incr(win->src_w, win->dst_w, 15);
411 }
412 #ifdef DMR_DEBUG_WINDOW
413 printf("\n");
414 printf(" bpp: %d, size: h: %d v: %d, offset: h:%d v: %d\n",
415 bpp, h_size, v_size, h_offset, v_offset);
416 printf(" init_dda: h: %d v: %d, incr_dda: h: %d v: %d\n",
417 h_init_dda, v_init_dda, h_incr_dda, v_incr_dda);
418 #endif
419
420 LOCK(sc);
421
422 /* Select target window */
423 val = WINDOW_A_SELECT << index;
424 WR4(sc, DC_CMD_DISPLAY_WINDOW_HEADER, val);
425
426 /* Sizes */
427 WR4(sc, DC_WIN_POSITION, WIN_POSITION(win->dst_x, win->dst_y));
428 WR4(sc, DC_WIN_SIZE, WIN_SIZE(win->dst_w, win->dst_h));
429 WR4(sc, DC_WIN_PRESCALED_SIZE, WIN_PRESCALED_SIZE(h_size, v_size));
430
431 /* DDA */
432 WR4(sc, DC_WIN_DDA_INCREMENT,
433 WIN_DDA_INCREMENT(h_incr_dda, v_incr_dda));
434 WR4(sc, DC_WIN_H_INITIAL_DDA, h_init_dda);
435 WR4(sc, DC_WIN_V_INITIAL_DDA, v_init_dda);
436
437 /* Color planes base addresses and strides */
438 WR4(sc, DC_WINBUF_START_ADDR, win->base[0]);
439 if (win->is_yuv_planar) {
440 WR4(sc, DC_WINBUF_START_ADDR_U, win->base[1]);
441 WR4(sc, DC_WINBUF_START_ADDR_V, win->base[2]);
442 WR4(sc, DC_WIN_LINE_STRIDE,
443 win->stride[1] << 16 | win->stride[0]);
444 } else {
445 WR4(sc, DC_WIN_LINE_STRIDE, win->stride[0]);
446 }
447
448 /* Offsets for rotation and axis flip */
449 WR4(sc, DC_WINBUF_ADDR_H_OFFSET, h_offset);
450 WR4(sc, DC_WINBUF_ADDR_V_OFFSET, v_offset);
451
452 /* Color format */
453 WR4(sc, DC_WIN_COLOR_DEPTH, win->color_mode);
454 WR4(sc, DC_WIN_BYTE_SWAP, win->swap);
455
456 /* Tiling */
457 val = win->surface_kind;
458 if (win->surface_kind == SURFACE_KIND_BL_16B2)
459 val |= SURFACE_KIND_BLOCK_HEIGHT(win->block_height);
460 WR4(sc, DC_WINBUF_SURFACE_KIND, val);
461
462 /* Color space coefs for YUV modes */
463 if (win->is_yuv) {
464 WR4(sc, DC_WINC_CSC_YOF, 0x00f0);
465 WR4(sc, DC_WINC_CSC_KYRGB, 0x012a);
466 WR4(sc, DC_WINC_CSC_KUR, 0x0000);
467 WR4(sc, DC_WINC_CSC_KVR, 0x0198);
468 WR4(sc, DC_WINC_CSC_KUG, 0x039b);
469 WR4(sc, DC_WINC_CSC_KVG, 0x032f);
470 WR4(sc, DC_WINC_CSC_KUB, 0x0204);
471 WR4(sc, DC_WINC_CSC_KVB, 0x0000);
472 }
473
474 val = WIN_ENABLE;
475 if (win->is_yuv)
476 val |= CSC_ENABLE;
477 else if (win->bits_per_pixel < 24)
478 val |= COLOR_EXPAND;
479 if (win->flip_y)
480 val |= V_DIRECTION;
481 if (win->flip_x)
482 val |= H_DIRECTION;
483 if (win->transpose_xy)
484 val |= SCAN_COLUMN;
485 WR4(sc, DC_WINC_WIN_OPTIONS, val);
486
487 #ifdef DMR_DEBUG_WINDOW
488 /* Set underflow debug mode -> highlight missing pixels. */
489 WR4(sc, DC_WINBUF_UFLOW_CTRL, UFLOW_CTR_ENABLE);
490 WR4(sc, DC_WINBUF_UFLOW_DBG_PIXEL, 0xFFFF0000);
491 #endif
492
493 UNLOCK(sc);
494 }
495
496 /* -------------------------------------------------------------------
497 *
498 * Plane functions.
499 *
500 */
501 static int
dc_plane_update(struct drm_plane * drm_plane,struct drm_crtc * drm_crtc,struct drm_framebuffer * drm_fb,int crtc_x,int crtc_y,unsigned int crtc_w,unsigned int crtc_h,uint32_t src_x,uint32_t src_y,uint32_t src_w,uint32_t src_h)502 dc_plane_update(struct drm_plane *drm_plane, struct drm_crtc *drm_crtc,
503 struct drm_framebuffer *drm_fb,
504 int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h,
505 uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h)
506 {
507 struct tegra_plane *plane;
508 struct tegra_crtc *crtc;
509 struct tegra_fb *fb;
510 struct dc_softc *sc;
511 struct dc_window win;
512 int rv;
513
514 plane = container_of(drm_plane, struct tegra_plane, drm_plane);
515 fb = container_of(drm_fb, struct tegra_fb, drm_fb);
516 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
517 sc = device_get_softc(crtc->dev);
518
519 memset(&win, 0, sizeof(win));
520 win.src_x = src_x >> 16;
521 win.src_y = src_y >> 16;
522 win.src_w = src_w >> 16;
523 win.src_h = src_h >> 16;
524 win.dst_x = crtc_x;
525 win.dst_y = crtc_y;
526 win.dst_w = crtc_w;
527 win.dst_h = crtc_h;
528
529 rv = dc_parse_drm_format(fb, &win);
530 if (rv != 0) {
531 DRM_WARNING("unsupported pixel format %d\n",
532 fb->drm_fb.pixel_format);
533 return (rv);
534 }
535
536 dc_setup_window(sc, plane->index, &win);
537
538 WR4(sc, DC_CMD_STATE_CONTROL, WIN_A_UPDATE << plane->index);
539 WR4(sc, DC_CMD_STATE_CONTROL, WIN_A_ACT_REQ << plane->index);
540
541 return (0);
542 }
543
544 static int
dc_plane_disable(struct drm_plane * drm_plane)545 dc_plane_disable(struct drm_plane *drm_plane)
546 {
547 struct tegra_plane *plane;
548 struct tegra_crtc *crtc;
549 struct dc_softc *sc;
550 uint32_t val, idx;
551
552 if (drm_plane->crtc == NULL)
553 return (0);
554 plane = container_of(drm_plane, struct tegra_plane, drm_plane);
555 crtc = container_of(drm_plane->crtc, struct tegra_crtc, drm_crtc);
556
557 sc = device_get_softc(crtc->dev);
558 idx = plane->index;
559
560 LOCK(sc);
561
562 WR4(sc, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT << idx);
563
564 val = RD4(sc, DC_WINC_WIN_OPTIONS);
565 val &= ~WIN_ENABLE;
566 WR4(sc, DC_WINC_WIN_OPTIONS, val);
567
568 UNLOCK(sc);
569
570 WR4(sc, DC_CMD_STATE_CONTROL, WIN_A_UPDATE << idx);
571 WR4(sc, DC_CMD_STATE_CONTROL, WIN_A_ACT_REQ << idx);
572
573 return (0);
574 }
575
576 static void
dc_plane_destroy(struct drm_plane * plane)577 dc_plane_destroy(struct drm_plane *plane)
578 {
579
580 dc_plane_disable(plane);
581 drm_plane_cleanup(plane);
582 free(plane, DRM_MEM_KMS);
583 }
584
585 static const struct drm_plane_funcs dc_plane_funcs = {
586 .update_plane = dc_plane_update,
587 .disable_plane = dc_plane_disable,
588 .destroy = dc_plane_destroy,
589 };
590
591 /* -------------------------------------------------------------------
592 *
593 * CRTC helper functions.
594 *
595 */
596 static void
dc_crtc_dpms(struct drm_crtc * crtc,int mode)597 dc_crtc_dpms(struct drm_crtc *crtc, int mode)
598 {
599 /* Empty function */
600 }
601
602 static bool
dc_crtc_mode_fixup(struct drm_crtc * crtc,const struct drm_display_mode * mode,struct drm_display_mode * adjusted)603 dc_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode,
604 struct drm_display_mode *adjusted)
605 {
606
607 return (true);
608 }
609
610 static int
dc_set_base(struct dc_softc * sc,int x,int y,struct tegra_fb * fb)611 dc_set_base(struct dc_softc *sc, int x, int y, struct tegra_fb *fb)
612 {
613 struct dc_window win;
614 int rv;
615
616 memset(&win, 0, sizeof(win));
617 win.src_x = x;
618 win.src_y = y;
619 win.src_w = fb->drm_fb.width;
620 win.src_h = fb->drm_fb.height;
621 win.dst_x = x;
622 win.dst_y = y;
623 win.dst_w = fb->drm_fb.width;
624 win.dst_h = fb->drm_fb.height;
625
626 rv = dc_parse_drm_format(fb, &win);
627 if (rv != 0) {
628 DRM_WARNING("unsupported pixel format %d\n",
629 fb->drm_fb.pixel_format);
630 return (rv);
631 }
632 dc_setup_window(sc, 0, &win);
633
634 return (0);
635 }
636
637 static int
dc_crtc_mode_set(struct drm_crtc * drm_crtc,struct drm_display_mode * mode,struct drm_display_mode * adjusted,int x,int y,struct drm_framebuffer * old_fb)638 dc_crtc_mode_set(struct drm_crtc *drm_crtc, struct drm_display_mode *mode,
639 struct drm_display_mode *adjusted, int x, int y,
640 struct drm_framebuffer *old_fb)
641 {
642 struct dc_softc *sc;
643 struct tegra_crtc *crtc;
644 struct tegra_fb *fb;
645 struct dc_window win;
646 uint32_t div, h_ref_to_sync, v_ref_to_sync;
647 int rv;
648
649 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
650 sc = device_get_softc(crtc->dev);
651 fb = container_of(drm_crtc->fb, struct tegra_fb, drm_fb);
652
653 h_ref_to_sync = 1;
654 v_ref_to_sync = 1;
655 /* Setup timing */
656 rv = dc_setup_clk(sc, drm_crtc, mode, &div);
657 if (rv != 0) {
658 device_printf(sc->dev, "Cannot set pixel clock\n");
659 return (rv);
660 }
661
662 /* Timing */
663 WR4(sc, DC_DISP_DISP_TIMING_OPTIONS, 0);
664
665 WR4(sc, DC_DISP_REF_TO_SYNC,
666 (v_ref_to_sync << 16) |
667 h_ref_to_sync);
668
669 WR4(sc, DC_DISP_SYNC_WIDTH,
670 ((mode->vsync_end - mode->vsync_start) << 16) |
671 ((mode->hsync_end - mode->hsync_start) << 0));
672
673 WR4(sc, DC_DISP_BACK_PORCH,
674 ((mode->vtotal - mode->vsync_end) << 16) |
675 ((mode->htotal - mode->hsync_end) << 0));
676
677 WR4(sc, DC_DISP_FRONT_PORCH,
678 ((mode->vsync_start - mode->vdisplay) << 16) |
679 ((mode->hsync_start - mode->hdisplay) << 0));
680
681 WR4(sc, DC_DISP_DISP_ACTIVE,
682 (mode->vdisplay << 16) | mode->hdisplay);
683
684 WR4(sc, DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT(DF1P1C));
685
686 WR4(sc,DC_DISP_DISP_CLOCK_CONTROL,
687 SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER(PCD1));
688
689 memset(&win, 0, sizeof(win));
690 win.src_x = x;
691 win.src_y = y;
692 win.src_w = mode->hdisplay;
693 win.src_h = mode->vdisplay;
694 win.dst_x = x;
695 win.dst_y = y;
696 win.dst_w = mode->hdisplay;
697 win.dst_h = mode->vdisplay;
698
699 rv = dc_parse_drm_format(fb, &win);
700 if (rv != 0) {
701 DRM_WARNING("unsupported pixel format %d\n",
702 drm_crtc->fb->pixel_format);
703 return (rv);
704 }
705
706 dc_setup_window(sc, 0, &win);
707
708 return (0);
709
710 }
711
712 static int
dc_crtc_mode_set_base(struct drm_crtc * drm_crtc,int x,int y,struct drm_framebuffer * old_fb)713 dc_crtc_mode_set_base(struct drm_crtc *drm_crtc, int x, int y,
714 struct drm_framebuffer *old_fb)
715 {
716 struct dc_softc *sc;
717 struct tegra_crtc *crtc;
718 struct tegra_fb *fb;
719 int rv;
720
721 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
722 fb = container_of(drm_crtc->fb, struct tegra_fb, drm_fb);
723 sc = device_get_softc(crtc->dev);
724
725 rv = dc_set_base(sc, x, y, fb);
726
727 /* Commit */
728 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE);
729 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ);
730 return (rv);
731 }
732
733 static void
dc_crtc_prepare(struct drm_crtc * drm_crtc)734 dc_crtc_prepare(struct drm_crtc *drm_crtc)
735 {
736
737 struct dc_softc *sc;
738 struct tegra_crtc *crtc;
739 uint32_t val;
740
741 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
742 sc = device_get_softc(crtc->dev);
743
744 WR4(sc, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL, SYNCPT_CNTRL_NO_STALL);
745 /* XXX allocate syncpoint from host1x */
746 WR4(sc, DC_CMD_CONT_SYNCPT_VSYNC, SYNCPT_VSYNC_ENABLE |
747 (sc->tegra_crtc.nvidia_head == 0 ? SYNCPT_VBLANK0: SYNCPT_VBLANK1));
748
749 WR4(sc, DC_CMD_DISPLAY_POWER_CONTROL,
750 PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
751 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
752
753 val = RD4(sc, DC_CMD_DISPLAY_COMMAND);
754 val |= DISPLAY_CTRL_MODE(CTRL_MODE_C_DISPLAY);
755 WR4(sc, DC_CMD_DISPLAY_COMMAND, val);
756
757 WR4(sc, DC_CMD_INT_MASK,
758 WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
759 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT);
760
761 WR4(sc, DC_CMD_INT_ENABLE,
762 VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
763 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT);
764 }
765
766 static void
dc_crtc_commit(struct drm_crtc * drm_crtc)767 dc_crtc_commit(struct drm_crtc *drm_crtc)
768 {
769 struct dc_softc *sc;
770 struct tegra_crtc *crtc;
771 uint32_t val;
772
773 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
774 sc = device_get_softc(crtc->dev);
775
776 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE);
777
778 val = RD4(sc, DC_CMD_INT_MASK);
779 val |= FRAME_END_INT;
780 WR4(sc, DC_CMD_INT_MASK, val);
781
782 val = RD4(sc, DC_CMD_INT_ENABLE);
783 val |= FRAME_END_INT;
784 WR4(sc, DC_CMD_INT_ENABLE, val);
785
786 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ);
787 }
788
789 static void
dc_crtc_load_lut(struct drm_crtc * crtc)790 dc_crtc_load_lut(struct drm_crtc *crtc)
791 {
792
793 /* empty function */
794 }
795
796 static const struct drm_crtc_helper_funcs dc_crtc_helper_funcs = {
797 .dpms = dc_crtc_dpms,
798 .mode_fixup = dc_crtc_mode_fixup,
799 .mode_set = dc_crtc_mode_set,
800 .mode_set_base = dc_crtc_mode_set_base,
801 .prepare = dc_crtc_prepare,
802 .commit = dc_crtc_commit,
803 .load_lut = dc_crtc_load_lut,
804 };
805
806 static int
drm_crtc_index(struct drm_crtc * crtc)807 drm_crtc_index(struct drm_crtc *crtc)
808 {
809 int idx;
810 struct drm_crtc *tmp;
811
812 idx = 0;
813 list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
814 if (tmp == crtc)
815 return (idx);
816 idx++;
817 }
818 panic("Cannot find CRTC");
819 }
820
821 /* -------------------------------------------------------------------
822 *
823 * Exported functions (mainly vsync related).
824 *
825 * XXX revisit this -> convert to bus methods?
826 */
827 int
tegra_dc_get_pipe(struct drm_crtc * drm_crtc)828 tegra_dc_get_pipe(struct drm_crtc *drm_crtc)
829 {
830 struct tegra_crtc *crtc;
831
832 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
833 return (crtc->nvidia_head);
834 }
835
836 void
tegra_dc_enable_vblank(struct drm_crtc * drm_crtc)837 tegra_dc_enable_vblank(struct drm_crtc *drm_crtc)
838 {
839 struct dc_softc *sc;
840 struct tegra_crtc *crtc;
841 uint32_t val;
842
843 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
844 sc = device_get_softc(crtc->dev);
845
846 LOCK(sc);
847 val = RD4(sc, DC_CMD_INT_MASK);
848 val |= VBLANK_INT;
849 WR4(sc, DC_CMD_INT_MASK, val);
850 UNLOCK(sc);
851 }
852
853 void
tegra_dc_disable_vblank(struct drm_crtc * drm_crtc)854 tegra_dc_disable_vblank(struct drm_crtc *drm_crtc)
855 {
856 struct dc_softc *sc;
857 struct tegra_crtc *crtc;
858 uint32_t val;
859
860 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
861 sc = device_get_softc(crtc->dev);
862
863 LOCK(sc);
864 val = RD4(sc, DC_CMD_INT_MASK);
865 val &= ~VBLANK_INT;
866 WR4(sc, DC_CMD_INT_MASK, val);
867 UNLOCK(sc);
868 }
869
870 static void
dc_finish_page_flip(struct dc_softc * sc)871 dc_finish_page_flip(struct dc_softc *sc)
872 {
873 struct drm_crtc *drm_crtc;
874 struct drm_device *drm;
875 struct tegra_fb *fb;
876 struct tegra_bo *bo;
877 uint32_t base;
878 int idx;
879
880 drm_crtc = &sc->tegra_crtc.drm_crtc;
881 drm = drm_crtc->dev;
882 fb = container_of(drm_crtc->fb, struct tegra_fb, drm_fb);
883
884 mtx_lock(&drm->event_lock);
885
886 if (sc->event == NULL) {
887 mtx_unlock(&drm->event_lock);
888 return;
889 }
890
891 LOCK(sc);
892 /* Read active copy of WINBUF_START_ADDR */
893 WR4(sc, DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT);
894 WR4(sc, DC_CMD_STATE_ACCESS, READ_MUX);
895 base = RD4(sc, DC_WINBUF_START_ADDR);
896 WR4(sc, DC_CMD_STATE_ACCESS, 0);
897 UNLOCK(sc);
898
899 /* Is already active */
900 bo = tegra_fb_get_plane(fb, 0);
901 if (base == (bo->pbase + fb->drm_fb.offsets[0])) {
902 idx = drm_crtc_index(drm_crtc);
903 drm_send_vblank_event(drm, idx, sc->event);
904 drm_vblank_put(drm, idx);
905 sc->event = NULL;
906 }
907
908 mtx_unlock(&drm->event_lock);
909 }
910
911 void
tegra_dc_cancel_page_flip(struct drm_crtc * drm_crtc,struct drm_file * file)912 tegra_dc_cancel_page_flip(struct drm_crtc *drm_crtc, struct drm_file *file)
913 {
914 struct dc_softc *sc;
915 struct tegra_crtc *crtc;
916 struct drm_device *drm;
917
918 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
919 sc = device_get_softc(crtc->dev);
920 drm = drm_crtc->dev;
921 mtx_lock(&drm->event_lock);
922
923 if ((sc->event != NULL) && (sc->event->base.file_priv == file)) {
924 sc->event->base.destroy(&sc->event->base);
925 drm_vblank_put(drm, drm_crtc_index(drm_crtc));
926 sc->event = NULL;
927 }
928 mtx_unlock(&drm->event_lock);
929 }
930
931 /* -------------------------------------------------------------------
932 *
933 * CRTC functions.
934 *
935 */
936 static int
dc_page_flip(struct drm_crtc * drm_crtc,struct drm_framebuffer * drm_fb,struct drm_pending_vblank_event * event)937 dc_page_flip(struct drm_crtc *drm_crtc, struct drm_framebuffer *drm_fb,
938 struct drm_pending_vblank_event *event)
939 {
940 struct dc_softc *sc;
941 struct tegra_crtc *crtc;
942 struct tegra_fb *fb;
943 struct drm_device *drm;
944
945 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
946 sc = device_get_softc(crtc->dev);
947 fb = container_of(drm_crtc->fb, struct tegra_fb, drm_fb);
948 drm = drm_crtc->dev;
949
950 if (sc->event != NULL)
951 return (-EBUSY);
952
953 if (event != NULL) {
954 event->pipe = sc->tegra_crtc.nvidia_head;
955 sc->event = event;
956 drm_vblank_get(drm, event->pipe);
957 }
958
959 dc_set_base(sc, drm_crtc->x, drm_crtc->y, fb);
960 drm_crtc->fb = drm_fb;
961
962 /* Commit */
963 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE);
964
965 return (0);
966 }
967
968 static int
dc_cursor_set(struct drm_crtc * drm_crtc,struct drm_file * file,uint32_t handle,uint32_t width,uint32_t height)969 dc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file,
970 uint32_t handle, uint32_t width, uint32_t height)
971 {
972
973 struct dc_softc *sc;
974 struct tegra_crtc *crtc;
975 struct drm_gem_object *gem;
976 struct tegra_bo *bo;
977 int i;
978 uint32_t val, *src, *dst;
979
980 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
981 sc = device_get_softc(crtc->dev);
982
983 if (width != height)
984 return (-EINVAL);
985
986 switch (width) {
987 case 32:
988 val = CURSOR_SIZE(C32x32);
989 break;
990 case 64:
991 val = CURSOR_SIZE(C64x64);
992 break;
993 case 128:
994 val = CURSOR_SIZE(C128x128);
995 break;
996 case 256:
997 val = CURSOR_SIZE(C256x256);
998 break;
999 default:
1000 return (-EINVAL);
1001 }
1002
1003 bo = NULL;
1004 gem = NULL;
1005 if (handle != 0) {
1006 gem = drm_gem_object_lookup(drm_crtc->dev, file, handle);
1007 if (gem == NULL)
1008 return (-ENOENT);
1009 bo = container_of(gem, struct tegra_bo, gem_obj);
1010 }
1011
1012 if (sc->cursor_gem != NULL) {
1013 drm_gem_object_unreference(sc->cursor_gem);
1014 }
1015 sc->cursor_gem = gem;
1016
1017 if (bo != NULL) {
1018 /*
1019 * Copy cursor into cache and convert it from ARGB to RGBA.
1020 * XXXX - this is broken by design - client can write to BO at
1021 * any time. We can dedicate other window for cursor or switch
1022 * to sw cursor in worst case.
1023 */
1024 src = (uint32_t *)bo->vbase;
1025 dst = (uint32_t *)crtc->cursor_vbase;
1026 for (i = 0; i < width * height; i++)
1027 dst[i] = (src[i] << 8) | (src[i] >> 24);
1028
1029 val |= CURSOR_CLIP(CC_DISPLAY);
1030 val |= CURSOR_START_ADDR(crtc->cursor_pbase);
1031 WR4(sc, DC_DISP_CURSOR_START_ADDR, val);
1032
1033 val = RD4(sc, DC_DISP_BLEND_CURSOR_CONTROL);
1034 val &= ~CURSOR_DST_BLEND_FACTOR_SELECT(~0);
1035 val &= ~CURSOR_SRC_BLEND_FACTOR_SELECT(~0);
1036 val |= CURSOR_MODE_SELECT;
1037 val |= CURSOR_DST_BLEND_FACTOR_SELECT(DST_NEG_K1_TIMES_SRC);
1038 val |= CURSOR_SRC_BLEND_FACTOR_SELECT(SRC_BLEND_K1_TIMES_SRC);
1039 val |= CURSOR_ALPHA(~0);
1040 WR4(sc, DC_DISP_BLEND_CURSOR_CONTROL, val);
1041
1042 val = RD4(sc, DC_DISP_DISP_WIN_OPTIONS);
1043 val |= CURSOR_ENABLE;
1044 WR4(sc, DC_DISP_DISP_WIN_OPTIONS, val);
1045 } else {
1046 val = RD4(sc, DC_DISP_DISP_WIN_OPTIONS);
1047 val &= ~CURSOR_ENABLE;
1048 WR4(sc, DC_DISP_DISP_WIN_OPTIONS, val);
1049 }
1050
1051 /* XXX This fixes cursor underflow issues, but why ? */
1052 WR4(sc, DC_DISP_CURSOR_UNDERFLOW_CTRL, CURSOR_UFLOW_CYA);
1053
1054 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_UPDATE | CURSOR_UPDATE );
1055 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | CURSOR_ACT_REQ);
1056 return (0);
1057 }
1058
1059 static int
dc_cursor_move(struct drm_crtc * drm_crtc,int x,int y)1060 dc_cursor_move(struct drm_crtc *drm_crtc, int x, int y)
1061 {
1062 struct dc_softc *sc;
1063 struct tegra_crtc *crtc;
1064
1065 crtc = container_of(drm_crtc, struct tegra_crtc, drm_crtc);
1066 sc = device_get_softc(crtc->dev);
1067 WR4(sc, DC_DISP_CURSOR_POSITION, CURSOR_POSITION(x, y));
1068
1069 WR4(sc, DC_CMD_STATE_CONTROL, CURSOR_UPDATE);
1070 WR4(sc, DC_CMD_STATE_CONTROL, CURSOR_ACT_REQ);
1071
1072 return (0);
1073 }
1074
1075 static void
dc_destroy(struct drm_crtc * crtc)1076 dc_destroy(struct drm_crtc *crtc)
1077 {
1078
1079 drm_crtc_cleanup(crtc);
1080 memset(crtc, 0, sizeof(*crtc));
1081 }
1082
1083 static const struct drm_crtc_funcs dc_crtc_funcs = {
1084 .page_flip = dc_page_flip,
1085 .cursor_set = dc_cursor_set,
1086 .cursor_move = dc_cursor_move,
1087 .set_config = drm_crtc_helper_set_config,
1088 .destroy = dc_destroy,
1089 };
1090
1091 /* -------------------------------------------------------------------
1092 *
1093 * Bus and infrastructure.
1094 *
1095 */
1096 static int
dc_init_planes(struct dc_softc * sc,struct tegra_drm * drm)1097 dc_init_planes(struct dc_softc *sc, struct tegra_drm *drm)
1098 {
1099 int i, rv;
1100 struct tegra_plane *plane;
1101
1102 rv = 0;
1103 for (i = 0; i < DC_MAX_PLANES; i++) {
1104 plane = malloc(sizeof(*plane), DRM_MEM_KMS, M_WAITOK | M_ZERO);
1105 plane->index = i + 1;
1106 rv = drm_plane_init(&drm->drm_dev, &plane->drm_plane,
1107 1 << sc->tegra_crtc.nvidia_head, &dc_plane_funcs,
1108 dc_plane_formats, nitems(dc_plane_formats), false);
1109 if (rv != 0) {
1110 free(plane, DRM_MEM_KMS);
1111 return (rv);
1112 }
1113 }
1114 return 0;
1115 }
1116
1117 static void
dc_display_enable(device_t dev,bool enable)1118 dc_display_enable(device_t dev, bool enable)
1119 {
1120 struct dc_softc *sc;
1121 uint32_t val;
1122
1123 sc = device_get_softc(dev);
1124
1125 /* Set display mode */
1126 val = enable ? CTRL_MODE_C_DISPLAY: CTRL_MODE_STOP;
1127 WR4(sc, DC_CMD_DISPLAY_COMMAND, DISPLAY_CTRL_MODE(val));
1128
1129 /* and commit it*/
1130 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_UPDATE);
1131 WR4(sc, DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ);
1132 }
1133
1134 static void
dc_hdmi_enable(device_t dev,bool enable)1135 dc_hdmi_enable(device_t dev, bool enable)
1136 {
1137 struct dc_softc *sc;
1138 uint32_t val;
1139
1140 sc = device_get_softc(dev);
1141
1142 val = RD4(sc, DC_DISP_DISP_WIN_OPTIONS);
1143 if (enable)
1144 val |= HDMI_ENABLE;
1145 else
1146 val &= ~HDMI_ENABLE;
1147 WR4(sc, DC_DISP_DISP_WIN_OPTIONS, val);
1148
1149 }
1150
1151 static void
dc_setup_timing(device_t dev,int h_pulse_start)1152 dc_setup_timing(device_t dev, int h_pulse_start)
1153 {
1154 struct dc_softc *sc;
1155
1156 sc = device_get_softc(dev);
1157
1158 /* Setup display timing */
1159 WR4(sc, DC_DISP_DISP_TIMING_OPTIONS, VSYNC_H_POSITION(1));
1160 WR4(sc, DC_DISP_DISP_COLOR_CONTROL,
1161 DITHER_CONTROL(DITHER_DISABLE) | BASE_COLOR_SIZE(SIZE_BASE888));
1162
1163 WR4(sc, DC_DISP_DISP_SIGNAL_OPTIONS0, H_PULSE2_ENABLE);
1164 WR4(sc, DC_DISP_H_PULSE2_CONTROL,
1165 PULSE_CONTROL_QUAL(QUAL_VACTIVE) | PULSE_CONTROL_LAST(LAST_END_A));
1166
1167 WR4(sc, DC_DISP_H_PULSE2_POSITION_A,
1168 PULSE_START(h_pulse_start) | PULSE_END(h_pulse_start + 8));
1169 }
1170
1171 static void
dc_intr(void * arg)1172 dc_intr(void *arg)
1173 {
1174 struct dc_softc *sc;
1175 uint32_t status;
1176
1177 sc = arg;
1178
1179 /* Confirm interrupt */
1180 status = RD4(sc, DC_CMD_INT_STATUS);
1181 WR4(sc, DC_CMD_INT_STATUS, status);
1182 if (status & VBLANK_INT) {
1183 drm_handle_vblank(sc->tegra_crtc.drm_crtc.dev,
1184 sc->tegra_crtc.nvidia_head);
1185 dc_finish_page_flip(sc);
1186 }
1187 }
1188
1189 static int
dc_init_client(device_t dev,device_t host1x,struct tegra_drm * drm)1190 dc_init_client(device_t dev, device_t host1x, struct tegra_drm *drm)
1191 {
1192 struct dc_softc *sc;
1193 int rv;
1194
1195 sc = device_get_softc(dev);
1196
1197 if (drm->pitch_align < sc->pitch_align)
1198 drm->pitch_align = sc->pitch_align;
1199
1200 drm_crtc_init(&drm->drm_dev, &sc->tegra_crtc.drm_crtc, &dc_crtc_funcs);
1201 drm_mode_crtc_set_gamma_size(&sc->tegra_crtc.drm_crtc, 256);
1202 drm_crtc_helper_add(&sc->tegra_crtc.drm_crtc, &dc_crtc_helper_funcs);
1203
1204 rv = dc_init_planes(sc, drm);
1205 if (rv!= 0){
1206 device_printf(dev, "Cannot init planes\n");
1207 return (rv);
1208 }
1209
1210 WR4(sc, DC_CMD_INT_TYPE,
1211 WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1212 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT);
1213
1214 WR4(sc, DC_CMD_INT_POLARITY,
1215 WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1216 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT);
1217
1218 WR4(sc, DC_CMD_INT_ENABLE, 0);
1219 WR4(sc, DC_CMD_INT_MASK, 0);
1220
1221 rv = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
1222 NULL, dc_intr, sc, &sc->irq_ih);
1223 if (rv != 0) {
1224 device_printf(dev, "Cannot register interrupt handler\n");
1225 return (rv);
1226 }
1227
1228 /* allocate memory for cursor cache */
1229 sc->tegra_crtc.cursor_vbase = kmem_alloc_contig(256 * 256 * 4,
1230 M_WAITOK | M_ZERO, 0, -1UL, PAGE_SIZE, 0,
1231 VM_MEMATTR_WRITE_COMBINING);
1232 sc->tegra_crtc.cursor_pbase =
1233 vtophys((uintptr_t)sc->tegra_crtc.cursor_vbase);
1234 return (0);
1235 }
1236
1237 static int
dc_exit_client(device_t dev,device_t host1x,struct tegra_drm * drm)1238 dc_exit_client(device_t dev, device_t host1x, struct tegra_drm *drm)
1239 {
1240 struct dc_softc *sc;
1241
1242 sc = device_get_softc(dev);
1243
1244 if (sc->irq_ih != NULL)
1245 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1246 sc->irq_ih = NULL;
1247
1248 return (0);
1249 }
1250
1251 static int
get_fdt_resources(struct dc_softc * sc,phandle_t node)1252 get_fdt_resources(struct dc_softc *sc, phandle_t node)
1253 {
1254 int rv;
1255
1256 rv = hwreset_get_by_ofw_name(sc->dev, 0, "dc", &sc->hwreset_dc);
1257 if (rv != 0) {
1258 device_printf(sc->dev, "Cannot get 'dc' reset\n");
1259 return (rv);
1260 }
1261 rv = clk_get_by_ofw_name(sc->dev, 0, "parent", &sc->clk_parent);
1262 if (rv != 0) {
1263 device_printf(sc->dev, "Cannot get 'parent' clock\n");
1264 return (rv);
1265 }
1266 rv = clk_get_by_ofw_name(sc->dev, 0, "dc", &sc->clk_dc);
1267 if (rv != 0) {
1268 device_printf(sc->dev, "Cannot get 'dc' clock\n");
1269 return (rv);
1270 }
1271
1272 rv = OF_getencprop(node, "nvidia,head", &sc->tegra_crtc.nvidia_head,
1273 sizeof(sc->tegra_crtc.nvidia_head));
1274 if (rv <= 0) {
1275 device_printf(sc->dev,
1276 "Cannot get 'nvidia,head' property\n");
1277 return (rv);
1278 }
1279 return (0);
1280 }
1281
1282 static int
enable_fdt_resources(struct dc_softc * sc)1283 enable_fdt_resources(struct dc_softc *sc)
1284 {
1285 int id, rv;
1286
1287 rv = clk_set_parent_by_clk(sc->clk_dc, sc->clk_parent);
1288 if (rv != 0) {
1289 device_printf(sc->dev, "Cannot set parent for 'dc' clock\n");
1290 return (rv);
1291 }
1292
1293 id = (sc->tegra_crtc.nvidia_head == 0) ?
1294 TEGRA_POWERGATE_DIS: TEGRA_POWERGATE_DISB;
1295 rv = tegra_powergate_sequence_power_up(id, sc->clk_dc, sc->hwreset_dc);
1296 if (rv != 0) {
1297 device_printf(sc->dev, "Cannot enable 'DIS' powergate\n");
1298 return (rv);
1299 }
1300
1301 return (0);
1302 }
1303
1304 static int
dc_probe(device_t dev)1305 dc_probe(device_t dev)
1306 {
1307
1308 if (!ofw_bus_status_okay(dev))
1309 return (ENXIO);
1310
1311 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
1312 return (ENXIO);
1313
1314 device_set_desc(dev, "Tegra Display Controller");
1315 return (BUS_PROBE_DEFAULT);
1316 }
1317
1318 static int
dc_attach(device_t dev)1319 dc_attach(device_t dev)
1320 {
1321 struct dc_softc *sc;
1322 phandle_t node;
1323 int rid, rv;
1324
1325 sc = device_get_softc(dev);
1326 sc->dev = dev;
1327 sc->tegra_crtc.dev = dev;
1328
1329 node = ofw_bus_get_node(sc->dev);
1330 LOCK_INIT(sc);
1331
1332 rid = 0;
1333 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
1334 RF_ACTIVE);
1335 if (sc->mem_res == NULL) {
1336 device_printf(dev, "Cannot allocate memory resources\n");
1337 goto fail;
1338 }
1339
1340 rid = 0;
1341 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
1342 if (sc->irq_res == NULL) {
1343 device_printf(dev, "Cannot allocate IRQ resources\n");
1344 goto fail;
1345 }
1346
1347 rv = get_fdt_resources(sc, node);
1348 if (rv != 0) {
1349 device_printf(dev, "Cannot parse FDT resources\n");
1350 goto fail;
1351 }
1352 rv = enable_fdt_resources(sc);
1353 if (rv != 0) {
1354 device_printf(dev, "Cannot enable FDT resources\n");
1355 goto fail;
1356 }
1357
1358 /*
1359 * Tegra124
1360 * - 64 for RGB modes
1361 * - 128 for YUV planar modes
1362 * - 256 for block linear modes
1363 */
1364 sc->pitch_align = 256;
1365
1366 rv = TEGRA_DRM_REGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1367 if (rv != 0) {
1368 device_printf(dev, "Cannot register DRM device\n");
1369 goto fail;
1370 }
1371
1372 return (bus_generic_attach(dev));
1373
1374 fail:
1375 TEGRA_DRM_DEREGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1376 if (sc->irq_ih != NULL)
1377 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1378 if (sc->clk_parent != NULL)
1379 clk_release(sc->clk_parent);
1380 if (sc->clk_dc != NULL)
1381 clk_release(sc->clk_dc);
1382 if (sc->hwreset_dc != NULL)
1383 hwreset_release(sc->hwreset_dc);
1384 if (sc->irq_res != NULL)
1385 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1386 if (sc->mem_res != NULL)
1387 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
1388 LOCK_DESTROY(sc);
1389
1390 return (ENXIO);
1391 }
1392
1393 static int
dc_detach(device_t dev)1394 dc_detach(device_t dev)
1395 {
1396 struct dc_softc *sc;
1397
1398 sc = device_get_softc(dev);
1399
1400 TEGRA_DRM_DEREGISTER_CLIENT(device_get_parent(sc->dev), sc->dev);
1401
1402 if (sc->irq_ih != NULL)
1403 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih);
1404 if (sc->clk_parent != NULL)
1405 clk_release(sc->clk_parent);
1406 if (sc->clk_dc != NULL)
1407 clk_release(sc->clk_dc);
1408 if (sc->hwreset_dc != NULL)
1409 hwreset_release(sc->hwreset_dc);
1410 if (sc->irq_res != NULL)
1411 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
1412 if (sc->mem_res != NULL)
1413 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
1414 LOCK_DESTROY(sc);
1415
1416 return (bus_generic_detach(dev));
1417 }
1418
1419 static device_method_t tegra_dc_methods[] = {
1420 /* Device interface */
1421 DEVMETHOD(device_probe, dc_probe),
1422 DEVMETHOD(device_attach, dc_attach),
1423 DEVMETHOD(device_detach, dc_detach),
1424
1425 /* tegra drm interface */
1426 DEVMETHOD(tegra_drm_init_client, dc_init_client),
1427 DEVMETHOD(tegra_drm_exit_client, dc_exit_client),
1428
1429 /* tegra dc interface */
1430 DEVMETHOD(tegra_dc_display_enable, dc_display_enable),
1431 DEVMETHOD(tegra_dc_hdmi_enable, dc_hdmi_enable),
1432 DEVMETHOD(tegra_dc_setup_timing, dc_setup_timing),
1433
1434 DEVMETHOD_END
1435 };
1436
1437 DEFINE_CLASS_0(tegra_dc, tegra_dc_driver, tegra_dc_methods,
1438 sizeof(struct dc_softc));
1439 DRIVER_MODULE(tegra_dc, host1x, tegra_dc_driver, NULL, NULL);
1440