diff options
author | Dave Airlie <airlied@redhat.com> | 2016-01-13 16:59:21 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-01-13 16:59:21 -0500 |
commit | d6f7a18c8adcb77ca9bfff2d7fb152ac685b73fd (patch) | |
tree | 62602e618371b8b64795d030debfa643626fbd6b /drivers | |
parent | 06249e69324209b41ba017f476764eba347b1127 (diff) | |
parent | c74d8eb5649386c2cfcd65cc960fd283ba876877 (diff) |
Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next
This 2nd pull request includes the following,
- add configurable plane support and relevant cleanups.
- fixup kernel panic issue at drm releasing.
- remove unnecessary codes.
This has been delayed to resolve a critical issue - which incurrs
a kernel panic when driver is released - and review it.
* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
drm/exynos: fix kernel panic issue at drm releasing
drm/exynos: crtc: do not wait for the scanout completion
drm/exynos: mixer: properly update all planes on the same vblank event
drm/exynos: crtc: rework atomic_{begin,flush}
drm/exynos: mixer: unify a check for video-processor window
drm/exynos: mixer: also allow ARGB1555 and ARGB4444
drm/exynos: mixer: refactor layer setup
drm/exynos: mixer: remove all static blending setup
drm/exynos: mixer: set window priority based on zpos
drm/exynos: make zpos property configurable
drm/exynos: rename zpos to index
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos5433_drm_decon.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos7_drm_decon.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 69 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fimd.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_plane.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_mixer.c | 155 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/regs-mixer.h | 4 |
13 files changed, 235 insertions, 143 deletions
diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index c7362b99ce28..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->zpos, 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)) |
@@ -270,7 +271,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, | |||
270 | to_exynos_plane_state(plane->base.state); | 271 | to_exynos_plane_state(plane->base.state); |
271 | struct decon_context *ctx = crtc->ctx; | 272 | struct decon_context *ctx = crtc->ctx; |
272 | struct drm_framebuffer *fb = state->base.fb; | 273 | struct drm_framebuffer *fb = state->base.fb; |
273 | unsigned int win = plane->zpos; | 274 | unsigned int win = plane->index; |
274 | unsigned int bpp = fb->bits_per_pixel >> 3; | 275 | unsigned int bpp = fb->bits_per_pixel >> 3; |
275 | unsigned int pitch = fb->pitches[0]; | 276 | unsigned int pitch = fb->pitches[0]; |
276 | dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); | 277 | dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); |
@@ -320,7 +321,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, | |||
320 | struct exynos_drm_plane *plane) | 321 | struct exynos_drm_plane *plane) |
321 | { | 322 | { |
322 | struct decon_context *ctx = crtc->ctx; | 323 | struct decon_context *ctx = crtc->ctx; |
323 | unsigned int win = plane->zpos; | 324 | unsigned int win = plane->index; |
324 | 325 | ||
325 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) | 326 | if (test_bit(BIT_SUSPENDED, &ctx->flags)) |
326 | return; | 327 | return; |
@@ -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->zpos, 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); |
@@ -502,7 +504,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | |||
502 | ctx->configs[win].zpos = win; | 504 | ctx->configs[win].zpos = win; |
503 | ctx->configs[win].type = decon_win_types[tmp]; | 505 | ctx->configs[win].type = decon_win_types[tmp]; |
504 | 506 | ||
505 | ret = exynos_plane_init(drm_dev, &ctx->planes[win], | 507 | ret = exynos_plane_init(drm_dev, &ctx->planes[win], win, |
506 | 1 << ctx->pipe, &ctx->configs[win]); | 508 | 1 << ctx->pipe, &ctx->configs[win]); |
507 | if (ret) | 509 | if (ret) |
508 | return ret; | 510 | return ret; |
diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index c47f9af8170b..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->zpos, 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, |
@@ -407,7 +408,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, | |||
407 | unsigned long val, alpha; | 408 | unsigned long val, alpha; |
408 | unsigned int last_x; | 409 | unsigned int last_x; |
409 | unsigned int last_y; | 410 | unsigned int last_y; |
410 | unsigned int win = plane->zpos; | 411 | unsigned int win = plane->index; |
411 | unsigned int bpp = fb->bits_per_pixel >> 3; | 412 | unsigned int bpp = fb->bits_per_pixel >> 3; |
412 | unsigned int pitch = fb->pitches[0]; | 413 | unsigned int pitch = fb->pitches[0]; |
413 | 414 | ||
@@ -498,7 +499,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, | |||
498 | struct exynos_drm_plane *plane) | 499 | struct exynos_drm_plane *plane) |
499 | { | 500 | { |
500 | struct decon_context *ctx = crtc->ctx; | 501 | struct decon_context *ctx = crtc->ctx; |
501 | unsigned int win = plane->zpos; | 502 | unsigned int win = plane->index; |
502 | u32 val; | 503 | u32 val; |
503 | 504 | ||
504 | if (ctx->suspended) | 505 | if (ctx->suspended) |
@@ -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->zpos, 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) |
@@ -657,7 +659,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) | |||
657 | ctx->configs[i].zpos = i; | 659 | ctx->configs[i].zpos = i; |
658 | ctx->configs[i].type = decon_win_types[i]; | 660 | ctx->configs[i].type = decon_win_types[i]; |
659 | 661 | ||
660 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], | 662 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, |
661 | 1 << ctx->pipe, &ctx->configs[i]); | 663 | 1 << ctx->pipe, &ctx->configs[i]); |
662 | if (ret) | 664 | if (ret) |
663 | return ret; | 665 | return ret; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 8f5ac535d809..e36579c1c025 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 = { |
@@ -215,29 +203,6 @@ void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, | |||
215 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | 203 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); |
216 | } | 204 | } |
217 | 205 | ||
218 | void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb) | ||
219 | { | ||
220 | struct exynos_drm_crtc *exynos_crtc; | ||
221 | struct drm_device *dev = fb->dev; | ||
222 | struct drm_crtc *crtc; | ||
223 | |||
224 | /* | ||
225 | * make sure that overlay data are updated to real hardware | ||
226 | * for all encoders. | ||
227 | */ | ||
228 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
229 | exynos_crtc = to_exynos_crtc(crtc); | ||
230 | |||
231 | /* | ||
232 | * wait for vblank interrupt | ||
233 | * - this makes sure that overlay data are updated to | ||
234 | * real hardware. | ||
235 | */ | ||
236 | if (exynos_crtc->ops->wait_for_vblank) | ||
237 | exynos_crtc->ops->wait_for_vblank(exynos_crtc); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, | 206 | int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, |
242 | enum exynos_drm_output_type out_type) | 207 | enum exynos_drm_output_type out_type) |
243 | { | 208 | { |
@@ -261,3 +226,29 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) | |||
261 | if (exynos_crtc->ops->te_handler) | 226 | if (exynos_crtc->ops->te_handler) |
262 | exynos_crtc->ops->te_handler(exynos_crtc); | 227 | exynos_crtc->ops->te_handler(exynos_crtc); |
263 | } | 228 | } |
229 | |||
230 | void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc, | ||
231 | struct drm_file *file) | ||
232 | { | ||
233 | struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); | ||
234 | struct drm_pending_vblank_event *e; | ||
235 | unsigned long flags; | ||
236 | |||
237 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
238 | e = exynos_crtc->event; | ||
239 | if (e && e->base.file_priv == file) { | ||
240 | exynos_crtc->event = NULL; | ||
241 | /* | ||
242 | * event will be destroyed by core part | ||
243 | * so below line should be removed later with core changes | ||
244 | */ | ||
245 | e->base.destroy(&e->base); | ||
246 | /* | ||
247 | * event_space will be increased by core part | ||
248 | * so below line should be removed later with core changes. | ||
249 | */ | ||
250 | file->event_space += sizeof(e->event); | ||
251 | atomic_dec(&exynos_crtc->pending_update); | ||
252 | } | ||
253 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
254 | } | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.h b/drivers/gpu/drm/exynos/exynos_drm_crtc.h index f9f365bd0257..cfdcf3e4eb1b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.h +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.h | |||
@@ -28,7 +28,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); | |||
28 | void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc); | 28 | void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc); |
29 | void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, | 29 | void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, |
30 | struct exynos_drm_plane *exynos_plane); | 30 | struct exynos_drm_plane *exynos_plane); |
31 | void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb); | ||
32 | 31 | ||
33 | /* This function gets pipe value to crtc device matched with out_type. */ | 32 | /* This function gets pipe value to crtc device matched with out_type. */ |
34 | int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, | 33 | int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, |
@@ -41,4 +40,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, | |||
41 | */ | 40 | */ |
42 | void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); | 41 | void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); |
43 | 42 | ||
43 | /* This function cancels a page flip request. */ | ||
44 | void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc, | ||
45 | struct drm_file *file); | ||
46 | |||
44 | #endif | 47 | #endif |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 9756797a15a5..68f0f36f6e7e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -330,7 +330,12 @@ err_file_priv_free: | |||
330 | static void exynos_drm_preclose(struct drm_device *dev, | 330 | static void exynos_drm_preclose(struct drm_device *dev, |
331 | struct drm_file *file) | 331 | struct drm_file *file) |
332 | { | 332 | { |
333 | struct drm_crtc *crtc; | ||
334 | |||
333 | exynos_drm_subdrv_close(dev, file); | 335 | exynos_drm_subdrv_close(dev, file); |
336 | |||
337 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
338 | exynos_drm_crtc_cancel_page_flip(crtc, file); | ||
334 | } | 339 | } |
335 | 340 | ||
336 | static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) | 341 | static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 82bbd7f4b316..17b5ded72ff1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -64,6 +64,7 @@ struct exynos_drm_plane_state { | |||
64 | struct exynos_drm_rect src; | 64 | struct exynos_drm_rect src; |
65 | unsigned int h_ratio; | 65 | unsigned int h_ratio; |
66 | unsigned int v_ratio; | 66 | unsigned int v_ratio; |
67 | unsigned int zpos; | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | static inline struct exynos_drm_plane_state * | 70 | static inline struct exynos_drm_plane_state * |
@@ -76,7 +77,7 @@ to_exynos_plane_state(struct drm_plane_state *state) | |||
76 | * Exynos drm common overlay structure. | 77 | * Exynos drm common overlay structure. |
77 | * | 78 | * |
78 | * @base: plane object | 79 | * @base: plane object |
79 | * @zpos: order of overlay layer(z position). | 80 | * @index: hardware index of the overlay layer |
80 | * | 81 | * |
81 | * this structure is common to exynos SoC and its contents would be copied | 82 | * this structure is common to exynos SoC and its contents would be copied |
82 | * to hardware specific overlay info. | 83 | * to hardware specific overlay info. |
@@ -85,17 +86,18 @@ to_exynos_plane_state(struct drm_plane_state *state) | |||
85 | struct exynos_drm_plane { | 86 | struct exynos_drm_plane { |
86 | struct drm_plane base; | 87 | struct drm_plane base; |
87 | const struct exynos_drm_plane_config *config; | 88 | const struct exynos_drm_plane_config *config; |
88 | unsigned int zpos; | 89 | unsigned int index; |
89 | struct drm_framebuffer *pending_fb; | 90 | struct drm_framebuffer *pending_fb; |
90 | }; | 91 | }; |
91 | 92 | ||
92 | #define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0) | 93 | #define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0) |
93 | #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) | 94 | #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) |
95 | #define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2) | ||
94 | 96 | ||
95 | /* | 97 | /* |
96 | * Exynos DRM plane configuration structure. | 98 | * Exynos DRM plane configuration structure. |
97 | * | 99 | * |
98 | * @zpos: z-position of the plane. | 100 | * @zpos: initial z-position of the plane. |
99 | * @type: type of the plane (primary, cursor or overlay). | 101 | * @type: type of the plane (primary, cursor or overlay). |
100 | * @pixel_formats: supported pixel formats. | 102 | * @pixel_formats: supported pixel formats. |
101 | * @num_pixel_formats: number of elements in 'pixel_formats'. | 103 | * @num_pixel_formats: number of elements in 'pixel_formats'. |
@@ -121,8 +123,8 @@ struct exynos_drm_plane_config { | |||
121 | * @wait_for_vblank: wait for vblank interrupt to make sure that | 123 | * @wait_for_vblank: wait for vblank interrupt to make sure that |
122 | * hardware overlay is updated. | 124 | * hardware overlay is updated. |
123 | * @atomic_check: validate state | 125 | * @atomic_check: validate state |
124 | * @atomic_begin: prepare a window to receive a update | 126 | * @atomic_begin: prepare device to receive an update |
125 | * @atomic_flush: mark the end of a window update | 127 | * @atomic_flush: mark the end of device update |
126 | * @update_plane: apply hardware specific overlay data to registers. | 128 | * @update_plane: apply hardware specific overlay data to registers. |
127 | * @disable_plane: disable hardware specific overlay. | 129 | * @disable_plane: disable hardware specific overlay. |
128 | * @te_handler: trigger to transfer video image at the tearing effect | 130 | * @te_handler: trigger to transfer video image at the tearing effect |
@@ -142,14 +144,12 @@ struct exynos_drm_crtc_ops { | |||
142 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); | 144 | void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); |
143 | int (*atomic_check)(struct exynos_drm_crtc *crtc, | 145 | int (*atomic_check)(struct exynos_drm_crtc *crtc, |
144 | struct drm_crtc_state *state); | 146 | struct drm_crtc_state *state); |
145 | void (*atomic_begin)(struct exynos_drm_crtc *crtc, | 147 | void (*atomic_begin)(struct exynos_drm_crtc *crtc); |
146 | struct exynos_drm_plane *plane); | ||
147 | void (*update_plane)(struct exynos_drm_crtc *crtc, | 148 | void (*update_plane)(struct exynos_drm_crtc *crtc, |
148 | struct exynos_drm_plane *plane); | 149 | struct exynos_drm_plane *plane); |
149 | void (*disable_plane)(struct exynos_drm_crtc *crtc, | 150 | void (*disable_plane)(struct exynos_drm_crtc *crtc, |
150 | struct exynos_drm_plane *plane); | 151 | struct exynos_drm_plane *plane); |
151 | void (*atomic_flush)(struct exynos_drm_crtc *crtc, | 152 | void (*atomic_flush)(struct exynos_drm_crtc *crtc); |
152 | struct exynos_drm_plane *plane); | ||
153 | void (*te_handler)(struct exynos_drm_crtc *crtc); | 153 | void (*te_handler)(struct exynos_drm_crtc *crtc); |
154 | void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); | 154 | void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); |
155 | }; | 155 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index cbbb1a86e70a..d614194644c8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -71,9 +71,6 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) | |||
71 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); | 71 | struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); |
72 | unsigned int i; | 72 | unsigned int i; |
73 | 73 | ||
74 | /* make sure that overlay data are updated before relesing fb. */ | ||
75 | exynos_drm_crtc_complete_scanout(fb); | ||
76 | |||
77 | drm_framebuffer_cleanup(fb); | 74 | drm_framebuffer_cleanup(fb); |
78 | 75 | ||
79 | for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) { | 76 | for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 2e2247126581..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->zpos, 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->zpos, 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, |
@@ -654,7 +656,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, | |||
654 | dma_addr_t dma_addr; | 656 | dma_addr_t dma_addr; |
655 | unsigned long val, size, offset; | 657 | unsigned long val, size, offset; |
656 | unsigned int last_x, last_y, buf_offsize, line_size; | 658 | unsigned int last_x, last_y, buf_offsize, line_size; |
657 | unsigned int win = plane->zpos; | 659 | unsigned int win = plane->index; |
658 | unsigned int bpp = fb->bits_per_pixel >> 3; | 660 | unsigned int bpp = fb->bits_per_pixel >> 3; |
659 | unsigned int pitch = fb->pitches[0]; | 661 | unsigned int pitch = fb->pitches[0]; |
660 | 662 | ||
@@ -740,7 +742,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, | |||
740 | struct exynos_drm_plane *plane) | 742 | struct exynos_drm_plane *plane) |
741 | { | 743 | { |
742 | struct fimd_context *ctx = crtc->ctx; | 744 | struct fimd_context *ctx = crtc->ctx; |
743 | unsigned int win = plane->zpos; | 745 | unsigned int win = plane->index; |
744 | 746 | ||
745 | if (ctx->suspended) | 747 | if (ctx->suspended) |
746 | return; | 748 | return; |
@@ -944,7 +946,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) | |||
944 | ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); | 946 | ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); |
945 | ctx->configs[i].zpos = i; | 947 | ctx->configs[i].zpos = i; |
946 | ctx->configs[i].type = fimd_win_types[i]; | 948 | ctx->configs[i].type = fimd_win_types[i]; |
947 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], | 949 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, |
948 | 1 << ctx->pipe, &ctx->configs[i]); | 950 | 1 << ctx->pipe, &ctx->configs[i]); |
949 | if (ret) | 951 | if (ret) |
950 | return ret; | 952 | return ret; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index e668fcdbcafc..d86227236f55 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -124,6 +124,7 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) | |||
124 | 124 | ||
125 | static void exynos_drm_plane_reset(struct drm_plane *plane) | 125 | static void exynos_drm_plane_reset(struct drm_plane *plane) |
126 | { | 126 | { |
127 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | ||
127 | struct exynos_drm_plane_state *exynos_state; | 128 | struct exynos_drm_plane_state *exynos_state; |
128 | 129 | ||
129 | if (plane->state) { | 130 | if (plane->state) { |
@@ -136,6 +137,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane) | |||
136 | 137 | ||
137 | exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL); | 138 | exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL); |
138 | if (exynos_state) { | 139 | if (exynos_state) { |
140 | exynos_state->zpos = exynos_plane->config->zpos; | ||
139 | plane->state = &exynos_state->base; | 141 | plane->state = &exynos_state->base; |
140 | plane->state->plane = plane; | 142 | plane->state->plane = plane; |
141 | } | 143 | } |
@@ -153,6 +155,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane) | |||
153 | return NULL; | 155 | return NULL; |
154 | 156 | ||
155 | __drm_atomic_helper_plane_duplicate_state(plane, ©->base); | 157 | __drm_atomic_helper_plane_duplicate_state(plane, ©->base); |
158 | copy->zpos = exynos_state->zpos; | ||
156 | return ©->base; | 159 | return ©->base; |
157 | } | 160 | } |
158 | 161 | ||
@@ -165,13 +168,53 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane, | |||
165 | kfree(old_exynos_state); | 168 | kfree(old_exynos_state); |
166 | } | 169 | } |
167 | 170 | ||
171 | static int exynos_drm_plane_atomic_set_property(struct drm_plane *plane, | ||
172 | struct drm_plane_state *state, | ||
173 | struct drm_property *property, | ||
174 | uint64_t val) | ||
175 | { | ||
176 | struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); | ||
177 | struct exynos_drm_plane_state *exynos_state = | ||
178 | to_exynos_plane_state(state); | ||
179 | struct exynos_drm_private *dev_priv = plane->dev->dev_private; | ||
180 | const struct exynos_drm_plane_config *config = exynos_plane->config; | ||
181 | |||
182 | if (property == dev_priv->plane_zpos_property && | ||
183 | (config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS)) | ||
184 | exynos_state->zpos = val; | ||
185 | else | ||
186 | return -EINVAL; | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static int exynos_drm_plane_atomic_get_property(struct drm_plane *plane, | ||
192 | const struct drm_plane_state *state, | ||
193 | struct drm_property *property, | ||
194 | uint64_t *val) | ||
195 | { | ||
196 | const struct exynos_drm_plane_state *exynos_state = | ||
197 | container_of(state, const struct exynos_drm_plane_state, base); | ||
198 | struct exynos_drm_private *dev_priv = plane->dev->dev_private; | ||
199 | |||
200 | if (property == dev_priv->plane_zpos_property) | ||
201 | *val = exynos_state->zpos; | ||
202 | else | ||
203 | return -EINVAL; | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
168 | static struct drm_plane_funcs exynos_plane_funcs = { | 208 | static struct drm_plane_funcs exynos_plane_funcs = { |
169 | .update_plane = drm_atomic_helper_update_plane, | 209 | .update_plane = drm_atomic_helper_update_plane, |
170 | .disable_plane = drm_atomic_helper_disable_plane, | 210 | .disable_plane = drm_atomic_helper_disable_plane, |
171 | .destroy = drm_plane_cleanup, | 211 | .destroy = drm_plane_cleanup, |
212 | .set_property = drm_atomic_helper_plane_set_property, | ||
172 | .reset = exynos_drm_plane_reset, | 213 | .reset = exynos_drm_plane_reset, |
173 | .atomic_duplicate_state = exynos_drm_plane_duplicate_state, | 214 | .atomic_duplicate_state = exynos_drm_plane_duplicate_state, |
174 | .atomic_destroy_state = exynos_drm_plane_destroy_state, | 215 | .atomic_destroy_state = exynos_drm_plane_destroy_state, |
216 | .atomic_set_property = exynos_drm_plane_atomic_set_property, | ||
217 | .atomic_get_property = exynos_drm_plane_atomic_get_property, | ||
175 | }; | 218 | }; |
176 | 219 | ||
177 | static int | 220 | static int |
@@ -267,8 +310,8 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane, | |||
267 | 310 | ||
268 | prop = dev_priv->plane_zpos_property; | 311 | prop = dev_priv->plane_zpos_property; |
269 | if (!prop) { | 312 | if (!prop) { |
270 | prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, | 313 | prop = drm_property_create_range(dev, 0, "zpos", |
271 | "zpos", 0, MAX_PLANE - 1); | 314 | 0, MAX_PLANE - 1); |
272 | if (!prop) | 315 | if (!prop) |
273 | return; | 316 | return; |
274 | 317 | ||
@@ -280,7 +323,7 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane, | |||
280 | 323 | ||
281 | int exynos_plane_init(struct drm_device *dev, | 324 | int exynos_plane_init(struct drm_device *dev, |
282 | struct exynos_drm_plane *exynos_plane, | 325 | struct exynos_drm_plane *exynos_plane, |
283 | unsigned long possible_crtcs, | 326 | unsigned int index, unsigned long possible_crtcs, |
284 | const struct exynos_drm_plane_config *config) | 327 | const struct exynos_drm_plane_config *config) |
285 | { | 328 | { |
286 | int err; | 329 | int err; |
@@ -298,12 +341,10 @@ int exynos_plane_init(struct drm_device *dev, | |||
298 | 341 | ||
299 | drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs); | 342 | drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs); |
300 | 343 | ||
301 | exynos_plane->zpos = config->zpos; | 344 | exynos_plane->index = index; |
302 | exynos_plane->config = config; | 345 | exynos_plane->config = config; |
303 | 346 | ||
304 | if (config->type == DRM_PLANE_TYPE_OVERLAY) | 347 | exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos); |
305 | exynos_plane_attach_zpos_property(&exynos_plane->base, | ||
306 | config->zpos); | ||
307 | 348 | ||
308 | return 0; | 349 | return 0; |
309 | } | 350 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h index 0dd096548284..9aafad164cdf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.h +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h | |||
@@ -10,6 +10,6 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | int exynos_plane_init(struct drm_device *dev, | 12 | int exynos_plane_init(struct drm_device *dev, |
13 | struct exynos_drm_plane *exynos_plane, | 13 | struct exynos_drm_plane *exynos_plane, unsigned int index, |
14 | unsigned long possible_crtcs, | 14 | unsigned long possible_crtcs, |
15 | const struct exynos_drm_plane_config *config); | 15 | const struct exynos_drm_plane_config *config); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 0be29c1b2c05..62ac4e5fa51d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -461,7 +461,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) | |||
461 | plane_config.zpos = i; | 461 | plane_config.zpos = i; |
462 | plane_config.type = vidi_win_types[i]; | 462 | plane_config.type = vidi_win_types[i]; |
463 | 463 | ||
464 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], | 464 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, |
465 | 1 << ctx->pipe, &plane_config); | 465 | 1 << ctx->pipe, &plane_config); |
466 | if (ret) | 466 | if (ret) |
467 | return ret; | 467 | return ret; |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index dfb35e2da4db..b5fbc1cbf024 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -76,7 +76,9 @@ enum mixer_flag_bits { | |||
76 | 76 | ||
77 | static const uint32_t mixer_formats[] = { | 77 | static const uint32_t mixer_formats[] = { |
78 | DRM_FORMAT_XRGB4444, | 78 | DRM_FORMAT_XRGB4444, |
79 | DRM_FORMAT_ARGB4444, | ||
79 | DRM_FORMAT_XRGB1555, | 80 | DRM_FORMAT_XRGB1555, |
81 | DRM_FORMAT_ARGB1555, | ||
80 | DRM_FORMAT_RGB565, | 82 | DRM_FORMAT_RGB565, |
81 | DRM_FORMAT_XRGB8888, | 83 | DRM_FORMAT_XRGB8888, |
82 | DRM_FORMAT_ARGB8888, | 84 | DRM_FORMAT_ARGB8888, |
@@ -117,19 +119,22 @@ static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = { | |||
117 | .type = DRM_PLANE_TYPE_PRIMARY, | 119 | .type = DRM_PLANE_TYPE_PRIMARY, |
118 | .pixel_formats = mixer_formats, | 120 | .pixel_formats = mixer_formats, |
119 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), | 121 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), |
120 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE, | 122 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | |
123 | EXYNOS_DRM_PLANE_CAP_ZPOS, | ||
121 | }, { | 124 | }, { |
122 | .zpos = 1, | 125 | .zpos = 1, |
123 | .type = DRM_PLANE_TYPE_CURSOR, | 126 | .type = DRM_PLANE_TYPE_CURSOR, |
124 | .pixel_formats = mixer_formats, | 127 | .pixel_formats = mixer_formats, |
125 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), | 128 | .num_pixel_formats = ARRAY_SIZE(mixer_formats), |
126 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE, | 129 | .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE | |
130 | EXYNOS_DRM_PLANE_CAP_ZPOS, | ||
127 | }, { | 131 | }, { |
128 | .zpos = 2, | 132 | .zpos = 2, |
129 | .type = DRM_PLANE_TYPE_OVERLAY, | 133 | .type = DRM_PLANE_TYPE_OVERLAY, |
130 | .pixel_formats = vp_formats, | 134 | .pixel_formats = vp_formats, |
131 | .num_pixel_formats = ARRAY_SIZE(vp_formats), | 135 | .num_pixel_formats = ARRAY_SIZE(vp_formats), |
132 | .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE, | 136 | .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE | |
137 | EXYNOS_DRM_PLANE_CAP_ZPOS, | ||
133 | }, | 138 | }, |
134 | }; | 139 | }; |
135 | 140 | ||
@@ -162,6 +167,18 @@ static const u8 filter_cr_horiz_tap4[] = { | |||
162 | 70, 59, 48, 37, 27, 19, 11, 5, | 167 | 70, 59, 48, 37, 27, 19, 11, 5, |
163 | }; | 168 | }; |
164 | 169 | ||
170 | static inline bool is_alpha_format(unsigned int pixel_format) | ||
171 | { | ||
172 | switch (pixel_format) { | ||
173 | case DRM_FORMAT_ARGB8888: | ||
174 | case DRM_FORMAT_ARGB1555: | ||
175 | case DRM_FORMAT_ARGB4444: | ||
176 | return true; | ||
177 | default: | ||
178 | return false; | ||
179 | } | ||
180 | } | ||
181 | |||
165 | static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) | 182 | static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id) |
166 | { | 183 | { |
167 | return readl(res->vp_regs + reg_id); | 184 | return readl(res->vp_regs + reg_id); |
@@ -291,6 +308,37 @@ static void vp_default_filter(struct mixer_resources *res) | |||
291 | filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); | 308 | filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); |
292 | } | 309 | } |
293 | 310 | ||
311 | static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win, | ||
312 | bool alpha) | ||
313 | { | ||
314 | struct mixer_resources *res = &ctx->mixer_res; | ||
315 | u32 val; | ||
316 | |||
317 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ | ||
318 | if (alpha) { | ||
319 | /* blending based on pixel alpha */ | ||
320 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; | ||
321 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | ||
322 | } | ||
323 | mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), | ||
324 | val, MXR_GRP_CFG_MISC_MASK); | ||
325 | } | ||
326 | |||
327 | static void mixer_cfg_vp_blend(struct mixer_context *ctx) | ||
328 | { | ||
329 | struct mixer_resources *res = &ctx->mixer_res; | ||
330 | u32 val; | ||
331 | |||
332 | /* | ||
333 | * No blending at the moment since the NV12/NV21 pixelformats don't | ||
334 | * have an alpha channel. However the mixer supports a global alpha | ||
335 | * value for a layer. Once this functionality is exposed, we can | ||
336 | * support blending of the video layer through this. | ||
337 | */ | ||
338 | val = 0; | ||
339 | mixer_reg_write(res, MXR_VIDEO_CFG, val); | ||
340 | } | ||
341 | |||
294 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) | 342 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) |
295 | { | 343 | { |
296 | struct mixer_resources *res = &ctx->mixer_res; | 344 | struct mixer_resources *res = &ctx->mixer_res; |
@@ -372,7 +420,7 @@ static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height) | |||
372 | } | 420 | } |
373 | 421 | ||
374 | static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, | 422 | static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, |
375 | bool enable) | 423 | unsigned int priority, bool enable) |
376 | { | 424 | { |
377 | struct mixer_resources *res = &ctx->mixer_res; | 425 | struct mixer_resources *res = &ctx->mixer_res; |
378 | u32 val = enable ? ~0 : 0; | 426 | u32 val = enable ? ~0 : 0; |
@@ -380,20 +428,24 @@ static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win, | |||
380 | switch (win) { | 428 | switch (win) { |
381 | case 0: | 429 | case 0: |
382 | mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); | 430 | mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE); |
431 | mixer_reg_writemask(res, MXR_LAYER_CFG, | ||
432 | MXR_LAYER_CFG_GRP0_VAL(priority), | ||
433 | MXR_LAYER_CFG_GRP0_MASK); | ||
383 | break; | 434 | break; |
384 | case 1: | 435 | case 1: |
385 | mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); | 436 | mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE); |
437 | mixer_reg_writemask(res, MXR_LAYER_CFG, | ||
438 | MXR_LAYER_CFG_GRP1_VAL(priority), | ||
439 | MXR_LAYER_CFG_GRP1_MASK); | ||
386 | break; | 440 | break; |
387 | case 2: | 441 | case VP_DEFAULT_WIN: |
388 | if (ctx->vp_enabled) { | 442 | if (ctx->vp_enabled) { |
389 | vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); | 443 | vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON); |
390 | mixer_reg_writemask(res, MXR_CFG, val, | 444 | mixer_reg_writemask(res, MXR_CFG, val, |
391 | MXR_CFG_VP_ENABLE); | 445 | MXR_CFG_VP_ENABLE); |
392 | 446 | mixer_reg_writemask(res, MXR_LAYER_CFG, | |
393 | /* control blending of graphic layer 0 */ | 447 | MXR_LAYER_CFG_VP_VAL(priority), |
394 | mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val, | 448 | MXR_LAYER_CFG_VP_MASK); |
395 | MXR_GRP_CFG_BLEND_PRE_MUL | | ||
396 | MXR_GRP_CFG_PIXEL_BLEND_EN); | ||
397 | } | 449 | } |
398 | break; | 450 | break; |
399 | } | 451 | } |
@@ -464,7 +516,6 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
464 | } | 516 | } |
465 | 517 | ||
466 | spin_lock_irqsave(&res->reg_slock, flags); | 518 | spin_lock_irqsave(&res->reg_slock, flags); |
467 | mixer_vsync_set_update(ctx, false); | ||
468 | 519 | ||
469 | /* interlace or progressive scan mode */ | 520 | /* interlace or progressive scan mode */ |
470 | val = (ctx->interlace ? ~0 : 0); | 521 | val = (ctx->interlace ? ~0 : 0); |
@@ -511,10 +562,10 @@ static void vp_video_buffer(struct mixer_context *ctx, | |||
511 | 562 | ||
512 | mixer_cfg_scan(ctx, mode->vdisplay); | 563 | mixer_cfg_scan(ctx, mode->vdisplay); |
513 | mixer_cfg_rgb_fmt(ctx, mode->vdisplay); | 564 | mixer_cfg_rgb_fmt(ctx, mode->vdisplay); |
514 | mixer_cfg_layer(ctx, plane->zpos, true); | 565 | mixer_cfg_layer(ctx, plane->index, state->zpos + 1, true); |
566 | mixer_cfg_vp_blend(ctx); | ||
515 | mixer_run(ctx); | 567 | mixer_run(ctx); |
516 | 568 | ||
517 | mixer_vsync_set_update(ctx, true); | ||
518 | spin_unlock_irqrestore(&res->reg_slock, flags); | 569 | spin_unlock_irqrestore(&res->reg_slock, flags); |
519 | 570 | ||
520 | mixer_regs_dump(ctx); | 571 | mixer_regs_dump(ctx); |
@@ -537,7 +588,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
537 | struct mixer_resources *res = &ctx->mixer_res; | 588 | struct mixer_resources *res = &ctx->mixer_res; |
538 | struct drm_framebuffer *fb = state->base.fb; | 589 | struct drm_framebuffer *fb = state->base.fb; |
539 | unsigned long flags; | 590 | unsigned long flags; |
540 | unsigned int win = plane->zpos; | 591 | unsigned int win = plane->index; |
541 | unsigned int x_ratio = 0, y_ratio = 0; | 592 | unsigned int x_ratio = 0, y_ratio = 0; |
542 | unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; | 593 | unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset; |
543 | dma_addr_t dma_addr; | 594 | dma_addr_t dma_addr; |
@@ -546,10 +597,12 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
546 | 597 | ||
547 | switch (fb->pixel_format) { | 598 | switch (fb->pixel_format) { |
548 | case DRM_FORMAT_XRGB4444: | 599 | case DRM_FORMAT_XRGB4444: |
600 | case DRM_FORMAT_ARGB4444: | ||
549 | fmt = MXR_FORMAT_ARGB4444; | 601 | fmt = MXR_FORMAT_ARGB4444; |
550 | break; | 602 | break; |
551 | 603 | ||
552 | case DRM_FORMAT_XRGB1555: | 604 | case DRM_FORMAT_XRGB1555: |
605 | case DRM_FORMAT_ARGB1555: | ||
553 | fmt = MXR_FORMAT_ARGB1555; | 606 | fmt = MXR_FORMAT_ARGB1555; |
554 | break; | 607 | break; |
555 | 608 | ||
@@ -587,7 +640,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
587 | ctx->interlace = false; | 640 | ctx->interlace = false; |
588 | 641 | ||
589 | spin_lock_irqsave(&res->reg_slock, flags); | 642 | spin_lock_irqsave(&res->reg_slock, flags); |
590 | mixer_vsync_set_update(ctx, false); | ||
591 | 643 | ||
592 | /* setup format */ | 644 | /* setup format */ |
593 | mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), | 645 | mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win), |
@@ -626,7 +678,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
626 | 678 | ||
627 | mixer_cfg_scan(ctx, mode->vdisplay); | 679 | mixer_cfg_scan(ctx, mode->vdisplay); |
628 | mixer_cfg_rgb_fmt(ctx, mode->vdisplay); | 680 | mixer_cfg_rgb_fmt(ctx, mode->vdisplay); |
629 | mixer_cfg_layer(ctx, win, true); | 681 | mixer_cfg_layer(ctx, win, state->zpos + 1, true); |
682 | mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->pixel_format)); | ||
630 | 683 | ||
631 | /* layer update mandatory for mixer 16.0.33.0 */ | 684 | /* layer update mandatory for mixer 16.0.33.0 */ |
632 | if (ctx->mxr_ver == MXR_VER_16_0_33_0 || | 685 | if (ctx->mxr_ver == MXR_VER_16_0_33_0 || |
@@ -635,7 +688,6 @@ static void mixer_graph_buffer(struct mixer_context *ctx, | |||
635 | 688 | ||
636 | mixer_run(ctx); | 689 | mixer_run(ctx); |
637 | 690 | ||
638 | mixer_vsync_set_update(ctx, true); | ||
639 | spin_unlock_irqrestore(&res->reg_slock, flags); | 691 | spin_unlock_irqrestore(&res->reg_slock, flags); |
640 | 692 | ||
641 | mixer_regs_dump(ctx); | 693 | mixer_regs_dump(ctx); |
@@ -660,10 +712,8 @@ static void mixer_win_reset(struct mixer_context *ctx) | |||
660 | { | 712 | { |
661 | struct mixer_resources *res = &ctx->mixer_res; | 713 | struct mixer_resources *res = &ctx->mixer_res; |
662 | unsigned long flags; | 714 | unsigned long flags; |
663 | u32 val; /* value stored to register */ | ||
664 | 715 | ||
665 | spin_lock_irqsave(&res->reg_slock, flags); | 716 | spin_lock_irqsave(&res->reg_slock, flags); |
666 | mixer_vsync_set_update(ctx, false); | ||
667 | 717 | ||
668 | mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); | 718 | mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK); |
669 | 719 | ||
@@ -674,40 +724,14 @@ static void mixer_win_reset(struct mixer_context *ctx) | |||
674 | mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, | 724 | mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, |
675 | MXR_STATUS_BURST_MASK); | 725 | MXR_STATUS_BURST_MASK); |
676 | 726 | ||
677 | /* setting default layer priority: layer1 > layer0 > video | 727 | /* reset default layer priority */ |
678 | * because typical usage scenario would be | 728 | mixer_reg_write(res, MXR_LAYER_CFG, 0); |
679 | * layer1 - OSD | ||
680 | * layer0 - framebuffer | ||
681 | * video - video overlay | ||
682 | */ | ||
683 | val = MXR_LAYER_CFG_GRP1_VAL(3); | ||
684 | val |= MXR_LAYER_CFG_GRP0_VAL(2); | ||
685 | if (ctx->vp_enabled) | ||
686 | val |= MXR_LAYER_CFG_VP_VAL(1); | ||
687 | mixer_reg_write(res, MXR_LAYER_CFG, val); | ||
688 | 729 | ||
689 | /* setting background color */ | 730 | /* setting background color */ |
690 | mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); | 731 | mixer_reg_write(res, MXR_BG_COLOR0, 0x008080); |
691 | mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); | 732 | mixer_reg_write(res, MXR_BG_COLOR1, 0x008080); |
692 | mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); | 733 | mixer_reg_write(res, MXR_BG_COLOR2, 0x008080); |
693 | 734 | ||
694 | /* setting graphical layers */ | ||
695 | val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */ | ||
696 | val |= MXR_GRP_CFG_WIN_BLEND_EN; | ||
697 | val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */ | ||
698 | |||
699 | /* Don't blend layer 0 onto the mixer background */ | ||
700 | mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val); | ||
701 | |||
702 | /* Blend layer 1 into layer 0 */ | ||
703 | val |= MXR_GRP_CFG_BLEND_PRE_MUL; | ||
704 | val |= MXR_GRP_CFG_PIXEL_BLEND_EN; | ||
705 | mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val); | ||
706 | |||
707 | /* setting video layers */ | ||
708 | val = MXR_GRP_CFG_ALPHA_VAL(0); | ||
709 | mixer_reg_write(res, MXR_VIDEO_CFG, val); | ||
710 | |||
711 | if (ctx->vp_enabled) { | 735 | if (ctx->vp_enabled) { |
712 | /* configuration of Video Processor Registers */ | 736 | /* configuration of Video Processor Registers */ |
713 | vp_win_reset(ctx); | 737 | vp_win_reset(ctx); |
@@ -720,7 +744,6 @@ static void mixer_win_reset(struct mixer_context *ctx) | |||
720 | if (ctx->vp_enabled) | 744 | if (ctx->vp_enabled) |
721 | mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); | 745 | mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE); |
722 | 746 | ||
723 | mixer_vsync_set_update(ctx, true); | ||
724 | spin_unlock_irqrestore(&res->reg_slock, flags); | 747 | spin_unlock_irqrestore(&res->reg_slock, flags); |
725 | } | 748 | } |
726 | 749 | ||
@@ -951,17 +974,27 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc) | |||
951 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); | 974 | mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC); |
952 | } | 975 | } |
953 | 976 | ||
977 | static void mixer_atomic_begin(struct exynos_drm_crtc *crtc) | ||
978 | { | ||
979 | struct mixer_context *mixer_ctx = crtc->ctx; | ||
980 | |||
981 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) | ||
982 | return; | ||
983 | |||
984 | mixer_vsync_set_update(mixer_ctx, false); | ||
985 | } | ||
986 | |||
954 | static void mixer_update_plane(struct exynos_drm_crtc *crtc, | 987 | static void mixer_update_plane(struct exynos_drm_crtc *crtc, |
955 | struct exynos_drm_plane *plane) | 988 | struct exynos_drm_plane *plane) |
956 | { | 989 | { |
957 | struct mixer_context *mixer_ctx = crtc->ctx; | 990 | struct mixer_context *mixer_ctx = crtc->ctx; |
958 | 991 | ||
959 | DRM_DEBUG_KMS("win: %d\n", plane->zpos); | 992 | DRM_DEBUG_KMS("win: %d\n", plane->index); |
960 | 993 | ||
961 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) | 994 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) |
962 | return; | 995 | return; |
963 | 996 | ||
964 | if (plane->zpos > 1 && mixer_ctx->vp_enabled) | 997 | if (plane->index == VP_DEFAULT_WIN) |
965 | vp_video_buffer(mixer_ctx, plane); | 998 | vp_video_buffer(mixer_ctx, plane); |
966 | else | 999 | else |
967 | mixer_graph_buffer(mixer_ctx, plane); | 1000 | mixer_graph_buffer(mixer_ctx, plane); |
@@ -974,18 +1007,24 @@ static void mixer_disable_plane(struct exynos_drm_crtc *crtc, | |||
974 | struct mixer_resources *res = &mixer_ctx->mixer_res; | 1007 | struct mixer_resources *res = &mixer_ctx->mixer_res; |
975 | unsigned long flags; | 1008 | unsigned long flags; |
976 | 1009 | ||
977 | DRM_DEBUG_KMS("win: %d\n", plane->zpos); | 1010 | DRM_DEBUG_KMS("win: %d\n", plane->index); |
978 | 1011 | ||
979 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) | 1012 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) |
980 | return; | 1013 | return; |
981 | 1014 | ||
982 | spin_lock_irqsave(&res->reg_slock, flags); | 1015 | spin_lock_irqsave(&res->reg_slock, flags); |
983 | mixer_vsync_set_update(mixer_ctx, false); | 1016 | mixer_cfg_layer(mixer_ctx, plane->index, 0, false); |
1017 | spin_unlock_irqrestore(&res->reg_slock, flags); | ||
1018 | } | ||
984 | 1019 | ||
985 | mixer_cfg_layer(mixer_ctx, plane->zpos, false); | 1020 | static void mixer_atomic_flush(struct exynos_drm_crtc *crtc) |
1021 | { | ||
1022 | struct mixer_context *mixer_ctx = crtc->ctx; | ||
1023 | |||
1024 | if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags)) | ||
1025 | return; | ||
986 | 1026 | ||
987 | mixer_vsync_set_update(mixer_ctx, true); | 1027 | mixer_vsync_set_update(mixer_ctx, true); |
988 | spin_unlock_irqrestore(&res->reg_slock, flags); | ||
989 | } | 1028 | } |
990 | 1029 | ||
991 | static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) | 1030 | static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc) |
@@ -1026,6 +1065,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) | |||
1026 | 1065 | ||
1027 | pm_runtime_get_sync(ctx->dev); | 1066 | pm_runtime_get_sync(ctx->dev); |
1028 | 1067 | ||
1068 | mixer_vsync_set_update(ctx, false); | ||
1069 | |||
1029 | mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); | 1070 | mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET); |
1030 | 1071 | ||
1031 | if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) { | 1072 | if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) { |
@@ -1034,6 +1075,8 @@ static void mixer_enable(struct exynos_drm_crtc *crtc) | |||
1034 | } | 1075 | } |
1035 | mixer_win_reset(ctx); | 1076 | mixer_win_reset(ctx); |
1036 | 1077 | ||
1078 | mixer_vsync_set_update(ctx, true); | ||
1079 | |||
1037 | set_bit(MXR_BIT_POWERED, &ctx->flags); | 1080 | set_bit(MXR_BIT_POWERED, &ctx->flags); |
1038 | } | 1081 | } |
1039 | 1082 | ||
@@ -1084,8 +1127,10 @@ static const struct exynos_drm_crtc_ops mixer_crtc_ops = { | |||
1084 | .enable_vblank = mixer_enable_vblank, | 1127 | .enable_vblank = mixer_enable_vblank, |
1085 | .disable_vblank = mixer_disable_vblank, | 1128 | .disable_vblank = mixer_disable_vblank, |
1086 | .wait_for_vblank = mixer_wait_for_vblank, | 1129 | .wait_for_vblank = mixer_wait_for_vblank, |
1130 | .atomic_begin = mixer_atomic_begin, | ||
1087 | .update_plane = mixer_update_plane, | 1131 | .update_plane = mixer_update_plane, |
1088 | .disable_plane = mixer_disable_plane, | 1132 | .disable_plane = mixer_disable_plane, |
1133 | .atomic_flush = mixer_atomic_flush, | ||
1089 | .atomic_check = mixer_atomic_check, | 1134 | .atomic_check = mixer_atomic_check, |
1090 | }; | 1135 | }; |
1091 | 1136 | ||
@@ -1160,7 +1205,7 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) | |||
1160 | if (i == VP_DEFAULT_WIN && !ctx->vp_enabled) | 1205 | if (i == VP_DEFAULT_WIN && !ctx->vp_enabled) |
1161 | continue; | 1206 | continue; |
1162 | 1207 | ||
1163 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], | 1208 | ret = exynos_plane_init(drm_dev, &ctx->planes[i], i, |
1164 | 1 << ctx->pipe, &plane_configs[i]); | 1209 | 1 << ctx->pipe, &plane_configs[i]); |
1165 | if (ret) | 1210 | if (ret) |
1166 | return ret; | 1211 | return ret; |
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h index ac60260c2389..7f22df5bf707 100644 --- a/drivers/gpu/drm/exynos/regs-mixer.h +++ b/drivers/gpu/drm/exynos/regs-mixer.h | |||
@@ -113,6 +113,7 @@ | |||
113 | #define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) | 113 | #define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) |
114 | #define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) | 114 | #define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) |
115 | #define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) | 115 | #define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) |
116 | #define MXR_GRP_CFG_MISC_MASK ((3 << 16) | (3 << 20)) | ||
116 | #define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) | 117 | #define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) |
117 | #define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) | 118 | #define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) |
118 | #define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) | 119 | #define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) |
@@ -145,8 +146,11 @@ | |||
145 | 146 | ||
146 | /* bit for MXR_LAYER_CFG */ | 147 | /* bit for MXR_LAYER_CFG */ |
147 | #define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8) | 148 | #define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8) |
149 | #define MXR_LAYER_CFG_GRP1_MASK MXR_LAYER_CFG_GRP1_VAL(~0) | ||
148 | #define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4) | 150 | #define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4) |
151 | #define MXR_LAYER_CFG_GRP0_MASK MXR_LAYER_CFG_GRP0_VAL(~0) | ||
149 | #define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0) | 152 | #define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0) |
153 | #define MXR_LAYER_CFG_VP_MASK MXR_LAYER_CFG_VP_VAL(~0) | ||
150 | 154 | ||
151 | #endif /* SAMSUNG_REGS_MIXER_H */ | 155 | #endif /* SAMSUNG_REGS_MIXER_H */ |
152 | 156 | ||