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