Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6083 → Rev 6084

/drivers/video/drm/i915/intel_i2c.c
34,20 → 34,71
#include <drm/i915_drm.h>
#include "i915_drv.h"
 
struct gmbus_port {
struct gmbus_pin {
const char *name;
int reg;
};
 
static const struct gmbus_port gmbus_ports[] = {
{ "ssc", GPIOB },
{ "vga", GPIOA },
{ "panel", GPIOC },
{ "dpc", GPIOD },
{ "dpb", GPIOE },
{ "dpd", GPIOF },
/* Map gmbus pin pairs to names and registers. */
static const struct gmbus_pin gmbus_pins[] = {
[GMBUS_PIN_SSC] = { "ssc", GPIOB },
[GMBUS_PIN_VGADDC] = { "vga", GPIOA },
[GMBUS_PIN_PANEL] = { "panel", GPIOC },
[GMBUS_PIN_DPC] = { "dpc", GPIOD },
[GMBUS_PIN_DPB] = { "dpb", GPIOE },
[GMBUS_PIN_DPD] = { "dpd", GPIOF },
};
 
static const struct gmbus_pin gmbus_pins_bdw[] = {
[GMBUS_PIN_VGADDC] = { "vga", GPIOA },
[GMBUS_PIN_DPC] = { "dpc", GPIOD },
[GMBUS_PIN_DPB] = { "dpb", GPIOE },
[GMBUS_PIN_DPD] = { "dpd", GPIOF },
};
 
static const struct gmbus_pin gmbus_pins_skl[] = {
[GMBUS_PIN_DPC] = { "dpc", GPIOD },
[GMBUS_PIN_DPB] = { "dpb", GPIOE },
[GMBUS_PIN_DPD] = { "dpd", GPIOF },
};
 
static const struct gmbus_pin gmbus_pins_bxt[] = {
[GMBUS_PIN_1_BXT] = { "dpb", PCH_GPIOB },
[GMBUS_PIN_2_BXT] = { "dpc", PCH_GPIOC },
[GMBUS_PIN_3_BXT] = { "misc", PCH_GPIOD },
};
 
/* pin is expected to be valid */
static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
unsigned int pin)
{
if (IS_BROXTON(dev_priv))
return &gmbus_pins_bxt[pin];
else if (IS_SKYLAKE(dev_priv))
return &gmbus_pins_skl[pin];
else if (IS_BROADWELL(dev_priv))
return &gmbus_pins_bdw[pin];
else
return &gmbus_pins[pin];
}
 
bool intel_gmbus_is_valid_pin(struct drm_i915_private *dev_priv,
unsigned int pin)
{
unsigned int size;
 
if (IS_BROXTON(dev_priv))
size = ARRAY_SIZE(gmbus_pins_bxt);
else if (IS_SKYLAKE(dev_priv))
size = ARRAY_SIZE(gmbus_pins_skl);
else if (IS_BROADWELL(dev_priv))
size = ARRAY_SIZE(gmbus_pins_bdw);
else
size = ARRAY_SIZE(gmbus_pins);
 
return pin < size && get_gmbus_pin(dev_priv, pin)->reg;
}
 
/* Intel GPIO access functions */
 
#define I2C_RISEFALL_TIME 10
63,8 → 114,8
{
struct drm_i915_private *dev_priv = dev->dev_private;
 
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS0, 0);
I915_WRITE(dev_priv->gpio_mmio_base + GMBUS4, 0);
I915_WRITE(GMBUS0, 0);
I915_WRITE(GMBUS4, 0);
}
 
static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable)
182,7 → 233,7
}
 
static void
intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
{
struct drm_i915_private *dev_priv = bus->dev_priv;
struct i2c_algo_bit_data *algo;
189,8 → 240,8
 
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;
bus->gpio_reg = dev_priv->gpio_mmio_base +
get_gmbus_pin(dev_priv, pin)->reg;
 
bus->adapter.algo_data = algo;
algo->setsda = set_data;
210,7 → 261,6
u32 gmbus4_irq_en)
{
int i;
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus2 = 0;
DEFINE_WAIT(wait);
 
220,13 → 270,13
/* Important: The hw handles only the first bit, so set only one! Since
* we also need to check for NAKs besides the hw ready/idle signal, we
* need to wake up periodically and check that ourselves. */
I915_WRITE(GMBUS4 + reg_offset, gmbus4_irq_en);
I915_WRITE(GMBUS4, gmbus4_irq_en);
 
for (i = 0; i < msecs_to_jiffies_timeout(50); i++) {
prepare_to_wait(&dev_priv->gmbus_wait_queue, &wait,
TASK_UNINTERRUPTIBLE);
 
gmbus2 = I915_READ_NOTRACE(GMBUS2 + reg_offset);
gmbus2 = I915_READ_NOTRACE(GMBUS2);
if (gmbus2 & (GMBUS_SATOER | gmbus2_status))
break;
 
234,7 → 284,7
}
finish_wait(&dev_priv->gmbus_wait_queue, &wait);
 
I915_WRITE(GMBUS4 + reg_offset, 0);
I915_WRITE(GMBUS4, 0);
 
if (gmbus2 & GMBUS_SATOER)
return -ENXIO;
247,20 → 297,19
gmbus_wait_idle(struct drm_i915_private *dev_priv)
{
int ret;
int reg_offset = dev_priv->gpio_mmio_base;
 
#define C ((I915_READ_NOTRACE(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0)
#define C ((I915_READ_NOTRACE(GMBUS2) & GMBUS_ACTIVE) == 0)
 
if (!HAS_GMBUS_IRQ(dev_priv->dev))
return wait_for(C, 10);
 
/* Important: The hw handles only the first bit, so set only one! */
I915_WRITE(GMBUS4 + reg_offset, GMBUS_IDLE_EN);
I915_WRITE(GMBUS4, GMBUS_IDLE_EN);
 
ret = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
msecs_to_jiffies_timeout(10));
 
I915_WRITE(GMBUS4 + reg_offset, 0);
I915_WRITE(GMBUS4, 0);
 
if (ret)
return 0;
270,18 → 319,15
}
 
static int
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
unsigned short addr, u8 *buf, unsigned int len,
u32 gmbus1_index)
{
int reg_offset = dev_priv->gpio_mmio_base;
u16 len = msg->len;
u8 *buf = msg->buf;
 
I915_WRITE(GMBUS1 + reg_offset,
I915_WRITE(GMBUS1,
gmbus1_index |
GMBUS_CYCLE_WAIT |
(len << GMBUS_BYTE_COUNT_SHIFT) |
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_READ | GMBUS_SW_RDY);
while (len) {
int ret;
292,7 → 338,7
if (ret)
return ret;
 
val = I915_READ(GMBUS3 + reg_offset);
val = I915_READ(GMBUS3);
do {
*buf++ = val & 0xff;
val >>= 8;
303,11 → 349,34
}
 
static int
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
u32 gmbus1_index)
{
int reg_offset = dev_priv->gpio_mmio_base;
u16 len = msg->len;
u8 *buf = msg->buf;
unsigned int rx_size = msg->len;
unsigned int len;
int ret;
 
do {
len = min(rx_size, GMBUS_BYTE_COUNT_MAX);
 
ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
buf, len, gmbus1_index);
if (ret)
return ret;
 
rx_size -= len;
buf += len;
} while (rx_size != 0);
 
return 0;
}
 
static int
gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
unsigned short addr, u8 *buf, unsigned int len)
{
unsigned int chunk_size = len;
u32 val, loop;
 
val = loop = 0;
316,11 → 385,11
len -= 1;
}
 
I915_WRITE(GMBUS3 + reg_offset, val);
I915_WRITE(GMBUS1 + reg_offset,
I915_WRITE(GMBUS3, val);
I915_WRITE(GMBUS1,
GMBUS_CYCLE_WAIT |
(msg->len << GMBUS_BYTE_COUNT_SHIFT) |
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
(chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
while (len) {
int ret;
330,7 → 399,7
val |= *buf++ << (8 * loop);
} while (--len && ++loop < 4);
 
I915_WRITE(GMBUS3 + reg_offset, val);
I915_WRITE(GMBUS3, val);
 
ret = gmbus_wait_hw_status(dev_priv, GMBUS_HW_RDY,
GMBUS_HW_RDY_EN);
337,9 → 406,32
if (ret)
return ret;
}
 
return 0;
}
 
static int
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
{
u8 *buf = msg->buf;
unsigned int tx_size = msg->len;
unsigned int len;
int ret;
 
do {
len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
 
ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
if (ret)
return ret;
 
buf += len;
tx_size -= len;
} while (tx_size != 0);
 
return 0;
}
 
/*
* The gmbus controller can combine a 1 or 2 byte write with a read that
* immediately follows it by using an "INDEX" cycle.
355,7 → 447,6
static int
gmbus_xfer_index_read(struct drm_i915_private *dev_priv, struct i2c_msg *msgs)
{
int reg_offset = dev_priv->gpio_mmio_base;
u32 gmbus1_index = 0;
u32 gmbus5 = 0;
int ret;
369,13 → 460,13
 
/* GMBUS5 holds 16-bit index */
if (gmbus5)
I915_WRITE(GMBUS5 + reg_offset, gmbus5);
I915_WRITE(GMBUS5, gmbus5);
 
ret = gmbus_xfer_read(dev_priv, &msgs[1], gmbus1_index);
 
/* Clear GMBUS5 after each index transfer */
if (gmbus5)
I915_WRITE(GMBUS5 + reg_offset, 0);
I915_WRITE(GMBUS5, 0);
 
return ret;
}
389,10 → 480,10
struct intel_gmbus,
adapter);
struct drm_i915_private *dev_priv = bus->dev_priv;
int i, reg_offset;
int i = 0, inc, try = 0;
int ret = 0;
 
intel_aux_display_runtime_get(dev_priv);
intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
mutex_lock(&dev_priv->gmbus_mutex);
 
if (bus->force_bit) {
400,14 → 491,14
goto out;
}
 
reg_offset = dev_priv->gpio_mmio_base;
retry:
I915_WRITE(GMBUS0, bus->reg0);
 
I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
 
for (i = 0; i < num; i++) {
for (; i < num; i += inc) {
inc = 1;
if (gmbus_is_index_read(msgs, i, num)) {
ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
i += 1; /* set i to the index of the read xfer */
inc = 2; /* an index read is two msgs */
} else if (msgs[i].flags & I2C_M_RD) {
ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
} else {
431,7 → 522,7
* a STOP on the very first cycle. To simplify the code we
* unconditionally generate the STOP condition with an additional gmbus
* cycle. */
I915_WRITE(GMBUS1 + reg_offset, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
I915_WRITE(GMBUS1, GMBUS_CYCLE_STOP | GMBUS_SW_RDY);
 
/* Mark the GMBUS interface as disabled after waiting for idle.
* We will re-enable it at the start of the next xfer,
442,7 → 533,7
adapter->name);
ret = -ETIMEDOUT;
}
I915_WRITE(GMBUS0 + reg_offset, 0);
I915_WRITE(GMBUS0, 0);
ret = ret ?: i;
goto out;
 
471,20 → 562,32
* of resetting the GMBUS controller and so clearing the
* BUS_ERROR raised by the slave's NAK.
*/
I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT);
I915_WRITE(GMBUS1 + reg_offset, 0);
I915_WRITE(GMBUS0 + reg_offset, 0);
I915_WRITE(GMBUS1, GMBUS_SW_CLR_INT);
I915_WRITE(GMBUS1, 0);
I915_WRITE(GMBUS0, 0);
 
DRM_DEBUG_KMS("GMBUS [%s] NAK for addr: %04x %c(%d)\n",
adapter->name, msgs[i].addr,
(msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
 
/*
* Passive adapters sometimes NAK the first probe. Retry the first
* message once on -ENXIO for GMBUS transfers; the bit banging algorithm
* has retries internally. See also the retry loop in
* drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
*/
if (ret == -ENXIO && i == 0 && try++ == 0) {
DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
adapter->name);
goto retry;
}
 
goto out;
 
timeout:
DRM_INFO("GMBUS [%s] timed out, falling back to bit banging on pin %d\n",
bus->adapter.name, bus->reg0 & 0xff);
I915_WRITE(GMBUS0 + reg_offset, 0);
I915_WRITE(GMBUS0, 0);
 
/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
bus->force_bit = 1;
492,7 → 595,9
 
out:
mutex_unlock(&dev_priv->gmbus_mutex);
intel_aux_display_runtime_put(dev_priv);
 
intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
 
return ret;
}
 
517,7 → 622,9
int intel_setup_gmbus(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i;
struct intel_gmbus *bus;
unsigned int pin;
int ret;
 
if (HAS_PCH_NOP(dev))
return 0;
531,16 → 638,18
mutex_init(&dev_priv->gmbus_mutex);
init_waitqueue_head(&dev_priv->gmbus_wait_queue);
 
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 */
for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
if (!intel_gmbus_is_valid_pin(dev_priv, pin))
continue;
 
bus = &dev_priv->gmbus[pin];
 
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);
get_gmbus_pin(dev_priv, pin)->name);
 
bus->adapter.dev.parent = &dev->pdev->dev;
bus->dev_priv = dev_priv;
548,13 → 657,13
bus->adapter.algo = &gmbus_algorithm;
 
/* By default use a conservative clock rate */
bus->reg0 = port | GMBUS_RATE_100KHZ;
bus->reg0 = pin | GMBUS_RATE_100KHZ;
 
/* gmbus seems to be broken on i830 */
if (IS_I830(dev))
bus->force_bit = 1;
 
intel_gpio_setup(bus, port);
intel_gpio_setup(bus, pin);
 
ret = i2c_add_adapter(&bus->adapter);
if (ret)
566,8 → 675,11
return 0;
 
err:
while (--i) {
struct intel_gmbus *bus = &dev_priv->gmbus[i];
while (--pin) {
if (!intel_gmbus_is_valid_pin(dev_priv, pin))
continue;
 
bus = &dev_priv->gmbus[pin];
i2c_del_adapter(&bus->adapter);
}
return ret;
574,12 → 686,12
}
 
struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
unsigned port)
unsigned int pin)
{
WARN_ON(!intel_gmbus_is_port_valid(port));
/* -1 to map pin pair to gmbus index */
return (intel_gmbus_is_port_valid(port)) ?
&dev_priv->gmbus[port - 1].adapter : NULL;
if (WARN_ON(!intel_gmbus_is_valid_pin(dev_priv, pin)))
return NULL;
 
return &dev_priv->gmbus[pin].adapter;
}
 
void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
602,10 → 714,14
void intel_teardown_gmbus(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
int i;
struct intel_gmbus *bus;
unsigned int pin;
 
for (i = 0; i < GMBUS_NUM_PORTS; i++) {
struct intel_gmbus *bus = &dev_priv->gmbus[i];
for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
if (!intel_gmbus_is_valid_pin(dev_priv, pin))
continue;
 
bus = &dev_priv->gmbus[pin];
i2c_del_adapter(&bus->adapter);
}
}