Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 890f3359 authored by Chris Wilson's avatar Chris Wilson
Browse files

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: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 2cf34d7b
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -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");
+3 −2
Original line number Diff line number Diff line
@@ -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);
+5 −4
Original line number Diff line number Diff line
@@ -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);
+10 −8
Original line number Diff line number Diff line
@@ -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)
+17 −9
Original line number Diff line number Diff line
@@ -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;
Loading