bool enable)
 {
        struct drm_device *dev = &dev_priv->drm;
-       struct intel_crtc *crtc =
-               to_intel_crtc(dev_priv->pipe_to_crtc_mapping[PIPE_A]);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[PIPE_A];
        struct intel_crtc_state *pipe_config;
        struct drm_atomic_state *state;
        int ret = 0;
 {
        struct drm_device *dev = &dev_priv->drm;
        struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
-       struct intel_crtc *crtc =
-                       to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+       struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
        enum intel_display_power_domain power_domain;
        u32 val = 0; /* shut up gcc */
        int ret;
        /* real source -> none transition */
        if (source == INTEL_PIPE_CRC_SOURCE_NONE) {
                struct intel_pipe_crc_entry *entries;
-               struct intel_crtc *crtc =
-                       to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+               struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
                DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n",
                                 pipe_name(pipe));
 
 
        /* Kernel Modesetting */
 
-       struct drm_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
-       struct drm_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
+       struct intel_crtc *plane_to_crtc_mapping[I915_MAX_PIPES];
+       struct intel_crtc *pipe_to_crtc_mapping[I915_MAX_PIPES];
        wait_queue_head_t pending_flip_queue;
 
 #ifdef CONFIG_DEBUG_FS
 
        struct drm_i915_private *dev_priv = to_i915(dev);
        i915_reg_t high_frame, low_frame;
        u32 high1, high2, low, pixel, vbl_start, hsync_start, htotal;
-       struct intel_crtc *intel_crtc =
-               to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+       struct intel_crtc *intel_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        const struct drm_display_mode *mode = &intel_crtc->base.hwmode;
 
        htotal = mode->crtc_htotal;
                                    const struct drm_display_mode *mode)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *intel_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        int position;
        int vbl_start, vbl_end, hsync_start, htotal, vtotal;
        bool in_vbl = true;
                              struct timeval *vblank_time,
                              unsigned flags)
 {
-       struct drm_crtc *crtc;
+       struct intel_crtc *crtc;
 
        if (pipe >= INTEL_INFO(dev)->num_pipes) {
                DRM_ERROR("Invalid crtc %u\n", pipe);
                return -EINVAL;
        }
 
-       if (!crtc->hwmode.crtc_clock) {
+       if (!crtc->base.hwmode.crtc_clock) {
                DRM_DEBUG_KMS("crtc %u is disabled\n", pipe);
                return -EBUSY;
        }
        /* Helper routine in DRM core does all the work: */
        return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
                                                     vblank_time, flags,
-                                                    &crtc->hwmode);
+                                                    &crtc->base.hwmode);
 }
 
 static void ironlake_rps_change_irq_handler(struct drm_i915_private *dev_priv)
 
 enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
                                             enum pipe pipe)
 {
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
-       return intel_crtc->config->cpu_transcoder;
+       return crtc->config->cpu_transcoder;
 }
 
 static bool pipe_dsl_stopped(struct drm_device *dev, enum pipe pipe)
 static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
                                           enum pipe pipe)
 {
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *intel_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        i915_reg_t reg;
        uint32_t val, pipeconf_val;
 
                if (pipe_config->fdi_lanes <= 2)
                        return 0;
 
-               other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_C));
+               other_crtc = intel_get_crtc_for_pipe(dev, PIPE_C);
                other_crtc_state =
                        intel_atomic_get_crtc_state(state, other_crtc);
                if (IS_ERR(other_crtc_state))
                        return -EINVAL;
                }
 
-               other_crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, PIPE_B));
+               other_crtc = intel_get_crtc_for_pipe(dev, PIPE_B);
                other_crtc_state =
                        intel_atomic_get_crtc_state(state, other_crtc);
                if (IS_ERR(other_crtc_state))
 int vlv_force_pll_on(struct drm_device *dev, enum pipe pipe,
                     const struct dpll *dpll)
 {
-       struct intel_crtc *crtc =
-               to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+       struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
        struct intel_crtc_state *pipe_config;
 
        pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL);
 void intel_finish_page_flip_cs(struct drm_i915_private *dev_priv, int pipe)
 {
        struct drm_device *dev = &dev_priv->drm;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_flip_work *work;
        unsigned long flags;
 
         * lost pageflips) so needs the full irqsave spinlocks.
         */
        spin_lock_irqsave(&dev->event_lock, flags);
-       work = intel_crtc->flip_work;
+       work = crtc->flip_work;
 
        if (work != NULL &&
            !is_mmio_work(work) &&
-           pageflip_finished(intel_crtc, work))
-               page_flip_completed(intel_crtc);
+           pageflip_finished(crtc, work))
+               page_flip_completed(crtc);
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 void intel_finish_page_flip_mmio(struct drm_i915_private *dev_priv, int pipe)
 {
        struct drm_device *dev = &dev_priv->drm;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_flip_work *work;
        unsigned long flags;
 
         * lost pageflips) so needs the full irqsave spinlocks.
         */
        spin_lock_irqsave(&dev->event_lock, flags);
-       work = intel_crtc->flip_work;
+       work = crtc->flip_work;
 
        if (work != NULL &&
            is_mmio_work(work) &&
-           pageflip_finished(intel_crtc, work))
-               page_flip_completed(intel_crtc);
+           pageflip_finished(crtc, work))
+               page_flip_completed(crtc);
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 void intel_check_page_flip(struct drm_i915_private *dev_priv, int pipe)
 {
        struct drm_device *dev = &dev_priv->drm;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_flip_work *work;
 
        WARN_ON(!in_interrupt());
                return;
 
        spin_lock(&dev->event_lock);
-       work = intel_crtc->flip_work;
+       work = crtc->flip_work;
 
        if (work != NULL && !is_mmio_work(work) &&
-           __pageflip_stall_check_cs(dev_priv, intel_crtc, work)) {
+           __pageflip_stall_check_cs(dev_priv, crtc, work)) {
                WARN_ONCE(1,
                          "Kicking stuck page flip: queued at %d, now %d\n",
-                       work->flip_queued_vblank, intel_crtc_get_vblank_counter(intel_crtc));
-               page_flip_completed(intel_crtc);
+                       work->flip_queued_vblank, intel_crtc_get_vblank_counter(crtc));
+               page_flip_completed(crtc);
                work = NULL;
        }
 
        if (work != NULL && !is_mmio_work(work) &&
-           intel_crtc_get_vblank_counter(intel_crtc) - work->flip_queued_vblank > 1)
+           intel_crtc_get_vblank_counter(crtc) - work->flip_queued_vblank > 1)
                intel_queue_rps_boost_for_request(work->flip_queued_req);
        spin_unlock(&dev->event_lock);
 }
                return;
 
        for_each_pipe(dev_priv, pipe) {
-               struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+               struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
                if (!((1 << pipe) & crtc_mask))
                        continue;
 
-               ret = drm_crtc_vblank_get(crtc);
+               ret = drm_crtc_vblank_get(&crtc->base);
                if (WARN_ON(ret != 0)) {
                        crtc_mask &= ~(1 << pipe);
                        continue;
                }
 
-               last_vblank_count[pipe] = drm_crtc_vblank_count(crtc);
+               last_vblank_count[pipe] = drm_crtc_vblank_count(&crtc->base);
        }
 
        for_each_pipe(dev_priv, pipe) {
-               struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+               struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
                long lret;
 
                if (!((1 << pipe) & crtc_mask))
 
                lret = wait_event_timeout(dev->vblank[pipe].queue,
                                last_vblank_count[pipe] !=
-                                       drm_crtc_vblank_count(crtc),
+                                       drm_crtc_vblank_count(&crtc->base),
                                msecs_to_jiffies(50));
 
                WARN(!lret, "pipe %c vblank wait timed out\n", pipe_name(pipe));
 
-               drm_crtc_vblank_put(crtc);
+               drm_crtc_vblank_put(&crtc->base);
        }
 }
 
 
        BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
               dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL);
-       dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base;
-       dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base;
+       dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = intel_crtc;
+       dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = intel_crtc;
 
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 
                pipe = 0;
 
                if (encoder->get_hw_state(encoder, &pipe)) {
-                       crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+                       crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
                        encoder->base.crtc = &crtc->base;
                        crtc->config->output_types |= 1 << encoder->type;
                        encoder->get_config(encoder, crtc->config);
        }
 
        for_each_pipe(dev_priv, pipe) {
-               crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+               crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+
                intel_sanitize_crtc(crtc);
                intel_dump_pipe_config(crtc, crtc->config,
                                       "[setup_hw_state]");
 
        }
 }
 
-static inline struct drm_crtc *
+static inline struct intel_crtc *
 intel_get_crtc_for_pipe(struct drm_device *dev, int pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
        return dev_priv->pipe_to_crtc_mapping[pipe];
 }
 
-static inline struct drm_crtc *
+static inline struct intel_crtc *
 intel_get_crtc_for_plane(struct drm_device *dev, int plane)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
 static inline void
 intel_wait_for_vblank_if_active(struct drm_device *dev, int pipe)
 {
-       const struct intel_crtc *crtc =
-               to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe));
+       const struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev, pipe);
 
        if (crtc->active)
                intel_wait_for_vblank(dev, pipe);
 
         * its timings to get how the BIOS set up the panel.
         */
        if (dvo_val & DVO_ENABLE) {
-               struct drm_crtc *crtc;
+               struct intel_crtc *crtc;
                int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0;
 
                crtc = intel_get_crtc_for_pipe(dev, pipe);
                if (crtc) {
-                       mode = intel_crtc_mode_get(dev, crtc);
+                       mode = intel_crtc_mode_get(dev, &crtc->base);
                        if (mode) {
                                mode->type |= DRM_MODE_TYPE_PREFERRED;
                                if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
 
        assert_spin_locked(&dev_priv->irq_lock);
 
        for_each_pipe(dev_priv, pipe) {
-               crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+               crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
                if (crtc->cpu_fifo_underrun_disabled)
                        return false;
        assert_spin_locked(&dev_priv->irq_lock);
 
        for_each_pipe(dev_priv, pipe) {
-               crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+               crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
                if (crtc->pch_fifo_underrun_disabled)
                        return false;
                                                    enum pipe pipe, bool enable)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        bool old;
 
        assert_spin_locked(&dev_priv->irq_lock);
 
-       old = !intel_crtc->cpu_fifo_underrun_disabled;
-       intel_crtc->cpu_fifo_underrun_disabled = !enable;
+       old = !crtc->cpu_fifo_underrun_disabled;
+       crtc->cpu_fifo_underrun_disabled = !enable;
 
        if (HAS_GMCH_DISPLAY(dev_priv))
                i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
                                           enum transcoder pch_transcoder,
                                           bool enable)
 {
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
        unsigned long flags;
        bool old;
 
 
        spin_lock_irqsave(&dev_priv->irq_lock, flags);
 
-       old = !intel_crtc->pch_fifo_underrun_disabled;
-       intel_crtc->pch_fifo_underrun_disabled = !enable;
+       old = !crtc->pch_fifo_underrun_disabled;
+       crtc->pch_fifo_underrun_disabled = !enable;
 
        if (HAS_PCH_IBX(dev_priv))
                ibx_set_fifo_underrun_reporting(&dev_priv->drm,
 void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
                                         enum pipe pipe)
 {
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+       struct intel_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
 
        /* We may be called too early in init, thanks BIOS! */
        if (crtc == NULL)
 
        /* GMCH can't disable fifo underruns, filter them. */
        if (HAS_GMCH_DISPLAY(dev_priv) &&
-           to_intel_crtc(crtc)->cpu_fifo_underrun_disabled)
+           crtc->cpu_fifo_underrun_disabled)
                return;
 
        if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))
 
        struct drm_display_mode *fixed_mode = NULL;
        struct drm_display_mode *downclock_mode = NULL;
        struct edid *edid;
-       struct drm_crtc *crtc;
+       struct intel_crtc *crtc;
        i915_reg_t lvds_reg;
        u32 lvds;
        int pipe;
        crtc = intel_get_crtc_for_pipe(dev, pipe);
 
        if (crtc && (lvds & LVDS_PORT_EN)) {
-               fixed_mode = intel_crtc_mode_get(dev, crtc);
+               fixed_mode = intel_crtc_mode_get(dev, &crtc->base);
                if (fixed_mode) {
                        DRM_DEBUG_KMS("using current (BIOS) mode: ");
                        drm_mode_debug_printmodeline(fixed_mode);
 
        int line_time_us, line_count;
        int entries, tlb_miss;
 
-       crtc = to_intel_crtc(intel_get_crtc_for_plane(dev, plane));
+       crtc = intel_get_crtc_for_plane(dev, plane);
        if (!intel_crtc_active(crtc)) {
                *cursor_wm = cursor->guard_size;
                *plane_wm = display->guard_size;
                return false;
        }
 
-       crtc = to_intel_crtc(intel_get_crtc_for_plane(dev, plane));
+       crtc = intel_get_crtc_for_plane(dev, plane);
        adjusted_mode = &crtc->config->base.adjusted_mode;
        fb = crtc->base.primary->state->fb;
        clock = adjusted_mode->crtc_clock;
                wm_info = &i830_a_wm_info;
 
        fifo_size = dev_priv->display.get_fifo_size(dev, 0);
-       crtc = to_intel_crtc(intel_get_crtc_for_plane(dev, 0));
+       crtc = intel_get_crtc_for_plane(dev, 0);
        if (intel_crtc_active(crtc)) {
                const struct drm_display_mode *adjusted_mode =
                        &crtc->config->base.adjusted_mode;
                wm_info = &i830_bc_wm_info;
 
        fifo_size = dev_priv->display.get_fifo_size(dev, 1);
-       crtc = to_intel_crtc(intel_get_crtc_for_plane(dev, 1));
+       crtc = intel_get_crtc_for_plane(dev, 1);
        if (intel_crtc_active(crtc)) {
                const struct drm_display_mode *adjusted_mode =
                        &crtc->config->base.adjusted_mode;
 
        /* Since we're now guaranteed to only have one active CRTC... */
        pipe = ffs(intel_state->active_crtcs) - 1;
-       crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+       crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        cstate = to_intel_crtc_state(crtc->base.state);
 
        if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)