1 /* exynos_drm_fimd.c 2 * 3 * Copyright (C) 2011 Samsung Electronics Co.Ltd 4 * Authors: 5 * Joonyoung Shim <jy0922.shim@samsung.com> 6 * Inki Dae <inki.dae@samsung.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 #include <drm/drmP.h> 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/platform_device.h> 19 #include <linux/clk.h> 20 #include <linux/of_device.h> 21 #include <linux/pm_runtime.h> 22 23 #include <video/samsung_fimd.h> 24 #include <drm/exynos_drm.h> 25 26 #include "exynos_drm_drv.h" 27 #include "exynos_drm_fbdev.h" 28 #include "exynos_drm_crtc.h" 29 #include "exynos_drm_iommu.h" 30 31 /* 32 * FIMD is stand for Fully Interactive Mobile Display and 33 * as a display controller, it transfers contents drawn on memory 34 * to a LCD Panel through Display Interfaces such as RGB or 35 * CPU Interface. 36 */ 37 38 /* position control register for hardware window 0, 2 ~ 4.*/ 39 #define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) 40 #define VIDOSD_B(win) (VIDOSD_BASE + 0x04 + (win) * 16) 41 /* 42 * size control register for hardware windows 0 and alpha control register 43 * for hardware windows 1 ~ 4 44 */ 45 #define VIDOSD_C(win) (VIDOSD_BASE + 0x08 + (win) * 16) 46 /* size control register for hardware windows 1 ~ 2. */ 47 #define VIDOSD_D(win) (VIDOSD_BASE + 0x0C + (win) * 16) 48 49 #define VIDWx_BUF_START(win, buf) (VIDW_BUF_START(buf) + (win) * 8) 50 #define VIDWx_BUF_END(win, buf) (VIDW_BUF_END(buf) + (win) * 8) 51 #define VIDWx_BUF_SIZE(win, buf) (VIDW_BUF_SIZE(buf) + (win) * 4) 52 53 /* color key control register for hardware window 1 ~ 4. */ 54 #define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + ((x - 1) * 8)) 55 /* color key value register for hardware window 1 ~ 4. */ 56 #define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8)) 57 58 /* FIMD has totally five hardware windows. */ 59 #define WINDOWS_NR 5 60 61 #define get_fimd_context(dev) platform_get_drvdata(to_platform_device(dev)) 62 63 struct fimd_driver_data { 64 unsigned int timing_base; 65 }; 66 67 static struct fimd_driver_data exynos4_fimd_driver_data = { 68 .timing_base = 0x0, 69 }; 70 71 static struct fimd_driver_data exynos5_fimd_driver_data = { 72 .timing_base = 0x20000, 73 }; 74 75 struct fimd_win_data { 76 unsigned int offset_x; 77 unsigned int offset_y; 78 unsigned int ovl_width; 79 unsigned int ovl_height; 80 unsigned int fb_width; 81 unsigned int fb_height; 82 unsigned int bpp; 83 dma_addr_t dma_addr; 84 unsigned int buf_offsize; 85 unsigned int line_size; /* bytes */ 86 bool enabled; 87 bool resume; 88 }; 89 90 struct fimd_context { 91 struct exynos_drm_subdrv subdrv; 92 int irq; 93 struct drm_crtc *crtc; 94 struct clk *bus_clk; 95 struct clk *lcd_clk; 96 void __iomem *regs; 97 struct fimd_win_data win_data[WINDOWS_NR]; 98 unsigned int clkdiv; 99 unsigned int default_win; 100 unsigned long irq_flags; 101 u32 vidcon0; 102 u32 vidcon1; 103 bool suspended; 104 struct mutex lock; 105 wait_queue_head_t wait_vsync_queue; 106 atomic_t wait_vsync_event; 107 108 struct exynos_drm_panel_info *panel; 109 }; 110 111 #ifdef CONFIG_OF 112 static const struct of_device_id fimd_driver_dt_match[] = { 113 { .compatible = "samsung,exynos4210-fimd", 114 .data = &exynos4_fimd_driver_data }, 115 { .compatible = "samsung,exynos5250-fimd", 116 .data = &exynos5_fimd_driver_data }, 117 {}, 118 }; 119 MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); 120 #endif 121 122 static inline struct fimd_driver_data *drm_fimd_get_driver_data( 123 struct platform_device *pdev) 124 { 125 #ifdef CONFIG_OF 126 const struct of_device_id *of_id = 127 of_match_device(fimd_driver_dt_match, &pdev->dev); 128 129 if (of_id) 130 return (struct fimd_driver_data *)of_id->data; 131 #endif 132 133 return (struct fimd_driver_data *) 134 platform_get_device_id(pdev)->driver_data; 135 } 136 137 static bool fimd_display_is_connected(struct device *dev) 138 { 139 DRM_DEBUG_KMS("%s\n", __FILE__); 140 141 /* TODO. */ 142 143 return true; 144 } 145 146 static void *fimd_get_panel(struct device *dev) 147 { 148 struct fimd_context *ctx = get_fimd_context(dev); 149 150 DRM_DEBUG_KMS("%s\n", __FILE__); 151 152 return ctx->panel; 153 } 154 155 static int fimd_check_timing(struct device *dev, void *timing) 156 { 157 DRM_DEBUG_KMS("%s\n", __FILE__); 158 159 /* TODO. */ 160 161 return 0; 162 } 163 164 static int fimd_display_power_on(struct device *dev, int mode) 165 { 166 DRM_DEBUG_KMS("%s\n", __FILE__); 167 168 /* TODO */ 169 170 return 0; 171 } 172 173 static struct exynos_drm_display_ops fimd_display_ops = { 174 .type = EXYNOS_DISPLAY_TYPE_LCD, 175 .is_connected = fimd_display_is_connected, 176 .get_panel = fimd_get_panel, 177 .check_timing = fimd_check_timing, 178 .power_on = fimd_display_power_on, 179 }; 180 181 static void fimd_dpms(struct device *subdrv_dev, int mode) 182 { 183 struct fimd_context *ctx = get_fimd_context(subdrv_dev); 184 185 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); 186 187 mutex_lock(&ctx->lock); 188 189 switch (mode) { 190 case DRM_MODE_DPMS_ON: 191 /* 192 * enable fimd hardware only if suspended status. 193 * 194 * P.S. fimd_dpms function would be called at booting time so 195 * clk_enable could be called double time. 196 */ 197 if (ctx->suspended) 198 pm_runtime_get_sync(subdrv_dev); 199 break; 200 case DRM_MODE_DPMS_STANDBY: 201 case DRM_MODE_DPMS_SUSPEND: 202 case DRM_MODE_DPMS_OFF: 203 if (!ctx->suspended) 204 pm_runtime_put_sync(subdrv_dev); 205 break; 206 default: 207 DRM_DEBUG_KMS("unspecified mode %d\n", mode); 208 break; 209 } 210 211 mutex_unlock(&ctx->lock); 212 } 213 214 static void fimd_apply(struct device *subdrv_dev) 215 { 216 struct fimd_context *ctx = get_fimd_context(subdrv_dev); 217 struct exynos_drm_manager *mgr = ctx->subdrv.manager; 218 struct exynos_drm_manager_ops *mgr_ops = mgr->ops; 219 struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; 220 struct fimd_win_data *win_data; 221 int i; 222 223 DRM_DEBUG_KMS("%s\n", __FILE__); 224 225 for (i = 0; i < WINDOWS_NR; i++) { 226 win_data = &ctx->win_data[i]; 227 if (win_data->enabled && (ovl_ops && ovl_ops->commit)) 228 ovl_ops->commit(subdrv_dev, i); 229 } 230 231 if (mgr_ops && mgr_ops->commit) 232 mgr_ops->commit(subdrv_dev); 233 } 234 235 static void fimd_commit(struct device *dev) 236 { 237 struct fimd_context *ctx = get_fimd_context(dev); 238 struct exynos_drm_panel_info *panel = ctx->panel; 239 struct fb_videomode *timing = &panel->timing; 240 struct fimd_driver_data *driver_data; 241 struct platform_device *pdev = to_platform_device(dev); 242 u32 val; 243 244 driver_data = drm_fimd_get_driver_data(pdev); 245 if (ctx->suspended) 246 return; 247 248 DRM_DEBUG_KMS("%s\n", __FILE__); 249 250 /* setup polarity values from machine code. */ 251 writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1); 252 253 /* setup vertical timing values. */ 254 val = VIDTCON0_VBPD(timing->upper_margin - 1) | 255 VIDTCON0_VFPD(timing->lower_margin - 1) | 256 VIDTCON0_VSPW(timing->vsync_len - 1); 257 writel(val, ctx->regs + driver_data->timing_base + VIDTCON0); 258 259 /* setup horizontal timing values. */ 260 val = VIDTCON1_HBPD(timing->left_margin - 1) | 261 VIDTCON1_HFPD(timing->right_margin - 1) | 262 VIDTCON1_HSPW(timing->hsync_len - 1); 263 writel(val, ctx->regs + driver_data->timing_base + VIDTCON1); 264 265 /* setup horizontal and vertical display size. */ 266 val = VIDTCON2_LINEVAL(timing->yres - 1) | 267 VIDTCON2_HOZVAL(timing->xres - 1) | 268 VIDTCON2_LINEVAL_E(timing->yres - 1) | 269 VIDTCON2_HOZVAL_E(timing->xres - 1); 270 writel(val, ctx->regs + driver_data->timing_base + VIDTCON2); 271 272 /* setup clock source, clock divider, enable dma. */ 273 val = ctx->vidcon0; 274 val &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR); 275 276 if (ctx->clkdiv > 1) 277 val |= VIDCON0_CLKVAL_F(ctx->clkdiv - 1) | VIDCON0_CLKDIR; 278 else 279 val &= ~VIDCON0_CLKDIR; /* 1:1 clock */ 280 281 /* 282 * fields of register with prefix '_F' would be updated 283 * at vsync(same as dma start) 284 */ 285 val |= VIDCON0_ENVID | VIDCON0_ENVID_F; 286 writel(val, ctx->regs + VIDCON0); 287 } 288 289 static int fimd_enable_vblank(struct device *dev) 290 { 291 struct fimd_context *ctx = get_fimd_context(dev); 292 u32 val; 293 294 DRM_DEBUG_KMS("%s\n", __FILE__); 295 296 if (ctx->suspended) 297 return -EPERM; 298 299 if (!test_and_set_bit(0, &ctx->irq_flags)) { 300 val = readl(ctx->regs + VIDINTCON0); 301 302 val |= VIDINTCON0_INT_ENABLE; 303 val |= VIDINTCON0_INT_FRAME; 304 305 val &= ~VIDINTCON0_FRAMESEL0_MASK; 306 val |= VIDINTCON0_FRAMESEL0_VSYNC; 307 val &= ~VIDINTCON0_FRAMESEL1_MASK; 308 val |= VIDINTCON0_FRAMESEL1_NONE; 309 310 writel(val, ctx->regs + VIDINTCON0); 311 } 312 313 return 0; 314 } 315 316 static void fimd_disable_vblank(struct device *dev) 317 { 318 struct fimd_context *ctx = get_fimd_context(dev); 319 u32 val; 320 321 DRM_DEBUG_KMS("%s\n", __FILE__); 322 323 if (ctx->suspended) 324 return; 325 326 if (test_and_clear_bit(0, &ctx->irq_flags)) { 327 val = readl(ctx->regs + VIDINTCON0); 328 329 val &= ~VIDINTCON0_INT_FRAME; 330 val &= ~VIDINTCON0_INT_ENABLE; 331 332 writel(val, ctx->regs + VIDINTCON0); 333 } 334 } 335 336 static void fimd_wait_for_vblank(struct device *dev) 337 { 338 struct fimd_context *ctx = get_fimd_context(dev); 339 340 if (ctx->suspended) 341 return; 342 343 atomic_set(&ctx->wait_vsync_event, 1); 344 345 /* 346 * wait for FIMD to signal VSYNC interrupt or return after 347 * timeout which is set to 50ms (refresh rate of 20). 348 */ 349 if (!wait_event_timeout(ctx->wait_vsync_queue, 350 !atomic_read(&ctx->wait_vsync_event), 351 DRM_HZ/20)) 352 DRM_DEBUG_KMS("vblank wait timed out.\n"); 353 } 354 355 static struct exynos_drm_manager_ops fimd_manager_ops = { 356 .dpms = fimd_dpms, 357 .apply = fimd_apply, 358 .commit = fimd_commit, 359 .enable_vblank = fimd_enable_vblank, 360 .disable_vblank = fimd_disable_vblank, 361 .wait_for_vblank = fimd_wait_for_vblank, 362 }; 363 364 static void fimd_win_mode_set(struct device *dev, 365 struct exynos_drm_overlay *overlay) 366 { 367 struct fimd_context *ctx = get_fimd_context(dev); 368 struct fimd_win_data *win_data; 369 int win; 370 unsigned long offset; 371 372 DRM_DEBUG_KMS("%s\n", __FILE__); 373 374 if (!overlay) { 375 dev_err(dev, "overlay is NULL\n"); 376 return; 377 } 378 379 win = overlay->zpos; 380 if (win == DEFAULT_ZPOS) 381 win = ctx->default_win; 382 383 if (win < 0 || win > WINDOWS_NR) 384 return; 385 386 offset = overlay->fb_x * (overlay->bpp >> 3); 387 offset += overlay->fb_y * overlay->pitch; 388 389 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); 390 391 win_data = &ctx->win_data[win]; 392 393 win_data->offset_x = overlay->crtc_x; 394 win_data->offset_y = overlay->crtc_y; 395 win_data->ovl_width = overlay->crtc_width; 396 win_data->ovl_height = overlay->crtc_height; 397 win_data->fb_width = overlay->fb_width; 398 win_data->fb_height = overlay->fb_height; 399 win_data->dma_addr = overlay->dma_addr[0] + offset; 400 win_data->bpp = overlay->bpp; 401 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) * 402 (overlay->bpp >> 3); 403 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3); 404 405 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", 406 win_data->offset_x, win_data->offset_y); 407 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", 408 win_data->ovl_width, win_data->ovl_height); 409 DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); 410 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", 411 overlay->fb_width, overlay->crtc_width); 412 } 413 414 static void fimd_win_set_pixfmt(struct device *dev, unsigned int win) 415 { 416 struct fimd_context *ctx = get_fimd_context(dev); 417 struct fimd_win_data *win_data = &ctx->win_data[win]; 418 unsigned long val; 419 420 DRM_DEBUG_KMS("%s\n", __FILE__); 421 422 val = WINCONx_ENWIN; 423 424 switch (win_data->bpp) { 425 case 1: 426 val |= WINCON0_BPPMODE_1BPP; 427 val |= WINCONx_BITSWP; 428 val |= WINCONx_BURSTLEN_4WORD; 429 break; 430 case 2: 431 val |= WINCON0_BPPMODE_2BPP; 432 val |= WINCONx_BITSWP; 433 val |= WINCONx_BURSTLEN_8WORD; 434 break; 435 case 4: 436 val |= WINCON0_BPPMODE_4BPP; 437 val |= WINCONx_BITSWP; 438 val |= WINCONx_BURSTLEN_8WORD; 439 break; 440 case 8: 441 val |= WINCON0_BPPMODE_8BPP_PALETTE; 442 val |= WINCONx_BURSTLEN_8WORD; 443 val |= WINCONx_BYTSWP; 444 break; 445 case 16: 446 val |= WINCON0_BPPMODE_16BPP_565; 447 val |= WINCONx_HAWSWP; 448 val |= WINCONx_BURSTLEN_16WORD; 449 break; 450 case 24: 451 val |= WINCON0_BPPMODE_24BPP_888; 452 val |= WINCONx_WSWP; 453 val |= WINCONx_BURSTLEN_16WORD; 454 break; 455 case 32: 456 val |= WINCON1_BPPMODE_28BPP_A4888 457 | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL; 458 val |= WINCONx_WSWP; 459 val |= WINCONx_BURSTLEN_16WORD; 460 break; 461 default: 462 DRM_DEBUG_KMS("invalid pixel size so using unpacked 24bpp.\n"); 463 464 val |= WINCON0_BPPMODE_24BPP_888; 465 val |= WINCONx_WSWP; 466 val |= WINCONx_BURSTLEN_16WORD; 467 break; 468 } 469 470 DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); 471 472 writel(val, ctx->regs + WINCON(win)); 473 } 474 475 static void fimd_win_set_colkey(struct device *dev, unsigned int win) 476 { 477 struct fimd_context *ctx = get_fimd_context(dev); 478 unsigned int keycon0 = 0, keycon1 = 0; 479 480 DRM_DEBUG_KMS("%s\n", __FILE__); 481 482 keycon0 = ~(WxKEYCON0_KEYBL_EN | WxKEYCON0_KEYEN_F | 483 WxKEYCON0_DIRCON) | WxKEYCON0_COMPKEY(0); 484 485 keycon1 = WxKEYCON1_COLVAL(0xffffffff); 486 487 writel(keycon0, ctx->regs + WKEYCON0_BASE(win)); 488 writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); 489 } 490 491 static void fimd_win_commit(struct device *dev, int zpos) 492 { 493 struct fimd_context *ctx = get_fimd_context(dev); 494 struct fimd_win_data *win_data; 495 int win = zpos; 496 unsigned long val, alpha, size; 497 unsigned int last_x; 498 unsigned int last_y; 499 500 DRM_DEBUG_KMS("%s\n", __FILE__); 501 502 if (ctx->suspended) 503 return; 504 505 if (win == DEFAULT_ZPOS) 506 win = ctx->default_win; 507 508 if (win < 0 || win > WINDOWS_NR) 509 return; 510 511 win_data = &ctx->win_data[win]; 512 513 /* 514 * SHADOWCON register is used for enabling timing. 515 * 516 * for example, once only width value of a register is set, 517 * if the dma is started then fimd hardware could malfunction so 518 * with protect window setting, the register fields with prefix '_F' 519 * wouldn't be updated at vsync also but updated once unprotect window 520 * is set. 521 */ 522 523 /* protect windows */ 524 val = readl(ctx->regs + SHADOWCON); 525 val |= SHADOWCON_WINx_PROTECT(win); 526 writel(val, ctx->regs + SHADOWCON); 527 528 /* buffer start address */ 529 val = (unsigned long)win_data->dma_addr; 530 writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); 531 532 /* buffer end address */ 533 size = win_data->fb_width * win_data->ovl_height * (win_data->bpp >> 3); 534 val = (unsigned long)(win_data->dma_addr + size); 535 writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); 536 537 DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", 538 (unsigned long)win_data->dma_addr, val, size); 539 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", 540 win_data->ovl_width, win_data->ovl_height); 541 542 /* buffer size */ 543 val = VIDW_BUF_SIZE_OFFSET(win_data->buf_offsize) | 544 VIDW_BUF_SIZE_PAGEWIDTH(win_data->line_size) | 545 VIDW_BUF_SIZE_OFFSET_E(win_data->buf_offsize) | 546 VIDW_BUF_SIZE_PAGEWIDTH_E(win_data->line_size); 547 writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); 548 549 /* OSD position */ 550 val = VIDOSDxA_TOPLEFT_X(win_data->offset_x) | 551 VIDOSDxA_TOPLEFT_Y(win_data->offset_y) | 552 VIDOSDxA_TOPLEFT_X_E(win_data->offset_x) | 553 VIDOSDxA_TOPLEFT_Y_E(win_data->offset_y); 554 writel(val, ctx->regs + VIDOSD_A(win)); 555 556 last_x = win_data->offset_x + win_data->ovl_width; 557 if (last_x) 558 last_x--; 559 last_y = win_data->offset_y + win_data->ovl_height; 560 if (last_y) 561 last_y--; 562 563 val = VIDOSDxB_BOTRIGHT_X(last_x) | VIDOSDxB_BOTRIGHT_Y(last_y) | 564 VIDOSDxB_BOTRIGHT_X_E(last_x) | VIDOSDxB_BOTRIGHT_Y_E(last_y); 565 566 writel(val, ctx->regs + VIDOSD_B(win)); 567 568 DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", 569 win_data->offset_x, win_data->offset_y, last_x, last_y); 570 571 /* hardware window 0 doesn't support alpha channel. */ 572 if (win != 0) { 573 /* OSD alpha */ 574 alpha = VIDISD14C_ALPHA1_R(0xf) | 575 VIDISD14C_ALPHA1_G(0xf) | 576 VIDISD14C_ALPHA1_B(0xf); 577 578 writel(alpha, ctx->regs + VIDOSD_C(win)); 579 } 580 581 /* OSD size */ 582 if (win != 3 && win != 4) { 583 u32 offset = VIDOSD_D(win); 584 if (win == 0) 585 offset = VIDOSD_C(win); 586 val = win_data->ovl_width * win_data->ovl_height; 587 writel(val, ctx->regs + offset); 588 589 DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); 590 } 591 592 fimd_win_set_pixfmt(dev, win); 593 594 /* hardware window 0 doesn't support color key. */ 595 if (win != 0) 596 fimd_win_set_colkey(dev, win); 597 598 /* wincon */ 599 val = readl(ctx->regs + WINCON(win)); 600 val |= WINCONx_ENWIN; 601 writel(val, ctx->regs + WINCON(win)); 602 603 /* Enable DMA channel and unprotect windows */ 604 val = readl(ctx->regs + SHADOWCON); 605 val |= SHADOWCON_CHx_ENABLE(win); 606 val &= ~SHADOWCON_WINx_PROTECT(win); 607 writel(val, ctx->regs + SHADOWCON); 608 609 win_data->enabled = true; 610 } 611 612 static void fimd_win_disable(struct device *dev, int zpos) 613 { 614 struct fimd_context *ctx = get_fimd_context(dev); 615 struct fimd_win_data *win_data; 616 int win = zpos; 617 u32 val; 618 619 DRM_DEBUG_KMS("%s\n", __FILE__); 620 621 if (win == DEFAULT_ZPOS) 622 win = ctx->default_win; 623 624 if (win < 0 || win > WINDOWS_NR) 625 return; 626 627 win_data = &ctx->win_data[win]; 628 629 if (ctx->suspended) { 630 /* do not resume this window*/ 631 win_data->resume = false; 632 return; 633 } 634 635 /* protect windows */ 636 val = readl(ctx->regs + SHADOWCON); 637 val |= SHADOWCON_WINx_PROTECT(win); 638 writel(val, ctx->regs + SHADOWCON); 639 640 /* wincon */ 641 val = readl(ctx->regs + WINCON(win)); 642 val &= ~WINCONx_ENWIN; 643 writel(val, ctx->regs + WINCON(win)); 644 645 /* unprotect windows */ 646 val = readl(ctx->regs + SHADOWCON); 647 val &= ~SHADOWCON_CHx_ENABLE(win); 648 val &= ~SHADOWCON_WINx_PROTECT(win); 649 writel(val, ctx->regs + SHADOWCON); 650 651 win_data->enabled = false; 652 } 653 654 static struct exynos_drm_overlay_ops fimd_overlay_ops = { 655 .mode_set = fimd_win_mode_set, 656 .commit = fimd_win_commit, 657 .disable = fimd_win_disable, 658 }; 659 660 static struct exynos_drm_manager fimd_manager = { 661 .pipe = -1, 662 .ops = &fimd_manager_ops, 663 .overlay_ops = &fimd_overlay_ops, 664 .display_ops = &fimd_display_ops, 665 }; 666 667 static irqreturn_t fimd_irq_handler(int irq, void *dev_id) 668 { 669 struct fimd_context *ctx = (struct fimd_context *)dev_id; 670 struct exynos_drm_subdrv *subdrv = &ctx->subdrv; 671 struct drm_device *drm_dev = subdrv->drm_dev; 672 struct exynos_drm_manager *manager = subdrv->manager; 673 u32 val; 674 675 val = readl(ctx->regs + VIDINTCON1); 676 677 if (val & VIDINTCON1_INT_FRAME) 678 /* VSYNC interrupt */ 679 writel(VIDINTCON1_INT_FRAME, ctx->regs + VIDINTCON1); 680 681 /* check the crtc is detached already from encoder */ 682 if (manager->pipe < 0) 683 goto out; 684 685 drm_handle_vblank(drm_dev, manager->pipe); 686 exynos_drm_crtc_finish_pageflip(drm_dev, manager->pipe); 687 688 /* set wait vsync event to zero and wake up queue. */ 689 if (atomic_read(&ctx->wait_vsync_event)) { 690 atomic_set(&ctx->wait_vsync_event, 0); 691 DRM_WAKEUP(&ctx->wait_vsync_queue); 692 } 693 out: 694 return IRQ_HANDLED; 695 } 696 697 static int fimd_subdrv_probe(struct drm_device *drm_dev, struct device *dev) 698 { 699 DRM_DEBUG_KMS("%s\n", __FILE__); 700 701 /* 702 * enable drm irq mode. 703 * - with irq_enabled = 1, we can use the vblank feature. 704 * 705 * P.S. note that we wouldn't use drm irq handler but 706 * just specific driver own one instead because 707 * drm framework supports only one irq handler. 708 */ 709 drm_dev->irq_enabled = 1; 710 711 /* 712 * with vblank_disable_allowed = 1, vblank interrupt will be disabled 713 * by drm timer once a current process gives up ownership of 714 * vblank event.(after drm_vblank_put function is called) 715 */ 716 drm_dev->vblank_disable_allowed = 1; 717 718 /* attach this sub driver to iommu mapping if supported. */ 719 if (is_drm_iommu_supported(drm_dev)) 720 drm_iommu_attach_device(drm_dev, dev); 721 722 return 0; 723 } 724 725 static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev) 726 { 727 DRM_DEBUG_KMS("%s\n", __FILE__); 728 729 /* detach this sub driver from iommu mapping if supported. */ 730 if (is_drm_iommu_supported(drm_dev)) 731 drm_iommu_detach_device(drm_dev, dev); 732 } 733 734 static int fimd_calc_clkdiv(struct fimd_context *ctx, 735 struct fb_videomode *timing) 736 { 737 unsigned long clk = clk_get_rate(ctx->lcd_clk); 738 u32 retrace; 739 u32 clkdiv; 740 u32 best_framerate = 0; 741 u32 framerate; 742 743 DRM_DEBUG_KMS("%s\n", __FILE__); 744 745 retrace = timing->left_margin + timing->hsync_len + 746 timing->right_margin + timing->xres; 747 retrace *= timing->upper_margin + timing->vsync_len + 748 timing->lower_margin + timing->yres; 749 750 /* default framerate is 60Hz */ 751 if (!timing->refresh) 752 timing->refresh = 60; 753 754 clk /= retrace; 755 756 for (clkdiv = 1; clkdiv < 0x100; clkdiv++) { 757 int tmp; 758 759 /* get best framerate */ 760 framerate = clk / clkdiv; 761 tmp = timing->refresh - framerate; 762 if (tmp < 0) { 763 best_framerate = framerate; 764 continue; 765 } else { 766 if (!best_framerate) 767 best_framerate = framerate; 768 else if (tmp < (best_framerate - framerate)) 769 best_framerate = framerate; 770 break; 771 } 772 } 773 774 return clkdiv; 775 } 776 777 static void fimd_clear_win(struct fimd_context *ctx, int win) 778 { 779 u32 val; 780 781 DRM_DEBUG_KMS("%s\n", __FILE__); 782 783 writel(0, ctx->regs + WINCON(win)); 784 writel(0, ctx->regs + VIDOSD_A(win)); 785 writel(0, ctx->regs + VIDOSD_B(win)); 786 writel(0, ctx->regs + VIDOSD_C(win)); 787 788 if (win == 1 || win == 2) 789 writel(0, ctx->regs + VIDOSD_D(win)); 790 791 val = readl(ctx->regs + SHADOWCON); 792 val &= ~SHADOWCON_WINx_PROTECT(win); 793 writel(val, ctx->regs + SHADOWCON); 794 } 795 796 static int fimd_clock(struct fimd_context *ctx, bool enable) 797 { 798 DRM_DEBUG_KMS("%s\n", __FILE__); 799 800 if (enable) { 801 int ret; 802 803 ret = clk_enable(ctx->bus_clk); 804 if (ret < 0) 805 return ret; 806 807 ret = clk_enable(ctx->lcd_clk); 808 if (ret < 0) { 809 clk_disable(ctx->bus_clk); 810 return ret; 811 } 812 } else { 813 clk_disable(ctx->lcd_clk); 814 clk_disable(ctx->bus_clk); 815 } 816 817 return 0; 818 } 819 820 static void fimd_window_suspend(struct device *dev) 821 { 822 struct fimd_context *ctx = get_fimd_context(dev); 823 struct fimd_win_data *win_data; 824 int i; 825 826 for (i = 0; i < WINDOWS_NR; i++) { 827 win_data = &ctx->win_data[i]; 828 win_data->resume = win_data->enabled; 829 fimd_win_disable(dev, i); 830 } 831 fimd_wait_for_vblank(dev); 832 } 833 834 static void fimd_window_resume(struct device *dev) 835 { 836 struct fimd_context *ctx = get_fimd_context(dev); 837 struct fimd_win_data *win_data; 838 int i; 839 840 for (i = 0; i < WINDOWS_NR; i++) { 841 win_data = &ctx->win_data[i]; 842 win_data->enabled = win_data->resume; 843 win_data->resume = false; 844 } 845 } 846 847 static int fimd_activate(struct fimd_context *ctx, bool enable) 848 { 849 struct device *dev = ctx->subdrv.dev; 850 if (enable) { 851 int ret; 852 853 ret = fimd_clock(ctx, true); 854 if (ret < 0) 855 return ret; 856 857 ctx->suspended = false; 858 859 /* if vblank was enabled status, enable it again. */ 860 if (test_and_clear_bit(0, &ctx->irq_flags)) 861 fimd_enable_vblank(dev); 862 863 fimd_window_resume(dev); 864 } else { 865 fimd_window_suspend(dev); 866 867 fimd_clock(ctx, false); 868 ctx->suspended = true; 869 } 870 871 return 0; 872 } 873 874 static int fimd_probe(struct platform_device *pdev) 875 { 876 struct device *dev = &pdev->dev; 877 struct fimd_context *ctx; 878 struct exynos_drm_subdrv *subdrv; 879 struct exynos_drm_fimd_pdata *pdata; 880 struct exynos_drm_panel_info *panel; 881 struct resource *res; 882 int win; 883 int ret = -EINVAL; 884 885 DRM_DEBUG_KMS("%s\n", __FILE__); 886 887 pdata = pdev->dev.platform_data; 888 if (!pdata) { 889 dev_err(dev, "no platform data specified\n"); 890 return -EINVAL; 891 } 892 893 panel = &pdata->panel; 894 if (!panel) { 895 dev_err(dev, "panel is null.\n"); 896 return -EINVAL; 897 } 898 899 ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); 900 if (!ctx) 901 return -ENOMEM; 902 903 ctx->bus_clk = devm_clk_get(dev, "fimd"); 904 if (IS_ERR(ctx->bus_clk)) { 905 dev_err(dev, "failed to get bus clock\n"); 906 return PTR_ERR(ctx->bus_clk); 907 } 908 909 ctx->lcd_clk = devm_clk_get(dev, "sclk_fimd"); 910 if (IS_ERR(ctx->lcd_clk)) { 911 dev_err(dev, "failed to get lcd clock\n"); 912 return PTR_ERR(ctx->lcd_clk); 913 } 914 915 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 916 917 ctx->regs = devm_ioremap_resource(&pdev->dev, res); 918 if (IS_ERR(ctx->regs)) 919 return PTR_ERR(ctx->regs); 920 921 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 922 if (!res) { 923 dev_err(dev, "irq request failed.\n"); 924 return -ENXIO; 925 } 926 927 ctx->irq = res->start; 928 929 ret = devm_request_irq(&pdev->dev, ctx->irq, fimd_irq_handler, 930 0, "drm_fimd", ctx); 931 if (ret) { 932 dev_err(dev, "irq request failed.\n"); 933 return ret; 934 } 935 936 ctx->vidcon0 = pdata->vidcon0; 937 ctx->vidcon1 = pdata->vidcon1; 938 ctx->default_win = pdata->default_win; 939 ctx->panel = panel; 940 DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue); 941 atomic_set(&ctx->wait_vsync_event, 0); 942 943 subdrv = &ctx->subdrv; 944 945 subdrv->dev = dev; 946 subdrv->manager = &fimd_manager; 947 subdrv->probe = fimd_subdrv_probe; 948 subdrv->remove = fimd_subdrv_remove; 949 950 mutex_init(&ctx->lock); 951 952 platform_set_drvdata(pdev, ctx); 953 954 pm_runtime_enable(dev); 955 pm_runtime_get_sync(dev); 956 957 ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); 958 panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; 959 960 DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", 961 panel->timing.pixclock, ctx->clkdiv); 962 963 for (win = 0; win < WINDOWS_NR; win++) 964 fimd_clear_win(ctx, win); 965 966 exynos_drm_subdrv_register(subdrv); 967 968 return 0; 969 } 970 971 static int fimd_remove(struct platform_device *pdev) 972 { 973 struct device *dev = &pdev->dev; 974 struct fimd_context *ctx = platform_get_drvdata(pdev); 975 976 DRM_DEBUG_KMS("%s\n", __FILE__); 977 978 exynos_drm_subdrv_unregister(&ctx->subdrv); 979 980 if (ctx->suspended) 981 goto out; 982 983 clk_disable(ctx->lcd_clk); 984 clk_disable(ctx->bus_clk); 985 986 pm_runtime_set_suspended(dev); 987 pm_runtime_put_sync(dev); 988 989 out: 990 pm_runtime_disable(dev); 991 992 return 0; 993 } 994 995 #ifdef CONFIG_PM_SLEEP 996 static int fimd_suspend(struct device *dev) 997 { 998 struct fimd_context *ctx = get_fimd_context(dev); 999 1000 /* 1001 * do not use pm_runtime_suspend(). if pm_runtime_suspend() is 1002 * called here, an error would be returned by that interface 1003 * because the usage_count of pm runtime is more than 1. 1004 */ 1005 if (!pm_runtime_suspended(dev)) 1006 return fimd_activate(ctx, false); 1007 1008 return 0; 1009 } 1010 1011 static int fimd_resume(struct device *dev) 1012 { 1013 struct fimd_context *ctx = get_fimd_context(dev); 1014 1015 /* 1016 * if entered to sleep when lcd panel was on, the usage_count 1017 * of pm runtime would still be 1 so in this case, fimd driver 1018 * should be on directly not drawing on pm runtime interface. 1019 */ 1020 if (!pm_runtime_suspended(dev)) { 1021 int ret; 1022 1023 ret = fimd_activate(ctx, true); 1024 if (ret < 0) 1025 return ret; 1026 1027 /* 1028 * in case of dpms on(standby), fimd_apply function will 1029 * be called by encoder's dpms callback to update fimd's 1030 * registers but in case of sleep wakeup, it's not. 1031 * so fimd_apply function should be called at here. 1032 */ 1033 fimd_apply(dev); 1034 } 1035 1036 return 0; 1037 } 1038 #endif 1039 1040 #ifdef CONFIG_PM_RUNTIME 1041 static int fimd_runtime_suspend(struct device *dev) 1042 { 1043 struct fimd_context *ctx = get_fimd_context(dev); 1044 1045 DRM_DEBUG_KMS("%s\n", __FILE__); 1046 1047 return fimd_activate(ctx, false); 1048 } 1049 1050 static int fimd_runtime_resume(struct device *dev) 1051 { 1052 struct fimd_context *ctx = get_fimd_context(dev); 1053 1054 DRM_DEBUG_KMS("%s\n", __FILE__); 1055 1056 return fimd_activate(ctx, true); 1057 } 1058 #endif 1059 1060 static struct platform_device_id fimd_driver_ids[] = { 1061 { 1062 .name = "exynos4-fb", 1063 .driver_data = (unsigned long)&exynos4_fimd_driver_data, 1064 }, { 1065 .name = "exynos5-fb", 1066 .driver_data = (unsigned long)&exynos5_fimd_driver_data, 1067 }, 1068 {}, 1069 }; 1070 MODULE_DEVICE_TABLE(platform, fimd_driver_ids); 1071 1072 static const struct dev_pm_ops fimd_pm_ops = { 1073 SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) 1074 SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) 1075 }; 1076 1077 struct platform_driver fimd_driver = { 1078 .probe = fimd_probe, 1079 .remove = fimd_remove, 1080 .id_table = fimd_driver_ids, 1081 .driver = { 1082 .name = "exynos4-fb", 1083 .owner = THIS_MODULE, 1084 .pm = &fimd_pm_ops, 1085 .of_match_table = of_match_ptr(fimd_driver_dt_match), 1086 }, 1087 }; 1088