diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 2eef24db21f8..bdb4b57d2c12 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -35,6 +35,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <drm/drmP.h>
+#include <drm/drm_client.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_crtc_helper.h>
@@ -321,13 +322,14 @@ static bool drm_fb_helper_panel_rotation(struct drm_connector *connector,
 	return true;
 }
 
-static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
+static int drm_client_display_restore_atomic(struct drm_client_display *display, bool active)
 {
-	struct drm_device *dev = fb_helper->dev;
+	struct drm_device *dev = display->dev;
 	struct drm_plane_state *plane_state;
+	struct drm_mode_set *mode_set;
 	struct drm_plane *plane;
 	struct drm_atomic_state *state;
-	int i, ret;
+	int ret;
 	unsigned int plane_mask;
 	struct drm_modeset_acquire_ctx ctx;
 
@@ -363,8 +365,7 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 			goto out_state;
 	}
 
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+	drm_client_display_for_each_modeset(mode_set, display) {
 		struct drm_plane *primary = mode_set->crtc->primary;
 		unsigned int rotation;
 
@@ -412,13 +413,14 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ
 	goto retry;
 }
 
-static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
+static int drm_client_display_restore_legacy(struct drm_client_display *display)
 {
-	struct drm_device *dev = fb_helper->dev;
+	struct drm_device *dev = display->dev;
+	struct drm_mode_set *mode_set;
 	struct drm_plane *plane;
-	int i, ret = 0;
+	int ret = 0;
 
-	drm_modeset_lock_all(fb_helper->dev);
+	drm_modeset_lock_all(dev);
 	drm_for_each_plane(plane, dev) {
 		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
 			drm_plane_force_disable(plane);
@@ -429,8 +431,7 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
 						    DRM_MODE_ROTATE_0);
 	}
 
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
+	drm_client_display_for_each_modeset(mode_set, display) {
 		struct drm_crtc *crtc = mode_set->crtc;
 
 		if (crtc->funcs->cursor_set2) {
@@ -448,19 +449,17 @@ static int restore_fbdev_mode_legacy(struct drm_fb_helper *fb_helper)
 			goto out;
 	}
 out:
-	drm_modeset_unlock_all(fb_helper->dev);
+	drm_modeset_unlock_all(dev);
 
 	return ret;
 }
 
-static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
+static int drm_client_display_restore(struct drm_client_display *display)
 {
-	struct drm_device *dev = fb_helper->dev;
-
-	if (drm_drv_uses_atomic_modeset(dev))
-		return restore_fbdev_mode_atomic(fb_helper, true);
+	if (drm_drv_uses_atomic_modeset(display->dev))
+		return drm_client_display_restore_atomic(display, true);
 	else
-		return restore_fbdev_mode_legacy(fb_helper);
+		return drm_client_display_restore_legacy(display);
 }
 
 /**
@@ -486,7 +485,7 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
 		return 0;
 
 	mutex_lock(&fb_helper->lock);
-	ret = restore_fbdev_mode(fb_helper);
+	ret = drm_client_display_restore(fb_helper->display);
 
 	do_delayed = fb_helper->delayed_hotplug;
 	if (do_delayed)
@@ -548,7 +547,7 @@ static bool drm_fb_helper_force_kernel_mode(void)
 			continue;
 
 		mutex_lock(&helper->lock);
-		ret = restore_fbdev_mode(helper);
+		ret = drm_client_display_restore(helper->display);
 		if (ret)
 			error = true;
 		mutex_unlock(&helper->lock);
@@ -580,22 +579,20 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
 static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
 #endif
 
-static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode)
+static void drm_client_display_dpms_legacy(struct drm_client_display *display, int dpms_mode)
 {
-	struct drm_device *dev = fb_helper->dev;
+	struct drm_device *dev = display->dev;
 	struct drm_connector *connector;
 	struct drm_mode_set *modeset;
-	int i, j;
+	int i;
 
 	drm_modeset_lock_all(dev);
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		modeset = &fb_helper->crtc_info[i].mode_set;
-
+	drm_client_display_for_each_modeset(modeset, display) {
 		if (!modeset->crtc->enabled)
 			continue;
 
-		for (j = 0; j < modeset->num_connectors; j++) {
-			connector = modeset->connectors[j];
+		for (i = 0; i < modeset->num_connectors; i++) {
+			connector = modeset->connectors[i];
 			connector->funcs->dpms(connector, dpms_mode);
 			drm_object_property_set_value(&connector->base,
 				dev->mode_config.dpms_property, dpms_mode);
@@ -604,23 +601,21 @@ static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode)
 	drm_modeset_unlock_all(dev);
 }
 
+static void drm_client_display_dpms(struct drm_client_display *display, int mode)
+{
+	if (drm_drv_uses_atomic_modeset(display->dev))
+		drm_client_display_restore_atomic(display, mode == DRM_MODE_DPMS_ON);
+	else
+		drm_client_display_dpms_legacy(display, mode);
+}
+
 static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
 {
 	struct drm_fb_helper *fb_helper = info->par;
 
-	/*
-	 * For each CRTC in this fb, turn the connectors on/off.
-	 */
 	mutex_lock(&fb_helper->lock);
-	if (!drm_fb_helper_is_bound(fb_helper)) {
-		mutex_unlock(&fb_helper->lock);
-		return;
-	}
-
-	if (drm_drv_uses_atomic_modeset(fb_helper->dev))
-		restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON);
-	else
-		dpms_legacy(fb_helper, dpms_mode);
+	if (drm_fb_helper_is_bound(fb_helper))
+		drm_client_display_dpms(fb_helper->display, dpms_mode);
 	mutex_unlock(&fb_helper->lock);
 }
 
@@ -811,6 +806,10 @@ int drm_fb_helper_init(struct drm_device *dev,
 		i++;
 	}
 
+	fb_helper->display = drm_client_display_create(dev);
+	if (IS_ERR(fb_helper->display))
+		goto out_free;
+
 	dev->fb_helper = fb_helper;
 
 	return 0;
@@ -919,6 +918,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 	mutex_unlock(&kernel_fb_helper_lock);
 
 	mutex_destroy(&fb_helper->lock);
+	drm_client_display_free(fb_helper->display);
 	drm_fb_helper_crtc_free(fb_helper);
 
 }
@@ -1265,13 +1265,14 @@ static int setcmap_pseudo_palette(struct fb_cmap *cmap, struct fb_info *info)
 static int setcmap_legacy(struct fb_cmap *cmap, struct fb_info *info)
 {
 	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_mode_set *modeset;
 	struct drm_crtc *crtc;
 	u16 *r, *g, *b;
-	int i, ret = 0;
+	int ret = 0;
 
 	drm_modeset_lock_all(fb_helper->dev);
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		crtc = fb_helper->crtc_info[i].mode_set.crtc;
+	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
+		crtc = modeset->crtc;
 		if (!crtc->funcs->gamma_set || !crtc->gamma_size)
 			return -EINVAL;
 
@@ -1347,9 +1348,10 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info)
 	struct drm_modeset_acquire_ctx ctx;
 	struct drm_crtc_state *crtc_state;
 	struct drm_atomic_state *state;
+	struct drm_mode_set *modeset;
 	struct drm_crtc *crtc;
 	u16 *r, *g, *b;
-	int i, ret = 0;
+	int ret = 0;
 	bool replaced;
 
 	drm_modeset_acquire_init(&ctx, 0);
@@ -1362,8 +1364,8 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info)
 
 	state->acquire_ctx = &ctx;
 retry:
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		crtc = fb_helper->crtc_info[i].mode_set.crtc;
+	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
+		crtc = modeset->crtc;
 
 		if (!gamma_lut)
 			gamma_lut = setcmap_new_gamma_lut(crtc, cmap);
@@ -1391,8 +1393,8 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info)
 	if (ret)
 		goto out_state;
 
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		crtc = fb_helper->crtc_info[i].mode_set.crtc;
+	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
+		crtc = modeset->crtc;
 
 		r = crtc->gamma_store;
 		g = r + crtc->gamma_size;
@@ -1468,7 +1470,6 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
 			unsigned long arg)
 {
 	struct drm_fb_helper *fb_helper = info->par;
-	struct drm_mode_set *mode_set;
 	struct drm_crtc *crtc;
 	int ret = 0;
 
@@ -1496,8 +1497,7 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
 		 * make. If we're not smart enough here, one should
 		 * just consider switch the userspace to KMS.
 		 */
-		mode_set = &fb_helper->crtc_info[0].mode_set;
-		crtc = mode_set->crtc;
+		crtc = fb_helper->display->modesets[0].crtc;
 
 		/*
 		 * Only wait for a vblank event if the CRTC is
@@ -1651,13 +1651,9 @@ EXPORT_SYMBOL(drm_fb_helper_set_par);
 
 static void pan_set(struct drm_fb_helper *fb_helper, int x, int y)
 {
-	int i;
-
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		struct drm_mode_set *mode_set;
-
-		mode_set = &fb_helper->crtc_info[i].mode_set;
+	struct drm_mode_set *mode_set;
 
+	drm_client_display_for_each_modeset(mode_set, fb_helper->display) {
 		mode_set->x = x;
 		mode_set->y = y;
 	}
@@ -1671,7 +1667,7 @@ static int pan_display_atomic(struct fb_var_screeninfo *var,
 
 	pan_set(fb_helper, var->xoffset, var->yoffset);
 
-	ret = restore_fbdev_mode_atomic(fb_helper, true);
+	ret = drm_client_display_restore(fb_helper->display);
 	if (!ret) {
 		info->var.xoffset = var->xoffset;
 		info->var.yoffset = var->yoffset;
@@ -1687,12 +1683,9 @@ static int pan_display_legacy(struct fb_var_screeninfo *var,
 	struct drm_fb_helper *fb_helper = info->par;
 	struct drm_mode_set *modeset;
 	int ret = 0;
-	int i;
 
 	drm_modeset_lock_all(fb_helper->dev);
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		modeset = &fb_helper->crtc_info[i].mode_set;
-
+	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
 		modeset->x = var->xoffset;
 		modeset->y = var->yoffset;
 
@@ -1751,6 +1744,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 	int crtc_count = 0;
 	int i;
 	struct drm_fb_helper_surface_size sizes;
+	struct drm_mode_set *mode_set;
 	int gamma_size = 0;
 
 	memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
@@ -1795,9 +1789,8 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 	}
 
 	crtc_count = 0;
-	for (i = 0; i < fb_helper->crtc_count; i++) {
+	drm_client_display_for_each_modeset(mode_set, fb_helper->display) {
 		struct drm_display_mode *desired_mode;
-		struct drm_mode_set *mode_set;
 		int x, y, j;
 		/* in case of tile group, are we the last tile vert or horiz?
 		 * If no tile group you are always the last one both vertically
@@ -1805,19 +1798,18 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 		 */
 		bool lastv = true, lasth = true;
 
-		desired_mode = fb_helper->crtc_info[i].desired_mode;
-		mode_set = &fb_helper->crtc_info[i].mode_set;
+		desired_mode = mode_set->mode;
 
 		if (!desired_mode)
 			continue;
 
 		crtc_count++;
 
-		x = fb_helper->crtc_info[i].x;
-		y = fb_helper->crtc_info[i].y;
+		x = mode_set->x;
+		y = mode_set->y;
 
 		if (gamma_size == 0)
-			gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
+			gamma_size = mode_set->crtc->gamma_size;
 
 		sizes.surface_width  = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
 		sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height);
@@ -1844,7 +1836,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 
 		/* First time: disable all crtc's.. */
 		if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master))
-			restore_fbdev_mode(fb_helper);
+			drm_client_display_restore(fb_helper->display);
 		return -EAGAIN;
 	}
 
@@ -2379,6 +2371,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
 	struct drm_device *dev = fb_helper->dev;
+	struct drm_client_display *display;
 	struct drm_fb_helper_crtc **crtcs;
 	struct drm_display_mode **modes;
 	struct drm_fb_offset *offsets;
@@ -2402,6 +2395,10 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		goto out;
 	}
 
+	display = drm_client_display_create(dev);
+	if (IS_ERR(display))
+		goto out;
+
 	mutex_lock(&fb_helper->dev->mode_config.mutex);
 	if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
 		DRM_DEBUG_KMS("No connectors reported connected with modes\n");
@@ -2440,24 +2437,29 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 		struct drm_fb_offset *offset = &offsets[i];
 
 		if (mode && fb_crtc) {
-			struct drm_mode_set *modeset = &fb_crtc->mode_set;
 			struct drm_connector *connector =
 				fb_helper->connector_info[i]->connector;
+			struct drm_mode_set *modeset;
+
+			modeset = drm_client_display_find_modeset(display, fb_crtc->mode_set.crtc);
+			if (WARN_ON(!modeset)) {
+				drm_client_display_free(display);
+				goto out;
+			}
 
 			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
-				      mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
+				      mode->name, modeset->crtc->base.id, offset->x, offset->y);
 
-			fb_crtc->desired_mode = mode;
-			fb_crtc->x = offset->x;
-			fb_crtc->y = offset->y;
-			modeset->mode = drm_mode_duplicate(dev,
-							   fb_crtc->desired_mode);
+			modeset->mode = drm_mode_duplicate(dev, mode);
 			drm_connector_get(connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
 		}
 	}
+
+	drm_client_display_free(fb_helper->display);
+	fb_helper->display = display;
 out:
 	kfree(crtcs);
 	kfree(modes);
@@ -2476,11 +2478,10 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
 {
 	struct fb_info *info = fb_helper->fbdev;
 	unsigned int rotation, sw_rotations = 0;
+	struct drm_mode_set *modeset;
 	int i;
 
-	for (i = 0; i < fb_helper->crtc_count; i++) {
-		struct drm_mode_set *modeset = &fb_helper->crtc_info[i].mode_set;
-
+	drm_client_display_for_each_modeset(modeset, fb_helper->display) {
 		if (!modeset->num_connectors)
 			continue;
 
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index d1e45c832cd5..e2df40ad5063 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -155,6 +155,14 @@ struct drm_fb_helper_connector {
 struct drm_fb_helper {
 	struct drm_framebuffer *fb;
 	struct drm_device *dev;
+
+	/**
+	 * @display:
+	 *
+	 * Display representation.
+	 */
+	struct drm_client_display *display;
+
 	int crtc_count;
 	struct drm_fb_helper_crtc *crtc_info;
 	int connector_count;
