提交 de49442f 编写于 作者: D Dave Airlie

Merge tag 'drm-intel-next-2012-03-01' of...

Merge tag 'drm-intel-next-2012-03-01' of git://people.freedesktop.org/~danvet/drm-intel into drm-next

* tag 'drm-intel-next-2012-03-01' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: Only clear the GPU domains upon a successful finish
  drm/i915: reenable gmbus on gen3+ again
  drm/i915: i2c: unconditionally set up gpio fallback
  drm/i915: merge gmbus and gpio i2c adpater into one
  drm/i915: merge struct intel_gpio into struct intel_gmbus
  i2c: export bit-banging algo functions
  drm/nouveau: do a better job at hiding the NIH i2c bit-banging algo
  drm/i915: add dev_priv to intel_gmbus
  drm/i915: Fix single msg gmbus_xfers writes
  drm/i915: error_buffer->ring should be signed
  drm/i915: Silence the error message from i915_wait_request()
  drm/i915: use the new hdmi_force_audio enum more
  drm/i915: No need to search again after retiring requests
  drm/i915: Only bump refcnt on objects scheduled for eviction
  drm/i915/bios: Downgrade the "signature missing" DRM_ERROR to debug
  drm/i915: Ignore LVDS on hp t5745 and hp st5747 thin client
  drm/i915: Fixes distorted external screen image on HP 2730p
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "intel_ringbuffer.h" #include "intel_ringbuffer.h"
#include <linux/io-mapping.h> #include <linux/io-mapping.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <drm/intel-gtt.h> #include <drm/intel-gtt.h>
#include <linux/backlight.h> #include <linux/backlight.h>
...@@ -199,7 +200,7 @@ struct drm_i915_error_state { ...@@ -199,7 +200,7 @@ struct drm_i915_error_state {
u32 tiling:2; u32 tiling:2;
u32 dirty:1; u32 dirty:1;
u32 purgeable:1; u32 purgeable:1;
u32 ring:4; s32 ring:4;
u32 cache_level:2; u32 cache_level:2;
} *active_bo, *pinned_bo; } *active_bo, *pinned_bo;
u32 active_bo_count, pinned_bo_count; u32 active_bo_count, pinned_bo_count;
...@@ -298,6 +299,16 @@ enum intel_pch { ...@@ -298,6 +299,16 @@ enum intel_pch {
struct intel_fbdev; struct intel_fbdev;
struct intel_fbc_work; struct intel_fbc_work;
struct intel_gmbus {
struct i2c_adapter adapter;
bool force_bit;
bool has_gpio;
u32 reg0;
u32 gpio_reg;
struct i2c_algo_bit_data bit_algo;
struct drm_i915_private *dev_priv;
};
typedef struct drm_i915_private { typedef struct drm_i915_private {
struct drm_device *dev; struct drm_device *dev;
...@@ -315,11 +326,7 @@ typedef struct drm_i915_private { ...@@ -315,11 +326,7 @@ typedef struct drm_i915_private {
/** gt_lock is also taken in irq contexts. */ /** gt_lock is also taken in irq contexts. */
struct spinlock gt_lock; struct spinlock gt_lock;
struct intel_gmbus { struct intel_gmbus *gmbus;
struct i2c_adapter adapter;
struct i2c_adapter *force_bit;
u32 reg0;
} *gmbus;
/** gmbus_mutex protects against concurrent usage of the single hw gmbus /** gmbus_mutex protects against concurrent usage of the single hw gmbus
* controller on different i2c buses. */ * controller on different i2c buses. */
......
...@@ -1985,11 +1985,6 @@ i915_wait_request(struct intel_ring_buffer *ring, ...@@ -1985,11 +1985,6 @@ i915_wait_request(struct intel_ring_buffer *ring,
if (atomic_read(&dev_priv->mm.wedged)) if (atomic_read(&dev_priv->mm.wedged))
ret = -EAGAIN; ret = -EAGAIN;
if (ret && ret != -ERESTARTSYS)
DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n",
__func__, ret, seqno, ring->get_seqno(ring),
dev_priv->next_seqno);
/* Directly dispatch request retiring. While we have the work queue /* Directly dispatch request retiring. While we have the work queue
* to handle this, the waiter on a request often wants an associated * to handle this, the waiter on a request often wants an associated
* buffer to have made it to the inactive list, and we would need * buffer to have made it to the inactive list, and we would need
...@@ -3069,10 +3064,13 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj) ...@@ -3069,10 +3064,13 @@ i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj)
return ret; return ret;
} }
ret = i915_gem_object_wait_rendering(obj);
if (ret)
return ret;
/* Ensure that we invalidate the GPU's caches and TLBs. */ /* Ensure that we invalidate the GPU's caches and TLBs. */
obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS;
return 0;
return i915_gem_object_wait_rendering(obj);
} }
/** /**
......
...@@ -36,7 +36,6 @@ static bool ...@@ -36,7 +36,6 @@ static bool
mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind)
{ {
list_add(&obj->exec_list, unwind); list_add(&obj->exec_list, unwind);
drm_gem_object_reference(&obj->base);
return drm_mm_scan_add_block(obj->gtt_space); return drm_mm_scan_add_block(obj->gtt_space);
} }
...@@ -49,21 +48,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, ...@@ -49,21 +48,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
int ret = 0; int ret = 0;
i915_gem_retire_requests(dev);
/* Re-check for free space after retiring requests */
if (mappable) {
if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space,
min_size, alignment, 0,
dev_priv->mm.gtt_mappable_end,
0))
return 0;
} else {
if (drm_mm_search_free(&dev_priv->mm.gtt_space,
min_size, alignment, 0))
return 0;
}
trace_i915_gem_evict(dev, min_size, alignment, mappable); trace_i915_gem_evict(dev, min_size, alignment, mappable);
/* /*
...@@ -139,7 +123,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, ...@@ -139,7 +123,6 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
BUG_ON(ret); BUG_ON(ret);
list_del_init(&obj->exec_list); list_del_init(&obj->exec_list);
drm_gem_object_unreference(&obj->base);
} }
/* We expect the caller to unpin, evict all and try again, or give up. /* We expect the caller to unpin, evict all and try again, or give up.
...@@ -158,10 +141,10 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, ...@@ -158,10 +141,10 @@ i915_gem_evict_something(struct drm_device *dev, int min_size,
exec_list); exec_list);
if (drm_mm_scan_remove_block(obj->gtt_space)) { if (drm_mm_scan_remove_block(obj->gtt_space)) {
list_move(&obj->exec_list, &eviction_list); list_move(&obj->exec_list, &eviction_list);
drm_gem_object_reference(&obj->base);
continue; continue;
} }
list_del_init(&obj->exec_list); list_del_init(&obj->exec_list);
drm_gem_object_unreference(&obj->base);
} }
/* Unbinding will emit any required flushes */ /* Unbinding will emit any required flushes */
......
...@@ -669,7 +669,7 @@ intel_parse_bios(struct drm_device *dev) ...@@ -669,7 +669,7 @@ intel_parse_bios(struct drm_device *dev)
} }
if (!vbt) { if (!vbt) {
DRM_ERROR("VBT signature missing\n"); DRM_DEBUG_DRIVER("VBT signature missing\n");
pci_unmap_rom(pdev, bios); pci_unmap_rom(pdev, bios);
return -1; return -1;
} }
......
...@@ -9049,8 +9049,6 @@ struct intel_quirk { ...@@ -9049,8 +9049,6 @@ struct intel_quirk {
}; };
struct intel_quirk intel_quirks[] = { struct intel_quirk intel_quirks[] = {
/* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */
{ 0x2a42, 0x103c, 0x30eb, quirk_pipea_force },
/* HP Mini needs pipe A force quirk (LP: #322104) */ /* HP Mini needs pipe A force quirk (LP: #322104) */
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, { 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
......
...@@ -49,7 +49,7 @@ struct intel_dp { ...@@ -49,7 +49,7 @@ struct intel_dp {
uint32_t DP; uint32_t DP;
uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
bool has_audio; bool has_audio;
int force_audio; enum hdmi_force_audio force_audio;
uint32_t color_range; uint32_t color_range;
int dpms_mode; int dpms_mode;
uint8_t link_bw; uint8_t link_bw;
...@@ -2116,8 +2116,8 @@ intel_dp_detect(struct drm_connector *connector, bool force) ...@@ -2116,8 +2116,8 @@ intel_dp_detect(struct drm_connector *connector, bool force)
if (status != connector_status_connected) if (status != connector_status_connected)
return status; return status;
if (intel_dp->force_audio) { if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
intel_dp->has_audio = intel_dp->force_audio > 0; intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
} else { } else {
edid = intel_dp_get_edid(connector, &intel_dp->adapter); edid = intel_dp_get_edid(connector, &intel_dp->adapter);
if (edid) { if (edid) {
...@@ -2217,10 +2217,10 @@ intel_dp_set_property(struct drm_connector *connector, ...@@ -2217,10 +2217,10 @@ intel_dp_set_property(struct drm_connector *connector,
intel_dp->force_audio = i; intel_dp->force_audio = i;
if (i == 0) if (i == HDMI_AUDIO_AUTO)
has_audio = intel_dp_detect_audio(connector); has_audio = intel_dp_detect_audio(connector);
else else
has_audio = i > 0; has_audio = (i == HDMI_AUDIO_ON);
if (has_audio == intel_dp->has_audio) if (has_audio == intel_dp->has_audio)
return 0; return 0;
......
...@@ -45,13 +45,6 @@ to_intel_gmbus(struct i2c_adapter *i2c) ...@@ -45,13 +45,6 @@ to_intel_gmbus(struct i2c_adapter *i2c)
return container_of(i2c, struct intel_gmbus, adapter); return container_of(i2c, struct intel_gmbus, adapter);
} }
struct intel_gpio {
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
struct drm_i915_private *dev_priv;
u32 reg;
};
void void
intel_i2c_reset(struct drm_device *dev) intel_i2c_reset(struct drm_device *dev)
{ {
...@@ -78,15 +71,15 @@ static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) ...@@ -78,15 +71,15 @@ static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable)
I915_WRITE(DSPCLK_GATE_D, val); I915_WRITE(DSPCLK_GATE_D, val);
} }
static u32 get_reserved(struct intel_gpio *gpio) static u32 get_reserved(struct intel_gmbus *bus)
{ {
struct drm_i915_private *dev_priv = gpio->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
u32 reserved = 0; u32 reserved = 0;
/* On most chips, these bits must be preserved in software. */ /* On most chips, these bits must be preserved in software. */
if (!IS_I830(dev) && !IS_845G(dev)) if (!IS_I830(dev) && !IS_845G(dev))
reserved = I915_READ_NOTRACE(gpio->reg) & reserved = I915_READ_NOTRACE(bus->gpio_reg) &
(GPIO_DATA_PULLUP_DISABLE | (GPIO_DATA_PULLUP_DISABLE |
GPIO_CLOCK_PULLUP_DISABLE); GPIO_CLOCK_PULLUP_DISABLE);
...@@ -95,29 +88,29 @@ static u32 get_reserved(struct intel_gpio *gpio) ...@@ -95,29 +88,29 @@ static u32 get_reserved(struct intel_gpio *gpio)
static int get_clock(void *data) static int get_clock(void *data)
{ {
struct intel_gpio *gpio = data; struct intel_gmbus *bus = data;
struct drm_i915_private *dev_priv = gpio->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
u32 reserved = get_reserved(gpio); u32 reserved = get_reserved(bus);
I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_CLOCK_DIR_MASK);
I915_WRITE_NOTRACE(gpio->reg, reserved); I915_WRITE_NOTRACE(bus->gpio_reg, reserved);
return (I915_READ_NOTRACE(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_CLOCK_VAL_IN) != 0;
} }
static int get_data(void *data) static int get_data(void *data)
{ {
struct intel_gpio *gpio = data; struct intel_gmbus *bus = data;
struct drm_i915_private *dev_priv = gpio->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
u32 reserved = get_reserved(gpio); u32 reserved = get_reserved(bus);
I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); I915_WRITE_NOTRACE(bus->gpio_reg, reserved | GPIO_DATA_DIR_MASK);
I915_WRITE_NOTRACE(gpio->reg, reserved); I915_WRITE_NOTRACE(bus->gpio_reg, reserved);
return (I915_READ_NOTRACE(gpio->reg) & GPIO_DATA_VAL_IN) != 0; return (I915_READ_NOTRACE(bus->gpio_reg) & GPIO_DATA_VAL_IN) != 0;
} }
static void set_clock(void *data, int state_high) static void set_clock(void *data, int state_high)
{ {
struct intel_gpio *gpio = data; struct intel_gmbus *bus = data;
struct drm_i915_private *dev_priv = gpio->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
u32 reserved = get_reserved(gpio); u32 reserved = get_reserved(bus);
u32 clock_bits; u32 clock_bits;
if (state_high) if (state_high)
...@@ -126,15 +119,15 @@ static void set_clock(void *data, int state_high) ...@@ -126,15 +119,15 @@ static void set_clock(void *data, int state_high)
clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
GPIO_CLOCK_VAL_MASK; GPIO_CLOCK_VAL_MASK;
I915_WRITE_NOTRACE(gpio->reg, reserved | clock_bits); I915_WRITE_NOTRACE(bus->gpio_reg, reserved | clock_bits);
POSTING_READ(gpio->reg); POSTING_READ(bus->gpio_reg);
} }
static void set_data(void *data, int state_high) static void set_data(void *data, int state_high)
{ {
struct intel_gpio *gpio = data; struct intel_gmbus *bus = data;
struct drm_i915_private *dev_priv = gpio->dev_priv; struct drm_i915_private *dev_priv = bus->dev_priv;
u32 reserved = get_reserved(gpio); u32 reserved = get_reserved(bus);
u32 data_bits; u32 data_bits;
if (state_high) if (state_high)
...@@ -143,13 +136,14 @@ static void set_data(void *data, int state_high) ...@@ -143,13 +136,14 @@ static void set_data(void *data, int state_high)
data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
GPIO_DATA_VAL_MASK; GPIO_DATA_VAL_MASK;
I915_WRITE_NOTRACE(gpio->reg, reserved | data_bits); I915_WRITE_NOTRACE(bus->gpio_reg, reserved | data_bits);
POSTING_READ(gpio->reg); POSTING_READ(bus->gpio_reg);
} }
static struct i2c_adapter * static bool
intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
{ {
struct drm_i915_private *dev_priv = bus->dev_priv;
static const int map_pin_to_reg[] = { static const int map_pin_to_reg[] = {
0, 0,
GPIOB, GPIOB,
...@@ -160,65 +154,48 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) ...@@ -160,65 +154,48 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin)
0, 0,
GPIOF, GPIOF,
}; };
struct intel_gpio *gpio; struct i2c_algo_bit_data *algo;
if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin])
return NULL; return false;
gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); algo = &bus->bit_algo;
if (gpio == NULL)
return NULL;
gpio->reg = map_pin_to_reg[pin]; bus->gpio_reg = map_pin_to_reg[pin];
if (HAS_PCH_SPLIT(dev_priv->dev)) if (HAS_PCH_SPLIT(dev_priv->dev))
gpio->reg += PCH_GPIOA - GPIOA; bus->gpio_reg += PCH_GPIOA - GPIOA;
gpio->dev_priv = dev_priv;
bus->adapter.algo_data = algo;
snprintf(gpio->adapter.name, sizeof(gpio->adapter.name), algo->setsda = set_data;
"i915 GPIO%c", "?BACDE?F"[pin]); algo->setscl = set_clock;
gpio->adapter.owner = THIS_MODULE; algo->getsda = get_data;
gpio->adapter.algo_data = &gpio->algo; algo->getscl = get_clock;
gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; algo->udelay = I2C_RISEFALL_TIME;
gpio->algo.setsda = set_data; algo->timeout = usecs_to_jiffies(2200);
gpio->algo.setscl = set_clock; algo->data = bus;
gpio->algo.getsda = get_data;
gpio->algo.getscl = get_clock; return true;
gpio->algo.udelay = I2C_RISEFALL_TIME;
gpio->algo.timeout = usecs_to_jiffies(2200);
gpio->algo.data = gpio;
if (i2c_bit_add_bus(&gpio->adapter))
goto out_free;
return &gpio->adapter;
out_free:
kfree(gpio);
return NULL;
} }
static int static int
intel_i2c_quirk_xfer(struct drm_i915_private *dev_priv, intel_i2c_quirk_xfer(struct intel_gmbus *bus,
struct i2c_adapter *adapter,
struct i2c_msg *msgs, struct i2c_msg *msgs,
int num) int num)
{ {
struct intel_gpio *gpio = container_of(adapter, struct drm_i915_private *dev_priv = bus->dev_priv;
struct intel_gpio,
adapter);
int ret; int ret;
intel_i2c_reset(dev_priv->dev); intel_i2c_reset(dev_priv->dev);
intel_i2c_quirk_set(dev_priv, true); intel_i2c_quirk_set(dev_priv, true);
set_data(gpio, 1); set_data(bus, 1);
set_clock(gpio, 1); set_clock(bus, 1);
udelay(I2C_RISEFALL_TIME); udelay(I2C_RISEFALL_TIME);
ret = adapter->algo->master_xfer(adapter, msgs, num); ret = i2c_bit_algo.master_xfer(&bus->adapter, msgs, num);
set_data(gpio, 1); set_data(bus, 1);
set_clock(gpio, 1); set_clock(bus, 1);
intel_i2c_quirk_set(dev_priv, false); intel_i2c_quirk_set(dev_priv, false);
return ret; return ret;
...@@ -232,14 +209,13 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -232,14 +209,13 @@ gmbus_xfer(struct i2c_adapter *adapter,
struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus *bus = container_of(adapter,
struct intel_gmbus, struct intel_gmbus,
adapter); adapter);
struct drm_i915_private *dev_priv = adapter->algo_data; struct drm_i915_private *dev_priv = bus->dev_priv;
int i, reg_offset, ret; int i, reg_offset, ret;
mutex_lock(&dev_priv->gmbus_mutex); mutex_lock(&dev_priv->gmbus_mutex);
if (bus->force_bit) { if (bus->force_bit) {
ret = intel_i2c_quirk_xfer(dev_priv, ret = intel_i2c_quirk_xfer(bus, msgs, num);
bus->force_bit, msgs, num);
goto out; goto out;
} }
...@@ -253,7 +229,8 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -253,7 +229,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
if (msgs[i].flags & I2C_M_RD) { if (msgs[i].flags & I2C_M_RD) {
I915_WRITE(GMBUS1 + reg_offset, I915_WRITE(GMBUS1 + reg_offset,
GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | GMBUS_CYCLE_WAIT |
(i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
(len << GMBUS_BYTE_COUNT_SHIFT) | (len << GMBUS_BYTE_COUNT_SHIFT) |
(msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_READ | GMBUS_SW_RDY); GMBUS_SLAVE_READ | GMBUS_SW_RDY);
...@@ -282,7 +259,8 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -282,7 +259,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
I915_WRITE(GMBUS3 + reg_offset, val); I915_WRITE(GMBUS3 + reg_offset, val);
I915_WRITE(GMBUS1 + reg_offset, I915_WRITE(GMBUS1 + reg_offset,
(i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | GMBUS_CYCLE_WAIT |
(i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
(msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
(msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
...@@ -321,9 +299,12 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -321,9 +299,12 @@ gmbus_xfer(struct i2c_adapter *adapter,
I915_WRITE(GMBUS1 + reg_offset, 0); I915_WRITE(GMBUS1 + reg_offset, 0);
done: done:
/* Mark the GMBUS interface as disabled. We will re-enable it at the /* Mark the GMBUS interface as disabled after waiting for idle.
* start of the next xfer, till then let it sleep. * We will re-enable it at the start of the next xfer,
* till then let it sleep.
*/ */
if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10))
DRM_INFO("GMBUS timed out waiting for idle\n");
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0);
ret = i; ret = i;
goto out; goto out;
...@@ -334,11 +315,12 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -334,11 +315,12 @@ gmbus_xfer(struct i2c_adapter *adapter,
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0);
/* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */
bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); if (!bus->has_gpio) {
if (!bus->force_bit) ret = -EIO;
ret = -ENOMEM; } else {
else bus->force_bit = true;
ret = intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num); ret = intel_i2c_quirk_xfer(bus, msgs, num);
}
out: out:
mutex_unlock(&dev_priv->gmbus_mutex); mutex_unlock(&dev_priv->gmbus_mutex);
return ret; return ret;
...@@ -346,14 +328,8 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -346,14 +328,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
static u32 gmbus_func(struct i2c_adapter *adapter) static u32 gmbus_func(struct i2c_adapter *adapter)
{ {
struct intel_gmbus *bus = container_of(adapter, return i2c_bit_algo.functionality(adapter) &
struct intel_gmbus, (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
adapter);
if (bus->force_bit)
bus->force_bit->algo->functionality(bus->force_bit);
return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
/* I2C_FUNC_10BIT_ADDR | */ /* I2C_FUNC_10BIT_ADDR | */
I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_READ_BLOCK_DATA |
I2C_FUNC_SMBUS_BLOCK_PROC_CALL); I2C_FUNC_SMBUS_BLOCK_PROC_CALL);
...@@ -401,7 +377,7 @@ int intel_setup_gmbus(struct drm_device *dev) ...@@ -401,7 +377,7 @@ int intel_setup_gmbus(struct drm_device *dev)
names[i]); names[i]);
bus->adapter.dev.parent = &dev->pdev->dev; bus->adapter.dev.parent = &dev->pdev->dev;
bus->adapter.algo_data = dev_priv; bus->dev_priv = dev_priv;
bus->adapter.algo = &gmbus_algorithm; bus->adapter.algo = &gmbus_algorithm;
ret = i2c_add_adapter(&bus->adapter); ret = i2c_add_adapter(&bus->adapter);
...@@ -411,8 +387,11 @@ int intel_setup_gmbus(struct drm_device *dev) ...@@ -411,8 +387,11 @@ int intel_setup_gmbus(struct drm_device *dev)
/* By default use a conservative clock rate */ /* By default use a conservative clock rate */
bus->reg0 = i | GMBUS_RATE_100KHZ; bus->reg0 = i | GMBUS_RATE_100KHZ;
bus->has_gpio = intel_gpio_setup(bus, i);
/* XXX force bit banging until GMBUS is fully debugged */ /* XXX force bit banging until GMBUS is fully debugged */
bus->force_bit = intel_gpio_create(dev_priv, i); if (bus->has_gpio && IS_GEN2(dev))
bus->force_bit = true;
} }
intel_i2c_reset(dev_priv->dev); intel_i2c_reset(dev_priv->dev);
...@@ -440,19 +419,8 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) ...@@ -440,19 +419,8 @@ 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 (force_bit) { if (bus->has_gpio)
if (bus->force_bit == NULL) { bus->force_bit = force_bit;
struct drm_i915_private *dev_priv = adapter->algo_data;
bus->force_bit = intel_gpio_create(dev_priv,
bus->reg0 & 0xff);
}
} else {
if (bus->force_bit) {
i2c_del_adapter(bus->force_bit);
kfree(bus->force_bit);
bus->force_bit = NULL;
}
}
} }
void intel_teardown_gmbus(struct drm_device *dev) void intel_teardown_gmbus(struct drm_device *dev)
...@@ -465,10 +433,6 @@ void intel_teardown_gmbus(struct drm_device *dev) ...@@ -465,10 +433,6 @@ void intel_teardown_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];
if (bus->force_bit) {
i2c_del_adapter(bus->force_bit);
kfree(bus->force_bit);
}
i2c_del_adapter(&bus->adapter); i2c_del_adapter(&bus->adapter);
} }
......
...@@ -739,6 +739,22 @@ static const struct dmi_system_id intel_no_lvds[] = { ...@@ -739,6 +739,22 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"),
}, },
}, },
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Hewlett-Packard t5745",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_BOARD_NAME, "hp t5745"),
},
},
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Hewlett-Packard st5747",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_BOARD_NAME, "hp st5747"),
},
},
{ } /* terminating entry */ { } /* terminating entry */
}; };
......
...@@ -148,7 +148,7 @@ struct intel_sdvo_connector { ...@@ -148,7 +148,7 @@ struct intel_sdvo_connector {
/* Mark the type of connector */ /* Mark the type of connector */
uint16_t output_flag; uint16_t output_flag;
int force_audio; enum hdmi_force_audio force_audio;
/* This contains all current supported TV format */ /* This contains all current supported TV format */
u8 tv_format_supported[TV_FORMAT_NUM]; u8 tv_format_supported[TV_FORMAT_NUM];
...@@ -1309,8 +1309,8 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) ...@@ -1309,8 +1309,8 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
if (status == connector_status_connected) { if (status == connector_status_connected) {
struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
if (intel_sdvo_connector->force_audio) if (intel_sdvo_connector->force_audio != HDMI_AUDIO_AUTO)
intel_sdvo->has_hdmi_audio = intel_sdvo_connector->force_audio > 0; intel_sdvo->has_hdmi_audio = (intel_sdvo_connector->force_audio == HDMI_AUDIO_ON);
} }
return status; return status;
...@@ -1683,10 +1683,10 @@ intel_sdvo_set_property(struct drm_connector *connector, ...@@ -1683,10 +1683,10 @@ intel_sdvo_set_property(struct drm_connector *connector,
intel_sdvo_connector->force_audio = i; intel_sdvo_connector->force_audio = i;
if (i == 0) if (i == HDMI_AUDIO_AUTO)
has_audio = intel_sdvo_detect_hdmi_audio(connector); has_audio = intel_sdvo_detect_hdmi_audio(connector);
else else
has_audio = i > 0; has_audio = (i == HDMI_AUDIO_ON);
if (has_audio == intel_sdvo->has_hdmi_audio) if (has_audio == intel_sdvo->has_hdmi_audio)
return 0; return 0;
......
...@@ -277,7 +277,7 @@ i2c_bit_func(struct i2c_adapter *adap) ...@@ -277,7 +277,7 @@ i2c_bit_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
} }
const struct i2c_algorithm i2c_bit_algo = { const struct i2c_algorithm nouveau_i2c_bit_algo = {
.master_xfer = i2c_bit_xfer, .master_xfer = i2c_bit_xfer,
.functionality = i2c_bit_func .functionality = i2c_bit_func
}; };
...@@ -384,12 +384,12 @@ nouveau_i2c_init(struct drm_device *dev) ...@@ -384,12 +384,12 @@ nouveau_i2c_init(struct drm_device *dev)
case 0: /* NV04:NV50 */ case 0: /* NV04:NV50 */
port->drive = entry[0]; port->drive = entry[0];
port->sense = entry[1]; port->sense = entry[1];
port->adapter.algo = &i2c_bit_algo; port->adapter.algo = &nouveau_i2c_bit_algo;
break; break;
case 4: /* NV4E */ case 4: /* NV4E */
port->drive = 0x600800 + entry[1]; port->drive = 0x600800 + entry[1];
port->sense = port->drive; port->sense = port->drive;
port->adapter.algo = &i2c_bit_algo; port->adapter.algo = &nouveau_i2c_bit_algo;
break; break;
case 5: /* NV50- */ case 5: /* NV50- */
port->drive = entry[0] & 0x0f; port->drive = entry[0] & 0x0f;
...@@ -402,7 +402,7 @@ nouveau_i2c_init(struct drm_device *dev) ...@@ -402,7 +402,7 @@ nouveau_i2c_init(struct drm_device *dev)
port->drive = 0x00d014 + (port->drive * 0x20); port->drive = 0x00d014 + (port->drive * 0x20);
port->sense = port->drive; port->sense = port->drive;
} }
port->adapter.algo = &i2c_bit_algo; port->adapter.algo = &nouveau_i2c_bit_algo;
break; break;
case 6: /* NV50- DP AUX */ case 6: /* NV50- DP AUX */
port->drive = entry[0]; port->drive = entry[0];
......
...@@ -610,10 +610,11 @@ static u32 bit_func(struct i2c_adapter *adap) ...@@ -610,10 +610,11 @@ static u32 bit_func(struct i2c_adapter *adap)
/* -----exported algorithm data: ------------------------------------- */ /* -----exported algorithm data: ------------------------------------- */
static const struct i2c_algorithm i2c_bit_algo = { const struct i2c_algorithm i2c_bit_algo = {
.master_xfer = bit_xfer, .master_xfer = bit_xfer,
.functionality = bit_func, .functionality = bit_func,
}; };
EXPORT_SYMBOL(i2c_bit_algo);
/* /*
* registering functions to load algorithms at runtime * registering functions to load algorithms at runtime
......
...@@ -49,5 +49,6 @@ struct i2c_algo_bit_data { ...@@ -49,5 +49,6 @@ struct i2c_algo_bit_data {
int i2c_bit_add_bus(struct i2c_adapter *); int i2c_bit_add_bus(struct i2c_adapter *);
int i2c_bit_add_numbered_bus(struct i2c_adapter *); int i2c_bit_add_numbered_bus(struct i2c_adapter *);
extern const struct i2c_algorithm i2c_bit_algo;
#endif /* _LINUX_I2C_ALGO_BIT_H */ #endif /* _LINUX_I2C_ALGO_BIT_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册