void (*set_false_color)(struct intel_fbc *fbc, bool enable);
 };
 
+struct intel_fbc_state {
+       const char *no_fbc_reason;
+       enum i9xx_plane_id i9xx_plane;
+       unsigned int cfb_stride;
+       unsigned int cfb_size;
+       unsigned int fence_y_offset;
+       u16 override_cfb_stride;
+       u16 interval;
+       s8 fence_id;
+};
+
+struct intel_fbc {
+       struct drm_i915_private *i915;
+       const struct intel_fbc_funcs *funcs;
+
+       /*
+        * This is always the inner lock when overlapping with
+        * struct_mutex and it's the outer lock when overlapping
+        * with stolen_lock.
+        */
+       struct mutex lock;
+       unsigned int possible_framebuffer_bits;
+       unsigned int busy_bits;
+       struct intel_plane *plane;
+
+       struct drm_mm_node compressed_fb;
+       struct drm_mm_node compressed_llb;
+
+       u8 limit;
+
+       bool false_color;
+
+       bool active;
+       bool activated;
+       bool flip_pending;
+
+       bool underrun_detected;
+       struct work_struct underrun_work;
+
+       /*
+        * Due to the atomic rules we can't access some structures without the
+        * appropriate locking, so we cache information here in order to avoid
+        * these problems.
+        */
+       struct intel_fbc_state state_cache;
+
+       /*
+        * This structure contains everything that's relevant to program the
+        * hardware registers. When we want to figure out if we need to disable
+        * and re-enable FBC for a new configuration we just check if there's
+        * something different in the struct. The genx_fbc_activate functions
+        * are supposed to read from it in order to program the registers.
+        */
+       struct intel_fbc_state params;
+       const char *no_fbc_reason;
+};
+
 /* plane stride in pixels */
 static unsigned int intel_fbc_plane_stride(const struct intel_plane_state *plane_state)
 {
 
 void intel_fbc_cleanup(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        mutex_lock(&fbc->lock);
        __intel_fbc_cleanup_cfb(fbc);
        mutex_unlock(&fbc->lock);
+
+       kfree(fbc);
 }
 
 static bool stride_is_valid(const struct intel_plane_state *plane_state)
                          unsigned int frontbuffer_bits,
                          enum fb_op_origin origin)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
 void intel_fbc_flush(struct drm_i915_private *i915,
                     unsigned int frontbuffer_bits, enum fb_op_origin origin)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        mutex_lock(&fbc->lock);
  */
 void intel_fbc_global_disable(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        mutex_lock(&fbc->lock);
 
 static void intel_fbc_underrun_work_fn(struct work_struct *work)
 {
-       struct drm_i915_private *i915 =
-               container_of(work, struct drm_i915_private, fbc.underrun_work);
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = container_of(work, typeof(*fbc), underrun_work);
+       struct drm_i915_private *i915 = fbc->i915;
 
        mutex_lock(&fbc->lock);
 
  */
 void intel_fbc_reset_underrun(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        cancel_work_sync(&fbc->underrun_work);
  */
 void intel_fbc_handle_fifo_underrun_irq(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (!HAS_FBC(i915))
+       if (!fbc)
                return;
 
        /* There's no guarantee that underrun_detected won't be set to true
        fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
 }
 
+static struct intel_fbc *intel_fbc_create(struct drm_i915_private *i915)
+{
+       struct intel_fbc *fbc;
+
+       fbc = kzalloc(sizeof(*fbc), GFP_KERNEL);
+       if (!fbc)
+               return NULL;
+
+       fbc->i915 = i915;
+       INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
+       mutex_init(&fbc->lock);
+
+       if (DISPLAY_VER(i915) >= 7)
+               fbc->funcs = &ivb_fbc_funcs;
+       else if (DISPLAY_VER(i915) == 6)
+               fbc->funcs = &snb_fbc_funcs;
+       else if (DISPLAY_VER(i915) == 5)
+               fbc->funcs = &ilk_fbc_funcs;
+       else if (IS_G4X(i915))
+               fbc->funcs = &g4x_fbc_funcs;
+       else if (DISPLAY_VER(i915) == 4)
+               fbc->funcs = &i965_fbc_funcs;
+       else
+               fbc->funcs = &i8xx_fbc_funcs;
+
+       return fbc;
+}
+
 /**
  * intel_fbc_init - Initialize FBC
  * @i915: the i915 device
  */
 void intel_fbc_init(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
-
-       fbc->i915 = i915;
-       INIT_WORK(&fbc->underrun_work, intel_fbc_underrun_work_fn);
-       mutex_init(&fbc->lock);
-       fbc->active = false;
+       struct intel_fbc *fbc;
 
        if (!drm_mm_initialized(&i915->mm.stolen))
                mkwrite_device_info(i915)->display.has_fbc = false;
        drm_dbg_kms(&i915->drm, "Sanitized enable_fbc value: %d\n",
                    i915->params.enable_fbc);
 
-       if (!HAS_FBC(i915)) {
-               fbc->no_fbc_reason = "unsupported by this chipset";
+       if (!HAS_FBC(i915))
                return;
-       }
 
-       if (DISPLAY_VER(i915) >= 7)
-               fbc->funcs = &ivb_fbc_funcs;
-       else if (DISPLAY_VER(i915) == 6)
-               fbc->funcs = &snb_fbc_funcs;
-       else if (DISPLAY_VER(i915) == 5)
-               fbc->funcs = &ilk_fbc_funcs;
-       else if (IS_G4X(i915))
-               fbc->funcs = &g4x_fbc_funcs;
-       else if (DISPLAY_VER(i915) == 4)
-               fbc->funcs = &i965_fbc_funcs;
-       else
-               fbc->funcs = &i8xx_fbc_funcs;
+       fbc = intel_fbc_create(i915);
+       if (!fbc)
+               return;
 
        /* We still don't have any sort of hardware state readout for FBC, so
         * deactivate it in case the BIOS activated it to make sure software
         * matches the hardware state. */
        if (intel_fbc_hw_is_active(fbc))
                intel_fbc_hw_deactivate(fbc);
+
+       i915->fbc = fbc;
 }
 
 static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused)
 
 void intel_fbc_debugfs_register(struct drm_i915_private *i915)
 {
-       struct intel_fbc *fbc = &i915->fbc;
+       struct intel_fbc *fbc = i915->fbc;
 
-       if (HAS_FBC(i915))
+       if (fbc)
                intel_fbc_debugfs_add(fbc);
 }
 
        void (*commit_modeset_enables)(struct intel_atomic_state *state);
 };
 
-struct intel_fbc_funcs;
-
 #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */
 
-struct intel_fbc_state {
-       const char *no_fbc_reason;
-       enum i9xx_plane_id i9xx_plane;
-       unsigned int cfb_stride;
-       unsigned int cfb_size;
-       unsigned int fence_y_offset;
-       u16 override_cfb_stride;
-       u16 interval;
-       s8 fence_id;
-};
-
-struct intel_fbc {
-       struct drm_i915_private *i915;
-       const struct intel_fbc_funcs *funcs;
-
-       /* This is always the inner lock when overlapping with struct_mutex and
-        * it's the outer lock when overlapping with stolen_lock. */
-       struct mutex lock;
-       unsigned int possible_framebuffer_bits;
-       unsigned int busy_bits;
-       struct intel_plane *plane;
-
-       struct drm_mm_node compressed_fb;
-       struct drm_mm_node compressed_llb;
-
-       u8 limit;
-
-       bool false_color;
-
-       bool active;
-       bool activated;
-       bool flip_pending;
-
-       bool underrun_detected;
-       struct work_struct underrun_work;
-
-       /*
-        * Due to the atomic rules we can't access some structures without the
-        * appropriate locking, so we cache information here in order to avoid
-        * these problems.
-        */
-       struct intel_fbc_state state_cache;
-
-       /*
-        * This structure contains everything that's relevant to program the
-        * hardware registers. When we want to figure out if we need to disable
-        * and re-enable FBC for a new configuration we just check if there's
-        * something different in the struct. The genx_fbc_activate functions
-        * are supposed to read from it in order to program the registers.
-        */
-       struct intel_fbc_state params;
-       const char *no_fbc_reason;
-};
-
 /*
  * HIGH_RR is the highest eDP panel refresh rate read from EDID
  * LOW_RR is the lowest eDP panel refresh rate found from EDID
 #define QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK (1<<8)
 
 struct intel_fbdev;
-struct intel_fbc_work;
 
 struct intel_gmbus {
        struct i2c_adapter adapter;
        u32 pipestat_irq_mask[I915_MAX_PIPES];
 
        struct i915_hotplug hotplug;
-       struct intel_fbc fbc;
+       struct intel_fbc *fbc;
        struct i915_drrs drrs;
        struct intel_opregion opregion;
        struct intel_vbt_data vbt;