aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos7_drm_decon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos7_drm_decon.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c173
1 files changed, 34 insertions, 139 deletions
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 6714e5b193ea..362532afd1a5 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -89,8 +89,9 @@ static void decon_wait_for_vblank(struct exynos_drm_crtc *crtc)
89 DRM_DEBUG_KMS("vblank wait timed out.\n"); 89 DRM_DEBUG_KMS("vblank wait timed out.\n");
90} 90}
91 91
92static void decon_clear_channel(struct decon_context *ctx) 92static void decon_clear_channels(struct exynos_drm_crtc *crtc)
93{ 93{
94 struct decon_context *ctx = crtc->ctx;
94 unsigned int win, ch_enabled = 0; 95 unsigned int win, ch_enabled = 0;
95 96
96 DRM_DEBUG_KMS("%s\n", __FILE__); 97 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -120,27 +121,16 @@ static int decon_ctx_initialize(struct decon_context *ctx,
120 struct drm_device *drm_dev) 121 struct drm_device *drm_dev)
121{ 122{
122 struct exynos_drm_private *priv = drm_dev->dev_private; 123 struct exynos_drm_private *priv = drm_dev->dev_private;
124 int ret;
123 125
124 ctx->drm_dev = drm_dev; 126 ctx->drm_dev = drm_dev;
125 ctx->pipe = priv->pipe++; 127 ctx->pipe = priv->pipe++;
126 128
127 /* attach this sub driver to iommu mapping if supported. */ 129 ret = drm_iommu_attach_device_if_possible(ctx->crtc, drm_dev, ctx->dev);
128 if (is_drm_iommu_supported(ctx->drm_dev)) { 130 if (ret)
129 int ret; 131 priv->pipe--;
130
131 /*
132 * If any channel is already active, iommu will throw
133 * a PAGE FAULT when enabled. So clear any channel if enabled.
134 */
135 decon_clear_channel(ctx);
136 ret = drm_iommu_attach_device(ctx->drm_dev, ctx->dev);
137 if (ret) {
138 DRM_ERROR("drm_iommu_attach failed.\n");
139 return ret;
140 }
141 }
142 132
143 return 0; 133 return ret;
144} 134}
145 135
146static void decon_ctx_remove(struct decon_context *ctx) 136static void decon_ctx_remove(struct decon_context *ctx)
@@ -175,7 +165,7 @@ static bool decon_mode_fixup(struct exynos_drm_crtc *crtc,
175static void decon_commit(struct exynos_drm_crtc *crtc) 165static void decon_commit(struct exynos_drm_crtc *crtc)
176{ 166{
177 struct decon_context *ctx = crtc->ctx; 167 struct decon_context *ctx = crtc->ctx;
178 struct drm_display_mode *mode = &crtc->base.mode; 168 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
179 u32 val, clkdiv; 169 u32 val, clkdiv;
180 170
181 if (ctx->suspended) 171 if (ctx->suspended)
@@ -395,7 +385,7 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
395static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win) 385static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
396{ 386{
397 struct decon_context *ctx = crtc->ctx; 387 struct decon_context *ctx = crtc->ctx;
398 struct drm_display_mode *mode = &crtc->base.mode; 388 struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
399 struct exynos_drm_plane *plane; 389 struct exynos_drm_plane *plane;
400 int padding; 390 int padding;
401 unsigned long val, alpha; 391 unsigned long val, alpha;
@@ -410,11 +400,8 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
410 400
411 plane = &ctx->planes[win]; 401 plane = &ctx->planes[win];
412 402
413 /* If suspended, enable this on resume */ 403 if (ctx->suspended)
414 if (ctx->suspended) {
415 plane->resume = true;
416 return; 404 return;
417 }
418 405
419 /* 406 /*
420 * SHADOWCON/PRTCON register is used for enabling timing. 407 * SHADOWCON/PRTCON register is used for enabling timing.
@@ -506,8 +493,6 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
506 val = readl(ctx->regs + DECON_UPDATE); 493 val = readl(ctx->regs + DECON_UPDATE);
507 val |= DECON_UPDATE_STANDALONE_F; 494 val |= DECON_UPDATE_STANDALONE_F;
508 writel(val, ctx->regs + DECON_UPDATE); 495 writel(val, ctx->regs + DECON_UPDATE);
509
510 plane->enabled = true;
511} 496}
512 497
513static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) 498static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
@@ -521,11 +506,8 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
521 506
522 plane = &ctx->planes[win]; 507 plane = &ctx->planes[win];
523 508
524 if (ctx->suspended) { 509 if (ctx->suspended)
525 /* do not resume this window*/
526 plane->resume = false;
527 return; 510 return;
528 }
529 511
530 /* protect windows */ 512 /* protect windows */
531 decon_shadow_protect_win(ctx, win, true); 513 decon_shadow_protect_win(ctx, win, true);
@@ -541,49 +523,6 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
541 val = readl(ctx->regs + DECON_UPDATE); 523 val = readl(ctx->regs + DECON_UPDATE);
542 val |= DECON_UPDATE_STANDALONE_F; 524 val |= DECON_UPDATE_STANDALONE_F;
543 writel(val, ctx->regs + DECON_UPDATE); 525 writel(val, ctx->regs + DECON_UPDATE);
544
545 plane->enabled = false;
546}
547
548static void decon_window_suspend(struct decon_context *ctx)
549{
550 struct exynos_drm_plane *plane;
551 int i;
552
553 for (i = 0; i < WINDOWS_NR; i++) {
554 plane = &ctx->planes[i];
555 plane->resume = plane->enabled;
556 if (plane->enabled)
557 decon_win_disable(ctx->crtc, i);
558 }
559}
560
561static void decon_window_resume(struct decon_context *ctx)
562{
563 struct exynos_drm_plane *plane;
564 int i;
565
566 for (i = 0; i < WINDOWS_NR; i++) {
567 plane = &ctx->planes[i];
568 plane->enabled = plane->resume;
569 plane->resume = false;
570 }
571}
572
573static void decon_apply(struct decon_context *ctx)
574{
575 struct exynos_drm_plane *plane;
576 int i;
577
578 for (i = 0; i < WINDOWS_NR; i++) {
579 plane = &ctx->planes[i];
580 if (plane->enabled)
581 decon_win_commit(ctx->crtc, i);
582 else
583 decon_win_disable(ctx->crtc, i);
584 }
585
586 decon_commit(ctx->crtc);
587} 526}
588 527
589static void decon_init(struct decon_context *ctx) 528static void decon_init(struct decon_context *ctx)
@@ -603,12 +542,13 @@ static void decon_init(struct decon_context *ctx)
603 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0)); 542 writel(VIDCON1_VCLK_HOLD, ctx->regs + VIDCON1(0));
604} 543}
605 544
606static int decon_poweron(struct decon_context *ctx) 545static void decon_enable(struct exynos_drm_crtc *crtc)
607{ 546{
547 struct decon_context *ctx = crtc->ctx;
608 int ret; 548 int ret;
609 549
610 if (!ctx->suspended) 550 if (!ctx->suspended)
611 return 0; 551 return;
612 552
613 ctx->suspended = false; 553 ctx->suspended = false;
614 554
@@ -617,68 +557,51 @@ static int decon_poweron(struct decon_context *ctx)
617 ret = clk_prepare_enable(ctx->pclk); 557 ret = clk_prepare_enable(ctx->pclk);
618 if (ret < 0) { 558 if (ret < 0) {
619 DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret); 559 DRM_ERROR("Failed to prepare_enable the pclk [%d]\n", ret);
620 goto pclk_err; 560 return;
621 } 561 }
622 562
623 ret = clk_prepare_enable(ctx->aclk); 563 ret = clk_prepare_enable(ctx->aclk);
624 if (ret < 0) { 564 if (ret < 0) {
625 DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret); 565 DRM_ERROR("Failed to prepare_enable the aclk [%d]\n", ret);
626 goto aclk_err; 566 return;
627 } 567 }
628 568
629 ret = clk_prepare_enable(ctx->eclk); 569 ret = clk_prepare_enable(ctx->eclk);
630 if (ret < 0) { 570 if (ret < 0) {
631 DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret); 571 DRM_ERROR("Failed to prepare_enable the eclk [%d]\n", ret);
632 goto eclk_err; 572 return;
633 } 573 }
634 574
635 ret = clk_prepare_enable(ctx->vclk); 575 ret = clk_prepare_enable(ctx->vclk);
636 if (ret < 0) { 576 if (ret < 0) {
637 DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret); 577 DRM_ERROR("Failed to prepare_enable the vclk [%d]\n", ret);
638 goto vclk_err; 578 return;
639 } 579 }
640 580
641 decon_init(ctx); 581 decon_init(ctx);
642 582
643 /* if vblank was enabled status, enable it again. */ 583 /* if vblank was enabled status, enable it again. */
644 if (test_and_clear_bit(0, &ctx->irq_flags)) { 584 if (test_and_clear_bit(0, &ctx->irq_flags))
645 ret = decon_enable_vblank(ctx->crtc); 585 decon_enable_vblank(ctx->crtc);
646 if (ret) {
647 DRM_ERROR("Failed to re-enable vblank [%d]\n", ret);
648 goto err;
649 }
650 }
651
652 decon_window_resume(ctx);
653
654 decon_apply(ctx);
655 586
656 return 0; 587 decon_commit(ctx->crtc);
657
658err:
659 clk_disable_unprepare(ctx->vclk);
660vclk_err:
661 clk_disable_unprepare(ctx->eclk);
662eclk_err:
663 clk_disable_unprepare(ctx->aclk);
664aclk_err:
665 clk_disable_unprepare(ctx->pclk);
666pclk_err:
667 ctx->suspended = true;
668 return ret;
669} 588}
670 589
671static int decon_poweroff(struct decon_context *ctx) 590static void decon_disable(struct exynos_drm_crtc *crtc)
672{ 591{
592 struct decon_context *ctx = crtc->ctx;
593 int i;
594
673 if (ctx->suspended) 595 if (ctx->suspended)
674 return 0; 596 return;
675 597
676 /* 598 /*
677 * We need to make sure that all windows are disabled before we 599 * We need to make sure that all windows are disabled before we
678 * suspend that connector. Otherwise we might try to scan from 600 * suspend that connector. Otherwise we might try to scan from
679 * a destroyed buffer later. 601 * a destroyed buffer later.
680 */ 602 */
681 decon_window_suspend(ctx); 603 for (i = 0; i < WINDOWS_NR; i++)
604 decon_win_disable(crtc, i);
682 605
683 clk_disable_unprepare(ctx->vclk); 606 clk_disable_unprepare(ctx->vclk);
684 clk_disable_unprepare(ctx->eclk); 607 clk_disable_unprepare(ctx->eclk);
@@ -688,30 +611,11 @@ static int decon_poweroff(struct decon_context *ctx)
688 pm_runtime_put_sync(ctx->dev); 611 pm_runtime_put_sync(ctx->dev);
689 612
690 ctx->suspended = true; 613 ctx->suspended = true;
691 return 0;
692}
693
694static void decon_dpms(struct exynos_drm_crtc *crtc, int mode)
695{
696 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
697
698 switch (mode) {
699 case DRM_MODE_DPMS_ON:
700 decon_poweron(crtc->ctx);
701 break;
702 case DRM_MODE_DPMS_STANDBY:
703 case DRM_MODE_DPMS_SUSPEND:
704 case DRM_MODE_DPMS_OFF:
705 decon_poweroff(crtc->ctx);
706 break;
707 default:
708 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
709 break;
710 }
711} 614}
712 615
713static const struct exynos_drm_crtc_ops decon_crtc_ops = { 616static const struct exynos_drm_crtc_ops decon_crtc_ops = {
714 .dpms = decon_dpms, 617 .enable = decon_enable,
618 .disable = decon_disable,
715 .mode_fixup = decon_mode_fixup, 619 .mode_fixup = decon_mode_fixup,
716 .commit = decon_commit, 620 .commit = decon_commit,
717 .enable_vblank = decon_enable_vblank, 621 .enable_vblank = decon_enable_vblank,
@@ -719,6 +623,7 @@ static const struct exynos_drm_crtc_ops decon_crtc_ops = {
719 .wait_for_vblank = decon_wait_for_vblank, 623 .wait_for_vblank = decon_wait_for_vblank,
720 .win_commit = decon_win_commit, 624 .win_commit = decon_win_commit,
721 .win_disable = decon_win_disable, 625 .win_disable = decon_win_disable,
626 .clear_channels = decon_clear_channels,
722}; 627};
723 628
724 629
@@ -796,7 +701,7 @@ static void decon_unbind(struct device *dev, struct device *master,
796{ 701{
797 struct decon_context *ctx = dev_get_drvdata(dev); 702 struct decon_context *ctx = dev_get_drvdata(dev);
798 703
799 decon_dpms(ctx->crtc, DRM_MODE_DPMS_OFF); 704 decon_disable(ctx->crtc);
800 705
801 if (ctx->display) 706 if (ctx->display)
802 exynos_dpi_remove(ctx->display); 707 exynos_dpi_remove(ctx->display);
@@ -824,11 +729,6 @@ static int decon_probe(struct platform_device *pdev)
824 if (!ctx) 729 if (!ctx)
825 return -ENOMEM; 730 return -ENOMEM;
826 731
827 ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
828 EXYNOS_DISPLAY_TYPE_LCD);
829 if (ret)
830 return ret;
831
832 ctx->dev = dev; 732 ctx->dev = dev;
833 ctx->suspended = true; 733 ctx->suspended = true;
834 734
@@ -838,10 +738,8 @@ static int decon_probe(struct platform_device *pdev)
838 of_node_put(i80_if_timings); 738 of_node_put(i80_if_timings);
839 739
840 ctx->regs = of_iomap(dev->of_node, 0); 740 ctx->regs = of_iomap(dev->of_node, 0);
841 if (!ctx->regs) { 741 if (!ctx->regs)
842 ret = -ENOMEM; 742 return -ENOMEM;
843 goto err_del_component;
844 }
845 743
846 ctx->pclk = devm_clk_get(dev, "pclk_decon0"); 744 ctx->pclk = devm_clk_get(dev, "pclk_decon0");
847 if (IS_ERR(ctx->pclk)) { 745 if (IS_ERR(ctx->pclk)) {
@@ -911,8 +809,6 @@ err_disable_pm_runtime:
911err_iounmap: 809err_iounmap:
912 iounmap(ctx->regs); 810 iounmap(ctx->regs);
913 811
914err_del_component:
915 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
916 return ret; 812 return ret;
917} 813}
918 814
@@ -925,7 +821,6 @@ static int decon_remove(struct platform_device *pdev)
925 iounmap(ctx->regs); 821 iounmap(ctx->regs);
926 822
927 component_del(&pdev->dev, &decon_component_ops); 823 component_del(&pdev->dev, &decon_component_ops);
928 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
929 824
930 return 0; 825 return 0;
931} 826}