Skip to content

Commit

Permalink
drm/i915/i2c: Track the parent encoder rather than just the dev
Browse files Browse the repository at this point in the history
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 <chris@chris-wilson.co.uk>
  • Loading branch information
Chris Wilson committed Sep 14, 2010
1 parent 2cf34d7 commit 890f335
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 65 deletions.
9 changes: 4 additions & 5 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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");
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 5 additions & 4 deletions drivers/gpu/drm/i915/intel_dvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
18 changes: 10 additions & 8 deletions drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 17 additions & 9 deletions drivers/gpu/drm/i915/intel_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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. */
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
62 changes: 26 additions & 36 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down

0 comments on commit 890f335

Please sign in to comment.