1 /* 2 * Copyright (C) 2012 Avionic Design GmbH 3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/debugfs.h> 12 #include <linux/reset.h> 13 14 #include "dc.h" 15 #include "drm.h" 16 #include "gem.h" 17 18 struct tegra_dc_soc_info { 19 bool supports_interlacing; 20 bool supports_cursor; 21 bool supports_block_linear; 22 unsigned int pitch_align; 23 }; 24 25 struct tegra_plane { 26 struct drm_plane base; 27 unsigned int index; 28 }; 29 30 static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane) 31 { 32 return container_of(plane, struct tegra_plane, base); 33 } 34 35 static unsigned int tegra_dc_format(uint32_t format, uint32_t *swap) 36 { 37 /* assume no swapping of fetched data */ 38 if (swap) 39 *swap = BYTE_SWAP_NOSWAP; 40 41 switch (format) { 42 case DRM_FORMAT_XBGR8888: 43 return WIN_COLOR_DEPTH_R8G8B8A8; 44 45 case DRM_FORMAT_XRGB8888: 46 return WIN_COLOR_DEPTH_B8G8R8A8; 47 48 case DRM_FORMAT_RGB565: 49 return WIN_COLOR_DEPTH_B5G6R5; 50 51 case DRM_FORMAT_UYVY: 52 return WIN_COLOR_DEPTH_YCbCr422; 53 54 case DRM_FORMAT_YUYV: 55 if (swap) 56 *swap = BYTE_SWAP_SWAP2; 57 58 return WIN_COLOR_DEPTH_YCbCr422; 59 60 case DRM_FORMAT_YUV420: 61 return WIN_COLOR_DEPTH_YCbCr420P; 62 63 case DRM_FORMAT_YUV422: 64 return WIN_COLOR_DEPTH_YCbCr422P; 65 66 default: 67 break; 68 } 69 70 WARN(1, "unsupported pixel format %u, using default\n", format); 71 return WIN_COLOR_DEPTH_B8G8R8A8; 72 } 73 74 static bool tegra_dc_format_is_yuv(unsigned int format, bool *planar) 75 { 76 switch (format) { 77 case WIN_COLOR_DEPTH_YCbCr422: 78 case WIN_COLOR_DEPTH_YUV422: 79 if (planar) 80 *planar = false; 81 82 return true; 83 84 case WIN_COLOR_DEPTH_YCbCr420P: 85 case WIN_COLOR_DEPTH_YUV420P: 86 case WIN_COLOR_DEPTH_YCbCr422P: 87 case WIN_COLOR_DEPTH_YUV422P: 88 case WIN_COLOR_DEPTH_YCbCr422R: 89 case WIN_COLOR_DEPTH_YUV422R: 90 case WIN_COLOR_DEPTH_YCbCr422RA: 91 case WIN_COLOR_DEPTH_YUV422RA: 92 if (planar) 93 *planar = true; 94 95 return true; 96 } 97 98 return false; 99 } 100 101 static inline u32 compute_dda_inc(unsigned int in, unsigned int out, bool v, 102 unsigned int bpp) 103 { 104 fixed20_12 outf = dfixed_init(out); 105 fixed20_12 inf = dfixed_init(in); 106 u32 dda_inc; 107 int max; 108 109 if (v) 110 max = 15; 111 else { 112 switch (bpp) { 113 case 2: 114 max = 8; 115 break; 116 117 default: 118 WARN_ON_ONCE(1); 119 /* fallthrough */ 120 case 4: 121 max = 4; 122 break; 123 } 124 } 125 126 outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1)); 127 inf.full -= dfixed_const(1); 128 129 dda_inc = dfixed_div(inf, outf); 130 dda_inc = min_t(u32, dda_inc, dfixed_const(max)); 131 132 return dda_inc; 133 } 134 135 static inline u32 compute_initial_dda(unsigned int in) 136 { 137 fixed20_12 inf = dfixed_init(in); 138 return dfixed_frac(inf); 139 } 140 141 static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, 142 const struct tegra_dc_window *window) 143 { 144 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; 145 unsigned long value; 146 bool yuv, planar; 147 148 /* 149 * For YUV planar modes, the number of bytes per pixel takes into 150 * account only the luma component and therefore is 1. 151 */ 152 yuv = tegra_dc_format_is_yuv(window->format, &planar); 153 if (!yuv) 154 bpp = window->bits_per_pixel / 8; 155 else 156 bpp = planar ? 1 : 2; 157 158 value = WINDOW_A_SELECT << index; 159 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); 160 161 tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH); 162 tegra_dc_writel(dc, window->swap, DC_WIN_BYTE_SWAP); 163 164 value = V_POSITION(window->dst.y) | H_POSITION(window->dst.x); 165 tegra_dc_writel(dc, value, DC_WIN_POSITION); 166 167 value = V_SIZE(window->dst.h) | H_SIZE(window->dst.w); 168 tegra_dc_writel(dc, value, DC_WIN_SIZE); 169 170 h_offset = window->src.x * bpp; 171 v_offset = window->src.y; 172 h_size = window->src.w * bpp; 173 v_size = window->src.h; 174 175 value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size); 176 tegra_dc_writel(dc, value, DC_WIN_PRESCALED_SIZE); 177 178 /* 179 * For DDA computations the number of bytes per pixel for YUV planar 180 * modes needs to take into account all Y, U and V components. 181 */ 182 if (yuv && planar) 183 bpp = 2; 184 185 h_dda = compute_dda_inc(window->src.w, window->dst.w, false, bpp); 186 v_dda = compute_dda_inc(window->src.h, window->dst.h, true, bpp); 187 188 value = V_DDA_INC(v_dda) | H_DDA_INC(h_dda); 189 tegra_dc_writel(dc, value, DC_WIN_DDA_INC); 190 191 h_dda = compute_initial_dda(window->src.x); 192 v_dda = compute_initial_dda(window->src.y); 193 194 tegra_dc_writel(dc, h_dda, DC_WIN_H_INITIAL_DDA); 195 tegra_dc_writel(dc, v_dda, DC_WIN_V_INITIAL_DDA); 196 197 tegra_dc_writel(dc, 0, DC_WIN_UV_BUF_STRIDE); 198 tegra_dc_writel(dc, 0, DC_WIN_BUF_STRIDE); 199 200 tegra_dc_writel(dc, window->base[0], DC_WINBUF_START_ADDR); 201 202 if (yuv && planar) { 203 tegra_dc_writel(dc, window->base[1], DC_WINBUF_START_ADDR_U); 204 tegra_dc_writel(dc, window->base[2], DC_WINBUF_START_ADDR_V); 205 value = window->stride[1] << 16 | window->stride[0]; 206 tegra_dc_writel(dc, value, DC_WIN_LINE_STRIDE); 207 } else { 208 tegra_dc_writel(dc, window->stride[0], DC_WIN_LINE_STRIDE); 209 } 210 211 if (window->bottom_up) 212 v_offset += window->src.h - 1; 213 214 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); 215 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); 216 217 if (dc->soc->supports_block_linear) { 218 unsigned long height = window->tiling.value; 219 220 switch (window->tiling.mode) { 221 case TEGRA_BO_TILING_MODE_PITCH: 222 value = DC_WINBUF_SURFACE_KIND_PITCH; 223 break; 224 225 case TEGRA_BO_TILING_MODE_TILED: 226 value = DC_WINBUF_SURFACE_KIND_TILED; 227 break; 228 229 case TEGRA_BO_TILING_MODE_BLOCK: 230 value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) | 231 DC_WINBUF_SURFACE_KIND_BLOCK; 232 break; 233 } 234 235 tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND); 236 } else { 237 switch (window->tiling.mode) { 238 case TEGRA_BO_TILING_MODE_PITCH: 239 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV | 240 DC_WIN_BUFFER_ADDR_MODE_LINEAR; 241 break; 242 243 case TEGRA_BO_TILING_MODE_TILED: 244 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV | 245 DC_WIN_BUFFER_ADDR_MODE_TILE; 246 break; 247 248 case TEGRA_BO_TILING_MODE_BLOCK: 249 DRM_ERROR("hardware doesn't support block linear mode\n"); 250 return -EINVAL; 251 } 252 253 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE); 254 } 255 256 value = WIN_ENABLE; 257 258 if (yuv) { 259 /* setup default colorspace conversion coefficients */ 260 tegra_dc_writel(dc, 0x00f0, DC_WIN_CSC_YOF); 261 tegra_dc_writel(dc, 0x012a, DC_WIN_CSC_KYRGB); 262 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KUR); 263 tegra_dc_writel(dc, 0x0198, DC_WIN_CSC_KVR); 264 tegra_dc_writel(dc, 0x039b, DC_WIN_CSC_KUG); 265 tegra_dc_writel(dc, 0x032f, DC_WIN_CSC_KVG); 266 tegra_dc_writel(dc, 0x0204, DC_WIN_CSC_KUB); 267 tegra_dc_writel(dc, 0x0000, DC_WIN_CSC_KVB); 268 269 value |= CSC_ENABLE; 270 } else if (window->bits_per_pixel < 24) { 271 value |= COLOR_EXPAND; 272 } 273 274 if (window->bottom_up) 275 value |= V_DIRECTION; 276 277 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); 278 279 /* 280 * Disable blending and assume Window A is the bottom-most window, 281 * Window C is the top-most window and Window B is in the middle. 282 */ 283 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_NOKEY); 284 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_1WIN); 285 286 switch (index) { 287 case 0: 288 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_X); 289 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y); 290 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY); 291 break; 292 293 case 1: 294 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X); 295 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_2WIN_Y); 296 tegra_dc_writel(dc, 0x000000, DC_WIN_BLEND_3WIN_XY); 297 break; 298 299 case 2: 300 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_X); 301 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_2WIN_Y); 302 tegra_dc_writel(dc, 0xffff00, DC_WIN_BLEND_3WIN_XY); 303 break; 304 } 305 306 tegra_dc_writel(dc, WIN_A_UPDATE << index, DC_CMD_STATE_CONTROL); 307 tegra_dc_writel(dc, WIN_A_ACT_REQ << index, DC_CMD_STATE_CONTROL); 308 309 return 0; 310 } 311 312 static int tegra_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, 313 struct drm_framebuffer *fb, int crtc_x, 314 int crtc_y, unsigned int crtc_w, 315 unsigned int crtc_h, uint32_t src_x, 316 uint32_t src_y, uint32_t src_w, uint32_t src_h) 317 { 318 struct tegra_plane *p = to_tegra_plane(plane); 319 struct tegra_dc *dc = to_tegra_dc(crtc); 320 struct tegra_dc_window window; 321 unsigned int i; 322 int err; 323 324 memset(&window, 0, sizeof(window)); 325 window.src.x = src_x >> 16; 326 window.src.y = src_y >> 16; 327 window.src.w = src_w >> 16; 328 window.src.h = src_h >> 16; 329 window.dst.x = crtc_x; 330 window.dst.y = crtc_y; 331 window.dst.w = crtc_w; 332 window.dst.h = crtc_h; 333 window.format = tegra_dc_format(fb->pixel_format, &window.swap); 334 window.bits_per_pixel = fb->bits_per_pixel; 335 window.bottom_up = tegra_fb_is_bottom_up(fb); 336 337 err = tegra_fb_get_tiling(fb, &window.tiling); 338 if (err < 0) 339 return err; 340 341 for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) { 342 struct tegra_bo *bo = tegra_fb_get_plane(fb, i); 343 344 window.base[i] = bo->paddr + fb->offsets[i]; 345 346 /* 347 * Tegra doesn't support different strides for U and V planes 348 * so we display a warning if the user tries to display a 349 * framebuffer with such a configuration. 350 */ 351 if (i >= 2) { 352 if (fb->pitches[i] != window.stride[1]) 353 DRM_ERROR("unsupported UV-plane configuration\n"); 354 } else { 355 window.stride[i] = fb->pitches[i]; 356 } 357 } 358 359 return tegra_dc_setup_window(dc, p->index, &window); 360 } 361 362 static int tegra_plane_disable(struct drm_plane *plane) 363 { 364 struct tegra_dc *dc = to_tegra_dc(plane->crtc); 365 struct tegra_plane *p = to_tegra_plane(plane); 366 unsigned long value; 367 368 if (!plane->crtc) 369 return 0; 370 371 value = WINDOW_A_SELECT << p->index; 372 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); 373 374 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); 375 value &= ~WIN_ENABLE; 376 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); 377 378 tegra_dc_writel(dc, WIN_A_UPDATE << p->index, DC_CMD_STATE_CONTROL); 379 tegra_dc_writel(dc, WIN_A_ACT_REQ << p->index, DC_CMD_STATE_CONTROL); 380 381 return 0; 382 } 383 384 static void tegra_plane_destroy(struct drm_plane *plane) 385 { 386 struct tegra_plane *p = to_tegra_plane(plane); 387 388 tegra_plane_disable(plane); 389 drm_plane_cleanup(plane); 390 kfree(p); 391 } 392 393 static const struct drm_plane_funcs tegra_plane_funcs = { 394 .update_plane = tegra_plane_update, 395 .disable_plane = tegra_plane_disable, 396 .destroy = tegra_plane_destroy, 397 }; 398 399 static const uint32_t plane_formats[] = { 400 DRM_FORMAT_XBGR8888, 401 DRM_FORMAT_XRGB8888, 402 DRM_FORMAT_RGB565, 403 DRM_FORMAT_UYVY, 404 DRM_FORMAT_YUYV, 405 DRM_FORMAT_YUV420, 406 DRM_FORMAT_YUV422, 407 }; 408 409 static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) 410 { 411 unsigned int i; 412 int err = 0; 413 414 for (i = 0; i < 2; i++) { 415 struct tegra_plane *plane; 416 417 plane = kzalloc(sizeof(*plane), GFP_KERNEL); 418 if (!plane) 419 return -ENOMEM; 420 421 plane->index = 1 + i; 422 423 err = drm_plane_init(drm, &plane->base, 1 << dc->pipe, 424 &tegra_plane_funcs, plane_formats, 425 ARRAY_SIZE(plane_formats), false); 426 if (err < 0) { 427 kfree(plane); 428 return err; 429 } 430 } 431 432 return 0; 433 } 434 435 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, 436 struct drm_framebuffer *fb) 437 { 438 struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); 439 unsigned int h_offset = 0, v_offset = 0; 440 struct tegra_bo_tiling tiling; 441 unsigned int format, swap; 442 unsigned long value; 443 int err; 444 445 err = tegra_fb_get_tiling(fb, &tiling); 446 if (err < 0) 447 return err; 448 449 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); 450 451 value = fb->offsets[0] + y * fb->pitches[0] + 452 x * fb->bits_per_pixel / 8; 453 454 tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR); 455 tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE); 456 457 format = tegra_dc_format(fb->pixel_format, &swap); 458 tegra_dc_writel(dc, format, DC_WIN_COLOR_DEPTH); 459 tegra_dc_writel(dc, swap, DC_WIN_BYTE_SWAP); 460 461 if (dc->soc->supports_block_linear) { 462 unsigned long height = tiling.value; 463 464 switch (tiling.mode) { 465 case TEGRA_BO_TILING_MODE_PITCH: 466 value = DC_WINBUF_SURFACE_KIND_PITCH; 467 break; 468 469 case TEGRA_BO_TILING_MODE_TILED: 470 value = DC_WINBUF_SURFACE_KIND_TILED; 471 break; 472 473 case TEGRA_BO_TILING_MODE_BLOCK: 474 value = DC_WINBUF_SURFACE_KIND_BLOCK_HEIGHT(height) | 475 DC_WINBUF_SURFACE_KIND_BLOCK; 476 break; 477 } 478 479 tegra_dc_writel(dc, value, DC_WINBUF_SURFACE_KIND); 480 } else { 481 switch (tiling.mode) { 482 case TEGRA_BO_TILING_MODE_PITCH: 483 value = DC_WIN_BUFFER_ADDR_MODE_LINEAR_UV | 484 DC_WIN_BUFFER_ADDR_MODE_LINEAR; 485 break; 486 487 case TEGRA_BO_TILING_MODE_TILED: 488 value = DC_WIN_BUFFER_ADDR_MODE_TILE_UV | 489 DC_WIN_BUFFER_ADDR_MODE_TILE; 490 break; 491 492 case TEGRA_BO_TILING_MODE_BLOCK: 493 DRM_ERROR("hardware doesn't support block linear mode\n"); 494 return -EINVAL; 495 } 496 497 tegra_dc_writel(dc, value, DC_WIN_BUFFER_ADDR_MODE); 498 } 499 500 /* make sure bottom-up buffers are properly displayed */ 501 if (tegra_fb_is_bottom_up(fb)) { 502 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); 503 value |= V_DIRECTION; 504 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); 505 506 v_offset += fb->height - 1; 507 } else { 508 value = tegra_dc_readl(dc, DC_WIN_WIN_OPTIONS); 509 value &= ~V_DIRECTION; 510 tegra_dc_writel(dc, value, DC_WIN_WIN_OPTIONS); 511 } 512 513 tegra_dc_writel(dc, h_offset, DC_WINBUF_ADDR_H_OFFSET); 514 tegra_dc_writel(dc, v_offset, DC_WINBUF_ADDR_V_OFFSET); 515 516 value = GENERAL_UPDATE | WIN_A_UPDATE; 517 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 518 519 value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; 520 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 521 522 return 0; 523 } 524 525 void tegra_dc_enable_vblank(struct tegra_dc *dc) 526 { 527 unsigned long value, flags; 528 529 spin_lock_irqsave(&dc->lock, flags); 530 531 value = tegra_dc_readl(dc, DC_CMD_INT_MASK); 532 value |= VBLANK_INT; 533 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 534 535 spin_unlock_irqrestore(&dc->lock, flags); 536 } 537 538 void tegra_dc_disable_vblank(struct tegra_dc *dc) 539 { 540 unsigned long value, flags; 541 542 spin_lock_irqsave(&dc->lock, flags); 543 544 value = tegra_dc_readl(dc, DC_CMD_INT_MASK); 545 value &= ~VBLANK_INT; 546 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 547 548 spin_unlock_irqrestore(&dc->lock, flags); 549 } 550 551 static int tegra_dc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file, 552 uint32_t handle, uint32_t width, 553 uint32_t height, int32_t hot_x, int32_t hot_y) 554 { 555 unsigned long value = CURSOR_CLIP_DISPLAY; 556 struct tegra_dc *dc = to_tegra_dc(crtc); 557 struct drm_gem_object *gem; 558 struct tegra_bo *bo = NULL; 559 560 if (!dc->soc->supports_cursor) 561 return -ENXIO; 562 563 if (width != height) 564 return -EINVAL; 565 566 switch (width) { 567 case 32: 568 value |= CURSOR_SIZE_32x32; 569 break; 570 571 case 64: 572 value |= CURSOR_SIZE_64x64; 573 break; 574 575 case 128: 576 value |= CURSOR_SIZE_128x128; 577 578 case 256: 579 value |= CURSOR_SIZE_256x256; 580 break; 581 582 default: 583 return -EINVAL; 584 } 585 586 if (handle) { 587 gem = drm_gem_object_lookup(crtc->dev, file, handle); 588 if (!gem) 589 return -ENOENT; 590 591 bo = to_tegra_bo(gem); 592 } 593 594 if (bo) { 595 unsigned long addr = (bo->paddr & 0xfffffc00) >> 10; 596 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 597 unsigned long high = (bo->paddr & 0xfffffffc) >> 32; 598 #endif 599 600 tegra_dc_writel(dc, value | addr, DC_DISP_CURSOR_START_ADDR); 601 602 #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT 603 tegra_dc_writel(dc, high, DC_DISP_CURSOR_START_ADDR_HI); 604 #endif 605 606 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); 607 value |= CURSOR_ENABLE; 608 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 609 610 value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL); 611 value &= ~CURSOR_DST_BLEND_MASK; 612 value &= ~CURSOR_SRC_BLEND_MASK; 613 value |= CURSOR_MODE_NORMAL; 614 value |= CURSOR_DST_BLEND_NEG_K1_TIMES_SRC; 615 value |= CURSOR_SRC_BLEND_K1_TIMES_SRC; 616 value |= CURSOR_ALPHA; 617 tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL); 618 } else { 619 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); 620 value &= ~CURSOR_ENABLE; 621 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 622 } 623 624 tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 625 tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL); 626 627 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 628 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); 629 630 return 0; 631 } 632 633 static int tegra_dc_cursor_move(struct drm_crtc *crtc, int x, int y) 634 { 635 struct tegra_dc *dc = to_tegra_dc(crtc); 636 unsigned long value; 637 638 if (!dc->soc->supports_cursor) 639 return -ENXIO; 640 641 value = ((y & 0x3fff) << 16) | (x & 0x3fff); 642 tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION); 643 644 tegra_dc_writel(dc, CURSOR_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 645 tegra_dc_writel(dc, CURSOR_ACT_REQ, DC_CMD_STATE_CONTROL); 646 647 /* XXX: only required on generations earlier than Tegra124? */ 648 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); 649 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); 650 651 return 0; 652 } 653 654 static void tegra_dc_finish_page_flip(struct tegra_dc *dc) 655 { 656 struct drm_device *drm = dc->base.dev; 657 struct drm_crtc *crtc = &dc->base; 658 unsigned long flags, base; 659 struct tegra_bo *bo; 660 661 if (!dc->event) 662 return; 663 664 bo = tegra_fb_get_plane(crtc->primary->fb, 0); 665 666 /* check if new start address has been latched */ 667 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); 668 base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); 669 tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); 670 671 if (base == bo->paddr + crtc->primary->fb->offsets[0]) { 672 spin_lock_irqsave(&drm->event_lock, flags); 673 drm_send_vblank_event(drm, dc->pipe, dc->event); 674 drm_vblank_put(drm, dc->pipe); 675 dc->event = NULL; 676 spin_unlock_irqrestore(&drm->event_lock, flags); 677 } 678 } 679 680 void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) 681 { 682 struct tegra_dc *dc = to_tegra_dc(crtc); 683 struct drm_device *drm = crtc->dev; 684 unsigned long flags; 685 686 spin_lock_irqsave(&drm->event_lock, flags); 687 688 if (dc->event && dc->event->base.file_priv == file) { 689 dc->event->base.destroy(&dc->event->base); 690 drm_vblank_put(drm, dc->pipe); 691 dc->event = NULL; 692 } 693 694 spin_unlock_irqrestore(&drm->event_lock, flags); 695 } 696 697 static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 698 struct drm_pending_vblank_event *event, uint32_t page_flip_flags) 699 { 700 struct tegra_dc *dc = to_tegra_dc(crtc); 701 struct drm_device *drm = crtc->dev; 702 703 if (dc->event) 704 return -EBUSY; 705 706 if (event) { 707 event->pipe = dc->pipe; 708 dc->event = event; 709 drm_vblank_get(drm, dc->pipe); 710 } 711 712 tegra_dc_set_base(dc, 0, 0, fb); 713 crtc->primary->fb = fb; 714 715 return 0; 716 } 717 718 static void drm_crtc_clear(struct drm_crtc *crtc) 719 { 720 memset(crtc, 0, sizeof(*crtc)); 721 } 722 723 static void tegra_dc_destroy(struct drm_crtc *crtc) 724 { 725 drm_crtc_cleanup(crtc); 726 drm_crtc_clear(crtc); 727 } 728 729 static const struct drm_crtc_funcs tegra_crtc_funcs = { 730 .cursor_set2 = tegra_dc_cursor_set2, 731 .cursor_move = tegra_dc_cursor_move, 732 .page_flip = tegra_dc_page_flip, 733 .set_config = drm_crtc_helper_set_config, 734 .destroy = tegra_dc_destroy, 735 }; 736 737 static void tegra_crtc_disable(struct drm_crtc *crtc) 738 { 739 struct tegra_dc *dc = to_tegra_dc(crtc); 740 struct drm_device *drm = crtc->dev; 741 struct drm_plane *plane; 742 743 drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) { 744 if (plane->crtc == crtc) { 745 tegra_plane_disable(plane); 746 plane->crtc = NULL; 747 748 if (plane->fb) { 749 drm_framebuffer_unreference(plane->fb); 750 plane->fb = NULL; 751 } 752 } 753 } 754 755 drm_vblank_off(drm, dc->pipe); 756 } 757 758 static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, 759 const struct drm_display_mode *mode, 760 struct drm_display_mode *adjusted) 761 { 762 return true; 763 } 764 765 static int tegra_dc_set_timings(struct tegra_dc *dc, 766 struct drm_display_mode *mode) 767 { 768 unsigned int h_ref_to_sync = 1; 769 unsigned int v_ref_to_sync = 1; 770 unsigned long value; 771 772 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS); 773 774 value = (v_ref_to_sync << 16) | h_ref_to_sync; 775 tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC); 776 777 value = ((mode->vsync_end - mode->vsync_start) << 16) | 778 ((mode->hsync_end - mode->hsync_start) << 0); 779 tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH); 780 781 value = ((mode->vtotal - mode->vsync_end) << 16) | 782 ((mode->htotal - mode->hsync_end) << 0); 783 tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH); 784 785 value = ((mode->vsync_start - mode->vdisplay) << 16) | 786 ((mode->hsync_start - mode->hdisplay) << 0); 787 tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH); 788 789 value = (mode->vdisplay << 16) | mode->hdisplay; 790 tegra_dc_writel(dc, value, DC_DISP_ACTIVE); 791 792 return 0; 793 } 794 795 static int tegra_crtc_setup_clk(struct drm_crtc *crtc, 796 struct drm_display_mode *mode) 797 { 798 unsigned long pclk = mode->clock * 1000; 799 struct tegra_dc *dc = to_tegra_dc(crtc); 800 struct tegra_output *output = NULL; 801 struct drm_encoder *encoder; 802 unsigned int div; 803 u32 value; 804 long err; 805 806 list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head) 807 if (encoder->crtc == crtc) { 808 output = encoder_to_output(encoder); 809 break; 810 } 811 812 if (!output) 813 return -ENODEV; 814 815 /* 816 * This assumes that the parent clock is pll_d_out0 or pll_d2_out 817 * respectively, each of which divides the base pll_d by 2. 818 */ 819 err = tegra_output_setup_clock(output, dc->clk, pclk, &div); 820 if (err < 0) { 821 dev_err(dc->dev, "failed to setup clock: %ld\n", err); 822 return err; 823 } 824 825 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), div); 826 827 value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1; 828 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); 829 830 return 0; 831 } 832 833 static int tegra_crtc_mode_set(struct drm_crtc *crtc, 834 struct drm_display_mode *mode, 835 struct drm_display_mode *adjusted, 836 int x, int y, struct drm_framebuffer *old_fb) 837 { 838 struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0); 839 struct tegra_dc *dc = to_tegra_dc(crtc); 840 struct tegra_dc_window window; 841 u32 value; 842 int err; 843 844 drm_vblank_pre_modeset(crtc->dev, dc->pipe); 845 846 err = tegra_crtc_setup_clk(crtc, mode); 847 if (err) { 848 dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err); 849 return err; 850 } 851 852 /* program display mode */ 853 tegra_dc_set_timings(dc, mode); 854 855 /* interlacing isn't supported yet, so disable it */ 856 if (dc->soc->supports_interlacing) { 857 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); 858 value &= ~INTERLACE_ENABLE; 859 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL); 860 } 861 862 /* setup window parameters */ 863 memset(&window, 0, sizeof(window)); 864 window.src.x = 0; 865 window.src.y = 0; 866 window.src.w = mode->hdisplay; 867 window.src.h = mode->vdisplay; 868 window.dst.x = 0; 869 window.dst.y = 0; 870 window.dst.w = mode->hdisplay; 871 window.dst.h = mode->vdisplay; 872 window.format = tegra_dc_format(crtc->primary->fb->pixel_format, 873 &window.swap); 874 window.bits_per_pixel = crtc->primary->fb->bits_per_pixel; 875 window.stride[0] = crtc->primary->fb->pitches[0]; 876 window.base[0] = bo->paddr; 877 878 err = tegra_dc_setup_window(dc, 0, &window); 879 if (err < 0) 880 dev_err(dc->dev, "failed to enable root plane\n"); 881 882 return 0; 883 } 884 885 static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 886 struct drm_framebuffer *old_fb) 887 { 888 struct tegra_dc *dc = to_tegra_dc(crtc); 889 890 return tegra_dc_set_base(dc, x, y, crtc->primary->fb); 891 } 892 893 static void tegra_crtc_prepare(struct drm_crtc *crtc) 894 { 895 struct tegra_dc *dc = to_tegra_dc(crtc); 896 unsigned int syncpt; 897 unsigned long value; 898 899 /* hardware initialization */ 900 reset_control_deassert(dc->rst); 901 usleep_range(10000, 20000); 902 903 if (dc->pipe) 904 syncpt = SYNCPT_VBLANK1; 905 else 906 syncpt = SYNCPT_VBLANK0; 907 908 /* initialize display controller */ 909 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 910 tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC); 911 912 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT; 913 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); 914 915 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 916 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 917 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); 918 919 /* initialize timer */ 920 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | 921 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); 922 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); 923 924 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) | 925 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1); 926 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 927 928 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT; 929 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); 930 931 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT; 932 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 933 } 934 935 static void tegra_crtc_commit(struct drm_crtc *crtc) 936 { 937 struct tegra_dc *dc = to_tegra_dc(crtc); 938 unsigned long value; 939 940 value = GENERAL_UPDATE | WIN_A_UPDATE; 941 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 942 943 value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; 944 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 945 946 drm_vblank_post_modeset(crtc->dev, dc->pipe); 947 } 948 949 static void tegra_crtc_load_lut(struct drm_crtc *crtc) 950 { 951 } 952 953 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = { 954 .disable = tegra_crtc_disable, 955 .mode_fixup = tegra_crtc_mode_fixup, 956 .mode_set = tegra_crtc_mode_set, 957 .mode_set_base = tegra_crtc_mode_set_base, 958 .prepare = tegra_crtc_prepare, 959 .commit = tegra_crtc_commit, 960 .load_lut = tegra_crtc_load_lut, 961 }; 962 963 static irqreturn_t tegra_dc_irq(int irq, void *data) 964 { 965 struct tegra_dc *dc = data; 966 unsigned long status; 967 968 status = tegra_dc_readl(dc, DC_CMD_INT_STATUS); 969 tegra_dc_writel(dc, status, DC_CMD_INT_STATUS); 970 971 if (status & FRAME_END_INT) { 972 /* 973 dev_dbg(dc->dev, "%s(): frame end\n", __func__); 974 */ 975 } 976 977 if (status & VBLANK_INT) { 978 /* 979 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); 980 */ 981 drm_handle_vblank(dc->base.dev, dc->pipe); 982 tegra_dc_finish_page_flip(dc); 983 } 984 985 if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) { 986 /* 987 dev_dbg(dc->dev, "%s(): underflow\n", __func__); 988 */ 989 } 990 991 return IRQ_HANDLED; 992 } 993 994 static int tegra_dc_show_regs(struct seq_file *s, void *data) 995 { 996 struct drm_info_node *node = s->private; 997 struct tegra_dc *dc = node->info_ent->data; 998 999 #define DUMP_REG(name) \ 1000 seq_printf(s, "%-40s %#05x %08lx\n", #name, name, \ 1001 tegra_dc_readl(dc, name)) 1002 1003 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT); 1004 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 1005 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR); 1006 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT); 1007 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL); 1008 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR); 1009 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT); 1010 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL); 1011 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR); 1012 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT); 1013 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL); 1014 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR); 1015 DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC); 1016 DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0); 1017 DUMP_REG(DC_CMD_DISPLAY_COMMAND); 1018 DUMP_REG(DC_CMD_SIGNAL_RAISE); 1019 DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL); 1020 DUMP_REG(DC_CMD_INT_STATUS); 1021 DUMP_REG(DC_CMD_INT_MASK); 1022 DUMP_REG(DC_CMD_INT_ENABLE); 1023 DUMP_REG(DC_CMD_INT_TYPE); 1024 DUMP_REG(DC_CMD_INT_POLARITY); 1025 DUMP_REG(DC_CMD_SIGNAL_RAISE1); 1026 DUMP_REG(DC_CMD_SIGNAL_RAISE2); 1027 DUMP_REG(DC_CMD_SIGNAL_RAISE3); 1028 DUMP_REG(DC_CMD_STATE_ACCESS); 1029 DUMP_REG(DC_CMD_STATE_CONTROL); 1030 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); 1031 DUMP_REG(DC_CMD_REG_ACT_CONTROL); 1032 DUMP_REG(DC_COM_CRC_CONTROL); 1033 DUMP_REG(DC_COM_CRC_CHECKSUM); 1034 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0)); 1035 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1)); 1036 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2)); 1037 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3)); 1038 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0)); 1039 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1)); 1040 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2)); 1041 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3)); 1042 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0)); 1043 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1)); 1044 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2)); 1045 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3)); 1046 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0)); 1047 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1)); 1048 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2)); 1049 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3)); 1050 DUMP_REG(DC_COM_PIN_INPUT_DATA(0)); 1051 DUMP_REG(DC_COM_PIN_INPUT_DATA(1)); 1052 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0)); 1053 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1)); 1054 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2)); 1055 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3)); 1056 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4)); 1057 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5)); 1058 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6)); 1059 DUMP_REG(DC_COM_PIN_MISC_CONTROL); 1060 DUMP_REG(DC_COM_PIN_PM0_CONTROL); 1061 DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE); 1062 DUMP_REG(DC_COM_PIN_PM1_CONTROL); 1063 DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE); 1064 DUMP_REG(DC_COM_SPI_CONTROL); 1065 DUMP_REG(DC_COM_SPI_START_BYTE); 1066 DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB); 1067 DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD); 1068 DUMP_REG(DC_COM_HSPI_CS_DC); 1069 DUMP_REG(DC_COM_SCRATCH_REGISTER_A); 1070 DUMP_REG(DC_COM_SCRATCH_REGISTER_B); 1071 DUMP_REG(DC_COM_GPIO_CTRL); 1072 DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER); 1073 DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED); 1074 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0); 1075 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1); 1076 DUMP_REG(DC_DISP_DISP_WIN_OPTIONS); 1077 DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY); 1078 DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 1079 DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS); 1080 DUMP_REG(DC_DISP_REF_TO_SYNC); 1081 DUMP_REG(DC_DISP_SYNC_WIDTH); 1082 DUMP_REG(DC_DISP_BACK_PORCH); 1083 DUMP_REG(DC_DISP_ACTIVE); 1084 DUMP_REG(DC_DISP_FRONT_PORCH); 1085 DUMP_REG(DC_DISP_H_PULSE0_CONTROL); 1086 DUMP_REG(DC_DISP_H_PULSE0_POSITION_A); 1087 DUMP_REG(DC_DISP_H_PULSE0_POSITION_B); 1088 DUMP_REG(DC_DISP_H_PULSE0_POSITION_C); 1089 DUMP_REG(DC_DISP_H_PULSE0_POSITION_D); 1090 DUMP_REG(DC_DISP_H_PULSE1_CONTROL); 1091 DUMP_REG(DC_DISP_H_PULSE1_POSITION_A); 1092 DUMP_REG(DC_DISP_H_PULSE1_POSITION_B); 1093 DUMP_REG(DC_DISP_H_PULSE1_POSITION_C); 1094 DUMP_REG(DC_DISP_H_PULSE1_POSITION_D); 1095 DUMP_REG(DC_DISP_H_PULSE2_CONTROL); 1096 DUMP_REG(DC_DISP_H_PULSE2_POSITION_A); 1097 DUMP_REG(DC_DISP_H_PULSE2_POSITION_B); 1098 DUMP_REG(DC_DISP_H_PULSE2_POSITION_C); 1099 DUMP_REG(DC_DISP_H_PULSE2_POSITION_D); 1100 DUMP_REG(DC_DISP_V_PULSE0_CONTROL); 1101 DUMP_REG(DC_DISP_V_PULSE0_POSITION_A); 1102 DUMP_REG(DC_DISP_V_PULSE0_POSITION_B); 1103 DUMP_REG(DC_DISP_V_PULSE0_POSITION_C); 1104 DUMP_REG(DC_DISP_V_PULSE1_CONTROL); 1105 DUMP_REG(DC_DISP_V_PULSE1_POSITION_A); 1106 DUMP_REG(DC_DISP_V_PULSE1_POSITION_B); 1107 DUMP_REG(DC_DISP_V_PULSE1_POSITION_C); 1108 DUMP_REG(DC_DISP_V_PULSE2_CONTROL); 1109 DUMP_REG(DC_DISP_V_PULSE2_POSITION_A); 1110 DUMP_REG(DC_DISP_V_PULSE3_CONTROL); 1111 DUMP_REG(DC_DISP_V_PULSE3_POSITION_A); 1112 DUMP_REG(DC_DISP_M0_CONTROL); 1113 DUMP_REG(DC_DISP_M1_CONTROL); 1114 DUMP_REG(DC_DISP_DI_CONTROL); 1115 DUMP_REG(DC_DISP_PP_CONTROL); 1116 DUMP_REG(DC_DISP_PP_SELECT_A); 1117 DUMP_REG(DC_DISP_PP_SELECT_B); 1118 DUMP_REG(DC_DISP_PP_SELECT_C); 1119 DUMP_REG(DC_DISP_PP_SELECT_D); 1120 DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL); 1121 DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL); 1122 DUMP_REG(DC_DISP_DISP_COLOR_CONTROL); 1123 DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS); 1124 DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS); 1125 DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS); 1126 DUMP_REG(DC_DISP_LCD_SPI_OPTIONS); 1127 DUMP_REG(DC_DISP_BORDER_COLOR); 1128 DUMP_REG(DC_DISP_COLOR_KEY0_LOWER); 1129 DUMP_REG(DC_DISP_COLOR_KEY0_UPPER); 1130 DUMP_REG(DC_DISP_COLOR_KEY1_LOWER); 1131 DUMP_REG(DC_DISP_COLOR_KEY1_UPPER); 1132 DUMP_REG(DC_DISP_CURSOR_FOREGROUND); 1133 DUMP_REG(DC_DISP_CURSOR_BACKGROUND); 1134 DUMP_REG(DC_DISP_CURSOR_START_ADDR); 1135 DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS); 1136 DUMP_REG(DC_DISP_CURSOR_POSITION); 1137 DUMP_REG(DC_DISP_CURSOR_POSITION_NS); 1138 DUMP_REG(DC_DISP_INIT_SEQ_CONTROL); 1139 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A); 1140 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B); 1141 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C); 1142 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D); 1143 DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL); 1144 DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST); 1145 DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST); 1146 DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST); 1147 DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST); 1148 DUMP_REG(DC_DISP_DAC_CRT_CTRL); 1149 DUMP_REG(DC_DISP_DISP_MISC_CONTROL); 1150 DUMP_REG(DC_DISP_SD_CONTROL); 1151 DUMP_REG(DC_DISP_SD_CSC_COEFF); 1152 DUMP_REG(DC_DISP_SD_LUT(0)); 1153 DUMP_REG(DC_DISP_SD_LUT(1)); 1154 DUMP_REG(DC_DISP_SD_LUT(2)); 1155 DUMP_REG(DC_DISP_SD_LUT(3)); 1156 DUMP_REG(DC_DISP_SD_LUT(4)); 1157 DUMP_REG(DC_DISP_SD_LUT(5)); 1158 DUMP_REG(DC_DISP_SD_LUT(6)); 1159 DUMP_REG(DC_DISP_SD_LUT(7)); 1160 DUMP_REG(DC_DISP_SD_LUT(8)); 1161 DUMP_REG(DC_DISP_SD_FLICKER_CONTROL); 1162 DUMP_REG(DC_DISP_DC_PIXEL_COUNT); 1163 DUMP_REG(DC_DISP_SD_HISTOGRAM(0)); 1164 DUMP_REG(DC_DISP_SD_HISTOGRAM(1)); 1165 DUMP_REG(DC_DISP_SD_HISTOGRAM(2)); 1166 DUMP_REG(DC_DISP_SD_HISTOGRAM(3)); 1167 DUMP_REG(DC_DISP_SD_HISTOGRAM(4)); 1168 DUMP_REG(DC_DISP_SD_HISTOGRAM(5)); 1169 DUMP_REG(DC_DISP_SD_HISTOGRAM(6)); 1170 DUMP_REG(DC_DISP_SD_HISTOGRAM(7)); 1171 DUMP_REG(DC_DISP_SD_BL_TF(0)); 1172 DUMP_REG(DC_DISP_SD_BL_TF(1)); 1173 DUMP_REG(DC_DISP_SD_BL_TF(2)); 1174 DUMP_REG(DC_DISP_SD_BL_TF(3)); 1175 DUMP_REG(DC_DISP_SD_BL_CONTROL); 1176 DUMP_REG(DC_DISP_SD_HW_K_VALUES); 1177 DUMP_REG(DC_DISP_SD_MAN_K_VALUES); 1178 DUMP_REG(DC_DISP_CURSOR_START_ADDR_HI); 1179 DUMP_REG(DC_DISP_BLEND_CURSOR_CONTROL); 1180 DUMP_REG(DC_WIN_WIN_OPTIONS); 1181 DUMP_REG(DC_WIN_BYTE_SWAP); 1182 DUMP_REG(DC_WIN_BUFFER_CONTROL); 1183 DUMP_REG(DC_WIN_COLOR_DEPTH); 1184 DUMP_REG(DC_WIN_POSITION); 1185 DUMP_REG(DC_WIN_SIZE); 1186 DUMP_REG(DC_WIN_PRESCALED_SIZE); 1187 DUMP_REG(DC_WIN_H_INITIAL_DDA); 1188 DUMP_REG(DC_WIN_V_INITIAL_DDA); 1189 DUMP_REG(DC_WIN_DDA_INC); 1190 DUMP_REG(DC_WIN_LINE_STRIDE); 1191 DUMP_REG(DC_WIN_BUF_STRIDE); 1192 DUMP_REG(DC_WIN_UV_BUF_STRIDE); 1193 DUMP_REG(DC_WIN_BUFFER_ADDR_MODE); 1194 DUMP_REG(DC_WIN_DV_CONTROL); 1195 DUMP_REG(DC_WIN_BLEND_NOKEY); 1196 DUMP_REG(DC_WIN_BLEND_1WIN); 1197 DUMP_REG(DC_WIN_BLEND_2WIN_X); 1198 DUMP_REG(DC_WIN_BLEND_2WIN_Y); 1199 DUMP_REG(DC_WIN_BLEND_3WIN_XY); 1200 DUMP_REG(DC_WIN_HP_FETCH_CONTROL); 1201 DUMP_REG(DC_WINBUF_START_ADDR); 1202 DUMP_REG(DC_WINBUF_START_ADDR_NS); 1203 DUMP_REG(DC_WINBUF_START_ADDR_U); 1204 DUMP_REG(DC_WINBUF_START_ADDR_U_NS); 1205 DUMP_REG(DC_WINBUF_START_ADDR_V); 1206 DUMP_REG(DC_WINBUF_START_ADDR_V_NS); 1207 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET); 1208 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS); 1209 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET); 1210 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS); 1211 DUMP_REG(DC_WINBUF_UFLOW_STATUS); 1212 DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS); 1213 DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS); 1214 DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS); 1215 1216 #undef DUMP_REG 1217 1218 return 0; 1219 } 1220 1221 static struct drm_info_list debugfs_files[] = { 1222 { "regs", tegra_dc_show_regs, 0, NULL }, 1223 }; 1224 1225 static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor) 1226 { 1227 unsigned int i; 1228 char *name; 1229 int err; 1230 1231 name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe); 1232 dc->debugfs = debugfs_create_dir(name, minor->debugfs_root); 1233 kfree(name); 1234 1235 if (!dc->debugfs) 1236 return -ENOMEM; 1237 1238 dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files), 1239 GFP_KERNEL); 1240 if (!dc->debugfs_files) { 1241 err = -ENOMEM; 1242 goto remove; 1243 } 1244 1245 for (i = 0; i < ARRAY_SIZE(debugfs_files); i++) 1246 dc->debugfs_files[i].data = dc; 1247 1248 err = drm_debugfs_create_files(dc->debugfs_files, 1249 ARRAY_SIZE(debugfs_files), 1250 dc->debugfs, minor); 1251 if (err < 0) 1252 goto free; 1253 1254 dc->minor = minor; 1255 1256 return 0; 1257 1258 free: 1259 kfree(dc->debugfs_files); 1260 dc->debugfs_files = NULL; 1261 remove: 1262 debugfs_remove(dc->debugfs); 1263 dc->debugfs = NULL; 1264 1265 return err; 1266 } 1267 1268 static int tegra_dc_debugfs_exit(struct tegra_dc *dc) 1269 { 1270 drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files), 1271 dc->minor); 1272 dc->minor = NULL; 1273 1274 kfree(dc->debugfs_files); 1275 dc->debugfs_files = NULL; 1276 1277 debugfs_remove(dc->debugfs); 1278 dc->debugfs = NULL; 1279 1280 return 0; 1281 } 1282 1283 static int tegra_dc_init(struct host1x_client *client) 1284 { 1285 struct drm_device *drm = dev_get_drvdata(client->parent); 1286 struct tegra_dc *dc = host1x_client_to_dc(client); 1287 struct tegra_drm *tegra = drm->dev_private; 1288 int err; 1289 1290 drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); 1291 drm_mode_crtc_set_gamma_size(&dc->base, 256); 1292 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1293 1294 /* 1295 * Keep track of the minimum pitch alignment across all display 1296 * controllers. 1297 */ 1298 if (dc->soc->pitch_align > tegra->pitch_align) 1299 tegra->pitch_align = dc->soc->pitch_align; 1300 1301 err = tegra_dc_rgb_init(drm, dc); 1302 if (err < 0 && err != -ENODEV) { 1303 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); 1304 return err; 1305 } 1306 1307 err = tegra_dc_add_planes(drm, dc); 1308 if (err < 0) 1309 return err; 1310 1311 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 1312 err = tegra_dc_debugfs_init(dc, drm->primary); 1313 if (err < 0) 1314 dev_err(dc->dev, "debugfs setup failed: %d\n", err); 1315 } 1316 1317 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0, 1318 dev_name(dc->dev), dc); 1319 if (err < 0) { 1320 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, 1321 err); 1322 return err; 1323 } 1324 1325 return 0; 1326 } 1327 1328 static int tegra_dc_exit(struct host1x_client *client) 1329 { 1330 struct tegra_dc *dc = host1x_client_to_dc(client); 1331 int err; 1332 1333 devm_free_irq(dc->dev, dc->irq, dc); 1334 1335 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 1336 err = tegra_dc_debugfs_exit(dc); 1337 if (err < 0) 1338 dev_err(dc->dev, "debugfs cleanup failed: %d\n", err); 1339 } 1340 1341 err = tegra_dc_rgb_exit(dc); 1342 if (err) { 1343 dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err); 1344 return err; 1345 } 1346 1347 return 0; 1348 } 1349 1350 static const struct host1x_client_ops dc_client_ops = { 1351 .init = tegra_dc_init, 1352 .exit = tegra_dc_exit, 1353 }; 1354 1355 static const struct tegra_dc_soc_info tegra20_dc_soc_info = { 1356 .supports_interlacing = false, 1357 .supports_cursor = false, 1358 .supports_block_linear = false, 1359 .pitch_align = 8, 1360 }; 1361 1362 static const struct tegra_dc_soc_info tegra30_dc_soc_info = { 1363 .supports_interlacing = false, 1364 .supports_cursor = false, 1365 .supports_block_linear = false, 1366 .pitch_align = 8, 1367 }; 1368 1369 static const struct tegra_dc_soc_info tegra114_dc_soc_info = { 1370 .supports_interlacing = false, 1371 .supports_cursor = false, 1372 .supports_block_linear = false, 1373 .pitch_align = 64, 1374 }; 1375 1376 static const struct tegra_dc_soc_info tegra124_dc_soc_info = { 1377 .supports_interlacing = true, 1378 .supports_cursor = true, 1379 .supports_block_linear = true, 1380 .pitch_align = 64, 1381 }; 1382 1383 static const struct of_device_id tegra_dc_of_match[] = { 1384 { 1385 .compatible = "nvidia,tegra124-dc", 1386 .data = &tegra124_dc_soc_info, 1387 }, { 1388 .compatible = "nvidia,tegra30-dc", 1389 .data = &tegra30_dc_soc_info, 1390 }, { 1391 .compatible = "nvidia,tegra20-dc", 1392 .data = &tegra20_dc_soc_info, 1393 }, { 1394 /* sentinel */ 1395 } 1396 }; 1397 MODULE_DEVICE_TABLE(of, tegra_dc_of_match); 1398 1399 static int tegra_dc_parse_dt(struct tegra_dc *dc) 1400 { 1401 struct device_node *np; 1402 u32 value = 0; 1403 int err; 1404 1405 err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value); 1406 if (err < 0) { 1407 dev_err(dc->dev, "missing \"nvidia,head\" property\n"); 1408 1409 /* 1410 * If the nvidia,head property isn't present, try to find the 1411 * correct head number by looking up the position of this 1412 * display controller's node within the device tree. Assuming 1413 * that the nodes are ordered properly in the DTS file and 1414 * that the translation into a flattened device tree blob 1415 * preserves that ordering this will actually yield the right 1416 * head number. 1417 * 1418 * If those assumptions don't hold, this will still work for 1419 * cases where only a single display controller is used. 1420 */ 1421 for_each_matching_node(np, tegra_dc_of_match) { 1422 if (np == dc->dev->of_node) 1423 break; 1424 1425 value++; 1426 } 1427 } 1428 1429 dc->pipe = value; 1430 1431 return 0; 1432 } 1433 1434 static int tegra_dc_probe(struct platform_device *pdev) 1435 { 1436 const struct of_device_id *id; 1437 struct resource *regs; 1438 struct tegra_dc *dc; 1439 int err; 1440 1441 dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL); 1442 if (!dc) 1443 return -ENOMEM; 1444 1445 id = of_match_node(tegra_dc_of_match, pdev->dev.of_node); 1446 if (!id) 1447 return -ENODEV; 1448 1449 spin_lock_init(&dc->lock); 1450 INIT_LIST_HEAD(&dc->list); 1451 dc->dev = &pdev->dev; 1452 dc->soc = id->data; 1453 1454 err = tegra_dc_parse_dt(dc); 1455 if (err < 0) 1456 return err; 1457 1458 dc->clk = devm_clk_get(&pdev->dev, NULL); 1459 if (IS_ERR(dc->clk)) { 1460 dev_err(&pdev->dev, "failed to get clock\n"); 1461 return PTR_ERR(dc->clk); 1462 } 1463 1464 dc->rst = devm_reset_control_get(&pdev->dev, "dc"); 1465 if (IS_ERR(dc->rst)) { 1466 dev_err(&pdev->dev, "failed to get reset\n"); 1467 return PTR_ERR(dc->rst); 1468 } 1469 1470 err = clk_prepare_enable(dc->clk); 1471 if (err < 0) 1472 return err; 1473 1474 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1475 dc->regs = devm_ioremap_resource(&pdev->dev, regs); 1476 if (IS_ERR(dc->regs)) 1477 return PTR_ERR(dc->regs); 1478 1479 dc->irq = platform_get_irq(pdev, 0); 1480 if (dc->irq < 0) { 1481 dev_err(&pdev->dev, "failed to get IRQ\n"); 1482 return -ENXIO; 1483 } 1484 1485 INIT_LIST_HEAD(&dc->client.list); 1486 dc->client.ops = &dc_client_ops; 1487 dc->client.dev = &pdev->dev; 1488 1489 err = tegra_dc_rgb_probe(dc); 1490 if (err < 0 && err != -ENODEV) { 1491 dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err); 1492 return err; 1493 } 1494 1495 err = host1x_client_register(&dc->client); 1496 if (err < 0) { 1497 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 1498 err); 1499 return err; 1500 } 1501 1502 platform_set_drvdata(pdev, dc); 1503 1504 return 0; 1505 } 1506 1507 static int tegra_dc_remove(struct platform_device *pdev) 1508 { 1509 struct tegra_dc *dc = platform_get_drvdata(pdev); 1510 int err; 1511 1512 err = host1x_client_unregister(&dc->client); 1513 if (err < 0) { 1514 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", 1515 err); 1516 return err; 1517 } 1518 1519 err = tegra_dc_rgb_remove(dc); 1520 if (err < 0) { 1521 dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err); 1522 return err; 1523 } 1524 1525 reset_control_assert(dc->rst); 1526 clk_disable_unprepare(dc->clk); 1527 1528 return 0; 1529 } 1530 1531 struct platform_driver tegra_dc_driver = { 1532 .driver = { 1533 .name = "tegra-dc", 1534 .owner = THIS_MODULE, 1535 .of_match_table = tegra_dc_of_match, 1536 }, 1537 .probe = tegra_dc_probe, 1538 .remove = tegra_dc_remove, 1539 }; 1540