[Intel-gfx] [PATCH] drm/i915: encoder/connector internal structure rework

Zhenyu Wang zhenyuw at linux.intel.com
Tue Mar 2 03:18:30 CET 2010


On 2010.03.01 17:24:33 +0800, ykzhao wrote:
> On Mon, 2010-03-01 at 16:10 +0800, Zhenyu Wang wrote:
> 
> Hi, Zhenyu
> 	I look at this patch and I think that it is better except the SDVO. I
> have the several questions about this patch.
> 	
> 	a. has_tv/has_lvds flag in SDVO encoder is initialized only once
> according to the SDVO capability. And it won't be updated again
> according to the external connected device. Then in course of
> modesetting, this flag will be used in the corresponding encoder
> callback function. It seems that this is incorrect. (the flag of
> needs_tv_clock is the same issue)

oops, you're right, the reason I didn't catch these is the testing cards don't
have both tv/lvds. 

>      
>         b. This patch will create two different connectors for SDVO card
> with the CVBS0/SVIDEO capability. Can we group some capabilities into
> one group? (Similarly one connector is created for the TMDS0/TMDS1.)
> 

Why? As from sdvo spec, I think both s-video/composite could exist, and
for TMDS0/1 too. It just forces that when TMDS1 exists, there must be TMDS0.

>         c. In the DVO file: Some info is stored in encoder private
> structure. This info will be free in course of encoder cleanup function.
> But this info is still accessed in the connector cleanup function.
> 

oh, right, so looks we should destroy those in encoder destroy function.

Thanks for the review, I'll check with your original patch to see if anything
I can pick up immediately. ;) And I think we might be able to split this into
two patches, one for 'intel_output' structure convert and another one for
multiple SDVO function. Good to you?

> 
> > This trys to rework intel driver's internal encoder/connector handling
> > code by replacing 'struct intel_output' with specific 'intel_encoder'
> > and 'intel_connector' structure, which according to 'drm_encoder' and
> > 'drm_connector' respectively.
> > 
> > The reason to do this is to implement multiple connector types for one
> > single SDVO device, so one 'intel_encoder' would be able to driver multiple
> > 'intel_connector' objects. We might be able to change internal code in
> > SDVO only for this, but I found it would bring lot of confusing and SDVO
> > only home-made stuff, and still need to hack driver common code here and
> > there. Which lead me to this more intrusive solution, but I hope would be
> > the most clean one.
> > 
> > With this, each supported connector type on SDVO device will be created
> > as a new 'intel_connector', and all attached to one 'intel_encoder' for
> > its SDVO port. Then SDVO encoder will handle SDVO protocol stuff, and each
> > connector does its easy part now like detection is only to check if current
> > active output is itself.
> > 
> > As it removes 'struct intel_output' completely, so patch is quite long
> > and mostly for renaming old struct to new one. For making it still bisectable
> > I think it has to be put in one place.
> > 
> > Test has been made on mobile and desktop 945/965 chips for VGA/HDMI/DP/LVDS/TV,
> > SDVO cards for single function DVI and multiple function TVs.
> > 
> > Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>
> > ---
> > 
> > Eric, I think Yakui's old quirk patch for fd.o bug #25787 on drm-intel-next
> > should be reverted for solution provided in this, and as Yakui said the quirk
> > patch is wrong. The SDVO device does support VGA and TV function, just IBM board
> > only has VGA output but no TV. With this patch it would create connector for VGA
> > and TV, and would only detect VGA active.
> > 
> >  drivers/gpu/drm/i915/i915_irq.c      |    6 +-
> >  drivers/gpu/drm/i915/intel_crt.c     |   81 +-
> >  drivers/gpu/drm/i915/intel_display.c |  104 ++-
> >  drivers/gpu/drm/i915/intel_dp.c      |  283 +++---
> >  drivers/gpu/drm/i915/intel_drv.h     |   34 +-
> >  drivers/gpu/drm/i915/intel_dvo.c     |  114 ++-
> >  drivers/gpu/drm/i915/intel_hdmi.c    |   98 ++-
> >  drivers/gpu/drm/i915/intel_lvds.c    |   75 +-
> >  drivers/gpu/drm/i915/intel_modes.c   |   23 +-
> >  drivers/gpu/drm/i915/intel_sdvo.c    | 1631 ++++++++++++++++++---------------
> >  drivers/gpu/drm/i915/intel_tv.c      |  116 ++--
> >  11 files changed, 1393 insertions(+), 1172 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> > index a17d6bd..fc2264d 100644
> > --- a/drivers/gpu/drm/i915/i915_irq.c
> > +++ b/drivers/gpu/drm/i915/i915_irq.c
> > @@ -259,10 +259,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
> > 
> >         if (mode_config->num_connector) {
> >                 list_for_each_entry(connector, &mode_config->connector_list, head) {
> > -                       struct intel_output *intel_output = to_intel_output(connector);
> > +                       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> > -                       if (intel_output->hot_plug)
> > -                               (*intel_output->hot_plug) (intel_output);
> > +                       if (intel_connector->hot_plug)
> > +                               (*intel_connector->hot_plug) (intel_connector);
> >                 }
> >         }
> >         /* Just fire off a uevent and let userspace tell us what to do */
> > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
> > index 79dd402..e182d02 100644
> > --- a/drivers/gpu/drm/i915/intel_crt.c
> > +++ b/drivers/gpu/drm/i915/intel_crt.c
> > @@ -246,19 +246,14 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
> > 
> >  static bool intel_crt_detect_ddc(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> > -       /* CRT should always be at 0, but check anyway */
> > -       if (intel_output->type != INTEL_OUTPUT_ANALOG)
> > -               return false;
> > -
> > -       return intel_ddc_probe(intel_output);
> > +       return intel_ddc_probe(intel_connector);
> >  }
> > 
> >  static enum drm_connector_status
> > -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
> > +intel_crt_load_detect(struct drm_crtc *crtc, struct drm_encoder *encoder)
> >  {
> > -       struct drm_encoder *encoder = &intel_output->enc;
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > @@ -386,8 +381,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
> >  static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct drm_encoder *encoder;
> >         struct drm_crtc *crtc;
> >         int dpms_mode;
> >         enum drm_connector_status status;
> > @@ -402,15 +396,18 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
> >         if (intel_crt_detect_ddc(connector))
> >                 return connector_status_connected;
> > 
> > +       encoder = intel_best_encoder(connector);
> > +       if (!encoder)
> > +               return connector_status_disconnected;
> > +
> >         /* for pre-945g platforms use load detect */
> >         if (encoder->crtc && encoder->crtc->enabled) {
> > -               status = intel_crt_load_detect(encoder->crtc, intel_output);
> > +               status = intel_crt_load_detect(encoder->crtc, encoder);
> >         } else {
> > -               crtc = intel_get_load_detect_pipe(intel_output,
> > -                                                 NULL, &dpms_mode);
> > +               crtc = intel_get_load_detect_pipe(connector, NULL, &dpms_mode);
> >                 if (crtc) {
> > -                       status = intel_crt_load_detect(crtc, intel_output);
> > -                       intel_release_load_detect_pipe(intel_output, dpms_mode);
> > +                       status = intel_crt_load_detect(crtc, encoder);
> > +                       intel_release_load_detect_pipe(connector, dpms_mode);
> >                 } else
> >                         status = connector_status_unknown;
> >         }
> > @@ -420,9 +417,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
> > 
> >  static void intel_crt_destroy(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> > -       intel_i2c_destroy(intel_output->ddc_bus);
> > +       intel_i2c_destroy(intel_connector->ddc_bus);
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> >         kfree(connector);
> > @@ -431,28 +428,27 @@ static void intel_crt_destroy(struct drm_connector *connector)
> >  static int intel_crt_get_modes(struct drm_connector *connector)
> >  {
> >         int ret;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> >         struct i2c_adapter *ddcbus;
> >         struct drm_device *dev = connector->dev;
> > 
> > -
> > -       ret = intel_ddc_get_modes(intel_output);
> > +       ret = intel_ddc_get_modes(intel_connector);
> >         if (ret || !IS_G4X(dev))
> >                 goto end;
> > 
> > -       ddcbus = intel_output->ddc_bus;
> > +       ddcbus = intel_connector->ddc_bus;
> >         /* Try to probe digital port for output in DVI-I -> VGA mode. */
> > -       intel_output->ddc_bus =
> > +       intel_connector->ddc_bus =
> >                 intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
> > 
> > -       if (!intel_output->ddc_bus) {
> > -               intel_output->ddc_bus = ddcbus;
> > +       if (!intel_connector->ddc_bus) {
> > +               intel_connector->ddc_bus = ddcbus;
> >                 dev_printk(KERN_ERR, &connector->dev->pdev->dev,
> >                            "DDC bus registration failed for CRTDDC_D.\n");
> >                 goto end;
> >         }
> >         /* Try to get modes by GPIOD port */
> > -       ret = intel_ddc_get_modes(intel_output);
> > +       ret = intel_ddc_get_modes(intel_connector);
> >         intel_i2c_destroy(ddcbus);
> > 
> >  end:
> > @@ -496,6 +492,7 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs
> >  static void intel_crt_enc_destroy(struct drm_encoder *encoder)
> >  {
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_crt_enc_funcs = {
> > @@ -505,23 +502,29 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
> >  void intel_crt_init(struct drm_device *dev)
> >  {
> >         struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > +       struct drm_encoder *encoder;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         u32 i2c_reg;
> > 
> > -       intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
> > -       if (!intel_output)
> > +       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
> > +
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > 
> > -       connector = &intel_output->base;
> > -       drm_connector_init(dev, &intel_output->base,
> > +       connector = &intel_connector->base;
> > +       encoder = &intel_encoder->base;
> > +       intel_encoder->connector = intel_connector;
> > +
> > +       drm_connector_init(dev, connector,
> >                            &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
> > 
> > -       drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
> > +       drm_encoder_init(dev, encoder, &intel_crt_enc_funcs,
> >                          DRM_MODE_ENCODER_DAC);
> > 
> > -       drm_mode_connector_attach_encoder(&intel_output->base,
> > -                                         &intel_output->enc);
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> > 
> >         /* Set up the DDC bus. */
> >         if (IS_IRONLAKE(dev))
> > @@ -532,22 +535,22 @@ void intel_crt_init(struct drm_device *dev)
> >                 if (dev_priv->crt_ddc_bus != 0)
> >                         i2c_reg = dev_priv->crt_ddc_bus;
> >         }
> > -       intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
> > -       if (!intel_output->ddc_bus) {
> > +       intel_connector->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
> > +       if (!intel_connector->ddc_bus) {
> >                 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
> >                            "failed.\n");
> >                 return;
> >         }
> > 
> > -       intel_output->type = INTEL_OUTPUT_ANALOG;
> > -       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > +       intel_encoder->type = INTEL_OUTPUT_ANALOG;
> > +       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> >                                    (1 << INTEL_ANALOG_CLONE_BIT) |
> >                                    (1 << INTEL_SDVO_LVDS_CLONE_BIT);
> > -       intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > +       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> >         connector->interlace_allowed = 0;
> >         connector->doublescan_allowed = 0;
> > 
> > -       drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
> > +       drm_encoder_helper_add(encoder, &intel_crt_helper_funcs);
> >         drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
> > 
> >         drm_sysfs_connector_add(connector);
> > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> > index b27202d..a9b6c0d 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -739,19 +739,17 @@ static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock
> >   */
> >  bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
> >  {
> > -    struct drm_device *dev = crtc->dev;
> > -    struct drm_mode_config *mode_config = &dev->mode_config;
> > -    struct drm_connector *l_entry;
> > +       struct drm_device *dev = crtc->dev;
> > +       struct drm_mode_config *mode_config = &dev->mode_config;
> > +       struct drm_encoder *l_entry;
> > +       struct intel_encoder *intel_encoder;
> > 
> > -    list_for_each_entry(l_entry, &mode_config->connector_list, head) {
> > -           if (l_entry->encoder &&
> > -               l_entry->encoder->crtc == crtc) {
> > -                   struct intel_output *intel_output = to_intel_output(l_entry);
> > -                   if (intel_output->type == type)
> > -                           return true;
> > -           }
> > -    }
> > -    return false;
> > +       list_for_each_entry(l_entry, &mode_config->encoder_list, head) {
> > +               intel_encoder = to_intel_encoder(l_entry);
> > +               if (l_entry->crtc == crtc && intel_encoder->type == type)
> > +                       return true;
> > +       }
> > +       return false;
> >  }
> > 
> >  struct drm_connector *
> > @@ -2907,7 +2905,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> >         bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
> >         bool is_edp = false;
> >         struct drm_mode_config *mode_config = &dev->mode_config;
> > -       struct drm_connector *connector;
> > +       struct drm_encoder *encoder;
> > +       struct intel_encoder *intel_encoder = NULL;
> >         const intel_limit_t *limit;
> >         int ret;
> >         struct fdi_m_n m_n = {0};
> > @@ -2925,20 +2924,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> > 
> >         drm_vblank_pre_modeset(dev, pipe);
> > 
> > -       list_for_each_entry(connector, &mode_config->connector_list, head) {
> > -               struct intel_output *intel_output = to_intel_output(connector);
> > -
> > -               if (!connector->encoder || connector->encoder->crtc != crtc)
> > +       list_for_each_entry(encoder, &mode_config->encoder_list, head) {
> > +               if (!encoder || encoder->crtc != crtc)
> >                         continue;
> > 
> > -               switch (intel_output->type) {
> > +               intel_encoder = to_intel_encoder(encoder);
> > +               switch (intel_encoder->type) {
> >                 case INTEL_OUTPUT_LVDS:
> >                         is_lvds = true;
> >                         break;
> >                 case INTEL_OUTPUT_SDVO:
> >                 case INTEL_OUTPUT_HDMI:
> >                         is_sdvo = true;
> > -                       if (intel_output->needs_tv_clock)
> > +                       if (intel_encoder->needs_tv_clock)
> >                                 is_tv = true;
> >                         break;
> >                 case INTEL_OUTPUT_DVO:
> > @@ -3030,11 +3028,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
> >                 /* eDP doesn't require FDI link, so just set DP M/N
> >                    according to current link config */
> >                 if (is_edp) {
> > -                       struct drm_connector *edp;
> >                         target_clock = mode->clock;
> > -                       edp = intel_pipe_get_output(crtc);
> > -                       intel_edp_link_config(to_intel_output(edp),
> > -                                       &lane, &link_bw);
> > +                       intel_edp_link_config(intel_encoder,
> > +                                             &lane, &link_bw);
> >                 } else {
> >                         /* DP over FDI requires target mode clock
> >                            instead of link clock */
> > @@ -3654,18 +3650,19 @@ static struct drm_display_mode load_detect_mode = {
> >                  704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
> >  };
> > 
> > -struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
> > +struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
> >                                             struct drm_display_mode *mode,
> >                                             int *dpms_mode)
> >  {
> >         struct intel_crtc *intel_crtc;
> >         struct drm_crtc *possible_crtc;
> >         struct drm_crtc *supported_crtc =NULL;
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> >         struct drm_crtc *crtc = NULL;
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
> >         struct drm_crtc_helper_funcs *crtc_funcs;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> >         int i = -1;
> > 
> >         /*
> > @@ -3713,8 +3710,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
> >         }
> > 
> >         encoder->crtc = crtc;
> > -       intel_output->base.encoder = encoder;
> > -       intel_output->load_detect_temp = true;
> > +       connector->encoder = encoder;
> > +       intel_encoder->load_detect_temp = true;
> > 
> >         intel_crtc = to_intel_crtc(crtc);
> >         *dpms_mode = intel_crtc->dpms_mode;
> > @@ -3739,18 +3736,19 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
> >         return crtc;
> >  }
> > 
> > -void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
> > +void intel_release_load_detect_pipe(struct drm_connector *connector, int dpms_mode)
> >  {
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
> >         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > 
> > -       if (intel_output->load_detect_temp) {
> > +       if (intel_encoder->load_detect_temp) {
> >                 encoder->crtc = NULL;
> > -               intel_output->base.encoder = NULL;
> > -               intel_output->load_detect_temp = false;
> > +               connector->encoder = NULL;
> > +               intel_encoder->load_detect_temp = false;
> >                 crtc->enabled = drm_helper_crtc_in_use(crtc);
> >                 drm_helper_disable_unused_functions(dev);
> >         }
> > @@ -4355,15 +4353,15 @@ struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
> >         return crtc;
> >  }
> > 
> > -static int intel_connector_clones(struct drm_device *dev, int type_mask)
> > +static int intel_encoder_clones(struct drm_device *dev, int type_mask)
> >  {
> >         int index_mask = 0;
> > -       struct drm_connector *connector;
> > +       struct drm_encoder *encoder;
> >         int entry = 0;
> > 
> > -        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> > -               struct intel_output *intel_output = to_intel_output(connector);
> > -               if (type_mask & intel_output->clone_mask)
> > +        list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
> > +               struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +               if (type_mask & intel_encoder->clone_mask)
> >                         index_mask |= (1 << entry);
> >                 entry++;
> >         }
> > @@ -4374,7 +4372,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
> >  static void intel_setup_outputs(struct drm_device *dev)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct drm_connector *connector;
> > +       struct drm_encoder *encoder;
> > 
> >         intel_crt_init(dev);
> > 
> > @@ -4457,13 +4455,12 @@ static void intel_setup_outputs(struct drm_device *dev)
> >         if (SUPPORTS_TV(dev))
> >                 intel_tv_init(dev);
> > 
> > -       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> > -               struct intel_output *intel_output = to_intel_output(connector);
> > -               struct drm_encoder *encoder = &intel_output->enc;
> > +       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
> > +               struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > 
> > -               encoder->possible_crtcs = intel_output->crtc_mask;
> > -               encoder->possible_clones = intel_connector_clones(dev,
> > -                                               intel_output->clone_mask);
> > +               encoder->possible_crtcs = intel_encoder->crtc_mask;
> > +               encoder->possible_clones = intel_encoder_clones(dev,
> > +                                               intel_encoder->clone_mask);
> >         }
> >  }
> > 
> > @@ -4845,9 +4842,24 @@ void intel_modeset_cleanup(struct drm_device *dev)
> >  */
> >  struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct drm_mode_object *obj;
> > +       struct drm_encoder *encoder;
> > +       int i;
> > +
> > +        for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
> > +               if (connector->encoder_ids[i] == 0)
> > +                       break;
> > 
> > -       return &intel_output->enc;
> > +               obj = drm_mode_object_find(connector->dev,
> > +                                          connector->encoder_ids[i],
> > +                                          DRM_MODE_OBJECT_ENCODER);
> > +               if (!obj)
> > +                       continue;
> > +
> > +               encoder = obj_to_encoder(obj);
> > +               return encoder;
> > +       }
> > +       return NULL;
> >  }
> > 
> >  /*
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index 439506c..5826fa3 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -41,7 +41,7 @@
> > 
> >  #define DP_LINK_CONFIGURATION_SIZE     9
> > 
> > -#define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP)
> > +#define IS_eDP(c) (((struct intel_dp_priv *)((c)->dev_priv))->output_reg == DP_A)
> > 
> >  struct intel_dp_priv {
> >         uint32_t output_reg;
> > @@ -54,23 +54,23 @@ struct intel_dp_priv {
> >         uint8_t link_bw;
> >         uint8_t lane_count;
> >         uint8_t dpcd[4];
> > -       struct intel_output *intel_output;
> > +       struct intel_encoder *intel_encoder;
> >         struct i2c_adapter adapter;
> >         struct i2c_algo_dp_aux_data algo;
> >  };
> > 
> >  static void
> > -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> > +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
> >                     uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
> > 
> >  static void
> > -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
> > +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
> > 
> >  void
> > -intel_edp_link_config (struct intel_output *intel_output,
> > +intel_edp_link_config (struct intel_encoder *intel_encoder,
> >                 int *lane_num, int *link_bw)
> >  {
> > -       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
> > 
> >         *lane_num = dp_priv->lane_count;
> >         if (dp_priv->link_bw == DP_LINK_BW_1_62)
> > @@ -80,9 +80,9 @@ intel_edp_link_config (struct intel_output *intel_output,
> >  }
> > 
> >  static int
> > -intel_dp_max_lane_count(struct intel_output *intel_output)
> > +intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
> >         int max_lane_count = 4;
> > 
> >         if (dp_priv->dpcd[0] >= 0x11) {
> > @@ -98,9 +98,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)
> >  }
> > 
> >  static int
> > -intel_dp_max_link_bw(struct intel_output *intel_output)
> > +intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
> >         int max_link_bw = dp_priv->dpcd[1];
> > 
> >         switch (max_link_bw) {
> > @@ -126,11 +126,11 @@ intel_dp_link_clock(uint8_t link_bw)
> >  /* I think this is a fiction */
> >  static int
> >  intel_dp_link_required(struct drm_device *dev,
> > -                      struct intel_output *intel_output, int pixel_clock)
> > +                      struct intel_encoder *intel_encoder, int pixel_clock)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > 
> > -       if (IS_eDP(intel_output))
> > +       if (IS_eDP(intel_encoder))
> >                 return (pixel_clock * dev_priv->edp_bpp) / 8;
> >         else
> >                 return pixel_clock * 3;
> > @@ -140,11 +140,12 @@ static int
> >  intel_dp_mode_valid(struct drm_connector *connector,
> >                     struct drm_display_mode *mode)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
> > -       int max_lanes = intel_dp_max_lane_count(intel_output);
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
> > +       int max_lanes = intel_dp_max_lane_count(intel_encoder);
> > 
> > -       if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
> > +       if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
> >                         > max_link_clock * max_lanes)
> >                 return MODE_CLOCK_HIGH;
> > 
> > @@ -208,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
> >  }
> > 
> >  static int
> > -intel_dp_aux_ch(struct intel_output *intel_output,
> > +intel_dp_aux_ch(struct intel_encoder *intel_encoder,
> >                 uint8_t *send, int send_bytes,
> >                 uint8_t *recv, int recv_size)
> >  {
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> >         uint32_t output_reg = dp_priv->output_reg;
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         uint32_t ch_ctl = output_reg + 0x10;
> >         uint32_t ch_data = ch_ctl + 4;
> > @@ -229,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
> >          * and would like to run at 2MHz. So, take the
> >          * hrawclk value and divide by 2 and use that
> >          */
> > -       if (IS_eDP(intel_output))
> > +       if (IS_eDP(intel_encoder))
> >                 aux_clock_divider = 225; /* eDP input clock at 450Mhz */
> >         else if (IS_IRONLAKE(dev))
> >                 aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
> > @@ -312,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
> > 
> >  /* Write data to the aux channel in native mode */
> >  static int
> > -intel_dp_aux_native_write(struct intel_output *intel_output,
> > +intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
> >                           uint16_t address, uint8_t *send, int send_bytes)
> >  {
> >         int ret;
> > @@ -329,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
> >         memcpy(&msg[4], send, send_bytes);
> >         msg_bytes = send_bytes + 4;
> >         for (;;) {
> > -               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
> > +               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
> >                 if (ret < 0)
> >                         return ret;
> >                 if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
> > @@ -344,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
> > 
> >  /* Write a single byte to the aux channel in native mode */
> >  static int
> > -intel_dp_aux_native_write_1(struct intel_output *intel_output,
> > +intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
> >                             uint16_t address, uint8_t byte)
> >  {
> > -       return intel_dp_aux_native_write(intel_output, address, &byte, 1);
> > +       return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
> >  }
> > 
> >  /* read bytes from a native aux channel */
> >  static int
> > -intel_dp_aux_native_read(struct intel_output *intel_output,
> > +intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
> >                          uint16_t address, uint8_t *recv, int recv_bytes)
> >  {
> >         uint8_t msg[4];
> > @@ -371,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
> >         reply_bytes = recv_bytes + 1;
> > 
> >         for (;;) {
> > -               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
> > +               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
> >                                       reply, reply_bytes);
> >                 if (ret == 0)
> >                         return -EPROTO;
> > @@ -397,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> >         struct intel_dp_priv *dp_priv = container_of(adapter,
> >                                                      struct intel_dp_priv,
> >                                                      adapter);
> > -       struct intel_output *intel_output = dp_priv->intel_output;
> > +       struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
> >         uint16_t address = algo_data->address;
> >         uint8_t msg[5];
> >         uint8_t reply[2];
> > @@ -436,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> >         }
> > 
> >         for (;;) {
> > -         ret = intel_dp_aux_ch(intel_output,
> > +         ret = intel_dp_aux_ch(intel_encoder,
> >                                 msg, msg_bytes,
> >                                 reply, reply_bytes);
> >                 if (ret < 0) {
> > @@ -464,9 +465,10 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
> >  }
> > 
> >  static int
> > -intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
> > +intel_dp_i2c_init(struct intel_encoder *intel_encoder,
> > +                 struct intel_connector *intel_connector, const char *name)
> >  {
> > -       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
> > 
> >         DRM_DEBUG_KMS("i2c_init %s\n", name);
> >         dp_priv->algo.running = false;
> > @@ -479,7 +481,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
> >         strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
> >         dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
> >         dp_priv->adapter.algo_data = &dp_priv->algo;
> > -       dp_priv->adapter.dev.parent = &intel_output->base.kdev;
> > +       dp_priv->adapter.dev.parent = &intel_connector->base.kdev;
> > 
> >         return i2c_dp_aux_add_bus(&dp_priv->adapter);
> >  }
> > @@ -488,18 +490,18 @@ static bool
> >  intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >                     struct drm_display_mode *adjusted_mode)
> >  {
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
> >         int lane_count, clock;
> > -       int max_lane_count = intel_dp_max_lane_count(intel_output);
> > -       int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
> > +       int max_lane_count = intel_dp_max_lane_count(intel_encoder);
> > +       int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
> >         static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
> > 
> >         for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
> >                 for (clock = 0; clock <= max_clock; clock++) {
> >                         int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
> > 
> > -                       if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
> > +                       if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
> >                                         <= link_avail) {
> >                                 dp_priv->link_bw = bws[clock];
> >                                 dp_priv->lane_count = lane_count;
> > @@ -554,23 +556,25 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
> >  {
> >         struct drm_device *dev = crtc->dev;
> >         struct drm_mode_config *mode_config = &dev->mode_config;
> > -       struct drm_connector *connector;
> > +       struct drm_encoder *encoder;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> >         int lane_count = 4;
> >         struct intel_dp_m_n m_n;
> > 
> >         /*
> > -        * Find the lane count in the intel_output private
> > +        * Find the lane count in the intel_encoder private
> >          */
> > -       list_for_each_entry(connector, &mode_config->connector_list, head) {
> > -               struct intel_output *intel_output = to_intel_output(connector);
> > -               struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       list_for_each_entry(encoder, &mode_config->encoder_list, head) {
> > +               struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +               struct intel_dp_priv *dp_priv;
> > 
> > -               if (!connector->encoder || connector->encoder->crtc != crtc)
> > +               if (!encoder || encoder->crtc != crtc)
> >                         continue;
> > 
> > -               if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
> > +               dp_priv = intel_encoder->dev_priv;
> > +
> > +               if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
> >                         lane_count = dp_priv->lane_count;
> >                         break;
> >                 }
> > @@ -625,9 +629,9 @@ static void
> >  intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >                   struct drm_display_mode *adjusted_mode)
> >  {
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > -       struct drm_crtc *crtc = intel_output->enc.crtc;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > +       struct drm_crtc *crtc = encoder->crtc;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > 
> >         dp_priv->DP = (DP_LINK_TRAIN_OFF |
> > @@ -666,7 +670,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >         if (intel_crtc->pipe == 1)
> >                 dp_priv->DP |= DP_PIPEB_SELECT;
> > 
> > -       if (IS_eDP(intel_output)) {
> > +       if (IS_eDP(intel_encoder)) {
> >                 /* don't miss out required setting for eDP */
> >                 dp_priv->DP |= DP_PLL_ENABLE;
> >                 if (adjusted_mode->clock < 200000)
> > @@ -701,22 +705,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
> >  static void
> >  intel_dp_dpms(struct drm_encoder *encoder, int mode)
> >  {
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > +       struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         uint32_t dp_reg = I915_READ(dp_priv->output_reg);
> > 
> >         if (mode != DRM_MODE_DPMS_ON) {
> >                 if (dp_reg & DP_PORT_EN) {
> > -                       intel_dp_link_down(intel_output, dp_priv->DP);
> > -                       if (IS_eDP(intel_output))
> > +                       intel_dp_link_down(intel_encoder, dp_priv->DP);
> > +                       if (IS_eDP(intel_encoder))
> >                                 ironlake_edp_backlight_off(dev);
> >                 }
> >         } else {
> >                 if (!(dp_reg & DP_PORT_EN)) {
> > -                       intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
> > -                       if (IS_eDP(intel_output))
> > +                       intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
> > +                       if (IS_eDP(intel_encoder))
> >                                 ironlake_edp_backlight_on(dev);
> >                 }
> >         }
> > @@ -728,12 +732,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
> >   * link status information
> >   */
> >  static bool
> > -intel_dp_get_link_status(struct intel_output *intel_output,
> > +intel_dp_get_link_status(struct intel_encoder *intel_encoder,
> >                          uint8_t link_status[DP_LINK_STATUS_SIZE])
> >  {
> >         int ret;
> > 
> > -       ret = intel_dp_aux_native_read(intel_output,
> > +       ret = intel_dp_aux_native_read(intel_encoder,
> >                                        DP_LANE0_1_STATUS,
> >                                        link_status, DP_LINK_STATUS_SIZE);
> >         if (ret != DP_LINK_STATUS_SIZE)
> > @@ -751,13 +755,14 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
> >  static void
> >  intel_dp_save(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > 
> >         dp_priv->save_DP = I915_READ(dp_priv->output_reg);
> > -       intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
> > +       intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
> >                                  dp_priv->save_link_configuration,
> >                                  sizeof (dp_priv->save_link_configuration));
> >  }
> > @@ -824,7 +829,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
> >  }
> > 
> >  static void
> > -intel_get_adjust_train(struct intel_output *intel_output,
> > +intel_get_adjust_train(struct intel_encoder *intel_encoder,
> >                        uint8_t link_status[DP_LINK_STATUS_SIZE],
> >                        int lane_count,
> >                        uint8_t train_set[4])
> > @@ -941,15 +946,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
> >  }
> > 
> >  static bool
> > -intel_dp_set_link_train(struct intel_output *intel_output,
> > +intel_dp_set_link_train(struct intel_encoder *intel_encoder,
> >                         uint32_t dp_reg_value,
> >                         uint8_t dp_train_pat,
> >                         uint8_t train_set[4],
> >                         bool first)
> >  {
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> >         int ret;
> > 
> >         I915_WRITE(dp_priv->output_reg, dp_reg_value);
> > @@ -957,11 +962,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,
> >         if (first)
> >                 intel_wait_for_vblank(dev);
> > 
> > -       intel_dp_aux_native_write_1(intel_output,
> > +       intel_dp_aux_native_write_1(intel_encoder,
> >                                     DP_TRAINING_PATTERN_SET,
> >                                     dp_train_pat);
> > 
> > -       ret = intel_dp_aux_native_write(intel_output,
> > +       ret = intel_dp_aux_native_write(intel_encoder,
> >                                         DP_TRAINING_LANE0_SET, train_set, 4);
> >         if (ret != 4)
> >                 return false;
> > @@ -970,12 +975,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,
> >  }
> > 
> >  static void
> > -intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> > +intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
> >                     uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
> >  {
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> >         uint8_t train_set[4];
> >         uint8_t link_status[DP_LINK_STATUS_SIZE];
> >         int i;
> > @@ -986,7 +991,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> >         int tries;
> > 
> >         /* Write the link configuration data */
> > -       intel_dp_aux_native_write(intel_output, 0x100,
> > +       intel_dp_aux_native_write(intel_encoder, 0x100,
> >                                   link_configuration, DP_LINK_CONFIGURATION_SIZE);
> > 
> >         DP |= DP_PORT_EN;
> > @@ -1000,14 +1005,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> >                 uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
> >                 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
> > 
> > -               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
> > +               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
> >                                              DP_TRAINING_PATTERN_1, train_set, first))
> >                         break;
> >                 first = false;
> >                 /* Set training pattern 1 */
> > 
> >                 udelay(100);
> > -               if (!intel_dp_get_link_status(intel_output, link_status))
> > +               if (!intel_dp_get_link_status(intel_encoder, link_status))
> >                         break;
> > 
> >                 if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
> > @@ -1032,7 +1037,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> >                 voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
> > 
> >                 /* Compute new train_set as requested by target */
> > -               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
> > +               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
> >         }
> > 
> >         /* channel equalization */
> > @@ -1044,13 +1049,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> >                 DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
> > 
> >                 /* channel eq pattern */
> > -               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
> > +               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
> >                                              DP_TRAINING_PATTERN_2, train_set,
> >                                              false))
> >                         break;
> > 
> >                 udelay(400);
> > -               if (!intel_dp_get_link_status(intel_output, link_status))
> > +               if (!intel_dp_get_link_status(intel_encoder, link_status))
> >                         break;
> > 
> >                 if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
> > @@ -1063,26 +1068,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
> >                         break;
> > 
> >                 /* Compute new train_set as requested by target */
> > -               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
> > +               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
> >                 ++tries;
> >         }
> > 
> >         I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
> >         POSTING_READ(dp_priv->output_reg);
> > -       intel_dp_aux_native_write_1(intel_output,
> > +       intel_dp_aux_native_write_1(intel_encoder,
> >                                     DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
> >  }
> > 
> >  static void
> > -intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
> > +intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
> >  {
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > 
> >         DRM_DEBUG_KMS("\n");
> > 
> > -       if (IS_eDP(intel_output)) {
> > +       if (IS_eDP(intel_encoder)) {
> >                 DP &= ~DP_PLL_ENABLE;
> >                 I915_WRITE(dp_priv->output_reg, DP);
> >                 POSTING_READ(dp_priv->output_reg);
> > @@ -1095,7 +1100,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
> > 
> >         udelay(17000);
> > 
> > -       if (IS_eDP(intel_output))
> > +       if (IS_eDP(intel_encoder))
> >                 DP |= DP_LINK_TRAIN_OFF;
> >         I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
> >         POSTING_READ(dp_priv->output_reg);
> > @@ -1104,13 +1109,14 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
> >  static void
> >  intel_dp_restore(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > 
> >         if (dp_priv->save_DP & DP_PORT_EN)
> > -               intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
> > +               intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
> >         else
> > -               intel_dp_link_down(intel_output,  dp_priv->save_DP);
> > +               intel_dp_link_down(intel_encoder,  dp_priv->save_DP);
> >  }
> > 
> >  /*
> > @@ -1123,32 +1129,34 @@ intel_dp_restore(struct drm_connector *connector)
> >   */
> > 
> >  static void
> > -intel_dp_check_link_status(struct intel_output *intel_output)
> > +intel_dp_check_link_status(struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = &intel_encoder->base;
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> >         uint8_t link_status[DP_LINK_STATUS_SIZE];
> > 
> > -       if (!intel_output->enc.crtc)
> > +       if (!encoder->crtc)
> >                 return;
> > 
> > -       if (!intel_dp_get_link_status(intel_output, link_status)) {
> > -               intel_dp_link_down(intel_output, dp_priv->DP);
> > +       if (!intel_dp_get_link_status(intel_encoder, link_status)) {
> > +               intel_dp_link_down(intel_encoder, dp_priv->DP);
> >                 return;
> >         }
> > 
> >         if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
> > -               intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
> > +               intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
> >  }
> > 
> >  static enum drm_connector_status
> >  ironlake_dp_detect(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> >         enum drm_connector_status status;
> > 
> >         status = connector_status_disconnected;
> > -       if (intel_dp_aux_native_read(intel_output,
> > +       if (intel_dp_aux_native_read(intel_encoder,
> >                                      0x000, dp_priv->dpcd,
> >                                      sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
> >         {
> > @@ -1167,10 +1175,11 @@ ironlake_dp_detect(struct drm_connector *connector)
> >  static enum drm_connector_status
> >  intel_dp_detect(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > +       struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> >         uint32_t temp, bit;
> >         enum drm_connector_status status;
> > 
> > @@ -1209,7 +1218,7 @@ intel_dp_detect(struct drm_connector *connector)
> >                 return connector_status_disconnected;
> > 
> >         status = connector_status_disconnected;
> > -       if (intel_dp_aux_native_read(intel_output,
> > +       if (intel_dp_aux_native_read(intel_encoder,
> >                                      0x000, dp_priv->dpcd,
> >                                      sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
> >         {
> > @@ -1221,20 +1230,22 @@ intel_dp_detect(struct drm_connector *connector)
> > 
> >  static int intel_dp_get_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         int ret;
> > 
> >         /* We should parse the EDID data and find out if it has an audio sink
> >          */
> > 
> > -       ret = intel_ddc_get_modes(intel_output);
> > +       ret = intel_ddc_get_modes(intel_connector);
> >         if (ret)
> >                 return ret;
> > 
> >         /* if eDP has no EDID, try to use fixed panel mode from VBT */
> > -       if (IS_eDP(intel_output)) {
> > +       if (IS_eDP(intel_encoder)) {
> >                 if (dev_priv->panel_fixed_mode != NULL) {
> >                         struct drm_display_mode *mode;
> >                         mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
> > @@ -1248,13 +1259,9 @@ static int intel_dp_get_modes(struct drm_connector *connector)
> >  static void
> >  intel_dp_destroy (struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -
> > -       if (intel_output->i2c_bus)
> > -               intel_i2c_destroy(intel_output->i2c_bus);
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> > -       kfree(intel_output);
> > +       kfree(connector);
> >  }
> > 
> >  static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
> > @@ -1283,6 +1290,7 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs =
> >  static void intel_dp_enc_destroy(struct drm_encoder *encoder)
> >  {
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_dp_enc_funcs = {
> > @@ -1290,12 +1298,15 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
> >  };
> > 
> >  void
> > -intel_dp_hot_plug(struct intel_output *intel_output)
> > +intel_dp_hot_plug(struct intel_connector *intel_connector)
> >  {
> > -       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
> > +       struct drm_connector *connector = &intel_connector->base;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
> > 
> >         if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
> > -               intel_dp_check_link_status(intel_output);
> > +               intel_dp_check_link_status(intel_encoder);
> >  }
> > 
> >  void
> > @@ -1303,53 +1314,57 @@ intel_dp_init(struct drm_device *dev, int output_reg)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > +       struct drm_encoder *encoder;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct intel_dp_priv *dp_priv;
> >         const char *name = NULL;
> > 
> > -       intel_output = kcalloc(sizeof(struct intel_output) +
> > -                              sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
> > -       if (!intel_output)
> > +       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc(sizeof(*intel_encoder) + sizeof(*dp_priv), GFP_KERNEL);
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > 
> > -       dp_priv = (struct intel_dp_priv *)(intel_output + 1);
> > +       dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
> > +       intel_encoder->dev_priv = dp_priv;
> > +
> > +       connector = &intel_connector->base;
> > +       encoder = &intel_encoder->base;
> > +       intel_encoder->connector = intel_connector;
> > 
> > -       connector = &intel_output->base;
> >         drm_connector_init(dev, connector, &intel_dp_connector_funcs,
> >                            DRM_MODE_CONNECTOR_DisplayPort);
> >         drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
> > 
> >         if (output_reg == DP_A)
> > -               intel_output->type = INTEL_OUTPUT_EDP;
> > +               intel_encoder->type = INTEL_OUTPUT_EDP;
> >         else
> > -               intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
> > +               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
> > 
> >         if (output_reg == DP_B || output_reg == PCH_DP_B)
> > -               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
> > +               intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
> >         else if (output_reg == DP_C || output_reg == PCH_DP_C)
> > -               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
> > +               intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
> >         else if (output_reg == DP_D || output_reg == PCH_DP_D)
> > -               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
> > +               intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
> > 
> > -       if (IS_eDP(intel_output))
> > -               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
> > +       if (IS_eDP(intel_encoder))
> > +               intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
> > 
> > -       intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > +       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> >         connector->interlace_allowed = true;
> >         connector->doublescan_allowed = 0;
> > 
> > -       dp_priv->intel_output = intel_output;
> > +       dp_priv->intel_encoder = intel_encoder;
> >         dp_priv->output_reg = output_reg;
> >         dp_priv->has_audio = false;
> >         dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
> > -       intel_output->dev_priv = dp_priv;
> > 
> > -       drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
> > +       drm_encoder_init(dev, encoder, &intel_dp_enc_funcs,
> >                          DRM_MODE_ENCODER_TMDS);
> > -       drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
> > +       drm_encoder_helper_add(encoder, &intel_dp_helper_funcs);
> > 
> > -       drm_mode_connector_attach_encoder(&intel_output->base,
> > -                                         &intel_output->enc);
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> >         drm_sysfs_connector_add(connector);
> > 
> >         /* Set up the DDC bus. */
> > @@ -1377,10 +1392,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
> >                         break;
> >         }
> > 
> > -       intel_dp_i2c_init(intel_output, name);
> > +       intel_dp_i2c_init(intel_encoder, intel_connector, name);
> > 
> > -       intel_output->ddc_bus = &dp_priv->adapter;
> > -       intel_output->hot_plug = intel_dp_hot_plug;
> > +       intel_connector->ddc_bus = &dp_priv->adapter;
> > +       intel_connector->hot_plug = intel_dp_hot_plug;
> > 
> >         if (output_reg == DP_A) {
> >                 /* initialize panel mode from VBT if available for eDP */
> > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> > index a51573d..85efc35 100644
> > --- a/drivers/gpu/drm/i915/intel_drv.h
> > +++ b/drivers/gpu/drm/i915/intel_drv.h
> > @@ -94,20 +94,24 @@ struct intel_framebuffer {
> >         struct drm_gem_object *obj;
> >  };
> > 
> > -
> > -struct intel_output {
> > -       struct drm_connector base;
> > -
> > -       struct drm_encoder enc;
> > +struct intel_encoder {
> > +       struct drm_encoder base;
> >         int type;
> > -       struct i2c_adapter *i2c_bus;
> > -       struct i2c_adapter *ddc_bus;
> > +       struct i2c_adapter *i2c_bus; /* For DVO/SDVO protocol */
> >         bool load_detect_temp;
> >         bool needs_tv_clock;
> >         void *dev_priv;
> > -       void (*hot_plug)(struct intel_output *);
> >         int crtc_mask;
> >         int clone_mask;
> > +       /* easy to track for single connector, only for SDVO hack */
> > +       struct intel_connector *connector;
> > +};
> > +
> > +struct intel_connector {
> > +       struct drm_connector base;
> > +       struct i2c_adapter *ddc_bus;
> > +       void *dev_priv;
> > +       void (*hot_plug)(struct intel_connector *);
> >  };
> > 
> >  struct intel_crtc;
> > @@ -152,15 +156,15 @@ struct intel_crtc {
> >  };
> > 
> >  #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
> > -#define to_intel_output(x) container_of(x, struct intel_output, base)
> > -#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
> > +#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
> > +#define to_intel_connector(x) container_of(x, struct intel_connector, base)
> >  #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
> > 
> >  struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
> >                                      const char *name);
> >  void intel_i2c_destroy(struct i2c_adapter *adapter);
> > -int intel_ddc_get_modes(struct intel_output *intel_output);
> > -extern bool intel_ddc_probe(struct intel_output *intel_output);
> > +int intel_ddc_get_modes(struct intel_connector *intel_connector);
> > +extern bool intel_ddc_probe(struct intel_connector *intel_connector);
> >  void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
> >  void intel_i2c_reset_gmbus(struct drm_device *dev);
> > 
> > @@ -175,7 +179,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
> >  void
> >  intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
> >                  struct drm_display_mode *adjusted_mode);
> > -extern void intel_edp_link_config (struct intel_output *, int *, int *);
> > +extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
> > 
> > 
> >  extern int intel_panel_fitter_pipe (struct drm_device *dev);
> > @@ -191,10 +195,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
> >                                 struct drm_file *file_priv);
> >  extern void intel_wait_for_vblank(struct drm_device *dev);
> >  extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
> > -extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
> > +extern struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
> >                                                    struct drm_display_mode *mode,
> >                                                    int *dpms_mode);
> > -extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
> > +extern void intel_release_load_detect_pipe(struct drm_connector *connector,
> >                                            int dpms_mode);
> > 
> >  extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
> > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
> > index a4d2606..6f8b35b 100644
> > --- a/drivers/gpu/drm/i915/intel_dvo.c
> > +++ b/drivers/gpu/drm/i915/intel_dvo.c
> > @@ -79,8 +79,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {
> >  static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
> >  {
> >         struct drm_i915_private *dev_priv = encoder->dev->dev_private;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> >         u32 dvo_reg = dvo->dvo_reg;
> >         u32 temp = I915_READ(dvo_reg);
> > 
> > @@ -98,8 +98,9 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
> >  static void intel_dvo_save(struct drm_connector *connector)
> >  {
> >         struct drm_i915_private *dev_priv = connector->dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > 
> >         /* Each output should probably just save the registers it touches,
> >          * but for now, use more overkill.
> > @@ -114,8 +115,9 @@ static void intel_dvo_save(struct drm_connector *connector)
> >  static void intel_dvo_restore(struct drm_connector *connector)
> >  {
> >         struct drm_i915_private *dev_priv = connector->dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > 
> >         dvo->dev_ops->restore(dvo);
> > 
> > @@ -127,8 +129,9 @@ static void intel_dvo_restore(struct drm_connector *connector)
> >  static int intel_dvo_mode_valid(struct drm_connector *connector,
> >                                 struct drm_display_mode *mode)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > 
> >         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> >                 return MODE_NO_DBLESCAN;
> > @@ -149,8 +152,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
> >                                  struct drm_display_mode *mode,
> >                                  struct drm_display_mode *adjusted_mode)
> >  {
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > 
> >         /* If we have timings from the BIOS for the panel, put them in
> >          * to the adjusted mode.  The CRTC will be set up for this mode,
> > @@ -185,8 +188,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> >         int pipe = intel_crtc->pipe;
> >         u32 dvo_val;
> >         u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
> > @@ -240,27 +243,29 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
> >   */
> >  static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > 
> >         return dvo->dev_ops->detect(dvo);
> >  }
> > 
> >  static int intel_dvo_get_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> >         /* We should probably have an i2c driver get_modes function for those
> >          * devices which will have a fixed set of modes determined by the chip
> >          * (TV-out, for example), but for now with just TMDS and LVDS,
> >          * that's not the case.
> >          */
> > -       intel_ddc_get_modes(intel_output);
> > +       intel_ddc_get_modes(intel_connector);
> >         if (!list_empty(&connector->probed_modes))
> >                 return 1;
> > 
> > -
> >         if (dvo->panel_fixed_mode != NULL) {
> >                 struct drm_display_mode *mode;
> >                 mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
> > @@ -274,24 +279,22 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
> > 
> >  static void intel_dvo_destroy (struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> >         if (dvo) {
> >                 if (dvo->dev_ops->destroy)
> >                         dvo->dev_ops->destroy(dvo);
> >                 if (dvo->panel_fixed_mode)
> >                         kfree(dvo->panel_fixed_mode);
> > -               /* no need, in i830_dvoices[] now */
> > -               //kfree(dvo);
> >         }
> > -       if (intel_output->i2c_bus)
> > -               intel_i2c_destroy(intel_output->i2c_bus);
> > -       if (intel_output->ddc_bus)
> > -               intel_i2c_destroy(intel_output->ddc_bus);
> > +       if (intel_connector->ddc_bus)
> > +               intel_i2c_destroy(intel_connector->ddc_bus);
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> > -       kfree(intel_output);
> > +       kfree(connector);
> >  }
> > 
> >  #ifdef RANDR_GET_CRTC_INTERFACE
> > @@ -299,8 +302,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_dvo_device *dvo = intel_connector->dev_priv;
> >         int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
> > 
> >         return intel_pipe_to_crtc(pScrn, pipe);
> > @@ -332,7 +335,12 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs
> > 
> >  static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
> >  {
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +
> > +       if (intel_encoder->i2c_bus)
> > +               intel_i2c_destroy(intel_encoder->i2c_bus);
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
> > @@ -351,8 +359,9 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_dvo_device *dvo = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
> >         uint32_t dvo_reg = dvo->dvo_reg;
> >         uint32_t dvo_val = I915_READ(dvo_reg);
> >         struct drm_display_mode *mode = NULL;
> > @@ -382,24 +391,31 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
> > 
> >  void intel_dvo_init(struct drm_device *dev)
> >  {
> > -       struct intel_output *intel_output;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct intel_dvo_device *dvo;
> >         struct i2c_adapter *i2cbus = NULL;
> >         int ret = 0;
> >         int i;
> >         int encoder_type = DRM_MODE_ENCODER_NONE;
> > -       intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
> > -       if (!intel_output)
> > +
> > +       intel_connector = kzalloc (sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc (sizeof(*intel_encoder), GFP_KERNEL);
> > +
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > 
> > +       intel_encoder->connector = intel_connector;
> > +
> >         /* Set up the DDC bus */
> > -       intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
> > -       if (!intel_output->ddc_bus)
> > +       intel_connector->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
> > +       if (!intel_connector->ddc_bus)
> >                 goto free_intel;
> > 
> >         /* Now, try to find a controller */
> >         for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
> > -               struct drm_connector *connector = &intel_output->base;
> > +               struct drm_connector *connector = &intel_connector->base;
> > +               struct drm_encoder *encoder = &intel_encoder->base;
> >                 int gpio;
> > 
> >                 dvo = &intel_dvo_devices[i];
> > @@ -434,11 +450,11 @@ void intel_dvo_init(struct drm_device *dev)
> >                 if (!ret)
> >                         continue;
> > 
> > -               intel_output->type = INTEL_OUTPUT_DVO;
> > -               intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > +               intel_encoder->type = INTEL_OUTPUT_DVO;
> > +               intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> >                 switch (dvo->type) {
> >                 case INTEL_DVO_CHIP_TMDS:
> > -                       intel_output->clone_mask =
> > +                       intel_encoder->clone_mask =
> >                                 (1 << INTEL_DVO_TMDS_CLONE_BIT) |
> >                                 (1 << INTEL_ANALOG_CLONE_BIT);
> >                         drm_connector_init(dev, connector,
> > @@ -447,7 +463,7 @@ void intel_dvo_init(struct drm_device *dev)
> >                         encoder_type = DRM_MODE_ENCODER_TMDS;
> >                         break;
> >                 case INTEL_DVO_CHIP_LVDS:
> > -                       intel_output->clone_mask =
> > +                       intel_encoder->clone_mask =
> >                                 (1 << INTEL_DVO_LVDS_CLONE_BIT);
> >                         drm_connector_init(dev, connector,
> >                                            &intel_dvo_connector_funcs,
> > @@ -462,16 +478,15 @@ void intel_dvo_init(struct drm_device *dev)
> >                 connector->interlace_allowed = false;
> >                 connector->doublescan_allowed = false;
> > 
> > -               intel_output->dev_priv = dvo;
> > -               intel_output->i2c_bus = i2cbus;
> > +               intel_encoder->dev_priv = dvo;
> > +               intel_encoder->i2c_bus = i2cbus;
> > 
> > -               drm_encoder_init(dev, &intel_output->enc,
> > +               drm_encoder_init(dev, encoder,
> >                                  &intel_dvo_enc_funcs, encoder_type);
> > -               drm_encoder_helper_add(&intel_output->enc,
> > +               drm_encoder_helper_add(encoder,
> >                                        &intel_dvo_helper_funcs);
> > 
> > -               drm_mode_connector_attach_encoder(&intel_output->base,
> > -                                                 &intel_output->enc);
> > +               drm_mode_connector_attach_encoder(connector, encoder);
> >                 if (dvo->type == INTEL_DVO_CHIP_LVDS) {
> >                         /* For our LVDS chipsets, we should hopefully be able
> >                          * to dig the fixed panel mode out of the BIOS data.
> > @@ -489,10 +504,11 @@ void intel_dvo_init(struct drm_device *dev)
> >                 return;
> >         }
> > 
> > -       intel_i2c_destroy(intel_output->ddc_bus);
> > +       intel_i2c_destroy(intel_connector->ddc_bus);
> >         /* Didn't find a chip, so tear down. */
> >         if (i2cbus != NULL)
> >                 intel_i2c_destroy(i2cbus);
> >  free_intel:
> > -       kfree(intel_output);
> > +       kfree(intel_connector);
> > +       kfree(intel_encoder);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
> > index 0e268de..8ae432f 100644
> > --- a/drivers/gpu/drm/i915/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/intel_hdmi.c
> > @@ -50,8 +50,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
> >         u32 sdvox;
> > 
> >         sdvox = SDVO_ENCODING_HDMI |
> > @@ -73,8 +73,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
> >  {
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
> >         u32 temp;
> > 
> >         temp = I915_READ(hdmi_priv->sdvox_reg);
> > @@ -109,8 +109,9 @@ static void intel_hdmi_save(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
> > 
> >         hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
> >  }
> > @@ -119,8 +120,9 @@ static void intel_hdmi_restore(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
> > 
> >         I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
> >         POSTING_READ(hdmi_priv->sdvox_reg);
> > @@ -150,21 +152,23 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
> >  static enum drm_connector_status
> >  intel_hdmi_detect(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> >         struct edid *edid = NULL;
> >         enum drm_connector_status status = connector_status_disconnected;
> > 
> >         hdmi_priv->has_hdmi_sink = false;
> > -       edid = drm_get_edid(&intel_output->base,
> > -                           intel_output->ddc_bus);
> > +       edid = drm_get_edid(connector,
> > +                           intel_connector->ddc_bus);
> > 
> >         if (edid) {
> >                 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
> >                         status = connector_status_connected;
> >                         hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
> >                 }
> > -               intel_output->base.display_info.raw_edid = NULL;
> > +               connector->display_info.raw_edid = NULL;
> >                 kfree(edid);
> >         }
> > 
> > @@ -173,24 +177,20 @@ intel_hdmi_detect(struct drm_connector *connector)
> > 
> >  static int intel_hdmi_get_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > 
> >         /* We should parse the EDID data and find out if it's an HDMI sink so
> >          * we can send audio to it.
> >          */
> > 
> > -       return intel_ddc_get_modes(intel_output);
> > +       return intel_ddc_get_modes(intel_connector);
> >  }
> > 
> >  static void intel_hdmi_destroy(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -
> > -       if (intel_output->i2c_bus)
> > -               intel_i2c_destroy(intel_output->i2c_bus);
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> > -       kfree(intel_output);
> > +       kfree(connector);
> >  }
> > 
> >  static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
> > @@ -219,6 +219,7 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs
> >  static void intel_hdmi_enc_destroy(struct drm_encoder *encoder)
> >  {
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
> > @@ -229,63 +230,69 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > +       struct drm_encoder *encoder;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct intel_hdmi_priv *hdmi_priv;
> > 
> > -       intel_output = kcalloc(sizeof(struct intel_output) +
> > -                              sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
> > -       if (!intel_output)
> > +       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc(sizeof(*intel_encoder) + sizeof(*hdmi_priv), GFP_KERNEL);
> > +
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > -       hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
> > 
> > -       connector = &intel_output->base;
> > +       hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
> > +
> > +       connector = &intel_connector->base;
> > +       encoder = &intel_encoder->base;
> > +       intel_encoder->connector = intel_connector;
> > +
> >         drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
> >                            DRM_MODE_CONNECTOR_HDMIA);
> >         drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
> > 
> > -       intel_output->type = INTEL_OUTPUT_HDMI;
> > +       intel_encoder->type = INTEL_OUTPUT_HDMI;
> > 
> >         connector->interlace_allowed = 0;
> >         connector->doublescan_allowed = 0;
> > -       intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > +       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> > 
> >         /* Set up the DDC bus. */
> >         if (sdvox_reg == SDVOB) {
> > -               intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
> > -               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
> > +               intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
> > +               intel_connector->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
> >                 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
> >         } else if (sdvox_reg == SDVOC) {
> > -               intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
> > -               intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
> > +               intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
> > +               intel_connector->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
> >                 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
> >         } else if (sdvox_reg == HDMIB) {
> > -               intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
> > -               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
> > +               intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
> > +               intel_connector->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
> >                                                                 "HDMIB");
> >                 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
> >         } else if (sdvox_reg == HDMIC) {
> > -               intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
> > -               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
> > +               intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
> > +               intel_connector->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
> >                                                                 "HDMIC");
> >                 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
> >         } else if (sdvox_reg == HDMID) {
> > -               intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
> > -               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
> > +               intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
> > +               intel_connector->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
> >                                                                 "HDMID");
> >                 dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
> >         }
> > -       if (!intel_output->ddc_bus)
> > +       if (!intel_connector->ddc_bus)
> >                 goto err_connector;
> > 
> >         hdmi_priv->sdvox_reg = sdvox_reg;
> > -       intel_output->dev_priv = hdmi_priv;
> > +       intel_encoder->dev_priv = hdmi_priv;
> > 
> > -       drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
> > +       drm_encoder_init(dev, encoder, &intel_hdmi_enc_funcs,
> >                          DRM_MODE_ENCODER_TMDS);
> > -       drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
> > +       drm_encoder_helper_add(encoder, &intel_hdmi_helper_funcs);
> > 
> > -       drm_mode_connector_attach_encoder(&intel_output->base,
> > -                                         &intel_output->enc);
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> >         drm_sysfs_connector_add(connector);
> > 
> >         /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
> > @@ -301,7 +308,8 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
> > 
> >  err_connector:
> >         drm_connector_cleanup(connector);
> > -       kfree(intel_output);
> > +       kfree(intel_connector);
> > +       kfree(intel_encoder);
> > 
> >         return;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> > index c2e8a45..9eba5b6 100644
> > --- a/drivers/gpu/drm/i915/intel_lvds.c
> > +++ b/drivers/gpu/drm/i915/intel_lvds.c
> > @@ -230,8 +230,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
> >         struct drm_encoder *tmp_encoder;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
> >         u32 pfit_control = 0, pfit_pgm_ratios = 0;
> >         int left_border = 0, right_border = 0, top_border = 0;
> >         int bottom_border = 0;
> > @@ -578,8 +578,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
> >  {
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
> > 
> >         /*
> >          * The LVDS pin pair will already have been turned on in the
> > @@ -669,11 +669,11 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
> >  static int intel_lvds_get_modes(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         int ret = 0;
> > 
> > -       ret = intel_ddc_get_modes(intel_output);
> > +       ret = intel_ddc_get_modes(intel_connector);
> > 
> >         if (ret)
> >                 return ret;
> > @@ -749,11 +749,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
> >  static void intel_lvds_destroy(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > 
> > -       if (intel_output->ddc_bus)
> > -               intel_i2c_destroy(intel_output->ddc_bus);
> > +       if (intel_connector->ddc_bus)
> > +               intel_i2c_destroy(intel_connector->ddc_bus);
> >         if (dev_priv->lid_notifier.notifier_call)
> >                 acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
> >         drm_sysfs_connector_remove(connector);
> > @@ -766,13 +766,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,
> >                                    uint64_t value)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output =
> > -                       to_intel_output(connector);
> > 
> >         if (property == dev->mode_config.scaling_mode_property &&
> >                                 connector->encoder) {
> >                 struct drm_crtc *crtc = connector->encoder->crtc;
> > -               struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
> > +               struct drm_encoder *encoder = connector->encoder;
> > +               struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +               struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
> >                 if (value == DRM_MODE_SCALE_NONE) {
> >                         DRM_DEBUG_KMS("no scaling not supported\n");
> >                         return 0;
> > @@ -823,6 +823,7 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
> >  static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
> >  {
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
> > @@ -1002,7 +1003,8 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
> >  void intel_lvds_init(struct drm_device *dev)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct drm_connector *connector;
> >         struct drm_encoder *encoder;
> >         struct drm_display_mode *scan; /* *modes, *bios_mode; */
> > @@ -1030,40 +1032,44 @@ void intel_lvds_init(struct drm_device *dev)
> >                 gpio = PCH_GPIOC;
> >         }
> > 
> > -       intel_output = kzalloc(sizeof(struct intel_output) +
> > -                               sizeof(struct intel_lvds_priv), GFP_KERNEL);
> > -       if (!intel_output) {
> > +       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc(sizeof(*intel_encoder) + sizeof(*lvds_priv),
> > +                               GFP_KERNEL);
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > -       }
> > 
> > -       connector = &intel_output->base;
> > -       encoder = &intel_output->enc;
> > -       drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
> > +       connector = &intel_connector->base;
> > +       encoder = &intel_encoder->base;
> > +       intel_encoder->connector = intel_connector;
> > +
> > +       drm_connector_init(dev, connector, &intel_lvds_connector_funcs,
> >                            DRM_MODE_CONNECTOR_LVDS);
> > 
> > -       drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
> > +       drm_encoder_init(dev, encoder, &intel_lvds_enc_funcs,
> >                          DRM_MODE_ENCODER_LVDS);
> > 
> > -       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
> > -       intel_output->type = INTEL_OUTPUT_LVDS;
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> > +
> > +       intel_encoder->type = INTEL_OUTPUT_LVDS;
> > +       intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
> > +       intel_encoder->crtc_mask = (1 << 1);
> > 
> > -       intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
> > -       intel_output->crtc_mask = (1 << 1);
> >         drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
> >         drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
> >         connector->display_info.subpixel_order = SubPixelHorizontalRGB;
> >         connector->interlace_allowed = false;
> >         connector->doublescan_allowed = false;
> > 
> > -       lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
> > -       intel_output->dev_priv = lvds_priv;
> > +       lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
> > +       intel_encoder->dev_priv = lvds_priv;
> > +
> >         /* create the scaling mode property */
> >         drm_mode_create_scaling_mode_property(dev);
> >         /*
> >          * the initial panel fitting mode will be FULL_SCREEN.
> >          */
> > 
> > -       drm_connector_attach_property(&intel_output->base,
> > +       drm_connector_attach_property(connector,
> >                                       dev->mode_config.scaling_mode_property,
> >                                       DRM_MODE_SCALE_FULLSCREEN);
> >         lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
> > @@ -1078,8 +1084,8 @@ void intel_lvds_init(struct drm_device *dev)
> >          */
> > 
> >         /* Set up the DDC bus. */
> > -       intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
> > -       if (!intel_output->ddc_bus) {
> > +       intel_connector->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
> > +       if (!intel_connector->ddc_bus) {
> >                 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
> >                            "failed.\n");
> >                 goto failed;
> > @@ -1089,7 +1095,7 @@ void intel_lvds_init(struct drm_device *dev)
> >          * Attempt to get the fixed panel mode from DDC.  Assume that the
> >          * preferred mode is the right one.
> >          */
> > -       intel_ddc_get_modes(intel_output);
> > +       intel_ddc_get_modes(intel_connector);
> > 
> >         list_for_each_entry(scan, &connector->probed_modes, head) {
> >                 mutex_lock(&dev->mode_config.mutex);
> > @@ -1167,9 +1173,10 @@ out:
> > 
> >  failed:
> >         DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
> > -       if (intel_output->ddc_bus)
> > -               intel_i2c_destroy(intel_output->ddc_bus);
> > +       if (intel_connector->ddc_bus)
> > +               intel_i2c_destroy(intel_connector->ddc_bus);
> >         drm_connector_cleanup(connector);
> >         drm_encoder_cleanup(encoder);
> > -       kfree(intel_output);
> > +       kfree(intel_connector);
> > +       kfree(intel_encoder);
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
> > index 67e2f46..b84d09d 100644
> > --- a/drivers/gpu/drm/i915/intel_modes.c
> > +++ b/drivers/gpu/drm/i915/intel_modes.c
> > @@ -33,7 +33,7 @@
> >   * intel_ddc_probe
> >   *
> >   */
> > -bool intel_ddc_probe(struct intel_output *intel_output)
> > +bool intel_ddc_probe(struct intel_connector *intel_connector)
> >  {
> >         u8 out_buf[] = { 0x0, 0x0};
> >         u8 buf[2];
> > @@ -53,9 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
> >                 }
> >         };
> > 
> > -       intel_i2c_quirk_set(intel_output->base.dev, true);
> > -       ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
> > -       intel_i2c_quirk_set(intel_output->base.dev, false);
> > +       intel_i2c_quirk_set(intel_connector->base.dev, true);
> > +       ret = i2c_transfer(intel_connector->ddc_bus, msgs, 2);
> > +       intel_i2c_quirk_set(intel_connector->base.dev, false);
> >         if (ret == 2)
> >                 return true;
> > 
> > @@ -68,19 +68,20 @@ bool intel_ddc_probe(struct intel_output *intel_output)
> >   *
> >   * Fetch the EDID information from @connector using the DDC bus.
> >   */
> > -int intel_ddc_get_modes(struct intel_output *intel_output)
> > +int intel_ddc_get_modes(struct intel_connector *intel_connector)
> >  {
> >         struct edid *edid;
> >         int ret = 0;
> > +       struct drm_connector *connector = &intel_connector->base;
> > 
> > -       intel_i2c_quirk_set(intel_output->base.dev, true);
> > -       edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
> > -       intel_i2c_quirk_set(intel_output->base.dev, false);
> > +       intel_i2c_quirk_set(connector->dev, true);
> > +       edid = drm_get_edid(connector, intel_connector->ddc_bus);
> > +       intel_i2c_quirk_set(connector->dev, false);
> >         if (edid) {
> > -               drm_mode_connector_update_edid_property(&intel_output->base,
> > +               drm_mode_connector_update_edid_property(connector,
> >                                                         edid);
> > -               ret = drm_add_edid_modes(&intel_output->base, edid);
> > -               intel_output->base.display_info.raw_edid = NULL;
> > +               ret = drm_add_edid_modes(connector, edid);
> > +               connector->display_info.raw_edid = NULL;
> >                 kfree(edid);
> >         }
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> > index 82678d3..2719025 100644
> > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > @@ -48,30 +48,30 @@ static char *tv_format_names[] = {
> > 
> >  #define TV_FORMAT_NUM  (sizeof(tv_format_names) / sizeof(*tv_format_names))
> > 
> > -struct intel_sdvo_priv {
> > +struct intel_sdvo_encoder {
> >         u8 slave_addr;
> > -
> >         /* Register for the SDVO device: SDVOB or SDVOC */
> >         int output_device;
> > -
> > -       /* Active outputs controlled by this SDVO output */
> > -       uint16_t controlled_output;
> > -
> >         /*
> >          * Capabilities of the SDVO device returned by
> >          * i830_sdvo_get_capabilities()
> >          */
> >         struct intel_sdvo_caps caps;
> > 
> > -       /* Pixel clock limitations reported by the SDVO device, in kHz */
> > -       int pixel_clock_min, pixel_clock_max;
> > -
> > +       /* Active outputs controlled by this SDVO output */
> > +       uint16_t controlled_output;
> >         /*
> >         * For multiple function SDVO device,
> >         * this is for current attached outputs.
> >         */
> >         uint16_t attached_output;
> > 
> > +       /* DDC bus used by this SDVO output */
> > +       uint8_t ddc_bus;
> > +
> > +       /* Pixel clock limitations reported by the SDVO device, in kHz */
> > +       int pixel_clock_min, pixel_clock_max;
> > +
> >         /**
> >          * This is set if we're going to treat the device as TV-out.
> >          *
> > @@ -79,60 +79,62 @@ struct intel_sdvo_priv {
> >          * to decide this for us, the S-Video output on our HDMI+S-Video card
> >          * shows up as RGB1 (VGA).
> >          */
> > -       bool is_tv;
> > -
> > -       /* This is for current tv format name */
> > -       char *tv_format_name;
> > -
> > -       /* This contains all current supported TV format */
> > -       char *tv_format_supported[TV_FORMAT_NUM];
> > -       int   format_supported_num;
> > -       struct drm_property *tv_format_property;
> > -       struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
> > -
> > +       bool has_tv;
> >         /**
> >          * This is set if we treat the device as HDMI, instead of DVI.
> >          */
> > -       bool is_hdmi;
> > +       bool has_hdmi;
> > 
> >         /**
> >          * This is set if we detect output of sdvo device as LVDS.
> >          */
> > -       bool is_lvds;
> > -
> > -       /**
> > -        * This is sdvo flags for input timing.
> > -        */
> > -       uint8_t sdvo_flags;
> > +       bool has_lvds;
> > 
> >         /**
> >          * This is sdvo fixed pannel mode pointer
> >          */
> >         struct drm_display_mode *sdvo_lvds_fixed_mode;
> > -
> > -       /**
> > -        * Returned SDTV resolutions allowed for the current format, if the
> > -        * device reported it.
> > -        */
> > -       struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
> > -
> >         /*
> >          * supported encoding mode, used to determine whether HDMI is
> >          * supported
> >          */
> >         struct intel_sdvo_encode encode;
> > 
> > -       /* DDC bus used by this SDVO output */
> > -       uint8_t ddc_bus;
> > +       /**
> > +        * This is sdvo flags for input timing.
> > +        */
> > +       uint8_t sdvo_flags;
> > 
> > -       /* Mac mini hack -- use the same DDC as the analog connector */
> > -       struct i2c_adapter *analog_ddc_bus;
> > +       /* This is for current tv format name */
> > +       char *tv_format_name;
> > 
> >         int save_sdvo_mult;
> >         u16 save_active_outputs;
> >         struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
> >         struct intel_sdvo_dtd save_output_dtd[16];
> >         u32 save_SDVOX;
> > +};
> > +
> > +struct intel_sdvo_connector {
> > +
> > +       /* Mark the type of connector */
> > +       uint16_t output_flag;
> > +
> > +       /* This contains all current supported TV format */
> > +       char *tv_format_supported[TV_FORMAT_NUM];
> > +       int   format_supported_num;
> > +       struct drm_property *tv_format_property;
> > +       struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
> > +
> > +       /**
> > +        * Returned SDTV resolutions allowed for the current format, if the
> > +        * device reported it.
> > +        */
> > +       struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
> > +
> > +       /* Mac mini hack -- use the same DDC as the analog connector */
> > +       struct i2c_adapter *analog_ddc_bus;
> > +
> >         /* add the property for the SDVO-TV */
> >         struct drm_property *left_property;
> >         struct drm_property *right_property;
> > @@ -160,22 +162,26 @@ struct intel_sdvo_priv {
> >  };
> > 
> >  static bool
> > -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
> > +intel_sdvo_output_setup(struct intel_encoder *intel_encoder);
> > 
> > +static void intel_sdvo_tv_create_property(struct drm_encoder *encoder,
> > +                                         struct drm_connector *connector);
> > +static void intel_sdvo_create_enhance_property(struct drm_encoder *encoder,
> > +                                              struct drm_connector *connector);
> >  /**
> >   * Writes the SDVOB or SDVOC with the given value, but always writes both
> >   * SDVOB and SDVOC to work around apparent hardware issues (according to
> >   * comments in the BIOS).
> >   */
> > -static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
> > +static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
> >  {
> > -       struct drm_device *dev = intel_output->base.dev;
> > +       struct drm_device *dev = intel_encoder->base.dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u32 bval = val, cval = val;
> >         int i;
> > 
> > -       if (sdvo_priv->output_device == SDVOB) {
> > +       if (sdvo_encoder->output_device == SDVOB) {
> >                 cval = I915_READ(SDVOC);
> >         } else {
> >                 bval = I915_READ(SDVOB);
> > @@ -194,23 +200,23 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
> >         }
> >  }
> > 
> > -static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
> > +static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
> >                                  u8 *ch)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u8 out_buf[2];
> >         u8 buf[2];
> >         int ret;
> > 
> >         struct i2c_msg msgs[] = {
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = 0,
> >                         .len = 1,
> >                         .buf = out_buf,
> >                 },
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = I2C_M_RD,
> >                         .len = 1,
> >                         .buf = buf,
> > @@ -220,7 +226,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
> >         out_buf[0] = addr;
> >         out_buf[1] = 0;
> > 
> > -       if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
> > +       if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
> >         {
> >                 *ch = buf[0];
> >                 return true;
> > @@ -230,14 +236,14 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
> >         return false;
> >  }
> > 
> > -static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
> > +static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
> >                                   u8 ch)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u8 out_buf[2];
> >         struct i2c_msg msgs[] = {
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = 0,
> >                         .len = 2,
> >                         .buf = out_buf,
> > @@ -247,7 +253,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
> >         out_buf[0] = addr;
> >         out_buf[1] = ch;
> > 
> > -       if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
> > +       if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
> >         {
> >                 return true;
> >         }
> > @@ -352,16 +358,15 @@ static const struct _sdvo_cmd_name {
> >  };
> > 
> >  #define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
> > -#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
> > 
> > -static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
> > +static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
> >                                    void *args, int args_len)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         int i;
> > 
> >         DRM_DEBUG_KMS("%s: W: %02X ",
> > -                               SDVO_NAME(sdvo_priv), cmd);
> > +                               SDVO_NAME(sdvo_encoder), cmd);
> >         for (i = 0; i < args_len; i++)
> >                 DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
> >         for (; i < 8; i++)
> > @@ -377,19 +382,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
> >         DRM_LOG_KMS("\n");
> >  }
> > 
> > -static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
> > +static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
> >                                  void *args, int args_len)
> >  {
> >         int i;
> > 
> > -       intel_sdvo_debug_write(intel_output, cmd, args, args_len);
> > +       intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
> > 
> >         for (i = 0; i < args_len; i++) {
> > -               intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
> > +               intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
> >                                       ((u8*)args)[i]);
> >         }
> > 
> > -       intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
> > +       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
> >  }
> > 
> >  static const char *cmd_status_names[] = {
> > @@ -402,14 +407,14 @@ static const char *cmd_status_names[] = {
> >         "Scaling not supported"
> >  };
> > 
> > -static void intel_sdvo_debug_response(struct intel_output *intel_output,
> > +static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
> >                                       void *response, int response_len,
> >                                       u8 status)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         int i;
> > 
> > -       DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
> > +       DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_encoder));
> >         for (i = 0; i < response_len; i++)
> >                 DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
> >         for (; i < 8; i++)
> > @@ -421,7 +426,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
> >         DRM_LOG_KMS("\n");
> >  }
> > 
> > -static u8 intel_sdvo_read_response(struct intel_output *intel_output,
> > +static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
> >                                    void *response, int response_len)
> >  {
> >         int i;
> > @@ -431,16 +436,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,
> >         while (retry--) {
> >                 /* Read the command response */
> >                 for (i = 0; i < response_len; i++) {
> > -                       intel_sdvo_read_byte(intel_output,
> > +                       intel_sdvo_read_byte(intel_encoder,
> >                                              SDVO_I2C_RETURN_0 + i,
> >                                              &((u8 *)response)[i]);
> >                 }
> > 
> >                 /* read the return status */
> > -               intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
> > +               intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
> >                                      &status);
> > 
> > -               intel_sdvo_debug_response(intel_output, response, response_len,
> > +               intel_sdvo_debug_response(intel_encoder, response, response_len,
> >                                           status);
> >                 if (status != SDVO_CMD_STATUS_PENDING)
> >                         return status;
> > @@ -468,37 +473,37 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
> >   * another I2C transaction after issuing the DDC bus switch, it will be
> >   * switched to the internal SDVO register.
> >   */
> > -static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
> > +static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
> >                                               u8 target)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
> >         struct i2c_msg msgs[] = {
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = 0,
> >                         .len = 2,
> >                         .buf = out_buf,
> >                 },
> >                 /* the following two are to read the response */
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = 0,
> >                         .len = 1,
> >                         .buf = cmd_buf,
> >                 },
> >                 {
> > -                       .addr = sdvo_priv->slave_addr >> 1,
> > +                       .addr = sdvo_encoder->slave_addr >> 1,
> >                         .flags = I2C_M_RD,
> >                         .len = 1,
> >                         .buf = ret_value,
> >                 },
> >         };
> > 
> > -       intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
> > +       intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
> >                                         &target, 1);
> >         /* write the DDC switch command argument */
> > -       intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
> > +       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
> > 
> >         out_buf[0] = SDVO_I2C_OPCODE;
> >         out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
> > @@ -507,7 +512,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
> >         ret_value[0] = 0;
> >         ret_value[1] = 0;
> > 
> > -       ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
> > +       ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
> >         if (ret != 3) {
> >                 /* failure in I2C transfer */
> >                 DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
> > @@ -521,7 +526,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
> >         return;
> >  }
> > 
> > -static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
> > +static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
> >  {
> >         struct intel_sdvo_set_target_input_args targets = {0};
> >         u8 status;
> > @@ -532,10 +537,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
> >         if (target_1)
> >                 targets.target_1 = 1;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
> >                              sizeof(targets));
> > 
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> > 
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > @@ -546,13 +551,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
> >   * This function is making an assumption about the layout of the response,
> >   * which should be checked against the docs.
> >   */
> > -static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
> > +static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
> >  {
> >         struct intel_sdvo_get_trained_inputs_response response;
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> > @@ -561,29 +566,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
> > +static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
> >                                           u16 *outputs)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
> > 
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > 
> > -static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
> > +static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
> >                                           u16 outputs)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
> >                              sizeof(outputs));
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > 
> > -static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
> > +static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
> >                                                int mode)
> >  {
> >         u8 status, state = SDVO_ENCODER_STATE_ON;
> > @@ -603,24 +608,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output
> >                 break;
> >         }
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
> >                              sizeof(state));
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> > 
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > 
> > -static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
> > +static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
> >                                                    int *clock_min,
> >                                                    int *clock_max)
> >  {
> >         struct intel_sdvo_pixel_clock_range clocks;
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
> >                              NULL, 0);
> > 
> > -       status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
> > +       status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
> > 
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > @@ -632,31 +637,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
> > +static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
> >                                          u16 outputs)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
> >                              sizeof(outputs));
> > 
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > 
> > -static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
> > +static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
> >                                   struct intel_sdvo_dtd *dtd)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, &dtd->part1,
> > +       intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
> >                                           sizeof(dtd->part1));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> > -       intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, &dtd->part2,
> > +       intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
> >                                           sizeof(dtd->part2));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > @@ -664,60 +669,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
> > +static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
> >                                          struct intel_sdvo_dtd *dtd)
> >  {
> > -       return intel_sdvo_get_timing(intel_output,
> > +       return intel_sdvo_get_timing(intel_encoder,
> >                                      SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
> >  }
> > 
> > -static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
> > +static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
> >                                          struct intel_sdvo_dtd *dtd)
> >  {
> > -       return intel_sdvo_get_timing(intel_output,
> > +       return intel_sdvo_get_timing(intel_encoder,
> >                                      SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
> >  }
> > 
> > -static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
> > +static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
> >                                   struct intel_sdvo_dtd *dtd)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> > -       intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
> > +static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
> >                                          struct intel_sdvo_dtd *dtd)
> >  {
> > -       return intel_sdvo_set_timing(intel_output,
> > +       return intel_sdvo_set_timing(intel_encoder,
> >                                      SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
> >  }
> > 
> > -static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
> > +static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
> >                                          struct intel_sdvo_dtd *dtd)
> >  {
> > -       return intel_sdvo_set_timing(intel_output,
> > +       return intel_sdvo_set_timing(intel_encoder,
> >                                      SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
> >  }
> > 
> >  static bool
> > -intel_sdvo_create_preferred_input_timing(struct intel_output *output,
> > +intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
> >                                          uint16_t clock,
> >                                          uint16_t width,
> >                                          uint16_t height)
> >  {
> >         struct intel_sdvo_preferred_input_timing_args args;
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         uint8_t status;
> > 
> >         memset(&args, 0, sizeof(args));
> > @@ -726,37 +731,37 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
> >         args.height = height;
> >         args.interlace = 0;
> > 
> > -       if (sdvo_priv->is_lvds &&
> > -          (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width ||
> > -           sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
> > +       if (sdvo_encoder->has_lvds &&
> > +          (sdvo_encoder->sdvo_lvds_fixed_mode->hdisplay != width ||
> > +           sdvo_encoder->sdvo_lvds_fixed_mode->vdisplay != height))
> >                 args.scaled = 1;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
> >                              &args, sizeof(args));
> > -       status = intel_sdvo_read_response(output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
> > +static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
> >                                                   struct intel_sdvo_dtd *dtd)
> >  {
> >         bool status;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
> >                              NULL, 0);
> > 
> > -       status = intel_sdvo_read_response(output, &dtd->part1,
> > +       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
> >                                           sizeof(dtd->part1));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
> >                              NULL, 0);
> > 
> > -       status = intel_sdvo_read_response(output, &dtd->part2,
> > +       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
> >                                           sizeof(dtd->part2));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > @@ -764,12 +769,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
> >         return false;
> >  }
> > 
> > -static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
> > +static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
> >  {
> >         u8 response, status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, &response, 1);
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, &response, 1);
> > 
> >         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                 DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
> > @@ -781,12 +786,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
> >         return response;
> >  }
> > 
> > -static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
> > +static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
> > -       status = intel_sdvo_read_response(intel_output, NULL, 0);
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> > @@ -875,13 +880,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
> >                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
> >  }
> > 
> > -static bool intel_sdvo_get_supp_encode(struct intel_output *output,
> > +static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
> >                                        struct intel_sdvo_encode *encode)
> >  {
> >         uint8_t status;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
> > -       status = intel_sdvo_read_response(output, encode, sizeof(*encode));
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
> >         if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
> >                 memset(encode, 0, sizeof(*encode));
> >                 return false;
> > @@ -890,23 +895,23 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,
> >         return true;
> >  }
> > 
> > -static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
> > +static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, uint8_t mode)
> >  {
> >         uint8_t status;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
> > -       status = intel_sdvo_read_response(output, NULL, 0);
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> > 
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > 
> > -static bool intel_sdvo_set_colorimetry(struct intel_output *output,
> > +static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
> >                                        uint8_t mode)
> >  {
> >         uint8_t status;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
> > -       status = intel_sdvo_read_response(output, NULL, 0);
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> > 
> >         return (status == SDVO_CMD_STATUS_SUCCESS);
> >  }
> > @@ -942,7 +947,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
> >  }
> >  #endif
> > 
> > -static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
> > +static void intel_sdvo_set_hdmi_buf(struct intel_encoder *encoder, int index,
> >                                 uint8_t *data, int8_t size, uint8_t tx_rate)
> >  {
> >      uint8_t set_buf_index[2];
> > @@ -950,14 +955,14 @@ static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
> >      set_buf_index[0] = index;
> >      set_buf_index[1] = 0;
> > 
> > -    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
> > +    intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
> > 
> >      for (; size > 0; size -= 8) {
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
> > +       intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
> >         data += 8;
> >      }
> > 
> > -    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
> > +    intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
> >  }
> > 
> >  static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
> > @@ -1032,7 +1037,7 @@ struct dip_infoframe {
> >         } __attribute__ ((packed)) u;
> >  } __attribute__((packed));
> > 
> > -static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
> > +static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
> >                                          struct drm_display_mode * mode)
> >  {
> >         struct dip_infoframe avi_if = {
> > @@ -1043,20 +1048,20 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
> > 
> >         avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
> >                                                     4 + avi_if.len);
> > -       intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
> > +       intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
> >                                 SDVO_HBUF_TX_VSYNC);
> >  }
> > 
> > -static void intel_sdvo_set_tv_format(struct intel_output *output)
> > +static void intel_sdvo_set_tv_format(struct intel_encoder *encoder)
> >  {
> > 
> >         struct intel_sdvo_tv_format format;
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = encoder->dev_priv;
> >         uint32_t format_map, i;
> >         uint8_t status;
> > 
> >         for (i = 0; i < TV_FORMAT_NUM; i++)
> > -               if (tv_format_names[i] == sdvo_priv->tv_format_name)
> > +               if (tv_format_names[i] == sdvo_encoder->tv_format_name)
> >                         break;
> > 
> >         format_map = 1 << i;
> > @@ -1064,23 +1069,23 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)
> >         memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
> >                         sizeof(format) : sizeof(format_map));
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
> > +       intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
> >                              sizeof(format));
> > 
> > -       status = intel_sdvo_read_response(output, NULL, 0);
> > +       status = intel_sdvo_read_response(encoder, NULL, 0);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 DRM_DEBUG_KMS("%s: Failed to set TV format\n",
> > -                         SDVO_NAME(sdvo_priv));
> > +                         SDVO_NAME(sdvo_encoder));
> >  }
> > 
> >  static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >                                   struct drm_display_mode *mode,
> >                                   struct drm_display_mode *adjusted_mode)
> >  {
> > -       struct intel_output *output = enc_to_intel_output(encoder);
> > -       struct intel_sdvo_priv *dev_priv = output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > 
> > -       if (dev_priv->is_tv) {
> > +       if (sdvo_encoder->has_tv) {
> >                 struct intel_sdvo_dtd output_dtd;
> >                 bool success;
> > 
> > @@ -1090,28 +1095,26 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >                  * the sequence to do it. Oh well.
> >                  */
> > 
> > -
> >                 /* Set output timings */
> >                 intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
> > -               intel_sdvo_set_target_output(output,
> > -                                            dev_priv->controlled_output);
> > -               intel_sdvo_set_output_timing(output, &output_dtd);
> > +               intel_sdvo_set_target_output(intel_encoder,
> > +                                            sdvo_encoder->attached_output);
> > +               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
> > 
> >                 /* Set the input timing to the screen. Assume always input 0. */
> > -               intel_sdvo_set_target_input(output, true, false);
> > -
> > +               intel_sdvo_set_target_input(intel_encoder, true, false);
> > 
> > -               success = intel_sdvo_create_preferred_input_timing(output,
> > +               success = intel_sdvo_create_preferred_input_timing(intel_encoder,
> >                                                                    mode->clock / 10,
> >                                                                    mode->hdisplay,
> >                                                                    mode->vdisplay);
> >                 if (success) {
> >                         struct intel_sdvo_dtd input_dtd;
> > 
> > -                       intel_sdvo_get_preferred_input_timing(output,
> > +                       intel_sdvo_get_preferred_input_timing(intel_encoder,
> >                                                              &input_dtd);
> >                         intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
> > -                       dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
> > +                       sdvo_encoder->sdvo_flags = input_dtd.part2.sdvo_flags;
> > 
> >                         drm_mode_set_crtcinfo(adjusted_mode, 0);
> > 
> > @@ -1122,25 +1125,24 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >                 } else {
> >                         return false;
> >                 }
> > -       } else if (dev_priv->is_lvds) {
> > +       } else if (sdvo_encoder->has_lvds) {
> >                 struct intel_sdvo_dtd output_dtd;
> >                 bool success;
> > 
> > -               drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0);
> > +               drm_mode_set_crtcinfo(sdvo_encoder->sdvo_lvds_fixed_mode, 0);
> >                 /* Set output timings */
> >                 intel_sdvo_get_dtd_from_mode(&output_dtd,
> > -                               dev_priv->sdvo_lvds_fixed_mode);
> > +                                            sdvo_encoder->sdvo_lvds_fixed_mode);
> > 
> > -               intel_sdvo_set_target_output(output,
> > -                                            dev_priv->controlled_output);
> > -               intel_sdvo_set_output_timing(output, &output_dtd);
> > +               intel_sdvo_set_target_output(intel_encoder,
> > +                                            sdvo_encoder->attached_output);
> > +               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
> > 
> >                 /* Set the input timing to the screen. Assume always input 0. */
> > -               intel_sdvo_set_target_input(output, true, false);
> > -
> > +               intel_sdvo_set_target_input(intel_encoder, true, false);
> > 
> >                 success = intel_sdvo_create_preferred_input_timing(
> > -                               output,
> > +                               intel_encoder,
> >                                 mode->clock / 10,
> >                                 mode->hdisplay,
> >                                 mode->vdisplay);
> > @@ -1148,10 +1150,10 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
> >                 if (success) {
> >                         struct intel_sdvo_dtd input_dtd;
> > 
> > -                       intel_sdvo_get_preferred_input_timing(output,
> > +                       intel_sdvo_get_preferred_input_timing(intel_encoder,
> >                                                              &input_dtd);
> >                         intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
> > -                       dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
> > +                       sdvo_encoder->sdvo_flags = input_dtd.part2.sdvo_flags;
> > 
> >                         drm_mode_set_crtcinfo(adjusted_mode, 0);
> > 
> > @@ -1180,8 +1182,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -       struct intel_output *output = enc_to_intel_output(encoder);
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u32 sdvox = 0;
> >         int sdvo_pixel_multiply;
> >         struct intel_sdvo_in_out_map in_out;
> > @@ -1197,41 +1199,41 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >          * channel on the motherboard.  In a two-input device, the first input
> >          * will be SDVOB and the second SDVOC.
> >          */
> > -       in_out.in0 = sdvo_priv->controlled_output;
> > +       in_out.in0 = sdvo_encoder->attached_output;
> >         in_out.in1 = 0;
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
> >                              &in_out, sizeof(in_out));
> > -       status = intel_sdvo_read_response(output, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
> > 
> > -       if (sdvo_priv->is_hdmi) {
> > -               intel_sdvo_set_avi_infoframe(output, mode);
> > +       if (sdvo_encoder->has_hdmi) {
> > +               intel_sdvo_set_avi_infoframe(intel_encoder, mode);
> >                 sdvox |= SDVO_AUDIO_ENABLE;
> >         }
> > 
> >         /* We have tried to get input timing in mode_fixup, and filled into
> >            adjusted_mode */
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
> > +       if (sdvo_encoder->has_tv || sdvo_encoder->has_lvds) {
> >                 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
> > -               input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags;
> > +               input_dtd.part2.sdvo_flags = sdvo_encoder->sdvo_flags;
> >         } else
> >                 intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
> > 
> >         /* If it's a TV, we already set the output timing in mode_fixup.
> >          * Otherwise, the output timing is equal to the input timing.
> >          */
> > -       if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
> > +       if (!sdvo_encoder->has_tv && !sdvo_encoder->has_lvds) {
> >                 /* Set the output timing to the screen */
> > -               intel_sdvo_set_target_output(output,
> > -                                            sdvo_priv->controlled_output);
> > -               intel_sdvo_set_output_timing(output, &input_dtd);
> > +               intel_sdvo_set_target_output(intel_encoder,
> > +                                            sdvo_encoder->attached_output);
> > +               intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
> >         }
> > 
> >         /* Set the input timing to the screen. Assume always input 0. */
> > -       intel_sdvo_set_target_input(output, true, false);
> > +       intel_sdvo_set_target_input(intel_encoder, true, false);
> > 
> > -       if (sdvo_priv->is_tv)
> > -               intel_sdvo_set_tv_format(output);
> > +       if (sdvo_encoder->has_tv)
> > +               intel_sdvo_set_tv_format(intel_encoder);
> > 
> >         /* We would like to use intel_sdvo_create_preferred_input_timing() to
> >          * provide the device with a timing it can support, if it supports that
> > @@ -1248,20 +1250,20 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >                 intel_sdvo_set_input_timing(output, &input_dtd);
> >         }
> >  #else
> > -       intel_sdvo_set_input_timing(output, &input_dtd);
> > +       intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
> >  #endif
> > 
> >         switch (intel_sdvo_get_pixel_multiplier(mode)) {
> >         case 1:
> > -               intel_sdvo_set_clock_rate_mult(output,
> > +               intel_sdvo_set_clock_rate_mult(intel_encoder,
> >                                                SDVO_CLOCK_RATE_MULT_1X);
> >                 break;
> >         case 2:
> > -               intel_sdvo_set_clock_rate_mult(output,
> > +               intel_sdvo_set_clock_rate_mult(intel_encoder,
> >                                                SDVO_CLOCK_RATE_MULT_2X);
> >                 break;
> >         case 4:
> > -               intel_sdvo_set_clock_rate_mult(output,
> > +               intel_sdvo_set_clock_rate_mult(intel_encoder,
> >                                                SDVO_CLOCK_RATE_MULT_4X);
> >                 break;
> >         }
> > @@ -1272,8 +1274,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >                         SDVO_VSYNC_ACTIVE_HIGH |
> >                         SDVO_HSYNC_ACTIVE_HIGH;
> >         } else {
> > -               sdvox |= I915_READ(sdvo_priv->output_device);
> > -               switch (sdvo_priv->output_device) {
> > +               sdvox |= I915_READ(sdvo_encoder->output_device);
> > +               switch (sdvo_encoder->output_device) {
> >                 case SDVOB:
> >                         sdvox &= SDVOB_PRESERVE_MASK;
> >                         break;
> > @@ -1295,28 +1297,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
> >                 sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
> >         }
> > 
> > -       if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
> > +       if (sdvo_encoder->sdvo_flags & SDVO_NEED_TO_STALL)
> >                 sdvox |= SDVO_STALL_SELECT;
> > -       intel_sdvo_write_sdvox(output, sdvox);
> > +       intel_sdvo_write_sdvox(intel_encoder, sdvox);
> >  }
> > 
> >  static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
> >  {
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         u32 temp;
> > 
> >         if (mode != DRM_MODE_DPMS_ON) {
> > -               intel_sdvo_set_active_outputs(intel_output, 0);
> > +               intel_sdvo_set_active_outputs(intel_encoder, 0);
> >                 if (0)
> > -                       intel_sdvo_set_encoder_power_state(intel_output, mode);
> > +                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
> > 
> >                 if (mode == DRM_MODE_DPMS_OFF) {
> > -                       temp = I915_READ(sdvo_priv->output_device);
> > +                       temp = I915_READ(sdvo_encoder->output_device);
> >                         if ((temp & SDVO_ENABLE) != 0) {
> > -                               intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
> > +                               intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
> >                         }
> >                 }
> >         } else {
> > @@ -1324,13 +1326,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
> >                 int i;
> >                 u8 status;
> > 
> > -               temp = I915_READ(sdvo_priv->output_device);
> > +               temp = I915_READ(sdvo_encoder->output_device);
> >                 if ((temp & SDVO_ENABLE) == 0)
> > -                       intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
> > +                       intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
> >                 for (i = 0; i < 2; i++)
> >                   intel_wait_for_vblank(dev);
> > 
> > -               status = intel_sdvo_get_trained_inputs(intel_output, &input1,
> > +               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
> >                                                        &input2);
> > 
> > 
> > @@ -1340,12 +1342,12 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
> >                  */
> >                 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
> >                         DRM_DEBUG_KMS("First %s output reported failure to "
> > -                                       "sync\n", SDVO_NAME(sdvo_priv));
> > +                                       "sync\n", SDVO_NAME(sdvo_encoder));
> >                 }
> > 
> >                 if (0)
> > -                       intel_sdvo_set_encoder_power_state(intel_output, mode);
> > -               intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
> > +                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
> > +               intel_sdvo_set_active_outputs(intel_encoder, sdvo_encoder->attached_output);
> >         }
> >         return;
> >  }
> > @@ -1354,135 +1356,140 @@ static void intel_sdvo_save(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         int o;
> > 
> > -       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
> > -       intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
> > +       sdvo_encoder->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
> > +       intel_sdvo_get_active_outputs(intel_encoder, &sdvo_encoder->save_active_outputs);
> > 
> > -       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
> > -               intel_sdvo_set_target_input(intel_output, true, false);
> > -               intel_sdvo_get_input_timing(intel_output,
> > -                                           &sdvo_priv->save_input_dtd_1);
> > +       if (sdvo_encoder->caps.sdvo_inputs_mask & 0x1) {
> > +               intel_sdvo_set_target_input(intel_encoder, true, false);
> > +               intel_sdvo_get_input_timing(intel_encoder,
> > +                                           &sdvo_encoder->save_input_dtd_1);
> >         }
> > 
> > -       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
> > -               intel_sdvo_set_target_input(intel_output, false, true);
> > -               intel_sdvo_get_input_timing(intel_output,
> > -                                           &sdvo_priv->save_input_dtd_2);
> > +       if (sdvo_encoder->caps.sdvo_inputs_mask & 0x2) {
> > +               intel_sdvo_set_target_input(intel_encoder, false, true);
> > +               intel_sdvo_get_input_timing(intel_encoder,
> > +                                           &sdvo_encoder->save_input_dtd_2);
> >         }
> > 
> >         for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
> >         {
> >                 u16  this_output = (1 << o);
> > -               if (sdvo_priv->caps.output_flags & this_output)
> > +               if (sdvo_encoder->caps.output_flags & this_output)
> >                 {
> > -                       intel_sdvo_set_target_output(intel_output, this_output);
> > -                       intel_sdvo_get_output_timing(intel_output,
> > -                                                    &sdvo_priv->save_output_dtd[o]);
> > +                       intel_sdvo_set_target_output(intel_encoder, this_output);
> > +                       intel_sdvo_get_output_timing(intel_encoder,
> > +                                                    &sdvo_encoder->save_output_dtd[o]);
> >                 }
> >         }
> > -       if (sdvo_priv->is_tv) {
> > +       if (sdvo_encoder->has_tv) {
> >                 /* XXX: Save TV format/enhancements. */
> >         }
> > 
> > -       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
> > +       sdvo_encoder->save_SDVOX = I915_READ(sdvo_encoder->output_device);
> >  }
> > 
> >  static void intel_sdvo_restore(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = connector->encoder;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         int o;
> >         int i;
> >         bool input1, input2;
> >         u8 status;
> > 
> > -       intel_sdvo_set_active_outputs(intel_output, 0);
> > +       intel_sdvo_set_active_outputs(intel_encoder, 0);
> > 
> >         for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
> >         {
> >                 u16  this_output = (1 << o);
> > -               if (sdvo_priv->caps.output_flags & this_output) {
> > -                       intel_sdvo_set_target_output(intel_output, this_output);
> > -                       intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
> > +               if (sdvo_encoder->caps.output_flags & this_output) {
> > +                       intel_sdvo_set_target_output(intel_encoder, this_output);
> > +                       intel_sdvo_set_output_timing(intel_encoder, &sdvo_encoder->save_output_dtd[o]);
> >                 }
> >         }
> > 
> > -       if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
> > -               intel_sdvo_set_target_input(intel_output, true, false);
> > -               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
> > +       if (sdvo_encoder->caps.sdvo_inputs_mask & 0x1) {
> > +               intel_sdvo_set_target_input(intel_encoder, true, false);
> > +               intel_sdvo_set_input_timing(intel_encoder, &sdvo_encoder->save_input_dtd_1);
> >         }
> > 
> > -       if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
> > -               intel_sdvo_set_target_input(intel_output, false, true);
> > -               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
> > +       if (sdvo_encoder->caps.sdvo_inputs_mask & 0x2) {
> > +               intel_sdvo_set_target_input(intel_encoder, false, true);
> > +               intel_sdvo_set_input_timing(intel_encoder, &sdvo_encoder->save_input_dtd_2);
> >         }
> > 
> > -       intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
> > +       intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_encoder->save_sdvo_mult);
> > 
> > -       if (sdvo_priv->is_tv) {
> > +       if (sdvo_encoder->has_tv) {
> >                 /* XXX: Restore TV format/enhancements. */
> >         }
> > 
> > -       intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
> > +       intel_sdvo_write_sdvox(intel_encoder, sdvo_encoder->save_SDVOX);
> > 
> > -       if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
> > +       if (sdvo_encoder->save_SDVOX & SDVO_ENABLE)
> >         {
> >                 for (i = 0; i < 2; i++)
> >                         intel_wait_for_vblank(dev);
> > -               status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
> > +               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
> >                 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
> >                         DRM_DEBUG_KMS("First %s output reported failure to "
> > -                                       "sync\n", SDVO_NAME(sdvo_priv));
> > +                                       "sync\n", SDVO_NAME(sdvo_encoder));
> >         }
> > 
> > -       intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
> > +       intel_sdvo_set_active_outputs(intel_encoder, sdvo_encoder->save_active_outputs);
> >  }
> > 
> >  static int intel_sdvo_mode_valid(struct drm_connector *connector,
> >                                  struct drm_display_mode *mode)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > 
> >         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> >                 return MODE_NO_DBLESCAN;
> > 
> > -       if (sdvo_priv->pixel_clock_min > mode->clock)
> > +       if (sdvo_encoder->pixel_clock_min > mode->clock)
> >                 return MODE_CLOCK_LOW;
> > 
> > -       if (sdvo_priv->pixel_clock_max < mode->clock)
> > +       if (sdvo_encoder->pixel_clock_max < mode->clock)
> >                 return MODE_CLOCK_HIGH;
> > 
> > -       if (sdvo_priv->is_lvds == true) {
> > -               if (sdvo_priv->sdvo_lvds_fixed_mode == NULL)
> > +       if (sdvo_encoder->has_lvds) {
> > +               if (sdvo_encoder->sdvo_lvds_fixed_mode == NULL)
> >                         return MODE_PANEL;
> > 
> > -               if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay)
> > +               if (mode->hdisplay > sdvo_encoder->sdvo_lvds_fixed_mode->hdisplay)
> >                         return MODE_PANEL;
> > 
> > -               if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay)
> > +               if (mode->vdisplay > sdvo_encoder->sdvo_lvds_fixed_mode->vdisplay)
> >                         return MODE_PANEL;
> >         }
> > 
> >         return MODE_OK;
> >  }
> > 
> > -static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
> > +static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
> >  {
> >         u8 status;
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> > 
> >         return true;
> >  }
> > 
> > + /* XXX no use */
> > +#if 0
> >  struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
> >  {
> >         struct drm_connector *connector = NULL;
> > @@ -1553,11 +1560,12 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
> >         intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
> >         intel_sdvo_read_response(intel_output, &response, 2);
> >  }
> > +#endif
> > 
> >  static bool
> > -intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
> > +intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_priv = intel_encoder->dev_priv;
> >         int caps = 0;
> > 
> >         if (sdvo_priv->caps.output_flags &
> > @@ -1590,13 +1598,13 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
> >  static struct drm_connector *
> >  intel_find_analog_connector(struct drm_device *dev)
> >  {
> > -       struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > +       struct intel_encoder *intel_encoder;
> > +       struct drm_encoder *encoder;
> > 
> > -       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> > -               intel_output = to_intel_output(connector);
> > -               if (intel_output->type == INTEL_OUTPUT_ANALOG)
> > -                       return connector;
> > +       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
> > +               intel_encoder = to_intel_encoder(encoder);
> > +               if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
> > +                       return &intel_encoder->connector->base;
> >         }
> >         return NULL;
> >  }
> > @@ -1620,62 +1628,63 @@ intel_analog_is_connected(struct drm_device *dev)
> >  enum drm_connector_status
> >  intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         enum drm_connector_status status = connector_status_connected;
> >         struct edid *edid = NULL;
> > 
> > -       edid = drm_get_edid(&intel_output->base,
> > -                           intel_output->ddc_bus);
> > +       edid = drm_get_edid(connector, intel_connector->ddc_bus);
> > 
> >         /* This is only applied to SDVO cards with multiple outputs */
> > -       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
> > +       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
> >                 uint8_t saved_ddc, temp_ddc;
> > -               saved_ddc = sdvo_priv->ddc_bus;
> > -               temp_ddc = sdvo_priv->ddc_bus >> 1;
> > +               saved_ddc = sdvo_encoder->ddc_bus;
> > +               temp_ddc = sdvo_encoder->ddc_bus >> 1;
> >                 /*
> >                  * Don't use the 1 as the argument of DDC bus switch to get
> >                  * the EDID. It is used for SDVO SPD ROM.
> >                  */
> >                 while(temp_ddc > 1) {
> > -                       sdvo_priv->ddc_bus = temp_ddc;
> > -                       edid = drm_get_edid(&intel_output->base,
> > -                               intel_output->ddc_bus);
> > +                       sdvo_encoder->ddc_bus = temp_ddc;
> > +                       edid = drm_get_edid(connector, intel_connector->ddc_bus);
> >                         if (edid) {
> >                                 /*
> >                                  * When we can get the EDID, maybe it is the
> >                                  * correct DDC bus. Update it.
> >                                  */
> > -                               sdvo_priv->ddc_bus = temp_ddc;
> > +                               sdvo_encoder->ddc_bus = temp_ddc;
> >                                 break;
> >                         }
> >                         temp_ddc >>= 1;
> >                 }
> >                 if (edid == NULL)
> > -                       sdvo_priv->ddc_bus = saved_ddc;
> > +                       sdvo_encoder->ddc_bus = saved_ddc;
> >         }
> >         /* when there is no edid and no monitor is connected with VGA
> >          * port, try to use the CRT ddc to read the EDID for DVI-connector
> >          */
> >         if (edid == NULL &&
> > -           sdvo_priv->analog_ddc_bus &&
> > -           !intel_analog_is_connected(intel_output->base.dev))
> > -               edid = drm_get_edid(&intel_output->base,
> > -                                   sdvo_priv->analog_ddc_bus);
> > +           sdvo_connector->analog_ddc_bus &&
> > +           !intel_analog_is_connected(intel_connector->base.dev))
> > +               edid = drm_get_edid(connector, sdvo_connector->analog_ddc_bus);
> > +
> >         if (edid != NULL) {
> >                 /* Don't report the output as connected if it's a DVI-I
> >                  * connector with a non-digital EDID coming out.
> >                  */
> >                 if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
> >                         if (edid->input & DRM_EDID_INPUT_DIGITAL)
> > -                               sdvo_priv->is_hdmi =
> > +                               sdvo_encoder->has_hdmi =
> >                                         drm_detect_hdmi_monitor(edid);
> >                         else
> >                                 status = connector_status_disconnected;
> >                 }
> > 
> >                 kfree(edid);
> > -               intel_output->base.display_info.raw_edid = NULL;
> > +               intel_connector->base.display_info.raw_edid = NULL;
> > 
> >         } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
> >                 status = connector_status_disconnected;
> > @@ -1687,16 +1696,20 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
> >  {
> >         uint16_t response;
> >         u8 status;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> > 
> > -       intel_sdvo_write_cmd(intel_output,
> > +       intel_sdvo_write_cmd(intel_encoder,
> >                              SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
> > -       if (sdvo_priv->is_tv) {
> > +
> > +       if (sdvo_encoder->has_tv) {
> >                 /* add 30ms delay when the output type is SDVO-TV */
> >                 mdelay(30);
> >         }
> > -       status = intel_sdvo_read_response(intel_output, &response, 2);
> > +       status = intel_sdvo_read_response(intel_encoder, &response, 2);
> > 
> >         DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
> > 
> > @@ -1706,24 +1719,24 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
> >         if (response == 0)
> >                 return connector_status_disconnected;
> > 
> > -       if (intel_sdvo_multifunc_encoder(intel_output) &&
> > -               sdvo_priv->attached_output != response) {
> > -               if (sdvo_priv->controlled_output != response &&
> > -                       intel_sdvo_output_setup(intel_output, response) != true)
> > -                       return connector_status_unknown;
> > -               sdvo_priv->attached_output = response;
> > -       }
> > -       return intel_sdvo_hdmi_sink_detect(connector, response);
> > +       sdvo_encoder->attached_output = response;
> > +
> > +       if ((sdvo_connector->output_flag & response) == 0)
> > +               return connector_status_disconnected;
> > +       else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
> > +               return intel_sdvo_hdmi_sink_detect(connector, response);
> > +       else
> > +               return connector_status_connected;
> >  }
> > 
> >  static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> >         int num_modes;
> > 
> >         /* set the bus switch and get the modes */
> > -       num_modes = intel_ddc_get_modes(intel_output);
> > +       num_modes = intel_ddc_get_modes(intel_connector);
> > 
> >         /*
> >          * Mac mini hack.  On this device, the DVI-I connector shares one DDC
> > @@ -1732,18 +1745,18 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
> >          * which case we'll look there for the digital DDC data.
> >          */
> >         if (num_modes == 0 &&
> > -           sdvo_priv->analog_ddc_bus &&
> > -           !intel_analog_is_connected(intel_output->base.dev)) {
> > +           sdvo_connector->analog_ddc_bus &&
> > +           !intel_analog_is_connected(intel_connector->base.dev)) {
> >                 struct i2c_adapter *digital_ddc_bus;
> > 
> >                 /* Switch to the analog ddc bus and try that
> >                  */
> > -               digital_ddc_bus = intel_output->ddc_bus;
> > -               intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
> > +               digital_ddc_bus = intel_connector->ddc_bus;
> > +               intel_connector->ddc_bus = sdvo_connector->analog_ddc_bus;
> > 
> > -               (void) intel_ddc_get_modes(intel_output);
> > +               (void) intel_ddc_get_modes(intel_connector);
> > 
> > -               intel_output->ddc_bus = digital_ddc_bus;
> > +               intel_connector->ddc_bus = digital_ddc_bus;
> >         }
> >  }
> > 
> > @@ -1814,8 +1827,9 @@ struct drm_display_mode sdvo_tv_modes[] = {
> > 
> >  static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         struct intel_sdvo_sdtv_resolution_request tv_res;
> >         uint32_t reply = 0, format_map = 0;
> >         int i;
> > @@ -1826,7 +1840,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
> >          * format.
> >          */
> >         for (i = 0; i < TV_FORMAT_NUM; i++)
> > -               if (tv_format_names[i] ==  sdvo_priv->tv_format_name)
> > +               if (tv_format_names[i] ==  sdvo_encoder->tv_format_name)
> >                         break;
> > 
> >         format_map = (1 << i);
> > @@ -1835,11 +1849,11 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
> >                sizeof(format_map) ? sizeof(format_map) :
> >                sizeof(struct intel_sdvo_sdtv_resolution_request));
> > 
> > -       intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
> > +       intel_sdvo_set_target_output(intel_encoder, sdvo_encoder->attached_output);
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
> >                              &tv_res, sizeof(tv_res));
> > -       status = intel_sdvo_read_response(output, &reply, 3);
> > +       status = intel_sdvo_read_response(intel_encoder, &reply, 3);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return;
> > 
> > @@ -1856,9 +1870,11 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
> > 
> >  static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         struct drm_i915_private *dev_priv = connector->dev->dev_private;
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> >         struct drm_display_mode *newmode;
> > 
> >         /*
> > @@ -1866,7 +1882,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
> >          * Assume that the preferred modes are
> >          * arranged in priority order.
> >          */
> > -       intel_ddc_get_modes(intel_output);
> > +       intel_ddc_get_modes(intel_connector);
> >         if (list_empty(&connector->probed_modes) == false)
> >                 goto end;
> > 
> > @@ -1885,7 +1901,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
> >  end:
> >         list_for_each_entry(newmode, &connector->probed_modes, head) {
> >                 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
> > -                       sdvo_priv->sdvo_lvds_fixed_mode =
> > +                       sdvo_encoder->sdvo_lvds_fixed_mode =
> >                                 drm_mode_duplicate(connector->dev, newmode);
> >                         break;
> >                 }
> > @@ -1895,12 +1911,13 @@ end:
> > 
> >  static int intel_sdvo_get_modes(struct drm_connector *connector)
> >  {
> > -       struct intel_output *output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > 
> > -       if (sdvo_priv->is_tv)
> > +       if (sdvo_encoder->has_tv)
> >                 intel_sdvo_get_tv_modes(connector);
> > -       else if (sdvo_priv->is_lvds == true)
> > +       else if (sdvo_encoder->has_lvds)
> >                 intel_sdvo_get_lvds_modes(connector);
> >         else
> >                 intel_sdvo_get_ddc_modes(connector);
> > @@ -1913,69 +1930,62 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
> >  static
> >  void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> >         struct drm_device *dev = connector->dev;
> > 
> > -       if (sdvo_priv->is_tv) {
> > -               if (sdvo_priv->left_property)
> > -                       drm_property_destroy(dev, sdvo_priv->left_property);
> > -               if (sdvo_priv->right_property)
> > -                       drm_property_destroy(dev, sdvo_priv->right_property);
> > -               if (sdvo_priv->top_property)
> > -                       drm_property_destroy(dev, sdvo_priv->top_property);
> > -               if (sdvo_priv->bottom_property)
> > -                       drm_property_destroy(dev, sdvo_priv->bottom_property);
> > -               if (sdvo_priv->hpos_property)
> > -                       drm_property_destroy(dev, sdvo_priv->hpos_property);
> > -               if (sdvo_priv->vpos_property)
> > -                       drm_property_destroy(dev, sdvo_priv->vpos_property);
> > -       }
> > -       if (sdvo_priv->is_tv) {
> > -               if (sdvo_priv->saturation_property)
> > +       if (sdvo_encoder->has_tv) {
> > +               if (sdvo_connector->left_property)
> > +                       drm_property_destroy(dev, sdvo_connector->left_property);
> > +               if (sdvo_connector->right_property)
> > +                       drm_property_destroy(dev, sdvo_connector->right_property);
> > +               if (sdvo_connector->top_property)
> > +                       drm_property_destroy(dev, sdvo_connector->top_property);
> > +               if (sdvo_connector->bottom_property)
> > +                       drm_property_destroy(dev, sdvo_connector->bottom_property);
> > +               if (sdvo_connector->hpos_property)
> > +                       drm_property_destroy(dev, sdvo_connector->hpos_property);
> > +               if (sdvo_connector->vpos_property)
> > +                       drm_property_destroy(dev, sdvo_connector->vpos_property);
> > +               if (sdvo_connector->saturation_property)
> >                         drm_property_destroy(dev,
> > -                                       sdvo_priv->saturation_property);
> > -               if (sdvo_priv->contrast_property)
> > +                                       sdvo_connector->saturation_property);
> > +               if (sdvo_connector->contrast_property)
> >                         drm_property_destroy(dev,
> > -                                       sdvo_priv->contrast_property);
> > -               if (sdvo_priv->hue_property)
> > -                       drm_property_destroy(dev, sdvo_priv->hue_property);
> > +                                       sdvo_connector->contrast_property);
> > +               if (sdvo_connector->hue_property)
> > +                       drm_property_destroy(dev, sdvo_connector->hue_property);
> >         }
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
> > -               if (sdvo_priv->brightness_property)
> > +       if (sdvo_encoder->has_tv || sdvo_encoder->has_lvds) {
> > +               if (sdvo_connector->brightness_property)
> >                         drm_property_destroy(dev,
> > -                                       sdvo_priv->brightness_property);
> > +                                       sdvo_connector->brightness_property);
> >         }
> >         return;
> >  }
> > 
> >  static void intel_sdvo_destroy(struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> > 
> > -       if (intel_output->i2c_bus)
> > -               intel_i2c_destroy(intel_output->i2c_bus);
> > -       if (intel_output->ddc_bus)
> > -               intel_i2c_destroy(intel_output->ddc_bus);
> > -       if (sdvo_priv->analog_ddc_bus)
> > -               intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
> > +       if (intel_connector->ddc_bus)
> > +               intel_i2c_destroy(intel_connector->ddc_bus);
> > +       if (sdvo_connector->analog_ddc_bus)
> > +               intel_i2c_destroy(sdvo_connector->analog_ddc_bus);
> > 
> > -       if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
> > -               drm_mode_destroy(connector->dev,
> > -                                sdvo_priv->sdvo_lvds_fixed_mode);
> > -
> > -       if (sdvo_priv->tv_format_property)
> > +       if (sdvo_connector->tv_format_property)
> >                 drm_property_destroy(connector->dev,
> > -                                    sdvo_priv->tv_format_property);
> > +                                    sdvo_connector->tv_format_property);
> > 
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds)
> > -               intel_sdvo_destroy_enhance_property(connector);
> > +       intel_sdvo_destroy_enhance_property(connector);
> > 
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> > -
> > -       kfree(intel_output);
> > +       kfree(connector);
> >  }
> > 
> >  static int
> > @@ -1983,9 +1993,11 @@ intel_sdvo_set_property(struct drm_connector *connector,
> >                         struct drm_property *property,
> >                         uint64_t val)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         int ret = 0;
> >         bool changed = false;
> > @@ -1996,105 +2008,105 @@ intel_sdvo_set_property(struct drm_connector *connector,
> >         if (ret < 0)
> >                 goto out;
> > 
> > -       if (property == sdvo_priv->tv_format_property) {
> > +       if (property == sdvo_connector->tv_format_property) {
> >                 if (val >= TV_FORMAT_NUM) {
> >                         ret = -EINVAL;
> >                         goto out;
> >                 }
> > -               if (sdvo_priv->tv_format_name ==
> > -                   sdvo_priv->tv_format_supported[val])
> > +               if (sdvo_encoder->tv_format_name ==
> > +                   sdvo_connector->tv_format_supported[val])
> >                         goto out;
> > 
> > -               sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val];
> > +               sdvo_encoder->tv_format_name = sdvo_connector->tv_format_supported[val];
> >                 changed = true;
> >         }
> > 
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
> > +       if (sdvo_encoder->has_tv || sdvo_encoder->has_lvds) {
> >                 cmd = 0;
> >                 temp_value = val;
> > -               if (sdvo_priv->left_property == property) {
> > +               if (sdvo_connector->left_property == property) {
> >                         drm_connector_property_set_value(connector,
> > -                               sdvo_priv->right_property, val);
> > -                       if (sdvo_priv->left_margin == temp_value)
> > +                               sdvo_connector->right_property, val);
> > +                       if (sdvo_connector->left_margin == temp_value)
> >                                 goto out;
> > 
> > -                       sdvo_priv->left_margin = temp_value;
> > -                       sdvo_priv->right_margin = temp_value;
> > -                       temp_value = sdvo_priv->max_hscan -
> > -                                       sdvo_priv->left_margin;
> > +                       sdvo_connector->left_margin = temp_value;
> > +                       sdvo_connector->right_margin = temp_value;
> > +                       temp_value = sdvo_connector->max_hscan -
> > +                                       sdvo_connector->left_margin;
> >                         cmd = SDVO_CMD_SET_OVERSCAN_H;
> > -               } else if (sdvo_priv->right_property == property) {
> > +               } else if (sdvo_connector->right_property == property) {
> >                         drm_connector_property_set_value(connector,
> > -                               sdvo_priv->left_property, val);
> > -                       if (sdvo_priv->right_margin == temp_value)
> > +                               sdvo_connector->left_property, val);
> > +                       if (sdvo_connector->right_margin == temp_value)
> >                                 goto out;
> > 
> > -                       sdvo_priv->left_margin = temp_value;
> > -                       sdvo_priv->right_margin = temp_value;
> > -                       temp_value = sdvo_priv->max_hscan -
> > -                               sdvo_priv->left_margin;
> > +                       sdvo_connector->left_margin = temp_value;
> > +                       sdvo_connector->right_margin = temp_value;
> > +                       temp_value = sdvo_connector->max_hscan -
> > +                               sdvo_connector->left_margin;
> >                         cmd = SDVO_CMD_SET_OVERSCAN_H;
> > -               } else if (sdvo_priv->top_property == property) {
> > +               } else if (sdvo_connector->top_property == property) {
> >                         drm_connector_property_set_value(connector,
> > -                               sdvo_priv->bottom_property, val);
> > -                       if (sdvo_priv->top_margin == temp_value)
> > +                               sdvo_connector->bottom_property, val);
> > +                       if (sdvo_connector->top_margin == temp_value)
> >                                 goto out;
> > 
> > -                       sdvo_priv->top_margin = temp_value;
> > -                       sdvo_priv->bottom_margin = temp_value;
> > -                       temp_value = sdvo_priv->max_vscan -
> > -                                       sdvo_priv->top_margin;
> > +                       sdvo_connector->top_margin = temp_value;
> > +                       sdvo_connector->bottom_margin = temp_value;
> > +                       temp_value = sdvo_connector->max_vscan -
> > +                                       sdvo_connector->top_margin;
> >                         cmd = SDVO_CMD_SET_OVERSCAN_V;
> > -               } else if (sdvo_priv->bottom_property == property) {
> > +               } else if (sdvo_connector->bottom_property == property) {
> >                         drm_connector_property_set_value(connector,
> > -                               sdvo_priv->top_property, val);
> > -                       if (sdvo_priv->bottom_margin == temp_value)
> > +                               sdvo_connector->top_property, val);
> > +                       if (sdvo_connector->bottom_margin == temp_value)
> >                                 goto out;
> > -                       sdvo_priv->top_margin = temp_value;
> > -                       sdvo_priv->bottom_margin = temp_value;
> > -                       temp_value = sdvo_priv->max_vscan -
> > -                                       sdvo_priv->top_margin;
> > +                       sdvo_connector->top_margin = temp_value;
> > +                       sdvo_connector->bottom_margin = temp_value;
> > +                       temp_value = sdvo_connector->max_vscan -
> > +                                       sdvo_connector->top_margin;
> >                         cmd = SDVO_CMD_SET_OVERSCAN_V;
> > -               } else if (sdvo_priv->hpos_property == property) {
> > -                       if (sdvo_priv->cur_hpos == temp_value)
> > +               } else if (sdvo_connector->hpos_property == property) {
> > +                       if (sdvo_connector->cur_hpos == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_POSITION_H;
> > -                       sdvo_priv->cur_hpos = temp_value;
> > -               } else if (sdvo_priv->vpos_property == property) {
> > -                       if (sdvo_priv->cur_vpos == temp_value)
> > +                       sdvo_connector->cur_hpos = temp_value;
> > +               } else if (sdvo_connector->vpos_property == property) {
> > +                       if (sdvo_connector->cur_vpos == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_POSITION_V;
> > -                       sdvo_priv->cur_vpos = temp_value;
> > -               } else if (sdvo_priv->saturation_property == property) {
> > -                       if (sdvo_priv->cur_saturation == temp_value)
> > +                       sdvo_connector->cur_vpos = temp_value;
> > +               } else if (sdvo_connector->saturation_property == property) {
> > +                       if (sdvo_connector->cur_saturation == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_SATURATION;
> > -                       sdvo_priv->cur_saturation = temp_value;
> > -               } else if (sdvo_priv->contrast_property == property) {
> > -                       if (sdvo_priv->cur_contrast == temp_value)
> > +                       sdvo_connector->cur_saturation = temp_value;
> > +               } else if (sdvo_connector->contrast_property == property) {
> > +                       if (sdvo_connector->cur_contrast == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_CONTRAST;
> > -                       sdvo_priv->cur_contrast = temp_value;
> > -               } else if (sdvo_priv->hue_property == property) {
> > -                       if (sdvo_priv->cur_hue == temp_value)
> > +                       sdvo_connector->cur_contrast = temp_value;
> > +               } else if (sdvo_connector->hue_property == property) {
> > +                       if (sdvo_connector->cur_hue == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_HUE;
> > -                       sdvo_priv->cur_hue = temp_value;
> > -               } else if (sdvo_priv->brightness_property == property) {
> > -                       if (sdvo_priv->cur_brightness == temp_value)
> > +                       sdvo_connector->cur_hue = temp_value;
> > +               } else if (sdvo_connector->brightness_property == property) {
> > +                       if (sdvo_connector->cur_brightness == temp_value)
> >                                 goto out;
> > 
> >                         cmd = SDVO_CMD_SET_BRIGHTNESS;
> > -                       sdvo_priv->cur_brightness = temp_value;
> > +                       sdvo_connector->cur_brightness = temp_value;
> >                 }
> >                 if (cmd) {
> > -                       intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                                                 NULL, 0);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO command \n");
> > @@ -2136,7 +2148,18 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs
> > 
> >  static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
> >  {
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +
> > +       if (intel_encoder->i2c_bus)
> > +               intel_i2c_destroy(intel_encoder->i2c_bus);
> > +
> > +       if (sdvo_encoder->sdvo_lvds_fixed_mode != NULL)
> > +               drm_mode_destroy(encoder->dev,
> > +                                sdvo_encoder->sdvo_lvds_fixed_mode);
> > +
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
> > @@ -2152,7 +2175,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
> >   * outputs, then LVDS outputs.
> >   */
> >  static void
> > -intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
> > +intel_sdvo_select_ddc_bus(struct intel_sdvo_encoder *dev_priv)
> >  {
> >         uint16_t mask = 0;
> >         unsigned int num_bits;
> > @@ -2189,56 +2212,59 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
> >  }
> > 
> >  static bool
> > -intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
> > +intel_sdvo_get_digital_encoding_mode(struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> >         uint8_t status;
> > 
> > -       intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
> > +       intel_sdvo_set_target_output(intel_encoder, sdvo_encoder->controlled_output);
> > 
> > -       intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0);
> > -       status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1);
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ENCODE, NULL, 0);
> > +       status = intel_sdvo_read_response(intel_encoder, &sdvo_encoder->has_hdmi, 1);
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return false;
> >         return true;
> >  }
> > 
> > -static struct intel_output *
> > -intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
> > +static struct intel_connector *
> > +intel_sdvo_chan_to_intel_connector(struct intel_i2c_chan *chan)
> >  {
> >         struct drm_device *dev = chan->drm_dev;
> >         struct drm_connector *connector;
> > -       struct intel_output *intel_output = NULL;
> > 
> > -       list_for_each_entry(connector,
> > -                       &dev->mode_config.connector_list, head) {
> > -               if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
> > -                       intel_output = to_intel_output(connector);
> > -                       break;
> > +       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> > +               if (to_intel_connector(connector)->ddc_bus == &chan->adapter) {
> > +                       return to_intel_connector(connector);
> >                 }
> >         }
> > -       return intel_output;
> > +       return NULL;
> >  }
> > 
> >  static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
> >                                   struct i2c_msg msgs[], int num)
> >  {
> > -       struct intel_output *intel_output;
> > -       struct intel_sdvo_priv *sdvo_priv;
> > +       struct intel_connector *intel_connector;
> >         struct i2c_algo_bit_data *algo_data;
> >         const struct i2c_algorithm *algo;
> > +       struct drm_connector *connector;
> > +       struct drm_encoder *encoder;
> > +       struct intel_encoder *intel_encoder;
> > +       struct intel_sdvo_encoder *sdvo_encoder;
> > 
> >         algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
> > -       intel_output =
> > -               intel_sdvo_chan_to_intel_output(
> > +       intel_connector = intel_sdvo_chan_to_intel_connector(
> >                                 (struct intel_i2c_chan *)(algo_data->data));
> > -       if (intel_output == NULL)
> > +       if (!intel_connector)
> >                 return -EINVAL;
> > 
> > -       sdvo_priv = intel_output->dev_priv;
> > -       algo = intel_output->i2c_bus->algo;
> > +       connector = &intel_connector->base;
> > +       encoder = intel_best_encoder(connector);
> > +       intel_encoder = to_intel_encoder(encoder);
> > +       sdvo_encoder = intel_encoder->dev_priv;
> > +
> > +       algo = intel_encoder->i2c_bus->algo;
> > 
> > -       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
> > +       intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_encoder->ddc_bus);
> >         return algo->master_xfer(i2c_adap, msgs, num);
> >  }
> > 
> > @@ -2284,126 +2310,288 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
> >  }
> > 
> >  static bool
> > -intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
> > +intel_sdvo_connector_alloc (struct drm_device *dev, struct intel_connector **ret)
> >  {
> > -       struct drm_connector *connector = &intel_output->base;
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > -       bool ret = true, registered = false;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_sdvo_connector *sdvo_connector;
> > +       struct drm_connector *connector;
> > 
> > -       sdvo_priv->is_tv = false;
> > -       intel_output->needs_tv_clock = false;
> > -       sdvo_priv->is_lvds = false;
> > +       *ret = kzalloc(sizeof(*intel_connector) +
> > +                      sizeof(*sdvo_connector), GFP_KERNEL);
> > +       if (!*ret)
> > +               return false;
> > +       intel_connector = *ret;
> > +
> > +       connector = &intel_connector->base;
> > +       sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1);
> > +       intel_connector->dev_priv = sdvo_connector;
> > 
> > -       if (device_is_registered(&connector->kdev)) {
> > -               drm_sysfs_connector_remove(connector);
> > -               registered = true;
> > +       intel_connector->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVO DDC BUS");
> > +       sdvo_connector->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
> > +                                               "SDVO/VGA DDC BUS");
> > +       if (!intel_connector->ddc_bus || !sdvo_connector->analog_ddc_bus) {
> > +               kfree(intel_connector);
> > +               return false;
> >         }
> > 
> > -       if (flags &
> > -           (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
> > -               if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
> > -                       sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
> > -               else
> > -                       sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1;
> > +       /* Wrap with our custom algo which switches to DDC mode */
> > +       intel_connector->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
> > +       return true;
> > +}
> > +
> > +static void
> > +intel_sdvo_connector_create (struct drm_encoder *encoder, struct drm_connector *connector)
> > +{
> > +       drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs,
> > +                          connector->connector_type);
> > +
> > +       drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
> > +
> > +       connector->interlace_allowed = 0;
> > +       connector->doublescan_allowed = 0;
> > +       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
> > +
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> > +       drm_sysfs_connector_add(connector);
> > +}
> > +
> > +static bool
> > +intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device)
> > +{
> > +       struct drm_encoder *encoder = &intel_encoder->base;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct drm_connector *connector;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_sdvo_connector *sdvo_connector;
> > +
> > +       if (!intel_sdvo_connector_alloc(encoder->dev, &intel_connector))
> > +               return false;
> > +
> > +       sdvo_connector = intel_connector->dev_priv;
> > 
> > -               encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_DVID;
> > +       if (device == 0) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_TMDS0;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
> > +       } else if (device == 1) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_TMDS1;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
> > +       }
> > +
> > +       connector = &intel_connector->base;
> > +       encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
> > +       connector->connector_type = DRM_MODE_CONNECTOR_DVID;
> > 
> > -               if (intel_sdvo_get_supp_encode(intel_output,
> > -                                              &sdvo_priv->encode) &&
> > -                   intel_sdvo_get_digital_encoding_mode(intel_output) &&
> > -                   sdvo_priv->is_hdmi) {
> > +       if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_encoder->encode)
> > +               && intel_sdvo_get_digital_encoding_mode(intel_encoder)
> > +               && sdvo_encoder->has_hdmi) {
> >                         /* enable hdmi encoding mode if supported */
> > -                       intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
> > -                       intel_sdvo_set_colorimetry(intel_output,
> > +                       intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
> > +                       intel_sdvo_set_colorimetry(intel_encoder,
> >                                                    SDVO_COLORIMETRY_RGB256);
> >                         connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
> > -                       intel_output->clone_mask =
> > -                                       (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > -                                       (1 << INTEL_ANALOG_CLONE_BIT);
> >                 }
> > -       } else if (flags & SDVO_OUTPUT_SVID0) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
> > -               sdvo_priv->is_tv = true;
> > -               intel_output->needs_tv_clock = true;
> > -               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
> > -       } else if (flags & SDVO_OUTPUT_RGB0) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_DAC;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_VGA;
> > -               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > -                                       (1 << INTEL_ANALOG_CLONE_BIT);
> > -       } else if (flags & SDVO_OUTPUT_RGB1) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_DAC;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_VGA;
> > -               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > -                                       (1 << INTEL_ANALOG_CLONE_BIT);
> > -       } else if (flags & SDVO_OUTPUT_CVBS0) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
> > -               sdvo_priv->is_tv = true;
> > -               intel_output->needs_tv_clock = true;
> > -               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
> > -       } else if (flags & SDVO_OUTPUT_LVDS0) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
> > -               sdvo_priv->is_lvds = true;
> > -               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
> > -                                       (1 << INTEL_SDVO_LVDS_CLONE_BIT);
> > -       } else if (flags & SDVO_OUTPUT_LVDS1) {
> > -
> > -               sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
> > -               encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
> > -               connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
> > -               sdvo_priv->is_lvds = true;
> > -               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
> > -                                       (1 << INTEL_SDVO_LVDS_CLONE_BIT);
> > -       } else {
> > 
> > +       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > +                                   (1 << INTEL_ANALOG_CLONE_BIT);
> > +
> > +       intel_sdvo_connector_create(encoder, connector);
> > +
> > +       return true;
> > +}
> > +
> > +static bool
> > +intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type)
> > +{
> > +       struct drm_encoder *encoder = &intel_encoder->base;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct drm_connector *connector;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_sdvo_connector *sdvo_connector;
> > +
> > +       if (!intel_sdvo_connector_alloc(encoder->dev, &intel_connector))
> > +               return false;
> > +
> > +       connector = &intel_connector->base;
> > +       encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
> > +       connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
> > +       sdvo_connector = intel_connector->dev_priv;
> > +
> > +       sdvo_encoder->controlled_output |= type;
> > +       sdvo_connector->output_flag = type;
> > +
> > +       sdvo_encoder->has_tv = true;
> > +       intel_encoder->needs_tv_clock = true;
> > +       intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
> > +
> > +       intel_sdvo_connector_create(encoder, connector);
> > +
> > +       intel_sdvo_tv_create_property(encoder, connector);
> > +
> > +       intel_sdvo_create_enhance_property(encoder, connector);
> > +
> > +       return true;
> > +}
> > +
> > +static bool
> > +intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device)
> > +{
> > +       struct drm_encoder *encoder = &intel_encoder->base;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct drm_connector *connector;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_sdvo_connector *sdvo_connector;
> > +
> > +       if (!intel_sdvo_connector_alloc(encoder->dev, &intel_connector))
> > +               return false;
> > +
> > +       connector = &intel_connector->base;
> > +       encoder->encoder_type = DRM_MODE_ENCODER_DAC;
> > +       connector->connector_type = DRM_MODE_CONNECTOR_VGA;
> > +       sdvo_connector = intel_connector->dev_priv;
> > +
> > +       if (device == 0) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_RGB0;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
> > +       } else if (device == 1) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_RGB1;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
> > +       }
> > +
> > +       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
> > +                                   (1 << INTEL_ANALOG_CLONE_BIT);
> > +
> > +       intel_sdvo_connector_create(encoder, connector);
> > +       return true;
> > +}
> > +
> > +static bool
> > +intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device)
> > +{
> > +       struct drm_encoder *encoder = &intel_encoder->base;
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct drm_connector *connector;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_sdvo_connector *sdvo_connector;
> > +
> > +       if (!intel_sdvo_connector_alloc(encoder->dev, &intel_connector))
> > +               return false;
> > +
> > +       connector = &intel_connector->base;
> > +       encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
> > +       connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
> > +       sdvo_connector = intel_connector->dev_priv;
> > +
> > +       sdvo_encoder->has_lvds = true;
> > +
> > +       if (device == 0) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_LVDS0;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
> > +       } else if (device == 1) {
> > +               sdvo_encoder->controlled_output |= SDVO_OUTPUT_LVDS1;
> > +               sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
> > +       }
> > +
> > +       intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
> > +                                   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
> > +
> > +       intel_sdvo_connector_create(encoder, connector);
> > +       intel_sdvo_create_enhance_property(encoder, connector);
> > +       return true;
> > +}
> > +
> > +#define SDVO_DVI_MASK  (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
> > +#define SDVO_RGB_MASK  (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
> > +#define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)
> > +
> > +#define SDVO_OUTPUT_MASK (SDVO_OUTPUT_TMDS0 | \
> > +                         SDVO_OUTPUT_RGB0  | \
> > +                         SDVO_OUTPUT_CVBS0 | \
> > +                         SDVO_OUTPUT_SVID0 | \
> > +                         SDVO_OUTPUT_LVDS0 | \
> > +                         SDVO_OUTPUT_TMDS1 | \
> > +                         SDVO_OUTPUT_RGB1 | \
> > +                         SDVO_OUTPUT_LVDS1)
> > +
> > +static bool
> > +intel_sdvo_output_setup(struct intel_encoder *intel_encoder)
> > +{
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       int flags = sdvo_encoder->caps.output_flags;
> > +
> > +       intel_encoder->needs_tv_clock = false;
> > +       sdvo_encoder->has_tv = false;
> > +       sdvo_encoder->has_lvds = false;
> > +
> > +       /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
> > +
> > +       if (flags & SDVO_OUTPUT_TMDS0)
> > +               if (!intel_sdvo_dvi_init(intel_encoder, 0))
> > +                       return false;
> > +
> > +       if ((flags & SDVO_DVI_MASK) == SDVO_DVI_MASK)
> > +               if (!intel_sdvo_dvi_init(intel_encoder, 1))
> > +                       return false;
> > +
> > +       /* TV has no XXX1 function block */
> > +       if (flags & SDVO_OUTPUT_SVID0)
> > +               if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0))
> > +                       return false;
> > +
> > +       if (flags & SDVO_OUTPUT_CVBS0)
> > +               if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0))
> > +                       return false;
> > +
> > +       if (flags & SDVO_OUTPUT_RGB0)
> > +               if (!intel_sdvo_analog_init(intel_encoder, 0))
> > +                       return false;
> > +
> > +       if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
> > +               if (!intel_sdvo_analog_init(intel_encoder, 1))
> > +                       return false;
> > +
> > +       if (flags & SDVO_OUTPUT_LVDS0)
> > +               if (!intel_sdvo_lvds_init(intel_encoder, 0))
> > +                       return false;
> > +
> > +       if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
> > +               if (!intel_sdvo_lvds_init(intel_encoder, 1))
> > +                       return false;
> > +
> > +       if ((flags & SDVO_OUTPUT_MASK) == 0)
> > +       {
> >                 unsigned char bytes[2];
> > 
> > -               sdvo_priv->controlled_output = 0;
> > -               memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
> > +               sdvo_encoder->controlled_output = 0;
> > +               memcpy(bytes, &sdvo_encoder->caps.output_flags, 2);
> >                 DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
> > -                             SDVO_NAME(sdvo_priv),
> > +                             SDVO_NAME(sdvo_encoder),
> >                               bytes[0], bytes[1]);
> > -               ret = false;
> > +               return false;
> >         }
> > -       intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > 
> > -       if (ret && registered)
> > -               ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
> > +       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> > 
> > -
> > -       return ret;
> > +       return true;
> > 
> >  }
> > 
> > -static void intel_sdvo_tv_create_property(struct drm_connector *connector)
> > +static void intel_sdvo_tv_create_property(struct drm_encoder *encoder,
> > +                                         struct drm_connector *connector)
> >  {
> > -      struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> >         struct intel_sdvo_tv_format format;
> >         uint32_t format_map, i;
> >         uint8_t status;
> > 
> > -       intel_sdvo_set_target_output(intel_output,
> > -                                    sdvo_priv->controlled_output);
> > +       intel_sdvo_set_target_output(intel_encoder,
> > +                                    sdvo_encoder->controlled_output);
> > 
> > -       intel_sdvo_write_cmd(intel_output,
> > +       intel_sdvo_write_cmd(intel_encoder,
> >                              SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output,
> > +       status = intel_sdvo_read_response(intel_encoder,
> >                                           &format, sizeof(format));
> >         if (status != SDVO_CMD_STATUS_SUCCESS)
> >                 return;
> > @@ -2414,43 +2602,46 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)
> >         if (format_map == 0)
> >                 return;
> > 
> > -       sdvo_priv->format_supported_num = 0;
> > +       sdvo_connector->format_supported_num = 0;
> >         for (i = 0 ; i < TV_FORMAT_NUM; i++)
> >                 if (format_map & (1 << i)) {
> > -                       sdvo_priv->tv_format_supported
> > -                       [sdvo_priv->format_supported_num++] =
> > +                       sdvo_connector->tv_format_supported
> > +                       [sdvo_connector->format_supported_num++] =
> >                         tv_format_names[i];
> >                 }
> > 
> > 
> > -       sdvo_priv->tv_format_property =
> > +       sdvo_connector->tv_format_property =
> >                         drm_property_create(
> >                                 connector->dev, DRM_MODE_PROP_ENUM,
> > -                               "mode", sdvo_priv->format_supported_num);
> > +                               "mode", sdvo_connector->format_supported_num);
> > 
> > -       for (i = 0; i < sdvo_priv->format_supported_num; i++)
> > +       for (i = 0; i < sdvo_connector->format_supported_num; i++)
> >                 drm_property_add_enum(
> > -                               sdvo_priv->tv_format_property, i,
> > -                               i, sdvo_priv->tv_format_supported[i]);
> > +                               sdvo_connector->tv_format_property, i,
> > +                               i, sdvo_connector->tv_format_supported[i]);
> > 
> > -       sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0];
> > +       sdvo_encoder->tv_format_name = sdvo_connector->tv_format_supported[0];
> >         drm_connector_attach_property(
> > -                       connector, sdvo_priv->tv_format_property, 0);
> > +                       connector, sdvo_connector->tv_format_property, 0);
> > 
> >  }
> > 
> > -static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
> > +static void intel_sdvo_create_enhance_property(struct drm_encoder *encoder,
> > +                                              struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_connector *intel_connector = to_intel_connector(connector);
> > +       struct intel_sdvo_encoder *sdvo_encoder = intel_encoder->dev_priv;
> > +       struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
> >         struct intel_sdvo_enhancements_reply sdvo_data;
> >         struct drm_device *dev = connector->dev;
> >         uint8_t status;
> >         uint16_t response, data_value[2];
> > 
> > -       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
> > +       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
> >                                                 NULL, 0);
> > -       status = intel_sdvo_read_response(intel_output, &sdvo_data,
> > +       status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
> >                                         sizeof(sdvo_data));
> >         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                 DRM_DEBUG_KMS(" incorrect response is returned\n");
> > @@ -2461,280 +2652,280 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
> >                 DRM_DEBUG_KMS("No enhancement is supported\n");
> >                 return;
> >         }
> > -       if (sdvo_priv->is_tv) {
> > +       if (sdvo_encoder->has_tv) {
> >                 /* when horizontal overscan is supported, Add the left/right
> >                  * property
> >                  */
> >                 if (sdvo_data.overscan_h) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO max "
> >                                                 "h_overscan\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_hscan = data_value[0];
> > -                       sdvo_priv->left_margin = data_value[0] - response;
> > -                       sdvo_priv->right_margin = sdvo_priv->left_margin;
> > -                       sdvo_priv->left_property =
> > +                       sdvo_connector->max_hscan = data_value[0];
> > +                       sdvo_connector->left_margin = data_value[0] - response;
> > +                       sdvo_connector->right_margin = sdvo_connector->left_margin;
> > +                       sdvo_connector->left_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "left_margin", 2);
> > -                       sdvo_priv->left_property->values[0] = 0;
> > -                       sdvo_priv->left_property->values[1] = data_value[0];
> > +                       sdvo_connector->left_property->values[0] = 0;
> > +                       sdvo_connector->left_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->left_property,
> > -                                               sdvo_priv->left_margin);
> > -                       sdvo_priv->right_property =
> > +                                               sdvo_connector->left_property,
> > +                                               sdvo_connector->left_margin);
> > +                       sdvo_connector->right_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "right_margin", 2);
> > -                       sdvo_priv->right_property->values[0] = 0;
> > -                       sdvo_priv->right_property->values[1] = data_value[0];
> > +                       sdvo_connector->right_property->values[0] = 0;
> > +                       sdvo_connector->right_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->right_property,
> > -                                               sdvo_priv->right_margin);
> > +                                               sdvo_connector->right_property,
> > +                                               sdvo_connector->right_margin);
> >                         DRM_DEBUG_KMS("h_overscan: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >                 if (sdvo_data.overscan_v) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO max "
> >                                                 "v_overscan\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_vscan = data_value[0];
> > -                       sdvo_priv->top_margin = data_value[0] - response;
> > -                       sdvo_priv->bottom_margin = sdvo_priv->top_margin;
> > -                       sdvo_priv->top_property =
> > +                       sdvo_connector->max_vscan = data_value[0];
> > +                       sdvo_connector->top_margin = data_value[0] - response;
> > +                       sdvo_connector->bottom_margin = sdvo_connector->top_margin;
> > +                       sdvo_connector->top_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "top_margin", 2);
> > -                       sdvo_priv->top_property->values[0] = 0;
> > -                       sdvo_priv->top_property->values[1] = data_value[0];
> > +                       sdvo_connector->top_property->values[0] = 0;
> > +                       sdvo_connector->top_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->top_property,
> > -                                               sdvo_priv->top_margin);
> > -                       sdvo_priv->bottom_property =
> > +                                               sdvo_connector->top_property,
> > +                                               sdvo_connector->top_margin);
> > +                       sdvo_connector->bottom_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "bottom_margin", 2);
> > -                       sdvo_priv->bottom_property->values[0] = 0;
> > -                       sdvo_priv->bottom_property->values[1] = data_value[0];
> > +                       sdvo_connector->bottom_property->values[0] = 0;
> > +                       sdvo_connector->bottom_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->bottom_property,
> > -                                               sdvo_priv->bottom_margin);
> > +                                               sdvo_connector->bottom_property,
> > +                                               sdvo_connector->bottom_margin);
> >                         DRM_DEBUG_KMS("v_overscan: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >                 if (sdvo_data.position_h) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_POSITION_H, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_hpos = data_value[0];
> > -                       sdvo_priv->cur_hpos = response;
> > -                       sdvo_priv->hpos_property =
> > +                       sdvo_connector->max_hpos = data_value[0];
> > +                       sdvo_connector->cur_hpos = response;
> > +                       sdvo_connector->hpos_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "hpos", 2);
> > -                       sdvo_priv->hpos_property->values[0] = 0;
> > -                       sdvo_priv->hpos_property->values[1] = data_value[0];
> > +                       sdvo_connector->hpos_property->values[0] = 0;
> > +                       sdvo_connector->hpos_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->hpos_property,
> > -                                               sdvo_priv->cur_hpos);
> > +                                               sdvo_connector->hpos_property,
> > +                                               sdvo_connector->cur_hpos);
> >                         DRM_DEBUG_KMS("h_position: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >                 if (sdvo_data.position_v) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_POSITION_V, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_vpos = data_value[0];
> > -                       sdvo_priv->cur_vpos = response;
> > -                       sdvo_priv->vpos_property =
> > +                       sdvo_connector->max_vpos = data_value[0];
> > +                       sdvo_connector->cur_vpos = response;
> > +                       sdvo_connector->vpos_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "vpos", 2);
> > -                       sdvo_priv->vpos_property->values[0] = 0;
> > -                       sdvo_priv->vpos_property->values[1] = data_value[0];
> > +                       sdvo_connector->vpos_property->values[0] = 0;
> > +                       sdvo_connector->vpos_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->vpos_property,
> > -                                               sdvo_priv->cur_vpos);
> > +                                               sdvo_connector->vpos_property,
> > +                                               sdvo_connector->cur_vpos);
> >                         DRM_DEBUG_KMS("v_position: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> > -       }
> > -       if (sdvo_priv->is_tv) {
> > +
> >                 if (sdvo_data.saturation) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_SATURATION, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_saturation = data_value[0];
> > -                       sdvo_priv->cur_saturation = response;
> > -                       sdvo_priv->saturation_property =
> > +                       sdvo_connector->max_saturation = data_value[0];
> > +                       sdvo_connector->cur_saturation = response;
> > +                       sdvo_connector->saturation_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "saturation", 2);
> > -                       sdvo_priv->saturation_property->values[0] = 0;
> > -                       sdvo_priv->saturation_property->values[1] =
> > +                       sdvo_connector->saturation_property->values[0] = 0;
> > +                       sdvo_connector->saturation_property->values[1] =
> >                                                         data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->saturation_property,
> > -                                               sdvo_priv->cur_saturation);
> > +                                               sdvo_connector->saturation_property,
> > +                                               sdvo_connector->cur_saturation);
> >                         DRM_DEBUG_KMS("saturation: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >                 if (sdvo_data.contrast) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_CONTRAST, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_contrast = data_value[0];
> > -                       sdvo_priv->cur_contrast = response;
> > -                       sdvo_priv->contrast_property =
> > +                       sdvo_connector->max_contrast = data_value[0];
> > +                       sdvo_connector->cur_contrast = response;
> > +                       sdvo_connector->contrast_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "contrast", 2);
> > -                       sdvo_priv->contrast_property->values[0] = 0;
> > -                       sdvo_priv->contrast_property->values[1] = data_value[0];
> > +                       sdvo_connector->contrast_property->values[0] = 0;
> > +                       sdvo_connector->contrast_property->values[1] = data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->contrast_property,
> > -                                               sdvo_priv->cur_contrast);
> > +                                               sdvo_connector->contrast_property,
> > +                                               sdvo_connector->cur_contrast);
> >                         DRM_DEBUG_KMS("contrast: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >                 if (sdvo_data.hue) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_HUE, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_HUE, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_hue = data_value[0];
> > -                       sdvo_priv->cur_hue = response;
> > -                       sdvo_priv->hue_property =
> > +                       sdvo_connector->max_hue = data_value[0];
> > +                       sdvo_connector->cur_hue = response;
> > +                       sdvo_connector->hue_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "hue", 2);
> > -                       sdvo_priv->hue_property->values[0] = 0;
> > -                       sdvo_priv->hue_property->values[1] =
> > +                       sdvo_connector->hue_property->values[0] = 0;
> > +                       sdvo_connector->hue_property->values[1] =
> >                                                         data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->hue_property,
> > -                                               sdvo_priv->cur_hue);
> > +                                               sdvo_connector->hue_property,
> > +                                               sdvo_connector->cur_hue);
> >                         DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> >                 }
> >         }
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
> > +
> > +       if (sdvo_encoder->has_tv || sdvo_encoder->has_lvds) {
> >                 if (sdvo_data.brightness) {
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &data_value, 4);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
> >                                 return;
> >                         }
> > -                       intel_sdvo_write_cmd(intel_output,
> > +                       intel_sdvo_write_cmd(intel_encoder,
> >                                 SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
> > -                       status = intel_sdvo_read_response(intel_output,
> > +                       status = intel_sdvo_read_response(intel_encoder,
> >                                 &response, 2);
> >                         if (status != SDVO_CMD_STATUS_SUCCESS) {
> >                                 DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
> >                                 return;
> >                         }
> > -                       sdvo_priv->max_brightness = data_value[0];
> > -                       sdvo_priv->cur_brightness = response;
> > -                       sdvo_priv->brightness_property =
> > +                       sdvo_connector->max_brightness = data_value[0];
> > +                       sdvo_connector->cur_brightness = response;
> > +                       sdvo_connector->brightness_property =
> >                                 drm_property_create(dev, DRM_MODE_PROP_RANGE,
> >                                                 "brightness", 2);
> > -                       sdvo_priv->brightness_property->values[0] = 0;
> > -                       sdvo_priv->brightness_property->values[1] =
> > +                       sdvo_connector->brightness_property->values[0] = 0;
> > +                       sdvo_connector->brightness_property->values[1] =
> >                                                         data_value[0];
> >                         drm_connector_attach_property(connector,
> > -                                               sdvo_priv->brightness_property,
> > -                                               sdvo_priv->cur_brightness);
> > +                                               sdvo_connector->brightness_property,
> > +                                               sdvo_connector->cur_brightness);
> >                         DRM_DEBUG_KMS("brightness: max %d, "
> >                                         "default %d, current %d\n",
> >                                         data_value[0], data_value[1], response);
> > @@ -2746,138 +2937,96 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
> >  bool intel_sdvo_init(struct drm_device *dev, int output_device)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > -       struct intel_sdvo_priv *sdvo_priv;
> > -
> > +       struct intel_encoder *intel_encoder;
> > +       struct intel_sdvo_encoder *sdvo_encoder;
> > +       struct drm_encoder *encoder;
> >         u8 ch[0x40];
> >         int i;
> > 
> > -       intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
> > -       if (!intel_output) {
> > -               return false;
> > -       }
> > +       intel_encoder = kzalloc(sizeof(*intel_encoder) + sizeof(*sdvo_encoder), GFP_KERNEL);
> > 
> > -       sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
> > -       sdvo_priv->output_device = output_device;
> > +       if (!intel_encoder)
> > +               return false;
> > 
> > -       intel_output->dev_priv = sdvo_priv;
> > -       intel_output->type = INTEL_OUTPUT_SDVO;
> > +       intel_encoder->type = INTEL_OUTPUT_SDVO;
> > +       sdvo_encoder = (struct intel_sdvo_encoder *)(intel_encoder + 1);
> > +       intel_encoder->dev_priv = sdvo_encoder;
> > 
> >         /* setup the DDC bus. */
> >         if (output_device == SDVOB)
> > -               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
> > +               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
> >         else
> > -               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
> > +               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
> > 
> > -       if (!intel_output->i2c_bus)
> > -               goto err_inteloutput;
> > +       if (!intel_encoder->i2c_bus)
> > +               goto err;
> > 
> > -       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
> > +       sdvo_encoder->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
> > +       sdvo_encoder->output_device = output_device;
> > 
> >         /* Save the bit-banging i2c functionality for use by the DDC wrapper */
> > -       intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
> > +       intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
> > 
> >         /* Read the regs to test if we can talk to the device */
> >         for (i = 0; i < 0x40; i++) {
> > -               if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
> > +               if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
> >                         DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
> >                                         output_device == SDVOB ? 'B' : 'C');
> > -                       goto err_i2c;
> > +                       goto err;
> >                 }
> >         }
> > 
> > -       /* setup the DDC bus. */
> > -       if (output_device == SDVOB) {
> > -               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
> > -               sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
> > -                                               "SDVOB/VGA DDC BUS");
> > +       if (output_device == SDVOB)
> >                 dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
> > -       } else {
> > -               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
> > -               sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
> > -                                               "SDVOC/VGA DDC BUS");
> > +       else
> >                 dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
> > -       }
> > 
> > -       if (intel_output->ddc_bus == NULL)
> > -               goto err_i2c;
> > +       encoder = &intel_encoder->base;
> > 
> > -       /* Wrap with our custom algo which switches to DDC mode */
> > -       intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
> > +       /* encoder type will be decided later */
> > +       drm_encoder_init(dev, encoder, &intel_sdvo_enc_funcs, 0);
> > 
> > -       /* In default case sdvo lvds is false */
> > -       intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
> > +       drm_encoder_helper_add(encoder, &intel_sdvo_helper_funcs);
> > 
> > -       if (intel_sdvo_output_setup(intel_output,
> > -                                   sdvo_priv->caps.output_flags) != true) {
> > +       intel_sdvo_get_capabilities(intel_encoder, &sdvo_encoder->caps);
> > +
> > +       if (!intel_sdvo_output_setup(intel_encoder)) {
> >                 DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
> >                           output_device == SDVOB ? 'B' : 'C');
> > -               goto err_i2c;
> > +               goto err;
> >         }
> > 
> > -
> > -       connector = &intel_output->base;
> > -       drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
> > -                          connector->connector_type);
> > -
> > -       drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
> > -       connector->interlace_allowed = 0;
> > -       connector->doublescan_allowed = 0;
> > -       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
> > -
> > -       drm_encoder_init(dev, &intel_output->enc,
> > -                       &intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
> > -
> > -       drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
> > -
> > -       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
> > -       if (sdvo_priv->is_tv)
> > -               intel_sdvo_tv_create_property(connector);
> > -
> > -       if (sdvo_priv->is_tv || sdvo_priv->is_lvds)
> > -               intel_sdvo_create_enhance_property(connector);
> > -
> > -       drm_sysfs_connector_add(connector);
> > -
> > -       intel_sdvo_select_ddc_bus(sdvo_priv);
> > +       intel_sdvo_select_ddc_bus(sdvo_encoder);
> > 
> >         /* Set the input timing to the screen. Assume always input 0. */
> > -       intel_sdvo_set_target_input(intel_output, true, false);
> > +       intel_sdvo_set_target_input(intel_encoder, true, false);
> > 
> > -       intel_sdvo_get_input_pixel_clock_range(intel_output,
> > -                                              &sdvo_priv->pixel_clock_min,
> > -                                              &sdvo_priv->pixel_clock_max);
> > +       intel_sdvo_get_input_pixel_clock_range(intel_encoder,
> > +                                              &sdvo_encoder->pixel_clock_min,
> > +                                              &sdvo_encoder->pixel_clock_max);
> > 
> > 
> >         DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
> >                         "clock range %dMHz - %dMHz, "
> >                         "input 1: %c, input 2: %c, "
> >                         "output 1: %c, output 2: %c\n",
> > -                       SDVO_NAME(sdvo_priv),
> > -                       sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
> > -                       sdvo_priv->caps.device_rev_id,
> > -                       sdvo_priv->pixel_clock_min / 1000,
> > -                       sdvo_priv->pixel_clock_max / 1000,
> > -                       (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
> > -                       (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
> > +                       SDVO_NAME(sdvo_encoder),
> > +                       sdvo_encoder->caps.vendor_id, sdvo_encoder->caps.device_id,
> > +                       sdvo_encoder->caps.device_rev_id,
> > +                       sdvo_encoder->pixel_clock_min / 1000,
> > +                       sdvo_encoder->pixel_clock_max / 1000,
> > +                       (sdvo_encoder->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
> > +                       (sdvo_encoder->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
> >                         /* check currently supported outputs */
> > -                       sdvo_priv->caps.output_flags &
> > +                       sdvo_encoder->caps.output_flags &
> >                         (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
> > -                       sdvo_priv->caps.output_flags &
> > +                       sdvo_encoder->caps.output_flags &
> >                         (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
> > 
> >         return true;
> > 
> > -err_i2c:
> > -       if (sdvo_priv->analog_ddc_bus != NULL)
> > -               intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
> > -       if (intel_output->ddc_bus != NULL)
> > -               intel_i2c_destroy(intel_output->ddc_bus);
> > -       if (intel_output->i2c_bus != NULL)
> > -               intel_i2c_destroy(intel_output->i2c_bus);
> > -err_inteloutput:
> > -       kfree(intel_output);
> > +err:
> > +       kfree(intel_encoder);
> > 
> >         return false;
> >  }
> > diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
> > index 552ec11..b54e40c 100644
> > --- a/drivers/gpu/drm/i915/intel_tv.c
> > +++ b/drivers/gpu/drm/i915/intel_tv.c
> > @@ -921,8 +921,9 @@ intel_tv_save(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> >         int i;
> > 
> >         tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
> > @@ -971,8 +972,9 @@ intel_tv_restore(struct drm_connector *connector)
> >  {
> >         struct drm_device *dev = connector->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> >         struct drm_crtc *crtc = connector->encoder->crtc;
> >         struct intel_crtc *intel_crtc;
> >         int i;
> > @@ -1068,9 +1070,9 @@ intel_tv_mode_lookup (char *tv_format)
> >  }
> > 
> >  static const struct tv_mode *
> > -intel_tv_mode_find (struct intel_output *intel_output)
> > +intel_tv_mode_find (struct intel_encoder *intel_encoder)
> >  {
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> > 
> >         return intel_tv_mode_lookup(tv_priv->tv_format);
> >  }
> > @@ -1078,8 +1080,9 @@ intel_tv_mode_find (struct intel_output *intel_output)
> >  static enum drm_mode_status
> >  intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
> > 
> >         /* Ensure TV refresh is close to desired refresh */
> >         if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
> > @@ -1095,8 +1098,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >  {
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_mode_config *drm_config = &dev->mode_config;
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
> >         struct drm_encoder *other_encoder;
> > 
> >         if (!tv_mode)
> > @@ -1121,9 +1124,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> > -       struct intel_output *intel_output = enc_to_intel_output(encoder);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
> >         u32 tv_ctl;
> >         u32 hctl1, hctl2, hctl3;
> >         u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
> > @@ -1360,9 +1363,8 @@ static const struct drm_display_mode reported_modes[] = {
> >   * \return false if TV is disconnected.
> >   */
> >  static int
> > -intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
> > +intel_tv_detect_type (struct drm_crtc *crtc, struct drm_encoder *encoder)
> >  {
> > -       struct drm_encoder *encoder = &intel_output->enc;
> >         struct drm_device *dev = encoder->dev;
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         unsigned long irqflags;
> > @@ -1439,11 +1441,12 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
> >   * Here we set accurate tv format according to connector type
> >   * i.e Component TV should not be assigned by NTSC or PAL
> >   */
> > -static void intel_tv_find_better_format(struct drm_connector *connector)
> > +static void intel_tv_find_better_format(struct drm_encoder *encoder,
> > +                                       struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
> >         int i;
> > 
> >         if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
> > @@ -1475,9 +1478,9 @@ intel_tv_detect(struct drm_connector *connector)
> >  {
> >         struct drm_crtc *crtc;
> >         struct drm_display_mode mode;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> >         int dpms_mode;
> >         int type = tv_priv->type;
> > 
> > @@ -1485,12 +1488,12 @@ intel_tv_detect(struct drm_connector *connector)
> >         drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
> > 
> >         if (encoder->crtc && encoder->crtc->enabled) {
> > -               type = intel_tv_detect_type(encoder->crtc, intel_output);
> > +               type = intel_tv_detect_type(encoder->crtc, encoder);
> >         } else {
> > -               crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
> > +               crtc = intel_get_load_detect_pipe(connector, &mode, &dpms_mode);
> >                 if (crtc) {
> > -                       type = intel_tv_detect_type(crtc, intel_output);
> > -                       intel_release_load_detect_pipe(intel_output, dpms_mode);
> > +                       type = intel_tv_detect_type(crtc, encoder);
> > +                       intel_release_load_detect_pipe(connector, dpms_mode);
> >                 } else
> >                         type = -1;
> >         }
> > @@ -1500,7 +1503,7 @@ intel_tv_detect(struct drm_connector *connector)
> >         if (type < 0)
> >                 return connector_status_disconnected;
> > 
> > -       intel_tv_find_better_format(connector);
> > +       intel_tv_find_better_format(encoder, connector);
> >         return connector_status_connected;
> >  }
> > 
> > @@ -1522,11 +1525,11 @@ static struct input_res {
> >   * Chose preferred mode  according to line number of TV format
> >   */
> >  static void
> > -intel_tv_chose_preferred_modes(struct drm_connector *connector,
> > +intel_tv_chose_preferred_modes(struct drm_encoder *encoder,
> >                                struct drm_display_mode *mode_ptr)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
> > 
> >         if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
> >                 mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
> > @@ -1550,8 +1553,9 @@ static int
> >  intel_tv_get_modes(struct drm_connector *connector)
> >  {
> >         struct drm_display_mode *mode_ptr;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
> >         int j, count = 0;
> >         u64 tmp;
> > 
> > @@ -1593,7 +1597,7 @@ intel_tv_get_modes(struct drm_connector *connector)
> >                 mode_ptr->clock = (int) tmp;
> > 
> >                 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
> > -               intel_tv_chose_preferred_modes(connector, mode_ptr);
> > +               intel_tv_chose_preferred_modes(encoder, mode_ptr);
> >                 drm_mode_probed_add(connector, mode_ptr);
> >                 count++;
> >         }
> > @@ -1604,11 +1608,9 @@ intel_tv_get_modes(struct drm_connector *connector)
> >  static void
> >  intel_tv_destroy (struct drm_connector *connector)
> >  {
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -
> >         drm_sysfs_connector_remove(connector);
> >         drm_connector_cleanup(connector);
> > -       kfree(intel_output);
> > +       kfree(connector);
> >  }
> > 
> > 
> > @@ -1617,9 +1619,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
> >                       uint64_t val)
> >  {
> >         struct drm_device *dev = connector->dev;
> > -       struct intel_output *intel_output = to_intel_output(connector);
> > -       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
> > -       struct drm_encoder *encoder = &intel_output->enc;
> > +       struct drm_encoder *encoder = intel_best_encoder(connector);
> > +       struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
> > +       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
> >         struct drm_crtc *crtc = encoder->crtc;
> >         int ret = 0;
> >         bool changed = false;
> > @@ -1693,6 +1695,7 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs =
> >  static void intel_tv_enc_destroy(struct drm_encoder *encoder)
> >  {
> >         drm_encoder_cleanup(encoder);
> > +       kfree(encoder);
> >  }
> > 
> >  static const struct drm_encoder_funcs intel_tv_enc_funcs = {
> > @@ -1740,7 +1743,9 @@ intel_tv_init(struct drm_device *dev)
> >  {
> >         struct drm_i915_private *dev_priv = dev->dev_private;
> >         struct drm_connector *connector;
> > -       struct intel_output *intel_output;
> > +       struct drm_encoder *encoder;
> > +       struct intel_connector *intel_connector;
> > +       struct intel_encoder *intel_encoder;
> >         struct intel_tv_priv *tv_priv;
> >         u32 tv_dac_on, tv_dac_off, save_tv_dac;
> >         char **tv_format_names;
> > @@ -1780,28 +1785,29 @@ intel_tv_init(struct drm_device *dev)
> >             (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
> >                 return;
> > 
> > -       intel_output = kzalloc(sizeof(struct intel_output) +
> > -                              sizeof(struct intel_tv_priv), GFP_KERNEL);
> > -       if (!intel_output) {
> > +       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
> > +       intel_encoder = kzalloc(sizeof(*intel_encoder) + sizeof(*tv_priv), GFP_KERNEL);
> > +       if (!intel_connector || !intel_encoder)
> >                 return;
> > -       }
> > 
> > -       connector = &intel_output->base;
> > +       connector = &intel_connector->base;
> > +       encoder = &intel_encoder->base;
> > +       intel_encoder->connector = intel_connector;
> > 
> >         drm_connector_init(dev, connector, &intel_tv_connector_funcs,
> >                            DRM_MODE_CONNECTOR_SVIDEO);
> > 
> > -       drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
> > +       drm_encoder_init(dev, encoder, &intel_tv_enc_funcs,
> >                          DRM_MODE_ENCODER_TVDAC);
> > 
> > -       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
> > -       tv_priv = (struct intel_tv_priv *)(intel_output + 1);
> > -       intel_output->type = INTEL_OUTPUT_TVOUT;
> > -       intel_output->crtc_mask = (1 << 0) | (1 << 1);
> > -       intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
> > -       intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
> > -       intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
> > -       intel_output->dev_priv = tv_priv;
> > +       drm_mode_connector_attach_encoder(connector, encoder);
> > +       tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
> > +       intel_encoder->type = INTEL_OUTPUT_TVOUT;
> > +       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
> > +       intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
> > +       encoder->possible_crtcs = ((1 << 0) | (1 << 1));
> > +       encoder->possible_clones = (1 << INTEL_OUTPUT_TVOUT);
> > +       intel_encoder->dev_priv = tv_priv;
> >         tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
> > 
> >         /* BIOS margin values */
> > @@ -1812,7 +1818,7 @@ intel_tv_init(struct drm_device *dev)
> > 
> >         tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
> > 
> > -       drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
> > +       drm_encoder_helper_add(encoder, &intel_tv_helper_funcs);
> >         drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
> >         connector->interlace_allowed = false;
> >         connector->doublescan_allowed = false;
> > --
> > 1.7.0
> > 

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20100302/351d5580/attachment.sig>


More information about the Intel-gfx mailing list