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

ykzhao yakui.zhao at intel.com
Tue Mar 2 04:01:41 CET 2010


On Tue, 2010-03-02 at 10:48 +0800, Fu, Michael wrote:
> Zhenyu Wang wrote:
> > 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.
> 
> Hmm.. I doubt if more than one of CVBS/COMP/SVID could work simultaneously, even though there is a kind of SDVO TV card that have these 3 interfaces. blending them together as one connector called TV may be better. Just like the intgegrated TV, even though sometimes we can see more than one built-in connector ( 80% only have one external connector though ), they can't work at the same time.

I agree. It seems that the SDVO-TV card can report its capability that
it can support CVBS/SVIDE/COMP. As they use the same SDVO-TV encoder,
maybe they can't work simultaneously.

At most cases the SDVO-DVI card will export only one external connector.
Even when it can export more than one connector, the two connectors
can't work simultaneously as one SDVO encoder is shared by the two
connectors.

> >
> >>         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 *




More information about the Intel-gfx mailing list