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