Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'exynos-drm-next' of git://git.kernel.org:/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

- Support runtime pm
. In case of most ARM SoC, each IP has each power domain which should be
controlled by each IP driver using runtime pm interface. So this patch
series makes each IP driver to control its own power domain when
drm dpms is requested.
- Support of_graph based dt binding for DP panel.
. This patch series adds of_graph based dt binding for DP panel.
And also it keeps backward compatibility. This includes dt binding
patch so I got Acked-by from Krzysztof Kozlowski who is a Exynos
SoC maintainer and from Rob Herring who is a device tree maintainer.

- Cleanup for Exynos DRM IPP enhancement.
. This patch series is a first step for enhancing existing IPP framework
which will integrate existing IPP functions with DRM KMS part so that
these can be transparent to userspace. For other portion of the patch
series, we will have more times for the review.]

* 'exynos-drm-next' of git://git.kernel.org:/pub/scm/linux/kernel/git/daeinki/drm-exynos: (29 commits)
drm/exynos: gem: remove old unused prototypes
drm/exynos: fimd: fix dma burst size setting for small plane size
drm/exynos: fix clipping when scaling is enabled
drm/exynos: mixer: use ratio precalculated in exynos_state
drm/exynos: add generic check for plane state
drm/exynos: introduce exynos_drm_plane_config structure
drm/exynos: mixer: enable video overlay plane only when VP is available
drm/exynos: mixer: use crtc->state->adjusted_mode instead of crtc->mode
drm/exynos: introduce exynos_drm_plane_state structure
drm/exynos: move dma_addr attribute from exynos plane to exynos fb
drm/exynos: exynos7-decon: remove excessive check
drm/exynos: rotator: convert to common clock framework
drm/exynos: gsc: add device tree support and remove usage of static mappings
drm/exynos: gsc: fix wrong pm_runtime state
drm/exynos: gsc: prepare and unprepare gsc clock
ARM: dts: Use OF graph for DP to panel connection in exynos5800-peach-pi
dt-bindings: exynos-dp: update ports node binding for panel
drm/exynos: dp: add of_graph dt binding support for panel
drm/exynos: decon: remove unused variables
drm/exynos: dsi: modify a error type when getting a node failed
...

+982 -605
+37 -4
Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
··· 1 + Device-Tree bindings for Samsung Exynos Embedded DisplayPort Transmitter(eDP) 2 + 3 + DisplayPort is industry standard to accommodate the growing board adoption 4 + of digital display technology within the PC and CE industries. 5 + It consolidates the internal and external connection methods to reduce device 6 + complexity and cost. It also supports necessary features for important cross 7 + industry applications and provides performance scalability to enable the next 8 + generation of displays that feature higher color depths, refresh rates, and 9 + display resolutions. 10 + 11 + eDP (embedded display port) device is compliant with Embedded DisplayPort 12 + standard as follows, 13 + - DisplayPort standard 1.1a for Exynos5250 and Exynos5260. 14 + - DisplayPort standard 1.3 for Exynos5422s and Exynos5800. 15 + 16 + eDP resides between FIMD and panel or FIMD and bridge such as LVDS. 17 + 1 18 The Exynos display port interface should be configured based on 2 19 the type of panel connected to it. 3 20 ··· 83 66 Hotplug detect GPIO. 84 67 Indicates which GPIO should be used for hotplug 85 68 detection 86 - -video interfaces: Device node can contain video interface port 87 - nodes according to [1]. 69 + Video interfaces: 70 + Device node can contain video interface port nodes according to [1]. 71 + The following are properties specific to those nodes: 72 + 73 + endpoint node connected to bridge or panel node: 74 + - remote-endpoint: specifies the endpoint in panel or bridge node. 75 + This node is required in all kinds of exynos dp 76 + to represent the connection between dp and bridge 77 + or dp and panel. 88 78 89 79 [1]: Documentation/devicetree/bindings/media/video-interfaces.txt 90 80 ··· 135 111 }; 136 112 137 113 ports { 138 - port@0 { 114 + port { 139 115 dp_out: endpoint { 140 - remote-endpoint = <&bridge_in>; 116 + remote-endpoint = <&dp_in>; 117 + }; 118 + }; 119 + }; 120 + 121 + panel { 122 + ... 123 + port { 124 + dp_in: endpoint { 125 + remote-endpoint = <&dp_out>; 141 126 }; 142 127 }; 143 128 };
+4
Documentation/devicetree/bindings/media/exynos5-gsc.txt
··· 7 7 - reg: should contain G-Scaler physical address location and length. 8 8 - interrupts: should contain G-Scaler interrupt number 9 9 10 + Optional properties: 11 + - samsung,sysreg: handle to syscon used to control the system registers to 12 + set writeback input and destination 13 + 10 14 Example: 11 15 12 16 gsc_0: gsc@0x13e00000 {
+14 -1
arch/arm/boot/dts/exynos5800-peach-pi.dts
··· 122 122 compatible = "auo,b133htn01"; 123 123 power-supply = <&tps65090_fet6>; 124 124 backlight = <&backlight>; 125 + 126 + port { 127 + panel_in: endpoint { 128 + remote-endpoint = <&dp_out>; 129 + }; 130 + }; 125 131 }; 126 132 127 133 mmc1_pwrseq: mmc1_pwrseq { ··· 154 148 samsung,link-rate = <0x0a>; 155 149 samsung,lane-count = <2>; 156 150 samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; 157 - panel = <&panel>; 151 + 152 + ports { 153 + port { 154 + dp_out: endpoint { 155 + remote-endpoint = <&panel_in>; 156 + }; 157 + }; 158 + }; 158 159 }; 159 160 160 161 &fimd {
+1 -1
drivers/gpu/drm/exynos/Kconfig
··· 118 118 119 119 config DRM_EXYNOS_GSC 120 120 bool "GScaler" 121 - depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM 121 + depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !VIDEO_SAMSUNG_EXYNOS_GSC 122 122 help 123 123 Choose this option if you want to use Exynos GSC for DRM. 124 124
+69 -35
drivers/gpu/drm/exynos/exynos5433_drm_decon.c
··· 21 21 22 22 #include "exynos_drm_drv.h" 23 23 #include "exynos_drm_crtc.h" 24 + #include "exynos_drm_fb.h" 24 25 #include "exynos_drm_plane.h" 25 26 #include "exynos_drm_iommu.h" 26 27 27 28 #define WINDOWS_NR 3 28 - #define CURSOR_WIN 2 29 29 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 30 30 31 31 static const char * const decon_clks_name[] = { ··· 56 56 struct drm_device *drm_dev; 57 57 struct exynos_drm_crtc *crtc; 58 58 struct exynos_drm_plane planes[WINDOWS_NR]; 59 + struct exynos_drm_plane_config configs[WINDOWS_NR]; 59 60 void __iomem *addr; 60 61 struct clk *clks[ARRAY_SIZE(decon_clks_name)]; 61 62 int pipe; ··· 70 69 DRM_FORMAT_RGB565, 71 70 DRM_FORMAT_XRGB8888, 72 71 DRM_FORMAT_ARGB8888, 72 + }; 73 + 74 + static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { 75 + DRM_PLANE_TYPE_PRIMARY, 76 + DRM_PLANE_TYPE_OVERLAY, 77 + DRM_PLANE_TYPE_CURSOR, 73 78 }; 74 79 75 80 static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask, ··· 266 259 static void decon_update_plane(struct exynos_drm_crtc *crtc, 267 260 struct exynos_drm_plane *plane) 268 261 { 262 + struct exynos_drm_plane_state *state = 263 + to_exynos_plane_state(plane->base.state); 269 264 struct decon_context *ctx = crtc->ctx; 270 - struct drm_plane_state *state = plane->base.state; 265 + struct drm_framebuffer *fb = state->base.fb; 271 266 unsigned int win = plane->zpos; 272 - unsigned int bpp = state->fb->bits_per_pixel >> 3; 273 - unsigned int pitch = state->fb->pitches[0]; 267 + unsigned int bpp = fb->bits_per_pixel >> 3; 268 + unsigned int pitch = fb->pitches[0]; 269 + dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); 274 270 u32 val; 275 271 276 272 if (test_bit(BIT_SUSPENDED, &ctx->flags)) 277 273 return; 278 274 279 - val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); 275 + val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y); 280 276 writel(val, ctx->addr + DECON_VIDOSDxA(win)); 281 277 282 - val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) | 283 - COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1); 278 + val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) | 279 + COORDINATE_Y(state->crtc.y + state->crtc.h - 1); 284 280 writel(val, ctx->addr + DECON_VIDOSDxB(win)); 285 281 286 282 val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | ··· 294 284 VIDOSD_Wx_ALPHA_B_F(0x0); 295 285 writel(val, ctx->addr + DECON_VIDOSDxD(win)); 296 286 297 - writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win)); 287 + writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); 298 288 299 - val = plane->dma_addr[0] + pitch * plane->crtc_h; 289 + val = dma_addr + pitch * state->src.h; 300 290 writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); 301 291 302 292 if (ctx->out_type != IFTYPE_HDMI) 303 - val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14) 304 - | BIT_VAL(plane->crtc_w * bpp, 13, 0); 293 + val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14) 294 + | BIT_VAL(state->crtc.w * bpp, 13, 0); 305 295 else 306 - val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15) 307 - | BIT_VAL(plane->crtc_w * bpp, 14, 0); 296 + val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15) 297 + | BIT_VAL(state->crtc.w * bpp, 14, 0); 308 298 writel(val, ctx->addr + DECON_VIDW0xADD2(win)); 309 299 310 - decon_win_set_pixfmt(ctx, win, state->fb); 300 + decon_win_set_pixfmt(ctx, win, fb); 311 301 312 302 /* window enable */ 313 303 decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0); ··· 387 377 static void decon_enable(struct exynos_drm_crtc *crtc) 388 378 { 389 379 struct decon_context *ctx = crtc->ctx; 390 - int ret; 391 - int i; 392 380 393 381 if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags)) 394 382 return; 395 383 396 384 pm_runtime_get_sync(ctx->dev); 397 - 398 - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 399 - ret = clk_prepare_enable(ctx->clks[i]); 400 - if (ret < 0) 401 - goto err; 402 - } 403 385 404 386 set_bit(BIT_CLKS_ENABLED, &ctx->flags); 405 387 ··· 400 398 decon_enable_vblank(ctx->crtc); 401 399 402 400 decon_commit(ctx->crtc); 403 - 404 - return; 405 - err: 406 - while (--i >= 0) 407 - clk_disable_unprepare(ctx->clks[i]); 408 401 409 402 set_bit(BIT_SUSPENDED, &ctx->flags); 410 403 } ··· 421 424 decon_disable_plane(crtc, &ctx->planes[i]); 422 425 423 426 decon_swreset(ctx); 424 - 425 - for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) 426 - clk_disable_unprepare(ctx->clks[i]); 427 427 428 428 clear_bit(BIT_CLKS_ENABLED, &ctx->flags); 429 429 ··· 472 478 static struct exynos_drm_crtc_ops decon_crtc_ops = { 473 479 .enable = decon_enable, 474 480 .disable = decon_disable, 475 - .commit = decon_commit, 476 481 .enable_vblank = decon_enable_vblank, 477 482 .disable_vblank = decon_disable_vblank, 478 483 .atomic_begin = decon_atomic_begin, ··· 488 495 struct exynos_drm_private *priv = drm_dev->dev_private; 489 496 struct exynos_drm_plane *exynos_plane; 490 497 enum exynos_drm_output_type out_type; 491 - enum drm_plane_type type; 492 498 unsigned int win; 493 499 int ret; 494 500 ··· 497 505 for (win = ctx->first_win; win < WINDOWS_NR; win++) { 498 506 int tmp = (win == ctx->first_win) ? 0 : win; 499 507 500 - type = exynos_plane_get_type(tmp, CURSOR_WIN); 508 + ctx->configs[win].pixel_formats = decon_formats; 509 + ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats); 510 + ctx->configs[win].zpos = win; 511 + ctx->configs[win].type = decon_win_types[tmp]; 512 + 501 513 ret = exynos_plane_init(drm_dev, &ctx->planes[win], 502 - 1 << ctx->pipe, type, decon_formats, 503 - ARRAY_SIZE(decon_formats), win); 514 + 1 << ctx->pipe, &ctx->configs[win]); 504 515 if (ret) 505 516 return ret; 506 517 } ··· 575 580 out: 576 581 return IRQ_HANDLED; 577 582 } 583 + 584 + #ifdef CONFIG_PM 585 + static int exynos5433_decon_suspend(struct device *dev) 586 + { 587 + struct decon_context *ctx = dev_get_drvdata(dev); 588 + int i; 589 + 590 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) 591 + clk_disable_unprepare(ctx->clks[i]); 592 + 593 + return 0; 594 + } 595 + 596 + static int exynos5433_decon_resume(struct device *dev) 597 + { 598 + struct decon_context *ctx = dev_get_drvdata(dev); 599 + int i, ret; 600 + 601 + for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) { 602 + ret = clk_prepare_enable(ctx->clks[i]); 603 + if (ret < 0) 604 + goto err; 605 + } 606 + 607 + return 0; 608 + 609 + err: 610 + while (--i >= 0) 611 + clk_disable_unprepare(ctx->clks[i]); 612 + 613 + return ret; 614 + } 615 + #endif 616 + 617 + static const struct dev_pm_ops exynos5433_decon_pm_ops = { 618 + SET_RUNTIME_PM_OPS(exynos5433_decon_suspend, exynos5433_decon_resume, 619 + NULL) 620 + }; 578 621 579 622 static const struct of_device_id exynos5433_decon_driver_dt_match[] = { 580 623 { ··· 717 684 .remove = exynos5433_decon_remove, 718 685 .driver = { 719 686 .name = "exynos5433-decon", 687 + .pm = &exynos5433_decon_pm_ops, 720 688 .of_match_table = exynos5433_decon_driver_dt_match, 721 689 }, 722 690 };
+89 -72
drivers/gpu/drm/exynos/exynos7_drm_decon.c
··· 30 30 #include "exynos_drm_crtc.h" 31 31 #include "exynos_drm_plane.h" 32 32 #include "exynos_drm_drv.h" 33 + #include "exynos_drm_fb.h" 33 34 #include "exynos_drm_fbdev.h" 34 35 #include "exynos_drm_iommu.h" 35 36 ··· 41 40 #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 42 41 43 42 #define WINDOWS_NR 2 44 - #define CURSOR_WIN 1 45 43 46 44 struct decon_context { 47 45 struct device *dev; 48 46 struct drm_device *drm_dev; 49 47 struct exynos_drm_crtc *crtc; 50 48 struct exynos_drm_plane planes[WINDOWS_NR]; 49 + struct exynos_drm_plane_config configs[WINDOWS_NR]; 51 50 struct clk *pclk; 52 51 struct clk *aclk; 53 52 struct clk *eclk; ··· 80 79 DRM_FORMAT_ABGR8888, 81 80 DRM_FORMAT_RGBA8888, 82 81 DRM_FORMAT_BGRA8888, 82 + }; 83 + 84 + static const enum drm_plane_type decon_win_types[WINDOWS_NR] = { 85 + DRM_PLANE_TYPE_PRIMARY, 86 + DRM_PLANE_TYPE_CURSOR, 83 87 }; 84 88 85 89 static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc) ··· 125 119 } 126 120 127 121 /* Wait for vsync, as disable channel takes effect at next vsync */ 128 - if (ch_enabled) { 129 - unsigned int state = ctx->suspended; 130 - 131 - ctx->suspended = 0; 122 + if (ch_enabled) 132 123 decon_wait_for_vblank(ctx->crtc); 133 - ctx->suspended = state; 134 - } 135 124 } 136 125 137 126 static int decon_ctx_initialize(struct decon_context *ctx, ··· 399 398 static void decon_update_plane(struct exynos_drm_crtc *crtc, 400 399 struct exynos_drm_plane *plane) 401 400 { 401 + struct exynos_drm_plane_state *state = 402 + to_exynos_plane_state(plane->base.state); 402 403 struct decon_context *ctx = crtc->ctx; 403 - struct drm_display_mode *mode = &crtc->base.state->adjusted_mode; 404 - struct drm_plane_state *state = plane->base.state; 404 + struct drm_framebuffer *fb = state->base.fb; 405 405 int padding; 406 406 unsigned long val, alpha; 407 407 unsigned int last_x; 408 408 unsigned int last_y; 409 409 unsigned int win = plane->zpos; 410 - unsigned int bpp = state->fb->bits_per_pixel >> 3; 411 - unsigned int pitch = state->fb->pitches[0]; 410 + unsigned int bpp = fb->bits_per_pixel >> 3; 411 + unsigned int pitch = fb->pitches[0]; 412 412 413 413 if (ctx->suspended) 414 414 return; ··· 425 423 */ 426 424 427 425 /* buffer start address */ 428 - val = (unsigned long)plane->dma_addr[0]; 426 + val = (unsigned long)exynos_drm_fb_dma_addr(fb, 0); 429 427 writel(val, ctx->regs + VIDW_BUF_START(win)); 430 428 431 - padding = (pitch / bpp) - state->fb->width; 429 + padding = (pitch / bpp) - fb->width; 432 430 433 431 /* buffer size */ 434 - writel(state->fb->width + padding, ctx->regs + VIDW_WHOLE_X(win)); 435 - writel(state->fb->height, ctx->regs + VIDW_WHOLE_Y(win)); 432 + writel(fb->width + padding, ctx->regs + VIDW_WHOLE_X(win)); 433 + writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win)); 436 434 437 435 /* offset from the start of the buffer to read */ 438 - writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win)); 439 - writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win)); 436 + writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win)); 437 + writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win)); 440 438 441 439 DRM_DEBUG_KMS("start addr = 0x%lx\n", 442 440 (unsigned long)val); 443 441 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", 444 - plane->crtc_w, plane->crtc_h); 442 + state->crtc.w, state->crtc.h); 445 443 446 - /* 447 - * OSD position. 448 - * In case the window layout goes of LCD layout, DECON fails. 449 - */ 450 - if ((plane->crtc_x + plane->crtc_w) > mode->hdisplay) 451 - plane->crtc_x = mode->hdisplay - plane->crtc_w; 452 - if ((plane->crtc_y + plane->crtc_h) > mode->vdisplay) 453 - plane->crtc_y = mode->vdisplay - plane->crtc_h; 454 - 455 - val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | 456 - VIDOSDxA_TOPLEFT_Y(plane->crtc_y); 444 + val = VIDOSDxA_TOPLEFT_X(state->crtc.x) | 445 + VIDOSDxA_TOPLEFT_Y(state->crtc.y); 457 446 writel(val, ctx->regs + VIDOSD_A(win)); 458 447 459 - last_x = plane->crtc_x + plane->crtc_w; 448 + last_x = state->crtc.x + state->crtc.w; 460 449 if (last_x) 461 450 last_x--; 462 - last_y = plane->crtc_y + plane->crtc_h; 451 + last_y = state->crtc.y + state->crtc.h; 463 452 if (last_y) 464 453 last_y--; 465 454 ··· 459 466 writel(val, ctx->regs + VIDOSD_B(win)); 460 467 461 468 DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", 462 - plane->crtc_x, plane->crtc_y, last_x, last_y); 469 + state->crtc.x, state->crtc.y, last_x, last_y); 463 470 464 471 /* OSD alpha */ 465 472 alpha = VIDOSDxC_ALPHA0_R_F(0x0) | ··· 474 481 475 482 writel(alpha, ctx->regs + VIDOSD_D(win)); 476 483 477 - decon_win_set_pixfmt(ctx, win, state->fb); 484 + decon_win_set_pixfmt(ctx, win, fb); 478 485 479 486 /* hardware window 0 doesn't support color key. */ 480 487 if (win != 0) ··· 548 555 static void decon_enable(struct exynos_drm_crtc *crtc) 549 556 { 550 557 struct decon_context *ctx = crtc->ctx; 551 - int ret; 552 558 553 559 if (!ctx->suspended) 554 560 return; 555 561 556 - ctx->suspended = false; 557 - 558 562 pm_runtime_get_sync(ctx->dev); 559 - 560 - ret = clk_prepare_enable(ctx->pclk); 561 - if (ret < 0) { 562 - DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); 563 - return; 564 - } 565 - 566 - ret = clk_prepare_enable(ctx->aclk); 567 - if (ret < 0) { 568 - DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); 569 - return; 570 - } 571 - 572 - ret = clk_prepare_enable(ctx->eclk); 573 - if (ret < 0) { 574 - DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); 575 - return; 576 - } 577 - 578 - ret = clk_prepare_enable(ctx->vclk); 579 - if (ret < 0) { 580 - DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); 581 - return; 582 - } 583 563 584 564 decon_init(ctx); 585 565 ··· 561 595 decon_enable_vblank(ctx->crtc); 562 596 563 597 decon_commit(ctx->crtc); 598 + 599 + ctx->suspended = false; 564 600 } 565 601 566 602 static void decon_disable(struct exynos_drm_crtc *crtc) ··· 580 612 */ 581 613 for (i = 0; i < WINDOWS_NR; i++) 582 614 decon_disable_plane(crtc, &ctx->planes[i]); 583 - 584 - clk_disable_unprepare(ctx->vclk); 585 - clk_disable_unprepare(ctx->eclk); 586 - clk_disable_unprepare(ctx->aclk); 587 - clk_disable_unprepare(ctx->pclk); 588 615 589 616 pm_runtime_put_sync(ctx->dev); 590 617 ··· 642 679 struct decon_context *ctx = dev_get_drvdata(dev); 643 680 struct drm_device *drm_dev = data; 644 681 struct exynos_drm_plane *exynos_plane; 645 - enum drm_plane_type type; 646 - unsigned int zpos; 682 + unsigned int i; 647 683 int ret; 648 684 649 685 ret = decon_ctx_initialize(ctx, drm_dev); ··· 651 689 return ret; 652 690 } 653 691 654 - for (zpos = 0; zpos < WINDOWS_NR; zpos++) { 655 - type = exynos_plane_get_type(zpos, CURSOR_WIN); 656 - ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], 657 - 1 << ctx->pipe, type, decon_formats, 658 - ARRAY_SIZE(decon_formats), zpos); 692 + for (i = 0; i < WINDOWS_NR; i++) { 693 + ctx->configs[i].pixel_formats = decon_formats; 694 + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(decon_formats); 695 + ctx->configs[i].zpos = i; 696 + ctx->configs[i].type = decon_win_types[i]; 697 + 698 + ret = exynos_plane_init(drm_dev, &ctx->planes[i], 699 + 1 << ctx->pipe, &ctx->configs[i]); 659 700 if (ret) 660 701 return ret; 661 702 } ··· 808 843 return 0; 809 844 } 810 845 846 + #ifdef CONFIG_PM 847 + static int exynos7_decon_suspend(struct device *dev) 848 + { 849 + struct decon_context *ctx = dev_get_drvdata(dev); 850 + 851 + clk_disable_unprepare(ctx->vclk); 852 + clk_disable_unprepare(ctx->eclk); 853 + clk_disable_unprepare(ctx->aclk); 854 + clk_disable_unprepare(ctx->pclk); 855 + 856 + return 0; 857 + } 858 + 859 + static int exynos7_decon_resume(struct device *dev) 860 + { 861 + struct decon_context *ctx = dev_get_drvdata(dev); 862 + int ret; 863 + 864 + ret = clk_prepare_enable(ctx->pclk); 865 + if (ret < 0) { 866 + DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); 867 + return ret; 868 + } 869 + 870 + ret = clk_prepare_enable(ctx->aclk); 871 + if (ret < 0) { 872 + DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); 873 + return ret; 874 + } 875 + 876 + ret = clk_prepare_enable(ctx->eclk); 877 + if (ret < 0) { 878 + DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); 879 + return ret; 880 + } 881 + 882 + ret = clk_prepare_enable(ctx->vclk); 883 + if (ret < 0) { 884 + DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); 885 + return ret; 886 + } 887 + 888 + return 0; 889 + } 890 + #endif 891 + 892 + static const struct dev_pm_ops exynos7_decon_pm_ops = { 893 + SET_RUNTIME_PM_OPS(exynos7_decon_suspend, exynos7_decon_resume, 894 + NULL) 895 + }; 896 + 811 897 struct platform_driver decon_driver = { 812 898 .probe = decon_probe, 813 899 .remove = decon_remove, 814 900 .driver = { 815 901 .name = "exynos-decon", 902 + .pm = &exynos7_decon_pm_ops, 816 903 .of_match_table = decon_driver_dt_match, 817 904 }, 818 905 };
+145 -34
drivers/gpu/drm/exynos/exynos_dp_core.c
··· 1009 1009 { 1010 1010 int ret; 1011 1011 1012 - encoder->bridge = dp->bridge; 1013 - dp->bridge->encoder = encoder; 1014 - ret = drm_bridge_attach(encoder->dev, dp->bridge); 1012 + encoder->bridge->next = dp->ptn_bridge; 1013 + dp->ptn_bridge->encoder = encoder; 1014 + ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); 1015 1015 if (ret) { 1016 1016 DRM_ERROR("Failed to attach bridge to drm\n"); 1017 1017 return ret; ··· 1020 1020 return 0; 1021 1021 } 1022 1022 1023 - static int exynos_dp_create_connector(struct drm_encoder *encoder) 1023 + static int exynos_dp_bridge_attach(struct drm_bridge *bridge) 1024 1024 { 1025 - struct exynos_dp_device *dp = encoder_to_dp(encoder); 1025 + struct exynos_dp_device *dp = bridge->driver_private; 1026 + struct drm_encoder *encoder = &dp->encoder; 1026 1027 struct drm_connector *connector = &dp->connector; 1027 1028 int ret; 1028 1029 1029 1030 /* Pre-empt DP connector creation if there's a bridge */ 1030 - if (dp->bridge) { 1031 + if (dp->ptn_bridge) { 1031 1032 ret = exynos_drm_attach_lcd_bridge(dp, encoder); 1032 1033 if (!ret) 1033 1034 return 0; ··· 1053 1052 return ret; 1054 1053 } 1055 1054 1056 - static bool exynos_dp_mode_fixup(struct drm_encoder *encoder, 1057 - const struct drm_display_mode *mode, 1058 - struct drm_display_mode *adjusted_mode) 1055 + static void exynos_dp_bridge_enable(struct drm_bridge *bridge) 1059 1056 { 1060 - return true; 1061 - } 1062 - 1063 - static void exynos_dp_mode_set(struct drm_encoder *encoder, 1064 - struct drm_display_mode *mode, 1065 - struct drm_display_mode *adjusted_mode) 1066 - { 1067 - } 1068 - 1069 - static void exynos_dp_enable(struct drm_encoder *encoder) 1070 - { 1071 - struct exynos_dp_device *dp = encoder_to_dp(encoder); 1057 + struct exynos_dp_device *dp = bridge->driver_private; 1072 1058 struct exynos_drm_crtc *crtc = dp_to_crtc(dp); 1073 1059 1074 1060 if (dp->dpms_mode == DRM_MODE_DPMS_ON) 1075 1061 return; 1062 + 1063 + pm_runtime_get_sync(dp->dev); 1076 1064 1077 1065 if (dp->panel) { 1078 1066 if (drm_panel_prepare(dp->panel)) { ··· 1073 1083 if (crtc->ops->clock_enable) 1074 1084 crtc->ops->clock_enable(dp_to_crtc(dp), true); 1075 1085 1076 - clk_prepare_enable(dp->clock); 1077 1086 phy_power_on(dp->phy); 1078 1087 exynos_dp_init_dp(dp); 1079 1088 enable_irq(dp->irq); ··· 1081 1092 dp->dpms_mode = DRM_MODE_DPMS_ON; 1082 1093 } 1083 1094 1084 - static void exynos_dp_disable(struct drm_encoder *encoder) 1095 + static void exynos_dp_bridge_disable(struct drm_bridge *bridge) 1085 1096 { 1086 - struct exynos_dp_device *dp = encoder_to_dp(encoder); 1097 + struct exynos_dp_device *dp = bridge->driver_private; 1087 1098 struct exynos_drm_crtc *crtc = dp_to_crtc(dp); 1088 1099 1089 1100 if (dp->dpms_mode != DRM_MODE_DPMS_ON) ··· 1099 1110 disable_irq(dp->irq); 1100 1111 flush_work(&dp->hotplug_work); 1101 1112 phy_power_off(dp->phy); 1102 - clk_disable_unprepare(dp->clock); 1103 1113 1104 1114 if (crtc->ops->clock_enable) 1105 1115 crtc->ops->clock_enable(dp_to_crtc(dp), false); ··· 1108 1120 DRM_ERROR("failed to turnoff the panel\n"); 1109 1121 } 1110 1122 1123 + pm_runtime_put_sync(dp->dev); 1124 + 1111 1125 dp->dpms_mode = DRM_MODE_DPMS_OFF; 1126 + } 1127 + 1128 + static void exynos_dp_bridge_nop(struct drm_bridge *bridge) 1129 + { 1130 + /* do nothing */ 1131 + } 1132 + 1133 + static const struct drm_bridge_funcs exynos_dp_bridge_funcs = { 1134 + .enable = exynos_dp_bridge_enable, 1135 + .disable = exynos_dp_bridge_disable, 1136 + .pre_enable = exynos_dp_bridge_nop, 1137 + .post_disable = exynos_dp_bridge_nop, 1138 + .attach = exynos_dp_bridge_attach, 1139 + }; 1140 + 1141 + static int exynos_dp_create_connector(struct drm_encoder *encoder) 1142 + { 1143 + struct exynos_dp_device *dp = encoder_to_dp(encoder); 1144 + struct drm_device *drm_dev = dp->drm_dev; 1145 + struct drm_bridge *bridge; 1146 + int ret; 1147 + 1148 + bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); 1149 + if (!bridge) { 1150 + DRM_ERROR("failed to allocate for drm bridge\n"); 1151 + return -ENOMEM; 1152 + } 1153 + 1154 + dp->bridge = bridge; 1155 + 1156 + encoder->bridge = bridge; 1157 + bridge->driver_private = dp; 1158 + bridge->encoder = encoder; 1159 + bridge->funcs = &exynos_dp_bridge_funcs; 1160 + 1161 + ret = drm_bridge_attach(drm_dev, bridge); 1162 + if (ret) { 1163 + DRM_ERROR("failed to attach drm bridge\n"); 1164 + return -EINVAL; 1165 + } 1166 + 1167 + return 0; 1168 + } 1169 + 1170 + static bool exynos_dp_mode_fixup(struct drm_encoder *encoder, 1171 + const struct drm_display_mode *mode, 1172 + struct drm_display_mode *adjusted_mode) 1173 + { 1174 + return true; 1175 + } 1176 + 1177 + static void exynos_dp_mode_set(struct drm_encoder *encoder, 1178 + struct drm_display_mode *mode, 1179 + struct drm_display_mode *adjusted_mode) 1180 + { 1181 + } 1182 + 1183 + static void exynos_dp_enable(struct drm_encoder *encoder) 1184 + { 1185 + } 1186 + 1187 + static void exynos_dp_disable(struct drm_encoder *encoder) 1188 + { 1112 1189 } 1113 1190 1114 1191 static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = { ··· 1291 1238 } 1292 1239 } 1293 1240 1294 - if (!dp->panel && !dp->bridge) { 1241 + if (!dp->panel && !dp->ptn_bridge) { 1295 1242 ret = exynos_dp_dt_parse_panel(dp); 1296 1243 if (ret) 1297 1244 return ret; ··· 1341 1288 } 1342 1289 1343 1290 INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); 1344 - 1345 - phy_power_on(dp->phy); 1346 - 1347 - exynos_dp_init_dp(dp); 1348 1291 1349 1292 ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 1350 1293 irq_flags, "exynos-dp", dp); ··· 1392 1343 static int exynos_dp_probe(struct platform_device *pdev) 1393 1344 { 1394 1345 struct device *dev = &pdev->dev; 1395 - struct device_node *panel_node, *bridge_node, *endpoint; 1346 + struct device_node *panel_node = NULL, *bridge_node, *endpoint = NULL; 1396 1347 struct exynos_dp_device *dp; 1348 + int ret; 1397 1349 1398 1350 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1399 1351 GFP_KERNEL); ··· 1403 1353 1404 1354 platform_set_drvdata(pdev, dp); 1405 1355 1356 + /* This is for the backward compatibility. */ 1406 1357 panel_node = of_parse_phandle(dev->of_node, "panel", 0); 1407 1358 if (panel_node) { 1408 1359 dp->panel = of_drm_find_panel(panel_node); 1409 1360 of_node_put(panel_node); 1410 1361 if (!dp->panel) 1411 1362 return -EPROBE_DEFER; 1363 + } else { 1364 + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 1365 + if (endpoint) { 1366 + panel_node = of_graph_get_remote_port_parent(endpoint); 1367 + if (panel_node) { 1368 + dp->panel = of_drm_find_panel(panel_node); 1369 + of_node_put(panel_node); 1370 + if (!dp->panel) 1371 + return -EPROBE_DEFER; 1372 + } else { 1373 + DRM_ERROR("no port node for panel device.\n"); 1374 + return -EINVAL; 1375 + } 1376 + } 1412 1377 } 1378 + 1379 + if (endpoint) 1380 + goto out; 1413 1381 1414 1382 endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 1415 1383 if (endpoint) { 1416 1384 bridge_node = of_graph_get_remote_port_parent(endpoint); 1417 1385 if (bridge_node) { 1418 - dp->bridge = of_drm_find_bridge(bridge_node); 1386 + dp->ptn_bridge = of_drm_find_bridge(bridge_node); 1419 1387 of_node_put(bridge_node); 1420 - if (!dp->bridge) 1388 + if (!dp->ptn_bridge) 1421 1389 return -EPROBE_DEFER; 1422 1390 } else 1423 1391 return -EPROBE_DEFER; 1424 1392 } 1425 1393 1426 - return component_add(&pdev->dev, &exynos_dp_ops); 1394 + out: 1395 + pm_runtime_enable(dev); 1396 + 1397 + ret = component_add(&pdev->dev, &exynos_dp_ops); 1398 + if (ret) 1399 + goto err_disable_pm_runtime; 1400 + 1401 + return ret; 1402 + 1403 + err_disable_pm_runtime: 1404 + pm_runtime_disable(dev); 1405 + 1406 + return ret; 1427 1407 } 1428 1408 1429 1409 static int exynos_dp_remove(struct platform_device *pdev) 1430 1410 { 1411 + pm_runtime_disable(&pdev->dev); 1431 1412 component_del(&pdev->dev, &exynos_dp_ops); 1432 1413 1433 1414 return 0; 1434 1415 } 1416 + 1417 + #ifdef CONFIG_PM 1418 + static int exynos_dp_suspend(struct device *dev) 1419 + { 1420 + struct exynos_dp_device *dp = dev_get_drvdata(dev); 1421 + 1422 + clk_disable_unprepare(dp->clock); 1423 + 1424 + return 0; 1425 + } 1426 + 1427 + static int exynos_dp_resume(struct device *dev) 1428 + { 1429 + struct exynos_dp_device *dp = dev_get_drvdata(dev); 1430 + int ret; 1431 + 1432 + ret = clk_prepare_enable(dp->clock); 1433 + if (ret < 0) { 1434 + DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret); 1435 + return ret; 1436 + } 1437 + 1438 + return 0; 1439 + } 1440 + #endif 1441 + 1442 + static const struct dev_pm_ops exynos_dp_pm_ops = { 1443 + SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL) 1444 + }; 1435 1445 1436 1446 static const struct of_device_id exynos_dp_match[] = { 1437 1447 { .compatible = "samsung,exynos5-dp" }, ··· 1505 1395 .driver = { 1506 1396 .name = "exynos-dp", 1507 1397 .owner = THIS_MODULE, 1398 + .pm = &exynos_dp_pm_ops, 1508 1399 .of_match_table = exynos_dp_match, 1509 1400 }, 1510 1401 };
+1
drivers/gpu/drm/exynos/exynos_dp_core.h
··· 153 153 struct drm_connector connector; 154 154 struct drm_panel *panel; 155 155 struct drm_bridge *bridge; 156 + struct drm_bridge *ptn_bridge; 156 157 struct clk *clock; 157 158 unsigned int irq; 158 159 void __iomem *reg_base;
+30 -46
drivers/gpu/drm/exynos/exynos_drm_drv.c
··· 304 304 return 0; 305 305 } 306 306 307 - #ifdef CONFIG_PM_SLEEP 308 - static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state) 309 - { 310 - struct drm_connector *connector; 311 - 312 - drm_modeset_lock_all(dev); 313 - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 314 - int old_dpms = connector->dpms; 315 - 316 - if (connector->funcs->dpms) 317 - connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); 318 - 319 - /* Set the old mode back to the connector for resume */ 320 - connector->dpms = old_dpms; 321 - } 322 - drm_modeset_unlock_all(dev); 323 - 324 - return 0; 325 - } 326 - 327 - static int exynos_drm_resume(struct drm_device *dev) 328 - { 329 - struct drm_connector *connector; 330 - 331 - drm_modeset_lock_all(dev); 332 - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 333 - if (connector->funcs->dpms) { 334 - int dpms = connector->dpms; 335 - 336 - connector->dpms = DRM_MODE_DPMS_OFF; 337 - connector->funcs->dpms(connector, dpms); 338 - } 339 - } 340 - drm_modeset_unlock_all(dev); 341 - 342 - return 0; 343 - } 344 - #endif 345 - 346 307 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) 347 308 { 348 309 struct drm_exynos_file_private *file_priv; ··· 437 476 }; 438 477 439 478 #ifdef CONFIG_PM_SLEEP 440 - static int exynos_drm_sys_suspend(struct device *dev) 479 + static int exynos_drm_suspend(struct device *dev) 441 480 { 442 481 struct drm_device *drm_dev = dev_get_drvdata(dev); 443 - pm_message_t message; 482 + struct drm_connector *connector; 444 483 445 484 if (pm_runtime_suspended(dev) || !drm_dev) 446 485 return 0; 447 486 448 - message.event = PM_EVENT_SUSPEND; 449 - return exynos_drm_suspend(drm_dev, message); 487 + drm_modeset_lock_all(drm_dev); 488 + drm_for_each_connector(connector, drm_dev) { 489 + int old_dpms = connector->dpms; 490 + 491 + if (connector->funcs->dpms) 492 + connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); 493 + 494 + /* Set the old mode back to the connector for resume */ 495 + connector->dpms = old_dpms; 496 + } 497 + drm_modeset_unlock_all(drm_dev); 498 + 499 + return 0; 450 500 } 451 501 452 - static int exynos_drm_sys_resume(struct device *dev) 502 + static int exynos_drm_resume(struct device *dev) 453 503 { 454 504 struct drm_device *drm_dev = dev_get_drvdata(dev); 505 + struct drm_connector *connector; 455 506 456 507 if (pm_runtime_suspended(dev) || !drm_dev) 457 508 return 0; 458 509 459 - return exynos_drm_resume(drm_dev); 510 + drm_modeset_lock_all(drm_dev); 511 + drm_for_each_connector(connector, drm_dev) { 512 + if (connector->funcs->dpms) { 513 + int dpms = connector->dpms; 514 + 515 + connector->dpms = DRM_MODE_DPMS_OFF; 516 + connector->funcs->dpms(connector, dpms); 517 + } 518 + } 519 + drm_modeset_unlock_all(drm_dev); 520 + 521 + return 0; 460 522 } 461 523 #endif 462 524 463 525 static const struct dev_pm_ops exynos_drm_pm_ops = { 464 - SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume) 526 + SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_suspend, exynos_drm_resume) 465 527 }; 466 528 467 529 /* forward declaration */
+56 -25
drivers/gpu/drm/exynos/exynos_drm_drv.h
··· 38 38 EXYNOS_DISPLAY_TYPE_VIDI, 39 39 }; 40 40 41 + struct exynos_drm_rect { 42 + unsigned int x, y; 43 + unsigned int w, h; 44 + }; 45 + 46 + /* 47 + * Exynos drm plane state structure. 48 + * 49 + * @base: plane_state object (contains drm_framebuffer pointer) 50 + * @src: rectangle of the source image data to be displayed (clipped to 51 + * visible part). 52 + * @crtc: rectangle of the target image position on hardware screen 53 + * (clipped to visible part). 54 + * @h_ratio: horizontal scaling ratio, 16.16 fixed point 55 + * @v_ratio: vertical scaling ratio, 16.16 fixed point 56 + * 57 + * this structure consists plane state data that will be applied to hardware 58 + * specific overlay info. 59 + */ 60 + 61 + struct exynos_drm_plane_state { 62 + struct drm_plane_state base; 63 + struct exynos_drm_rect crtc; 64 + struct exynos_drm_rect src; 65 + unsigned int h_ratio; 66 + unsigned int v_ratio; 67 + }; 68 + 69 + static inline struct exynos_drm_plane_state * 70 + to_exynos_plane_state(struct drm_plane_state *state) 71 + { 72 + return container_of(state, struct exynos_drm_plane_state, base); 73 + } 74 + 41 75 /* 42 76 * Exynos drm common overlay structure. 43 77 * 44 78 * @base: plane object 45 - * @src_x: offset x on a framebuffer to be displayed. 46 - * - the unit is screen coordinates. 47 - * @src_y: offset y on a framebuffer to be displayed. 48 - * - the unit is screen coordinates. 49 - * @src_w: width of a partial image to be displayed from framebuffer. 50 - * @src_h: height of a partial image to be displayed from framebuffer. 51 - * @crtc_x: offset x on hardware screen. 52 - * @crtc_y: offset y on hardware screen. 53 - * @crtc_w: window width to be displayed (hardware screen). 54 - * @crtc_h: window height to be displayed (hardware screen). 55 - * @h_ratio: horizontal scaling ratio, 16.16 fixed point 56 - * @v_ratio: vertical scaling ratio, 16.16 fixed point 57 - * @dma_addr: array of bus(accessed by dma) address to the memory region 58 - * allocated for a overlay. 59 79 * @zpos: order of overlay layer(z position). 60 80 * 61 81 * this structure is common to exynos SoC and its contents would be copied ··· 84 64 85 65 struct exynos_drm_plane { 86 66 struct drm_plane base; 87 - unsigned int src_x; 88 - unsigned int src_y; 89 - unsigned int src_w; 90 - unsigned int src_h; 91 - unsigned int crtc_x; 92 - unsigned int crtc_y; 93 - unsigned int crtc_w; 94 - unsigned int crtc_h; 95 - unsigned int h_ratio; 96 - unsigned int v_ratio; 97 - dma_addr_t dma_addr[MAX_FB_BUFFER]; 67 + const struct exynos_drm_plane_config *config; 98 68 unsigned int zpos; 99 69 struct drm_framebuffer *pending_fb; 70 + }; 71 + 72 + #define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0) 73 + #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) 74 + 75 + /* 76 + * Exynos DRM plane configuration structure. 77 + * 78 + * @zpos: z-position of the plane. 79 + * @type: type of the plane (primary, cursor or overlay). 80 + * @pixel_formats: supported pixel formats. 81 + * @num_pixel_formats: number of elements in 'pixel_formats'. 82 + * @capabilities: supported features (see EXYNOS_DRM_PLANE_CAP_*) 83 + */ 84 + 85 + struct exynos_drm_plane_config { 86 + unsigned int zpos; 87 + enum drm_plane_type type; 88 + const uint32_t *pixel_formats; 89 + unsigned int num_pixel_formats; 90 + unsigned int capabilities; 100 91 }; 101 92 102 93 /*
+83 -68
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 1458 1458 .transfer = exynos_dsi_host_transfer, 1459 1459 }; 1460 1460 1461 - static int exynos_dsi_poweron(struct exynos_dsi *dsi) 1462 - { 1463 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1464 - int ret, i; 1465 - 1466 - ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1467 - if (ret < 0) { 1468 - dev_err(dsi->dev, "cannot enable regulators %d\n", ret); 1469 - return ret; 1470 - } 1471 - 1472 - for (i = 0; i < driver_data->num_clks; i++) { 1473 - ret = clk_prepare_enable(dsi->clks[i]); 1474 - if (ret < 0) 1475 - goto err_clk; 1476 - } 1477 - 1478 - ret = phy_power_on(dsi->phy); 1479 - if (ret < 0) { 1480 - dev_err(dsi->dev, "cannot enable phy %d\n", ret); 1481 - goto err_clk; 1482 - } 1483 - 1484 - return 0; 1485 - 1486 - err_clk: 1487 - while (--i > -1) 1488 - clk_disable_unprepare(dsi->clks[i]); 1489 - regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1490 - 1491 - return ret; 1492 - } 1493 - 1494 - static void exynos_dsi_poweroff(struct exynos_dsi *dsi) 1495 - { 1496 - struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1497 - int ret, i; 1498 - 1499 - usleep_range(10000, 20000); 1500 - 1501 - if (dsi->state & DSIM_STATE_INITIALIZED) { 1502 - dsi->state &= ~DSIM_STATE_INITIALIZED; 1503 - 1504 - exynos_dsi_disable_clock(dsi); 1505 - 1506 - exynos_dsi_disable_irq(dsi); 1507 - } 1508 - 1509 - dsi->state &= ~DSIM_STATE_CMD_LPM; 1510 - 1511 - phy_power_off(dsi->phy); 1512 - 1513 - for (i = driver_data->num_clks - 1; i > -1; i--) 1514 - clk_disable_unprepare(dsi->clks[i]); 1515 - 1516 - ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1517 - if (ret < 0) 1518 - dev_err(dsi->dev, "cannot disable regulators %d\n", ret); 1519 - } 1520 - 1521 1461 static void exynos_dsi_enable(struct drm_encoder *encoder) 1522 1462 { 1523 1463 struct exynos_dsi *dsi = encoder_to_dsi(encoder); ··· 1466 1526 if (dsi->state & DSIM_STATE_ENABLED) 1467 1527 return; 1468 1528 1469 - ret = exynos_dsi_poweron(dsi); 1470 - if (ret < 0) 1471 - return; 1529 + pm_runtime_get_sync(dsi->dev); 1472 1530 1473 1531 dsi->state |= DSIM_STATE_ENABLED; 1474 1532 1475 1533 ret = drm_panel_prepare(dsi->panel); 1476 1534 if (ret < 0) { 1477 1535 dsi->state &= ~DSIM_STATE_ENABLED; 1478 - exynos_dsi_poweroff(dsi); 1536 + pm_runtime_put_sync(dsi->dev); 1479 1537 return; 1480 1538 } 1481 1539 ··· 1485 1547 dsi->state &= ~DSIM_STATE_ENABLED; 1486 1548 exynos_dsi_set_display_enable(dsi, false); 1487 1549 drm_panel_unprepare(dsi->panel); 1488 - exynos_dsi_poweroff(dsi); 1550 + pm_runtime_put_sync(dsi->dev); 1489 1551 return; 1490 1552 } 1491 1553 ··· 1507 1569 1508 1570 dsi->state &= ~DSIM_STATE_ENABLED; 1509 1571 1510 - exynos_dsi_poweroff(dsi); 1572 + pm_runtime_put_sync(dsi->dev); 1511 1573 } 1512 1574 1513 1575 static enum drm_connector_status ··· 1735 1797 1736 1798 ep = of_graph_get_next_endpoint(node, NULL); 1737 1799 if (!ep) { 1738 - ret = -ENXIO; 1800 + ret = -EINVAL; 1739 1801 goto end; 1740 1802 } 1741 1803 1742 1804 dsi->bridge_node = of_graph_get_remote_port_parent(ep); 1743 1805 if (!dsi->bridge_node) { 1744 - ret = -ENXIO; 1806 + ret = -EINVAL; 1745 1807 goto end; 1746 1808 } 1747 1809 end: ··· 1892 1954 1893 1955 platform_set_drvdata(pdev, &dsi->encoder); 1894 1956 1957 + pm_runtime_enable(dev); 1958 + 1895 1959 return component_add(dev, &exynos_dsi_component_ops); 1896 1960 } 1897 1961 1898 1962 static int exynos_dsi_remove(struct platform_device *pdev) 1899 1963 { 1964 + pm_runtime_disable(&pdev->dev); 1965 + 1900 1966 component_del(&pdev->dev, &exynos_dsi_component_ops); 1901 1967 1902 1968 return 0; 1903 1969 } 1970 + 1971 + #ifdef CONFIG_PM 1972 + static int exynos_dsi_suspend(struct device *dev) 1973 + { 1974 + struct drm_encoder *encoder = dev_get_drvdata(dev); 1975 + struct exynos_dsi *dsi = encoder_to_dsi(encoder); 1976 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 1977 + int ret, i; 1978 + 1979 + usleep_range(10000, 20000); 1980 + 1981 + if (dsi->state & DSIM_STATE_INITIALIZED) { 1982 + dsi->state &= ~DSIM_STATE_INITIALIZED; 1983 + 1984 + exynos_dsi_disable_clock(dsi); 1985 + 1986 + exynos_dsi_disable_irq(dsi); 1987 + } 1988 + 1989 + dsi->state &= ~DSIM_STATE_CMD_LPM; 1990 + 1991 + phy_power_off(dsi->phy); 1992 + 1993 + for (i = driver_data->num_clks - 1; i > -1; i--) 1994 + clk_disable_unprepare(dsi->clks[i]); 1995 + 1996 + ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 1997 + if (ret < 0) 1998 + dev_err(dsi->dev, "cannot disable regulators %d\n", ret); 1999 + 2000 + return 0; 2001 + } 2002 + 2003 + static int exynos_dsi_resume(struct device *dev) 2004 + { 2005 + struct drm_encoder *encoder = dev_get_drvdata(dev); 2006 + struct exynos_dsi *dsi = encoder_to_dsi(encoder); 2007 + struct exynos_dsi_driver_data *driver_data = dsi->driver_data; 2008 + int ret, i; 2009 + 2010 + ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 2011 + if (ret < 0) { 2012 + dev_err(dsi->dev, "cannot enable regulators %d\n", ret); 2013 + return ret; 2014 + } 2015 + 2016 + for (i = 0; i < driver_data->num_clks; i++) { 2017 + ret = clk_prepare_enable(dsi->clks[i]); 2018 + if (ret < 0) 2019 + goto err_clk; 2020 + } 2021 + 2022 + ret = phy_power_on(dsi->phy); 2023 + if (ret < 0) { 2024 + dev_err(dsi->dev, "cannot enable phy %d\n", ret); 2025 + goto err_clk; 2026 + } 2027 + 2028 + return 0; 2029 + 2030 + err_clk: 2031 + while (--i > -1) 2032 + clk_disable_unprepare(dsi->clks[i]); 2033 + regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies); 2034 + 2035 + return ret; 2036 + } 2037 + #endif 2038 + 2039 + static const struct dev_pm_ops exynos_dsi_pm_ops = { 2040 + SET_RUNTIME_PM_OPS(exynos_dsi_suspend, exynos_dsi_resume, NULL) 2041 + }; 1904 2042 1905 2043 struct platform_driver dsi_driver = { 1906 2044 .probe = exynos_dsi_probe, ··· 1984 1970 .driver = { 1985 1971 .name = "exynos-dsi", 1986 1972 .owner = THIS_MODULE, 1973 + .pm = &exynos_dsi_pm_ops, 1987 1974 .of_match_table = exynos_dsi_of_match, 1988 1975 }, 1989 1976 };
+6 -10
drivers/gpu/drm/exynos/exynos_drm_fb.c
··· 37 37 struct exynos_drm_fb { 38 38 struct drm_framebuffer fb; 39 39 struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; 40 + dma_addr_t dma_addr[MAX_FB_BUFFER]; 40 41 }; 41 42 42 43 static int check_fb_gem_memory_type(struct drm_device *drm_dev, ··· 136 135 goto err; 137 136 138 137 exynos_fb->exynos_gem[i] = exynos_gem[i]; 138 + exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr 139 + + mode_cmd->offsets[i]; 139 140 } 140 141 141 142 drm_helper_mode_fill_fb_struct(&exynos_fb->fb, mode_cmd); ··· 192 189 return ERR_PTR(ret); 193 190 } 194 191 195 - struct exynos_drm_gem *exynos_drm_fb_gem(struct drm_framebuffer *fb, int index) 192 + dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index) 196 193 { 197 194 struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); 198 - struct exynos_drm_gem *exynos_gem; 199 195 200 196 if (index >= MAX_FB_BUFFER) 201 - return NULL; 197 + return DMA_ERROR_CODE; 202 198 203 - exynos_gem = exynos_fb->exynos_gem[index]; 204 - if (!exynos_gem) 205 - return NULL; 206 - 207 - DRM_DEBUG_KMS("dma_addr: 0x%lx\n", (unsigned long)exynos_gem->dma_addr); 208 - 209 - return exynos_gem; 199 + return exynos_fb->dma_addr[index]; 210 200 } 211 201 212 202 static void exynos_drm_output_poll_changed(struct drm_device *dev)
+1 -2
drivers/gpu/drm/exynos/exynos_drm_fb.h
··· 22 22 struct exynos_drm_gem **exynos_gem, 23 23 int count); 24 24 25 - /* get gem object of a drm framebuffer */ 26 - struct exynos_drm_gem *exynos_drm_fb_gem(struct drm_framebuffer *fb, int index); 25 + dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index); 27 26 28 27 void exynos_drm_mode_config_init(struct drm_device *dev); 29 28
+86 -56
drivers/gpu/drm/exynos/exynos_drm_fimd.c
··· 29 29 #include <drm/exynos_drm.h> 30 30 31 31 #include "exynos_drm_drv.h" 32 + #include "exynos_drm_fb.h" 32 33 #include "exynos_drm_fbdev.h" 33 34 #include "exynos_drm_crtc.h" 34 35 #include "exynos_drm_plane.h" ··· 88 87 89 88 /* FIMD has totally five hardware windows. */ 90 89 #define WINDOWS_NR 5 91 - #define CURSOR_WIN 4 92 90 93 91 struct fimd_driver_data { 94 92 unsigned int timing_base; ··· 150 150 struct drm_device *drm_dev; 151 151 struct exynos_drm_crtc *crtc; 152 152 struct exynos_drm_plane planes[WINDOWS_NR]; 153 + struct exynos_drm_plane_config configs[WINDOWS_NR]; 153 154 struct clk *bus_clk; 154 155 struct clk *lcd_clk; 155 156 void __iomem *regs; ··· 187 186 {}, 188 187 }; 189 188 MODULE_DEVICE_TABLE(of, fimd_driver_dt_match); 189 + 190 + static const enum drm_plane_type fimd_win_types[WINDOWS_NR] = { 191 + DRM_PLANE_TYPE_PRIMARY, 192 + DRM_PLANE_TYPE_OVERLAY, 193 + DRM_PLANE_TYPE_OVERLAY, 194 + DRM_PLANE_TYPE_OVERLAY, 195 + DRM_PLANE_TYPE_CURSOR, 196 + }; 190 197 191 198 static const uint32_t fimd_formats[] = { 192 199 DRM_FORMAT_C8, ··· 487 478 488 479 489 480 static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, 490 - struct drm_framebuffer *fb) 481 + uint32_t pixel_format, int width) 491 482 { 492 483 unsigned long val; 493 484 ··· 498 489 * So the request format is ARGB8888 then change it to XRGB8888. 499 490 */ 500 491 if (ctx->driver_data->has_limited_fmt && !win) { 501 - if (fb->pixel_format == DRM_FORMAT_ARGB8888) 502 - fb->pixel_format = DRM_FORMAT_XRGB8888; 492 + if (pixel_format == DRM_FORMAT_ARGB8888) 493 + pixel_format = DRM_FORMAT_XRGB8888; 503 494 } 504 495 505 - switch (fb->pixel_format) { 496 + switch (pixel_format) { 506 497 case DRM_FORMAT_C8: 507 498 val |= WINCON0_BPPMODE_8BPP_PALETTE; 508 499 val |= WINCONx_BURSTLEN_8WORD; ··· 538 529 break; 539 530 } 540 531 541 - DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel); 542 - 543 532 /* 544 - * In case of exynos, setting dma-burst to 16Word causes permanent 545 - * tearing for very small buffers, e.g. cursor buffer. Burst Mode 546 - * switching which is based on plane size is not recommended as 547 - * plane size varies alot towards the end of the screen and rapid 548 - * movement causes unstable DMA which results into iommu crash/tear. 533 + * Setting dma-burst to 16Word causes permanent tearing for very small 534 + * buffers, e.g. cursor buffer. Burst Mode switching which based on 535 + * plane size is not recommended as plane size varies alot towards the 536 + * end of the screen and rapid movement causes unstable DMA, but it is 537 + * still better to change dma-burst than displaying garbage. 549 538 */ 550 539 551 - if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) { 540 + if (width < MIN_FB_WIDTH_FOR_16WORD_BURST) { 552 541 val &= ~WINCONx_BURSTLEN_MASK; 553 542 val |= WINCONx_BURSTLEN_4WORD; 554 543 } ··· 647 640 static void fimd_update_plane(struct exynos_drm_crtc *crtc, 648 641 struct exynos_drm_plane *plane) 649 642 { 643 + struct exynos_drm_plane_state *state = 644 + to_exynos_plane_state(plane->base.state); 650 645 struct fimd_context *ctx = crtc->ctx; 651 - struct drm_plane_state *state = plane->base.state; 646 + struct drm_framebuffer *fb = state->base.fb; 652 647 dma_addr_t dma_addr; 653 648 unsigned long val, size, offset; 654 649 unsigned int last_x, last_y, buf_offsize, line_size; 655 650 unsigned int win = plane->zpos; 656 - unsigned int bpp = state->fb->bits_per_pixel >> 3; 657 - unsigned int pitch = state->fb->pitches[0]; 651 + unsigned int bpp = fb->bits_per_pixel >> 3; 652 + unsigned int pitch = fb->pitches[0]; 658 653 659 654 if (ctx->suspended) 660 655 return; 661 656 662 - offset = plane->src_x * bpp; 663 - offset += plane->src_y * pitch; 657 + offset = state->src.x * bpp; 658 + offset += state->src.y * pitch; 664 659 665 660 /* buffer start address */ 666 - dma_addr = plane->dma_addr[0] + offset; 661 + dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset; 667 662 val = (unsigned long)dma_addr; 668 663 writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); 669 664 670 665 /* buffer end address */ 671 - size = pitch * plane->crtc_h; 666 + size = pitch * state->crtc.h; 672 667 val = (unsigned long)(dma_addr + size); 673 668 writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); 674 669 675 670 DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", 676 671 (unsigned long)dma_addr, val, size); 677 672 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", 678 - plane->crtc_w, plane->crtc_h); 673 + state->crtc.w, state->crtc.h); 679 674 680 675 /* buffer size */ 681 - buf_offsize = pitch - (plane->crtc_w * bpp); 682 - line_size = plane->crtc_w * bpp; 676 + buf_offsize = pitch - (state->crtc.w * bpp); 677 + line_size = state->crtc.w * bpp; 683 678 val = VIDW_BUF_SIZE_OFFSET(buf_offsize) | 684 679 VIDW_BUF_SIZE_PAGEWIDTH(line_size) | 685 680 VIDW_BUF_SIZE_OFFSET_E(buf_offsize) | ··· 689 680 writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); 690 681 691 682 /* OSD position */ 692 - val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | 693 - VIDOSDxA_TOPLEFT_Y(plane->crtc_y) | 694 - VIDOSDxA_TOPLEFT_X_E(plane->crtc_x) | 695 - VIDOSDxA_TOPLEFT_Y_E(plane->crtc_y); 683 + val = VIDOSDxA_TOPLEFT_X(state->crtc.x) | 684 + VIDOSDxA_TOPLEFT_Y(state->crtc.y) | 685 + VIDOSDxA_TOPLEFT_X_E(state->crtc.x) | 686 + VIDOSDxA_TOPLEFT_Y_E(state->crtc.y); 696 687 writel(val, ctx->regs + VIDOSD_A(win)); 697 688 698 - last_x = plane->crtc_x + plane->crtc_w; 689 + last_x = state->crtc.x + state->crtc.w; 699 690 if (last_x) 700 691 last_x--; 701 - last_y = plane->crtc_y + plane->crtc_h; 692 + last_y = state->crtc.y + state->crtc.h; 702 693 if (last_y) 703 694 last_y--; 704 695 ··· 708 699 writel(val, ctx->regs + VIDOSD_B(win)); 709 700 710 701 DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", 711 - plane->crtc_x, plane->crtc_y, last_x, last_y); 702 + state->crtc.x, state->crtc.y, last_x, last_y); 712 703 713 704 /* OSD size */ 714 705 if (win != 3 && win != 4) { 715 706 u32 offset = VIDOSD_D(win); 716 707 if (win == 0) 717 708 offset = VIDOSD_C(win); 718 - val = plane->crtc_w * plane->crtc_h; 709 + val = state->crtc.w * state->crtc.h; 719 710 writel(val, ctx->regs + offset); 720 711 721 712 DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); 722 713 } 723 714 724 - fimd_win_set_pixfmt(ctx, win, state->fb); 715 + fimd_win_set_pixfmt(ctx, win, fb->pixel_format, state->src.w); 725 716 726 717 /* hardware window 0 doesn't support color key. */ 727 718 if (win != 0) ··· 754 745 static void fimd_enable(struct exynos_drm_crtc *crtc) 755 746 { 756 747 struct fimd_context *ctx = crtc->ctx; 757 - int ret; 758 748 759 749 if (!ctx->suspended) 760 750 return; ··· 761 753 ctx->suspended = false; 762 754 763 755 pm_runtime_get_sync(ctx->dev); 764 - 765 - ret = clk_prepare_enable(ctx->bus_clk); 766 - if (ret < 0) { 767 - DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); 768 - return; 769 - } 770 - 771 - ret = clk_prepare_enable(ctx->lcd_clk); 772 - if (ret < 0) { 773 - DRM_ERROR("Failed to prepare_enable the lcd clk [%d]\n", ret); 774 - return; 775 - } 776 756 777 757 /* if vblank was enabled status, enable it again. */ 778 758 if (test_and_clear_bit(0, &ctx->irq_flags)) ··· 791 795 792 796 writel(0, ctx->regs + VIDCON0); 793 797 794 - clk_disable_unprepare(ctx->lcd_clk); 795 - clk_disable_unprepare(ctx->bus_clk); 796 - 797 798 pm_runtime_put_sync(ctx->dev); 798 - 799 799 ctx->suspended = true; 800 800 } 801 801 ··· 933 941 struct drm_device *drm_dev = data; 934 942 struct exynos_drm_private *priv = drm_dev->dev_private; 935 943 struct exynos_drm_plane *exynos_plane; 936 - enum drm_plane_type type; 937 - unsigned int zpos; 944 + unsigned int i; 938 945 int ret; 939 946 940 947 ctx->drm_dev = drm_dev; 941 948 ctx->pipe = priv->pipe++; 942 949 943 - for (zpos = 0; zpos < WINDOWS_NR; zpos++) { 944 - type = exynos_plane_get_type(zpos, CURSOR_WIN); 945 - ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], 946 - 1 << ctx->pipe, type, fimd_formats, 947 - ARRAY_SIZE(fimd_formats), zpos); 950 + for (i = 0; i < WINDOWS_NR; i++) { 951 + ctx->configs[i].pixel_formats = fimd_formats; 952 + ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); 953 + ctx->configs[i].zpos = i; 954 + ctx->configs[i].type = fimd_win_types[i]; 955 + ret = exynos_plane_init(drm_dev, &ctx->planes[i], 956 + 1 << ctx->pipe, &ctx->configs[i]); 948 957 if (ret) 949 958 return ret; 950 959 } ··· 1114 1121 return 0; 1115 1122 } 1116 1123 1124 + #ifdef CONFIG_PM 1125 + static int exynos_fimd_suspend(struct device *dev) 1126 + { 1127 + struct fimd_context *ctx = dev_get_drvdata(dev); 1128 + 1129 + clk_disable_unprepare(ctx->lcd_clk); 1130 + clk_disable_unprepare(ctx->bus_clk); 1131 + 1132 + return 0; 1133 + } 1134 + 1135 + static int exynos_fimd_resume(struct device *dev) 1136 + { 1137 + struct fimd_context *ctx = dev_get_drvdata(dev); 1138 + int ret; 1139 + 1140 + ret = clk_prepare_enable(ctx->bus_clk); 1141 + if (ret < 0) { 1142 + DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); 1143 + return ret; 1144 + } 1145 + 1146 + ret = clk_prepare_enable(ctx->lcd_clk); 1147 + if (ret < 0) { 1148 + DRM_ERROR("Failed to prepare_enable the lcd clk [%d]\n", ret); 1149 + return ret; 1150 + } 1151 + 1152 + return 0; 1153 + } 1154 + #endif 1155 + 1156 + static const struct dev_pm_ops exynos_fimd_pm_ops = { 1157 + SET_RUNTIME_PM_OPS(exynos_fimd_suspend, exynos_fimd_resume, NULL) 1158 + }; 1159 + 1117 1160 struct platform_driver fimd_driver = { 1118 1161 .probe = fimd_probe, 1119 1162 .remove = fimd_remove, 1120 1163 .driver = { 1121 1164 .name = "exynos4-fb", 1122 1165 .owner = THIS_MODULE, 1166 + .pm = &exynos_fimd_pm_ops, 1123 1167 .of_match_table = fimd_driver_dt_match, 1124 1168 }, 1125 1169 };
-28
drivers/gpu/drm/exynos/exynos_drm_gem.h
··· 55 55 struct sg_table *sgt; 56 56 }; 57 57 58 - struct page **exynos_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); 59 - 60 58 /* destroy a buffer with gem object */ 61 59 void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem); 62 60 ··· 89 91 unsigned int gem_handle, 90 92 struct drm_file *filp); 91 93 92 - /* map user space allocated by malloc to pages. */ 93 - int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, 94 - struct drm_file *file_priv); 95 - 96 94 /* get buffer information to memory region allocated by gem. */ 97 95 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, 98 96 struct drm_file *file_priv); ··· 116 122 117 123 /* set vm_flags and we can change the vm attribute to other one at here. */ 118 124 int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 119 - 120 - static inline int vma_is_io(struct vm_area_struct *vma) 121 - { 122 - return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); 123 - } 124 - 125 - /* get a copy of a virtual memory region. */ 126 - struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma); 127 - 128 - /* release a userspace virtual memory area. */ 129 - void exynos_gem_put_vma(struct vm_area_struct *vma); 130 - 131 - /* get pages from user space. */ 132 - int exynos_gem_get_pages_from_userptr(unsigned long start, 133 - unsigned int npages, 134 - struct page **pages, 135 - struct vm_area_struct *vma); 136 - 137 - /* drop the reference to pages. */ 138 - void exynos_gem_put_pages_to_userptr(struct page **pages, 139 - unsigned int npages, 140 - struct vm_area_struct *vma); 141 125 142 126 /* map sgt with dma region. */ 143 127 int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
+28 -7
drivers/gpu/drm/exynos/exynos_drm_gsc.c
··· 15 15 #include <linux/platform_device.h> 16 16 #include <linux/clk.h> 17 17 #include <linux/pm_runtime.h> 18 - #include <plat/map-base.h> 18 + #include <linux/mfd/syscon.h> 19 + #include <linux/regmap.h> 19 20 20 21 #include <drm/drmP.h> 21 22 #include <drm/exynos_drm.h> ··· 127 126 * @ippdrv: prepare initialization using ippdrv. 128 127 * @regs_res: register resources. 129 128 * @regs: memory mapped io registers. 129 + * @sysreg: handle to SYSREG block regmap. 130 130 * @lock: locking of operations. 131 131 * @gsc_clk: gsc gate clock. 132 132 * @sc: scaler infomations. ··· 140 138 struct exynos_drm_ippdrv ippdrv; 141 139 struct resource *regs_res; 142 140 void __iomem *regs; 141 + struct regmap *sysreg; 143 142 struct mutex lock; 144 143 struct clk *gsc_clk; 145 144 struct gsc_scaler sc; ··· 440 437 441 438 static void gsc_set_gscblk_fimd_wb(struct gsc_context *ctx, bool enable) 442 439 { 443 - u32 gscblk_cfg; 440 + unsigned int gscblk_cfg; 444 441 445 - gscblk_cfg = readl(SYSREG_GSCBLK_CFG1); 442 + if (!ctx->sysreg) 443 + return; 444 + 445 + regmap_read(ctx->sysreg, SYSREG_GSCBLK_CFG1, &gscblk_cfg); 446 446 447 447 if (enable) 448 448 gscblk_cfg |= GSC_BLK_DISP1WB_DEST(ctx->id) | ··· 454 448 else 455 449 gscblk_cfg |= GSC_BLK_PXLASYNC_LO_MASK_WB(ctx->id); 456 450 457 - writel(gscblk_cfg, SYSREG_GSCBLK_CFG1); 451 + regmap_write(ctx->sysreg, SYSREG_GSCBLK_CFG1, gscblk_cfg); 458 452 } 459 453 460 454 static void gsc_handle_irq(struct gsc_context *ctx, bool enable, ··· 1221 1215 DRM_DEBUG_KMS("enable[%d]\n", enable); 1222 1216 1223 1217 if (enable) { 1224 - clk_enable(ctx->gsc_clk); 1218 + clk_prepare_enable(ctx->gsc_clk); 1225 1219 ctx->suspended = false; 1226 1220 } else { 1227 - clk_disable(ctx->gsc_clk); 1221 + clk_disable_unprepare(ctx->gsc_clk); 1228 1222 ctx->suspended = true; 1229 1223 } 1230 1224 ··· 1669 1663 if (!ctx) 1670 1664 return -ENOMEM; 1671 1665 1666 + if (dev->of_node) { 1667 + ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node, 1668 + "samsung,sysreg"); 1669 + if (IS_ERR(ctx->sysreg)) { 1670 + dev_warn(dev, "failed to get system register.\n"); 1671 + ctx->sysreg = NULL; 1672 + } 1673 + } 1674 + 1672 1675 /* clock control */ 1673 1676 ctx->gsc_clk = devm_clk_get(dev, "gscl"); 1674 1677 if (IS_ERR(ctx->gsc_clk)) { ··· 1728 1713 mutex_init(&ctx->lock); 1729 1714 platform_set_drvdata(pdev, ctx); 1730 1715 1731 - pm_runtime_set_active(dev); 1732 1716 pm_runtime_enable(dev); 1733 1717 1734 1718 ret = exynos_drm_ippdrv_register(ippdrv); ··· 1811 1797 SET_RUNTIME_PM_OPS(gsc_runtime_suspend, gsc_runtime_resume, NULL) 1812 1798 }; 1813 1799 1800 + static const struct of_device_id exynos_drm_gsc_of_match[] = { 1801 + { .compatible = "samsung,exynos5-gsc" }, 1802 + { }, 1803 + }; 1804 + MODULE_DEVICE_TABLE(of, exynos_drm_gsc_of_match); 1805 + 1814 1806 struct platform_driver gsc_driver = { 1815 1807 .probe = gsc_probe, 1816 1808 .remove = gsc_remove, ··· 1824 1804 .name = "exynos-drm-gsc", 1825 1805 .owner = THIS_MODULE, 1826 1806 .pm = &gsc_pm_ops, 1807 + .of_match_table = of_match_ptr(exynos_drm_gsc_of_match), 1827 1808 }, 1828 1809 }; 1829 1810
+139 -75
drivers/gpu/drm/exynos/exynos_drm_plane.c
··· 56 56 return size; 57 57 } 58 58 59 - static void exynos_plane_mode_set(struct drm_plane *plane, 60 - struct drm_crtc *crtc, 61 - struct drm_framebuffer *fb, 62 - int crtc_x, int crtc_y, 63 - unsigned int crtc_w, unsigned int crtc_h, 64 - uint32_t src_x, uint32_t src_y, 65 - uint32_t src_w, uint32_t src_h) 59 + static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) 60 + 66 61 { 67 - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 62 + struct drm_plane_state *state = &exynos_state->base; 63 + struct drm_crtc *crtc = exynos_state->base.crtc; 68 64 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 65 + int crtc_x, crtc_y; 66 + unsigned int crtc_w, crtc_h; 67 + unsigned int src_x, src_y; 68 + unsigned int src_w, src_h; 69 69 unsigned int actual_w; 70 70 unsigned int actual_h; 71 71 72 + /* 73 + * The original src/dest coordinates are stored in exynos_state->base, 74 + * but we want to keep another copy internal to our driver that we can 75 + * clip/modify ourselves. 76 + */ 77 + 78 + crtc_x = state->crtc_x; 79 + crtc_y = state->crtc_y; 80 + crtc_w = state->crtc_w; 81 + crtc_h = state->crtc_h; 82 + 83 + src_x = state->src_x >> 16; 84 + src_y = state->src_y >> 16; 85 + src_w = state->src_w >> 16; 86 + src_h = state->src_h >> 16; 87 + 88 + /* set ratio */ 89 + exynos_state->h_ratio = (src_w << 16) / crtc_w; 90 + exynos_state->v_ratio = (src_h << 16) / crtc_h; 91 + 92 + /* clip to visible area */ 72 93 actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay); 73 94 actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay); 74 95 75 96 if (crtc_x < 0) { 76 97 if (actual_w) 77 - src_x -= crtc_x; 98 + src_x += ((-crtc_x) * exynos_state->h_ratio) >> 16; 78 99 crtc_x = 0; 79 100 } 80 101 81 102 if (crtc_y < 0) { 82 103 if (actual_h) 83 - src_y -= crtc_y; 104 + src_y += ((-crtc_y) * exynos_state->v_ratio) >> 16; 84 105 crtc_y = 0; 85 106 } 86 107 87 - /* set ratio */ 88 - exynos_plane->h_ratio = (src_w << 16) / crtc_w; 89 - exynos_plane->v_ratio = (src_h << 16) / crtc_h; 90 - 91 108 /* set drm framebuffer data. */ 92 - exynos_plane->src_x = src_x; 93 - exynos_plane->src_y = src_y; 94 - exynos_plane->src_w = (actual_w * exynos_plane->h_ratio) >> 16; 95 - exynos_plane->src_h = (actual_h * exynos_plane->v_ratio) >> 16; 109 + exynos_state->src.x = src_x; 110 + exynos_state->src.y = src_y; 111 + exynos_state->src.w = (actual_w * exynos_state->h_ratio) >> 16; 112 + exynos_state->src.h = (actual_h * exynos_state->v_ratio) >> 16; 96 113 97 114 /* set plane range to be displayed. */ 98 - exynos_plane->crtc_x = crtc_x; 99 - exynos_plane->crtc_y = crtc_y; 100 - exynos_plane->crtc_w = actual_w; 101 - exynos_plane->crtc_h = actual_h; 115 + exynos_state->crtc.x = crtc_x; 116 + exynos_state->crtc.y = crtc_y; 117 + exynos_state->crtc.w = actual_w; 118 + exynos_state->crtc.h = actual_h; 102 119 103 120 DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)", 104 - exynos_plane->crtc_x, exynos_plane->crtc_y, 105 - exynos_plane->crtc_w, exynos_plane->crtc_h); 121 + exynos_state->crtc.x, exynos_state->crtc.y, 122 + exynos_state->crtc.w, exynos_state->crtc.h); 123 + } 106 124 107 - plane->crtc = crtc; 125 + static void exynos_drm_plane_reset(struct drm_plane *plane) 126 + { 127 + struct exynos_drm_plane_state *exynos_state; 128 + 129 + if (plane->state) { 130 + exynos_state = to_exynos_plane_state(plane->state); 131 + if (exynos_state->base.fb) 132 + drm_framebuffer_unreference(exynos_state->base.fb); 133 + kfree(exynos_state); 134 + plane->state = NULL; 135 + } 136 + 137 + exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL); 138 + if (exynos_state) { 139 + plane->state = &exynos_state->base; 140 + plane->state->plane = plane; 141 + } 142 + } 143 + 144 + static struct drm_plane_state * 145 + exynos_drm_plane_duplicate_state(struct drm_plane *plane) 146 + { 147 + struct exynos_drm_plane_state *exynos_state; 148 + struct exynos_drm_plane_state *copy; 149 + 150 + exynos_state = to_exynos_plane_state(plane->state); 151 + copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL); 152 + if (!copy) 153 + return NULL; 154 + 155 + __drm_atomic_helper_plane_duplicate_state(plane, &copy->base); 156 + return &copy->base; 157 + } 158 + 159 + static void exynos_drm_plane_destroy_state(struct drm_plane *plane, 160 + struct drm_plane_state *old_state) 161 + { 162 + struct exynos_drm_plane_state *old_exynos_state = 163 + to_exynos_plane_state(old_state); 164 + __drm_atomic_helper_plane_destroy_state(plane, old_state); 165 + kfree(old_exynos_state); 108 166 } 109 167 110 168 static struct drm_plane_funcs exynos_plane_funcs = { 111 169 .update_plane = drm_atomic_helper_update_plane, 112 170 .disable_plane = drm_atomic_helper_disable_plane, 113 171 .destroy = drm_plane_cleanup, 114 - .reset = drm_atomic_helper_plane_reset, 115 - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 116 - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 172 + .reset = exynos_drm_plane_reset, 173 + .atomic_duplicate_state = exynos_drm_plane_duplicate_state, 174 + .atomic_destroy_state = exynos_drm_plane_destroy_state, 117 175 }; 176 + 177 + static int 178 + exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config, 179 + struct exynos_drm_plane_state *state) 180 + { 181 + bool width_ok = false, height_ok = false; 182 + 183 + if (config->capabilities & EXYNOS_DRM_PLANE_CAP_SCALE) 184 + return 0; 185 + 186 + if (state->src.w == state->crtc.w) 187 + width_ok = true; 188 + 189 + if (state->src.h == state->crtc.h) 190 + height_ok = true; 191 + 192 + if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE) && 193 + state->h_ratio == (1 << 15)) 194 + width_ok = true; 195 + 196 + if ((config->capabilities & EXYNOS_DRM_PLANE_CAP_DOUBLE) && 197 + state->v_ratio == (1 << 15)) 198 + height_ok = true; 199 + 200 + if (width_ok & height_ok) 201 + return 0; 202 + 203 + DRM_DEBUG_KMS("scaling mode is not supported"); 204 + return -ENOTSUPP; 205 + } 118 206 119 207 static int exynos_plane_atomic_check(struct drm_plane *plane, 120 208 struct drm_plane_state *state) 121 209 { 122 210 struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); 123 - int nr; 124 - int i; 211 + struct exynos_drm_plane_state *exynos_state = 212 + to_exynos_plane_state(state); 213 + int ret = 0; 125 214 126 - if (!state->fb) 215 + if (!state->crtc || !state->fb) 127 216 return 0; 128 217 129 - nr = drm_format_num_planes(state->fb->pixel_format); 130 - for (i = 0; i < nr; i++) { 131 - struct exynos_drm_gem *exynos_gem = 132 - exynos_drm_fb_gem(state->fb, i); 133 - if (!exynos_gem) { 134 - DRM_DEBUG_KMS("gem object is null\n"); 135 - return -EFAULT; 136 - } 218 + /* translate state into exynos_state */ 219 + exynos_plane_mode_set(exynos_state); 137 220 138 - exynos_plane->dma_addr[i] = exynos_gem->dma_addr + 139 - state->fb->offsets[i]; 140 - 141 - DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", 142 - i, (unsigned long)exynos_plane->dma_addr[i]); 143 - } 144 - 145 - return 0; 221 + ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state); 222 + return ret; 146 223 } 147 224 148 225 static void exynos_plane_atomic_update(struct drm_plane *plane, ··· 232 155 if (!state->crtc) 233 156 return; 234 157 235 - exynos_plane_mode_set(plane, state->crtc, state->fb, 236 - state->crtc_x, state->crtc_y, 237 - state->crtc_w, state->crtc_h, 238 - state->src_x >> 16, state->src_y >> 16, 239 - state->src_w >> 16, state->src_h >> 16); 240 - 158 + plane->crtc = state->crtc; 241 159 exynos_plane->pending_fb = state->fb; 242 160 243 161 if (exynos_crtc->ops->update_plane) ··· 249 177 return; 250 178 251 179 if (exynos_crtc->ops->disable_plane) 252 - exynos_crtc->ops->disable_plane(exynos_crtc, 253 - exynos_plane); 180 + exynos_crtc->ops->disable_plane(exynos_crtc, exynos_plane); 254 181 } 255 182 256 183 static const struct drm_plane_helper_funcs plane_helper_funcs = { ··· 278 207 drm_object_attach_property(&plane->base, prop, zpos); 279 208 } 280 209 281 - enum drm_plane_type exynos_plane_get_type(unsigned int zpos, 282 - unsigned int cursor_win) 283 - { 284 - if (zpos == DEFAULT_WIN) 285 - return DRM_PLANE_TYPE_PRIMARY; 286 - else if (zpos == cursor_win) 287 - return DRM_PLANE_TYPE_CURSOR; 288 - else 289 - return DRM_PLANE_TYPE_OVERLAY; 290 - } 291 - 292 210 int exynos_plane_init(struct drm_device *dev, 293 211 struct exynos_drm_plane *exynos_plane, 294 - unsigned long possible_crtcs, enum drm_plane_type type, 295 - const uint32_t *formats, unsigned int fcount, 296 - unsigned int zpos) 212 + unsigned long possible_crtcs, 213 + const struct exynos_drm_plane_config *config) 297 214 { 298 215 int err; 299 216 300 - err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs, 301 - &exynos_plane_funcs, formats, fcount, 302 - type, NULL); 217 + err = drm_universal_plane_init(dev, &exynos_plane->base, 218 + possible_crtcs, 219 + &exynos_plane_funcs, 220 + config->pixel_formats, 221 + config->num_pixel_formats, 222 + config->type, NULL); 303 223 if (err) { 304 224 DRM_ERROR("failed to initialize plane\n"); 305 225 return err; ··· 298 236 299 237 drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs); 300 238 301 - exynos_plane->zpos = zpos; 239 + exynos_plane->zpos = config->zpos; 240 + exynos_plane->config = config; 302 241 303 - if (type == DRM_PLANE_TYPE_OVERLAY) 304 - exynos_plane_attach_zpos_property(&exynos_plane->base, zpos); 242 + if (config->type == DRM_PLANE_TYPE_OVERLAY) 243 + exynos_plane_attach_zpos_property(&exynos_plane->base, 244 + config->zpos); 305 245 306 246 return 0; 307 247 }
+2 -5
drivers/gpu/drm/exynos/exynos_drm_plane.h
··· 9 9 * 10 10 */ 11 11 12 - enum drm_plane_type exynos_plane_get_type(unsigned int zpos, 13 - unsigned int cursor_win); 14 12 int exynos_plane_init(struct drm_device *dev, 15 13 struct exynos_drm_plane *exynos_plane, 16 - unsigned long possible_crtcs, enum drm_plane_type type, 17 - const uint32_t *formats, unsigned int fcount, 18 - unsigned int zpos); 14 + unsigned long possible_crtcs, 15 + const struct exynos_drm_plane_config *config);
+2 -2
drivers/gpu/drm/exynos/exynos_drm_rotator.c
··· 790 790 static int rotator_clk_crtl(struct rot_context *rot, bool enable) 791 791 { 792 792 if (enable) { 793 - clk_enable(rot->clock); 793 + clk_prepare_enable(rot->clock); 794 794 rot->suspended = false; 795 795 } else { 796 - clk_disable(rot->clock); 796 + clk_disable_unprepare(rot->clock); 797 797 rot->suspended = true; 798 798 } 799 799
+22 -9
drivers/gpu/drm/exynos/exynos_drm_vidi.c
··· 24 24 25 25 #include "exynos_drm_drv.h" 26 26 #include "exynos_drm_crtc.h" 27 + #include "exynos_drm_fb.h" 27 28 #include "exynos_drm_plane.h" 28 29 #include "exynos_drm_vidi.h" 29 30 30 31 /* vidi has totally three virtual windows. */ 31 32 #define WINDOWS_NR 3 32 - #define CURSOR_WIN 2 33 33 34 34 #define ctx_from_connector(c) container_of(c, struct vidi_context, \ 35 35 connector) ··· 89 89 DRM_FORMAT_NV12, 90 90 }; 91 91 92 + static const enum drm_plane_type vidi_win_types[WINDOWS_NR] = { 93 + DRM_PLANE_TYPE_PRIMARY, 94 + DRM_PLANE_TYPE_OVERLAY, 95 + DRM_PLANE_TYPE_CURSOR, 96 + }; 97 + 92 98 static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) 93 99 { 94 100 struct vidi_context *ctx = crtc->ctx; ··· 131 125 static void vidi_update_plane(struct exynos_drm_crtc *crtc, 132 126 struct exynos_drm_plane *plane) 133 127 { 128 + struct drm_plane_state *state = plane->base.state; 134 129 struct vidi_context *ctx = crtc->ctx; 130 + dma_addr_t addr; 135 131 136 132 if (ctx->suspended) 137 133 return; 138 134 139 - DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr); 135 + addr = exynos_drm_fb_dma_addr(state->fb, 0); 136 + DRM_DEBUG_KMS("dma_addr = %pad\n", &addr); 140 137 141 138 if (ctx->vblank_on) 142 139 schedule_work(&ctx->work); ··· 448 439 struct drm_device *drm_dev = data; 449 440 struct drm_encoder *encoder = &ctx->encoder; 450 441 struct exynos_drm_plane *exynos_plane; 451 - enum drm_plane_type type; 452 - unsigned int zpos; 442 + struct exynos_drm_plane_config plane_config = { 0 }; 443 + unsigned int i; 453 444 int pipe, ret; 454 445 455 446 vidi_ctx_initialize(ctx, drm_dev); 456 447 457 - for (zpos = 0; zpos < WINDOWS_NR; zpos++) { 458 - type = exynos_plane_get_type(zpos, CURSOR_WIN); 459 - ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], 460 - 1 << ctx->pipe, type, formats, 461 - ARRAY_SIZE(formats), zpos); 448 + plane_config.pixel_formats = formats; 449 + plane_config.num_pixel_formats = ARRAY_SIZE(formats); 450 + 451 + for (i = 0; i < WINDOWS_NR; i++) { 452 + plane_config.zpos = i; 453 + plane_config.type = vidi_win_types[i]; 454 + 455 + ret = exynos_plane_init(drm_dev, &ctx->planes[i], 456 + 1 << ctx->pipe, &plane_config); 462 457 if (ret) 463 458 return ret; 464 459 }
+40 -9
drivers/gpu/drm/exynos/exynos_hdmi.c
··· 113 113 void __iomem *regs_hdmiphy; 114 114 struct i2c_client *hdmiphy_port; 115 115 struct i2c_adapter *ddc_adpt; 116 - struct gpio_desc *hpd_gpio; 116 + struct gpio_desc *hpd_gpio; 117 117 int irq; 118 118 struct regmap *pmureg; 119 119 struct clk *hdmi; ··· 1588 1588 if (hdata->powered) 1589 1589 return; 1590 1590 1591 - hdata->powered = true; 1592 - 1593 1591 pm_runtime_get_sync(hdata->dev); 1594 1592 1595 1593 if (regulator_bulk_enable(ARRAY_SIZE(supply), hdata->regul_bulk)) ··· 1597 1599 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, 1598 1600 PMU_HDMI_PHY_ENABLE_BIT, 1); 1599 1601 1600 - clk_prepare_enable(hdata->hdmi); 1601 - clk_prepare_enable(hdata->sclk_hdmi); 1602 - 1603 1602 hdmi_conf_apply(hdata); 1603 + 1604 + hdata->powered = true; 1604 1605 } 1605 1606 1606 1607 static void hdmi_disable(struct drm_encoder *encoder) ··· 1629 1632 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_EN); 1630 1633 1631 1634 cancel_delayed_work(&hdata->hotplug_work); 1632 - 1633 - clk_disable_unprepare(hdata->sclk_hdmi); 1634 - clk_disable_unprepare(hdata->hdmi); 1635 1635 1636 1636 /* reset pmu hdmiphy control bit to disable hdmiphy */ 1637 1637 regmap_update_bits(hdata->pmureg, PMU_HDMI_PHY_CONTROL, ··· 1972 1978 return 0; 1973 1979 } 1974 1980 1981 + #ifdef CONFIG_PM 1982 + static int exynos_hdmi_suspend(struct device *dev) 1983 + { 1984 + struct hdmi_context *hdata = dev_get_drvdata(dev); 1985 + 1986 + clk_disable_unprepare(hdata->sclk_hdmi); 1987 + clk_disable_unprepare(hdata->hdmi); 1988 + 1989 + return 0; 1990 + } 1991 + 1992 + static int exynos_hdmi_resume(struct device *dev) 1993 + { 1994 + struct hdmi_context *hdata = dev_get_drvdata(dev); 1995 + int ret; 1996 + 1997 + ret = clk_prepare_enable(hdata->hdmi); 1998 + if (ret < 0) { 1999 + DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); 2000 + return ret; 2001 + } 2002 + ret = clk_prepare_enable(hdata->sclk_hdmi); 2003 + if (ret < 0) { 2004 + DRM_ERROR("Failed to prepare_enable the sclk_mixer clk [%d]\n", 2005 + ret); 2006 + return ret; 2007 + } 2008 + 2009 + return 0; 2010 + } 2011 + #endif 2012 + 2013 + static const struct dev_pm_ops exynos_hdmi_pm_ops = { 2014 + SET_RUNTIME_PM_OPS(exynos_hdmi_suspend, exynos_hdmi_resume, NULL) 2015 + }; 2016 + 1975 2017 struct platform_driver hdmi_driver = { 1976 2018 .probe = hdmi_probe, 1977 2019 .remove = hdmi_remove, 1978 2020 .driver = { 1979 2021 .name = "exynos-hdmi", 1980 2022 .owner = THIS_MODULE, 2023 + .pm = &exynos_hdmi_pm_ops, 1981 2024 .of_match_table = hdmi_match_types, 1982 2025 }, 1983 2026 };
+125 -114
drivers/gpu/drm/exynos/exynos_mixer.c
··· 37 37 38 38 #include "exynos_drm_drv.h" 39 39 #include "exynos_drm_crtc.h" 40 + #include "exynos_drm_fb.h" 40 41 #include "exynos_drm_plane.h" 41 42 #include "exynos_drm_iommu.h" 42 43 43 44 #define MIXER_WIN_NR 3 44 45 #define VP_DEFAULT_WIN 2 45 - #define CURSOR_WIN 1 46 46 47 47 /* The pixelformats that are natively supported by the mixer. */ 48 48 #define MXR_FORMAT_RGB565 4 ··· 109 109 enum mixer_version_id version; 110 110 bool is_vp_enabled; 111 111 bool has_sclk; 112 + }; 113 + 114 + static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { 115 + { 116 + .zpos = 0, 117 + .type = DRM_PLANE_TYPE_PRIMARY, 118 + .pixel_formats = mixer_formats, 119 + .num_pixel_formats = ARRAY_SIZE(mixer_formats), 120 + .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE, 121 + }, { 122 + .zpos = 1, 123 + .type = DRM_PLANE_TYPE_CURSOR, 124 + .pixel_formats = mixer_formats, 125 + .num_pixel_formats = ARRAY_SIZE(mixer_formats), 126 + .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE, 127 + }, { 128 + .zpos = 2, 129 + .type = DRM_PLANE_TYPE_OVERLAY, 130 + .pixel_formats = vp_formats, 131 + .num_pixel_formats = ARRAY_SIZE(vp_formats), 132 + .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE, 133 + }, 112 134 }; 113 135 114 136 static const u8 filter_y_horiz_tap8[] = { ··· 421 399 static void vp_video_buffer(struct mixer_context *ctx, 422 400 struct exynos_drm_plane *plane) 423 401 { 402 + struct exynos_drm_plane_state *state = 403 + to_exynos_plane_state(plane->base.state); 404 + struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode; 424 405 struct mixer_resources *res = &ctx->mixer_res; 425 - struct drm_plane_state *state = plane->base.state; 426 - struct drm_framebuffer *fb = state->fb; 427 - struct drm_display_mode *mode = &state->crtc->mode; 406 + struct drm_framebuffer *fb = state->base.fb; 428 407 unsigned long flags; 429 408 dma_addr_t luma_addr[2], chroma_addr[2]; 430 409 bool tiled_mode = false; ··· 445 422 return; 446 423 } 447 424 448 - luma_addr[0] = plane->dma_addr[0]; 449 - chroma_addr[0] = plane->dma_addr[1]; 425 + luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0); 426 + chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1); 450 427 451 428 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 452 429 ctx->interlace = true; ··· 482 459 vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | 483 460 VP_IMG_VSIZE(fb->height / 2)); 484 461 485 - vp_reg_write(res, VP_SRC_WIDTH, plane->src_w); 486 - vp_reg_write(res, VP_SRC_HEIGHT, plane->src_h); 462 + vp_reg_write(res, VP_SRC_WIDTH, state->src.w); 463 + vp_reg_write(res, VP_SRC_HEIGHT, state->src.h); 487 464 vp_reg_write(res, VP_SRC_H_POSITION, 488 - VP_SRC_H_POSITION_VAL(plane->src_x)); 489 - vp_reg_write(res, VP_SRC_V_POSITION, plane->src_y); 465 + VP_SRC_H_POSITION_VAL(state->src.x)); 466 + vp_reg_write(res, VP_SRC_V_POSITION, state->src.y); 490 467 491 - vp_reg_write(res, VP_DST_WIDTH, plane->crtc_w); 492 - vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x); 468 + vp_reg_write(res, VP_DST_WIDTH, state->crtc.w); 469 + vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x); 493 470 if (ctx->interlace) { 494 - vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h / 2); 495 - vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2); 471 + vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2); 472 + vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2); 496 473 } else { 497 - vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h); 498 - vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y); 474 + vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h); 475 + vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y); 499 476 } 500 477 501 - vp_reg_write(res, VP_H_RATIO, plane->h_ratio); 502 - vp_reg_write(res, VP_V_RATIO, plane->v_ratio); 478 + vp_reg_write(res, VP_H_RATIO, state->h_ratio); 479 + vp_reg_write(res, VP_V_RATIO, state->v_ratio); 503 480 504 481 vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); 505 482 ··· 528 505 mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE); 529 506 } 530 507 531 - static int mixer_setup_scale(const struct exynos_drm_plane *plane, 532 - unsigned int *x_ratio, unsigned int *y_ratio) 533 - { 534 - if (plane->crtc_w != plane->src_w) { 535 - if (plane->crtc_w == 2 * plane->src_w) 536 - *x_ratio = 1; 537 - else 538 - goto fail; 539 - } 540 - 541 - if (plane->crtc_h != plane->src_h) { 542 - if (plane->crtc_h == 2 * plane->src_h) 543 - *y_ratio = 1; 544 - else 545 - goto fail; 546 - } 547 - 548 - return 0; 549 - 550 - fail: 551 - DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n"); 552 - return -ENOTSUPP; 553 - } 554 - 555 508 static void mixer_graph_buffer(struct mixer_context *ctx, 556 509 struct exynos_drm_plane *plane) 557 510 { 511 + struct exynos_drm_plane_state *state = 512 + to_exynos_plane_state(plane->base.state); 513 + struct drm_display_mode *mode = &state->base.crtc->state->adjusted_mode; 558 514 struct mixer_resources *res = &ctx->mixer_res; 559 - struct drm_plane_state *state = plane->base.state; 560 - struct drm_framebuffer *fb = state->fb; 561 - struct drm_display_mode *mode = &state->crtc->mode; 515 + struct drm_framebuffer *fb = state->base.fb; 562 516 unsigned long flags; 563 517 unsigned int win = plane->zpos; 564 518 unsigned int x_ratio = 0, y_ratio = 0; ··· 567 567 return; 568 568 } 569 569 570 - /* check if mixer supports requested scaling setup */ 571 - if (mixer_setup_scale(plane, &x_ratio, &y_ratio)) 572 - return; 570 + /* ratio is already checked by common plane code */ 571 + x_ratio = state->h_ratio == (1 << 15); 572 + y_ratio = state->v_ratio == (1 << 15); 573 573 574 - dst_x_offset = plane->crtc_x; 575 - dst_y_offset = plane->crtc_y; 574 + dst_x_offset = state->crtc.x; 575 + dst_y_offset = state->crtc.y; 576 576 577 577 /* converting dma address base and source offset */ 578 - dma_addr = plane->dma_addr[0] 579 - + (plane->src_x * fb->bits_per_pixel >> 3) 580 - + (plane->src_y * fb->pitches[0]); 578 + dma_addr = exynos_drm_fb_dma_addr(fb, 0) 579 + + (state->src.x * fb->bits_per_pixel >> 3) 580 + + (state->src.y * fb->pitches[0]); 581 581 src_x_offset = 0; 582 582 src_y_offset = 0; 583 583 ··· 605 605 mixer_reg_write(res, MXR_RESOLUTION, val); 606 606 } 607 607 608 - val = MXR_GRP_WH_WIDTH(plane->src_w); 609 - val |= MXR_GRP_WH_HEIGHT(plane->src_h); 608 + val = MXR_GRP_WH_WIDTH(state->src.w); 609 + val |= MXR_GRP_WH_HEIGHT(state->src.h); 610 610 val |= MXR_GRP_WH_H_SCALE(x_ratio); 611 611 val |= MXR_GRP_WH_V_SCALE(y_ratio); 612 612 mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); ··· 1020 1020 { 1021 1021 struct mixer_context *ctx = crtc->ctx; 1022 1022 struct mixer_resources *res = &ctx->mixer_res; 1023 - int ret; 1024 1023 1025 1024 if (test_bit(MXR_BIT_POWERED, &ctx->flags)) 1026 1025 return; 1027 1026 1028 1027 pm_runtime_get_sync(ctx->dev); 1029 - 1030 - ret = clk_prepare_enable(res->mixer); 1031 - if (ret < 0) { 1032 - DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); 1033 - return; 1034 - } 1035 - ret = clk_prepare_enable(res->hdmi); 1036 - if (ret < 0) { 1037 - DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); 1038 - return; 1039 - } 1040 - if (ctx->vp_enabled) { 1041 - ret = clk_prepare_enable(res->vp); 1042 - if (ret < 0) { 1043 - DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", 1044 - ret); 1045 - return; 1046 - } 1047 - if (ctx->has_sclk) { 1048 - ret = clk_prepare_enable(res->sclk_mixer); 1049 - if (ret < 0) { 1050 - DRM_ERROR("Failed to prepare_enable the " \ 1051 - "sclk_mixer clk [%d]\n", 1052 - ret); 1053 - return; 1054 - } 1055 - } 1056 - } 1057 - 1058 - set_bit(MXR_BIT_POWERED, &ctx->flags); 1059 1028 1060 1029 mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); 1061 1030 ··· 1033 1064 mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC); 1034 1065 } 1035 1066 mixer_win_reset(ctx); 1067 + 1068 + set_bit(MXR_BIT_POWERED, &ctx->flags); 1036 1069 } 1037 1070 1038 1071 static void mixer_disable(struct exynos_drm_crtc *crtc) 1039 1072 { 1040 1073 struct mixer_context *ctx = crtc->ctx; 1041 - struct mixer_resources *res = &ctx->mixer_res; 1042 1074 int i; 1043 1075 1044 1076 if (!test_bit(MXR_BIT_POWERED, &ctx->flags)) ··· 1051 1081 for (i = 0; i < MIXER_WIN_NR; i++) 1052 1082 mixer_disable_plane(crtc, &ctx->planes[i]); 1053 1083 1084 + pm_runtime_put(ctx->dev); 1085 + 1054 1086 clear_bit(MXR_BIT_POWERED, &ctx->flags); 1055 - 1056 - clk_disable_unprepare(res->hdmi); 1057 - clk_disable_unprepare(res->mixer); 1058 - if (ctx->vp_enabled) { 1059 - clk_disable_unprepare(res->vp); 1060 - if (ctx->has_sclk) 1061 - clk_disable_unprepare(res->sclk_mixer); 1062 - } 1063 - 1064 - pm_runtime_put_sync(ctx->dev); 1065 1087 } 1066 1088 1067 1089 /* Only valid for Mixer version 16.0.33.0 */ ··· 1149 1187 struct mixer_context *ctx = dev_get_drvdata(dev); 1150 1188 struct drm_device *drm_dev = data; 1151 1189 struct exynos_drm_plane *exynos_plane; 1152 - unsigned int zpos; 1190 + unsigned int i; 1153 1191 int ret; 1154 1192 1155 1193 ret = mixer_initialize(ctx, drm_dev); 1156 1194 if (ret) 1157 1195 return ret; 1158 1196 1159 - for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) { 1160 - enum drm_plane_type type; 1161 - const uint32_t *formats; 1162 - unsigned int fcount; 1197 + for (i = 0; i < MIXER_WIN_NR; i++) { 1198 + if (i == VP_DEFAULT_WIN && !ctx->vp_enabled) 1199 + continue; 1163 1200 1164 - if (zpos < VP_DEFAULT_WIN) { 1165 - formats = mixer_formats; 1166 - fcount = ARRAY_SIZE(mixer_formats); 1167 - } else { 1168 - formats = vp_formats; 1169 - fcount = ARRAY_SIZE(vp_formats); 1170 - } 1171 - 1172 - type = exynos_plane_get_type(zpos, CURSOR_WIN); 1173 - ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], 1174 - 1 << ctx->pipe, type, formats, fcount, 1175 - zpos); 1201 + ret = exynos_plane_init(drm_dev, &ctx->planes[i], 1202 + 1 << ctx->pipe, &plane_configs[i]); 1176 1203 if (ret) 1177 1204 return ret; 1178 1205 } ··· 1244 1293 return 0; 1245 1294 } 1246 1295 1296 + #ifdef CONFIG_PM_SLEEP 1297 + static int exynos_mixer_suspend(struct device *dev) 1298 + { 1299 + struct mixer_context *ctx = dev_get_drvdata(dev); 1300 + struct mixer_resources *res = &ctx->mixer_res; 1301 + 1302 + clk_disable_unprepare(res->hdmi); 1303 + clk_disable_unprepare(res->mixer); 1304 + if (ctx->vp_enabled) { 1305 + clk_disable_unprepare(res->vp); 1306 + if (ctx->has_sclk) 1307 + clk_disable_unprepare(res->sclk_mixer); 1308 + } 1309 + 1310 + return 0; 1311 + } 1312 + 1313 + static int exynos_mixer_resume(struct device *dev) 1314 + { 1315 + struct mixer_context *ctx = dev_get_drvdata(dev); 1316 + struct mixer_resources *res = &ctx->mixer_res; 1317 + int ret; 1318 + 1319 + ret = clk_prepare_enable(res->mixer); 1320 + if (ret < 0) { 1321 + DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret); 1322 + return ret; 1323 + } 1324 + ret = clk_prepare_enable(res->hdmi); 1325 + if (ret < 0) { 1326 + DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret); 1327 + return ret; 1328 + } 1329 + if (ctx->vp_enabled) { 1330 + ret = clk_prepare_enable(res->vp); 1331 + if (ret < 0) { 1332 + DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n", 1333 + ret); 1334 + return ret; 1335 + } 1336 + if (ctx->has_sclk) { 1337 + ret = clk_prepare_enable(res->sclk_mixer); 1338 + if (ret < 0) { 1339 + DRM_ERROR("Failed to prepare_enable the " \ 1340 + "sclk_mixer clk [%d]\n", 1341 + ret); 1342 + return ret; 1343 + } 1344 + } 1345 + } 1346 + 1347 + return 0; 1348 + } 1349 + #endif 1350 + 1351 + static const struct dev_pm_ops exynos_mixer_pm_ops = { 1352 + SET_RUNTIME_PM_OPS(exynos_mixer_suspend, exynos_mixer_resume, NULL) 1353 + }; 1354 + 1247 1355 struct platform_driver mixer_driver = { 1248 1356 .driver = { 1249 1357 .name = "exynos-mixer", 1250 1358 .owner = THIS_MODULE, 1359 + .pm = &exynos_mixer_pm_ops, 1251 1360 .of_match_table = mixer_match_types, 1252 1361 }, 1253 1362 .probe = mixer_probe,
+2 -2
drivers/gpu/drm/exynos/regs-gsc.h
··· 273 273 #define GSC_CLK_GATE_MODE_SNOOP_CNT(x) ((x) << 0) 274 274 275 275 /* SYSCON. GSCBLK_CFG */ 276 - #define SYSREG_GSCBLK_CFG1 (S3C_VA_SYS + 0x0224) 276 + #define SYSREG_GSCBLK_CFG1 0x0224 277 277 #define GSC_BLK_DISP1WB_DEST(x) (x << 10) 278 278 #define GSC_BLK_SW_RESET_WB_DEST(x) (1 << (18 + x)) 279 279 #define GSC_BLK_PXLASYNC_LO_MASK_WB(x) (0 << (14 + x)) 280 280 #define GSC_BLK_GSCL_WB_IN_SRC_SEL(x) (1 << (2 * x)) 281 - #define SYSREG_GSCBLK_CFG2 (S3C_VA_SYS + 0x2000) 281 + #define SYSREG_GSCBLK_CFG2 0x2000 282 282 #define PXLASYNC_LO_MASK_CAMIF_GSCL(x) (1 << (x)) 283 283 284 284 #endif /* EXYNOS_REGS_GSC_H_ */