aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2016-09-23 09:21:38 -0400
committerInki Dae <daeinki@gmail.com>2016-09-30 11:39:37 -0400
commit9276dff7a89d81e84a4e4a1a07b636232be5aab0 (patch)
tree63249e35eaa03fc21e5d04c1567831dd8deb07e7
parentd42c09628a14fd07185d189d245ed57854e06179 (diff)
drm/exynos: use drm core to handle page-flip event
Exynos DRM framework handled page-flip event with custom code. The patch replaces it with drm-core vblank queue. Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos5433_drm_decon.c11
-rw-r--r--drivers/gpu/drm/exynos/exynos7_drm_decon.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c42
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c15
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c10
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c9
8 files changed, 21 insertions, 78 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
index ac21b4000835..6ca1f3117fe8 100644
--- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c
@@ -551,7 +551,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
551{ 551{
552 struct decon_context *ctx = dev_id; 552 struct decon_context *ctx = dev_id;
553 u32 val; 553 u32 val;
554 int win;
555 554
556 if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags)) 555 if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
557 goto out; 556 goto out;
@@ -560,16 +559,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
560 val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND; 559 val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
561 560
562 if (val) { 561 if (val) {
563 for (win = ctx->first_win; win < WINDOWS_NR ; win++) {
564 struct exynos_drm_plane *plane = &ctx->planes[win];
565
566 if (!plane->pending_fb)
567 continue;
568
569 exynos_drm_crtc_finish_update(ctx->crtc, plane);
570 }
571
572 /* clear */
573 writel(val, ctx->addr + DECON_VIDINTCON1); 562 writel(val, ctx->addr + DECON_VIDINTCON1);
574 drm_crtc_handle_vblank(&ctx->crtc->base); 563 drm_crtc_handle_vblank(&ctx->crtc->base);
575 } 564 }
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
index 7f9901b7777b..f4d5a2133777 100644
--- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c
+++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c
@@ -603,7 +603,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
603{ 603{
604 struct decon_context *ctx = (struct decon_context *)dev_id; 604 struct decon_context *ctx = (struct decon_context *)dev_id;
605 u32 val, clear_bit; 605 u32 val, clear_bit;
606 int win;
607 606
608 val = readl(ctx->regs + VIDINTCON1); 607 val = readl(ctx->regs + VIDINTCON1);
609 608
@@ -617,14 +616,6 @@ static irqreturn_t decon_irq_handler(int irq, void *dev_id)
617 616
618 if (!ctx->i80_if) { 617 if (!ctx->i80_if) {
619 drm_crtc_handle_vblank(&ctx->crtc->base); 618 drm_crtc_handle_vblank(&ctx->crtc->base);
620 for (win = 0 ; win < WINDOWS_NR ; win++) {
621 struct exynos_drm_plane *plane = &ctx->planes[win];
622
623 if (!plane->pending_fb)
624 continue;
625
626 exynos_drm_crtc_finish_update(ctx->crtc, plane);
627 }
628 619
629 /* set wait vsync event to zero and wake up queue. */ 620 /* set wait vsync event to zero and wake up queue. */
630 if (atomic_read(&ctx->wait_vsync_event)) { 621 if (atomic_read(&ctx->wait_vsync_event)) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 5b6845bc18fc..2530bf57716a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -69,8 +69,6 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc,
69{ 69{
70 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 70 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
71 71
72 exynos_crtc->event = crtc->state->event;
73
74 if (exynos_crtc->ops->atomic_begin) 72 if (exynos_crtc->ops->atomic_begin)
75 exynos_crtc->ops->atomic_begin(exynos_crtc); 73 exynos_crtc->ops->atomic_begin(exynos_crtc);
76} 74}
@@ -79,9 +77,24 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
79 struct drm_crtc_state *old_crtc_state) 77 struct drm_crtc_state *old_crtc_state)
80{ 78{
81 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); 79 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
80 struct drm_pending_vblank_event *event;
81 unsigned long flags;
82 82
83 if (exynos_crtc->ops->atomic_flush) 83 if (exynos_crtc->ops->atomic_flush)
84 exynos_crtc->ops->atomic_flush(exynos_crtc); 84 exynos_crtc->ops->atomic_flush(exynos_crtc);
85
86 event = crtc->state->event;
87 if (event) {
88 crtc->state->event = NULL;
89
90 spin_lock_irqsave(&crtc->dev->event_lock, flags);
91 if (drm_crtc_vblank_get(crtc) == 0)
92 drm_crtc_arm_vblank_event(crtc, event);
93 else
94 drm_crtc_send_vblank_event(crtc, event);
95 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
96 }
97
85} 98}
86 99
87static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { 100static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
@@ -173,22 +186,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe)
173 exynos_crtc->ops->disable_vblank(exynos_crtc); 186 exynos_crtc->ops->disable_vblank(exynos_crtc);
174} 187}
175 188
176void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
177 struct exynos_drm_plane *exynos_plane)
178{
179 struct drm_crtc *crtc = &exynos_crtc->base;
180 unsigned long flags;
181
182 exynos_plane->pending_fb = NULL;
183
184 spin_lock_irqsave(&crtc->dev->event_lock, flags);
185 if (exynos_crtc->event)
186 drm_crtc_send_vblank_event(crtc, exynos_crtc->event);
187
188 exynos_crtc->event = NULL;
189 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
190}
191
192int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, 189int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
193 enum exynos_drm_output_type out_type) 190 enum exynos_drm_output_type out_type)
194{ 191{
@@ -216,18 +213,19 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
216void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc, 213void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
217 struct drm_file *file) 214 struct drm_file *file)
218{ 215{
219 struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
220 struct drm_pending_vblank_event *e; 216 struct drm_pending_vblank_event *e;
221 unsigned long flags; 217 unsigned long flags;
222 218
223 spin_lock_irqsave(&crtc->dev->event_lock, flags); 219 spin_lock_irqsave(&crtc->dev->event_lock, flags);
224 220
225 e = exynos_crtc->event; 221 e = crtc->state->event;
226 if (e && e->base.file_priv == file) 222 if (e && e->base.file_priv == file)
227 exynos_crtc->event = NULL; 223 crtc->state->event = NULL;
224 else
225 e = NULL;
228 226
229 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 227 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
230 228
231 if (e && e->base.file_priv == file) 229 if (e)
232 drm_event_cancel_free(crtc->dev, &e->base); 230 drm_event_cancel_free(crtc->dev, &e->base);
233} 231}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index cee3a4c76106..d215149e737b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -86,7 +86,6 @@ struct exynos_drm_plane {
86 struct drm_plane base; 86 struct drm_plane base;
87 const struct exynos_drm_plane_config *config; 87 const struct exynos_drm_plane_config *config;
88 unsigned int index; 88 unsigned int index;
89 struct drm_framebuffer *pending_fb;
90}; 89};
91 90
92#define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0) 91#define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0)
@@ -172,7 +171,6 @@ struct exynos_drm_crtc {
172 struct drm_crtc base; 171 struct drm_crtc base;
173 enum exynos_drm_output_type type; 172 enum exynos_drm_output_type type;
174 unsigned int pipe; 173 unsigned int pipe;
175 struct drm_pending_vblank_event *event;
176 const struct exynos_drm_crtc_ops *ops; 174 const struct exynos_drm_crtc_ops *ops;
177 void *ctx; 175 void *ctx;
178 struct exynos_drm_clk *pipe_clk; 176 struct exynos_drm_clk *pipe_clk;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 27efe3087d18..e2e405170d35 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -962,8 +962,7 @@ static const struct exynos_drm_crtc_ops fimd_crtc_ops = {
962static irqreturn_t fimd_irq_handler(int irq, void *dev_id) 962static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
963{ 963{
964 struct fimd_context *ctx = (struct fimd_context *)dev_id; 964 struct fimd_context *ctx = (struct fimd_context *)dev_id;
965 u32 val, clear_bit, start, start_s; 965 u32 val, clear_bit;
966 int win;
967 966
968 val = readl(ctx->regs + VIDINTCON1); 967 val = readl(ctx->regs + VIDINTCON1);
969 968
@@ -978,18 +977,6 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
978 if (!ctx->i80_if) 977 if (!ctx->i80_if)
979 drm_crtc_handle_vblank(&ctx->crtc->base); 978 drm_crtc_handle_vblank(&ctx->crtc->base);
980 979
981 for (win = 0 ; win < WINDOWS_NR ; win++) {
982 struct exynos_drm_plane *plane = &ctx->planes[win];
983
984 if (!plane->pending_fb)
985 continue;
986
987 start = readl(ctx->regs + VIDWx_BUF_START(win, 0));
988 start_s = readl(ctx->regs + VIDWx_BUF_START_S(win, 0));
989 if (start == start_s)
990 exynos_drm_crtc_finish_update(ctx->crtc, plane);
991 }
992
993 if (ctx->i80_if) { 980 if (ctx->i80_if) {
994 /* Exits triggering mode */ 981 /* Exits triggering mode */
995 atomic_set(&ctx->triggering, 0); 982 atomic_set(&ctx->triggering, 0);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 7f32419b25ea..c2f17f30afab 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -238,7 +238,6 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
238 return; 238 return;
239 239
240 plane->crtc = state->crtc; 240 plane->crtc = state->crtc;
241 exynos_plane->pending_fb = state->fb;
242 241
243 if (exynos_crtc->ops->update_plane) 242 if (exynos_crtc->ops->update_plane)
244 exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane); 243 exynos_crtc->ops->update_plane(exynos_crtc, exynos_plane);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index a91dad65e908..57fe514d5c5b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -175,7 +175,6 @@ static const struct exynos_drm_crtc_ops vidi_crtc_ops = {
175static void vidi_fake_vblank_timer(unsigned long arg) 175static void vidi_fake_vblank_timer(unsigned long arg)
176{ 176{
177 struct vidi_context *ctx = (void *)arg; 177 struct vidi_context *ctx = (void *)arg;
178 int win;
179 178
180 if (ctx->pipe < 0) 179 if (ctx->pipe < 0)
181 return; 180 return;
@@ -183,15 +182,6 @@ static void vidi_fake_vblank_timer(unsigned long arg)
183 if (drm_crtc_handle_vblank(&ctx->crtc->base)) 182 if (drm_crtc_handle_vblank(&ctx->crtc->base))
184 mod_timer(&ctx->timer, 183 mod_timer(&ctx->timer,
185 jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1); 184 jiffies + msecs_to_jiffies(VIDI_REFRESH_TIME) - 1);
186
187 for (win = 0 ; win < WINDOWS_NR ; win++) {
188 struct exynos_drm_plane *plane = &ctx->planes[win];
189
190 if (!plane->pending_fb)
191 continue;
192
193 exynos_drm_crtc_finish_update(ctx->crtc, plane);
194 }
195} 185}
196 186
197static ssize_t vidi_show_connection(struct device *dev, 187static ssize_t vidi_show_connection(struct device *dev,
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index bea3cbd39a25..edb20a34c66c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -754,7 +754,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
754 struct mixer_context *ctx = arg; 754 struct mixer_context *ctx = arg;
755 struct mixer_resources *res = &ctx->mixer_res; 755 struct mixer_resources *res = &ctx->mixer_res;
756 u32 val, base, shadow; 756 u32 val, base, shadow;
757 int win;
758 757
759 spin_lock(&res->reg_slock); 758 spin_lock(&res->reg_slock);
760 759
@@ -781,14 +780,6 @@ static irqreturn_t mixer_irq_handler(int irq, void *arg)
781 } 780 }
782 781
783 drm_crtc_handle_vblank(&ctx->crtc->base); 782 drm_crtc_handle_vblank(&ctx->crtc->base);
784 for (win = 0 ; win < MIXER_WIN_NR ; win++) {
785 struct exynos_drm_plane *plane = &ctx->planes[win];
786
787 if (!plane->pending_fb)
788 continue;
789
790 exynos_drm_crtc_finish_update(ctx->crtc, plane);
791 }
792 } 783 }
793 784
794out: 785out: