From 890f3359f7b84d7015104360d647ccac5f515542 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Sep 2010 16:46:59 +0100 Subject: [PATCH] drm/i915/i2c: Track the parent encoder rather than just the dev The SDVO proxy i2c adapter wants to be able to use information stored in the encoder, so pass that through intel_i2c rather than iterate over all known encoders every time. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_crt.c | 9 ++--- drivers/gpu/drm/i915/intel_drv.h | 5 ++- drivers/gpu/drm/i915/intel_dvo.c | 9 +++-- drivers/gpu/drm/i915/intel_hdmi.c | 18 +++++---- drivers/gpu/drm/i915/intel_i2c.c | 26 ++++++++----- drivers/gpu/drm/i915/intel_lvds.c | 3 +- drivers/gpu/drm/i915/intel_sdvo.c | 62 +++++++++++++------------------ 7 files changed, 67 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index b39183bcc9f..0403ec9e164 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -445,19 +445,17 @@ static void intel_crt_destroy(struct drm_connector *connector) static int intel_crt_get_modes(struct drm_connector *connector) { - int ret; struct intel_encoder *encoder = intel_attached_encoder(connector); struct i2c_adapter *ddc_bus; struct drm_device *dev = connector->dev; - + int ret; ret = intel_ddc_get_modes(connector, encoder->ddc_bus); if (ret || !IS_G4X(dev)) goto end; /* Try to probe digital port for output in DVI-I -> VGA mode. */ - ddc_bus = intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); - + ddc_bus = intel_i2c_create(encoder, GPIOD, "CRTDDC_D"); if (!ddc_bus) { dev_printk(KERN_ERR, &connector->dev->pdev->dev, "DDC bus registration failed for CRTDDC_D.\n"); @@ -545,7 +543,8 @@ void intel_crt_init(struct drm_device *dev) if (dev_priv->crt_ddc_bus != 0) i2c_reg = dev_priv->crt_ddc_bus; } - intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + i2c_reg, "CRTDDC_A"); if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 31f072d31e3..8fe6b730c67 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -128,7 +128,7 @@ intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) } struct intel_i2c_chan { - struct drm_device *drm_dev; /* for getting at dev. private (mmio etc.) */ + struct intel_encoder *encoder; u32 reg; /* GPIO reg */ struct i2c_adapter adapter; struct i2c_algo_bit_data algo; @@ -206,7 +206,8 @@ struct intel_unpin_work { bool enable_stall_check; }; -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, +struct i2c_adapter *intel_i2c_create(struct intel_encoder *encoder, + const u32 reg, const char *name); void intel_i2c_destroy(struct i2c_adapter *adapter); int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index df42a9c9afc..7de7d1a68c0 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -362,7 +362,8 @@ void intel_dvo_init(struct drm_device *dev) intel_encoder = &intel_dvo->base; /* Set up the DDC bus */ - intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + GPIOD, "DVODDC_D"); if (!intel_encoder->ddc_bus) goto free_intel; @@ -389,10 +390,10 @@ void intel_dvo_init(struct drm_device *dev) */ if (i2cbus != NULL) intel_i2c_destroy(i2cbus); - if (!(i2cbus = intel_i2c_create(dev, gpio, - gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { + i2cbus = intel_i2c_create(intel_encoder, gpio, + gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"); + if (i2cbus == NULL) continue; - } intel_dvo->dev = *dvo; ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index bba0aba15a9..93d5b61bf5b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -243,26 +243,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) /* Set up the DDC bus. */ if (sdvox_reg == SDVOB) { intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); - intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == SDVOC) { intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); - intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIB) { intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); - intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, - "HDMIB"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + PCH_GPIOE, "HDMIB"); dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMIC) { intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); - intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, - "HDMIC"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + PCH_GPIOD, "HDMIC"); dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS; } else if (sdvox_reg == HDMID) { intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); - intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, - "HDMID"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + PCH_GPIOF, "HDMID"); dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS; } if (!intel_encoder->ddc_bus) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index de03989d6df..d3d65a9cfba 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -58,25 +58,31 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable) #define I2C_RISEFALL_TIME 20 +static inline struct drm_i915_private * +get_dev_priv(struct intel_i2c_chan *chan) +{ + return chan->encoder->base.dev->dev_private; +} + static int get_clock(void *data) { struct intel_i2c_chan *chan = data; - struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; + struct drm_i915_private *dev_priv = get_dev_priv(chan); return (I915_READ(chan->reg) & GPIO_CLOCK_VAL_IN) != 0; } static int get_data(void *data) { struct intel_i2c_chan *chan = data; - struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; + struct drm_i915_private *dev_priv = get_dev_priv(chan); return (I915_READ(chan->reg) & GPIO_DATA_VAL_IN) != 0; } static void set_clock(void *data, int state_high) { struct intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; + struct drm_i915_private *dev_priv = get_dev_priv(chan); + struct drm_device *dev = dev_priv->dev; u32 reserved = 0, clock_bits; /* On most chips, these bits must be preserved in software. */ @@ -96,8 +102,8 @@ static void set_clock(void *data, int state_high) static void set_data(void *data, int state_high) { struct intel_i2c_chan *chan = data; - struct drm_device *dev = chan->drm_dev; - struct drm_i915_private *dev_priv = chan->drm_dev->dev_private; + struct drm_i915_private *dev_priv = get_dev_priv(chan); + struct drm_device *dev = dev_priv->dev; u32 reserved = 0, data_bits; /* On most chips, these bits must be preserved in software. */ @@ -153,16 +159,18 @@ intel_i2c_reset_gmbus(struct drm_device *dev) * %GPIOH * see PRM for details on how these different busses are used. */ -struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, +struct i2c_adapter *intel_i2c_create(struct intel_encoder *encoder, + const u32 reg, const char *name) { struct intel_i2c_chan *chan; + struct drm_device *dev = encoder->base.dev; chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL); if (!chan) goto out_free; - chan->drm_dev = dev; + chan->encoder = encoder; chan->reg = reg; snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name); chan->adapter.owner = THIS_MODULE; @@ -178,7 +186,7 @@ struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, i2c_set_adapdata(&chan->adapter, chan); - if(i2c_bit_add_bus(&chan->adapter)) + if (i2c_bit_add_bus(&chan->adapter)) goto out_free; intel_i2c_reset_gmbus(dev); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b56b59236e3..2ff4a5cb2d5 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -899,7 +899,8 @@ void intel_lvds_init(struct drm_device *dev) */ /* Set up the DDC bus. */ - intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C"); + intel_encoder->ddc_bus = intel_i2c_create(intel_encoder, + gpio, "LVDSDDC_C"); if (!intel_encoder->ddc_bus) { dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " "failed.\n"); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index a812d65fa31..0e68f962256 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -184,7 +184,7 @@ struct intel_sdvo_connector { u32 cur_dot_crawl, max_dot_crawl; }; -static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) +static struct intel_sdvo *to_intel_sdvo(struct drm_encoder *encoder) { return container_of(encoder, struct intel_sdvo, base.base); } @@ -1051,7 +1051,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); + struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); int multiplier; /* We need to construct preferred input timings based on our @@ -1093,7 +1093,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); + struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); u32 sdvox; struct intel_sdvo_in_out_map in_out; struct intel_sdvo_dtd input_dtd; @@ -1200,7 +1200,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); + struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); u32 temp; @@ -1899,7 +1899,7 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) { - struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); + struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); if (intel_sdvo->analog_ddc_bus) intel_i2c_destroy(intel_sdvo->analog_ddc_bus); @@ -1984,35 +1984,15 @@ intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) &intel_sdvo->is_hdmi, 1); } -static struct intel_sdvo * -intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) -{ - struct drm_device *dev = chan->drm_dev; - struct drm_encoder *encoder; - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); - if (intel_sdvo->base.ddc_bus == &chan->adapter) - return intel_sdvo; - } - - return NULL; -} - static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct intel_sdvo *intel_sdvo; - struct i2c_algo_bit_data *algo_data; const struct i2c_algorithm *algo; - algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; - intel_sdvo = - intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) - (algo_data->data)); - if (intel_sdvo == NULL) - return -EINVAL; - + intel_sdvo = container_of(i2c_adap->algo_data, + struct intel_sdvo, + base); algo = intel_sdvo->base.i2c_bus->algo; intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); @@ -2560,9 +2540,13 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) /* setup the DDC bus. */ if (IS_SDVOB(sdvo_reg)) - intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOB"); + intel_encoder->i2c_bus = + intel_i2c_create(intel_encoder, + i2c_reg, "SDVOCTRL_E for SDVOB"); else - intel_encoder->i2c_bus = intel_i2c_create(dev, i2c_reg, "SDVOCTRL_E for SDVOC"); + intel_encoder->i2c_bus = + intel_i2c_create(intel_encoder, + i2c_reg, "SDVOCTRL_E for SDVOC"); if (!intel_encoder->i2c_bus) goto err_inteloutput; @@ -2583,14 +2567,20 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) /* setup the DDC bus. */ if (IS_SDVOB(sdvo_reg)) { - intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); - intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, - "SDVOB/VGA DDC BUS"); + intel_encoder->ddc_bus = + intel_i2c_create(intel_encoder, + ddc_reg, "SDVOB DDC BUS"); + intel_sdvo->analog_ddc_bus = + intel_i2c_create(intel_encoder, + analog_ddc_reg, "SDVOB/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; } else { - intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); - intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, - "SDVOC/VGA DDC BUS"); + intel_encoder->ddc_bus = + intel_i2c_create(intel_encoder, + ddc_reg, "SDVOC DDC BUS"); + intel_sdvo->analog_ddc_bus = + intel_i2c_create(intel_encoder, + analog_ddc_reg, "SDVOC/VGA DDC BUS"); dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; } if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) -- 2.46.0