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