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