aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2015-06-12 07:34:28 -0400
committerInki Dae <daeinki@gmail.com>2015-06-19 11:32:58 -0400
commitc329f667ba3392c3270902335690f548a2778374 (patch)
tree4cbf0e227b157c878fa1e72f04dc5e08eb9a9a60
parentba4b77c4856a26b926d3892511568b9f4c6102e1 (diff)
drm/exynos: remove chained calls to enable
With atomic modesetting all the control for CRTC, Planes, Encoders and Connectors should come from DRM core, so the driver is not allowed to enable or disable planes from inside the crtc_enable()/disable() call. But it needs to disable planes with crtc_disable in exynos driver internally. Because crtc is disabled before plane is disabled, it means plane_disable just returns without any register changes, then we cannot be sure setting register to disable plane when crtc is disable. This patch removes this chainned calls to enable plane from exynos hw drivers code letting only DRM core touch planes except to disable plane. Also it leads eliminable enabled and resume of struct exynos_drm_plane. Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c63
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c63
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c25
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c38
5 files changed, 16 insertions, 178 deletions
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 7d0955d9bf94..2b9221cc811f 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -410,11 +410,8 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
410 410
411 plane = &ctx->planes[win]; 411 plane = &ctx->planes[win];
412 412
413 /* If suspended, enable this on resume */ 413 if (ctx->suspended)
414 if (ctx->suspended) {
415 plane->resume = true;
416 return; 414 return;
417 }
418 415
419 /* 416 /*
420 * SHADOWCON/PRTCON register is used for enabling timing. 417 * SHADOWCON/PRTCON register is used for enabling timing.
@@ -506,8 +503,6 @@ static void decon_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
506 val = readl(ctx->regs + DECON_UPDATE); 503 val = readl(ctx->regs + DECON_UPDATE);
507 val |= DECON_UPDATE_STANDALONE_F; 504 val |= DECON_UPDATE_STANDALONE_F;
508 writel(val, ctx->regs + DECON_UPDATE); 505 writel(val, ctx->regs + DECON_UPDATE);
509
510 plane->enabled = true;
511} 506}
512 507
513static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) 508static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
@@ -521,11 +516,8 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
521 516
522 plane = &ctx->planes[win]; 517 plane = &ctx->planes[win];
523 518
524 if (ctx->suspended) { 519 if (ctx->suspended)
525 /* do not resume this window*/
526 plane->resume = false;
527 return; 520 return;
528 }
529 521
530 /* protect windows */ 522 /* protect windows */
531 decon_shadow_protect_win(ctx, win, true); 523 decon_shadow_protect_win(ctx, win, true);
@@ -541,49 +533,6 @@ static void decon_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
541 val = readl(ctx->regs + DECON_UPDATE); 533 val = readl(ctx->regs + DECON_UPDATE);
542 val |= DECON_UPDATE_STANDALONE_F; 534 val |= DECON_UPDATE_STANDALONE_F;
543 writel(val, ctx->regs + DECON_UPDATE); 535 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} 536}
588 537
589static void decon_init(struct decon_context *ctx) 538static void decon_init(struct decon_context *ctx)
@@ -645,14 +594,13 @@ static void decon_enable(struct exynos_drm_crtc *crtc)
645 if (test_and_clear_bit(0, &ctx->irq_flags)) 594 if (test_and_clear_bit(0, &ctx->irq_flags))
646 decon_enable_vblank(ctx->crtc); 595 decon_enable_vblank(ctx->crtc);
647 596
648 decon_window_resume(ctx); 597 decon_commit(ctx->crtc);
649
650 decon_apply(ctx);
651} 598}
652 599
653static void decon_disable(struct exynos_drm_crtc *crtc) 600static void decon_disable(struct exynos_drm_crtc *crtc)
654{ 601{
655 struct decon_context *ctx = crtc->ctx; 602 struct decon_context *ctx = crtc->ctx;
603 int i;
656 604
657 if (ctx->suspended) 605 if (ctx->suspended)
658 return; 606 return;
@@ -662,7 +610,8 @@ static void decon_disable(struct exynos_drm_crtc *crtc)
662 * suspend that connector. Otherwise we might try to scan from 610 * suspend that connector. Otherwise we might try to scan from
663 * a destroyed buffer later. 611 * a destroyed buffer later.
664 */ 612 */
665 decon_window_suspend(ctx); 613 for (i = 0; i < WINDOWS_NR; i++)
614 decon_win_disable(crtc, i);
666 615
667 clk_disable_unprepare(ctx->vclk); 616 clk_disable_unprepare(ctx->vclk);
668 clk_disable_unprepare(ctx->eclk); 617 clk_disable_unprepare(ctx->eclk);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 6b4958bd4fc3..a3845693c634 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -64,8 +64,6 @@ enum exynos_drm_output_type {
64 * @dma_addr: array of bus(accessed by dma) address to the memory region 64 * @dma_addr: array of bus(accessed by dma) address to the memory region
65 * allocated for a overlay. 65 * allocated for a overlay.
66 * @zpos: order of overlay layer(z position). 66 * @zpos: order of overlay layer(z position).
67 * @enabled: enabled or not.
68 * @resume: to resume or not.
69 * 67 *
70 * this structure is common to exynos SoC and its contents would be copied 68 * this structure is common to exynos SoC and its contents would be copied
71 * to hardware specific overlay info. 69 * to hardware specific overlay info.
@@ -94,9 +92,6 @@ struct exynos_drm_plane {
94 uint32_t pixel_format; 92 uint32_t pixel_format;
95 dma_addr_t dma_addr[MAX_FB_BUFFER]; 93 dma_addr_t dma_addr[MAX_FB_BUFFER];
96 unsigned int zpos; 94 unsigned int zpos;
97
98 bool enabled:1;
99 bool resume:1;
100}; 95};
101 96
102/* 97/*
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 9cce2bca74c4..eafcf07987a6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -634,11 +634,8 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
634 634
635 plane = &ctx->planes[win]; 635 plane = &ctx->planes[win];
636 636
637 /* If suspended, enable this on resume */ 637 if (ctx->suspended)
638 if (ctx->suspended) {
639 plane->resume = true;
640 return; 638 return;
641 }
642 639
643 /* 640 /*
644 * SHADOWCON/PRTCON register is used for enabling timing. 641 * SHADOWCON/PRTCON register is used for enabling timing.
@@ -728,8 +725,6 @@ static void fimd_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
728 /* Enable DMA channel and unprotect windows */ 725 /* Enable DMA channel and unprotect windows */
729 fimd_shadow_protect_win(ctx, win, false); 726 fimd_shadow_protect_win(ctx, win, false);
730 727
731 plane->enabled = true;
732
733 if (ctx->i80_if) 728 if (ctx->i80_if)
734 atomic_set(&ctx->win_updated, 1); 729 atomic_set(&ctx->win_updated, 1);
735} 730}
@@ -744,11 +739,8 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
744 739
745 plane = &ctx->planes[win]; 740 plane = &ctx->planes[win];
746 741
747 if (ctx->suspended) { 742 if (ctx->suspended)
748 /* do not resume this window*/
749 plane->resume = false;
750 return; 743 return;
751 }
752 744
753 /* protect windows */ 745 /* protect windows */
754 fimd_shadow_protect_win(ctx, win, true); 746 fimd_shadow_protect_win(ctx, win, true);
@@ -760,49 +752,6 @@ static void fimd_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
760 752
761 /* unprotect windows */ 753 /* unprotect windows */
762 fimd_shadow_protect_win(ctx, win, false); 754 fimd_shadow_protect_win(ctx, win, false);
763
764 plane->enabled = false;
765}
766
767static void fimd_window_suspend(struct fimd_context *ctx)
768{
769 struct exynos_drm_plane *plane;
770 int i;
771
772 for (i = 0; i < WINDOWS_NR; i++) {
773 plane = &ctx->planes[i];
774 plane->resume = plane->enabled;
775 if (plane->enabled)
776 fimd_win_disable(ctx->crtc, i);
777 }
778}
779
780static void fimd_window_resume(struct fimd_context *ctx)
781{
782 struct exynos_drm_plane *plane;
783 int i;
784
785 for (i = 0; i < WINDOWS_NR; i++) {
786 plane = &ctx->planes[i];
787 plane->enabled = plane->resume;
788 plane->resume = false;
789 }
790}
791
792static void fimd_apply(struct fimd_context *ctx)
793{
794 struct exynos_drm_plane *plane;
795 int i;
796
797 for (i = 0; i < WINDOWS_NR; i++) {
798 plane = &ctx->planes[i];
799 if (plane->enabled)
800 fimd_win_commit(ctx->crtc, i);
801 else
802 fimd_win_disable(ctx->crtc, i);
803 }
804
805 fimd_commit(ctx->crtc);
806} 755}
807 756
808static void fimd_enable(struct exynos_drm_crtc *crtc) 757static void fimd_enable(struct exynos_drm_crtc *crtc)
@@ -833,14 +782,13 @@ static void fimd_enable(struct exynos_drm_crtc *crtc)
833 if (test_and_clear_bit(0, &ctx->irq_flags)) 782 if (test_and_clear_bit(0, &ctx->irq_flags))
834 fimd_enable_vblank(ctx->crtc); 783 fimd_enable_vblank(ctx->crtc);
835 784
836 fimd_window_resume(ctx); 785 fimd_commit(ctx->crtc);
837
838 fimd_apply(ctx);
839} 786}
840 787
841static void fimd_disable(struct exynos_drm_crtc *crtc) 788static void fimd_disable(struct exynos_drm_crtc *crtc)
842{ 789{
843 struct fimd_context *ctx = crtc->ctx; 790 struct fimd_context *ctx = crtc->ctx;
791 int i;
844 792
845 if (ctx->suspended) 793 if (ctx->suspended)
846 return; 794 return;
@@ -850,7 +798,8 @@ static void fimd_disable(struct exynos_drm_crtc *crtc)
850 * suspend that connector. Otherwise we might try to scan from 798 * suspend that connector. Otherwise we might try to scan from
851 * a destroyed buffer later. 799 * a destroyed buffer later.
852 */ 800 */
853 fimd_window_suspend(ctx); 801 for (i = 0; i < WINDOWS_NR; i++)
802 fimd_win_disable(crtc, i);
854 803
855 clk_disable_unprepare(ctx->lcd_clk); 804 clk_disable_unprepare(ctx->lcd_clk);
856 clk_disable_unprepare(ctx->bus_clk); 805 clk_disable_unprepare(ctx->bus_clk);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index a277191343ba..3413393d8a16 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -131,33 +131,15 @@ static void vidi_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
131 131
132 plane = &ctx->planes[win]; 132 plane = &ctx->planes[win];
133 133
134 plane->enabled = true;
135
136 DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr); 134 DRM_DEBUG_KMS("dma_addr = %pad\n", plane->dma_addr);
137 135
138 if (ctx->vblank_on) 136 if (ctx->vblank_on)
139 schedule_work(&ctx->work); 137 schedule_work(&ctx->work);
140} 138}
141 139
142static void vidi_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
143{
144 struct vidi_context *ctx = crtc->ctx;
145 struct exynos_drm_plane *plane;
146
147 if (win < 0 || win >= WINDOWS_NR)
148 return;
149
150 plane = &ctx->planes[win];
151 plane->enabled = false;
152
153 /* TODO. */
154}
155
156static void vidi_enable(struct exynos_drm_crtc *crtc) 140static void vidi_enable(struct exynos_drm_crtc *crtc)
157{ 141{
158 struct vidi_context *ctx = crtc->ctx; 142 struct vidi_context *ctx = crtc->ctx;
159 struct exynos_drm_plane *plane;
160 int i;
161 143
162 mutex_lock(&ctx->lock); 144 mutex_lock(&ctx->lock);
163 145
@@ -167,12 +149,6 @@ static void vidi_enable(struct exynos_drm_crtc *crtc)
167 if (test_and_clear_bit(0, &ctx->irq_flags)) 149 if (test_and_clear_bit(0, &ctx->irq_flags))
168 vidi_enable_vblank(ctx->crtc); 150 vidi_enable_vblank(ctx->crtc);
169 151
170 for (i = 0; i < WINDOWS_NR; i++) {
171 plane = &ctx->planes[i];
172 if (plane->enabled)
173 vidi_win_commit(ctx->crtc, i);
174 }
175
176 mutex_unlock(&ctx->lock); 152 mutex_unlock(&ctx->lock);
177} 153}
178 154
@@ -204,7 +180,6 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
204 .enable_vblank = vidi_enable_vblank, 180 .enable_vblank = vidi_enable_vblank,
205 .disable_vblank = vidi_disable_vblank, 181 .disable_vblank = vidi_disable_vblank,
206 .win_commit = vidi_win_commit, 182 .win_commit = vidi_win_commit,
207 .win_disable = vidi_win_disable,
208}; 183};
209 184
210static void vidi_fake_vblank_handler(struct work_struct *work) 185static void vidi_fake_vblank_handler(struct work_struct *work)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 24f0c22ff495..f57068781a37 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -937,8 +937,6 @@ static void mixer_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
937 vp_video_buffer(mixer_ctx, win); 937 vp_video_buffer(mixer_ctx, win);
938 else 938 else
939 mixer_graph_buffer(mixer_ctx, win); 939 mixer_graph_buffer(mixer_ctx, win);
940
941 mixer_ctx->planes[win].enabled = true;
942} 940}
943 941
944static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win) 942static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
@@ -952,7 +950,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
952 mutex_lock(&mixer_ctx->mixer_mutex); 950 mutex_lock(&mixer_ctx->mixer_mutex);
953 if (!mixer_ctx->powered) { 951 if (!mixer_ctx->powered) {
954 mutex_unlock(&mixer_ctx->mixer_mutex); 952 mutex_unlock(&mixer_ctx->mixer_mutex);
955 mixer_ctx->planes[win].resume = false;
956 return; 953 return;
957 } 954 }
958 mutex_unlock(&mixer_ctx->mixer_mutex); 955 mutex_unlock(&mixer_ctx->mixer_mutex);
@@ -964,8 +961,6 @@ static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
964 961
965 mixer_vsync_set_update(mixer_ctx, true); 962 mixer_vsync_set_update(mixer_ctx, true);
966 spin_unlock_irqrestore(&res->reg_slock, flags); 963 spin_unlock_irqrestore(&res->reg_slock, flags);
967
968 mixer_ctx->planes[win].enabled = false;
969} 964}
970 965
971static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) 966static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
@@ -1000,32 +995,6 @@ static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
1000 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe); 995 drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
1001} 996}
1002 997
1003static void mixer_window_suspend(struct mixer_context *ctx)
1004{
1005 struct exynos_drm_plane *plane;
1006 int i;
1007
1008 for (i = 0; i < MIXER_WIN_NR; i++) {
1009 plane = &ctx->planes[i];
1010 plane->resume = plane->enabled;
1011 mixer_win_disable(ctx->crtc, i);
1012 }
1013}
1014
1015static void mixer_window_resume(struct mixer_context *ctx)
1016{
1017 struct exynos_drm_plane *plane;
1018 int i;
1019
1020 for (i = 0; i < MIXER_WIN_NR; i++) {
1021 plane = &ctx->planes[i];
1022 plane->enabled = plane->resume;
1023 plane->resume = false;
1024 if (plane->enabled)
1025 mixer_win_commit(ctx->crtc, i);
1026 }
1027}
1028
1029static void mixer_enable(struct exynos_drm_crtc *crtc) 998static void mixer_enable(struct exynos_drm_crtc *crtc)
1030{ 999{
1031 struct mixer_context *ctx = crtc->ctx; 1000 struct mixer_context *ctx = crtc->ctx;
@@ -1078,14 +1047,13 @@ static void mixer_enable(struct exynos_drm_crtc *crtc)
1078 1047
1079 mixer_reg_write(res, MXR_INT_EN, ctx->int_en); 1048 mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1080 mixer_win_reset(ctx); 1049 mixer_win_reset(ctx);
1081
1082 mixer_window_resume(ctx);
1083} 1050}
1084 1051
1085static void mixer_disable(struct exynos_drm_crtc *crtc) 1052static void mixer_disable(struct exynos_drm_crtc *crtc)
1086{ 1053{
1087 struct mixer_context *ctx = crtc->ctx; 1054 struct mixer_context *ctx = crtc->ctx;
1088 struct mixer_resources *res = &ctx->mixer_res; 1055 struct mixer_resources *res = &ctx->mixer_res;
1056 int i;
1089 1057
1090 mutex_lock(&ctx->mixer_mutex); 1058 mutex_lock(&ctx->mixer_mutex);
1091 if (!ctx->powered) { 1059 if (!ctx->powered) {
@@ -1096,7 +1064,9 @@ static void mixer_disable(struct exynos_drm_crtc *crtc)
1096 1064
1097 mixer_stop(ctx); 1065 mixer_stop(ctx);
1098 mixer_regs_dump(ctx); 1066 mixer_regs_dump(ctx);
1099 mixer_window_suspend(ctx); 1067
1068 for (i = 0; i < MIXER_WIN_NR; i++)
1069 mixer_win_disable(crtc, i);
1100 1070
1101 ctx->int_en = mixer_reg_read(res, MXR_INT_EN); 1071 ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1102 1072