/* If the pipe isn't enabled, we can't pump pixels and may hang */
        assert_pipe_enabled(dev_priv, intel_crtc->pipe);
-
-       if (intel_crtc->primary_enabled)
-               return;
-
-       intel_crtc->primary_enabled = true;
+       to_intel_plane_state(plane->state)->visible = true;
 
        dev_priv->display.update_primary_plane(crtc, plane->fb,
                                               crtc->x, crtc->y);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct drm_plane *primary = crtc->primary;
+       bool visible = to_intel_plane_state(primary->state)->visible;
        struct drm_i915_gem_object *obj;
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
        u32 reg = DSPCNTR(plane);
        int pixel_size;
 
-       if (!intel_crtc->primary_enabled || !fb) {
+       if (!visible || !fb) {
                I915_WRITE(reg, 0);
                if (INTEL_INFO(dev)->gen >= 4)
                        I915_WRITE(DSPSURF(plane), 0);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct drm_plane *primary = crtc->primary;
+       bool visible = to_intel_plane_state(primary->state)->visible;
        struct drm_i915_gem_object *obj;
        int plane = intel_crtc->plane;
        unsigned long linear_offset;
        u32 reg = DSPCNTR(plane);
        int pixel_size;
 
-       if (!intel_crtc->primary_enabled || !fb) {
+       if (!visible || !fb) {
                I915_WRITE(reg, 0);
                I915_WRITE(DSPSURF(plane), 0);
                POSTING_READ(reg);
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct drm_plane *plane = crtc->primary;
+       bool visible = to_intel_plane_state(plane->state)->visible;
        struct drm_i915_gem_object *obj;
        int pipe = intel_crtc->pipe;
        u32 plane_ctl, stride_div, stride;
        unsigned int rotation;
        int x_offset, y_offset;
        unsigned long surf_addr;
-       struct drm_plane *plane;
        struct intel_crtc_state *crtc_state = intel_crtc->config;
        struct intel_plane_state *plane_state;
        int src_x = 0, src_y = 0, src_w = 0, src_h = 0;
        int dst_x = 0, dst_y = 0, dst_w = 0, dst_h = 0;
        int scaler_id = -1;
 
-       plane = crtc->primary;
        plane_state = to_intel_plane_state(plane->state);
 
-       if (!intel_crtc->primary_enabled || !fb) {
+       if (!visible || !fb) {
                I915_WRITE(PLANE_CTL(pipe, 0), 0);
                I915_WRITE(PLANE_SURF(pipe, 0), 0);
                POSTING_READ(PLANE_CTL(pipe, 0));
        hsw_disable_ips(intel_crtc);
 
        intel_crtc_dpms_overlay(intel_crtc, false);
-       intel_crtc->primary_enabled = false;
        for_each_intel_plane(dev, intel_plane) {
                if (intel_plane->pipe == pipe) {
                        struct drm_crtc *from = intel_plane->base.crtc;
        } else if (config->fb_changed) {
                struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc);
                struct drm_plane *primary = set->crtc->primary;
+               struct intel_plane_state *plane_state =
+                               to_intel_plane_state(primary->state);
+               bool was_visible = plane_state->visible;
                int vdisplay, hdisplay;
 
                drm_crtc_get_hv_timing(set->mode, &hdisplay, &vdisplay);
                 * We need to make sure the primary plane is re-enabled if it
                 * has previously been turned off.
                 */
-               if (!intel_crtc->primary_enabled && ret == 0) {
+               plane_state = to_intel_plane_state(primary->state);
+               if (ret == 0 && !was_visible && plane_state->visible) {
                        WARN_ON(!intel_crtc->active);
                        intel_enable_primary_hw_plane(set->crtc->primary, set->crtc);
                }
                return ret;
 
        if (intel_crtc->active) {
+               struct intel_plane_state *old_state =
+                       to_intel_plane_state(plane->state);
+
                intel_crtc->atomic.wait_for_flips = true;
 
                /*
                 * one is done too late. We eventually need to unify
                 * this.
                 */
-               if (intel_crtc->primary_enabled &&
+               if (state->visible &&
                    INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
                    dev_priv->fbc.crtc == intel_crtc &&
                    state->base.rotation != BIT(DRM_ROTATE_0)) {
                        intel_crtc->atomic.disable_fbc = true;
                }
 
-               if (state->visible) {
+               if (state->visible && !old_state->visible) {
                        /*
                         * BDW signals flip done immediately if the plane
                         * is disabled, even if the plane enable is already
                         * armed to occur at the next vblank :(
                         */
-                       if (IS_BROADWELL(dev) && !intel_crtc->primary_enabled)
+                       if (IS_BROADWELL(dev))
                                intel_crtc->atomic.wait_vblank = true;
                }
 
        crtc->y = src->y1 >> 16;
 
        if (intel_crtc->active) {
-               intel_crtc->primary_enabled = state->visible;
-
                if (state->visible)
                        /* FIXME: kill this fastboot hack */
                        intel_update_pipe_size(intel_crtc);
        struct drm_device *dev = plane->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (!force)
-               to_intel_crtc(crtc)->primary_enabled = false;
-
        dev_priv->display.update_primary_plane(crtc, NULL, 0, 0);
 }
 
                 * Temporarily change the plane mapping and disable everything
                 * ...  */
                plane = crtc->plane;
+               to_intel_plane_state(crtc->base.primary->state)->visible = true;
                crtc->plane = !plane;
-               crtc->primary_enabled = true;
                dev_priv->display.crtc_disable(&crtc->base);
                crtc->plane = plane;
 
        int i;
 
        for_each_intel_crtc(dev, crtc) {
+               struct drm_plane *primary = crtc->base.primary;
+               struct intel_plane_state *plane_state;
+
                memset(crtc->config, 0, sizeof(*crtc->config));
 
                crtc->config->quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
 
                crtc->base.state->enable = crtc->active;
                crtc->base.enabled = crtc->active;
-               crtc->primary_enabled = primary_get_hw_state(crtc);
+
+               plane_state = to_intel_plane_state(primary->state);
+               plane_state->visible = primary_get_hw_state(crtc);
 
                DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
                              crtc->base.base.id,