aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kurtz <djkurtz@chromium.org>2012-03-27 14:36:15 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-28 09:02:53 -0400
commit2ed06c93a1fce057808894d73167aae03c76deaf (patch)
tree163c39d4fffc678c507604a67fed8f1c778a9ec6
parent3bd7d90938f1fe77de5991dc4b727843c4980b2a (diff)
drm/i915/intel_i2c: gmbus disabled and reserved ports are invalid
There is no GMBUS "disabled" port 0, nor "reserved" port 7. For the other 6 ports there is a fixed 1:1 mapping between pin pairs and gmbus ports, which means every real gmbus port has a gpio pin. Given these realizations, clean up gmbus initialization. Tested on Sandybridge (gen 6, PCH == CougarPoint) hardware. Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c70
3 files changed, 29 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 44e6430af3d4..c5ad7b96b065 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -303,7 +303,6 @@ struct intel_fbc_work;
303struct intel_gmbus { 303struct intel_gmbus {
304 struct i2c_adapter adapter; 304 struct i2c_adapter adapter;
305 bool force_bit; 305 bool force_bit;
306 bool has_gpio;
307 u32 reg0; 306 u32 reg0;
308 u32 gpio_reg; 307 u32 gpio_reg;
309 struct i2c_algo_bit_data bit_algo; 308 struct i2c_algo_bit_data bit_algo;
@@ -1344,7 +1343,7 @@ extern int intel_setup_gmbus(struct drm_device *dev);
1344extern void intel_teardown_gmbus(struct drm_device *dev); 1343extern void intel_teardown_gmbus(struct drm_device *dev);
1345extern inline bool intel_gmbus_is_port_valid(unsigned port) 1344extern inline bool intel_gmbus_is_port_valid(unsigned port)
1346{ 1345{
1347 return (port >= GMBUS_PORT_DISABLED && port <= GMBUS_PORT_RESERVED); 1346 return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD);
1348} 1347}
1349 1348
1350extern struct i2c_adapter *intel_gmbus_get_adapter( 1349extern struct i2c_adapter *intel_gmbus_get_adapter(
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index accd8ee48f9d..a8d218ca7d1d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -744,7 +744,7 @@
744#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ 744#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */
745#define GMBUS_PORT_DPD 6 /* HDMID */ 745#define GMBUS_PORT_DPD 6 /* HDMID */
746#define GMBUS_PORT_RESERVED 7 /* 7 reserved */ 746#define GMBUS_PORT_RESERVED 7 /* 7 reserved */
747#define GMBUS_NUM_PORTS 8 747#define GMBUS_NUM_PORTS (GMBUS_PORT_DPD - GMBUS_PORT_SSC + 1)
748#define GMBUS1 0x5104 /* command/status */ 748#define GMBUS1 0x5104 /* command/status */
749#define GMBUS_SW_CLR_INT (1<<31) 749#define GMBUS_SW_CLR_INT (1<<31)
750#define GMBUS_SW_RDY (1<<30) 750#define GMBUS_SW_RDY (1<<30)
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 2f65d01340ff..dcde6f64777a 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -35,6 +35,20 @@
35#include "i915_drm.h" 35#include "i915_drm.h"
36#include "i915_drv.h" 36#include "i915_drv.h"
37 37
38struct gmbus_port {
39 const char *name;
40 int reg;
41};
42
43static const struct gmbus_port gmbus_ports[] = {
44 { "ssc", GPIOB },
45 { "vga", GPIOA },
46 { "panel", GPIOC },
47 { "dpc", GPIOD },
48 { "dpb", GPIOE },
49 { "dpd", GPIOF },
50};
51
38/* Intel GPIO access functions */ 52/* Intel GPIO access functions */
39 53
40#define I2C_RISEFALL_TIME 10 54#define I2C_RISEFALL_TIME 10
@@ -166,29 +180,16 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
166 intel_i2c_quirk_set(dev_priv, false); 180 intel_i2c_quirk_set(dev_priv, false);
167} 181}
168 182
169static bool 183static void
170intel_gpio_setup(struct intel_gmbus *bus, u32 pin) 184intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
171{ 185{
172 struct drm_i915_private *dev_priv = bus->dev_priv; 186 struct drm_i915_private *dev_priv = bus->dev_priv;
173 static const int map_pin_to_reg[] = {
174 0,
175 GPIOB,
176 GPIOA,
177 GPIOC,
178 GPIOD,
179 GPIOE,
180 GPIOF,
181 0,
182 };
183 struct i2c_algo_bit_data *algo; 187 struct i2c_algo_bit_data *algo;
184 188
185 if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
186 return false;
187
188 algo = &bus->bit_algo; 189 algo = &bus->bit_algo;
189 190
190 bus->gpio_reg = map_pin_to_reg[pin]; 191 /* -1 to map pin pair to gmbus index */
191 bus->gpio_reg += dev_priv->gpio_mmio_base; 192 bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_ports[pin - 1].reg;
192 193
193 bus->adapter.algo_data = algo; 194 bus->adapter.algo_data = algo;
194 algo->setsda = set_data; 195 algo->setsda = set_data;
@@ -200,8 +201,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
200 algo->udelay = I2C_RISEFALL_TIME; 201 algo->udelay = I2C_RISEFALL_TIME;
201 algo->timeout = usecs_to_jiffies(2200); 202 algo->timeout = usecs_to_jiffies(2200);
202 algo->data = bus; 203 algo->data = bus;
203
204 return true;
205} 204}
206 205
207static int 206static int
@@ -351,15 +350,9 @@ timeout:
351 bus->adapter.name, bus->reg0 & 0xff); 350 bus->adapter.name, bus->reg0 & 0xff);
352 I915_WRITE(GMBUS0 + reg_offset, 0); 351 I915_WRITE(GMBUS0 + reg_offset, 0);
353 352
354 /* Hardware may not support GMBUS over these pins? 353 /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
355 * Try GPIO bitbanging instead. 354 bus->force_bit = true;
356 */ 355 ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
357 if (!bus->has_gpio) {
358 ret = -EIO;
359 } else {
360 bus->force_bit = true;
361 ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
362 }
363 356
364out: 357out:
365 mutex_unlock(&dev_priv->gmbus_mutex); 358 mutex_unlock(&dev_priv->gmbus_mutex);
@@ -386,16 +379,6 @@ static const struct i2c_algorithm gmbus_algorithm = {
386 */ 379 */
387int intel_setup_gmbus(struct drm_device *dev) 380int intel_setup_gmbus(struct drm_device *dev)
388{ 381{
389 static const char *names[GMBUS_NUM_PORTS] = {
390 "disabled",
391 "ssc",
392 "vga",
393 "panel",
394 "dpc",
395 "dpb",
396 "dpd",
397 "reserved",
398 };
399 struct drm_i915_private *dev_priv = dev->dev_private; 382 struct drm_i915_private *dev_priv = dev->dev_private;
400 int ret, i; 383 int ret, i;
401 384
@@ -413,13 +396,14 @@ int intel_setup_gmbus(struct drm_device *dev)
413 396
414 for (i = 0; i < GMBUS_NUM_PORTS; i++) { 397 for (i = 0; i < GMBUS_NUM_PORTS; i++) {
415 struct intel_gmbus *bus = &dev_priv->gmbus[i]; 398 struct intel_gmbus *bus = &dev_priv->gmbus[i];
399 u32 port = i + 1; /* +1 to map gmbus index to pin pair */
416 400
417 bus->adapter.owner = THIS_MODULE; 401 bus->adapter.owner = THIS_MODULE;
418 bus->adapter.class = I2C_CLASS_DDC; 402 bus->adapter.class = I2C_CLASS_DDC;
419 snprintf(bus->adapter.name, 403 snprintf(bus->adapter.name,
420 sizeof(bus->adapter.name), 404 sizeof(bus->adapter.name),
421 "i915 gmbus %s", 405 "i915 gmbus %s",
422 names[i]); 406 gmbus_ports[i].name);
423 407
424 bus->adapter.dev.parent = &dev->pdev->dev; 408 bus->adapter.dev.parent = &dev->pdev->dev;
425 bus->dev_priv = dev_priv; 409 bus->dev_priv = dev_priv;
@@ -430,9 +414,9 @@ int intel_setup_gmbus(struct drm_device *dev)
430 goto err; 414 goto err;
431 415
432 /* By default use a conservative clock rate */ 416 /* By default use a conservative clock rate */
433 bus->reg0 = i | GMBUS_RATE_100KHZ; 417 bus->reg0 = port | GMBUS_RATE_100KHZ;
434 418
435 bus->has_gpio = intel_gpio_setup(bus, i); 419 intel_gpio_setup(bus, port);
436 } 420 }
437 421
438 intel_i2c_reset(dev_priv->dev); 422 intel_i2c_reset(dev_priv->dev);
@@ -453,8 +437,9 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
453 unsigned port) 437 unsigned port)
454{ 438{
455 WARN_ON(!intel_gmbus_is_port_valid(port)); 439 WARN_ON(!intel_gmbus_is_port_valid(port));
440 /* -1 to map pin pair to gmbus index */
456 return (intel_gmbus_is_port_valid(port)) ? 441 return (intel_gmbus_is_port_valid(port)) ?
457 &dev_priv->gmbus[port].adapter : NULL; 442 &dev_priv->gmbus[port - 1].adapter : NULL;
458} 443}
459 444
460void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) 445void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
@@ -468,8 +453,7 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
468{ 453{
469 struct intel_gmbus *bus = to_intel_gmbus(adapter); 454 struct intel_gmbus *bus = to_intel_gmbus(adapter);
470 455
471 if (bus->has_gpio) 456 bus->force_bit = force_bit;
472 bus->force_bit = force_bit;
473} 457}
474 458
475void intel_teardown_gmbus(struct drm_device *dev) 459void intel_teardown_gmbus(struct drm_device *dev)