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