[RFCv3 08/14] drm: Replace crtc fb with primary plane fb (v2)

Matt Roper matthew.d.roper at intel.com
Mon Mar 24 18:20:35 PDT 2014


On Wed, Mar 19, 2014 at 12:57:21PM +0100, Daniel Vetter wrote:
> On Tue, Mar 18, 2014 at 05:22:53PM -0700, Matt Roper wrote:
> > Now that CRTC's have a primary plane, there's no need to track the
> > framebuffer in the CRTC.  Replace all references to the CRTC fb
> > with the primary plane's fb.
> > 
> > Also note that this simplifies framebuffer removal slightly; we no
> > longer need to scan all CRTC's and disable the ones that were using the
> > framebuffer since the existing loop over all planes will take care
> > of disabling the primary plane (and on most hardware, the CRTC by
> > extension).
> > 
> > v2: Fixup several lingering crtc->fb instances that were missed in the
> >     first patch iteration.
> > 
> > Tested-by: Rob Clark <robdclark at gmail.com>
> > Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
> 
> Giant patch again, and I don't think there's any sane way we can avoid
> this big sed job. Put I think we can make it less intrusive.
> 
> First: Have you looked into cocinelle to do this? I'm not sure whether
> cocinelle is sufficiently type aware, but the upside of using it is that
> it's much easier to regenerate the patch.

Good idea!  Yeah, I think Coccinelle should do this pretty easily with
just:

        @@ struct drm_crtc *crtc; @@
        -   crtc->fb
        +   crtc->primary->fb

        @@ struct drm_crtc crtc; @@
        -   crtc.fb
        +   crtc.primary->fb

> In any case I think we need to split this into the usual 3 phases to avoid
> flag days:
> 
> 1) Switch to crtc->primary->fb all over the core, but keep crtc->fb fully
> functional. I.e. update it before calling into drivers and use that to
> update crtc->primary->fb on return (e.g. in the pageflip ioctl).

I'm starting to worry that this may be more tricky than it sounded when
I first read your email.  To be safe, it seems like we'll need to
sandwich all the various ->funcs-> driver calls in the core between
prepare_crtc_fbs() / finish_crtc_fbs() or similar since it's hard to
predict in a universal way when a driver might decide to go look at a
crtc's framebuffer (or even which crtcs it will decide to look at).
However even if we do that wrapping, there may be cases where the driver
calls back into a core helper function after modifying crtc->fb and the
core won't have that updated value unless we throw in extra sync-up
points.  

Is this pretty much what you had in mind or am I overlooking a much
simpler way to accomplish this?


Matt

> 
> 2) Switch drivers over to look at crtc->primary->fb. This way we can even
> split up the patch into per-driver patches which gives driver maintainers
> more wiggle room.
> 
> 3) Kill crtc->fb.
> 
> Steps 2&3 don't block merging of the universal planes support at all. So
> we could get the core support in all early for 3.16, then let driver
> maintainers pick up patche for 2 and shortly before the 3.16 merge window
> opens send a pull request with all the stragglers and step 3.
> 
> No comments on the actual patch, the few functional changes hidden in the
> massive diff looked ok. But hard to review properly ;-)
> 
> Cheers, Daniel
> 
> > ---
> >  drivers/gpu/drm/ast/ast_mode.c               |  12 +--
> >  drivers/gpu/drm/bochs/bochs_kms.c            |   4 +-
> >  drivers/gpu/drm/cirrus/cirrus_mode.c         |  10 +-
> >  drivers/gpu/drm/drm_crtc.c                   |  56 ++++------
> >  drivers/gpu/drm/drm_crtc_helper.c            |  21 ++--
> >  drivers/gpu/drm/drm_fb_helper.c              |   6 +-
> >  drivers/gpu/drm/gma500/cdv_intel_display.c   |   2 +-
> >  drivers/gpu/drm/gma500/cdv_intel_dp.c        |   2 +-
> >  drivers/gpu/drm/gma500/cdv_intel_hdmi.c      |   3 +-
> >  drivers/gpu/drm/gma500/cdv_intel_lvds.c      |   2 +-
> >  drivers/gpu/drm/gma500/gma_display.c         |  17 ++--
> >  drivers/gpu/drm/gma500/mdfld_dsi_output.c    |   2 +-
> >  drivers/gpu/drm/gma500/mdfld_intel_display.c |  17 ++--
> >  drivers/gpu/drm/gma500/oaktrail_crtc.c       |  13 +--
> >  drivers/gpu/drm/gma500/psb_intel_display.c   |   2 +-
> >  drivers/gpu/drm/gma500/psb_intel_lvds.c      |   2 +-
> >  drivers/gpu/drm/gma500/psb_intel_sdvo.c      |   2 +-
> >  drivers/gpu/drm/i915/i915_debugfs.c          |   4 +-
> >  drivers/gpu/drm/i915/i915_irq.c              |   4 +-
> >  drivers/gpu/drm/i915/intel_display.c         | 147 ++++++++++++++-------------
> >  drivers/gpu/drm/i915/intel_dp.c              |   5 +-
> >  drivers/gpu/drm/i915/intel_fbdev.c           |   6 +-
> >  drivers/gpu/drm/i915/intel_overlay.c         |   4 +-
> >  drivers/gpu/drm/i915/intel_pm.c              |  36 +++----
> >  drivers/gpu/drm/mgag200/mgag200_mode.c       |  28 ++---
> >  drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c     |  28 ++---
> >  drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c     |  22 ++--
> >  drivers/gpu/drm/nouveau/dispnv04/crtc.c      |  20 ++--
> >  drivers/gpu/drm/nouveau/dispnv04/dfp.c       |   2 +-
> >  drivers/gpu/drm/nouveau/nouveau_display.c    |   8 +-
> >  drivers/gpu/drm/nouveau/nv50_display.c       |  17 ++--
> >  drivers/gpu/drm/qxl/qxl_display.c            |  11 +-
> >  drivers/gpu/drm/radeon/atombios_crtc.c       |  20 ++--
> >  drivers/gpu/drm/radeon/r100.c                |   4 +-
> >  drivers/gpu/drm/radeon/radeon_connectors.c   |   2 +-
> >  drivers/gpu/drm/radeon/radeon_device.c       |   3 +-
> >  drivers/gpu/drm/radeon/radeon_display.c      |   4 +-
> >  drivers/gpu/drm/radeon/radeon_legacy_crtc.c  |  16 +--
> >  drivers/gpu/drm/udl/udl_modeset.c            |   2 +-
> >  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c          |  14 +--
> >  drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c          |   8 +-
> >  drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c         |   8 +-
> >  include/drm/drm_crtc.h                       |   3 -
> >  43 files changed, 300 insertions(+), 299 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
> > index 44f0d32..bd1e156 100644
> > --- a/drivers/gpu/drm/ast/ast_mode.c
> > +++ b/drivers/gpu/drm/ast/ast_mode.c
> > @@ -81,7 +81,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> >  	u32 refresh_rate_index = 0, mode_id, color_index, refresh_rate;
> >  	u32 hborder, vborder;
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		vbios_mode->std_table = &vbios_stdtable[VGAModeIndex];
> >  		color_index = VGAModeIndex - 1;
> > @@ -176,7 +176,7 @@ static bool ast_get_vbios_mode_info(struct drm_crtc *crtc, struct drm_display_mo
> >  		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff);
> >  
> >  		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8);
> > -		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->fb->bits_per_pixel);
> > +		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, crtc->primary->fb->bits_per_pixel);
> >  		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000);
> >  		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay);
> >  		ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8);
> > @@ -340,7 +340,7 @@ static void ast_set_offset_reg(struct drm_crtc *crtc)
> >  
> >  	u16 offset;
> >  
> > -	offset = crtc->fb->pitches[0] >> 3;
> > +	offset = crtc->primary->fb->pitches[0] >> 3;
> >  	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff));
> >  	ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f);
> >  }
> > @@ -365,7 +365,7 @@ static void ast_set_ext_reg(struct drm_crtc *crtc, struct drm_display_mode *mode
> >  	struct ast_private *ast = crtc->dev->dev_private;
> >  	u8 jregA0 = 0, jregA3 = 0, jregA8 = 0;
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		jregA0 = 0x70;
> >  		jregA3 = 0x01;
> > @@ -418,7 +418,7 @@ static void ast_set_sync_reg(struct drm_device *dev, struct drm_display_mode *mo
> >  static bool ast_set_dac_reg(struct drm_crtc *crtc, struct drm_display_mode *mode,
> >  		     struct ast_vbios_mode_info *vbios_mode)
> >  {
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		break;
> >  	default:
> > @@ -490,7 +490,7 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc,
> >  		ast_bo_unreserve(bo);
> >  	}
> >  
> > -	ast_fb = to_ast_framebuffer(crtc->fb);
> > +	ast_fb = to_ast_framebuffer(crtc->primary->fb);
> >  	obj = ast_fb->obj;
> >  	bo = gem_to_ast_bo(obj);
> >  
> > diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c
> > index 182f5c9..b67ad12 100644
> > --- a/drivers/gpu/drm/bochs/bochs_kms.c
> > +++ b/drivers/gpu/drm/bochs/bochs_kms.c
> > @@ -62,10 +62,10 @@ static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> >  		}
> >  	}
> >  
> > -	if (WARN_ON(crtc->fb == NULL))
> > +	if (WARN_ON(crtc->primary->fb == NULL))
> >  		return -EINVAL;
> >  
> > -	bochs_fb = to_bochs_framebuffer(crtc->fb);
> > +	bochs_fb = to_bochs_framebuffer(crtc->primary->fb);
> >  	bo = gem_to_bochs_bo(bochs_fb->obj);
> >  	ret = ttm_bo_reserve(&bo->bo, true, false, false, 0);
> >  	if (ret)
> > diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
> > index 449246f..5291d2f 100644
> > --- a/drivers/gpu/drm/cirrus/cirrus_mode.c
> > +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
> > @@ -149,7 +149,7 @@ static int cirrus_crtc_do_set_base(struct drm_crtc *crtc,
> >  		cirrus_bo_unreserve(bo);
> >  	}
> >  
> > -	cirrus_fb = to_cirrus_framebuffer(crtc->fb);
> > +	cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb);
> >  	obj = cirrus_fb->obj;
> >  	bo = gem_to_cirrus_bo(obj);
> >  
> > @@ -268,7 +268,7 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
> >  	sr07 = RREG8(SEQ_DATA);
> >  	sr07 &= 0xe0;
> >  	hdr = 0;
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		sr07 |= 0x11;
> >  		break;
> > @@ -291,13 +291,13 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
> >  	WREG_SEQ(0x7, sr07);
> >  
> >  	/* Program the pitch */
> > -	tmp = crtc->fb->pitches[0] / 8;
> > +	tmp = crtc->primary->fb->pitches[0] / 8;
> >  	WREG_CRT(VGA_CRTC_OFFSET, tmp);
> >  
> >  	/* Enable extended blanking and pitch bits, and enable full memory */
> >  	tmp = 0x22;
> > -	tmp |= (crtc->fb->pitches[0] >> 7) & 0x10;
> > -	tmp |= (crtc->fb->pitches[0] >> 6) & 0x40;
> > +	tmp |= (crtc->primary->fb->pitches[0] >> 7) & 0x10;
> > +	tmp |= (crtc->primary->fb->pitches[0] >> 6) & 0x40;
> >  	WREG_CRT(0x1b, tmp);
> >  
> >  	/* Enable high-colour modes */
> > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > index 0feb66cc..0c395e8 100644
> > --- a/drivers/gpu/drm/drm_crtc.c
> > +++ b/drivers/gpu/drm/drm_crtc.c
> > @@ -634,7 +634,7 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
> >   * drm_framebuffer_remove - remove and unreference a framebuffer object
> >   * @fb: framebuffer to remove
> >   *
> > - * Scans all the CRTCs and planes in @dev's mode_config.  If they're
> > + * Scans all the planes in @dev's mode_config.  If they're
> >   * using @fb, removes it, setting it to NULL. Then drops the reference to the
> >   * passed-in framebuffer. Might take the modeset locks.
> >   *
> > @@ -645,10 +645,7 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
> >  void drm_framebuffer_remove(struct drm_framebuffer *fb)
> >  {
> >  	struct drm_device *dev = fb->dev;
> > -	struct drm_crtc *crtc;
> >  	struct drm_plane *plane;
> > -	struct drm_mode_set set;
> > -	int ret;
> >  
> >  	WARN_ON(!list_empty(&fb->filp_head));
> >  
> > @@ -669,19 +666,7 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb)
> >  	 */
> >  	if (atomic_read(&fb->refcount.refcount) > 1) {
> >  		drm_modeset_lock_all(dev);
> > -		/* remove from any CRTC */
> > -		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> > -			if (crtc->fb == fb) {
> > -				/* should turn off the crtc */
> > -				memset(&set, 0, sizeof(struct drm_mode_set));
> > -				set.crtc = crtc;
> > -				set.fb = NULL;
> > -				ret = drm_mode_set_config_internal(&set);
> > -				if (ret)
> > -					DRM_ERROR("failed to reset crtc %p when fb was deleted\n", crtc);
> > -			}
> > -		}
> > -
> > +		/* remove from any plane */
> >  		list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> >  			if (plane->fb == fb)
> >  				drm_plane_force_disable(plane);
> > @@ -1930,8 +1915,8 @@ int drm_mode_getcrtc(struct drm_device *dev,
> >  	crtc_resp->x = crtc->x;
> >  	crtc_resp->y = crtc->y;
> >  	crtc_resp->gamma_size = crtc->gamma_size;
> > -	if (crtc->fb)
> > -		crtc_resp->fb_id = crtc->fb->base.id;
> > +	if (crtc->primary->fb)
> > +		crtc_resp->fb_id = crtc->primary->fb->base.id;
> >  	else
> >  		crtc_resp->fb_id = 0;
> >  
> > @@ -2438,7 +2423,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
> >  	 * crtcs. Atomic modeset will have saner semantics ...
> >  	 */
> >  	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head)
> > -		tmp->old_fb = tmp->fb;
> > +		tmp->old_fb = tmp->primary->fb;
> >  
> >  	fb = set->fb;
> >  
> > @@ -2446,13 +2431,16 @@ int drm_mode_set_config_internal(struct drm_mode_set *set)
> >  	if (ret == 0) {
> >  		crtc->primary->crtc = crtc;
> >  
> > -		/* crtc->fb must be updated by ->set_config, enforces this. */
> > -		WARN_ON(fb != crtc->fb);
> > +		/*
> > +		 * crtc->primary->fb must be updated by ->set_config,
> > +		 * enforces this.
> > +		 */
> > +		WARN_ON(fb != crtc->primary->fb);
> >  	}
> >  
> >  	list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) {
> > -		if (tmp->fb)
> > -			drm_framebuffer_reference(tmp->fb);
> > +		if (tmp->primary->fb)
> > +			drm_framebuffer_reference(tmp->primary->fb);
> >  		if (tmp->old_fb)
> >  			drm_framebuffer_unreference(tmp->old_fb);
> >  	}
> > @@ -2511,12 +2499,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
> >  		/* If we have a mode we need a framebuffer. */
> >  		/* If we pass -1, set the mode with the currently bound fb */
> >  		if (crtc_req->fb_id == -1) {
> > -			if (!crtc->fb) {
> > +			if (!crtc->primary->fb) {
> >  				DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
> >  				ret = -EINVAL;
> >  				goto out;
> >  			}
> > -			fb = crtc->fb;
> > +			fb = crtc->primary->fb;
> >  			/* Make refcounting symmetric with the lookup path. */
> >  			drm_framebuffer_reference(fb);
> >  		} else {
> > @@ -4309,7 +4297,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
> >  	crtc = obj_to_crtc(obj);
> >  
> >  	mutex_lock(&crtc->mutex);
> > -	if (crtc->fb == NULL) {
> > +	if (crtc->primary->fb == NULL) {
> >  		/* The framebuffer is currently unbound, presumably
> >  		 * due to a hotplug event, that userspace has not
> >  		 * yet discovered.
> > @@ -4331,7 +4319,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
> >  	if (ret)
> >  		goto out;
> >  
> > -	if (crtc->fb->pixel_format != fb->pixel_format) {
> > +	if (crtc->primary->fb->pixel_format != fb->pixel_format) {
> >  		DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
> >  		ret = -EINVAL;
> >  		goto out;
> > @@ -4364,7 +4352,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
> >  			(void (*) (struct drm_pending_event *)) kfree;
> >  	}
> >  
> > -	old_fb = crtc->fb;
> > +	old_fb = crtc->primary->fb;
> >  	ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags);
> >  	if (ret) {
> >  		if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) {
> > @@ -4377,12 +4365,12 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
> >  		old_fb = NULL;
> >  	} else {
> >  		/*
> > -		 * Warn if the driver hasn't properly updated the crtc->fb
> > -		 * field to reflect that the new framebuffer is now used.
> > -		 * Failing to do so will screw with the reference counting
> > -		 * on framebuffers.
> > +		 * Warn if the driver hasn't properly updated the
> > +		 * crtc->primary->fb field to reflect that the new framebuffer
> > +		 * is now used.  Failing to do so will screw with the reference
> > +		 * counting on framebuffers.
> >  		 */
> > -		WARN_ON(crtc->fb != fb);
> > +		WARN_ON(crtc->primary->fb != fb);
> >  		/* Unref only the old framebuffer. */
> >  		fb = NULL;
> >  	}
> > diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> > index a855178..8825afb 100644
> > --- a/drivers/gpu/drm/drm_crtc_helper.c
> > +++ b/drivers/gpu/drm/drm_crtc_helper.c
> > @@ -319,7 +319,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
> >  				(*crtc_funcs->disable)(crtc);
> >  			else
> >  				(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
> > -			crtc->fb = NULL;
> > +			crtc->primary->fb = NULL;
> >  		}
> >  	}
> >  }
> > @@ -646,19 +646,19 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
> >  	save_set.mode = &set->crtc->mode;
> >  	save_set.x = set->crtc->x;
> >  	save_set.y = set->crtc->y;
> > -	save_set.fb = set->crtc->fb;
> > +	save_set.fb = set->crtc->primary->fb;
> >  
> >  	/* We should be able to check here if the fb has the same properties
> >  	 * and then just flip_or_move it */
> > -	if (set->crtc->fb != set->fb) {
> > +	if (set->crtc->primary->fb != set->fb) {
> >  		/* If we have no fb then treat it as a full mode set */
> > -		if (set->crtc->fb == NULL) {
> > +		if (set->crtc->primary->fb == NULL) {
> >  			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
> >  			mode_changed = true;
> >  		} else if (set->fb == NULL) {
> >  			mode_changed = true;
> >  		} else if (set->fb->pixel_format !=
> > -			   set->crtc->fb->pixel_format) {
> > +			   set->crtc->primary->fb->pixel_format) {
> >  			mode_changed = true;
> >  		} else
> >  			fb_changed = true;
> > @@ -759,13 +759,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
> >  			DRM_DEBUG_KMS("attempting to set mode from"
> >  					" userspace\n");
> >  			drm_mode_debug_printmodeline(set->mode);
> > -			set->crtc->fb = set->fb;
> > +			set->crtc->primary->fb = set->fb;
> >  			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
> >  						      set->x, set->y,
> >  						      save_set.fb)) {
> >  				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
> >  					  set->crtc->base.id);
> > -				set->crtc->fb = save_set.fb;
> > +				set->crtc->primary->fb = save_set.fb;
> >  				ret = -EINVAL;
> >  				goto fail;
> >  			}
> > @@ -780,13 +780,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
> >  	} else if (fb_changed) {
> >  		set->crtc->x = set->x;
> >  		set->crtc->y = set->y;
> > -		set->crtc->fb = set->fb;
> > +		set->crtc->primary->fb = set->fb;
> >  		ret = crtc_funcs->mode_set_base(set->crtc,
> >  						set->x, set->y, save_set.fb);
> >  		if (ret != 0) {
> >  			set->crtc->x = save_set.x;
> >  			set->crtc->y = save_set.y;
> > -			set->crtc->fb = save_set.fb;
> > +			set->crtc->primary->fb = save_set.fb;
> >  			goto fail;
> >  		}
> >  	}
> > @@ -982,7 +982,8 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
> >  			continue;
> >  
> >  		ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
> > -					       crtc->x, crtc->y, crtc->fb);
> > +					       crtc->x, crtc->y,
> > +					       crtc->primary->fb);
> >  
> >  		/* Restoring the old config should never fail! */
> >  		if (ret == false)
> > diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> > index 9c6251f..e8e2b41 100644
> > --- a/drivers/gpu/drm/drm_fb_helper.c
> > +++ b/drivers/gpu/drm/drm_fb_helper.c
> > @@ -232,7 +232,7 @@ static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
> >  
> >  	list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
> >  		if (crtc->base.id == c->base.id)
> > -			return c->fb;
> > +			return c->primary->fb;
> >  	}
> >  
> >  	return NULL;
> > @@ -366,9 +366,9 @@ static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
> >  		return false;
> >  
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> > -		if (crtc->fb)
> > +		if (crtc->primary->fb)
> >  			crtcs_bound++;
> > -		if (crtc->fb == fb_helper->fb)
> > +		if (crtc->primary->fb == fb_helper->fb)
> >  			bound++;
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c
> > index 8fbfa06..1cddcf8 100644
> > --- a/drivers/gpu/drm/gma500/cdv_intel_display.c
> > +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c
> > @@ -463,7 +463,7 @@ static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe)
> >  	crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> >  	gma_crtc = to_gma_crtc(crtc);
> >  
> > -	if (crtc->fb == NULL || !gma_crtc->active)
> > +	if (crtc->primary->fb == NULL || !gma_crtc->active)
> >  		return false;
> >  	return true;
> >  }
> > diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c
> > index 0490ce3..9ff30c2 100644
> > --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c
> > +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c
> > @@ -1693,7 +1693,7 @@ done:
> >  		struct drm_crtc *crtc = encoder->base.crtc;
> >  		drm_crtc_helper_set_mode(crtc, &crtc->mode,
> >  					 crtc->x, crtc->y,
> > -					 crtc->fb);
> > +					 crtc->primary->fb);
> >  	}
> >  
> >  	return 0;
> > diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
> > index 1c0d723..04956e6 100644
> > --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
> > +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
> > @@ -199,7 +199,8 @@ static int cdv_hdmi_set_property(struct drm_connector *connector,
> >  		    crtc->saved_mode.vdisplay != 0) {
> >  			if (centre) {
> >  				if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode,
> > -					    encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
> > +					    encoder->crtc->x, encoder->crtc->y,
> > +					    encoder->crtc->primary->fb))
> >  					return -1;
> >  			} else {
> >  				struct drm_encoder_helper_funcs *helpers
> > diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
> > index 20e08e6..58f11df 100644
> > --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
> > +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
> > @@ -494,7 +494,7 @@ static int cdv_intel_lvds_set_property(struct drm_connector *connector,
> >  						      &crtc->saved_mode,
> >  						      encoder->crtc->x,
> >  						      encoder->crtc->y,
> > -						      encoder->crtc->fb))
> > +						      encoder->crtc->primary->fb))
> >  				return -1;
> >  		}
> >  	} else if (!strcmp(property->name, "backlight") && encoder) {
> > diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
> > index 386de2c..7b73dd1 100644
> > --- a/drivers/gpu/drm/gma500/gma_display.c
> > +++ b/drivers/gpu/drm/gma500/gma_display.c
> > @@ -59,7 +59,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_psb_private *dev_priv = dev->dev_private;
> >  	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
> > -	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
> > +	struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb);
> >  	int pipe = gma_crtc->pipe;
> >  	const struct psb_offset *map = &dev_priv->regmap[pipe];
> >  	unsigned long start, offset;
> > @@ -70,7 +70,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  		return 0;
> >  
> >  	/* no fb bound */
> > -	if (!crtc->fb) {
> > +	if (!crtc->primary->fb) {
> >  		dev_err(dev->dev, "No FB bound\n");
> >  		goto gma_pipe_cleaner;
> >  	}
> > @@ -81,19 +81,20 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  	if (ret < 0)
> >  		goto gma_pipe_set_base_exit;
> >  	start = psbfb->gtt->offset;
> > -	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
> > +	offset = y * crtc->primary->fb->pitches[0] +
> > +		x * (crtc->primary->fb->bits_per_pixel / 8);
> >  
> > -	REG_WRITE(map->stride, crtc->fb->pitches[0]);
> > +	REG_WRITE(map->stride, crtc->primary->fb->pitches[0]);
> >  
> >  	dspcntr = REG_READ(map->cntr);
> >  	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		dspcntr |= DISPPLANE_8BPP;
> >  		break;
> >  	case 16:
> > -		if (crtc->fb->depth == 15)
> > +		if (crtc->primary->fb->depth == 15)
> >  			dspcntr |= DISPPLANE_15_16BPP;
> >  		else
> >  			dspcntr |= DISPPLANE_16BPP;
> > @@ -511,8 +512,8 @@ void gma_crtc_disable(struct drm_crtc *crtc)
> >  
> >  	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
> >  
> > -	if (crtc->fb) {
> > -		gt = to_psb_fb(crtc->fb)->gtt;
> > +	if (crtc->primary->fb) {
> > +		gt = to_psb_fb(crtc->primary->fb)->gtt;
> >  		psb_gtt_unpin(gt);
> >  	}
> >  }
> > diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
> > index 860a4ee..6e91b20 100644
> > --- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
> > +++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
> > @@ -287,7 +287,7 @@ static int mdfld_dsi_connector_set_property(struct drm_connector *connector,
> >  						&gma_crtc->saved_mode,
> >  						encoder->crtc->x,
> >  						encoder->crtc->y,
> > -						encoder->crtc->fb))
> > +						encoder->crtc->primary->fb))
> >  					goto set_prop_error;
> >  			} else {
> >  				struct drm_encoder_helper_funcs *funcs =
> > diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c
> > index 321c00a..c54386a 100644
> > --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c
> > +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c
> > @@ -166,7 +166,7 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_psb_private *dev_priv = dev->dev_private;
> >  	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
> > -	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
> > +	struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb);
> >  	int pipe = gma_crtc->pipe;
> >  	const struct psb_offset *map = &dev_priv->regmap[pipe];
> >  	unsigned long start, offset;
> > @@ -178,12 +178,12 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  	dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe);
> >  
> >  	/* no fb bound */
> > -	if (!crtc->fb) {
> > +	if (!crtc->primary->fb) {
> >  		dev_dbg(dev->dev, "No FB bound\n");
> >  		return 0;
> >  	}
> >  
> > -	ret = check_fb(crtc->fb);
> > +	ret = check_fb(crtc->primary->fb);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -196,18 +196,19 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  		return 0;
> >  
> >  	start = psbfb->gtt->offset;
> > -	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
> > +	offset = y * crtc->primary->fb->pitches[0] +
> > +		x * (crtc->primary->fb->bits_per_pixel / 8);
> >  
> > -	REG_WRITE(map->stride, crtc->fb->pitches[0]);
> > +	REG_WRITE(map->stride, crtc->primary->fb->pitches[0]);
> >  	dspcntr = REG_READ(map->cntr);
> >  	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		dspcntr |= DISPPLANE_8BPP;
> >  		break;
> >  	case 16:
> > -		if (crtc->fb->depth == 15)
> > +		if (crtc->primary->fb->depth == 15)
> >  			dspcntr |= DISPPLANE_15_16BPP;
> >  		else
> >  			dspcntr |= DISPPLANE_16BPP;
> > @@ -700,7 +701,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
> >  	}
> >  #endif
> >  
> > -	ret = check_fb(crtc->fb);
> > +	ret = check_fb(crtc->primary->fb);
> >  	if (ret)
> >  		return ret;
> >  
> > diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
> > index 8195e85..b0fb42a 100644
> > --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c
> > +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
> > @@ -599,7 +599,7 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc,
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_psb_private *dev_priv = dev->dev_private;
> >  	struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
> > -	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
> > +	struct psb_framebuffer *psbfb = to_psb_fb(crtc->primary->fb);
> >  	int pipe = gma_crtc->pipe;
> >  	const struct psb_offset *map = &dev_priv->regmap[pipe];
> >  	unsigned long start, offset;
> > @@ -608,7 +608,7 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc,
> >  	int ret = 0;
> >  
> >  	/* no fb bound */
> > -	if (!crtc->fb) {
> > +	if (!crtc->primary->fb) {
> >  		dev_dbg(dev->dev, "No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -617,19 +617,20 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc,
> >  		return 0;
> >  
> >  	start = psbfb->gtt->offset;
> > -	offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
> > +	offset = y * crtc->primary->fb->pitches[0] +
> > +		x * (crtc->primary->fb->bits_per_pixel / 8);
> >  
> > -	REG_WRITE(map->stride, crtc->fb->pitches[0]);
> > +	REG_WRITE(map->stride, crtc->primary->fb->pitches[0]);
> >  
> >  	dspcntr = REG_READ(map->cntr);
> >  	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		dspcntr |= DISPPLANE_8BPP;
> >  		break;
> >  	case 16:
> > -		if (crtc->fb->depth == 15)
> > +		if (crtc->primary->fb->depth == 15)
> >  			dspcntr |= DISPPLANE_15_16BPP;
> >  		else
> >  			dspcntr |= DISPPLANE_16BPP;
> > diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c
> > index c8f833d..25c174c 100644
> > --- a/drivers/gpu/drm/gma500/psb_intel_display.c
> > +++ b/drivers/gpu/drm/gma500/psb_intel_display.c
> > @@ -120,7 +120,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
> >  	const struct gma_limit_t *limit;
> >  
> >  	/* No scan out no play */
> > -	if (crtc->fb == NULL) {
> > +	if (crtc->primary->fb == NULL) {
> >  		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
> >  		return 0;
> >  	}
> > diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
> > index 32342f6..dcdf70e 100644
> > --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
> > +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
> > @@ -614,7 +614,7 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
> >  						      &crtc->saved_mode,
> >  						      encoder->crtc->x,
> >  						      encoder->crtc->y,
> > -						      encoder->crtc->fb))
> > +						      encoder->crtc->primary->fb))
> >  				goto set_prop_error;
> >  		}
> >  	} else if (!strcmp(property->name, "backlight")) {
> > diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
> > index 07d3a9e..1c0a2fb 100644
> > --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
> > +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
> > @@ -1844,7 +1844,7 @@ done:
> >  	if (psb_intel_sdvo->base.base.crtc) {
> >  		struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc;
> >  		drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
> > -					 crtc->y, crtc->fb);
> > +					 crtc->y, crtc->primary->fb);
> >  	}
> >  
> >  	return 0;
> > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> > index d83d643..f00ba43 100644
> > --- a/drivers/gpu/drm/i915/i915_debugfs.c
> > +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> > @@ -2172,8 +2172,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *intel_crtc)
> >  	struct intel_encoder *intel_encoder;
> >  
> >  	seq_printf(m, "\tfb: %d, pos: %dx%d, size: %dx%d\n",
> > -		   crtc->fb->base.id, crtc->x, crtc->y,
> > -		   crtc->fb->width, crtc->fb->height);
> > +		   crtc->primary->fb->base.id, crtc->x, crtc->y,
> > +		   crtc->primary->fb->width, crtc->primary->fb->height);
> >  	for_each_encoder_on_crtc(dev, crtc, intel_encoder)
> >  		intel_encoder_info(m, intel_crtc, intel_encoder);
> >  }
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index 37f852d..e8b3f9f 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -2380,8 +2380,8 @@ static void __always_unused i915_pageflip_stall_check(struct drm_device *dev, in
> >  	} else {
> >  		int dspaddr = DSPADDR(intel_crtc->plane);
> >  		stall_detected = I915_READ(dspaddr) == (i915_gem_obj_ggtt_offset(obj) +
> > -							crtc->y * crtc->fb->pitches[0] +
> > -							crtc->x * crtc->fb->bits_per_pixel/8);
> > +							crtc->y * crtc->primary->fb->pitches[0] +
> > +							crtc->x * crtc->primary->fb->bits_per_pixel/8);
> >  	}
> >  
> >  	spin_unlock_irqrestore(&dev->event_lock, flags);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index 21d12a9..c2f3730 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -744,7 +744,7 @@ bool intel_crtc_active(struct drm_crtc *crtc)
> >  	 * We can ditch the crtc->fb check as soon as we can
> >  	 * properly reconstruct framebuffers.
> >  	 */
> > -	return intel_crtc->active && crtc->fb &&
> > +	return intel_crtc->active && crtc->primary->fb &&
> >  		intel_crtc->config.adjusted_mode.crtc_clock;
> >  }
> >  
> > @@ -2086,17 +2086,18 @@ static bool intel_alloc_plane_obj(struct intel_crtc *crtc,
> >  
> >  	if (plane_config->tiled) {
> >  		obj->tiling_mode = I915_TILING_X;
> > -		obj->stride = crtc->base.fb->pitches[0];
> > +		obj->stride = crtc->base.primary->fb->pitches[0];
> >  	}
> >  
> > -	mode_cmd.pixel_format = crtc->base.fb->pixel_format;
> > -	mode_cmd.width = crtc->base.fb->width;
> > -	mode_cmd.height = crtc->base.fb->height;
> > -	mode_cmd.pitches[0] = crtc->base.fb->pitches[0];
> > +	mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format;
> > +	mode_cmd.width = crtc->base.primary->fb->width;
> > +	mode_cmd.height = crtc->base.primary->fb->height;
> > +	mode_cmd.pitches[0] = crtc->base.primary->fb->pitches[0];
> >  
> >  	mutex_lock(&dev->struct_mutex);
> >  
> > -	if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.fb),
> > +	if (intel_framebuffer_init(dev,
> > +				   to_intel_framebuffer(crtc->base.primary->fb),
> >  				   &mode_cmd, obj)) {
> >  		DRM_DEBUG_KMS("intel fb init failed\n");
> >  		goto out_unref_obj;
> > @@ -2121,14 +2122,14 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
> >  	struct intel_crtc *i;
> >  	struct intel_framebuffer *fb;
> >  
> > -	if (!intel_crtc->base.fb)
> > +	if (!intel_crtc->base.primary->fb)
> >  		return;
> >  
> >  	if (intel_alloc_plane_obj(intel_crtc, plane_config))
> >  		return;
> >  
> > -	kfree(intel_crtc->base.fb);
> > -	intel_crtc->base.fb = NULL;
> > +	kfree(intel_crtc->base.primary->fb);
> > +	intel_crtc->base.primary->fb = NULL;
> >  
> >  	/*
> >  	 * Failed to alloc the obj, check to see if we should share
> > @@ -2140,13 +2141,13 @@ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
> >  		if (c == &intel_crtc->base)
> >  			continue;
> >  
> > -		if (!i->active || !c->fb)
> > +		if (!i->active || !c->primary->fb)
> >  			continue;
> >  
> > -		fb = to_intel_framebuffer(c->fb);
> > +		fb = to_intel_framebuffer(c->primary->fb);
> >  		if (i915_gem_obj_ggtt_offset(fb->obj) == plane_config->base) {
> > -			drm_framebuffer_reference(c->fb);
> > -			intel_crtc->base.fb = c->fb;
> > +			drm_framebuffer_reference(c->primary->fb);
> > +			intel_crtc->base.primary->fb = c->primary->fb;
> >  			break;
> >  		}
> >  	}
> > @@ -2394,11 +2395,13 @@ void intel_display_handle_reset(struct drm_device *dev)
> >  		/*
> >  		 * FIXME: Once we have proper support for primary planes (and
> >  		 * disabling them without disabling the entire crtc) allow again
> > -		 * a NULL crtc->fb.
> > +		 * a NULL crtc->primary->fb.
> >  		 */
> > -		if (intel_crtc->active && crtc->fb)
> > -			dev_priv->display.update_plane(crtc, crtc->fb,
> > -						       crtc->x, crtc->y);
> > +		if (intel_crtc->active && crtc->primary->fb)
> > +			dev_priv->display.update_plane(crtc,
> > +						       crtc->primary->fb,
> > +						       crtc->x,
> > +						       crtc->y);
> >  		mutex_unlock(&crtc->mutex);
> >  	}
> >  }
> > @@ -2523,8 +2526,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
> >  		return ret;
> >  	}
> >  
> > -	old_fb = crtc->fb;
> > -	crtc->fb = fb;
> > +	old_fb = crtc->primary->fb;
> > +	crtc->primary->fb = fb;
> >  	crtc->x = x;
> >  	crtc->y = y;
> >  
> > @@ -3118,7 +3121,7 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  
> > -	if (crtc->fb == NULL)
> > +	if (crtc->primary->fb == NULL)
> >  		return;
> >  
> >  	WARN_ON(waitqueue_active(&dev_priv->pending_flip_queue));
> > @@ -3127,7 +3130,7 @@ static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
> >  		   !intel_crtc_has_pending_flip(crtc));
> >  
> >  	mutex_lock(&dev->struct_mutex);
> > -	intel_finish_fb(crtc->fb);
> > +	intel_finish_fb(crtc->primary->fb);
> >  	mutex_unlock(&dev->struct_mutex);
> >  }
> >  
> > @@ -4583,11 +4586,11 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
> >  	assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe);
> >  	assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
> >  
> > -	if (crtc->fb) {
> > +	if (crtc->primary->fb) {
> >  		mutex_lock(&dev->struct_mutex);
> > -		intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj);
> > +		intel_unpin_fb_obj(to_intel_framebuffer(crtc->primary->fb)->obj);
> >  		mutex_unlock(&dev->struct_mutex);
> > -		crtc->fb = NULL;
> > +		crtc->primary->fb = NULL;
> >  	}
> >  
> >  	/* Update computed state. */
> > @@ -5738,8 +5741,9 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
> >  	int fourcc, pixel_format;
> >  	int aligned_height;
> >  
> > -	crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
> > -	if (!crtc->base.fb) {
> > +	crtc->base.primary->fb =
> > +		kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
> > +	if (!crtc->base.primary->fb) {
> >  		DRM_DEBUG_KMS("failed to alloc fb\n");
> >  		return;
> >  	}
> > @@ -5752,8 +5756,8 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
> >  
> >  	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
> >  	fourcc = intel_format_to_fourcc(pixel_format);
> > -	crtc->base.fb->pixel_format = fourcc;
> > -	crtc->base.fb->bits_per_pixel =
> > +	crtc->base.primary->fb->pixel_format = fourcc;
> > +	crtc->base.primary->fb->bits_per_pixel =
> >  		drm_format_plane_cpp(fourcc, 0) * 8;
> >  
> >  	if (INTEL_INFO(dev)->gen >= 4) {
> > @@ -5768,23 +5772,23 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
> >  	plane_config->base = base;
> >  
> >  	val = I915_READ(PIPESRC(pipe));
> > -	crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
> > -	crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
> > +	crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
> > +	crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
> >  
> >  	val = I915_READ(DSPSTRIDE(pipe));
> > -	crtc->base.fb->pitches[0] = val & 0xffffff80;
> > +	crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
> >  
> > -	aligned_height = intel_align_height(dev, crtc->base.fb->height,
> > +	aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
> >  					    plane_config->tiled);
> >  
> > -	plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
> > +	plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
> >  				   aligned_height, PAGE_SIZE);
> >  
> >  	DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
> > -		      pipe, plane, crtc->base.fb->width,
> > -		      crtc->base.fb->height,
> > -		      crtc->base.fb->bits_per_pixel, base,
> > -		      crtc->base.fb->pitches[0],
> > +		      pipe, plane, crtc->base.primary->fb->width,
> > +		      crtc->base.primary->fb->height,
> > +		      crtc->base.primary->fb->bits_per_pixel, base,
> > +		      crtc->base.primary->fb->pitches[0],
> >  		      plane_config->size);
> >  
> >  }
> > @@ -6746,8 +6750,9 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc,
> >  	int fourcc, pixel_format;
> >  	int aligned_height;
> >  
> > -	crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
> > -	if (!crtc->base.fb) {
> > +	crtc->base.primary->fb =
> > +		kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
> > +	if (!crtc->base.primary->fb) {
> >  		DRM_DEBUG_KMS("failed to alloc fb\n");
> >  		return;
> >  	}
> > @@ -6760,8 +6765,8 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc,
> >  
> >  	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
> >  	fourcc = intel_format_to_fourcc(pixel_format);
> > -	crtc->base.fb->pixel_format = fourcc;
> > -	crtc->base.fb->bits_per_pixel =
> > +	crtc->base.primary->fb->pixel_format = fourcc;
> > +	crtc->base.primary->fb->bits_per_pixel =
> >  		drm_format_plane_cpp(fourcc, 0) * 8;
> >  
> >  	base = I915_READ(DSPSURF(plane)) & 0xfffff000;
> > @@ -6776,23 +6781,23 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc,
> >  	plane_config->base = base;
> >  
> >  	val = I915_READ(PIPESRC(pipe));
> > -	crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
> > -	crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
> > +	crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
> > +	crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
> >  
> >  	val = I915_READ(DSPSTRIDE(pipe));
> > -	crtc->base.fb->pitches[0] = val & 0xffffff80;
> > +	crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
> >  
> > -	aligned_height = intel_align_height(dev, crtc->base.fb->height,
> > +	aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
> >  					    plane_config->tiled);
> >  
> > -	plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
> > +	plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
> >  				   aligned_height, PAGE_SIZE);
> >  
> >  	DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
> > -		      pipe, plane, crtc->base.fb->width,
> > -		      crtc->base.fb->height,
> > -		      crtc->base.fb->bits_per_pixel, base,
> > -		      crtc->base.fb->pitches[0],
> > +		      pipe, plane, crtc->base.primary->fb->width,
> > +		      crtc->base.primary->fb->height,
> > +		      crtc->base.primary->fb->bits_per_pixel, base,
> > +		      crtc->base.primary->fb->pitches[0],
> >  		      plane_config->size);
> >  }
> >  
> > @@ -8482,7 +8487,7 @@ void intel_mark_idle(struct drm_device *dev)
> >  		goto out;
> >  
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> > -		if (!crtc->fb)
> > +		if (!crtc->primary->fb)
> >  			continue;
> >  
> >  		intel_decrease_pllclock(crtc);
> > @@ -8505,10 +8510,10 @@ void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
> >  		return;
> >  
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> > -		if (!crtc->fb)
> > +		if (!crtc->primary->fb)
> >  			continue;
> >  
> > -		if (to_intel_framebuffer(crtc->fb)->obj != obj)
> > +		if (to_intel_framebuffer(crtc->primary->fb)->obj != obj)
> >  			continue;
> >  
> >  		intel_increase_pllclock(crtc);
> > @@ -8936,7 +8941,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct drm_framebuffer *old_fb = crtc->fb;
> > +	struct drm_framebuffer *old_fb = crtc->primary->fb;
> >  	struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >  	struct intel_unpin_work *work;
> > @@ -8944,7 +8949,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  	int ret;
> >  
> >  	/* Can't change pixel format via MI display flips. */
> > -	if (fb->pixel_format != crtc->fb->pixel_format)
> > +	if (fb->pixel_format != crtc->primary->fb->pixel_format)
> >  		return -EINVAL;
> >  
> >  	/*
> > @@ -8952,8 +8957,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  	 * Note that pitch changes could also affect these register.
> >  	 */
> >  	if (INTEL_INFO(dev)->gen > 3 &&
> > -	    (fb->offsets[0] != crtc->fb->offsets[0] ||
> > -	     fb->pitches[0] != crtc->fb->pitches[0]))
> > +	    (fb->offsets[0] != crtc->primary->fb->offsets[0] ||
> > +	     fb->pitches[0] != crtc->primary->fb->pitches[0]))
> >  		return -EINVAL;
> >  
> >  	if (i915_terminally_wedged(&dev_priv->gpu_error))
> > @@ -8996,7 +9001,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  	drm_gem_object_reference(&work->old_fb_obj->base);
> >  	drm_gem_object_reference(&obj->base);
> >  
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  
> >  	work->pending_flip_obj = obj;
> >  
> > @@ -9019,7 +9024,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
> >  
> >  cleanup_pending:
> >  	atomic_dec(&intel_crtc->unpin_work_count);
> > -	crtc->fb = old_fb;
> > +	crtc->primary->fb = old_fb;
> >  	drm_gem_object_unreference(&work->old_fb_obj->base);
> >  	drm_gem_object_unreference(&obj->base);
> >  	mutex_unlock(&dev->struct_mutex);
> > @@ -10060,7 +10065,7 @@ static int intel_set_mode(struct drm_crtc *crtc,
> >  
> >  void intel_crtc_restore_mode(struct drm_crtc *crtc)
> >  {
> > -	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->fb);
> > +	intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y, crtc->primary->fb);
> >  }
> >  
> >  #undef for_each_intel_crtc_masked
> > @@ -10184,9 +10189,9 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
> >  	 * and then just flip_or_move it */
> >  	if (is_crtc_connector_off(set)) {
> >  		config->mode_changed = true;
> > -	} else if (set->crtc->fb != set->fb) {
> > +	} else if (set->crtc->primary->fb != set->fb) {
> >  		/* If we have no fb then treat it as a full mode set */
> > -		if (set->crtc->fb == NULL) {
> > +		if (set->crtc->primary->fb == NULL) {
> >  			struct intel_crtc *intel_crtc =
> >  				to_intel_crtc(set->crtc);
> >  
> > @@ -10200,7 +10205,7 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set,
> >  		} else if (set->fb == NULL) {
> >  			config->mode_changed = true;
> >  		} else if (set->fb->pixel_format !=
> > -			   set->crtc->fb->pixel_format) {
> > +			   set->crtc->primary->fb->pixel_format) {
> >  			config->mode_changed = true;
> >  		} else {
> >  			config->fb_changed = true;
> > @@ -10413,7 +10418,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set)
> >  	save_set.mode = &set->crtc->mode;
> >  	save_set.x = set->crtc->x;
> >  	save_set.y = set->crtc->y;
> > -	save_set.fb = set->crtc->fb;
> > +	save_set.fb = set->crtc->primary->fb;
> >  
> >  	/* Compute whether we need a full modeset, only an fb base update or no
> >  	 * change at all. In the future we might also check whether only the
> > @@ -11755,7 +11760,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev,
> >  				dev_priv->pipe_to_crtc_mapping[pipe];
> >  
> >  			__intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
> > -					 crtc->fb);
> > +					 crtc->primary->fb);
> >  		}
> >  	} else {
> >  		intel_modeset_update_staged_output_state(dev);
> > @@ -11780,15 +11785,15 @@ void intel_modeset_gem_init(struct drm_device *dev)
> >  	 */
> >  	mutex_lock(&dev->struct_mutex);
> >  	list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
> > -		if (!c->fb)
> > +		if (!c->primary->fb)
> >  			continue;
> >  
> > -		fb = to_intel_framebuffer(c->fb);
> > +		fb = to_intel_framebuffer(c->primary->fb);
> >  		if (intel_pin_and_fence_fb_obj(dev, fb->obj, NULL)) {
> >  			DRM_ERROR("failed to pin boot fb on pipe %d\n",
> >  				  to_intel_crtc(c)->pipe);
> > -			drm_framebuffer_unreference(c->fb);
> > -			c->fb = NULL;
> > +			drm_framebuffer_unreference(c->primary->fb);
> > +			c->primary->fb = NULL;
> >  		}
> >  	}
> >  	mutex_unlock(&dev->struct_mutex);
> > @@ -11827,7 +11832,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
> >  
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> >  		/* Skip inactive CRTCs */
> > -		if (!crtc->fb)
> > +		if (!crtc->primary->fb)
> >  			continue;
> >  
> >  		intel_increase_pllclock(crtc);
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 59ee4dc..05531bf 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1634,7 +1634,8 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> >  	struct drm_crtc *crtc = dig_port->base.base.crtc;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -	struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj;
> > +	struct drm_i915_gem_object *obj =
> > +		to_intel_framebuffer(crtc->primary->fb)->obj;
> >  	struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
> >  
> >  	dev_priv->psr.source_ok = false;
> > @@ -1667,7 +1668,7 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp)
> >  		return false;
> >  	}
> >  
> > -	obj = to_intel_framebuffer(crtc->fb)->obj;
> > +	obj = to_intel_framebuffer(crtc->primary->fb)->obj;
> >  	if (obj->tiling_mode != I915_TILING_X ||
> >  	    obj->fence_reg == I915_FENCE_REG_NONE) {
> >  		DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
> > diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
> > index d6d78c8..2b1d42d 100644
> > --- a/drivers/gpu/drm/i915/intel_fbdev.c
> > +++ b/drivers/gpu/drm/i915/intel_fbdev.c
> > @@ -481,7 +481,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> >  		intel_crtc = to_intel_crtc(crtc);
> >  
> > -		if (!intel_crtc->active || !crtc->fb) {
> > +		if (!intel_crtc->active || !crtc->primary->fb) {
> >  			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
> >  				      pipe_name(intel_crtc->pipe));
> >  			continue;
> > @@ -491,7 +491,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
> >  			DRM_DEBUG_KMS("found possible fb from plane %c\n",
> >  				      pipe_name(intel_crtc->pipe));
> >  			plane_config = &intel_crtc->plane_config;
> > -			fb = to_intel_framebuffer(crtc->fb);
> > +			fb = to_intel_framebuffer(crtc->primary->fb);
> >  			max_size = plane_config->size;
> >  		}
> >  	}
> > @@ -560,7 +560,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
> >  		if (!intel_crtc->active)
> >  			continue;
> >  
> > -		WARN(!crtc->fb,
> > +		WARN(!crtc->primary->fb,
> >  		     "re-used BIOS config but lost an fb on crtc %d\n",
> >  		     crtc->base.id);
> >  	}
> > diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> > index 312961a..623cd32 100644
> > --- a/drivers/gpu/drm/i915/intel_overlay.c
> > +++ b/drivers/gpu/drm/i915/intel_overlay.c
> > @@ -606,14 +606,14 @@ static void update_colorkey(struct intel_overlay *overlay,
> >  {
> >  	u32 key = overlay->color_key;
> >  
> > -	switch (overlay->crtc->base.fb->bits_per_pixel) {
> > +	switch (overlay->crtc->base.primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		iowrite32(0, &regs->DCLRKV);
> >  		iowrite32(CLK_RGB8I_MASK | DST_KEY_ENABLE, &regs->DCLRKM);
> >  		break;
> >  
> >  	case 16:
> > -		if (overlay->crtc->base.fb->depth == 15) {
> > +		if (overlay->crtc->base.primary->fb->depth == 15) {
> >  			iowrite32(RGB15_TO_COLORKEY(key), &regs->DCLRKV);
> >  			iowrite32(CLK_RGB15_MASK | DST_KEY_ENABLE,
> >  				  &regs->DCLRKM);
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> > index 3a1b569..e2d73f4 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -92,7 +92,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> >  	struct drm_i915_gem_object *obj = intel_fb->obj;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -149,7 +149,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> >  	struct drm_i915_gem_object *obj = intel_fb->obj;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -221,7 +221,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> >  	struct drm_i915_gem_object *obj = intel_fb->obj;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -277,7 +277,7 @@ static void gen7_enable_fbc(struct drm_crtc *crtc)
> >  {
> >  	struct drm_device *dev = crtc->dev;
> >  	struct drm_i915_private *dev_priv = dev->dev_private;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
> >  	struct drm_i915_gem_object *obj = intel_fb->obj;
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -336,11 +336,11 @@ static void intel_fbc_work_fn(struct work_struct *__work)
> >  		/* Double check that we haven't switched fb without cancelling
> >  		 * the prior work.
> >  		 */
> > -		if (work->crtc->fb == work->fb) {
> > +		if (work->crtc->primary->fb == work->fb) {
> >  			dev_priv->display.enable_fbc(work->crtc);
> >  
> >  			dev_priv->fbc.plane = to_intel_crtc(work->crtc)->plane;
> > -			dev_priv->fbc.fb_id = work->crtc->fb->base.id;
> > +			dev_priv->fbc.fb_id = work->crtc->primary->fb->base.id;
> >  			dev_priv->fbc.y = work->crtc->y;
> >  		}
> >  
> > @@ -393,7 +393,7 @@ static void intel_enable_fbc(struct drm_crtc *crtc)
> >  	}
> >  
> >  	work->crtc = crtc;
> > -	work->fb = crtc->fb;
> > +	work->fb = crtc->primary->fb;
> >  	INIT_DELAYED_WORK(&work->work, intel_fbc_work_fn);
> >  
> >  	dev_priv->fbc.fbc_work = work;
> > @@ -499,14 +499,14 @@ void intel_update_fbc(struct drm_device *dev)
> >  		}
> >  	}
> >  
> > -	if (!crtc || crtc->fb == NULL) {
> > +	if (!crtc || crtc->primary->fb == NULL) {
> >  		if (set_no_fbc_reason(dev_priv, FBC_NO_OUTPUT))
> >  			DRM_DEBUG_KMS("no output, disabling\n");
> >  		goto out_disable;
> >  	}
> >  
> >  	intel_crtc = to_intel_crtc(crtc);
> > -	fb = crtc->fb;
> > +	fb = crtc->primary->fb;
> >  	intel_fb = to_intel_framebuffer(fb);
> >  	obj = intel_fb->obj;
> >  	adjusted_mode = &intel_crtc->config.adjusted_mode;
> > @@ -1041,7 +1041,7 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
> >  	crtc = single_enabled_crtc(dev);
> >  	if (crtc) {
> >  		const struct drm_display_mode *adjusted_mode;
> > -		int pixel_size = crtc->fb->bits_per_pixel / 8;
> > +		int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
> >  		int clock;
> >  
> >  		adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
> > @@ -1121,7 +1121,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
> >  	clock = adjusted_mode->crtc_clock;
> >  	htotal = adjusted_mode->crtc_htotal;
> >  	hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
> > -	pixel_size = crtc->fb->bits_per_pixel / 8;
> > +	pixel_size = crtc->primary->fb->bits_per_pixel / 8;
> >  
> >  	/* Use the small buffer method to calculate plane watermark */
> >  	entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
> > @@ -1208,7 +1208,7 @@ static bool g4x_compute_srwm(struct drm_device *dev,
> >  	clock = adjusted_mode->crtc_clock;
> >  	htotal = adjusted_mode->crtc_htotal;
> >  	hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
> > -	pixel_size = crtc->fb->bits_per_pixel / 8;
> > +	pixel_size = crtc->primary->fb->bits_per_pixel / 8;
> >  
> >  	line_time_us = max(htotal * 1000 / clock, 1);
> >  	line_count = (latency_ns / line_time_us + 1000) / 1000;
> > @@ -1247,7 +1247,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
> >  		return false;
> >  
> >  	clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
> > -	pixel_size = crtc->fb->bits_per_pixel / 8;	/* BPP */
> > +	pixel_size = crtc->primary->fb->bits_per_pixel / 8;	/* BPP */
> >  
> >  	entries = (clock / 1000) * pixel_size;
> >  	*plane_prec_mult = (entries > 256) ?
> > @@ -1439,7 +1439,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
> >  		int clock = adjusted_mode->crtc_clock;
> >  		int htotal = adjusted_mode->crtc_htotal;
> >  		int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
> > -		int pixel_size = crtc->fb->bits_per_pixel / 8;
> > +		int pixel_size = crtc->primary->fb->bits_per_pixel / 8;
> >  		unsigned long line_time_us;
> >  		int entries;
> >  
> > @@ -1512,7 +1512,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
> >  	crtc = intel_get_crtc_for_plane(dev, 0);
> >  	if (intel_crtc_active(crtc)) {
> >  		const struct drm_display_mode *adjusted_mode;
> > -		int cpp = crtc->fb->bits_per_pixel / 8;
> > +		int cpp = crtc->primary->fb->bits_per_pixel / 8;
> >  		if (IS_GEN2(dev))
> >  			cpp = 4;
> >  
> > @@ -1528,7 +1528,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
> >  	crtc = intel_get_crtc_for_plane(dev, 1);
> >  	if (intel_crtc_active(crtc)) {
> >  		const struct drm_display_mode *adjusted_mode;
> > -		int cpp = crtc->fb->bits_per_pixel / 8;
> > +		int cpp = crtc->primary->fb->bits_per_pixel / 8;
> >  		if (IS_GEN2(dev))
> >  			cpp = 4;
> >  
> > @@ -1565,7 +1565,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
> >  		int clock = adjusted_mode->crtc_clock;
> >  		int htotal = adjusted_mode->crtc_htotal;
> >  		int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
> > -		int pixel_size = enabled->fb->bits_per_pixel / 8;
> > +		int pixel_size = enabled->primary->fb->bits_per_pixel / 8;
> >  		unsigned long line_time_us;
> >  		int entries;
> >  
> > @@ -2117,7 +2117,7 @@ static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
> >  	if (p->active) {
> >  		p->pipe_htotal = intel_crtc->config.adjusted_mode.crtc_htotal;
> >  		p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
> > -		p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
> > +		p->pri.bytes_per_pixel = crtc->primary->fb->bits_per_pixel / 8;
> >  		p->cur.bytes_per_pixel = 4;
> >  		p->pri.horiz_pixels = intel_crtc->config.pipe_src_w;
> >  		p->cur.horiz_pixels = 64;
> > diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
> > index 1418414..f8c42b1 100644
> > --- a/drivers/gpu/drm/mgag200/mgag200_mode.c
> > +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
> > @@ -29,7 +29,7 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc)
> >  	struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
> >  	struct drm_device *dev = crtc->dev;
> >  	struct mga_device *mdev = dev->dev_private;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  	int i;
> >  
> >  	if (!crtc->enabled)
> > @@ -742,7 +742,7 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc,
> >  		mgag200_bo_unreserve(bo);
> >  	}
> >  
> > -	mga_fb = to_mga_framebuffer(crtc->fb);
> > +	mga_fb = to_mga_framebuffer(crtc->primary->fb);
> >  	obj = mga_fb->obj;
> >  	bo = gem_to_mga_bo(obj);
> >  
> > @@ -805,7 +805,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
> >  		/* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
> >  	};
> >  
> > -	bppshift = mdev->bpp_shifts[(crtc->fb->bits_per_pixel >> 3) - 1];
> > +	bppshift = mdev->bpp_shifts[(crtc->primary->fb->bits_per_pixel >> 3) - 1];
> >  
> >  	switch (mdev->type) {
> >  	case G200_SE_A:
> > @@ -843,12 +843,12 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
> >  		break;
> >  	}
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
> >  		break;
> >  	case 16:
> > -		if (crtc->fb->depth == 15)
> > +		if (crtc->primary->fb->depth == 15)
> >  			dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
> >  		else
> >  			dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
> > @@ -896,8 +896,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
> >  	WREG_SEQ(3, 0);
> >  	WREG_SEQ(4, 0xe);
> >  
> > -	pitch = crtc->fb->pitches[0] / (crtc->fb->bits_per_pixel / 8);
> > -	if (crtc->fb->bits_per_pixel == 24)
> > +	pitch = crtc->primary->fb->pitches[0] /
> > +		(crtc->primary->fb->bits_per_pixel / 8);
> > +	if (crtc->primary->fb->bits_per_pixel == 24)
> >  		pitch = (pitch * 3) >> (4 - bppshift);
> >  	else
> >  		pitch = pitch >> (4 - bppshift);
> > @@ -974,7 +975,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
> >  		((vdisplay & 0xc00) >> 7) |
> >  		((vsyncstart & 0xc00) >> 5) |
> >  		((vdisplay & 0x400) >> 3);
> > -	if (crtc->fb->bits_per_pixel == 24)
> > +	if (crtc->primary->fb->bits_per_pixel == 24)
> >  		ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
> >  	else
> >  		ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
> > @@ -1034,9 +1035,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
> >  			u32 bpp;
> >  			u32 mb;
> >  
> > -			if (crtc->fb->bits_per_pixel > 16)
> > +			if (crtc->primary->fb->bits_per_pixel > 16)
> >  				bpp = 32;
> > -			else if (crtc->fb->bits_per_pixel > 8)
> > +			else if (crtc->primary->fb->bits_per_pixel > 8)
> >  				bpp = 16;
> >  			else
> >  				bpp = 8;
> > @@ -1277,8 +1278,9 @@ static void mga_crtc_disable(struct drm_crtc *crtc)
> >  	int ret;
> >  	DRM_DEBUG_KMS("\n");
> >  	mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
> > -	if (crtc->fb) {
> > -		struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->fb);
> > +	if (crtc->primary->fb) {
> > +		struct mga_framebuffer *mga_fb =
> > +			to_mga_framebuffer(crtc->primary->fb);
> >  		struct drm_gem_object *obj = mga_fb->obj;
> >  		struct mgag200_bo *bo = gem_to_mga_bo(obj);
> >  		ret = mgag200_bo_reserve(bo, false);
> > @@ -1287,7 +1289,7 @@ static void mga_crtc_disable(struct drm_crtc *crtc)
> >  		mgag200_bo_push_sysram(bo);
> >  		mgag200_bo_unreserve(bo);
> >  	}
> > -	crtc->fb = NULL;
> > +	crtc->primary->fb = NULL;
> >  }
> >  
> >  /* These provide the minimum set of functions required to handle a CRTC */
> > diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
> > index b10f681..f96497b 100644
> > --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
> > +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
> > @@ -120,7 +120,7 @@ static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb)
> >  
> >  	/* grab reference to incoming scanout fb: */
> >  	drm_framebuffer_reference(new_fb);
> > -	mdp4_crtc->base.fb = new_fb;
> > +	mdp4_crtc->base.primary->fb = new_fb;
> >  	mdp4_crtc->fb = new_fb;
> >  
> >  	if (old_fb)
> > @@ -182,7 +182,7 @@ static void pageflip_cb(struct msm_fence_cb *cb)
> >  	struct mdp4_crtc *mdp4_crtc =
> >  		container_of(cb, struct mdp4_crtc, pageflip_cb);
> >  	struct drm_crtc *crtc = &mdp4_crtc->base;
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  
> >  	if (!fb)
> >  		return;
> > @@ -348,14 +348,14 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
> >  			mode->type, mode->flags);
> >  
> >  	/* grab extra ref for update_scanout() */
> > -	drm_framebuffer_reference(crtc->fb);
> > +	drm_framebuffer_reference(crtc->primary->fb);
> >  
> > -	ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb,
> > +	ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->primary->fb,
> >  			0, 0, mode->hdisplay, mode->vdisplay,
> >  			x << 16, y << 16,
> >  			mode->hdisplay << 16, mode->vdisplay << 16);
> >  	if (ret) {
> > -		drm_framebuffer_unreference(crtc->fb);
> > +		drm_framebuffer_unreference(crtc->primary->fb);
> >  		dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
> >  				mdp4_crtc->name, ret);
> >  		return ret;
> > @@ -368,7 +368,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
> >  	/* take data from pipe: */
> >  	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0);
> >  	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma),
> > -			crtc->fb->pitches[0]);
> > +			crtc->primary->fb->pitches[0]);
> >  	mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma),
> >  			MDP4_DMA_DST_SIZE_WIDTH(0) |
> >  			MDP4_DMA_DST_SIZE_HEIGHT(0));
> > @@ -378,7 +378,7 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
> >  			MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) |
> >  			MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay));
> >  	mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp),
> > -			crtc->fb->pitches[0]);
> > +			crtc->primary->fb->pitches[0]);
> >  
> >  	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);
> >  
> > @@ -388,8 +388,8 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
> >  		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
> >  	}
> >  
> > -	update_fb(crtc, crtc->fb);
> > -	update_scanout(crtc, crtc->fb);
> > +	update_fb(crtc, crtc->primary->fb);
> > +	update_scanout(crtc, crtc->primary->fb);
> >  
> >  	return 0;
> >  }
> > @@ -420,19 +420,19 @@ static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> >  	int ret;
> >  
> >  	/* grab extra ref for update_scanout() */
> > -	drm_framebuffer_reference(crtc->fb);
> > +	drm_framebuffer_reference(crtc->primary->fb);
> >  
> > -	ret = mdp4_plane_mode_set(plane, crtc, crtc->fb,
> > +	ret = mdp4_plane_mode_set(plane, crtc, crtc->primary->fb,
> >  			0, 0, mode->hdisplay, mode->vdisplay,
> >  			x << 16, y << 16,
> >  			mode->hdisplay << 16, mode->vdisplay << 16);
> >  	if (ret) {
> > -		drm_framebuffer_unreference(crtc->fb);
> > +		drm_framebuffer_unreference(crtc->primary->fb);
> >  		return ret;
> >  	}
> >  
> > -	update_fb(crtc, crtc->fb);
> > -	update_scanout(crtc, crtc->fb);
> > +	update_fb(crtc, crtc->primary->fb);
> > +	update_scanout(crtc, crtc->primary->fb);
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > index 7dc3d71..f200048 100644
> > --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
> > @@ -102,7 +102,7 @@ static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb)
> >  
> >  	/* grab reference to incoming scanout fb: */
> >  	drm_framebuffer_reference(new_fb);
> > -	mdp5_crtc->base.fb = new_fb;
> > +	mdp5_crtc->base.primary->fb = new_fb;
> >  	mdp5_crtc->fb = new_fb;
> >  
> >  	if (old_fb)
> > @@ -289,14 +289,14 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc,
> >  			mode->type, mode->flags);
> >  
> >  	/* grab extra ref for update_scanout() */
> > -	drm_framebuffer_reference(crtc->fb);
> > +	drm_framebuffer_reference(crtc->primary->fb);
> >  
> > -	ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->fb,
> > +	ret = mdp5_plane_mode_set(mdp5_crtc->plane, crtc, crtc->primary->fb,
> >  			0, 0, mode->hdisplay, mode->vdisplay,
> >  			x << 16, y << 16,
> >  			mode->hdisplay << 16, mode->vdisplay << 16);
> >  	if (ret) {
> > -		drm_framebuffer_unreference(crtc->fb);
> > +		drm_framebuffer_unreference(crtc->primary->fb);
> >  		dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
> >  				mdp5_crtc->name, ret);
> >  		return ret;
> > @@ -306,8 +306,8 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc,
> >  			MDP5_LM_OUT_SIZE_WIDTH(mode->hdisplay) |
> >  			MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay));
> >  
> > -	update_fb(crtc, crtc->fb);
> > -	update_scanout(crtc, crtc->fb);
> > +	update_fb(crtc, crtc->primary->fb);
> > +	update_scanout(crtc, crtc->primary->fb);
> >  
> >  	return 0;
> >  }
> > @@ -338,19 +338,19 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> >  	int ret;
> >  
> >  	/* grab extra ref for update_scanout() */
> > -	drm_framebuffer_reference(crtc->fb);
> > +	drm_framebuffer_reference(crtc->primary->fb);
> >  
> > -	ret = mdp5_plane_mode_set(plane, crtc, crtc->fb,
> > +	ret = mdp5_plane_mode_set(plane, crtc, crtc->primary->fb,
> >  			0, 0, mode->hdisplay, mode->vdisplay,
> >  			x << 16, y << 16,
> >  			mode->hdisplay << 16, mode->vdisplay << 16);
> >  	if (ret) {
> > -		drm_framebuffer_unreference(crtc->fb);
> > +		drm_framebuffer_unreference(crtc->primary->fb);
> >  		return ret;
> >  	}
> >  
> > -	update_fb(crtc, crtc->fb);
> > -	update_scanout(crtc, crtc->fb);
> > +	update_fb(crtc, crtc->primary->fb);
> > +	update_scanout(crtc, crtc->primary->fb);
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
> > index b55be84..2a5e9db 100644
> > --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
> > +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
> > @@ -239,7 +239,7 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
> >  	struct drm_device *dev = crtc->dev;
> >  	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
> >  	struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index];
> > -	struct drm_framebuffer *fb = crtc->fb;
> > +	struct drm_framebuffer *fb = crtc->primary->fb;
> >  
> >  	/* Calculate our timings */
> >  	int horizDisplay	= (mode->crtc_hdisplay >> 3)		- 1;
> > @@ -574,7 +574,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
> >  		regp->CRTC[NV_CIO_CRE_86] = 0x1;
> >  	}
> >  
> > -	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8;
> > +	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->primary->fb->depth + 1) / 8;
> >  	/* Enable slaved mode (called MODE_TV in nv4ref.h) */
> >  	if (lvds_output || tmds_output || tv_output)
> >  		regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7);
> > @@ -588,7 +588,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode)
> >  	regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS |
> >  				NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL |
> >  				NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON;
> > -	if (crtc->fb->depth == 16)
> > +	if (crtc->primary->fb->depth == 16)
> >  		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
> >  	if (nv_device(drm->device)->chipset >= 0x11)
> >  		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG;
> > @@ -609,7 +609,7 @@ static int
> >  nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
> >  {
> >  	struct nv04_display *disp = nv04_display(crtc->dev);
> > -	struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb);
> > +	struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb);
> >  	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
> >  	int ret;
> >  
> > @@ -808,7 +808,7 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
> >  	 * mark the lut values as dirty by setting depth==0, and it'll be
> >  	 * uploaded on the first mode_set_base()
> >  	 */
> > -	if (!nv_crtc->base.fb) {
> > +	if (!nv_crtc->base.primary->fb) {
> >  		nv_crtc->lut.depth = 0;
> >  		return;
> >  	}
> > @@ -832,7 +832,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
> >  	NV_DEBUG(drm, "index %d\n", nv_crtc->index);
> >  
> >  	/* no fb bound */
> > -	if (!atomic && !crtc->fb) {
> > +	if (!atomic && !crtc->primary->fb) {
> >  		NV_DEBUG(drm, "No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -844,8 +844,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
> >  		drm_fb = passed_fb;
> >  		fb = nouveau_framebuffer(passed_fb);
> >  	} else {
> > -		drm_fb = crtc->fb;
> > -		fb = nouveau_framebuffer(crtc->fb);
> > +		drm_fb = crtc->primary->fb;
> > +		fb = nouveau_framebuffer(crtc->primary->fb);
> >  	}
> >  
> >  	nv_crtc->fb.offset = fb->nvbo->bo.offset;
> > @@ -857,9 +857,9 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
> >  
> >  	/* Update the framebuffer format. */
> >  	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3;
> > -	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8;
> > +	regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->primary->fb->depth + 1) / 8;
> >  	regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
> > -	if (crtc->fb->depth == 16)
> > +	if (crtc->primary->fb->depth == 16)
> >  		regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL;
> >  	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX);
> >  	NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL,
> > diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
> > index 7fdc51e..a2d669b 100644
> > --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c
> > +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
> > @@ -415,7 +415,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder,
> >  	/* Output property. */
> >  	if ((nv_connector->dithering_mode == DITHERING_MODE_ON) ||
> >  	    (nv_connector->dithering_mode == DITHERING_MODE_AUTO &&
> > -	     encoder->crtc->fb->depth > connector->display_info.bpc * 3)) {
> > +	     encoder->crtc->primary->fb->depth > connector->display_info.bpc * 3)) {
> >  		if (nv_device(drm->device)->chipset == 0x11)
> >  			regp->dither = savep->dither | 0x00010000;
> >  		else {
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
> > index 2401159..4e24c72 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_display.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_display.c
> > @@ -569,7 +569,7 @@ nouveau_display_suspend(struct drm_device *dev)
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> >  		struct nouveau_framebuffer *nouveau_fb;
> >  
> > -		nouveau_fb = nouveau_framebuffer(crtc->fb);
> > +		nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
> >  		if (!nouveau_fb || !nouveau_fb->nvbo)
> >  			continue;
> >  
> > @@ -596,7 +596,7 @@ nouveau_display_repin(struct drm_device *dev)
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> >  		struct nouveau_framebuffer *nouveau_fb;
> >  
> > -		nouveau_fb = nouveau_framebuffer(crtc->fb);
> > +		nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
> >  		if (!nouveau_fb || !nouveau_fb->nvbo)
> >  			continue;
> >  
> > @@ -693,7 +693,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> >  	const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
> >  	struct drm_device *dev = crtc->dev;
> >  	struct nouveau_drm *drm = nouveau_drm(dev);
> > -	struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo;
> > +	struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo;
> >  	struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
> >  	struct nouveau_page_flip_state *s;
> >  	struct nouveau_channel *chan = drm->channel;
> > @@ -767,7 +767,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
> >  		goto fail_unreserve;
> >  
> >  	/* Update the crtc struct and cleanup */
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  
> >  	nouveau_bo_fence(old_bo, fence);
> >  	ttm_bo_unreserve(&old_bo->bo);
> > diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
> > index 5706842..c744bf6 100644
> > --- a/drivers/gpu/drm/nouveau/nv50_display.c
> > +++ b/drivers/gpu/drm/nouveau/nv50_display.c
> > @@ -651,7 +651,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
> >  	nv_connector = nouveau_crtc_connector_get(nv_crtc);
> >  	connector = &nv_connector->base;
> >  	if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) {
> > -		if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3)
> > +		if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3)
> >  			mode = DITHERING_MODE_DYNAMIC2X2;
> >  	} else {
> >  		mode = nv_connector->dithering_mode;
> > @@ -785,7 +785,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
> >  
> >  		if (update) {
> >  			nv50_display_flip_stop(crtc);
> > -			nv50_display_flip_next(crtc, crtc->fb, NULL, 1);
> > +			nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
> >  		}
> >  	}
> >  
> > @@ -1028,7 +1028,7 @@ nv50_crtc_commit(struct drm_crtc *crtc)
> >  	}
> >  
> >  	nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true);
> > -	nv50_display_flip_next(crtc, crtc->fb, NULL, 1);
> > +	nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
> >  }
> >  
> >  static bool
> > @@ -1042,7 +1042,8 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode,
> >  static int
> >  nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
> >  {
> > -	struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb);
> > +	struct nouveau_framebuffer *nvfb =
> > +		nouveau_framebuffer(crtc->primary->fb);
> >  	struct nv50_head *head = nv50_head(crtc);
> >  	int ret;
> >  
> > @@ -1139,7 +1140,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
> >  	nv50_crtc_set_dither(nv_crtc, false);
> >  	nv50_crtc_set_scale(nv_crtc, false);
> >  	nv50_crtc_set_color_vibrance(nv_crtc, false);
> > -	nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, false);
> > +	nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false);
> >  	return 0;
> >  }
> >  
> > @@ -1151,7 +1152,7 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> >  	struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
> >  	int ret;
> >  
> > -	if (!crtc->fb) {
> > +	if (!crtc->primary->fb) {
> >  		NV_DEBUG(drm, "No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -1161,8 +1162,8 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
> >  		return ret;
> >  
> >  	nv50_display_flip_stop(crtc);
> > -	nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, true);
> > -	nv50_display_flip_next(crtc, crtc->fb, NULL, 1);
> > +	nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true);
> > +	nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
> >  	return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
> > index 24b6112..5be0b87 100644
> > --- a/drivers/gpu/drm/qxl/qxl_display.c
> > +++ b/drivers/gpu/drm/qxl/qxl_display.c
> > @@ -527,7 +527,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
> >  	bool recreate_primary = false;
> >  	int ret;
> >  	int surf_id;
> > -	if (!crtc->fb) {
> > +	if (!crtc->primary->fb) {
> >  		DRM_DEBUG_KMS("No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -536,7 +536,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc,
> >  		qfb = to_qxl_framebuffer(old_fb);
> >  		old_bo = gem_to_qxl_bo(qfb->obj);
> >  	}
> > -	qfb = to_qxl_framebuffer(crtc->fb);
> > +	qfb = to_qxl_framebuffer(crtc->primary->fb);
> >  	bo = gem_to_qxl_bo(qfb->obj);
> >  	if (!m)
> >  		/* and do we care? */
> > @@ -609,14 +609,15 @@ static void qxl_crtc_disable(struct drm_crtc *crtc)
> >  	struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
> >  	struct drm_device *dev = crtc->dev;
> >  	struct qxl_device *qdev = dev->dev_private;
> > -	if (crtc->fb) {
> > -		struct qxl_framebuffer *qfb = to_qxl_framebuffer(crtc->fb);
> > +	if (crtc->primary->fb) {
> > +		struct qxl_framebuffer *qfb =
> > +			to_qxl_framebuffer(crtc->primary->fb);
> >  		struct qxl_bo *bo = gem_to_qxl_bo(qfb->obj);
> >  		int ret;
> >  		ret = qxl_bo_reserve(bo, false);
> >  		qxl_bo_unpin(bo);
> >  		qxl_bo_unreserve(bo);
> > -		crtc->fb = NULL;
> > +		crtc->primary->fb = NULL;
> >  	}
> >  
> >  	qxl_monitors_config_set(qdev, qcrtc->index, 0, 0, 0, 0, 0);
> > diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
> > index daa4dd3..fb187c7 100644
> > --- a/drivers/gpu/drm/radeon/atombios_crtc.c
> > +++ b/drivers/gpu/drm/radeon/atombios_crtc.c
> > @@ -1106,7 +1106,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
> >  	int r;
> >  
> >  	/* no fb bound */
> > -	if (!atomic && !crtc->fb) {
> > +	if (!atomic && !crtc->primary->fb) {
> >  		DRM_DEBUG_KMS("No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -1116,8 +1116,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
> >  		target_fb = fb;
> >  	}
> >  	else {
> > -		radeon_fb = to_radeon_framebuffer(crtc->fb);
> > -		target_fb = crtc->fb;
> > +		radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> > +		target_fb = crtc->primary->fb;
> >  	}
> >  
> >  	/* If atomic, assume fb object is pinned & idle & fenced and
> > @@ -1316,7 +1316,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
> >  	/* set pageflip to happen anywhere in vblank interval */
> >  	WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> >  
> > -	if (!atomic && fb && fb != crtc->fb) {
> > +	if (!atomic && fb && fb != crtc->primary->fb) {
> >  		radeon_fb = to_radeon_framebuffer(fb);
> >  		rbo = gem_to_radeon_bo(radeon_fb->obj);
> >  		r = radeon_bo_reserve(rbo, false);
> > @@ -1350,7 +1350,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
> >  	int r;
> >  
> >  	/* no fb bound */
> > -	if (!atomic && !crtc->fb) {
> > +	if (!atomic && !crtc->primary->fb) {
> >  		DRM_DEBUG_KMS("No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -1360,8 +1360,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
> >  		target_fb = fb;
> >  	}
> >  	else {
> > -		radeon_fb = to_radeon_framebuffer(crtc->fb);
> > -		target_fb = crtc->fb;
> > +		radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> > +		target_fb = crtc->primary->fb;
> >  	}
> >  
> >  	obj = radeon_fb->obj;
> > @@ -1485,7 +1485,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
> >  	/* set pageflip to happen anywhere in vblank interval */
> >  	WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
> >  
> > -	if (!atomic && fb && fb != crtc->fb) {
> > +	if (!atomic && fb && fb != crtc->primary->fb) {
> >  		radeon_fb = to_radeon_framebuffer(fb);
> >  		rbo = gem_to_radeon_bo(radeon_fb->obj);
> >  		r = radeon_bo_reserve(rbo, false);
> > @@ -1972,12 +1972,12 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
> >  	int i;
> >  
> >  	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
> > -	if (crtc->fb) {
> > +	if (crtc->primary->fb) {
> >  		int r;
> >  		struct radeon_framebuffer *radeon_fb;
> >  		struct radeon_bo *rbo;
> >  
> > -		radeon_fb = to_radeon_framebuffer(crtc->fb);
> > +		radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> >  		rbo = gem_to_radeon_bo(radeon_fb->obj);
> >  		r = radeon_bo_reserve(rbo, false);
> >  		if (unlikely(r))
> > diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> > index 030f8e4..b6c3264 100644
> > --- a/drivers/gpu/drm/radeon/r100.c
> > +++ b/drivers/gpu/drm/radeon/r100.c
> > @@ -3220,12 +3220,12 @@ void r100_bandwidth_update(struct radeon_device *rdev)
> >  
> >  	if (rdev->mode_info.crtcs[0]->base.enabled) {
> >  		mode1 = &rdev->mode_info.crtcs[0]->base.mode;
> > -		pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
> > +		pixel_bytes1 = rdev->mode_info.crtcs[0]->base.primary->fb->bits_per_pixel / 8;
> >  	}
> >  	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
> >  		if (rdev->mode_info.crtcs[1]->base.enabled) {
> >  			mode2 = &rdev->mode_info.crtcs[1]->base.mode;
> > -			pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
> > +			pixel_bytes2 = rdev->mode_info.crtcs[1]->base.primary->fb->bits_per_pixel / 8;
> >  		}
> >  	}
> >  
> > diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
> > index 82d4f86..33b482b 100644
> > --- a/drivers/gpu/drm/radeon/radeon_connectors.c
> > +++ b/drivers/gpu/drm/radeon/radeon_connectors.c
> > @@ -89,7 +89,7 @@ static void radeon_property_change_mode(struct drm_encoder *encoder)
> >  
> >  	if (crtc && crtc->enabled) {
> >  		drm_crtc_helper_set_mode(crtc, &crtc->mode,
> > -					 crtc->x, crtc->y, crtc->fb);
> > +					 crtc->x, crtc->y, crtc->primary->fb);
> >  	}
> >  }
> >  
> > diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> > index 2e72dcd..c524aba 100644
> > --- a/drivers/gpu/drm/radeon/radeon_device.c
> > +++ b/drivers/gpu/drm/radeon/radeon_device.c
> > @@ -1424,7 +1424,8 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
> >  
> >  	/* unpin the front buffers */
> >  	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> > -		struct radeon_framebuffer *rfb = to_radeon_framebuffer(crtc->fb);
> > +		struct radeon_framebuffer *rfb =
> > +			to_radeon_framebuffer(crtc->primary->fb);
> >  		struct radeon_bo *robj;
> >  
> >  		if (rfb == NULL || rfb->obj == NULL) {
> > diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> > index a29d217..4e90049 100644
> > --- a/drivers/gpu/drm/radeon/radeon_display.c
> > +++ b/drivers/gpu/drm/radeon/radeon_display.c
> > @@ -369,7 +369,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> >  	work->event = event;
> >  	work->rdev = rdev;
> >  	work->crtc_id = radeon_crtc->crtc_id;
> > -	old_radeon_fb = to_radeon_framebuffer(crtc->fb);
> > +	old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> >  	new_radeon_fb = to_radeon_framebuffer(fb);
> >  	/* schedule unpin of the old buffer */
> >  	obj = old_radeon_fb->obj;
> > @@ -460,7 +460,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
> >  	spin_unlock_irqrestore(&dev->event_lock, flags);
> >  
> >  	/* update crtc fb */
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  
> >  	r = drm_vblank_get(dev, radeon_crtc->crtc_id);
> >  	if (r) {
> > diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
> > index 0b158f9..cafb1cc 100644
> > --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
> > +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
> > @@ -385,7 +385,7 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc,
> >  
> >  	DRM_DEBUG_KMS("\n");
> >  	/* no fb bound */
> > -	if (!atomic && !crtc->fb) {
> > +	if (!atomic && !crtc->primary->fb) {
> >  		DRM_DEBUG_KMS("No FB bound\n");
> >  		return 0;
> >  	}
> > @@ -395,8 +395,8 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc,
> >  		target_fb = fb;
> >  	}
> >  	else {
> > -		radeon_fb = to_radeon_framebuffer(crtc->fb);
> > -		target_fb = crtc->fb;
> > +		radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> > +		target_fb = crtc->primary->fb;
> >  	}
> >  
> >  	switch (target_fb->bits_per_pixel) {
> > @@ -444,7 +444,7 @@ retry:
> >  		 * We don't shutdown the display controller because new buffer
> >  		 * will end up in same spot.
> >  		 */
> > -		if (!atomic && fb && fb != crtc->fb) {
> > +		if (!atomic && fb && fb != crtc->primary->fb) {
> >  			struct radeon_bo *old_rbo;
> >  			unsigned long nsize, osize;
> >  
> > @@ -555,7 +555,7 @@ retry:
> >  	WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
> >  	WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
> >  
> > -	if (!atomic && fb && fb != crtc->fb) {
> > +	if (!atomic && fb && fb != crtc->primary->fb) {
> >  		radeon_fb = to_radeon_framebuffer(fb);
> >  		rbo = gem_to_radeon_bo(radeon_fb->obj);
> >  		r = radeon_bo_reserve(rbo, false);
> > @@ -599,7 +599,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
> >  		}
> >  	}
> >  
> > -	switch (crtc->fb->bits_per_pixel) {
> > +	switch (crtc->primary->fb->bits_per_pixel) {
> >  	case 8:
> >  		format = 2;
> >  		break;
> > @@ -1087,12 +1087,12 @@ static void radeon_crtc_commit(struct drm_crtc *crtc)
> >  static void radeon_crtc_disable(struct drm_crtc *crtc)
> >  {
> >  	radeon_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
> > -	if (crtc->fb) {
> > +	if (crtc->primary->fb) {
> >  		int r;
> >  		struct radeon_framebuffer *radeon_fb;
> >  		struct radeon_bo *rbo;
> >  
> > -		radeon_fb = to_radeon_framebuffer(crtc->fb);
> > +		radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
> >  		rbo = gem_to_radeon_bo(radeon_fb->obj);
> >  		r = radeon_bo_reserve(rbo, false);
> >  		if (unlikely(r))
> > diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
> > index 1255944..c63b5e7 100644
> > --- a/drivers/gpu/drm/udl/udl_modeset.c
> > +++ b/drivers/gpu/drm/udl/udl_modeset.c
> > @@ -310,7 +310,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc,
> >  
> >  {
> >  	struct drm_device *dev = crtc->dev;
> > -	struct udl_framebuffer *ufb = to_udl_fb(crtc->fb);
> > +	struct udl_framebuffer *ufb = to_udl_fb(crtc->primary->fb);
> >  	struct udl_device *udl = dev->dev_private;
> >  	char *buf;
> >  	char *wrptr;
> > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> > index 8a65041..1d59ed3 100644
> > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
> > @@ -468,7 +468,7 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
> >  	num_units = 0;
> >  	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
> >  			    head) {
> > -		if (crtc->fb != &framebuffer->base)
> > +		if (crtc->primary->fb != &framebuffer->base)
> >  			continue;
> >  		units[num_units++] = vmw_crtc_to_du(crtc);
> >  	}
> > @@ -883,7 +883,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
> >  
> >  	num_units = 0;
> >  	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
> > -		if (crtc->fb != &framebuffer->base)
> > +		if (crtc->primary->fb != &framebuffer->base)
> >  			continue;
> >  		units[num_units++] = vmw_crtc_to_du(crtc);
> >  	}
> > @@ -1245,7 +1245,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
> >  
> >  	num_units = 0;
> >  	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
> > -		if (crtc->fb != &vfb->base)
> > +		if (crtc->primary->fb != &vfb->base)
> >  			continue;
> >  		units[num_units++] = vmw_crtc_to_du(crtc);
> >  	}
> > @@ -1382,7 +1382,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
> >  
> >  	num_units = 0;
> >  	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
> > -		if (crtc->fb != &vfb->base)
> > +		if (crtc->primary->fb != &vfb->base)
> >  			continue;
> >  		units[num_units++] = vmw_crtc_to_du(crtc);
> >  	}
> > @@ -1725,7 +1725,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc,
> >  		     uint32_t page_flip_flags)
> >  {
> >  	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
> > -	struct drm_framebuffer *old_fb = crtc->fb;
> > +	struct drm_framebuffer *old_fb = crtc->primary->fb;
> >  	struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
> >  	struct drm_file *file_priv ;
> >  	struct vmw_fence_obj *fence = NULL;
> > @@ -1743,7 +1743,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc,
> >  	if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
> >  		return -EINVAL;
> >  
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  
> >  	/* do a full screen dirty update */
> >  	clips.x1 = clips.y1 = 0;
> > @@ -1783,7 +1783,7 @@ int vmw_du_page_flip(struct drm_crtc *crtc,
> >  	return ret;
> >  
> >  out_no_fence:
> > -	crtc->fb = old_fb;
> > +	crtc->primary->fb = old_fb;
> >  	return ret;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
> > index 001ec81..08fdd7f 100644
> > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
> > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
> > @@ -93,7 +93,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
> >  
> >  		if (crtc == NULL)
> >  			return 0;
> > -		fb = entry->base.crtc.fb;
> > +		fb = entry->base.crtc.primary->fb;
> >  
> >  		return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0],
> >  					  fb->bits_per_pixel, fb->depth);
> > @@ -101,7 +101,7 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
> >  
> >  	if (!list_empty(&lds->active)) {
> >  		entry = list_entry(lds->active.next, typeof(*entry), active);
> > -		fb = entry->base.crtc.fb;
> > +		fb = entry->base.crtc.primary->fb;
> >  
> >  		vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitches[0],
> >  				   fb->bits_per_pixel, fb->depth);
> > @@ -259,7 +259,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
> >  
> >  		connector->encoder = NULL;
> >  		encoder->crtc = NULL;
> > -		crtc->fb = NULL;
> > +		crtc->primary->fb = NULL;
> >  		crtc->enabled = false;
> >  
> >  		vmw_ldu_del_active(dev_priv, ldu);
> > @@ -280,7 +280,7 @@ static int vmw_ldu_crtc_set_config(struct drm_mode_set *set)
> >  
> >  	vmw_fb_off(dev_priv);
> >  
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  	encoder->crtc = crtc;
> >  	connector->encoder = encoder;
> >  	crtc->x = set->x;
> > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
> > index 585da43..46ea096 100644
> > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
> > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
> > @@ -307,7 +307,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
> >  
> >  		connector->encoder = NULL;
> >  		encoder->crtc = NULL;
> > -		crtc->fb = NULL;
> > +		crtc->primary->fb = NULL;
> >  		crtc->x = 0;
> >  		crtc->y = 0;
> >  		crtc->enabled = false;
> > @@ -368,7 +368,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
> >  
> >  		connector->encoder = NULL;
> >  		encoder->crtc = NULL;
> > -		crtc->fb = NULL;
> > +		crtc->primary->fb = NULL;
> >  		crtc->x = 0;
> >  		crtc->y = 0;
> >  		crtc->enabled = false;
> > @@ -381,7 +381,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
> >  	connector->encoder = encoder;
> >  	encoder->crtc = crtc;
> >  	crtc->mode = *mode;
> > -	crtc->fb = fb;
> > +	crtc->primary->fb = fb;
> >  	crtc->x = set->x;
> >  	crtc->y = set->y;
> >  	crtc->enabled = true;
> > @@ -574,5 +574,5 @@ void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
> >  	BUG_ON(!sou->base.is_implicit);
> >  
> >  	dev_priv->sou_priv->implicit_fb =
> > -		vmw_framebuffer_to_vfb(sou->base.crtc.fb);
> > +		vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb);
> >  }
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index 4dc84f8..9f7824d 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -309,9 +309,6 @@ struct drm_crtc {
> >  	/* primary plane for CRTC */
> >  	struct drm_plane *primary;
> >  
> > -	/* framebuffer the connector is currently bound to */
> > -	struct drm_framebuffer *fb;
> > -
> >  	/* Temporary tracking of the old fb while a modeset is ongoing. Used
> >  	 * by drm_mode_set_config_internal to implement correct refcounting. */
> >  	struct drm_framebuffer *old_fb;
> > -- 
> > 1.8.5.1
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch

-- 
Matt Roper
Graphics Software Engineer
ISG Platform Enabling & Development
Intel Corporation
(916) 356-2795


More information about the dri-devel mailing list