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 drm_device *drm = crtc->dev; 740 struct drm_plane *plane; 741 742 drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) { 743 if (plane->crtc == crtc) { 744 tegra_plane_disable(plane); 745 plane->crtc = NULL; 746 747 if (plane->fb) { 748 drm_framebuffer_unreference(plane->fb); 749 plane->fb = NULL; 750 } 751 } 752 } 753 754 drm_crtc_vblank_off(crtc); 755 } 756 757 static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc, 758 const struct drm_display_mode *mode, 759 struct drm_display_mode *adjusted) 760 { 761 return true; 762 } 763 764 static int tegra_dc_set_timings(struct tegra_dc *dc, 765 struct drm_display_mode *mode) 766 { 767 unsigned int h_ref_to_sync = 1; 768 unsigned int v_ref_to_sync = 1; 769 unsigned long value; 770 771 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS); 772 773 value = (v_ref_to_sync << 16) | h_ref_to_sync; 774 tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC); 775 776 value = ((mode->vsync_end - mode->vsync_start) << 16) | 777 ((mode->hsync_end - mode->hsync_start) << 0); 778 tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH); 779 780 value = ((mode->vtotal - mode->vsync_end) << 16) | 781 ((mode->htotal - mode->hsync_end) << 0); 782 tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH); 783 784 value = ((mode->vsync_start - mode->vdisplay) << 16) | 785 ((mode->hsync_start - mode->hdisplay) << 0); 786 tegra_dc_writel(dc, value, DC_DISP_FRONT_PORCH); 787 788 value = (mode->vdisplay << 16) | mode->hdisplay; 789 tegra_dc_writel(dc, value, DC_DISP_ACTIVE); 790 791 return 0; 792 } 793 794 static int tegra_crtc_setup_clk(struct drm_crtc *crtc, 795 struct drm_display_mode *mode) 796 { 797 unsigned long pclk = mode->clock * 1000; 798 struct tegra_dc *dc = to_tegra_dc(crtc); 799 struct tegra_output *output = NULL; 800 struct drm_encoder *encoder; 801 unsigned int div; 802 u32 value; 803 long err; 804 805 list_for_each_entry(encoder, &crtc->dev->mode_config.encoder_list, head) 806 if (encoder->crtc == crtc) { 807 output = encoder_to_output(encoder); 808 break; 809 } 810 811 if (!output) 812 return -ENODEV; 813 814 /* 815 * This assumes that the parent clock is pll_d_out0 or pll_d2_out 816 * respectively, each of which divides the base pll_d by 2. 817 */ 818 err = tegra_output_setup_clock(output, dc->clk, pclk, &div); 819 if (err < 0) { 820 dev_err(dc->dev, "failed to setup clock: %ld\n", err); 821 return err; 822 } 823 824 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), div); 825 826 value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1; 827 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); 828 829 return 0; 830 } 831 832 static int tegra_crtc_mode_set(struct drm_crtc *crtc, 833 struct drm_display_mode *mode, 834 struct drm_display_mode *adjusted, 835 int x, int y, struct drm_framebuffer *old_fb) 836 { 837 struct tegra_bo *bo = tegra_fb_get_plane(crtc->primary->fb, 0); 838 struct tegra_dc *dc = to_tegra_dc(crtc); 839 struct tegra_dc_window window; 840 u32 value; 841 int err; 842 843 err = tegra_crtc_setup_clk(crtc, mode); 844 if (err) { 845 dev_err(dc->dev, "failed to setup clock for CRTC: %d\n", err); 846 return err; 847 } 848 849 /* program display mode */ 850 tegra_dc_set_timings(dc, mode); 851 852 /* interlacing isn't supported yet, so disable it */ 853 if (dc->soc->supports_interlacing) { 854 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); 855 value &= ~INTERLACE_ENABLE; 856 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL); 857 } 858 859 /* setup window parameters */ 860 memset(&window, 0, sizeof(window)); 861 window.src.x = 0; 862 window.src.y = 0; 863 window.src.w = mode->hdisplay; 864 window.src.h = mode->vdisplay; 865 window.dst.x = 0; 866 window.dst.y = 0; 867 window.dst.w = mode->hdisplay; 868 window.dst.h = mode->vdisplay; 869 window.format = tegra_dc_format(crtc->primary->fb->pixel_format, 870 &window.swap); 871 window.bits_per_pixel = crtc->primary->fb->bits_per_pixel; 872 window.stride[0] = crtc->primary->fb->pitches[0]; 873 window.base[0] = bo->paddr; 874 875 err = tegra_dc_setup_window(dc, 0, &window); 876 if (err < 0) 877 dev_err(dc->dev, "failed to enable root plane\n"); 878 879 return 0; 880 } 881 882 static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 883 struct drm_framebuffer *old_fb) 884 { 885 struct tegra_dc *dc = to_tegra_dc(crtc); 886 887 return tegra_dc_set_base(dc, x, y, crtc->primary->fb); 888 } 889 890 static void tegra_crtc_prepare(struct drm_crtc *crtc) 891 { 892 struct tegra_dc *dc = to_tegra_dc(crtc); 893 unsigned int syncpt; 894 unsigned long value; 895 896 drm_crtc_vblank_off(crtc); 897 898 /* hardware initialization */ 899 reset_control_deassert(dc->rst); 900 usleep_range(10000, 20000); 901 902 if (dc->pipe) 903 syncpt = SYNCPT_VBLANK1; 904 else 905 syncpt = SYNCPT_VBLANK0; 906 907 /* initialize display controller */ 908 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 909 tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC); 910 911 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT; 912 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); 913 914 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | 915 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT; 916 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY); 917 918 /* initialize timer */ 919 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) | 920 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20); 921 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY); 922 923 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) | 924 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1); 925 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 926 927 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT; 928 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE); 929 930 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT; 931 tegra_dc_writel(dc, value, DC_CMD_INT_MASK); 932 } 933 934 static void tegra_crtc_commit(struct drm_crtc *crtc) 935 { 936 struct tegra_dc *dc = to_tegra_dc(crtc); 937 unsigned long value; 938 939 value = GENERAL_UPDATE | WIN_A_UPDATE; 940 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 941 942 value = GENERAL_ACT_REQ | WIN_A_ACT_REQ; 943 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 944 945 drm_crtc_vblank_on(crtc); 946 } 947 948 static void tegra_crtc_load_lut(struct drm_crtc *crtc) 949 { 950 } 951 952 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = { 953 .disable = tegra_crtc_disable, 954 .mode_fixup = tegra_crtc_mode_fixup, 955 .mode_set = tegra_crtc_mode_set, 956 .mode_set_base = tegra_crtc_mode_set_base, 957 .prepare = tegra_crtc_prepare, 958 .commit = tegra_crtc_commit, 959 .load_lut = tegra_crtc_load_lut, 960 }; 961 962 static irqreturn_t tegra_dc_irq(int irq, void *data) 963 { 964 struct tegra_dc *dc = data; 965 unsigned long status; 966 967 status = tegra_dc_readl(dc, DC_CMD_INT_STATUS); 968 tegra_dc_writel(dc, status, DC_CMD_INT_STATUS); 969 970 if (status & FRAME_END_INT) { 971 /* 972 dev_dbg(dc->dev, "%s(): frame end\n", __func__); 973 */ 974 } 975 976 if (status & VBLANK_INT) { 977 /* 978 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); 979 */ 980 drm_handle_vblank(dc->base.dev, dc->pipe); 981 tegra_dc_finish_page_flip(dc); 982 } 983 984 if (status & (WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT)) { 985 /* 986 dev_dbg(dc->dev, "%s(): underflow\n", __func__); 987 */ 988 } 989 990 return IRQ_HANDLED; 991 } 992 993 static int tegra_dc_show_regs(struct seq_file *s, void *data) 994 { 995 struct drm_info_node *node = s->private; 996 struct tegra_dc *dc = node->info_ent->data; 997 998 #define DUMP_REG(name) \ 999 seq_printf(s, "%-40s %#05x %08lx\n", #name, name, \ 1000 tegra_dc_readl(dc, name)) 1001 1002 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT); 1003 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 1004 DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR); 1005 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT); 1006 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL); 1007 DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR); 1008 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT); 1009 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL); 1010 DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR); 1011 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT); 1012 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL); 1013 DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR); 1014 DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC); 1015 DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0); 1016 DUMP_REG(DC_CMD_DISPLAY_COMMAND); 1017 DUMP_REG(DC_CMD_SIGNAL_RAISE); 1018 DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL); 1019 DUMP_REG(DC_CMD_INT_STATUS); 1020 DUMP_REG(DC_CMD_INT_MASK); 1021 DUMP_REG(DC_CMD_INT_ENABLE); 1022 DUMP_REG(DC_CMD_INT_TYPE); 1023 DUMP_REG(DC_CMD_INT_POLARITY); 1024 DUMP_REG(DC_CMD_SIGNAL_RAISE1); 1025 DUMP_REG(DC_CMD_SIGNAL_RAISE2); 1026 DUMP_REG(DC_CMD_SIGNAL_RAISE3); 1027 DUMP_REG(DC_CMD_STATE_ACCESS); 1028 DUMP_REG(DC_CMD_STATE_CONTROL); 1029 DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER); 1030 DUMP_REG(DC_CMD_REG_ACT_CONTROL); 1031 DUMP_REG(DC_COM_CRC_CONTROL); 1032 DUMP_REG(DC_COM_CRC_CHECKSUM); 1033 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0)); 1034 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1)); 1035 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2)); 1036 DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3)); 1037 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0)); 1038 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1)); 1039 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2)); 1040 DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3)); 1041 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0)); 1042 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1)); 1043 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2)); 1044 DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3)); 1045 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0)); 1046 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1)); 1047 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2)); 1048 DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3)); 1049 DUMP_REG(DC_COM_PIN_INPUT_DATA(0)); 1050 DUMP_REG(DC_COM_PIN_INPUT_DATA(1)); 1051 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0)); 1052 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1)); 1053 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2)); 1054 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3)); 1055 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4)); 1056 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5)); 1057 DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6)); 1058 DUMP_REG(DC_COM_PIN_MISC_CONTROL); 1059 DUMP_REG(DC_COM_PIN_PM0_CONTROL); 1060 DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE); 1061 DUMP_REG(DC_COM_PIN_PM1_CONTROL); 1062 DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE); 1063 DUMP_REG(DC_COM_SPI_CONTROL); 1064 DUMP_REG(DC_COM_SPI_START_BYTE); 1065 DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB); 1066 DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD); 1067 DUMP_REG(DC_COM_HSPI_CS_DC); 1068 DUMP_REG(DC_COM_SCRATCH_REGISTER_A); 1069 DUMP_REG(DC_COM_SCRATCH_REGISTER_B); 1070 DUMP_REG(DC_COM_GPIO_CTRL); 1071 DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER); 1072 DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED); 1073 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0); 1074 DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1); 1075 DUMP_REG(DC_DISP_DISP_WIN_OPTIONS); 1076 DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY); 1077 DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER); 1078 DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS); 1079 DUMP_REG(DC_DISP_REF_TO_SYNC); 1080 DUMP_REG(DC_DISP_SYNC_WIDTH); 1081 DUMP_REG(DC_DISP_BACK_PORCH); 1082 DUMP_REG(DC_DISP_ACTIVE); 1083 DUMP_REG(DC_DISP_FRONT_PORCH); 1084 DUMP_REG(DC_DISP_H_PULSE0_CONTROL); 1085 DUMP_REG(DC_DISP_H_PULSE0_POSITION_A); 1086 DUMP_REG(DC_DISP_H_PULSE0_POSITION_B); 1087 DUMP_REG(DC_DISP_H_PULSE0_POSITION_C); 1088 DUMP_REG(DC_DISP_H_PULSE0_POSITION_D); 1089 DUMP_REG(DC_DISP_H_PULSE1_CONTROL); 1090 DUMP_REG(DC_DISP_H_PULSE1_POSITION_A); 1091 DUMP_REG(DC_DISP_H_PULSE1_POSITION_B); 1092 DUMP_REG(DC_DISP_H_PULSE1_POSITION_C); 1093 DUMP_REG(DC_DISP_H_PULSE1_POSITION_D); 1094 DUMP_REG(DC_DISP_H_PULSE2_CONTROL); 1095 DUMP_REG(DC_DISP_H_PULSE2_POSITION_A); 1096 DUMP_REG(DC_DISP_H_PULSE2_POSITION_B); 1097 DUMP_REG(DC_DISP_H_PULSE2_POSITION_C); 1098 DUMP_REG(DC_DISP_H_PULSE2_POSITION_D); 1099 DUMP_REG(DC_DISP_V_PULSE0_CONTROL); 1100 DUMP_REG(DC_DISP_V_PULSE0_POSITION_A); 1101 DUMP_REG(DC_DISP_V_PULSE0_POSITION_B); 1102 DUMP_REG(DC_DISP_V_PULSE0_POSITION_C); 1103 DUMP_REG(DC_DISP_V_PULSE1_CONTROL); 1104 DUMP_REG(DC_DISP_V_PULSE1_POSITION_A); 1105 DUMP_REG(DC_DISP_V_PULSE1_POSITION_B); 1106 DUMP_REG(DC_DISP_V_PULSE1_POSITION_C); 1107 DUMP_REG(DC_DISP_V_PULSE2_CONTROL); 1108 DUMP_REG(DC_DISP_V_PULSE2_POSITION_A); 1109 DUMP_REG(DC_DISP_V_PULSE3_CONTROL); 1110 DUMP_REG(DC_DISP_V_PULSE3_POSITION_A); 1111 DUMP_REG(DC_DISP_M0_CONTROL); 1112 DUMP_REG(DC_DISP_M1_CONTROL); 1113 DUMP_REG(DC_DISP_DI_CONTROL); 1114 DUMP_REG(DC_DISP_PP_CONTROL); 1115 DUMP_REG(DC_DISP_PP_SELECT_A); 1116 DUMP_REG(DC_DISP_PP_SELECT_B); 1117 DUMP_REG(DC_DISP_PP_SELECT_C); 1118 DUMP_REG(DC_DISP_PP_SELECT_D); 1119 DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL); 1120 DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL); 1121 DUMP_REG(DC_DISP_DISP_COLOR_CONTROL); 1122 DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS); 1123 DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS); 1124 DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS); 1125 DUMP_REG(DC_DISP_LCD_SPI_OPTIONS); 1126 DUMP_REG(DC_DISP_BORDER_COLOR); 1127 DUMP_REG(DC_DISP_COLOR_KEY0_LOWER); 1128 DUMP_REG(DC_DISP_COLOR_KEY0_UPPER); 1129 DUMP_REG(DC_DISP_COLOR_KEY1_LOWER); 1130 DUMP_REG(DC_DISP_COLOR_KEY1_UPPER); 1131 DUMP_REG(DC_DISP_CURSOR_FOREGROUND); 1132 DUMP_REG(DC_DISP_CURSOR_BACKGROUND); 1133 DUMP_REG(DC_DISP_CURSOR_START_ADDR); 1134 DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS); 1135 DUMP_REG(DC_DISP_CURSOR_POSITION); 1136 DUMP_REG(DC_DISP_CURSOR_POSITION_NS); 1137 DUMP_REG(DC_DISP_INIT_SEQ_CONTROL); 1138 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A); 1139 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B); 1140 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C); 1141 DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D); 1142 DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL); 1143 DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST); 1144 DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST); 1145 DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST); 1146 DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST); 1147 DUMP_REG(DC_DISP_DAC_CRT_CTRL); 1148 DUMP_REG(DC_DISP_DISP_MISC_CONTROL); 1149 DUMP_REG(DC_DISP_SD_CONTROL); 1150 DUMP_REG(DC_DISP_SD_CSC_COEFF); 1151 DUMP_REG(DC_DISP_SD_LUT(0)); 1152 DUMP_REG(DC_DISP_SD_LUT(1)); 1153 DUMP_REG(DC_DISP_SD_LUT(2)); 1154 DUMP_REG(DC_DISP_SD_LUT(3)); 1155 DUMP_REG(DC_DISP_SD_LUT(4)); 1156 DUMP_REG(DC_DISP_SD_LUT(5)); 1157 DUMP_REG(DC_DISP_SD_LUT(6)); 1158 DUMP_REG(DC_DISP_SD_LUT(7)); 1159 DUMP_REG(DC_DISP_SD_LUT(8)); 1160 DUMP_REG(DC_DISP_SD_FLICKER_CONTROL); 1161 DUMP_REG(DC_DISP_DC_PIXEL_COUNT); 1162 DUMP_REG(DC_DISP_SD_HISTOGRAM(0)); 1163 DUMP_REG(DC_DISP_SD_HISTOGRAM(1)); 1164 DUMP_REG(DC_DISP_SD_HISTOGRAM(2)); 1165 DUMP_REG(DC_DISP_SD_HISTOGRAM(3)); 1166 DUMP_REG(DC_DISP_SD_HISTOGRAM(4)); 1167 DUMP_REG(DC_DISP_SD_HISTOGRAM(5)); 1168 DUMP_REG(DC_DISP_SD_HISTOGRAM(6)); 1169 DUMP_REG(DC_DISP_SD_HISTOGRAM(7)); 1170 DUMP_REG(DC_DISP_SD_BL_TF(0)); 1171 DUMP_REG(DC_DISP_SD_BL_TF(1)); 1172 DUMP_REG(DC_DISP_SD_BL_TF(2)); 1173 DUMP_REG(DC_DISP_SD_BL_TF(3)); 1174 DUMP_REG(DC_DISP_SD_BL_CONTROL); 1175 DUMP_REG(DC_DISP_SD_HW_K_VALUES); 1176 DUMP_REG(DC_DISP_SD_MAN_K_VALUES); 1177 DUMP_REG(DC_DISP_CURSOR_START_ADDR_HI); 1178 DUMP_REG(DC_DISP_BLEND_CURSOR_CONTROL); 1179 DUMP_REG(DC_WIN_WIN_OPTIONS); 1180 DUMP_REG(DC_WIN_BYTE_SWAP); 1181 DUMP_REG(DC_WIN_BUFFER_CONTROL); 1182 DUMP_REG(DC_WIN_COLOR_DEPTH); 1183 DUMP_REG(DC_WIN_POSITION); 1184 DUMP_REG(DC_WIN_SIZE); 1185 DUMP_REG(DC_WIN_PRESCALED_SIZE); 1186 DUMP_REG(DC_WIN_H_INITIAL_DDA); 1187 DUMP_REG(DC_WIN_V_INITIAL_DDA); 1188 DUMP_REG(DC_WIN_DDA_INC); 1189 DUMP_REG(DC_WIN_LINE_STRIDE); 1190 DUMP_REG(DC_WIN_BUF_STRIDE); 1191 DUMP_REG(DC_WIN_UV_BUF_STRIDE); 1192 DUMP_REG(DC_WIN_BUFFER_ADDR_MODE); 1193 DUMP_REG(DC_WIN_DV_CONTROL); 1194 DUMP_REG(DC_WIN_BLEND_NOKEY); 1195 DUMP_REG(DC_WIN_BLEND_1WIN); 1196 DUMP_REG(DC_WIN_BLEND_2WIN_X); 1197 DUMP_REG(DC_WIN_BLEND_2WIN_Y); 1198 DUMP_REG(DC_WIN_BLEND_3WIN_XY); 1199 DUMP_REG(DC_WIN_HP_FETCH_CONTROL); 1200 DUMP_REG(DC_WINBUF_START_ADDR); 1201 DUMP_REG(DC_WINBUF_START_ADDR_NS); 1202 DUMP_REG(DC_WINBUF_START_ADDR_U); 1203 DUMP_REG(DC_WINBUF_START_ADDR_U_NS); 1204 DUMP_REG(DC_WINBUF_START_ADDR_V); 1205 DUMP_REG(DC_WINBUF_START_ADDR_V_NS); 1206 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET); 1207 DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS); 1208 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET); 1209 DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS); 1210 DUMP_REG(DC_WINBUF_UFLOW_STATUS); 1211 DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS); 1212 DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS); 1213 DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS); 1214 1215 #undef DUMP_REG 1216 1217 return 0; 1218 } 1219 1220 static struct drm_info_list debugfs_files[] = { 1221 { "regs", tegra_dc_show_regs, 0, NULL }, 1222 }; 1223 1224 static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor) 1225 { 1226 unsigned int i; 1227 char *name; 1228 int err; 1229 1230 name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe); 1231 dc->debugfs = debugfs_create_dir(name, minor->debugfs_root); 1232 kfree(name); 1233 1234 if (!dc->debugfs) 1235 return -ENOMEM; 1236 1237 dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files), 1238 GFP_KERNEL); 1239 if (!dc->debugfs_files) { 1240 err = -ENOMEM; 1241 goto remove; 1242 } 1243 1244 for (i = 0; i < ARRAY_SIZE(debugfs_files); i++) 1245 dc->debugfs_files[i].data = dc; 1246 1247 err = drm_debugfs_create_files(dc->debugfs_files, 1248 ARRAY_SIZE(debugfs_files), 1249 dc->debugfs, minor); 1250 if (err < 0) 1251 goto free; 1252 1253 dc->minor = minor; 1254 1255 return 0; 1256 1257 free: 1258 kfree(dc->debugfs_files); 1259 dc->debugfs_files = NULL; 1260 remove: 1261 debugfs_remove(dc->debugfs); 1262 dc->debugfs = NULL; 1263 1264 return err; 1265 } 1266 1267 static int tegra_dc_debugfs_exit(struct tegra_dc *dc) 1268 { 1269 drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files), 1270 dc->minor); 1271 dc->minor = NULL; 1272 1273 kfree(dc->debugfs_files); 1274 dc->debugfs_files = NULL; 1275 1276 debugfs_remove(dc->debugfs); 1277 dc->debugfs = NULL; 1278 1279 return 0; 1280 } 1281 1282 static int tegra_dc_init(struct host1x_client *client) 1283 { 1284 struct drm_device *drm = dev_get_drvdata(client->parent); 1285 struct tegra_dc *dc = host1x_client_to_dc(client); 1286 struct tegra_drm *tegra = drm->dev_private; 1287 int err; 1288 1289 drm_crtc_init(drm, &dc->base, &tegra_crtc_funcs); 1290 drm_mode_crtc_set_gamma_size(&dc->base, 256); 1291 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1292 1293 /* 1294 * Keep track of the minimum pitch alignment across all display 1295 * controllers. 1296 */ 1297 if (dc->soc->pitch_align > tegra->pitch_align) 1298 tegra->pitch_align = dc->soc->pitch_align; 1299 1300 err = tegra_dc_rgb_init(drm, dc); 1301 if (err < 0 && err != -ENODEV) { 1302 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err); 1303 return err; 1304 } 1305 1306 err = tegra_dc_add_planes(drm, dc); 1307 if (err < 0) 1308 return err; 1309 1310 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 1311 err = tegra_dc_debugfs_init(dc, drm->primary); 1312 if (err < 0) 1313 dev_err(dc->dev, "debugfs setup failed: %d\n", err); 1314 } 1315 1316 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0, 1317 dev_name(dc->dev), dc); 1318 if (err < 0) { 1319 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq, 1320 err); 1321 return err; 1322 } 1323 1324 return 0; 1325 } 1326 1327 static int tegra_dc_exit(struct host1x_client *client) 1328 { 1329 struct tegra_dc *dc = host1x_client_to_dc(client); 1330 int err; 1331 1332 devm_free_irq(dc->dev, dc->irq, dc); 1333 1334 if (IS_ENABLED(CONFIG_DEBUG_FS)) { 1335 err = tegra_dc_debugfs_exit(dc); 1336 if (err < 0) 1337 dev_err(dc->dev, "debugfs cleanup failed: %d\n", err); 1338 } 1339 1340 err = tegra_dc_rgb_exit(dc); 1341 if (err) { 1342 dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err); 1343 return err; 1344 } 1345 1346 return 0; 1347 } 1348 1349 static const struct host1x_client_ops dc_client_ops = { 1350 .init = tegra_dc_init, 1351 .exit = tegra_dc_exit, 1352 }; 1353 1354 static const struct tegra_dc_soc_info tegra20_dc_soc_info = { 1355 .supports_interlacing = false, 1356 .supports_cursor = false, 1357 .supports_block_linear = false, 1358 .pitch_align = 8, 1359 }; 1360 1361 static const struct tegra_dc_soc_info tegra30_dc_soc_info = { 1362 .supports_interlacing = false, 1363 .supports_cursor = false, 1364 .supports_block_linear = false, 1365 .pitch_align = 8, 1366 }; 1367 1368 static const struct tegra_dc_soc_info tegra114_dc_soc_info = { 1369 .supports_interlacing = false, 1370 .supports_cursor = false, 1371 .supports_block_linear = false, 1372 .pitch_align = 64, 1373 }; 1374 1375 static const struct tegra_dc_soc_info tegra124_dc_soc_info = { 1376 .supports_interlacing = true, 1377 .supports_cursor = true, 1378 .supports_block_linear = true, 1379 .pitch_align = 64, 1380 }; 1381 1382 static const struct of_device_id tegra_dc_of_match[] = { 1383 { 1384 .compatible = "nvidia,tegra124-dc", 1385 .data = &tegra124_dc_soc_info, 1386 }, { 1387 .compatible = "nvidia,tegra30-dc", 1388 .data = &tegra30_dc_soc_info, 1389 }, { 1390 .compatible = "nvidia,tegra20-dc", 1391 .data = &tegra20_dc_soc_info, 1392 }, { 1393 /* sentinel */ 1394 } 1395 }; 1396 MODULE_DEVICE_TABLE(of, tegra_dc_of_match); 1397 1398 static int tegra_dc_parse_dt(struct tegra_dc *dc) 1399 { 1400 struct device_node *np; 1401 u32 value = 0; 1402 int err; 1403 1404 err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value); 1405 if (err < 0) { 1406 dev_err(dc->dev, "missing \"nvidia,head\" property\n"); 1407 1408 /* 1409 * If the nvidia,head property isn't present, try to find the 1410 * correct head number by looking up the position of this 1411 * display controller's node within the device tree. Assuming 1412 * that the nodes are ordered properly in the DTS file and 1413 * that the translation into a flattened device tree blob 1414 * preserves that ordering this will actually yield the right 1415 * head number. 1416 * 1417 * If those assumptions don't hold, this will still work for 1418 * cases where only a single display controller is used. 1419 */ 1420 for_each_matching_node(np, tegra_dc_of_match) { 1421 if (np == dc->dev->of_node) 1422 break; 1423 1424 value++; 1425 } 1426 } 1427 1428 dc->pipe = value; 1429 1430 return 0; 1431 } 1432 1433 static int tegra_dc_probe(struct platform_device *pdev) 1434 { 1435 const struct of_device_id *id; 1436 struct resource *regs; 1437 struct tegra_dc *dc; 1438 int err; 1439 1440 dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL); 1441 if (!dc) 1442 return -ENOMEM; 1443 1444 id = of_match_node(tegra_dc_of_match, pdev->dev.of_node); 1445 if (!id) 1446 return -ENODEV; 1447 1448 spin_lock_init(&dc->lock); 1449 INIT_LIST_HEAD(&dc->list); 1450 dc->dev = &pdev->dev; 1451 dc->soc = id->data; 1452 1453 err = tegra_dc_parse_dt(dc); 1454 if (err < 0) 1455 return err; 1456 1457 dc->clk = devm_clk_get(&pdev->dev, NULL); 1458 if (IS_ERR(dc->clk)) { 1459 dev_err(&pdev->dev, "failed to get clock\n"); 1460 return PTR_ERR(dc->clk); 1461 } 1462 1463 dc->rst = devm_reset_control_get(&pdev->dev, "dc"); 1464 if (IS_ERR(dc->rst)) { 1465 dev_err(&pdev->dev, "failed to get reset\n"); 1466 return PTR_ERR(dc->rst); 1467 } 1468 1469 err = clk_prepare_enable(dc->clk); 1470 if (err < 0) 1471 return err; 1472 1473 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1474 dc->regs = devm_ioremap_resource(&pdev->dev, regs); 1475 if (IS_ERR(dc->regs)) 1476 return PTR_ERR(dc->regs); 1477 1478 dc->irq = platform_get_irq(pdev, 0); 1479 if (dc->irq < 0) { 1480 dev_err(&pdev->dev, "failed to get IRQ\n"); 1481 return -ENXIO; 1482 } 1483 1484 INIT_LIST_HEAD(&dc->client.list); 1485 dc->client.ops = &dc_client_ops; 1486 dc->client.dev = &pdev->dev; 1487 1488 err = tegra_dc_rgb_probe(dc); 1489 if (err < 0 && err != -ENODEV) { 1490 dev_err(&pdev->dev, "failed to probe RGB output: %d\n", err); 1491 return err; 1492 } 1493 1494 err = host1x_client_register(&dc->client); 1495 if (err < 0) { 1496 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 1497 err); 1498 return err; 1499 } 1500 1501 platform_set_drvdata(pdev, dc); 1502 1503 return 0; 1504 } 1505 1506 static int tegra_dc_remove(struct platform_device *pdev) 1507 { 1508 struct tegra_dc *dc = platform_get_drvdata(pdev); 1509 int err; 1510 1511 err = host1x_client_unregister(&dc->client); 1512 if (err < 0) { 1513 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", 1514 err); 1515 return err; 1516 } 1517 1518 err = tegra_dc_rgb_remove(dc); 1519 if (err < 0) { 1520 dev_err(&pdev->dev, "failed to remove RGB output: %d\n", err); 1521 return err; 1522 } 1523 1524 reset_control_assert(dc->rst); 1525 clk_disable_unprepare(dc->clk); 1526 1527 return 0; 1528 } 1529 1530 struct platform_driver tegra_dc_driver = { 1531 .driver = { 1532 .name = "tegra-dc", 1533 .owner = THIS_MODULE, 1534 .of_match_table = tegra_dc_of_match, 1535 }, 1536 .probe = tegra_dc_probe, 1537 .remove = tegra_dc_remove, 1538 }; 1539