[PATCH 20/49] drm/i915/bxt: Add change to support gmbus pin pair for BXT

Imre Deak
2015-03-17T09:40:37Z

From: "A.Sunil Kamath" <sunil.kamath@intel.com>

For BXT gmbus is pulled from GPU to CPU. From implementation
point of view only pin pair configuration will change. The
existing implementation supports all platforms previous to GEN8
and also SKL. But for BXT pin pair configuration
is completely different than SKL or other previous GEN's.
This patch introduces the new pin pair configuration structure
specific to BXT and also ensures every real gmbus port has a
gpio pin.

Tested on BDW hardware to confirm it doesnt break anything
in existing platform.

For BDW pin pair config will remain as:
gmbus[0]: Name = i915 gmbus ssc, gpio_reg = c5014, reg0 = 1
gmbus[1]: Name = i915 gmbus vga, gpio_reg = c5010, reg0 = 2
gmbus[2]: Name = i915 gmbus panel, gpio_reg = c5018, reg0 = 3
gmbus[3]: Name = i915 gmbus dpc, gpio_reg = c501c, reg0 = 4
gmbus[4]: Name = i915 gmbus dpb, gpio_reg = c5020, reg0 = 5
gmbus[5]: Name = i915 gmbus dpd, gpio_reg = c5024, reg0 = 6

BXT will have:
gmbus[0]: name = i915 gmbus None, gpio_reg = 0, reg0 = 0
gmbus[1]: name = i915 gmbus None, gpio_reg = 0, reg0 = 0
gmbus[2]: name = i915 gmbus None, gpio_reg = 0, reg0 = 0
gmbus[3]: name = i915 gmbus dpc, gpio_reg = c5018, reg0 = 2
gmbus[4]: name = i915 gmbus dpb, gpio_reg = c5014, reg0 = 1
gmbus[5]: name = i915 gmbus misc, gpio_reg = c501c, reg0 = 3

Values of GMBUS_PORT_DPB, GMBUS_PORT_DPC, GMBUS_PORT_DPD is
retained as it is like other platforms. Only logic in gmbus
structure creation is changed to minimize changes in multiple
files.

v1: Initial release
Structure gmbus_ports_bxt created for 3 ports only.
Here for BXT, gmbus[0], gmbus[1], gmbus[2] is untouched.
Logic used to calculate pin from respective register address as:
pin = reg & 0x000f >> 2

v2: Incorporated review comments from Jani Nikula.
Added a full bxt specific gmbus_ports_bxt and used it for bxt
regardless of pin >= 4.
Added const char *name and initialized it conditionally to
IS_BROXTON() so and avoided duplication of snprintf.
Added port_to_pin_bxt(port) function which returns right
pin value for a port for bxt platform.

Issue: VIZ-3574
Signed-off-by: A.Sunil Kamath <sunil.kamath@intel.com>
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
---
drivers/gpu/drm/i915/intel_i2c.c | 55 +++++++++++++++++++++++++++++++++++-----
1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index b31088a..3aa31e1 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -48,6 +48,16 @@ static const struct gmbus_port gmbus_ports[] = {
{ "dpd", GPIOF },
};

+/* gmbus pin pair configuration for bxt */
+static const struct gmbus_port gmbus_ports_bxt[] = {
+ { "None", 0 },
+ { "None", 0 },
+ { "None", 0 },
+ { "dpc", PCH_GPIOC },
+ { "dpb", PCH_GPIOB },
+ { "misc", PCH_GPIOD },
+};
+
/* Intel GPIO access functions */

#define I2C_RISEFALL_TIME 10
@@ -185,12 +195,17 @@ static void
intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
{
struct drm_i915_private *dev_priv = bus->dev_priv;
+ struct drm_device *dev = dev_priv->dev;
struct i2c_algo_bit_data *algo;

algo = &bus->bit_algo;

/* -1 to map pin pair to gmbus index */
- bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_ports[pin - 1].reg;
+ if (IS_BROXTON(dev))
+ bus->gpio_reg = gmbus_ports_bxt[pin - 1].reg;
+ else
+ bus->gpio_reg = dev_priv->gpio_mmio_base
+ + gmbus_ports[pin - 1].reg;

bus->adapter.algo_data = algo;
algo->setsda = set_data;
@@ -510,6 +525,27 @@ static const struct i2c_algorithm gmbus_algorithm = {
.functionality = gmbus_func
};

+/* returns mapped pin for a port in BXT */
+static u32 port_to_pin_bxt(u32 port)
+{
+ u32 pin;
+
+ switch (port) {
+ case GMBUS_PORT_DPB:
+ pin = 1;
+ break;
+ case GMBUS_PORT_DPC:
+ pin = 2;
+ break;
+ case GMBUS_PORT_DPD:
+ pin = 3;
+ break;
+ default:
+ pin = 0;
+ }
+ return pin;
+}
+
/**
* intel_gmbus_setup - instantiate all Intel i2c GMBuses
* @dev: DRM device
@@ -534,13 +570,17 @@ int intel_setup_gmbus(struct drm_device *dev)
for (i = 0; i < GMBUS_NUM_PORTS; i++) {
struct intel_gmbus *bus = &dev_priv->gmbus[i];
u32 port = i + 1; /* +1 to map gmbus index to pin pair */
+ const char *name;

bus->adapter.owner = THIS_MODULE;
bus->adapter.class = I2C_CLASS_DDC;
- snprintf(bus->adapter.name,
- sizeof(bus->adapter.name),
- "i915 gmbus %s",
- gmbus_ports[i].name);
+ if (IS_BROXTON(dev))
+ name = gmbus_ports_bxt[i].name;
+ else
+ name = gmbus_ports[i].name;
+
+ snprintf(bus->adapter.name, sizeof(bus->adapter.name),
+ "i915 gmbus %s", name);

bus->adapter.dev.parent = &dev->pdev->dev;
bus->dev_priv = dev_priv;
@@ -548,7 +588,10 @@ int intel_setup_gmbus(struct drm_device *dev)
bus->adapter.algo = &gmbus_algorithm;

/* By default use a conservative clock rate */
- bus->reg0 = port | GMBUS_RATE_100KHZ;
+ if (IS_BROXTON(dev))
+ bus->reg0 = port_to_pin_bxt(port) | GMBUS_RATE_100KHZ;
+ else
+ bus->reg0 = port | GMBUS_RATE_100KHZ;

/* gmbus seems to be broken on i830 */
if (IS_I830(dev))
--
2.1.0