Commit 2ed06c93 authored by Daniel Kurtz's avatar Daniel Kurtz Committed by Daniel Vetter

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: default avatarDaniel Kurtz <djkurtz@chromium.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 3bd7d909
...@@ -303,7 +303,6 @@ struct intel_fbc_work; ...@@ -303,7 +303,6 @@ struct intel_fbc_work;
struct intel_gmbus { struct intel_gmbus {
struct i2c_adapter adapter; struct i2c_adapter adapter;
bool force_bit; bool force_bit;
bool has_gpio;
u32 reg0; u32 reg0;
u32 gpio_reg; u32 gpio_reg;
struct i2c_algo_bit_data bit_algo; struct i2c_algo_bit_data bit_algo;
...@@ -1344,7 +1343,7 @@ extern int intel_setup_gmbus(struct drm_device *dev); ...@@ -1344,7 +1343,7 @@ extern int intel_setup_gmbus(struct drm_device *dev);
extern void intel_teardown_gmbus(struct drm_device *dev); extern void intel_teardown_gmbus(struct drm_device *dev);
extern inline bool intel_gmbus_is_port_valid(unsigned port) extern inline bool intel_gmbus_is_port_valid(unsigned port)
{ {
return (port >= GMBUS_PORT_DISABLED && port <= GMBUS_PORT_RESERVED); return (port >= GMBUS_PORT_SSC && port <= GMBUS_PORT_DPD);
} }
extern struct i2c_adapter *intel_gmbus_get_adapter( extern struct i2c_adapter *intel_gmbus_get_adapter(
......
...@@ -744,7 +744,7 @@ ...@@ -744,7 +744,7 @@
#define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */ #define GMBUS_PORT_DPB 5 /* SDVO, HDMIB */
#define GMBUS_PORT_DPD 6 /* HDMID */ #define GMBUS_PORT_DPD 6 /* HDMID */
#define GMBUS_PORT_RESERVED 7 /* 7 reserved */ #define GMBUS_PORT_RESERVED 7 /* 7 reserved */
#define GMBUS_NUM_PORTS 8 #define GMBUS_NUM_PORTS (GMBUS_PORT_DPD - GMBUS_PORT_SSC + 1)
#define GMBUS1 0x5104 /* command/status */ #define GMBUS1 0x5104 /* command/status */
#define GMBUS_SW_CLR_INT (1<<31) #define GMBUS_SW_CLR_INT (1<<31)
#define GMBUS_SW_RDY (1<<30) #define GMBUS_SW_RDY (1<<30)
......
...@@ -35,6 +35,20 @@ ...@@ -35,6 +35,20 @@
#include "i915_drm.h" #include "i915_drm.h"
#include "i915_drv.h" #include "i915_drv.h"
struct gmbus_port {
const char *name;
int reg;
};
static const struct gmbus_port gmbus_ports[] = {
{ "ssc", GPIOB },
{ "vga", GPIOA },
{ "panel", GPIOC },
{ "dpc", GPIOD },
{ "dpb", GPIOE },
{ "dpd", GPIOF },
};
/* Intel GPIO access functions */ /* Intel GPIO access functions */
#define I2C_RISEFALL_TIME 10 #define I2C_RISEFALL_TIME 10
...@@ -166,29 +180,16 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter) ...@@ -166,29 +180,16 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
intel_i2c_quirk_set(dev_priv, false); intel_i2c_quirk_set(dev_priv, false);
} }
static bool static void
intel_gpio_setup(struct intel_gmbus *bus, u32 pin) intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
{ {
struct drm_i915_private *dev_priv = bus->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
static const int map_pin_to_reg[] = {
0,
GPIOB,
GPIOA,
GPIOC,
GPIOD,
GPIOE,
GPIOF,
0,
};
struct i2c_algo_bit_data *algo; struct i2c_algo_bit_data *algo;
if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
return false;
algo = &bus->bit_algo; algo = &bus->bit_algo;
bus->gpio_reg = map_pin_to_reg[pin]; /* -1 to map pin pair to gmbus index */
bus->gpio_reg += dev_priv->gpio_mmio_base; bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_ports[pin - 1].reg;
bus->adapter.algo_data = algo; bus->adapter.algo_data = algo;
algo->setsda = set_data; algo->setsda = set_data;
...@@ -200,8 +201,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) ...@@ -200,8 +201,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
algo->udelay = I2C_RISEFALL_TIME; algo->udelay = I2C_RISEFALL_TIME;
algo->timeout = usecs_to_jiffies(2200); algo->timeout = usecs_to_jiffies(2200);
algo->data = bus; algo->data = bus;
return true;
} }
static int static int
...@@ -351,15 +350,9 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -351,15 +350,9 @@ gmbus_xfer(struct i2c_adapter *adapter,
bus->adapter.name, bus->reg0 & 0xff); bus->adapter.name, bus->reg0 & 0xff);
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0);
/* Hardware may not support GMBUS over these pins? /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
* Try GPIO bitbanging instead. bus->force_bit = true;
*/ ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
if (!bus->has_gpio) {
ret = -EIO;
} else {
bus->force_bit = true;
ret = i2c_bit_algo.master_xfer(adapter, msgs, num);
}
out: out:
mutex_unlock(&dev_priv->gmbus_mutex); mutex_unlock(&dev_priv->gmbus_mutex);
...@@ -386,16 +379,6 @@ static const struct i2c_algorithm gmbus_algorithm = { ...@@ -386,16 +379,6 @@ static const struct i2c_algorithm gmbus_algorithm = {
*/ */
int intel_setup_gmbus(struct drm_device *dev) int intel_setup_gmbus(struct drm_device *dev)
{ {
static const char *names[GMBUS_NUM_PORTS] = {
"disabled",
"ssc",
"vga",
"panel",
"dpc",
"dpb",
"dpd",
"reserved",
};
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i; int ret, i;
...@@ -413,13 +396,14 @@ int intel_setup_gmbus(struct drm_device *dev) ...@@ -413,13 +396,14 @@ int intel_setup_gmbus(struct drm_device *dev)
for (i = 0; i < GMBUS_NUM_PORTS; i++) { for (i = 0; i < GMBUS_NUM_PORTS; i++) {
struct intel_gmbus *bus = &dev_priv->gmbus[i]; struct intel_gmbus *bus = &dev_priv->gmbus[i];
u32 port = i + 1; /* +1 to map gmbus index to pin pair */
bus->adapter.owner = THIS_MODULE; bus->adapter.owner = THIS_MODULE;
bus->adapter.class = I2C_CLASS_DDC; bus->adapter.class = I2C_CLASS_DDC;
snprintf(bus->adapter.name, snprintf(bus->adapter.name,
sizeof(bus->adapter.name), sizeof(bus->adapter.name),
"i915 gmbus %s", "i915 gmbus %s",
names[i]); gmbus_ports[i].name);
bus->adapter.dev.parent = &dev->pdev->dev; bus->adapter.dev.parent = &dev->pdev->dev;
bus->dev_priv = dev_priv; bus->dev_priv = dev_priv;
...@@ -430,9 +414,9 @@ int intel_setup_gmbus(struct drm_device *dev) ...@@ -430,9 +414,9 @@ int intel_setup_gmbus(struct drm_device *dev)
goto err; goto err;
/* By default use a conservative clock rate */ /* By default use a conservative clock rate */
bus->reg0 = i | GMBUS_RATE_100KHZ; bus->reg0 = port | GMBUS_RATE_100KHZ;
bus->has_gpio = intel_gpio_setup(bus, i); intel_gpio_setup(bus, port);
} }
intel_i2c_reset(dev_priv->dev); intel_i2c_reset(dev_priv->dev);
...@@ -453,8 +437,9 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv, ...@@ -453,8 +437,9 @@ struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
unsigned port) unsigned port)
{ {
WARN_ON(!intel_gmbus_is_port_valid(port)); WARN_ON(!intel_gmbus_is_port_valid(port));
/* -1 to map pin pair to gmbus index */
return (intel_gmbus_is_port_valid(port)) ? return (intel_gmbus_is_port_valid(port)) ?
&dev_priv->gmbus[port].adapter : NULL; &dev_priv->gmbus[port - 1].adapter : NULL;
} }
void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) void 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,8 +453,7 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
{ {
struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_gmbus *bus = to_intel_gmbus(adapter);
if (bus->has_gpio) bus->force_bit = force_bit;
bus->force_bit = force_bit;
} }
void intel_teardown_gmbus(struct drm_device *dev) void intel_teardown_gmbus(struct drm_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment