diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index d269231d63c5..e3f2ddf7deae 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -1003,13 +1003,112 @@ int drm_mode_cursor2_ioctl(struct drm_device *dev,
 	return drm_mode_cursor_common(dev, req, file_priv);
 }
 
+static int page_flip_check_fbs(const struct drm_framebuffer *fb,
+			       const struct drm_framebuffer *old_fb)
+{
+	/* The framebuffer is currently unbound, presumably
+	 * due to a hotplug event, that userspace has not
+	 * yet discovered.
+	 */
+	if (!old_fb)
+		return -EBUSY;
+
+	if (old_fb->format != fb->format) {
+		DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int page_flip_internal(struct drm_crtc *crtc,
+			      struct drm_framebuffer *fb,
+			      struct drm_pending_vblank_event *e,
+			      u32 flags,
+			      u32 target_vblank,
+			      struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_plane *plane = crtc->primary;
+	int ret;
+
+	WARN_ON(drm_drv_uses_atomic_modeset(crtc->dev));
+
+	ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
+				      &crtc->mode, fb);
+	if (ret)
+		return ret;
+
+	ret = page_flip_check_fbs(fb, plane->fb);
+	if (ret)
+		return ret;
+
+	plane->old_fb = plane->fb;
+
+	if (crtc->funcs->page_flip_target)
+		ret = crtc->funcs->page_flip_target(crtc, fb, e, flags,
+						    target_vblank, ctx);
+	else
+		ret = crtc->funcs->page_flip(crtc, fb, e, flags, ctx);
+
+	if (ret) {
+		/* Keep the old fb, don't unref it. */
+		plane->old_fb = NULL;
+	} else {
+		plane->fb = fb;
+		drm_framebuffer_get(plane->fb);
+	}
+
+	if (plane->old_fb)
+		drm_framebuffer_put(plane->old_fb);
+	plane->old_fb = NULL;
+
+	return ret;
+}
+
+static int page_flip_atomic(struct drm_crtc *crtc,
+			    struct drm_framebuffer *fb,
+			    struct drm_pending_vblank_event *e,
+			    u32 flags,
+			    u32 target_vblank,
+			    struct drm_modeset_acquire_ctx *ctx)
+{
+	struct drm_plane *plane = crtc->primary;
+	struct drm_plane_state *plane_state = plane->state;
+	int ret;
+
+	WARN_ON(!drm_drv_uses_atomic_modeset(crtc->dev));
+
+	/*
+	 * FIXME: Can we assume all drivers end up calling
+	 * drm_atomic_plane_check() in their page flip paths?
+	 * If so we could remove this.
+	 */
+	ret = drm_framebuffer_check_src_coords(plane_state->src_x,
+					       plane_state->src_y,
+					       plane_state->src_w,
+					       plane_state->src_h,
+					       fb);
+	if (ret)
+		return ret;
+
+	ret = page_flip_check_fbs(fb, plane_state->fb);
+	if (ret)
+		return ret;
+
+	if (crtc->funcs->page_flip_target)
+		return crtc->funcs->page_flip_target(crtc, fb, e, flags,
+						     target_vblank, ctx);
+	else
+		return crtc->funcs->page_flip(crtc, fb, e, flags, ctx);
+}
+
 int drm_mode_page_flip_ioctl(struct drm_device *dev,
 			     void *data, struct drm_file *file_priv)
 {
 	struct drm_mode_crtc_page_flip_target *page_flip = data;
 	struct drm_crtc *crtc;
 	struct drm_plane *plane;
-	struct drm_framebuffer *fb, *old_fb;
+	struct drm_framebuffer *fb;
 	struct drm_pending_vblank_event *e = NULL;
 	u32 target_vblank = page_flip->sequence;
 	struct drm_modeset_acquire_ctx ctx;
@@ -1114,65 +1213,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
 	if (ret)
 		goto out;
 
-	if (plane->state)
-		old_fb = plane->state->fb;
-	else
-		old_fb = plane->fb;
-
-	if (old_fb == NULL) {
-		/* The framebuffer is currently unbound, presumably
-		 * due to a hotplug event, that userspace has not
-		 * yet discovered.
-		 */
-		ret = -EBUSY;
-		goto out;
-	}
-
-	if (plane->state) {
-		const struct drm_plane_state *state = plane->state;
-
-		ret = drm_framebuffer_check_src_coords(state->src_x,
-						       state->src_y,
-						       state->src_w,
-						       state->src_h,
-						       fb);
-	} else {
-		ret = drm_crtc_check_viewport(crtc, crtc->x, crtc->y,
-					      &crtc->mode, fb);
-	}
-	if (ret)
-		goto out;
-
-	if (old_fb->format != fb->format) {
-		DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
-		ret = -EINVAL;
-		goto out;
-	}
-
-	plane->old_fb = plane->fb;
-	if (crtc->funcs->page_flip_target)
-		ret = crtc->funcs->page_flip_target(crtc, fb, e,
-						    page_flip->flags,
-						    target_vblank,
-						    &ctx);
+	if (drm_drv_uses_atomic_modeset(dev))
+		ret = page_flip_atomic(crtc, fb, e, page_flip->flags,
+				       target_vblank, &ctx);
 	else
-		ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags,
-					     &ctx);
-	if (ret) {
-		/* Keep the old fb, don't unref it. */
-		plane->old_fb = NULL;
-	} else {
-		if (!plane->state) {
-			plane->fb = fb;
-			drm_framebuffer_get(fb);
-		}
-	}
+		ret = page_flip_internal(crtc, fb, e, page_flip->flags,
+					 target_vblank, &ctx);
 
 out:
-	if (plane->old_fb)
-		drm_framebuffer_put(plane->old_fb);
-	plane->old_fb = NULL;
-
 	if (ret == -EDEADLK) {
 		ret = drm_modeset_backoff(&ctx);
 		if (!ret)
