Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/mediatek: update cursors by using async atomic update

Support to async updates of cursors by using the new atomic
interface for that.

Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Signed-off-by: CK Hu <ck.hu@mediatek.com>

authored by

Bibby Hsieh and committed by
CK Hu
920fffcc 411f5c1e

+128 -21
+77 -21
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
··· 42 42 struct drm_plane *planes; 43 43 unsigned int layer_nr; 44 44 bool pending_planes; 45 + bool pending_async_planes; 45 46 46 47 void __iomem *config_regs; 47 48 struct mtk_disp_mutex *mutex; 48 49 unsigned int ddp_comp_nr; 49 50 struct mtk_ddp_comp **ddp_comp; 51 + 52 + /* lock for display hardware access */ 53 + struct mutex hw_lock; 50 54 }; 51 55 52 56 struct mtk_crtc_state { ··· 408 404 } 409 405 mtk_crtc->pending_planes = false; 410 406 } 407 + 408 + if (mtk_crtc->pending_async_planes) { 409 + for (i = 0; i < mtk_crtc->layer_nr; i++) { 410 + struct drm_plane *plane = &mtk_crtc->planes[i]; 411 + struct mtk_plane_state *plane_state; 412 + 413 + plane_state = to_mtk_plane_state(plane->state); 414 + 415 + if (!plane_state->pending.async_config) 416 + continue; 417 + 418 + comp = mtk_drm_ddp_comp_for_plane(crtc, plane, 419 + &local_layer); 420 + 421 + if (comp) 422 + mtk_ddp_comp_layer_config(comp, local_layer, 423 + plane_state); 424 + plane_state->pending.async_config = false; 425 + } 426 + mtk_crtc->pending_async_planes = false; 427 + } 428 + } 429 + 430 + static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc) 431 + { 432 + struct drm_crtc *crtc = &mtk_crtc->base; 433 + struct mtk_drm_private *priv = crtc->dev->dev_private; 434 + unsigned int pending_planes = 0, pending_async_planes = 0; 435 + int i; 436 + 437 + mutex_lock(&mtk_crtc->hw_lock); 438 + for (i = 0; i < mtk_crtc->layer_nr; i++) { 439 + struct drm_plane *plane = &mtk_crtc->planes[i]; 440 + struct mtk_plane_state *plane_state; 441 + 442 + plane_state = to_mtk_plane_state(plane->state); 443 + if (plane_state->pending.dirty) { 444 + plane_state->pending.config = true; 445 + plane_state->pending.dirty = false; 446 + pending_planes |= BIT(i); 447 + } else if (plane_state->pending.async_dirty) { 448 + plane_state->pending.async_config = true; 449 + plane_state->pending.async_dirty = false; 450 + pending_async_planes |= BIT(i); 451 + } 452 + } 453 + if (pending_planes) 454 + mtk_crtc->pending_planes = true; 455 + if (pending_async_planes) 456 + mtk_crtc->pending_async_planes = true; 457 + 458 + if (priv->data->shadow_register) { 459 + mtk_disp_mutex_acquire(mtk_crtc->mutex); 460 + mtk_crtc_ddp_config(crtc); 461 + mtk_disp_mutex_release(mtk_crtc->mutex); 462 + } 463 + mutex_unlock(&mtk_crtc->hw_lock); 411 464 } 412 465 413 466 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane, ··· 477 416 if (comp) 478 417 return mtk_ddp_comp_layer_check(comp, local_layer, state); 479 418 return 0; 419 + } 420 + 421 + void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane, 422 + struct drm_plane_state *new_state) 423 + { 424 + struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); 425 + const struct drm_plane_helper_funcs *plane_helper_funcs = 426 + plane->helper_private; 427 + 428 + if (!mtk_crtc->enabled) 429 + return; 430 + 431 + plane_helper_funcs->atomic_update(plane, new_state); 432 + mtk_drm_crtc_hw_config(mtk_crtc); 480 433 } 481 434 482 435 static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc, ··· 571 496 struct drm_crtc_state *old_crtc_state) 572 497 { 573 498 struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); 574 - struct mtk_drm_private *priv = crtc->dev->dev_private; 575 - unsigned int pending_planes = 0; 576 499 int i; 577 500 578 501 if (mtk_crtc->event) 579 502 mtk_crtc->pending_needs_vblank = true; 580 - for (i = 0; i < mtk_crtc->layer_nr; i++) { 581 - struct drm_plane *plane = &mtk_crtc->planes[i]; 582 - struct mtk_plane_state *plane_state; 583 - 584 - plane_state = to_mtk_plane_state(plane->state); 585 - if (plane_state->pending.dirty) { 586 - plane_state->pending.config = true; 587 - plane_state->pending.dirty = false; 588 - pending_planes |= BIT(i); 589 - } 590 - } 591 - if (pending_planes) 592 - mtk_crtc->pending_planes = true; 593 503 if (crtc->state->color_mgmt_changed) 594 504 for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) 595 505 mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state); 596 - 597 - if (priv->data->shadow_register) { 598 - mtk_disp_mutex_acquire(mtk_crtc->mutex); 599 - mtk_crtc_ddp_config(crtc); 600 - mtk_disp_mutex_release(mtk_crtc->mutex); 601 - } 506 + mtk_drm_crtc_hw_config(mtk_crtc); 602 507 } 603 508 604 509 static const struct drm_crtc_funcs mtk_crtc_funcs = { ··· 769 714 drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); 770 715 drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE); 771 716 priv->num_pipes++; 717 + mutex_init(&mtk_crtc->hw_lock); 772 718 773 719 return 0; 774 720 }
+2
drivers/gpu/drm/mediatek/mtk_drm_crtc.h
··· 21 21 unsigned int path_len); 22 22 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane, 23 23 struct mtk_plane_state *state); 24 + void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane, 25 + struct drm_plane_state *plane_state); 24 26 25 27 #endif /* MTK_DRM_CRTC_H */
+47
drivers/gpu/drm/mediatek/mtk_drm_plane.c
··· 7 7 #include <drm/drm_atomic.h> 8 8 #include <drm/drm_atomic_helper.h> 9 9 #include <drm/drm_fourcc.h> 10 + #include <drm/drm_atomic_uapi.h> 10 11 #include <drm/drm_plane_helper.h> 11 12 #include <drm/drm_gem_framebuffer_helper.h> 12 13 ··· 75 74 { 76 75 __drm_atomic_helper_plane_destroy_state(state); 77 76 kfree(to_mtk_plane_state(state)); 77 + } 78 + 79 + static int mtk_plane_atomic_async_check(struct drm_plane *plane, 80 + struct drm_plane_state *state) 81 + { 82 + struct drm_crtc_state *crtc_state; 83 + 84 + if (plane != state->crtc->cursor) 85 + return -EINVAL; 86 + 87 + if (!plane->state) 88 + return -EINVAL; 89 + 90 + if (!plane->state->fb) 91 + return -EINVAL; 92 + 93 + if (state->state) 94 + crtc_state = drm_atomic_get_existing_crtc_state(state->state, 95 + state->crtc); 96 + else /* Special case for asynchronous cursor updates. */ 97 + crtc_state = state->crtc->state; 98 + 99 + return drm_atomic_helper_check_plane_state(plane->state, crtc_state, 100 + DRM_PLANE_HELPER_NO_SCALING, 101 + DRM_PLANE_HELPER_NO_SCALING, 102 + true, true); 103 + } 104 + 105 + static void mtk_plane_atomic_async_update(struct drm_plane *plane, 106 + struct drm_plane_state *new_state) 107 + { 108 + struct mtk_plane_state *state = to_mtk_plane_state(plane->state); 109 + 110 + plane->state->crtc_x = new_state->crtc_x; 111 + plane->state->crtc_y = new_state->crtc_y; 112 + plane->state->crtc_h = new_state->crtc_h; 113 + plane->state->crtc_w = new_state->crtc_w; 114 + plane->state->src_x = new_state->src_x; 115 + plane->state->src_y = new_state->src_y; 116 + plane->state->src_h = new_state->src_h; 117 + plane->state->src_w = new_state->src_w; 118 + state->pending.async_dirty = true; 119 + 120 + mtk_drm_crtc_async_update(new_state->crtc, plane, new_state); 78 121 } 79 122 80 123 static const struct drm_plane_funcs mtk_plane_funcs = { ··· 209 164 .atomic_check = mtk_plane_atomic_check, 210 165 .atomic_update = mtk_plane_atomic_update, 211 166 .atomic_disable = mtk_plane_atomic_disable, 167 + .atomic_async_update = mtk_plane_atomic_async_update, 168 + .atomic_async_check = mtk_plane_atomic_async_check, 212 169 }; 213 170 214 171 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
+2
drivers/gpu/drm/mediatek/mtk_drm_plane.h
··· 22 22 unsigned int height; 23 23 unsigned int rotation; 24 24 bool dirty; 25 + bool async_dirty; 26 + bool async_config; 25 27 }; 26 28 27 29 struct mtk_plane_state {