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