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 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 282 dc_scaling_init(uint32_t start) 283 { 284 285 return (1 << 12); 286 } 287 288 static inline uint32_t 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 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 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 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 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 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 597 dc_crtc_dpms(struct drm_crtc *crtc, int mode) 598 { 599 /* Empty function */ 600 } 601 602 static bool 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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