diff options
author | Marek Szyprowski <m.szyprowski@samsung.com> | 2016-01-05 07:52:51 -0500 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2016-01-12 10:16:37 -0500 |
commit | d29c2c140787a1645306a11799e33adddf72e64f (patch) | |
tree | d1efa4ccf6facd7e7bbce7a7b6c67dfdd30abe27 | |
parent | 5e68fef24fab07f4decc78d421838eb73b7e3931 (diff) |
drm/exynos: crtc: rework atomic_{begin,flush}
Some CRTC drivers (like Exynos DRM Mixer) can handle blocking register
updates only on per-device level, not per-plane level. This patch changes
exynos_crts atomic_begin/atomic_flush callbacks to handle the entire crtc,
instead of given planes, so driver can handle both cases on their own.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos7_drm_decon.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 14 |
5 files changed, 32 insertions, 40 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 77073d8faaa3..1bf6a21130c7 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c | |||
@@ -248,15 +248,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win, | |||
248 | protect ? ~0 : 0); | 248 | protect ? ~0 : 0); |
249 | } | 249 | } |
250 | 250 | ||
251 | static void decon_atomic_begin(struct exynos_drm_crtc *crtc, | 251 | static void decon_atomic_begin(struct exynos_drm_crtc *crtc) |
252 | struct exynos_drm_plane *plane) | ||
253 | { | 252 | { |
254 | struct decon_context *ctx = crtc->ctx; | 253 | struct decon_context *ctx = crtc->ctx; |
254 | int i; | ||
255 | 255 | ||
256 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) | 256 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) |
257 | return; | 257 | return; |
258 | 258 | ||
259 | decon_shadow_protect_win(ctx, plane->index, true); | 259 | for (i = ctx->first_win; i < WINDOWS_NR; i++) |
260 | decon_shadow_protect_win(ctx, i, true); | ||
260 | } | 261 | } |
261 | 262 | ||
262 | #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s)) | 263 | #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s)) |
@@ -336,15 +337,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, | |||
336 | decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); | 337 | decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); |
337 | } | 338 | } |
338 | 339 | ||
339 | static void decon_atomic_flush(struct exynos_drm_crtc *crtc, | 340 | static void decon_atomic_flush(struct exynos_drm_crtc *crtc) |
340 | struct exynos_drm_plane *plane) | ||
341 | { | 341 | { |
342 | struct decon_context *ctx = crtc->ctx; | 342 | struct decon_context *ctx = crtc->ctx; |
343 | int i; | ||
343 | 344 | ||
344 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) | 345 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) |
345 | return; | 346 | return; |
346 | 347 | ||
347 | decon_shadow_protect_win(ctx, plane->index, false); | 348 | for (i = ctx->first_win; i < WINDOWS_NR; i++) |
349 | decon_shadow_protect_win(ctx, i, false); | ||
348 | 350 | ||
349 | if (ctx->out_type == IFTYPE_I80) | 351 | if (ctx->out_type == IFTYPE_I80) |
350 | set_bit(BIT_WIN_UPDATED, &ctx->flags); | 352 | set_bit(BIT_WIN_UPDATED, &ctx->flags); |
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index 8911f965b06c..52bda3b42fe0 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c | |||
@@ -385,15 +385,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, | |||
385 | writel(val, ctx->regs + SHADOWCON); | 385 | writel(val, ctx->regs + SHADOWCON); |
386 | } | 386 | } |
387 | 387 | ||
388 | static void decon_atomic_begin(struct exynos_drm_crtc *crtc, | 388 | static void decon_atomic_begin(struct exynos_drm_crtc *crtc) |
389 | struct exynos_drm_plane *plane) | ||
390 | { | 389 | { |
391 | struct decon_context *ctx = crtc->ctx; | 390 | struct decon_context *ctx = crtc->ctx; |
391 | int i; | ||
392 | 392 | ||
393 | if (ctx->suspended) | 393 | if (ctx->suspended) |
394 | return; | 394 | return; |
395 | 395 | ||
396 | decon_shadow_protect_win(ctx, plane->index, true); | 396 | for (i = 0; i < WINDOWS_NR; i++) |
397 | decon_shadow_protect_win(ctx, i, true); | ||
397 | } | 398 | } |
398 | 399 | ||
399 | static void decon_update_plane(struct exynos_drm_crtc *crtc, | 400 | static void decon_update_plane(struct exynos_drm_crtc *crtc, |
@@ -517,15 +518,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, | |||
517 | writel(val, ctx->regs + DECON_UPDATE); | 518 | writel(val, ctx->regs + DECON_UPDATE); |
518 | } | 519 | } |
519 | 520 | ||
520 | static void decon_atomic_flush(struct exynos_drm_crtc *crtc, | 521 | static void decon_atomic_flush(struct exynos_drm_crtc *crtc) |
521 | struct exynos_drm_plane *plane) | ||
522 | { | 522 | { |
523 | struct decon_context *ctx = crtc->ctx; | 523 | struct decon_context *ctx = crtc->ctx; |
524 | int i; | ||
524 | 525 | ||
525 | if (ctx->suspended) | 526 | if (ctx->suspended) |
526 | return; | 527 | return; |
527 | 528 | ||
528 | decon_shadow_protect_win(ctx, plane->index, false); | 529 | for (i = 0; i < WINDOWS_NR; i++) |
530 | decon_shadow_protect_win(ctx, i, false); | ||
529 | } | 531 | } |
530 | 532 | ||
531 | static void decon_init(struct decon_context *ctx) | 533 | static void decon_init(struct decon_context *ctx) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 8f5ac535d809..5acaecba450a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c | |||
@@ -68,32 +68,20 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, | |||
68 | struct drm_crtc_state *old_crtc_state) | 68 | struct drm_crtc_state *old_crtc_state) |
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 | struct drm_plane *plane; | ||
72 | 71 | ||
73 | exynos_crtc->event = crtc->state->event; | 72 | exynos_crtc->event = crtc->state->event; |
74 | 73 | ||
75 | drm_atomic_crtc_for_each_plane(plane, crtc) { | 74 | if (exynos_crtc->ops->atomic_begin) |
76 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 75 | exynos_crtc->ops->atomic_begin(exynos_crtc); |
77 | |||
78 | if (exynos_crtc->ops->atomic_begin) | ||
79 | exynos_crtc->ops->atomic_begin(exynos_crtc, | ||
80 | exynos_plane); | ||
81 | } | ||
82 | } | 76 | } |
83 | 77 | ||
84 | static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, | 78 | static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, |
85 | struct drm_crtc_state *old_crtc_state) | 79 | struct drm_crtc_state *old_crtc_state) |
86 | { | 80 | { |
87 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | 81 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); |
88 | struct drm_plane *plane; | ||
89 | 82 | ||
90 | drm_atomic_crtc_for_each_plane(plane, crtc) { | 83 | if (exynos_crtc->ops->atomic_flush) |
91 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | 84 | exynos_crtc->ops->atomic_flush(exynos_crtc); |
92 | |||
93 | if (exynos_crtc->ops->atomic_flush) | ||
94 | exynos_crtc->ops->atomic_flush(exynos_crtc, | ||
95 | exynos_plane); | ||
96 | } | ||
97 | } | 85 | } |
98 | 86 | ||
99 | static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { | 87 | static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index f0827dbebb7d..17b5ded72ff1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -123,8 +123,8 @@ struct exynos_drm_plane_config { | |||
123 | * @wait_for_vblank: wait for vblank interrupt to make sure that | 123 | * @wait_for_vblank: wait for vblank interrupt to make sure that |
124 | * hardware overlay is updated. | 124 | * hardware overlay is updated. |
125 | * @atomic_check: validate state | 125 | * @atomic_check: validate state |
126 | * @atomic_begin: prepare a window to receive a update | 126 | * @atomic_begin: prepare device to receive an update |
127 | * @atomic_flush: mark the end of a window update | 127 | * @atomic_flush: mark the end of device update |
128 | * @update_plane: apply hardware specific overlay data to registers. | 128 | * @update_plane: apply hardware specific overlay data to registers. |
129 | * @disable_plane: disable hardware specific overlay. | 129 | * @disable_plane: disable hardware specific overlay. |
130 | * @te_handler: trigger to transfer video image at the tearing effect | 130 | * @te_handler: trigger to transfer video image at the tearing effect |
@@ -144,14 +144,12 @@ struct exynos_drm_crtc_ops { | |||
144 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); | 144 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); |
145 | int (*atomic_check)(struct exynos_drm_crtc *crtc, | 145 | int (*atomic_check)(struct exynos_drm_crtc *crtc, |
146 | struct drm_crtc_state *state); | 146 | struct drm_crtc_state *state); |
147 | void (*atomic_begin)(struct exynos_drm_crtc *crtc, | 147 | void (*atomic_begin)(struct exynos_drm_crtc *crtc); |
148 | struct exynos_drm_plane *plane); | ||
149 | void (*update_plane)(struct exynos_drm_crtc *crtc, | 148 | void (*update_plane)(struct exynos_drm_crtc *crtc, |
150 | struct exynos_drm_plane *plane); | 149 | struct exynos_drm_plane *plane); |
151 | void (*disable_plane)(struct exynos_drm_crtc *crtc, | 150 | void (*disable_plane)(struct exynos_drm_crtc *crtc, |
152 | struct exynos_drm_plane *plane); | 151 | struct exynos_drm_plane *plane); |
153 | void (*atomic_flush)(struct exynos_drm_crtc *crtc, | 152 | void (*atomic_flush)(struct exynos_drm_crtc *crtc); |
154 | struct exynos_drm_plane *plane); | ||
155 | void (*te_handler)(struct exynos_drm_crtc *crtc); | 153 | void (*te_handler)(struct exynos_drm_crtc *crtc); |
156 | void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); | 154 | void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); |
157 | }; | 155 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 6ae1b1e55783..70194d0e4fe4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -622,26 +622,28 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, | |||
622 | writel(val, ctx->regs + reg); | 622 | writel(val, ctx->regs + reg); |
623 | } | 623 | } |
624 | 624 | ||
625 | static void fimd_atomic_begin(struct exynos_drm_crtc *crtc, | 625 | static void fimd_atomic_begin(struct exynos_drm_crtc *crtc) |
626 | struct exynos_drm_plane *plane) | ||
627 | { | 626 | { |
628 | struct fimd_context *ctx = crtc->ctx; | 627 | struct fimd_context *ctx = crtc->ctx; |
628 | int i; | ||
629 | 629 | ||
630 | if (ctx->suspended) | 630 | if (ctx->suspended) |
631 | return; | 631 | return; |
632 | 632 | ||
633 | fimd_shadow_protect_win(ctx, plane->index, true); | 633 | for (i = 0; i < WINDOWS_NR; i++) |
634 | fimd_shadow_protect_win(ctx, i, true); | ||
634 | } | 635 | } |
635 | 636 | ||
636 | static void fimd_atomic_flush(struct exynos_drm_crtc *crtc, | 637 | static void fimd_atomic_flush(struct exynos_drm_crtc *crtc) |
637 | struct exynos_drm_plane *plane) | ||
638 | { | 638 | { |
639 | struct fimd_context *ctx = crtc->ctx; | 639 | struct fimd_context *ctx = crtc->ctx; |
640 | int i; | ||
640 | 641 | ||
641 | if (ctx->suspended) | 642 | if (ctx->suspended) |
642 | return; | 643 | return; |
643 | 644 | ||
644 | fimd_shadow_protect_win(ctx, plane->index, false); | 645 | for (i = 0; i < WINDOWS_NR; i++) |
646 | fimd_shadow_protect_win(ctx, i, false); | ||
645 | } | 647 | } |
646 | 648 | ||
647 | static void fimd_update_plane(struct exynos_drm_crtc *crtc, | 649 | static void fimd_update_plane(struct exynos_drm_crtc *crtc, |