diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-04-03 08:03:40 -0400 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2015-04-12 22:39:39 -0400 |
commit | 7ee14cdcbc4f813b9c5875d6e8e3daef71c366b3 (patch) | |
tree | 2c65b033db13c2ed7175f511fc773dfa6a5ee812 /drivers/gpu/drm/exynos | |
parent | 1be4b7ee800a57ca613131304e01cd91ec8bca2a (diff) |
drm/exynos: remove struct *_win_data abstraction on planes
struct {fimd,mixer,vidi}_win_data was just keeping the same data
as struct exynos_drm_plane thus get ride of it and use exynos_drm_plane
directly.
It changes how planes are created and remove .win_mode_set() callback
that was only filling all *_win_data structs.
v2: check for return of exynos_plane_init()
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos7_drm_decon.c | 166 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 186 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 125 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 216 |
10 files changed, 250 insertions, 501 deletions
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 970046199608..c5dfd99653d8 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <video/exynos7_decon.h> | 28 | #include <video/exynos7_decon.h> |
29 | 29 | ||
30 | #include "exynos_drm_crtc.h" | 30 | #include "exynos_drm_crtc.h" |
31 | #include "exynos_drm_plane.h" | ||
31 | #include "exynos_drm_drv.h" | 32 | #include "exynos_drm_drv.h" |
32 | #include "exynos_drm_fbdev.h" | 33 | #include "exynos_drm_fbdev.h" |
33 | #include "exynos_drm_iommu.h" | 34 | #include "exynos_drm_iommu.h" |
@@ -41,32 +42,16 @@ | |||
41 | 42 | ||
42 | #define WINDOWS_NR 2 | 43 | #define WINDOWS_NR 2 |
43 | 44 | ||
44 | struct decon_win_data { | ||
45 | unsigned int ovl_x; | ||
46 | unsigned int ovl_y; | ||
47 | unsigned int offset_x; | ||
48 | unsigned int offset_y; | ||
49 | unsigned int ovl_width; | ||
50 | unsigned int ovl_height; | ||
51 | unsigned int fb_width; | ||
52 | unsigned int fb_height; | ||
53 | unsigned int bpp; | ||
54 | unsigned int pixel_format; | ||
55 | dma_addr_t dma_addr; | ||
56 | bool enabled; | ||
57 | bool resume; | ||
58 | }; | ||
59 | |||
60 | struct decon_context { | 45 | struct decon_context { |
61 | struct device *dev; | 46 | struct device *dev; |
62 | struct drm_device *drm_dev; | 47 | struct drm_device *drm_dev; |
63 | struct exynos_drm_crtc *crtc; | 48 | struct exynos_drm_crtc *crtc; |
49 | struct exynos_drm_plane planes[WINDOWS_NR]; | ||
64 | struct clk *pclk; | 50 | struct clk *pclk; |
65 | struct clk *aclk; | 51 | struct clk *aclk; |
66 | struct clk *eclk; | 52 | struct clk *eclk; |
67 | struct clk *vclk; | 53 | struct clk *vclk; |
68 | void __iomem *regs; | 54 | void __iomem *regs; |
69 | struct decon_win_data win_data[WINDOWS_NR]; | ||
70 | unsigned int default_win; | 55 | unsigned int default_win; |
71 | unsigned long irq_flags; | 56 | unsigned long irq_flags; |
72 | bool i80_if; | 57 | bool i80_if; |
@@ -296,59 +281,16 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc) | |||
296 | } | 281 | } |
297 | } | 282 | } |
298 | 283 | ||
299 | static void decon_win_mode_set(struct exynos_drm_crtc *crtc, | ||
300 | struct exynos_drm_plane *plane) | ||
301 | { | ||
302 | struct decon_context *ctx = crtc->ctx; | ||
303 | struct decon_win_data *win_data; | ||
304 | int win, padding; | ||
305 | |||
306 | if (!plane) { | ||
307 | DRM_ERROR("plane is NULL\n"); | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | win = plane->zpos; | ||
312 | if (win == DEFAULT_ZPOS) | ||
313 | win = ctx->default_win; | ||
314 | |||
315 | if (win < 0 || win >= WINDOWS_NR) | ||
316 | return; | ||
317 | |||
318 | |||
319 | win_data = &ctx->win_data[win]; | ||
320 | |||
321 | padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; | ||
322 | win_data->offset_x = plane->fb_x; | ||
323 | win_data->offset_y = plane->fb_y; | ||
324 | win_data->fb_width = plane->fb_width + padding; | ||
325 | win_data->fb_height = plane->fb_height; | ||
326 | win_data->ovl_x = plane->crtc_x; | ||
327 | win_data->ovl_y = plane->crtc_y; | ||
328 | win_data->ovl_width = plane->crtc_width; | ||
329 | win_data->ovl_height = plane->crtc_height; | ||
330 | win_data->dma_addr = plane->dma_addr[0]; | ||
331 | win_data->bpp = plane->bpp; | ||
332 | win_data->pixel_format = plane->pixel_format; | ||
333 | |||
334 | DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", | ||
335 | win_data->offset_x, win_data->offset_y); | ||
336 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | ||
337 | win_data->ovl_width, win_data->ovl_height); | ||
338 | DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); | ||
339 | DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", | ||
340 | plane->fb_width, plane->crtc_width); | ||
341 | } | ||
342 | |||
343 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) | 284 | static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) |
344 | { | 285 | { |
345 | struct decon_win_data *win_data = &ctx->win_data[win]; | 286 | struct exynos_drm_plane *plane = &ctx->planes[win]; |
346 | unsigned long val; | 287 | unsigned long val; |
288 | int padding; | ||
347 | 289 | ||
348 | val = readl(ctx->regs + WINCON(win)); | 290 | val = readl(ctx->regs + WINCON(win)); |
349 | val &= ~WINCONx_BPPMODE_MASK; | 291 | val &= ~WINCONx_BPPMODE_MASK; |
350 | 292 | ||
351 | switch (win_data->pixel_format) { | 293 | switch (plane->pixel_format) { |
352 | case DRM_FORMAT_RGB565: | 294 | case DRM_FORMAT_RGB565: |
353 | val |= WINCONx_BPPMODE_16BPP_565; | 295 | val |= WINCONx_BPPMODE_16BPP_565; |
354 | val |= WINCONx_BURSTLEN_16WORD; | 296 | val |= WINCONx_BURSTLEN_16WORD; |
@@ -397,7 +339,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) | |||
397 | break; | 339 | break; |
398 | } | 340 | } |
399 | 341 | ||
400 | DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); | 342 | DRM_DEBUG_KMS("bpp = %d\n", plane->bpp); |
401 | 343 | ||
402 | /* | 344 | /* |
403 | * In case of exynos, setting dma-burst to 16Word causes permanent | 345 | * In case of exynos, setting dma-burst to 16Word causes permanent |
@@ -407,7 +349,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) | |||
407 | * movement causes unstable DMA which results into iommu crash/tear. | 349 | * movement causes unstable DMA which results into iommu crash/tear. |
408 | */ | 350 | */ |
409 | 351 | ||
410 | if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) { | 352 | padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; |
353 | if (plane->fb_width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { | ||
411 | val &= ~WINCONx_BURSTLEN_MASK; | 354 | val &= ~WINCONx_BURSTLEN_MASK; |
412 | val |= WINCONx_BURSTLEN_8WORD; | 355 | val |= WINCONx_BURSTLEN_8WORD; |
413 | } | 356 | } |
@@ -453,8 +396,8 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
453 | { | 396 | { |
454 | struct decon_context *ctx = crtc->ctx; | 397 | struct decon_context *ctx = crtc->ctx; |
455 | struct drm_display_mode *mode = &crtc->base.mode; | 398 | struct drm_display_mode *mode = &crtc->base.mode; |
456 | struct decon_win_data *win_data; | 399 | struct exynos_drm_plane *plane; |
457 | int win = zpos; | 400 | int padding, win = zpos; |
458 | unsigned long val, alpha; | 401 | unsigned long val, alpha; |
459 | unsigned int last_x; | 402 | unsigned int last_x; |
460 | unsigned int last_y; | 403 | unsigned int last_y; |
@@ -468,11 +411,11 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
468 | if (win < 0 || win >= WINDOWS_NR) | 411 | if (win < 0 || win >= WINDOWS_NR) |
469 | return; | 412 | return; |
470 | 413 | ||
471 | win_data = &ctx->win_data[win]; | 414 | plane = &ctx->planes[win]; |
472 | 415 | ||
473 | /* If suspended, enable this on resume */ | 416 | /* If suspended, enable this on resume */ |
474 | if (ctx->suspended) { | 417 | if (ctx->suspended) { |
475 | win_data->resume = true; | 418 | plane->resume = true; |
476 | return; | 419 | return; |
477 | } | 420 | } |
478 | 421 | ||
@@ -490,39 +433,41 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
490 | decon_shadow_protect_win(ctx, win, true); | 433 | decon_shadow_protect_win(ctx, win, true); |
491 | 434 | ||
492 | /* buffer start address */ | 435 | /* buffer start address */ |
493 | val = (unsigned long)win_data->dma_addr; | 436 | val = (unsigned long)plane->dma_addr[0]; |
494 | writel(val, ctx->regs + VIDW_BUF_START(win)); | 437 | writel(val, ctx->regs + VIDW_BUF_START(win)); |
495 | 438 | ||
439 | padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; | ||
440 | |||
496 | /* buffer size */ | 441 | /* buffer size */ |
497 | writel(win_data->fb_width, ctx->regs + VIDW_WHOLE_X(win)); | 442 | writel(plane->fb_width + padding, ctx->regs + VIDW_WHOLE_X(win)); |
498 | writel(win_data->fb_height, ctx->regs + VIDW_WHOLE_Y(win)); | 443 | writel(plane->fb_height, ctx->regs + VIDW_WHOLE_Y(win)); |
499 | 444 | ||
500 | /* offset from the start of the buffer to read */ | 445 | /* offset from the start of the buffer to read */ |
501 | writel(win_data->offset_x, ctx->regs + VIDW_OFFSET_X(win)); | 446 | writel(plane->fb_x, ctx->regs + VIDW_OFFSET_X(win)); |
502 | writel(win_data->offset_y, ctx->regs + VIDW_OFFSET_Y(win)); | 447 | writel(plane->fb_y, ctx->regs + VIDW_OFFSET_Y(win)); |
503 | 448 | ||
504 | DRM_DEBUG_KMS("start addr = 0x%lx\n", | 449 | DRM_DEBUG_KMS("start addr = 0x%lx\n", |
505 | (unsigned long)win_data->dma_addr); | 450 | (unsigned long)val); |
506 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | 451 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", |
507 | win_data->ovl_width, win_data->ovl_height); | 452 | plane->crtc_width, plane->crtc_height); |
508 | 453 | ||
509 | /* | 454 | /* |
510 | * OSD position. | 455 | * OSD position. |
511 | * In case the window layout goes of LCD layout, DECON fails. | 456 | * In case the window layout goes of LCD layout, DECON fails. |
512 | */ | 457 | */ |
513 | if ((win_data->ovl_x + win_data->ovl_width) > mode->hdisplay) | 458 | if ((plane->crtc_x + plane->crtc_width) > mode->hdisplay) |
514 | win_data->ovl_x = mode->hdisplay - win_data->ovl_width; | 459 | plane->crtc_x = mode->hdisplay - plane->crtc_width; |
515 | if ((win_data->ovl_y + win_data->ovl_height) > mode->vdisplay) | 460 | if ((plane->crtc_y + plane->crtc_height) > mode->vdisplay) |
516 | win_data->ovl_y = mode->vdisplay - win_data->ovl_height; | 461 | plane->crtc_y = mode->vdisplay - plane->crtc_height; |
517 | 462 | ||
518 | val = VIDOSDxA_TOPLEFT_X(win_data->ovl_x) | | 463 | val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | |
519 | VIDOSDxA_TOPLEFT_Y(win_data->ovl_y); | 464 | VIDOSDxA_TOPLEFT_Y(plane->crtc_y); |
520 | writel(val, ctx->regs + VIDOSD_A(win)); | 465 | writel(val, ctx->regs + VIDOSD_A(win)); |
521 | 466 | ||
522 | last_x = win_data->ovl_x + win_data->ovl_width; | 467 | last_x = plane->crtc_x + plane->crtc_width; |
523 | if (last_x) | 468 | if (last_x) |
524 | last_x--; | 469 | last_x--; |
525 | last_y = win_data->ovl_y + win_data->ovl_height; | 470 | last_y = plane->crtc_y + plane->crtc_height; |
526 | if (last_y) | 471 | if (last_y) |
527 | last_y--; | 472 | last_y--; |
528 | 473 | ||
@@ -531,7 +476,7 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
531 | writel(val, ctx->regs + VIDOSD_B(win)); | 476 | writel(val, ctx->regs + VIDOSD_B(win)); |
532 | 477 | ||
533 | DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", | 478 | DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", |
534 | win_data->ovl_x, win_data->ovl_y, last_x, last_y); | 479 | plane->crtc_x, plane->crtc_y, last_x, last_y); |
535 | 480 | ||
536 | /* OSD alpha */ | 481 | /* OSD alpha */ |
537 | alpha = VIDOSDxC_ALPHA0_R_F(0x0) | | 482 | alpha = VIDOSDxC_ALPHA0_R_F(0x0) | |
@@ -565,13 +510,13 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
565 | val |= DECON_UPDATE_STANDALONE_F; | 510 | val |= DECON_UPDATE_STANDALONE_F; |
566 | writel(val, ctx->regs + DECON_UPDATE); | 511 | writel(val, ctx->regs + DECON_UPDATE); |
567 | 512 | ||
568 | win_data->enabled = true; | 513 | plane->enabled = true; |
569 | } | 514 | } |
570 | 515 | ||
571 | static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos) | 516 | static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
572 | { | 517 | { |
573 | struct decon_context *ctx = crtc->ctx; | 518 | struct decon_context *ctx = crtc->ctx; |
574 | struct decon_win_data *win_data; | 519 | struct exynos_drm_plane *plane; |
575 | int win = zpos; | 520 | int win = zpos; |
576 | u32 val; | 521 | u32 val; |
577 | 522 | ||
@@ -581,11 +526,11 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
581 | if (win < 0 || win >= WINDOWS_NR) | 526 | if (win < 0 || win >= WINDOWS_NR) |
582 | return; | 527 | return; |
583 | 528 | ||
584 | win_data = &ctx->win_data[win]; | 529 | plane = &ctx->planes[win]; |
585 | 530 | ||
586 | if (ctx->suspended) { | 531 | if (ctx->suspended) { |
587 | /* do not resume this window*/ | 532 | /* do not resume this window*/ |
588 | win_data->resume = false; | 533 | plane->resume = false; |
589 | return; | 534 | return; |
590 | } | 535 | } |
591 | 536 | ||
@@ -604,42 +549,42 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
604 | val |= DECON_UPDATE_STANDALONE_F; | 549 | val |= DECON_UPDATE_STANDALONE_F; |
605 | writel(val, ctx->regs + DECON_UPDATE); | 550 | writel(val, ctx->regs + DECON_UPDATE); |
606 | 551 | ||
607 | win_data->enabled = false; | 552 | plane->enabled = false; |
608 | } | 553 | } |
609 | 554 | ||
610 | static void decon_window_suspend(struct decon_context *ctx) | 555 | static void decon_window_suspend(struct decon_context *ctx) |
611 | { | 556 | { |
612 | struct decon_win_data *win_data; | 557 | struct exynos_drm_plane *plane; |
613 | int i; | 558 | int i; |
614 | 559 | ||
615 | for (i = 0; i < WINDOWS_NR; i++) { | 560 | for (i = 0; i < WINDOWS_NR; i++) { |
616 | win_data = &ctx->win_data[i]; | 561 | plane = &ctx->planes[i]; |
617 | win_data->resume = win_data->enabled; | 562 | plane->resume = plane->enabled; |
618 | if (win_data->enabled) | 563 | if (plane->enabled) |
619 | decon_win_disable(ctx->crtc, i); | 564 | decon_win_disable(ctx->crtc, i); |
620 | } | 565 | } |
621 | } | 566 | } |
622 | 567 | ||
623 | static void decon_window_resume(struct decon_context *ctx) | 568 | static void decon_window_resume(struct decon_context *ctx) |
624 | { | 569 | { |
625 | struct decon_win_data *win_data; | 570 | struct exynos_drm_plane *plane; |
626 | int i; | 571 | int i; |
627 | 572 | ||
628 | for (i = 0; i < WINDOWS_NR; i++) { | 573 | for (i = 0; i < WINDOWS_NR; i++) { |
629 | win_data = &ctx->win_data[i]; | 574 | plane = &ctx->planes[i]; |
630 | win_data->enabled = win_data->resume; | 575 | plane->enabled = plane->resume; |
631 | win_data->resume = false; | 576 | plane->resume = false; |
632 | } | 577 | } |
633 | } | 578 | } |
634 | 579 | ||
635 | static void decon_apply(struct decon_context *ctx) | 580 | static void decon_apply(struct decon_context *ctx) |
636 | { | 581 | { |
637 | struct decon_win_data *win_data; | 582 | struct exynos_drm_plane *plane; |
638 | int i; | 583 | int i; |
639 | 584 | ||
640 | for (i = 0; i < WINDOWS_NR; i++) { | 585 | for (i = 0; i < WINDOWS_NR; i++) { |
641 | win_data = &ctx->win_data[i]; | 586 | plane = &ctx->planes[i]; |
642 | if (win_data->enabled) | 587 | if (plane->enabled) |
643 | decon_win_commit(ctx->crtc, i); | 588 | decon_win_commit(ctx->crtc, i); |
644 | else | 589 | else |
645 | decon_win_disable(ctx->crtc, i); | 590 | decon_win_disable(ctx->crtc, i); |
@@ -779,7 +724,6 @@ static struct exynos_drm_crtc_ops decon_crtc_ops = { | |||
779 | .enable_vblank = decon_enable_vblank, | 724 | .enable_vblank = decon_enable_vblank, |
780 | .disable_vblank = decon_disable_vblank, | 725 | .disable_vblank = decon_disable_vblank, |
781 | .wait_for_vblank = decon_wait_for_vblank, | 726 | .wait_for_vblank = decon_wait_for_vblank, |
782 | .win_mode_set = decon_win_mode_set, | ||
783 | .win_commit = decon_win_commit, | 727 | .win_commit = decon_win_commit, |
784 | .win_disable = decon_win_disable, | 728 | .win_disable = decon_win_disable, |
785 | }; | 729 | }; |
@@ -818,7 +762,9 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | |||
818 | { | 762 | { |
819 | struct decon_context *ctx = dev_get_drvdata(dev); | 763 | struct decon_context *ctx = dev_get_drvdata(dev); |
820 | struct drm_device *drm_dev = data; | 764 | struct drm_device *drm_dev = data; |
821 | int ret; | 765 | struct exynos_drm_plane *exynos_plane; |
766 | enum drm_plane_type type; | ||
767 | int zpos, ret; | ||
822 | 768 | ||
823 | ret = decon_ctx_initialize(ctx, drm_dev); | 769 | ret = decon_ctx_initialize(ctx, drm_dev); |
824 | if (ret) { | 770 | if (ret) { |
@@ -826,8 +772,18 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | |||
826 | return ret; | 772 | return ret; |
827 | } | 773 | } |
828 | 774 | ||
829 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, | 775 | for (zpos = 0; zpos < WINDOWS_NR; zpos++) { |
830 | EXYNOS_DISPLAY_TYPE_LCD, | 776 | type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY : |
777 | DRM_PLANE_TYPE_OVERLAY; | ||
778 | ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], | ||
779 | 1 << ctx->pipe, type); | ||
780 | if (ret) | ||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | exynos_plane = &ctx->planes[ctx->default_win]; | ||
785 | ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, | ||
786 | ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD, | ||
831 | &decon_crtc_ops, ctx); | 787 | &decon_crtc_ops, ctx); |
832 | if (IS_ERR(ctx->crtc)) { | 788 | if (IS_ERR(ctx->crtc)) { |
833 | decon_ctx_remove(ctx); | 789 | decon_ctx_remove(ctx); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 48ccab7fdf63..47dd2b0f4aa5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -239,13 +239,13 @@ static struct drm_crtc_funcs exynos_crtc_funcs = { | |||
239 | }; | 239 | }; |
240 | 240 | ||
241 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | 241 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, |
242 | struct drm_plane *plane, | ||
242 | int pipe, | 243 | int pipe, |
243 | enum exynos_drm_output_type type, | 244 | enum exynos_drm_output_type type, |
244 | struct exynos_drm_crtc_ops *ops, | 245 | struct exynos_drm_crtc_ops *ops, |
245 | void *ctx) | 246 | void *ctx) |
246 | { | 247 | { |
247 | struct exynos_drm_crtc *exynos_crtc; | 248 | struct exynos_drm_crtc *exynos_crtc; |
248 | struct drm_plane *plane; | ||
249 | struct exynos_drm_private *private = drm_dev->dev_private; | 249 | struct exynos_drm_private *private = drm_dev->dev_private; |
250 | struct drm_crtc *crtc; | 250 | struct drm_crtc *crtc; |
251 | int ret; | 251 | int ret; |
@@ -262,12 +262,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | |||
262 | exynos_crtc->type = type; | 262 | exynos_crtc->type = type; |
263 | exynos_crtc->ops = ops; | 263 | exynos_crtc->ops = ops; |
264 | exynos_crtc->ctx = ctx; | 264 | exynos_crtc->ctx = ctx; |
265 | plane = exynos_plane_init(drm_dev, 1 << pipe, | ||
266 | DRM_PLANE_TYPE_PRIMARY); | ||
267 | if (IS_ERR(plane)) { | ||
268 | ret = PTR_ERR(plane); | ||
269 | goto err_plane; | ||
270 | } | ||
271 | 265 | ||
272 | crtc = &exynos_crtc->base; | 266 | crtc = &exynos_crtc->base; |
273 | 267 | ||
@@ -284,7 +278,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | |||
284 | 278 | ||
285 | err_crtc: | 279 | err_crtc: |
286 | plane->funcs->destroy(plane); | 280 | plane->funcs->destroy(plane); |
287 | err_plane: | ||
288 | kfree(exynos_crtc); | 281 | kfree(exynos_crtc); |
289 | return ERR_PTR(ret); | 282 | return ERR_PTR(ret); |
290 | } | 283 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index 6258b800aab8..e1fd2efc88ff 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "exynos_drm_drv.h" | 18 | #include "exynos_drm_drv.h" |
19 | 19 | ||
20 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, | 20 | struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, |
21 | struct drm_plane *plane, | ||
21 | int pipe, | 22 | int pipe, |
22 | enum exynos_drm_output_type type, | 23 | enum exynos_drm_output_type type, |
23 | struct exynos_drm_crtc_ops *ops, | 24 | struct exynos_drm_crtc_ops *ops, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 90168d7cf66a..bb6e7f72f9e0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -55,7 +55,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
55 | { | 55 | { |
56 | struct exynos_drm_private *private; | 56 | struct exynos_drm_private *private; |
57 | int ret; | 57 | int ret; |
58 | int nr; | ||
59 | 58 | ||
60 | private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); | 59 | private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); |
61 | if (!private) | 60 | if (!private) |
@@ -81,19 +80,6 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) | |||
81 | 80 | ||
82 | exynos_drm_mode_config_init(dev); | 81 | exynos_drm_mode_config_init(dev); |
83 | 82 | ||
84 | for (nr = 0; nr < MAX_PLANE; nr++) { | ||
85 | struct drm_plane *plane; | ||
86 | unsigned long possible_crtcs = (1 << MAX_CRTC) - 1; | ||
87 | |||
88 | plane = exynos_plane_init(dev, possible_crtcs, | ||
89 | DRM_PLANE_TYPE_OVERLAY); | ||
90 | if (!IS_ERR(plane)) | ||
91 | continue; | ||
92 | |||
93 | ret = PTR_ERR(plane); | ||
94 | goto err_mode_config_cleanup; | ||
95 | } | ||
96 | |||
97 | /* setup possible_clones. */ | 83 | /* setup possible_clones. */ |
98 | exynos_drm_encoder_setup(dev); | 84 | exynos_drm_encoder_setup(dev); |
99 | 85 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 4e8f0b04fff5..8a2f9430969d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -78,6 +78,7 @@ enum exynos_drm_output_type { | |||
78 | * @transparency: transparency on or off. | 78 | * @transparency: transparency on or off. |
79 | * @activated: activated or not. | 79 | * @activated: activated or not. |
80 | * @enabled: enabled or not. | 80 | * @enabled: enabled or not. |
81 | * @resume: to resume or not. | ||
81 | * | 82 | * |
82 | * this structure is common to exynos SoC and its contents would be copied | 83 | * this structure is common to exynos SoC and its contents would be copied |
83 | * to hardware specific overlay info. | 84 | * to hardware specific overlay info. |
@@ -112,6 +113,7 @@ struct exynos_drm_plane { | |||
112 | bool transparency:1; | 113 | bool transparency:1; |
113 | bool activated:1; | 114 | bool activated:1; |
114 | bool enabled:1; | 115 | bool enabled:1; |
116 | bool resume:1; | ||
115 | }; | 117 | }; |
116 | 118 | ||
117 | /* | 119 | /* |
@@ -172,7 +174,6 @@ struct exynos_drm_display { | |||
172 | * @disable_vblank: specific driver callback for disabling vblank interrupt. | 174 | * @disable_vblank: specific driver callback for disabling vblank interrupt. |
173 | * @wait_for_vblank: wait for vblank interrupt to make sure that | 175 | * @wait_for_vblank: wait for vblank interrupt to make sure that |
174 | * hardware overlay is updated. | 176 | * hardware overlay is updated. |
175 | * @win_mode_set: copy drm overlay info to hw specific overlay info. | ||
176 | * @win_commit: apply hardware specific overlay data to registers. | 177 | * @win_commit: apply hardware specific overlay data to registers. |
177 | * @win_disable: disable hardware specific overlay. | 178 | * @win_disable: disable hardware specific overlay. |
178 | * @te_handler: trigger to transfer video image at the tearing effect | 179 | * @te_handler: trigger to transfer video image at the tearing effect |
@@ -188,8 +189,6 @@ struct exynos_drm_crtc_ops { | |||
188 | int (*enable_vblank)(struct exynos_drm_crtc *crtc); | 189 | int (*enable_vblank)(struct exynos_drm_crtc *crtc); |
189 | void (*disable_vblank)(struct exynos_drm_crtc *crtc); | 190 | void (*disable_vblank)(struct exynos_drm_crtc *crtc); |
190 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); | 191 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); |
191 | void (*win_mode_set)(struct exynos_drm_crtc *crtc, | ||
192 | struct exynos_drm_plane *plane); | ||
193 | void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos); | 192 | void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos); |
194 | void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos); | 193 | void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos); |
195 | void (*te_handler)(struct exynos_drm_crtc *crtc); | 194 | void (*te_handler)(struct exynos_drm_crtc *crtc); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 6f51d3d7ef6f..ab97162dd76c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "exynos_drm_drv.h" | 31 | #include "exynos_drm_drv.h" |
32 | #include "exynos_drm_fbdev.h" | 32 | #include "exynos_drm_fbdev.h" |
33 | #include "exynos_drm_crtc.h" | 33 | #include "exynos_drm_crtc.h" |
34 | #include "exynos_drm_plane.h" | ||
34 | #include "exynos_drm_iommu.h" | 35 | #include "exynos_drm_iommu.h" |
35 | 36 | ||
36 | /* | 37 | /* |
@@ -143,32 +144,15 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { | |||
143 | .has_vtsel = 1, | 144 | .has_vtsel = 1, |
144 | }; | 145 | }; |
145 | 146 | ||
146 | struct fimd_win_data { | ||
147 | unsigned int offset_x; | ||
148 | unsigned int offset_y; | ||
149 | unsigned int ovl_width; | ||
150 | unsigned int ovl_height; | ||
151 | unsigned int fb_width; | ||
152 | unsigned int fb_height; | ||
153 | unsigned int fb_pitch; | ||
154 | unsigned int bpp; | ||
155 | unsigned int pixel_format; | ||
156 | dma_addr_t dma_addr; | ||
157 | unsigned int buf_offsize; | ||
158 | unsigned int line_size; /* bytes */ | ||
159 | bool enabled; | ||
160 | bool resume; | ||
161 | }; | ||
162 | |||
163 | struct fimd_context { | 147 | struct fimd_context { |
164 | struct device *dev; | 148 | struct device *dev; |
165 | struct drm_device *drm_dev; | 149 | struct drm_device *drm_dev; |
166 | struct exynos_drm_crtc *crtc; | 150 | struct exynos_drm_crtc *crtc; |
151 | struct exynos_drm_plane planes[WINDOWS_NR]; | ||
167 | struct clk *bus_clk; | 152 | struct clk *bus_clk; |
168 | struct clk *lcd_clk; | 153 | struct clk *lcd_clk; |
169 | void __iomem *regs; | 154 | void __iomem *regs; |
170 | struct regmap *sysreg; | 155 | struct regmap *sysreg; |
171 | struct fimd_win_data win_data[WINDOWS_NR]; | ||
172 | unsigned int default_win; | 156 | unsigned int default_win; |
173 | unsigned long irq_flags; | 157 | unsigned long irq_flags; |
174 | u32 vidcon0; | 158 | u32 vidcon0; |
@@ -505,59 +489,9 @@ static void fimd_disable_vblank(struct exynos_drm_crtc *crtc) | |||
505 | } | 489 | } |
506 | } | 490 | } |
507 | 491 | ||
508 | static void fimd_win_mode_set(struct exynos_drm_crtc *crtc, | ||
509 | struct exynos_drm_plane *plane) | ||
510 | { | ||
511 | struct fimd_context *ctx = crtc->ctx; | ||
512 | struct fimd_win_data *win_data; | ||
513 | int win; | ||
514 | unsigned long offset; | ||
515 | |||
516 | if (!plane) { | ||
517 | DRM_ERROR("plane is NULL\n"); | ||
518 | return; | ||
519 | } | ||
520 | |||
521 | win = plane->zpos; | ||
522 | if (win == DEFAULT_ZPOS) | ||
523 | win = ctx->default_win; | ||
524 | |||
525 | if (win < 0 || win >= WINDOWS_NR) | ||
526 | return; | ||
527 | |||
528 | offset = plane->fb_x * (plane->bpp >> 3); | ||
529 | offset += plane->fb_y * plane->pitch; | ||
530 | |||
531 | DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch); | ||
532 | |||
533 | win_data = &ctx->win_data[win]; | ||
534 | |||
535 | win_data->offset_x = plane->crtc_x; | ||
536 | win_data->offset_y = plane->crtc_y; | ||
537 | win_data->ovl_width = plane->crtc_width; | ||
538 | win_data->ovl_height = plane->crtc_height; | ||
539 | win_data->fb_pitch = plane->pitch; | ||
540 | win_data->fb_width = plane->fb_width; | ||
541 | win_data->fb_height = plane->fb_height; | ||
542 | win_data->dma_addr = plane->dma_addr[0] + offset; | ||
543 | win_data->bpp = plane->bpp; | ||
544 | win_data->pixel_format = plane->pixel_format; | ||
545 | win_data->buf_offsize = | ||
546 | plane->pitch - (plane->crtc_width * (plane->bpp >> 3)); | ||
547 | win_data->line_size = plane->crtc_width * (plane->bpp >> 3); | ||
548 | |||
549 | DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", | ||
550 | win_data->offset_x, win_data->offset_y); | ||
551 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | ||
552 | win_data->ovl_width, win_data->ovl_height); | ||
553 | DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); | ||
554 | DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", | ||
555 | plane->fb_width, plane->crtc_width); | ||
556 | } | ||
557 | |||
558 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) | 492 | static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) |
559 | { | 493 | { |
560 | struct fimd_win_data *win_data = &ctx->win_data[win]; | 494 | struct exynos_drm_plane *plane = &ctx->planes[win]; |
561 | unsigned long val; | 495 | unsigned long val; |
562 | 496 | ||
563 | val = WINCONx_ENWIN; | 497 | val = WINCONx_ENWIN; |
@@ -567,11 +501,11 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) | |||
567 | * So the request format is ARGB8888 then change it to XRGB8888. | 501 | * So the request format is ARGB8888 then change it to XRGB8888. |
568 | */ | 502 | */ |
569 | if (ctx->driver_data->has_limited_fmt && !win) { | 503 | if (ctx->driver_data->has_limited_fmt && !win) { |
570 | if (win_data->pixel_format == DRM_FORMAT_ARGB8888) | 504 | if (plane->pixel_format == DRM_FORMAT_ARGB8888) |
571 | win_data->pixel_format = DRM_FORMAT_XRGB8888; | 505 | plane->pixel_format = DRM_FORMAT_XRGB8888; |
572 | } | 506 | } |
573 | 507 | ||
574 | switch (win_data->pixel_format) { | 508 | switch (plane->pixel_format) { |
575 | case DRM_FORMAT_C8: | 509 | case DRM_FORMAT_C8: |
576 | val |= WINCON0_BPPMODE_8BPP_PALETTE; | 510 | val |= WINCON0_BPPMODE_8BPP_PALETTE; |
577 | val |= WINCONx_BURSTLEN_8WORD; | 511 | val |= WINCONx_BURSTLEN_8WORD; |
@@ -607,7 +541,7 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) | |||
607 | break; | 541 | break; |
608 | } | 542 | } |
609 | 543 | ||
610 | DRM_DEBUG_KMS("bpp = %d\n", win_data->bpp); | 544 | DRM_DEBUG_KMS("bpp = %d\n", plane->bpp); |
611 | 545 | ||
612 | /* | 546 | /* |
613 | * In case of exynos, setting dma-burst to 16Word causes permanent | 547 | * In case of exynos, setting dma-burst to 16Word causes permanent |
@@ -617,7 +551,7 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win) | |||
617 | * movement causes unstable DMA which results into iommu crash/tear. | 551 | * movement causes unstable DMA which results into iommu crash/tear. |
618 | */ | 552 | */ |
619 | 553 | ||
620 | if (win_data->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) { | 554 | if (plane->fb_width < MIN_FB_WIDTH_FOR_16WORD_BURST) { |
621 | val &= ~WINCONx_BURSTLEN_MASK; | 555 | val &= ~WINCONx_BURSTLEN_MASK; |
622 | val |= WINCONx_BURSTLEN_4WORD; | 556 | val |= WINCONx_BURSTLEN_4WORD; |
623 | } | 557 | } |
@@ -686,11 +620,11 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, | |||
686 | static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | 620 | static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) |
687 | { | 621 | { |
688 | struct fimd_context *ctx = crtc->ctx; | 622 | struct fimd_context *ctx = crtc->ctx; |
689 | struct fimd_win_data *win_data; | 623 | struct exynos_drm_plane *plane; |
690 | int win = zpos; | 624 | int win = zpos; |
691 | unsigned long val, size; | 625 | dma_addr_t dma_addr; |
692 | unsigned int last_x; | 626 | unsigned long val, size, offset; |
693 | unsigned int last_y; | 627 | unsigned int last_x, last_y, buf_offsize, line_size; |
694 | 628 | ||
695 | if (ctx->suspended) | 629 | if (ctx->suspended) |
696 | return; | 630 | return; |
@@ -701,11 +635,11 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
701 | if (win < 0 || win >= WINDOWS_NR) | 635 | if (win < 0 || win >= WINDOWS_NR) |
702 | return; | 636 | return; |
703 | 637 | ||
704 | win_data = &ctx->win_data[win]; | 638 | plane = &ctx->planes[win]; |
705 | 639 | ||
706 | /* If suspended, enable this on resume */ | 640 | /* If suspended, enable this on resume */ |
707 | if (ctx->suspended) { | 641 | if (ctx->suspended) { |
708 | win_data->resume = true; | 642 | plane->resume = true; |
709 | return; | 643 | return; |
710 | } | 644 | } |
711 | 645 | ||
@@ -722,38 +656,45 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
722 | /* protect windows */ | 656 | /* protect windows */ |
723 | fimd_shadow_protect_win(ctx, win, true); | 657 | fimd_shadow_protect_win(ctx, win, true); |
724 | 658 | ||
659 | |||
660 | offset = plane->fb_x * (plane->bpp >> 3); | ||
661 | offset += plane->fb_y * plane->pitch; | ||
662 | |||
725 | /* buffer start address */ | 663 | /* buffer start address */ |
726 | val = (unsigned long)win_data->dma_addr; | 664 | dma_addr = plane->dma_addr[0] + offset; |
665 | val = (unsigned long)dma_addr; | ||
727 | writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); | 666 | writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); |
728 | 667 | ||
729 | /* buffer end address */ | 668 | /* buffer end address */ |
730 | size = win_data->fb_pitch * win_data->ovl_height * (win_data->bpp >> 3); | 669 | size = plane->pitch * plane->crtc_height * (plane->bpp >> 3); |
731 | val = (unsigned long)(win_data->dma_addr + size); | 670 | val = (unsigned long)(dma_addr + size); |
732 | writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); | 671 | writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); |
733 | 672 | ||
734 | DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", | 673 | DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", |
735 | (unsigned long)win_data->dma_addr, val, size); | 674 | (unsigned long)dma_addr, val, size); |
736 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | 675 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", |
737 | win_data->ovl_width, win_data->ovl_height); | 676 | plane->crtc_width, plane->crtc_height); |
738 | 677 | ||
739 | /* buffer size */ | 678 | /* buffer size */ |
740 | val = VIDW_BUF_SIZE_OFFSET(win_data->buf_offsize) | | 679 | buf_offsize = (plane->fb_width - plane->crtc_width) * (plane->bpp >> 3); |
741 | VIDW_BUF_SIZE_PAGEWIDTH(win_data->line_size) | | 680 | line_size = plane->crtc_width * (plane->bpp >> 3); |
742 | VIDW_BUF_SIZE_OFFSET_E(win_data->buf_offsize) | | 681 | val = VIDW_BUF_SIZE_OFFSET(buf_offsize) | |
743 | VIDW_BUF_SIZE_PAGEWIDTH_E(win_data->line_size); | 682 | VIDW_BUF_SIZE_PAGEWIDTH(line_size) | |
683 | VIDW_BUF_SIZE_OFFSET_E(buf_offsize) | | ||
684 | VIDW_BUF_SIZE_PAGEWIDTH_E(line_size); | ||
744 | writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); | 685 | writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); |
745 | 686 | ||
746 | /* OSD position */ | 687 | /* OSD position */ |
747 | val = VIDOSDxA_TOPLEFT_X(win_data->offset_x) | | 688 | val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | |
748 | VIDOSDxA_TOPLEFT_Y(win_data->offset_y) | | 689 | VIDOSDxA_TOPLEFT_Y(plane->crtc_y) | |
749 | VIDOSDxA_TOPLEFT_X_E(win_data->offset_x) | | 690 | VIDOSDxA_TOPLEFT_X_E(plane->crtc_x) | |
750 | VIDOSDxA_TOPLEFT_Y_E(win_data->offset_y); | 691 | VIDOSDxA_TOPLEFT_Y_E(plane->crtc_y); |
751 | writel(val, ctx->regs + VIDOSD_A(win)); | 692 | writel(val, ctx->regs + VIDOSD_A(win)); |
752 | 693 | ||
753 | last_x = win_data->offset_x + win_data->ovl_width; | 694 | last_x = plane->crtc_x + plane->crtc_width; |
754 | if (last_x) | 695 | if (last_x) |
755 | last_x--; | 696 | last_x--; |
756 | last_y = win_data->offset_y + win_data->ovl_height; | 697 | last_y = plane->crtc_y + plane->crtc_height; |
757 | if (last_y) | 698 | if (last_y) |
758 | last_y--; | 699 | last_y--; |
759 | 700 | ||
@@ -763,14 +704,14 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
763 | writel(val, ctx->regs + VIDOSD_B(win)); | 704 | writel(val, ctx->regs + VIDOSD_B(win)); |
764 | 705 | ||
765 | DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", | 706 | DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", |
766 | win_data->offset_x, win_data->offset_y, last_x, last_y); | 707 | plane->crtc_x, plane->crtc_y, last_x, last_y); |
767 | 708 | ||
768 | /* OSD size */ | 709 | /* OSD size */ |
769 | if (win != 3 && win != 4) { | 710 | if (win != 3 && win != 4) { |
770 | u32 offset = VIDOSD_D(win); | 711 | u32 offset = VIDOSD_D(win); |
771 | if (win == 0) | 712 | if (win == 0) |
772 | offset = VIDOSD_C(win); | 713 | offset = VIDOSD_C(win); |
773 | val = win_data->ovl_width * win_data->ovl_height; | 714 | val = plane->crtc_width * plane->crtc_height; |
774 | writel(val, ctx->regs + offset); | 715 | writel(val, ctx->regs + offset); |
775 | 716 | ||
776 | DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); | 717 | DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); |
@@ -790,7 +731,7 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
790 | /* Enable DMA channel and unprotect windows */ | 731 | /* Enable DMA channel and unprotect windows */ |
791 | fimd_shadow_protect_win(ctx, win, false); | 732 | fimd_shadow_protect_win(ctx, win, false); |
792 | 733 | ||
793 | win_data->enabled = true; | 734 | plane->enabled = true; |
794 | 735 | ||
795 | if (ctx->i80_if) | 736 | if (ctx->i80_if) |
796 | atomic_set(&ctx->win_updated, 1); | 737 | atomic_set(&ctx->win_updated, 1); |
@@ -799,7 +740,7 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
799 | static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos) | 740 | static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
800 | { | 741 | { |
801 | struct fimd_context *ctx = crtc->ctx; | 742 | struct fimd_context *ctx = crtc->ctx; |
802 | struct fimd_win_data *win_data; | 743 | struct exynos_drm_plane *plane; |
803 | int win = zpos; | 744 | int win = zpos; |
804 | 745 | ||
805 | if (win == DEFAULT_ZPOS) | 746 | if (win == DEFAULT_ZPOS) |
@@ -808,11 +749,11 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
808 | if (win < 0 || win >= WINDOWS_NR) | 749 | if (win < 0 || win >= WINDOWS_NR) |
809 | return; | 750 | return; |
810 | 751 | ||
811 | win_data = &ctx->win_data[win]; | 752 | plane = &ctx->planes[win]; |
812 | 753 | ||
813 | if (ctx->suspended) { | 754 | if (ctx->suspended) { |
814 | /* do not resume this window*/ | 755 | /* do not resume this window*/ |
815 | win_data->resume = false; | 756 | plane->resume = false; |
816 | return; | 757 | return; |
817 | } | 758 | } |
818 | 759 | ||
@@ -827,42 +768,42 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
827 | /* unprotect windows */ | 768 | /* unprotect windows */ |
828 | fimd_shadow_protect_win(ctx, win, false); | 769 | fimd_shadow_protect_win(ctx, win, false); |
829 | 770 | ||
830 | win_data->enabled = false; | 771 | plane->enabled = false; |
831 | } | 772 | } |
832 | 773 | ||
833 | static void fimd_window_suspend(struct fimd_context *ctx) | 774 | static void fimd_window_suspend(struct fimd_context *ctx) |
834 | { | 775 | { |
835 | struct fimd_win_data *win_data; | 776 | struct exynos_drm_plane *plane; |
836 | int i; | 777 | int i; |
837 | 778 | ||
838 | for (i = 0; i < WINDOWS_NR; i++) { | 779 | for (i = 0; i < WINDOWS_NR; i++) { |
839 | win_data = &ctx->win_data[i]; | 780 | plane = &ctx->planes[i]; |
840 | win_data->resume = win_data->enabled; | 781 | plane->resume = plane->enabled; |
841 | if (win_data->enabled) | 782 | if (plane->enabled) |
842 | fimd_win_disable(ctx->crtc, i); | 783 | fimd_win_disable(ctx->crtc, i); |
843 | } | 784 | } |
844 | } | 785 | } |
845 | 786 | ||
846 | static void fimd_window_resume(struct fimd_context *ctx) | 787 | static void fimd_window_resume(struct fimd_context *ctx) |
847 | { | 788 | { |
848 | struct fimd_win_data *win_data; | 789 | struct exynos_drm_plane *plane; |
849 | int i; | 790 | int i; |
850 | 791 | ||
851 | for (i = 0; i < WINDOWS_NR; i++) { | 792 | for (i = 0; i < WINDOWS_NR; i++) { |
852 | win_data = &ctx->win_data[i]; | 793 | plane = &ctx->planes[i]; |
853 | win_data->enabled = win_data->resume; | 794 | plane->enabled = plane->resume; |
854 | win_data->resume = false; | 795 | plane->resume = false; |
855 | } | 796 | } |
856 | } | 797 | } |
857 | 798 | ||
858 | static void fimd_apply(struct fimd_context *ctx) | 799 | static void fimd_apply(struct fimd_context *ctx) |
859 | { | 800 | { |
860 | struct fimd_win_data *win_data; | 801 | struct exynos_drm_plane *plane; |
861 | int i; | 802 | int i; |
862 | 803 | ||
863 | for (i = 0; i < WINDOWS_NR; i++) { | 804 | for (i = 0; i < WINDOWS_NR; i++) { |
864 | win_data = &ctx->win_data[i]; | 805 | plane = &ctx->planes[i]; |
865 | if (win_data->enabled) | 806 | if (plane->enabled) |
866 | fimd_win_commit(ctx->crtc, i); | 807 | fimd_win_commit(ctx->crtc, i); |
867 | else | 808 | else |
868 | fimd_win_disable(ctx->crtc, i); | 809 | fimd_win_disable(ctx->crtc, i); |
@@ -1019,7 +960,6 @@ static struct exynos_drm_crtc_ops fimd_crtc_ops = { | |||
1019 | .enable_vblank = fimd_enable_vblank, | 960 | .enable_vblank = fimd_enable_vblank, |
1020 | .disable_vblank = fimd_disable_vblank, | 961 | .disable_vblank = fimd_disable_vblank, |
1021 | .wait_for_vblank = fimd_wait_for_vblank, | 962 | .wait_for_vblank = fimd_wait_for_vblank, |
1022 | .win_mode_set = fimd_win_mode_set, | ||
1023 | .win_commit = fimd_win_commit, | 963 | .win_commit = fimd_win_commit, |
1024 | .win_disable = fimd_win_disable, | 964 | .win_disable = fimd_win_disable, |
1025 | .te_handler = fimd_te_handler, | 965 | .te_handler = fimd_te_handler, |
@@ -1065,13 +1005,25 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | |||
1065 | struct fimd_context *ctx = dev_get_drvdata(dev); | 1005 | struct fimd_context *ctx = dev_get_drvdata(dev); |
1066 | struct drm_device *drm_dev = data; | 1006 | struct drm_device *drm_dev = data; |
1067 | struct exynos_drm_private *priv = drm_dev->dev_private; | 1007 | struct exynos_drm_private *priv = drm_dev->dev_private; |
1068 | int ret; | 1008 | struct exynos_drm_plane *exynos_plane; |
1009 | enum drm_plane_type type; | ||
1010 | int zpos, ret; | ||
1069 | 1011 | ||
1070 | ctx->drm_dev = drm_dev; | 1012 | ctx->drm_dev = drm_dev; |
1071 | ctx->pipe = priv->pipe++; | 1013 | ctx->pipe = priv->pipe++; |
1072 | 1014 | ||
1073 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, | 1015 | for (zpos = 0; zpos < WINDOWS_NR; zpos++) { |
1074 | EXYNOS_DISPLAY_TYPE_LCD, | 1016 | type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY : |
1017 | DRM_PLANE_TYPE_OVERLAY; | ||
1018 | ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], | ||
1019 | 1 << ctx->pipe, type); | ||
1020 | if (ret) | ||
1021 | return ret; | ||
1022 | } | ||
1023 | |||
1024 | exynos_plane = &ctx->planes[ctx->default_win]; | ||
1025 | ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, | ||
1026 | ctx->pipe, EXYNOS_DISPLAY_TYPE_LCD, | ||
1075 | &fimd_crtc_ops, ctx); | 1027 | &fimd_crtc_ops, ctx); |
1076 | 1028 | ||
1077 | if (ctx->display) | 1029 | if (ctx->display) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 8ad5b7294eb4..4014c746a534 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -92,7 +92,6 @@ void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
92 | uint32_t src_w, uint32_t src_h) | 92 | uint32_t src_w, uint32_t src_h) |
93 | { | 93 | { |
94 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 94 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); |
95 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
96 | unsigned int actual_w; | 95 | unsigned int actual_w; |
97 | unsigned int actual_h; | 96 | unsigned int actual_h; |
98 | 97 | ||
@@ -139,9 +138,6 @@ void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, | |||
139 | exynos_plane->crtc_width, exynos_plane->crtc_height); | 138 | exynos_plane->crtc_width, exynos_plane->crtc_height); |
140 | 139 | ||
141 | plane->crtc = crtc; | 140 | plane->crtc = crtc; |
142 | |||
143 | if (exynos_crtc->ops->win_mode_set) | ||
144 | exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane); | ||
145 | } | 141 | } |
146 | 142 | ||
147 | int | 143 | int |
@@ -184,11 +180,8 @@ static int exynos_disable_plane(struct drm_plane *plane) | |||
184 | 180 | ||
185 | static void exynos_plane_destroy(struct drm_plane *plane) | 181 | static void exynos_plane_destroy(struct drm_plane *plane) |
186 | { | 182 | { |
187 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | ||
188 | |||
189 | exynos_disable_plane(plane); | 183 | exynos_disable_plane(plane); |
190 | drm_plane_cleanup(plane); | 184 | drm_plane_cleanup(plane); |
191 | kfree(exynos_plane); | ||
192 | } | 185 | } |
193 | 186 | ||
194 | static int exynos_plane_set_property(struct drm_plane *plane, | 187 | static int exynos_plane_set_property(struct drm_plane *plane, |
@@ -233,24 +226,18 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane) | |||
233 | drm_object_attach_property(&plane->base, prop, 0); | 226 | drm_object_attach_property(&plane->base, prop, 0); |
234 | } | 227 | } |
235 | 228 | ||
236 | struct drm_plane *exynos_plane_init(struct drm_device *dev, | 229 | int exynos_plane_init(struct drm_device *dev, |
237 | unsigned long possible_crtcs, | 230 | struct exynos_drm_plane *exynos_plane, |
238 | enum drm_plane_type type) | 231 | unsigned long possible_crtcs, enum drm_plane_type type) |
239 | { | 232 | { |
240 | struct exynos_drm_plane *exynos_plane; | ||
241 | int err; | 233 | int err; |
242 | 234 | ||
243 | exynos_plane = kzalloc(sizeof(struct exynos_drm_plane), GFP_KERNEL); | ||
244 | if (!exynos_plane) | ||
245 | return ERR_PTR(-ENOMEM); | ||
246 | |||
247 | err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs, | 235 | err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs, |
248 | &exynos_plane_funcs, formats, | 236 | &exynos_plane_funcs, formats, |
249 | ARRAY_SIZE(formats), type); | 237 | ARRAY_SIZE(formats), type); |
250 | if (err) { | 238 | if (err) { |
251 | DRM_ERROR("failed to initialize plane\n"); | 239 | DRM_ERROR("failed to initialize plane\n"); |
252 | kfree(exynos_plane); | 240 | return err; |
253 | return ERR_PTR(err); | ||
254 | } | 241 | } |
255 | 242 | ||
256 | if (type == DRM_PLANE_TYPE_PRIMARY) | 243 | if (type == DRM_PLANE_TYPE_PRIMARY) |
@@ -258,5 +245,5 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev, | |||
258 | else | 245 | else |
259 | exynos_plane_attach_zpos_property(&exynos_plane->base); | 246 | exynos_plane_attach_zpos_property(&exynos_plane->base); |
260 | 247 | ||
261 | return &exynos_plane->base; | 248 | return 0; |
262 | } | 249 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h index 9d3c374e7b3e..d8a349491c68 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h | |||
@@ -20,6 +20,6 @@ int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
20 | unsigned int crtc_w, unsigned int crtc_h, | 20 | unsigned int crtc_w, unsigned int crtc_h, |
21 | uint32_t src_x, uint32_t src_y, | 21 | uint32_t src_x, uint32_t src_y, |
22 | uint32_t src_w, uint32_t src_h); | 22 | uint32_t src_w, uint32_t src_h); |
23 | struct drm_plane *exynos_plane_init(struct drm_device *dev, | 23 | int exynos_plane_init(struct drm_device *dev, |
24 | unsigned long possible_crtcs, | 24 | struct exynos_drm_plane *exynos_plane, |
25 | enum drm_plane_type type); | 25 | unsigned long possible_crtcs, enum drm_plane_type type); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index b886972b5888..da5ee15f6136 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "exynos_drm_drv.h" | 24 | #include "exynos_drm_drv.h" |
25 | #include "exynos_drm_crtc.h" | 25 | #include "exynos_drm_crtc.h" |
26 | #include "exynos_drm_plane.h" | ||
26 | #include "exynos_drm_encoder.h" | 27 | #include "exynos_drm_encoder.h" |
27 | #include "exynos_drm_vidi.h" | 28 | #include "exynos_drm_vidi.h" |
28 | 29 | ||
@@ -32,20 +33,6 @@ | |||
32 | #define ctx_from_connector(c) container_of(c, struct vidi_context, \ | 33 | #define ctx_from_connector(c) container_of(c, struct vidi_context, \ |
33 | connector) | 34 | connector) |
34 | 35 | ||
35 | struct vidi_win_data { | ||
36 | unsigned int offset_x; | ||
37 | unsigned int offset_y; | ||
38 | unsigned int ovl_width; | ||
39 | unsigned int ovl_height; | ||
40 | unsigned int fb_width; | ||
41 | unsigned int fb_height; | ||
42 | unsigned int bpp; | ||
43 | dma_addr_t dma_addr; | ||
44 | unsigned int buf_offsize; | ||
45 | unsigned int line_size; /* bytes */ | ||
46 | bool enabled; | ||
47 | }; | ||
48 | |||
49 | struct vidi_context { | 36 | struct vidi_context { |
50 | struct exynos_drm_display display; | 37 | struct exynos_drm_display display; |
51 | struct platform_device *pdev; | 38 | struct platform_device *pdev; |
@@ -53,7 +40,7 @@ struct vidi_context { | |||
53 | struct exynos_drm_crtc *crtc; | 40 | struct exynos_drm_crtc *crtc; |
54 | struct drm_encoder *encoder; | 41 | struct drm_encoder *encoder; |
55 | struct drm_connector connector; | 42 | struct drm_connector connector; |
56 | struct vidi_win_data win_data[WINDOWS_NR]; | 43 | struct exynos_drm_plane planes[WINDOWS_NR]; |
57 | struct edid *raw_edid; | 44 | struct edid *raw_edid; |
58 | unsigned int clkdiv; | 45 | unsigned int clkdiv; |
59 | unsigned int default_win; | 46 | unsigned int default_win; |
@@ -97,19 +84,6 @@ static const char fake_edid_info[] = { | |||
97 | 0x00, 0x00, 0x00, 0x06 | 84 | 0x00, 0x00, 0x00, 0x06 |
98 | }; | 85 | }; |
99 | 86 | ||
100 | static void vidi_apply(struct vidi_context *ctx) | ||
101 | { | ||
102 | struct exynos_drm_crtc_ops *crtc_ops = ctx->crtc->ops; | ||
103 | struct vidi_win_data *win_data; | ||
104 | int i; | ||
105 | |||
106 | for (i = 0; i < WINDOWS_NR; i++) { | ||
107 | win_data = &ctx->win_data[i]; | ||
108 | if (win_data->enabled && (crtc_ops && crtc_ops->win_commit)) | ||
109 | crtc_ops->win_commit(ctx->crtc, i); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) | 87 | static int vidi_enable_vblank(struct exynos_drm_crtc *crtc) |
114 | { | 88 | { |
115 | struct vidi_context *ctx = crtc->ctx; | 89 | struct vidi_context *ctx = crtc->ctx; |
@@ -143,63 +117,10 @@ static void vidi_disable_vblank(struct exynos_drm_crtc *crtc) | |||
143 | ctx->vblank_on = false; | 117 | ctx->vblank_on = false; |
144 | } | 118 | } |
145 | 119 | ||
146 | static void vidi_win_mode_set(struct exynos_drm_crtc *crtc, | ||
147 | struct exynos_drm_plane *plane) | ||
148 | { | ||
149 | struct vidi_context *ctx = crtc->ctx; | ||
150 | struct vidi_win_data *win_data; | ||
151 | int win; | ||
152 | unsigned long offset; | ||
153 | |||
154 | if (!plane) { | ||
155 | DRM_ERROR("plane is NULL\n"); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | win = plane->zpos; | ||
160 | if (win == DEFAULT_ZPOS) | ||
161 | win = ctx->default_win; | ||
162 | |||
163 | if (win < 0 || win >= WINDOWS_NR) | ||
164 | return; | ||
165 | |||
166 | offset = plane->fb_x * (plane->bpp >> 3); | ||
167 | offset += plane->fb_y * plane->pitch; | ||
168 | |||
169 | DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch); | ||
170 | |||
171 | win_data = &ctx->win_data[win]; | ||
172 | |||
173 | win_data->offset_x = plane->crtc_x; | ||
174 | win_data->offset_y = plane->crtc_y; | ||
175 | win_data->ovl_width = plane->crtc_width; | ||
176 | win_data->ovl_height = plane->crtc_height; | ||
177 | win_data->fb_width = plane->fb_width; | ||
178 | win_data->fb_height = plane->fb_height; | ||
179 | win_data->dma_addr = plane->dma_addr[0] + offset; | ||
180 | win_data->bpp = plane->bpp; | ||
181 | win_data->buf_offsize = (plane->fb_width - plane->crtc_width) * | ||
182 | (plane->bpp >> 3); | ||
183 | win_data->line_size = plane->crtc_width * (plane->bpp >> 3); | ||
184 | |||
185 | /* | ||
186 | * some parts of win_data should be transferred to user side | ||
187 | * through specific ioctl. | ||
188 | */ | ||
189 | |||
190 | DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n", | ||
191 | win_data->offset_x, win_data->offset_y); | ||
192 | DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", | ||
193 | win_data->ovl_width, win_data->ovl_height); | ||
194 | DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr); | ||
195 | DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n", | ||
196 | plane->fb_width, plane->crtc_width); | ||
197 | } | ||
198 | |||
199 | static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) | 120 | static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) |
200 | { | 121 | { |
201 | struct vidi_context *ctx = crtc->ctx; | 122 | struct vidi_context *ctx = crtc->ctx; |
202 | struct vidi_win_data *win_data; | 123 | struct exynos_drm_plane *plane; |
203 | int win = zpos; | 124 | int win = zpos; |
204 | 125 | ||
205 | if (ctx->suspended) | 126 | if (ctx->suspended) |
@@ -211,11 +132,11 @@ static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
211 | if (win < 0 || win >= WINDOWS_NR) | 132 | if (win < 0 || win >= WINDOWS_NR) |
212 | return; | 133 | return; |
213 | 134 | ||
214 | win_data = &ctx->win_data[win]; | 135 | plane = &ctx->planes[win]; |
215 | 136 | ||
216 | win_data->enabled = true; | 137 | plane->enabled = true; |
217 | 138 | ||
218 | DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr); | 139 | DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr); |
219 | 140 | ||
220 | if (ctx->vblank_on) | 141 | if (ctx->vblank_on) |
221 | schedule_work(&ctx->work); | 142 | schedule_work(&ctx->work); |
@@ -224,7 +145,7 @@ static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
224 | static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos) | 145 | static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
225 | { | 146 | { |
226 | struct vidi_context *ctx = crtc->ctx; | 147 | struct vidi_context *ctx = crtc->ctx; |
227 | struct vidi_win_data *win_data; | 148 | struct exynos_drm_plane *plane; |
228 | int win = zpos; | 149 | int win = zpos; |
229 | 150 | ||
230 | if (win == DEFAULT_ZPOS) | 151 | if (win == DEFAULT_ZPOS) |
@@ -233,14 +154,17 @@ static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
233 | if (win < 0 || win >= WINDOWS_NR) | 154 | if (win < 0 || win >= WINDOWS_NR) |
234 | return; | 155 | return; |
235 | 156 | ||
236 | win_data = &ctx->win_data[win]; | 157 | plane = &ctx->planes[win]; |
237 | win_data->enabled = false; | 158 | plane->enabled = false; |
238 | 159 | ||
239 | /* TODO. */ | 160 | /* TODO. */ |
240 | } | 161 | } |
241 | 162 | ||
242 | static int vidi_power_on(struct vidi_context *ctx, bool enable) | 163 | static int vidi_power_on(struct vidi_context *ctx, bool enable) |
243 | { | 164 | { |
165 | struct exynos_drm_plane *plane; | ||
166 | int i; | ||
167 | |||
244 | DRM_DEBUG_KMS("%s\n", __FILE__); | 168 | DRM_DEBUG_KMS("%s\n", __FILE__); |
245 | 169 | ||
246 | if (enable != false && enable != true) | 170 | if (enable != false && enable != true) |
@@ -253,7 +177,11 @@ static int vidi_power_on(struct vidi_context *ctx, bool enable) | |||
253 | if (test_and_clear_bit(0, &ctx->irq_flags)) | 177 | if (test_and_clear_bit(0, &ctx->irq_flags)) |
254 | vidi_enable_vblank(ctx->crtc); | 178 | vidi_enable_vblank(ctx->crtc); |
255 | 179 | ||
256 | vidi_apply(ctx); | 180 | for (i = 0; i < WINDOWS_NR; i++) { |
181 | plane = &ctx->planes[i]; | ||
182 | if (plane->enabled) | ||
183 | vidi_win_commit(ctx->crtc, i); | ||
184 | } | ||
257 | } else { | 185 | } else { |
258 | ctx->suspended = true; | 186 | ctx->suspended = true; |
259 | } | 187 | } |
@@ -301,7 +229,6 @@ static struct exynos_drm_crtc_ops vidi_crtc_ops = { | |||
301 | .dpms = vidi_dpms, | 229 | .dpms = vidi_dpms, |
302 | .enable_vblank = vidi_enable_vblank, | 230 | .enable_vblank = vidi_enable_vblank, |
303 | .disable_vblank = vidi_disable_vblank, | 231 | .disable_vblank = vidi_disable_vblank, |
304 | .win_mode_set = vidi_win_mode_set, | ||
305 | .win_commit = vidi_win_commit, | 232 | .win_commit = vidi_win_commit, |
306 | .win_disable = vidi_win_disable, | 233 | .win_disable = vidi_win_disable, |
307 | }; | 234 | }; |
@@ -543,12 +470,24 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) | |||
543 | { | 470 | { |
544 | struct vidi_context *ctx = dev_get_drvdata(dev); | 471 | struct vidi_context *ctx = dev_get_drvdata(dev); |
545 | struct drm_device *drm_dev = data; | 472 | struct drm_device *drm_dev = data; |
546 | int ret; | 473 | struct exynos_drm_plane *exynos_plane; |
474 | enum drm_plane_type type; | ||
475 | int zpos, ret; | ||
547 | 476 | ||
548 | vidi_ctx_initialize(ctx, drm_dev); | 477 | vidi_ctx_initialize(ctx, drm_dev); |
549 | 478 | ||
550 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, | 479 | for (zpos = 0; zpos < WINDOWS_NR; zpos++) { |
551 | EXYNOS_DISPLAY_TYPE_VIDI, | 480 | type = (zpos == ctx->default_win) ? DRM_PLANE_TYPE_PRIMARY : |
481 | DRM_PLANE_TYPE_OVERLAY; | ||
482 | ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], | ||
483 | 1 << ctx->pipe, type); | ||
484 | if (ret) | ||
485 | return ret; | ||
486 | } | ||
487 | |||
488 | exynos_plane = &ctx->planes[ctx->default_win]; | ||
489 | ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, | ||
490 | ctx->pipe, EXYNOS_DISPLAY_TYPE_VIDI, | ||
552 | &vidi_crtc_ops, ctx); | 491 | &vidi_crtc_ops, ctx); |
553 | if (IS_ERR(ctx->crtc)) { | 492 | if (IS_ERR(ctx->crtc)) { |
554 | DRM_ERROR("failed to create crtc.\n"); | 493 | DRM_ERROR("failed to create crtc.\n"); |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 2e3bc57ea50e..d181cb1ce71a 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -37,35 +37,13 @@ | |||
37 | 37 | ||
38 | #include "exynos_drm_drv.h" | 38 | #include "exynos_drm_drv.h" |
39 | #include "exynos_drm_crtc.h" | 39 | #include "exynos_drm_crtc.h" |
40 | #include "exynos_drm_plane.h" | ||
40 | #include "exynos_drm_iommu.h" | 41 | #include "exynos_drm_iommu.h" |
41 | #include "exynos_mixer.h" | 42 | #include "exynos_mixer.h" |
42 | 43 | ||
43 | #define MIXER_WIN_NR 3 | 44 | #define MIXER_WIN_NR 3 |
44 | #define MIXER_DEFAULT_WIN 0 | 45 | #define MIXER_DEFAULT_WIN 0 |
45 | 46 | ||
46 | struct hdmi_win_data { | ||
47 | dma_addr_t dma_addr; | ||
48 | dma_addr_t chroma_dma_addr; | ||
49 | uint32_t pixel_format; | ||
50 | unsigned int bpp; | ||
51 | unsigned int crtc_x; | ||
52 | unsigned int crtc_y; | ||
53 | unsigned int crtc_width; | ||
54 | unsigned int crtc_height; | ||
55 | unsigned int fb_x; | ||
56 | unsigned int fb_y; | ||
57 | unsigned int fb_width; | ||
58 | unsigned int fb_pitch; | ||
59 | unsigned int fb_height; | ||
60 | unsigned int src_width; | ||
61 | unsigned int src_height; | ||
62 | unsigned int mode_width; | ||
63 | unsigned int mode_height; | ||
64 | unsigned int scan_flags; | ||
65 | bool enabled; | ||
66 | bool resume; | ||
67 | }; | ||
68 | |||
69 | struct mixer_resources { | 47 | struct mixer_resources { |
70 | int irq; | 48 | int irq; |
71 | void __iomem *mixer_regs; | 49 | void __iomem *mixer_regs; |
@@ -90,6 +68,7 @@ struct mixer_context { | |||
90 | struct device *dev; | 68 | struct device *dev; |
91 | struct drm_device *drm_dev; | 69 | struct drm_device *drm_dev; |
92 | struct exynos_drm_crtc *crtc; | 70 | struct exynos_drm_crtc *crtc; |
71 | struct exynos_drm_plane planes[MIXER_WIN_NR]; | ||
93 | int pipe; | 72 | int pipe; |
94 | bool interlace; | 73 | bool interlace; |
95 | bool powered; | 74 | bool powered; |
@@ -99,7 +78,6 @@ struct mixer_context { | |||
99 | 78 | ||
100 | struct mutex mixer_mutex; | 79 | struct mutex mixer_mutex; |
101 | struct mixer_resources mixer_res; | 80 | struct mixer_resources mixer_res; |
102 | struct hdmi_win_data win_data[MIXER_WIN_NR]; | ||
103 | enum mixer_version_id mxr_ver; | 81 | enum mixer_version_id mxr_ver; |
104 | wait_queue_head_t wait_vsync_queue; | 82 | wait_queue_head_t wait_vsync_queue; |
105 | atomic_t wait_vsync_event; | 83 | atomic_t wait_vsync_event; |
@@ -403,7 +381,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
403 | { | 381 | { |
404 | struct mixer_resources *res = &ctx->mixer_res; | 382 | struct mixer_resources *res = &ctx->mixer_res; |
405 | unsigned long flags; | 383 | unsigned long flags; |
406 | struct hdmi_win_data *win_data; | 384 | struct exynos_drm_plane *plane; |
407 | unsigned int x_ratio, y_ratio; | 385 | unsigned int x_ratio, y_ratio; |
408 | unsigned int buf_num = 1; | 386 | unsigned int buf_num = 1; |
409 | dma_addr_t luma_addr[2], chroma_addr[2]; | 387 | dma_addr_t luma_addr[2], chroma_addr[2]; |
@@ -411,9 +389,9 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
411 | bool crcb_mode = false; | 389 | bool crcb_mode = false; |
412 | u32 val; | 390 | u32 val; |
413 | 391 | ||
414 | win_data = &ctx->win_data[win]; | 392 | plane = &ctx->planes[win]; |
415 | 393 | ||
416 | switch (win_data->pixel_format) { | 394 | switch (plane->pixel_format) { |
417 | case DRM_FORMAT_NV12: | 395 | case DRM_FORMAT_NV12: |
418 | crcb_mode = false; | 396 | crcb_mode = false; |
419 | buf_num = 2; | 397 | buf_num = 2; |
@@ -421,35 +399,35 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
421 | /* TODO: single buffer format NV12, NV21 */ | 399 | /* TODO: single buffer format NV12, NV21 */ |
422 | default: | 400 | default: |
423 | /* ignore pixel format at disable time */ | 401 | /* ignore pixel format at disable time */ |
424 | if (!win_data->dma_addr) | 402 | if (!plane->dma_addr[0]) |
425 | break; | 403 | break; |
426 | 404 | ||
427 | DRM_ERROR("pixel format for vp is wrong [%d].\n", | 405 | DRM_ERROR("pixel format for vp is wrong [%d].\n", |
428 | win_data->pixel_format); | 406 | plane->pixel_format); |
429 | return; | 407 | return; |
430 | } | 408 | } |
431 | 409 | ||
432 | /* scaling feature: (src << 16) / dst */ | 410 | /* scaling feature: (src << 16) / dst */ |
433 | x_ratio = (win_data->src_width << 16) / win_data->crtc_width; | 411 | x_ratio = (plane->src_width << 16) / plane->crtc_width; |
434 | y_ratio = (win_data->src_height << 16) / win_data->crtc_height; | 412 | y_ratio = (plane->src_height << 16) / plane->crtc_height; |
435 | 413 | ||
436 | if (buf_num == 2) { | 414 | if (buf_num == 2) { |
437 | luma_addr[0] = win_data->dma_addr; | 415 | luma_addr[0] = plane->dma_addr[0]; |
438 | chroma_addr[0] = win_data->chroma_dma_addr; | 416 | chroma_addr[0] = plane->dma_addr[1]; |
439 | } else { | 417 | } else { |
440 | luma_addr[0] = win_data->dma_addr; | 418 | luma_addr[0] = plane->dma_addr[0]; |
441 | chroma_addr[0] = win_data->dma_addr | 419 | chroma_addr[0] = plane->dma_addr[0] |
442 | + (win_data->fb_pitch * win_data->fb_height); | 420 | + (plane->pitch * plane->fb_height); |
443 | } | 421 | } |
444 | 422 | ||
445 | if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) { | 423 | if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) { |
446 | ctx->interlace = true; | 424 | ctx->interlace = true; |
447 | if (tiled_mode) { | 425 | if (tiled_mode) { |
448 | luma_addr[1] = luma_addr[0] + 0x40; | 426 | luma_addr[1] = luma_addr[0] + 0x40; |
449 | chroma_addr[1] = chroma_addr[0] + 0x40; | 427 | chroma_addr[1] = chroma_addr[0] + 0x40; |
450 | } else { | 428 | } else { |
451 | luma_addr[1] = luma_addr[0] + win_data->fb_pitch; | 429 | luma_addr[1] = luma_addr[0] + plane->pitch; |
452 | chroma_addr[1] = chroma_addr[0] + win_data->fb_pitch; | 430 | chroma_addr[1] = chroma_addr[0] + plane->pitch; |
453 | } | 431 | } |
454 | } else { | 432 | } else { |
455 | ctx->interlace = false; | 433 | ctx->interlace = false; |
@@ -470,26 +448,26 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
470 | vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); | 448 | vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK); |
471 | 449 | ||
472 | /* setting size of input image */ | 450 | /* setting size of input image */ |
473 | vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_pitch) | | 451 | vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(plane->pitch) | |
474 | VP_IMG_VSIZE(win_data->fb_height)); | 452 | VP_IMG_VSIZE(plane->fb_height)); |
475 | /* chroma height has to reduced by 2 to avoid chroma distorions */ | 453 | /* chroma height has to reduced by 2 to avoid chroma distorions */ |
476 | vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_pitch) | | 454 | vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(plane->pitch) | |
477 | VP_IMG_VSIZE(win_data->fb_height / 2)); | 455 | VP_IMG_VSIZE(plane->fb_height / 2)); |
478 | 456 | ||
479 | vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width); | 457 | vp_reg_write(res, VP_SRC_WIDTH, plane->src_width); |
480 | vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height); | 458 | vp_reg_write(res, VP_SRC_HEIGHT, plane->src_height); |
481 | vp_reg_write(res, VP_SRC_H_POSITION, | 459 | vp_reg_write(res, VP_SRC_H_POSITION, |
482 | VP_SRC_H_POSITION_VAL(win_data->fb_x)); | 460 | VP_SRC_H_POSITION_VAL(plane->fb_x)); |
483 | vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y); | 461 | vp_reg_write(res, VP_SRC_V_POSITION, plane->fb_y); |
484 | 462 | ||
485 | vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width); | 463 | vp_reg_write(res, VP_DST_WIDTH, plane->crtc_width); |
486 | vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x); | 464 | vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x); |
487 | if (ctx->interlace) { | 465 | if (ctx->interlace) { |
488 | vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2); | 466 | vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_height / 2); |
489 | vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2); | 467 | vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2); |
490 | } else { | 468 | } else { |
491 | vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height); | 469 | vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_height); |
492 | vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y); | 470 | vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y); |
493 | } | 471 | } |
494 | 472 | ||
495 | vp_reg_write(res, VP_H_RATIO, x_ratio); | 473 | vp_reg_write(res, VP_H_RATIO, x_ratio); |
@@ -503,8 +481,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win) | |||
503 | vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); | 481 | vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]); |
504 | vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); | 482 | vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]); |
505 | 483 | ||
506 | mixer_cfg_scan(ctx, win_data->mode_height); | 484 | mixer_cfg_scan(ctx, plane->mode_height); |
507 | mixer_cfg_rgb_fmt(ctx, win_data->mode_height); | 485 | mixer_cfg_rgb_fmt(ctx, plane->mode_height); |
508 | mixer_cfg_layer(ctx, win, true); | 486 | mixer_cfg_layer(ctx, win, true); |
509 | mixer_run(ctx); | 487 | mixer_run(ctx); |
510 | 488 | ||
@@ -525,21 +503,21 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) | |||
525 | { | 503 | { |
526 | struct mixer_resources *res = &ctx->mixer_res; | 504 | struct mixer_resources *res = &ctx->mixer_res; |
527 | unsigned long flags; | 505 | unsigned long flags; |
528 | struct hdmi_win_data *win_data; | 506 | struct exynos_drm_plane *plane; |
529 | unsigned int x_ratio, y_ratio; | 507 | unsigned int x_ratio, y_ratio; |
530 | unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; | 508 | unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; |
531 | dma_addr_t dma_addr; | 509 | dma_addr_t dma_addr; |
532 | unsigned int fmt; | 510 | unsigned int fmt; |
533 | u32 val; | 511 | u32 val; |
534 | 512 | ||
535 | win_data = &ctx->win_data[win]; | 513 | plane = &ctx->planes[win]; |
536 | 514 | ||
537 | #define RGB565 4 | 515 | #define RGB565 4 |
538 | #define ARGB1555 5 | 516 | #define ARGB1555 5 |
539 | #define ARGB4444 6 | 517 | #define ARGB4444 6 |
540 | #define ARGB8888 7 | 518 | #define ARGB8888 7 |
541 | 519 | ||
542 | switch (win_data->bpp) { | 520 | switch (plane->bpp) { |
543 | case 16: | 521 | case 16: |
544 | fmt = ARGB4444; | 522 | fmt = ARGB4444; |
545 | break; | 523 | break; |
@@ -554,17 +532,17 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) | |||
554 | x_ratio = 0; | 532 | x_ratio = 0; |
555 | y_ratio = 0; | 533 | y_ratio = 0; |
556 | 534 | ||
557 | dst_x_offset = win_data->crtc_x; | 535 | dst_x_offset = plane->crtc_x; |
558 | dst_y_offset = win_data->crtc_y; | 536 | dst_y_offset = plane->crtc_y; |
559 | 537 | ||
560 | /* converting dma address base and source offset */ | 538 | /* converting dma address base and source offset */ |
561 | dma_addr = win_data->dma_addr | 539 | dma_addr = plane->dma_addr[0] |
562 | + (win_data->fb_x * win_data->bpp >> 3) | 540 | + (plane->fb_x * plane->bpp >> 3) |
563 | + (win_data->fb_y * win_data->fb_pitch); | 541 | + (plane->fb_y * plane->pitch); |
564 | src_x_offset = 0; | 542 | src_x_offset = 0; |
565 | src_y_offset = 0; | 543 | src_y_offset = 0; |
566 | 544 | ||
567 | if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) | 545 | if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) |
568 | ctx->interlace = true; | 546 | ctx->interlace = true; |
569 | else | 547 | else |
570 | ctx->interlace = false; | 548 | ctx->interlace = false; |
@@ -578,18 +556,18 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) | |||
578 | 556 | ||
579 | /* setup geometry */ | 557 | /* setup geometry */ |
580 | mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), | 558 | mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), |
581 | win_data->fb_pitch / (win_data->bpp >> 3)); | 559 | plane->pitch / (plane->bpp >> 3)); |
582 | 560 | ||
583 | /* setup display size */ | 561 | /* setup display size */ |
584 | if (ctx->mxr_ver == MXR_VER_128_0_0_184 && | 562 | if (ctx->mxr_ver == MXR_VER_128_0_0_184 && |
585 | win == MIXER_DEFAULT_WIN) { | 563 | win == MIXER_DEFAULT_WIN) { |
586 | val = MXR_MXR_RES_HEIGHT(win_data->mode_height); | 564 | val = MXR_MXR_RES_HEIGHT(plane->mode_height); |
587 | val |= MXR_MXR_RES_WIDTH(win_data->mode_width); | 565 | val |= MXR_MXR_RES_WIDTH(plane->mode_width); |
588 | mixer_reg_write(res, MXR_RESOLUTION, val); | 566 | mixer_reg_write(res, MXR_RESOLUTION, val); |
589 | } | 567 | } |
590 | 568 | ||
591 | val = MXR_GRP_WH_WIDTH(win_data->crtc_width); | 569 | val = MXR_GRP_WH_WIDTH(plane->crtc_width); |
592 | val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height); | 570 | val |= MXR_GRP_WH_HEIGHT(plane->crtc_height); |
593 | val |= MXR_GRP_WH_H_SCALE(x_ratio); | 571 | val |= MXR_GRP_WH_H_SCALE(x_ratio); |
594 | val |= MXR_GRP_WH_V_SCALE(y_ratio); | 572 | val |= MXR_GRP_WH_V_SCALE(y_ratio); |
595 | mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); | 573 | mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); |
@@ -607,8 +585,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win) | |||
607 | /* set buffer address to mixer */ | 585 | /* set buffer address to mixer */ |
608 | mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); | 586 | mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr); |
609 | 587 | ||
610 | mixer_cfg_scan(ctx, win_data->mode_height); | 588 | mixer_cfg_scan(ctx, plane->mode_height); |
611 | mixer_cfg_rgb_fmt(ctx, win_data->mode_height); | 589 | mixer_cfg_rgb_fmt(ctx, plane->mode_height); |
612 | mixer_cfg_layer(ctx, win, true); | 590 | mixer_cfg_layer(ctx, win, true); |
613 | 591 | ||
614 | /* layer update mandatory for mixer 16.0.33.0 */ | 592 | /* layer update mandatory for mixer 16.0.33.0 */ |
@@ -920,59 +898,6 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) | |||
920 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); | 898 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); |
921 | } | 899 | } |
922 | 900 | ||
923 | static void mixer_win_mode_set(struct exynos_drm_crtc *crtc, | ||
924 | struct exynos_drm_plane *plane) | ||
925 | { | ||
926 | struct mixer_context *mixer_ctx = crtc->ctx; | ||
927 | struct hdmi_win_data *win_data; | ||
928 | int win; | ||
929 | |||
930 | if (!plane) { | ||
931 | DRM_ERROR("plane is NULL\n"); | ||
932 | return; | ||
933 | } | ||
934 | |||
935 | DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n", | ||
936 | plane->fb_width, plane->fb_height, | ||
937 | plane->fb_x, plane->fb_y, | ||
938 | plane->crtc_width, plane->crtc_height, | ||
939 | plane->crtc_x, plane->crtc_y); | ||
940 | |||
941 | win = plane->zpos; | ||
942 | if (win == DEFAULT_ZPOS) | ||
943 | win = MIXER_DEFAULT_WIN; | ||
944 | |||
945 | if (win < 0 || win >= MIXER_WIN_NR) { | ||
946 | DRM_ERROR("mixer window[%d] is wrong\n", win); | ||
947 | return; | ||
948 | } | ||
949 | |||
950 | win_data = &mixer_ctx->win_data[win]; | ||
951 | |||
952 | win_data->dma_addr = plane->dma_addr[0]; | ||
953 | win_data->chroma_dma_addr = plane->dma_addr[1]; | ||
954 | win_data->pixel_format = plane->pixel_format; | ||
955 | win_data->bpp = plane->bpp; | ||
956 | |||
957 | win_data->crtc_x = plane->crtc_x; | ||
958 | win_data->crtc_y = plane->crtc_y; | ||
959 | win_data->crtc_width = plane->crtc_width; | ||
960 | win_data->crtc_height = plane->crtc_height; | ||
961 | |||
962 | win_data->fb_x = plane->fb_x; | ||
963 | win_data->fb_y = plane->fb_y; | ||
964 | win_data->fb_width = plane->fb_width; | ||
965 | win_data->fb_height = plane->fb_height; | ||
966 | win_data->fb_pitch = plane->pitch; | ||
967 | win_data->src_width = plane->src_width; | ||
968 | win_data->src_height = plane->src_height; | ||
969 | |||
970 | win_data->mode_width = plane->mode_width; | ||
971 | win_data->mode_height = plane->mode_height; | ||
972 | |||
973 | win_data->scan_flags = plane->scan_flag; | ||
974 | } | ||
975 | |||
976 | static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos) | 901 | static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos) |
977 | { | 902 | { |
978 | struct mixer_context *mixer_ctx = crtc->ctx; | 903 | struct mixer_context *mixer_ctx = crtc->ctx; |
@@ -992,7 +917,7 @@ static void mixer_win_commit(struct exynos_drm_crtc *crtc, int zpos) | |||
992 | else | 917 | else |
993 | mixer_graph_buffer(mixer_ctx, win); | 918 | mixer_graph_buffer(mixer_ctx, win); |
994 | 919 | ||
995 | mixer_ctx->win_data[win].enabled = true; | 920 | mixer_ctx->planes[win].enabled = true; |
996 | } | 921 | } |
997 | 922 | ||
998 | static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos) | 923 | static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos) |
@@ -1007,7 +932,7 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
1007 | mutex_lock(&mixer_ctx->mixer_mutex); | 932 | mutex_lock(&mixer_ctx->mixer_mutex); |
1008 | if (!mixer_ctx->powered) { | 933 | if (!mixer_ctx->powered) { |
1009 | mutex_unlock(&mixer_ctx->mixer_mutex); | 934 | mutex_unlock(&mixer_ctx->mixer_mutex); |
1010 | mixer_ctx->win_data[win].resume = false; | 935 | mixer_ctx->planes[win].resume = false; |
1011 | return; | 936 | return; |
1012 | } | 937 | } |
1013 | mutex_unlock(&mixer_ctx->mixer_mutex); | 938 | mutex_unlock(&mixer_ctx->mixer_mutex); |
@@ -1020,7 +945,7 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, int zpos) | |||
1020 | mixer_vsync_set_update(mixer_ctx, true); | 945 | mixer_vsync_set_update(mixer_ctx, true); |
1021 | spin_unlock_irqrestore(&res->reg_slock, flags); | 946 | spin_unlock_irqrestore(&res->reg_slock, flags); |
1022 | 947 | ||
1023 | mixer_ctx->win_data[win].enabled = false; | 948 | mixer_ctx->planes[win].enabled = false; |
1024 | } | 949 | } |
1025 | 950 | ||
1026 | static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) | 951 | static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) |
@@ -1057,12 +982,12 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) | |||
1057 | 982 | ||
1058 | static void mixer_window_suspend(struct mixer_context *ctx) | 983 | static void mixer_window_suspend(struct mixer_context *ctx) |
1059 | { | 984 | { |
1060 | struct hdmi_win_data *win_data; | 985 | struct exynos_drm_plane *plane; |
1061 | int i; | 986 | int i; |
1062 | 987 | ||
1063 | for (i = 0; i < MIXER_WIN_NR; i++) { | 988 | for (i = 0; i < MIXER_WIN_NR; i++) { |
1064 | win_data = &ctx->win_data[i]; | 989 | plane = &ctx->planes[i]; |
1065 | win_data->resume = win_data->enabled; | 990 | plane->resume = plane->enabled; |
1066 | mixer_win_disable(ctx->crtc, i); | 991 | mixer_win_disable(ctx->crtc, i); |
1067 | } | 992 | } |
1068 | mixer_wait_for_vblank(ctx->crtc); | 993 | mixer_wait_for_vblank(ctx->crtc); |
@@ -1070,14 +995,14 @@ static void mixer_window_suspend(struct mixer_context *ctx) | |||
1070 | 995 | ||
1071 | static void mixer_window_resume(struct mixer_context *ctx) | 996 | static void mixer_window_resume(struct mixer_context *ctx) |
1072 | { | 997 | { |
1073 | struct hdmi_win_data *win_data; | 998 | struct exynos_drm_plane *plane; |
1074 | int i; | 999 | int i; |
1075 | 1000 | ||
1076 | for (i = 0; i < MIXER_WIN_NR; i++) { | 1001 | for (i = 0; i < MIXER_WIN_NR; i++) { |
1077 | win_data = &ctx->win_data[i]; | 1002 | plane = &ctx->planes[i]; |
1078 | win_data->enabled = win_data->resume; | 1003 | plane->enabled = plane->resume; |
1079 | win_data->resume = false; | 1004 | plane->resume = false; |
1080 | if (win_data->enabled) | 1005 | if (plane->enabled) |
1081 | mixer_win_commit(ctx->crtc, i); | 1006 | mixer_win_commit(ctx->crtc, i); |
1082 | } | 1007 | } |
1083 | } | 1008 | } |
@@ -1189,7 +1114,6 @@ static struct exynos_drm_crtc_ops mixer_crtc_ops = { | |||
1189 | .enable_vblank = mixer_enable_vblank, | 1114 | .enable_vblank = mixer_enable_vblank, |
1190 | .disable_vblank = mixer_disable_vblank, | 1115 | .disable_vblank = mixer_disable_vblank, |
1191 | .wait_for_vblank = mixer_wait_for_vblank, | 1116 | .wait_for_vblank = mixer_wait_for_vblank, |
1192 | .win_mode_set = mixer_win_mode_set, | ||
1193 | .win_commit = mixer_win_commit, | 1117 | .win_commit = mixer_win_commit, |
1194 | .win_disable = mixer_win_disable, | 1118 | .win_disable = mixer_win_disable, |
1195 | }; | 1119 | }; |
@@ -1253,15 +1177,27 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) | |||
1253 | { | 1177 | { |
1254 | struct mixer_context *ctx = dev_get_drvdata(dev); | 1178 | struct mixer_context *ctx = dev_get_drvdata(dev); |
1255 | struct drm_device *drm_dev = data; | 1179 | struct drm_device *drm_dev = data; |
1256 | int ret; | 1180 | struct exynos_drm_plane *exynos_plane; |
1181 | enum drm_plane_type type; | ||
1182 | int zpos, ret; | ||
1257 | 1183 | ||
1258 | ret = mixer_initialize(ctx, drm_dev); | 1184 | ret = mixer_initialize(ctx, drm_dev); |
1259 | if (ret) | 1185 | if (ret) |
1260 | return ret; | 1186 | return ret; |
1261 | 1187 | ||
1262 | ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe, | 1188 | for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) { |
1263 | EXYNOS_DISPLAY_TYPE_HDMI, | 1189 | type = (zpos == MIXER_DEFAULT_WIN) ? DRM_PLANE_TYPE_PRIMARY : |
1264 | &mixer_crtc_ops, ctx); | 1190 | DRM_PLANE_TYPE_OVERLAY; |
1191 | ret = exynos_plane_init(drm_dev, &ctx->planes[zpos], | ||
1192 | 1 << ctx->pipe, type); | ||
1193 | if (ret) | ||
1194 | return ret; | ||
1195 | } | ||
1196 | |||
1197 | exynos_plane = &ctx->planes[MIXER_DEFAULT_WIN]; | ||
1198 | ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base, | ||
1199 | ctx->pipe, EXYNOS_DISPLAY_TYPE_HDMI, | ||
1200 | &mixer_crtc_ops, ctx); | ||
1265 | if (IS_ERR(ctx->crtc)) { | 1201 | if (IS_ERR(ctx->crtc)) { |
1266 | mixer_ctx_remove(ctx); | 1202 | mixer_ctx_remove(ctx); |
1267 | ret = PTR_ERR(ctx->crtc); | 1203 | ret = PTR_ERR(ctx->crtc); |