1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2014 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7 #include <drm/drm_atomic_uapi.h> 8 9 #include "msm_drv.h" 10 #include "msm_gem.h" 11 #include "msm_kms.h" 12 13 static void msm_atomic_wait_for_commit_done(struct drm_device *dev, 14 struct drm_atomic_state *old_state) 15 { 16 struct drm_crtc *crtc; 17 struct drm_crtc_state *new_crtc_state; 18 struct msm_drm_private *priv = old_state->dev->dev_private; 19 struct msm_kms *kms = priv->kms; 20 int i; 21 22 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) { 23 if (!new_crtc_state->active) 24 continue; 25 26 if (drm_crtc_vblank_get(crtc)) 27 continue; 28 29 kms->funcs->wait_for_crtc_commit_done(kms, crtc); 30 31 drm_crtc_vblank_put(crtc); 32 } 33 } 34 35 int msm_atomic_prepare_fb(struct drm_plane *plane, 36 struct drm_plane_state *new_state) 37 { 38 struct msm_drm_private *priv = plane->dev->dev_private; 39 struct msm_kms *kms = priv->kms; 40 struct drm_gem_object *obj; 41 struct dma_fence *fence; 42 43 if (!new_state->fb) 44 return 0; 45 46 obj = msm_framebuffer_bo(new_state->fb, 0); 47 fence = reservation_object_get_excl_rcu(obj->resv); 48 49 drm_atomic_set_fence_for_plane(new_state, fence); 50 51 return msm_framebuffer_prepare(new_state->fb, kms->aspace); 52 } 53 54 void msm_atomic_commit_tail(struct drm_atomic_state *state) 55 { 56 struct drm_device *dev = state->dev; 57 struct msm_drm_private *priv = dev->dev_private; 58 struct msm_kms *kms = priv->kms; 59 60 kms->funcs->prepare_commit(kms, state); 61 62 drm_atomic_helper_commit_modeset_disables(dev, state); 63 64 drm_atomic_helper_commit_planes(dev, state, 0); 65 66 drm_atomic_helper_commit_modeset_enables(dev, state); 67 68 if (kms->funcs->commit) { 69 DRM_DEBUG_ATOMIC("triggering commit\n"); 70 kms->funcs->commit(kms, state); 71 } 72 73 if (!state->legacy_cursor_update) 74 msm_atomic_wait_for_commit_done(dev, state); 75 76 kms->funcs->complete_commit(kms, state); 77 78 drm_atomic_helper_commit_hw_done(state); 79 80 drm_atomic_helper_cleanup_planes(dev, state); 81 } 82