Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 612fb5d9 authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher
Browse files

drm/nouveau/kms/nv50: Switch to using atomic helper for flip.



v2:
Update code after flip_flags moved from plane_state
to crtc_state

v5:
Rename to pageflip_flags.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAndrey Grodzovsky <Andrey.Grodzovsky@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1486072591-3893-3-git-send-email-Andrey.Grodzovsky@amd.com
parent 6cbe5c46
Loading
Loading
Loading
Loading
+10 −74
Original line number Diff line number Diff line
@@ -831,7 +831,8 @@ nv50_wndw_atomic_check_release(struct nv50_wndw *wndw,
static int
nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw,
			       struct nv50_wndw_atom *asyw,
			       struct nv50_head_atom *asyh)
			       struct nv50_head_atom *asyh,
			       u32 pflip_flags)
{
	struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb);
	struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev);
@@ -846,6 +847,9 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw,
	asyw->image.w = fb->base.width;
	asyw->image.h = fb->base.height;
	asyw->image.kind = (fb->nvbo->tile_flags & 0x0000ff00) >> 8;

	asyw->interval = pflip_flags & DRM_MODE_PAGE_FLIP_ASYNC ? 0 : 1;

	if (asyw->image.kind) {
		asyw->image.layout = 0;
		if (drm->device.info.chipset >= 0xc0)
@@ -883,6 +887,7 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
	struct nv50_head_atom *harm = NULL, *asyh = NULL;
	bool varm = false, asyv = false, asym = false;
	int ret;
	u32 pflip_flags = 0;

	NV_ATOMIC(drm, "%s atomic_check\n", plane->name);
	if (asyw->state.crtc) {
@@ -891,6 +896,7 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
			return PTR_ERR(asyh);
		asym = drm_atomic_crtc_needs_modeset(&asyh->state);
		asyv = asyh->state.active;
		pflip_flags = asyh->state.pageflip_flags;
	}

	if (armw->state.crtc) {
@@ -907,7 +913,8 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
			asyw->set.point = true;

		if (!varm || asym || armw->state.fb != asyw->state.fb) {
			ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh);
			ret = nv50_wndw_atomic_check_acquire(
					wndw, asyw, asyh, pflip_flags);
			if (ret)
				return ret;
		}
@@ -2219,77 +2226,6 @@ nv50_head_help = {
	.atomic_check = nv50_head_atomic_check,
};

/* This is identical to the version in the atomic helpers, except that
 * it supports non-vblanked ("async") page flips.
 */
static int
nv50_head_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
		    struct drm_pending_vblank_event *event, u32 flags)
{
	struct drm_plane *plane = crtc->primary;
	struct drm_atomic_state *state;
	struct drm_plane_state *plane_state;
	struct drm_crtc_state *crtc_state;
	int ret = 0;

	state = drm_atomic_state_alloc(plane->dev);
	if (!state)
		return -ENOMEM;

	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
	crtc_state = drm_atomic_get_crtc_state(state, crtc);
	if (IS_ERR(crtc_state)) {
		ret = PTR_ERR(crtc_state);
		goto fail;
	}
	crtc_state->event = event;

	plane_state = drm_atomic_get_plane_state(state, plane);
	if (IS_ERR(plane_state)) {
		ret = PTR_ERR(plane_state);
		goto fail;
	}

	ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
	if (ret != 0)
		goto fail;
	drm_atomic_set_fb_for_plane(plane_state, fb);

	/* Make sure we don't accidentally do a full modeset. */
	state->allow_modeset = false;
	if (!crtc_state->active) {
		DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n",
				 crtc->base.id);
		ret = -EINVAL;
		goto fail;
	}

	if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
		nv50_wndw_atom(plane_state)->interval = 0;

	ret = drm_atomic_nonblocking_commit(state);
fail:
	if (ret == -EDEADLK)
		goto backoff;

	drm_atomic_state_put(state);
	return ret;

backoff:
	drm_atomic_state_clear(state);
	drm_atomic_legacy_backoff(state);

	/*
	 * Someone might have exchanged the framebuffer while we dropped locks
	 * in the backoff code. We need to fix up the fb refcount tracking the
	 * core does for us.
	 */
	plane->old_fb = plane->fb;

	goto retry;
}

static int
nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
		    uint32_t size)
@@ -2384,7 +2320,7 @@ nv50_head_func = {
	.gamma_set = nv50_head_gamma_set,
	.destroy = nv50_head_destroy,
	.set_config = drm_atomic_helper_set_config,
	.page_flip = nv50_head_page_flip,
	.page_flip = drm_atomic_helper_page_flip,
	.set_property = drm_atomic_helper_crtc_set_property,
	.atomic_duplicate_state = nv50_head_atomic_duplicate_state,
	.atomic_destroy_state = nv50_head_atomic_destroy_state,