/* The (potentially) asynchronous part of the commit. At this point * nothing can fail short of armageddon. */ static void complete_commit(struct msm_commit *c) { struct drm_atomic_state *state = c->state; struct drm_device *dev = state->dev; drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_planes(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state); /* NOTE: _wait_for_vblanks() only waits for vblank on * enabled CRTCs. So we end up faulting when disabling * due to (potentially) unref'ing the outgoing fb's * before the vblank when the disable has latched. * * But if it did wait on disabled (or newly disabled) * CRTCs, that would be racy (ie. we could have missed * the irq. We need some way to poll for pipe shut * down. Or just live with occasionally hitting the * timeout in the CRTC disable path (which really should * not be critical path) */ drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_state_free(state); end_atomic(dev->dev_private, c->crtc_mask); kfree(c); }
static void atmel_hlcdc_dc_atomic_complete(struct atmel_hlcdc_dc_commit *commit) { struct drm_device *dev = commit->dev; struct atmel_hlcdc_dc *dc = dev->dev_private; struct drm_atomic_state *old_state = commit->state; /* Apply the atomic update. */ drm_atomic_helper_commit_modeset_disables(dev, old_state); drm_atomic_helper_commit_planes(dev, old_state, 0); drm_atomic_helper_commit_modeset_enables(dev, old_state); drm_atomic_helper_wait_for_vblanks(dev, old_state); drm_atomic_helper_cleanup_planes(dev, old_state); drm_atomic_state_free(old_state); /* Complete the commit, wake up any waiter. */ spin_lock(&dc->commit.wait.lock); dc->commit.pending = false; wake_up_all_locked(&dc->commit.wait); spin_unlock(&dc->commit.wait.lock); kfree(commit); }
static void vgdev_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_planes(dev, state, 0); drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); }
/** * intel_atomic_commit - commit validated state object * @dev: DRM device * @state: the top-level driver state object * @async: asynchronous commit * * This function commits a top-level state object that has been validated * with drm_atomic_helper_check(). * * FIXME: Atomic modeset support for i915 is not yet complete. At the moment * we can only handle plane-related operations and do not yet support * asynchronous commit. * * RETURNS * Zero for success or -errno. */ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool async) { int ret; int i; if (async) { DRM_DEBUG_KMS("i915 does not yet support async commit\n"); return -EINVAL; } ret = drm_atomic_helper_prepare_planes(dev, state); if (ret) return ret; /* Point of no return */ /* * FIXME: The proper sequence here will eventually be: * * drm_atomic_helper_swap_state(dev, state) * drm_atomic_helper_commit_pre_planes(dev, state); * drm_atomic_helper_commit_planes(dev, state); * drm_atomic_helper_commit_post_planes(dev, state); * drm_atomic_helper_wait_for_vblanks(dev, state); * drm_atomic_helper_cleanup_planes(dev, state); * drm_atomic_state_free(state); * * once we have full atomic modeset. For now, just manually update * plane states to avoid clobbering good states with dummy states * while nuclear pageflipping. */ for (i = 0; i < dev->mode_config.num_total_plane; i++) { struct drm_plane *plane = state->planes[i]; if (!plane) continue; plane->state->state = state; swap(state->plane_states[i], plane->state); plane->state->state = NULL; } drm_atomic_helper_commit_planes(dev, state); drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_state_free(state); return 0; }
static void malidp_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *drm = state->dev; drm_atomic_helper_commit_modeset_disables(drm, state); drm_atomic_helper_commit_modeset_enables(drm, state); drm_atomic_helper_commit_planes(drm, state, true); malidp_atomic_commit_hw_done(state); drm_atomic_helper_wait_for_vblanks(drm, state); drm_atomic_helper_cleanup_planes(drm, state); }
static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); int i; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; drm_atomic_helper_wait_for_vblanks(mdp4_kms->dev, state); /* see 119ecb7fd */ for_each_new_crtc_in_state(state, crtc, crtc_state, i) drm_crtc_vblank_put(crtc); mdp4_disable(mdp4_kms); }
static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct device *dev = &mdp5_kms->pdev->dev; struct mdp5_global_state *global_state; drm_atomic_helper_wait_for_vblanks(mdp5_kms->dev, state); global_state = mdp5_get_existing_global_state(mdp5_kms); if (mdp5_kms->smp) mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp); pm_runtime_put_sync(dev); }
static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state) { struct drm_device *drm = old_state->dev; struct tegra_drm *tegra = drm->dev_private; if (tegra->hub) { drm_atomic_helper_commit_modeset_disables(drm, old_state); tegra_display_hub_atomic_commit(drm, old_state); drm_atomic_helper_commit_planes(drm, old_state, 0); drm_atomic_helper_commit_modeset_enables(drm, old_state); drm_atomic_helper_commit_hw_done(old_state); drm_atomic_helper_wait_for_vblanks(drm, old_state); drm_atomic_helper_cleanup_planes(drm, old_state); } else { drm_atomic_helper_commit_tail_rpm(old_state); } }
static void rockchip_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_modeset_enables(dev, state); drm_atomic_helper_commit_planes(dev, state, DRM_PLANE_COMMIT_ACTIVE_ONLY); drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_cleanup_planes(dev, state); }
void msm_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; struct msm_drm_private *priv = dev->dev_private; struct msm_kms *kms = priv->kms; kms->funcs->prepare_commit(kms, state); drm_atomic_helper_commit_modeset_disables(dev, state); drm_atomic_helper_commit_planes(dev, state, 0); drm_atomic_helper_commit_modeset_enables(dev, state); msm_atomic_wait_for_commit_done(dev, state); kms->funcs->complete_commit(kms, state); drm_atomic_helper_wait_for_vblanks(dev, state); drm_atomic_helper_commit_hw_done(state); drm_atomic_helper_cleanup_planes(dev, state); }