diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-24 07:52:03 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-28 08:29:10 -0400 |
commit | e957d7720a2797b31231616014b68f4f6203145e (patch) | |
tree | 07fd5eb66781405b408830381c99b45c26d34f85 | |
parent | a56ba56c275b1c2b982c8901ab92bf5a0fd0b757 (diff) |
drm/i915/sdvo: Fix GMBUSification
Besides a couple of bugs when writing more than a single byte along the
GMBUS, SDVO was completely failing whilst trying to use GMBUS, so use
bit banging instead.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 181 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 332 |
5 files changed, 339 insertions, 196 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 710d59ea479c..0bb255331764 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -132,10 +132,12 @@ struct drm_i915_fence_reg { | |||
132 | }; | 132 | }; |
133 | 133 | ||
134 | struct sdvo_device_mapping { | 134 | struct sdvo_device_mapping { |
135 | u8 initialized; | ||
135 | u8 dvo_port; | 136 | u8 dvo_port; |
136 | u8 slave_addr; | 137 | u8 slave_addr; |
137 | u8 dvo_wiring; | 138 | u8 dvo_wiring; |
138 | u8 initialized; | 139 | u8 i2c_pin; |
140 | u8 i2c_speed; | ||
139 | u8 ddc_pin; | 141 | u8 ddc_pin; |
140 | }; | 142 | }; |
141 | 143 | ||
@@ -248,8 +250,8 @@ typedef struct drm_i915_private { | |||
248 | 250 | ||
249 | struct intel_gmbus { | 251 | struct intel_gmbus { |
250 | struct i2c_adapter adapter; | 252 | struct i2c_adapter adapter; |
251 | struct i2c_adapter *force_bitbanging; | 253 | struct i2c_adapter *force_bit; |
252 | int pin; | 254 | u32 reg0; |
253 | } *gmbus; | 255 | } *gmbus; |
254 | 256 | ||
255 | struct pci_dev *bridge_dev; | 257 | struct pci_dev *bridge_dev; |
@@ -1104,6 +1106,8 @@ extern int i915_restore_state(struct drm_device *dev); | |||
1104 | /* intel_i2c.c */ | 1106 | /* intel_i2c.c */ |
1105 | extern int intel_setup_gmbus(struct drm_device *dev); | 1107 | extern int intel_setup_gmbus(struct drm_device *dev); |
1106 | extern void intel_teardown_gmbus(struct drm_device *dev); | 1108 | extern void intel_teardown_gmbus(struct drm_device *dev); |
1109 | extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed); | ||
1110 | extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit); | ||
1107 | extern void intel_i2c_reset(struct drm_device *dev); | 1111 | extern void intel_i2c_reset(struct drm_device *dev); |
1108 | 1112 | ||
1109 | /* intel_opregion.c */ | 1113 | /* intel_opregion.c */ |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 42a7a5b33a0a..7e868d228c7b 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -369,7 +369,16 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, | |||
369 | p_mapping->slave_addr = p_child->slave_addr; | 369 | p_mapping->slave_addr = p_child->slave_addr; |
370 | p_mapping->dvo_wiring = p_child->dvo_wiring; | 370 | p_mapping->dvo_wiring = p_child->dvo_wiring; |
371 | p_mapping->ddc_pin = p_child->ddc_pin; | 371 | p_mapping->ddc_pin = p_child->ddc_pin; |
372 | p_mapping->i2c_pin = p_child->i2c_pin; | ||
373 | p_mapping->i2c_speed = p_child->i2c_speed; | ||
372 | p_mapping->initialized = 1; | 374 | p_mapping->initialized = 1; |
375 | DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d, i2c_speed=%d\n", | ||
376 | p_mapping->dvo_port, | ||
377 | p_mapping->slave_addr, | ||
378 | p_mapping->dvo_wiring, | ||
379 | p_mapping->ddc_pin, | ||
380 | p_mapping->i2c_pin, | ||
381 | p_mapping->i2c_speed); | ||
373 | } else { | 382 | } else { |
374 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " | 383 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " |
375 | "two SDVO device.\n"); | 384 | "two SDVO device.\n"); |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 4c18514f6f80..e1a598f2a966 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
@@ -197,7 +197,8 @@ struct bdb_general_features { | |||
197 | struct child_device_config { | 197 | struct child_device_config { |
198 | u16 handle; | 198 | u16 handle; |
199 | u16 device_type; | 199 | u16 device_type; |
200 | u8 device_id[10]; /* See DEVICE_TYPE_* above */ | 200 | u8 i2c_speed; |
201 | u8 rsvd[9]; | ||
201 | u16 addin_offset; | 202 | u16 addin_offset; |
202 | u8 dvo_port; /* See Device_PORT_* above */ | 203 | u8 dvo_port; /* See Device_PORT_* above */ |
203 | u8 i2c_pin; | 204 | u8 i2c_pin; |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 6f4d128935ac..91920247d4ff 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -38,6 +38,12 @@ | |||
38 | 38 | ||
39 | #define I2C_RISEFALL_TIME 20 | 39 | #define I2C_RISEFALL_TIME 20 |
40 | 40 | ||
41 | static inline struct intel_gmbus * | ||
42 | to_intel_gmbus(struct i2c_adapter *i2c) | ||
43 | { | ||
44 | return container_of(i2c, struct intel_gmbus, adapter); | ||
45 | } | ||
46 | |||
41 | struct intel_gpio { | 47 | struct intel_gpio { |
42 | struct i2c_adapter adapter; | 48 | struct i2c_adapter adapter; |
43 | struct i2c_algo_bit_data algo; | 49 | struct i2c_algo_bit_data algo; |
@@ -71,10 +77,27 @@ static void intel_i2c_quirk_set(struct drm_i915_private *dev_priv, bool enable) | |||
71 | I915_WRITE(DSPCLK_GATE_D, val); | 77 | I915_WRITE(DSPCLK_GATE_D, val); |
72 | } | 78 | } |
73 | 79 | ||
80 | static u32 get_reserved(struct intel_gpio *gpio) | ||
81 | { | ||
82 | struct drm_i915_private *dev_priv = gpio->dev_priv; | ||
83 | struct drm_device *dev = dev_priv->dev; | ||
84 | u32 reserved = 0; | ||
85 | |||
86 | /* On most chips, these bits must be preserved in software. */ | ||
87 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
88 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | | ||
89 | GPIO_CLOCK_PULLUP_DISABLE); | ||
90 | |||
91 | return reserved; | ||
92 | } | ||
93 | |||
74 | static int get_clock(void *data) | 94 | static int get_clock(void *data) |
75 | { | 95 | { |
76 | struct intel_gpio *gpio = data; | 96 | struct intel_gpio *gpio = data; |
77 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 97 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
98 | u32 reserved = get_reserved(gpio); | ||
99 | I915_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); | ||
100 | I915_WRITE(gpio->reg, reserved); | ||
78 | return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; | 101 | return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; |
79 | } | 102 | } |
80 | 103 | ||
@@ -82,6 +105,9 @@ static int get_data(void *data) | |||
82 | { | 105 | { |
83 | struct intel_gpio *gpio = data; | 106 | struct intel_gpio *gpio = data; |
84 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 107 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
108 | u32 reserved = get_reserved(gpio); | ||
109 | I915_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); | ||
110 | I915_WRITE(gpio->reg, reserved); | ||
85 | return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; | 111 | return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; |
86 | } | 112 | } |
87 | 113 | ||
@@ -89,13 +115,8 @@ static void set_clock(void *data, int state_high) | |||
89 | { | 115 | { |
90 | struct intel_gpio *gpio = data; | 116 | struct intel_gpio *gpio = data; |
91 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 117 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
92 | struct drm_device *dev = dev_priv->dev; | 118 | u32 reserved = get_reserved(gpio); |
93 | u32 reserved = 0, clock_bits; | 119 | u32 clock_bits; |
94 | |||
95 | /* On most chips, these bits must be preserved in software. */ | ||
96 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
97 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | | ||
98 | GPIO_CLOCK_PULLUP_DISABLE); | ||
99 | 120 | ||
100 | if (state_high) | 121 | if (state_high) |
101 | clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; | 122 | clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK; |
@@ -111,13 +132,8 @@ static void set_data(void *data, int state_high) | |||
111 | { | 132 | { |
112 | struct intel_gpio *gpio = data; | 133 | struct intel_gpio *gpio = data; |
113 | struct drm_i915_private *dev_priv = gpio->dev_priv; | 134 | struct drm_i915_private *dev_priv = gpio->dev_priv; |
114 | struct drm_device *dev = dev_priv->dev; | 135 | u32 reserved = get_reserved(gpio); |
115 | u32 reserved = 0, data_bits; | 136 | u32 data_bits; |
116 | |||
117 | /* On most chips, these bits must be preserved in software. */ | ||
118 | if (!IS_I830(dev) && !IS_845G(dev)) | ||
119 | reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | | ||
120 | GPIO_CLOCK_PULLUP_DISABLE); | ||
121 | 137 | ||
122 | if (state_high) | 138 | if (state_high) |
123 | data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; | 139 | data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK; |
@@ -155,7 +171,7 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) | |||
155 | gpio->reg += PCH_GPIOA - GPIOA; | 171 | gpio->reg += PCH_GPIOA - GPIOA; |
156 | gpio->dev_priv = dev_priv; | 172 | gpio->dev_priv = dev_priv; |
157 | 173 | ||
158 | snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO %d", pin); | 174 | snprintf(gpio->adapter.name, I2C_NAME_SIZE, "GPIO%c", "?BACDEF?"[pin]); |
159 | gpio->adapter.owner = THIS_MODULE; | 175 | gpio->adapter.owner = THIS_MODULE; |
160 | gpio->adapter.algo_data = &gpio->algo; | 176 | gpio->adapter.algo_data = &gpio->algo; |
161 | gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; | 177 | gpio->adapter.dev.parent = &dev_priv->dev->pdev->dev; |
@@ -170,16 +186,6 @@ intel_gpio_create(struct drm_i915_private *dev_priv, u32 pin) | |||
170 | if (i2c_bit_add_bus(&gpio->adapter)) | 186 | if (i2c_bit_add_bus(&gpio->adapter)) |
171 | goto out_free; | 187 | goto out_free; |
172 | 188 | ||
173 | intel_i2c_reset(dev_priv->dev); | ||
174 | |||
175 | /* JJJ: raise SCL and SDA? */ | ||
176 | intel_i2c_quirk_set(dev_priv, true); | ||
177 | set_data(gpio, 1); | ||
178 | udelay(I2C_RISEFALL_TIME); | ||
179 | set_clock(gpio, 1); | ||
180 | udelay(I2C_RISEFALL_TIME); | ||
181 | intel_i2c_quirk_set(dev_priv, false); | ||
182 | |||
183 | return &gpio->adapter; | 189 | return &gpio->adapter; |
184 | 190 | ||
185 | out_free: | 191 | out_free: |
@@ -188,17 +194,27 @@ out_free: | |||
188 | } | 194 | } |
189 | 195 | ||
190 | static int | 196 | static int |
191 | quirk_i2c_transfer(struct drm_i915_private *dev_priv, | 197 | intel_i2c_quirk_xfer(struct drm_i915_private *dev_priv, |
192 | struct i2c_adapter *adapter, | 198 | struct i2c_adapter *adapter, |
193 | struct i2c_msg *msgs, | 199 | struct i2c_msg *msgs, |
194 | int num) | 200 | int num) |
195 | { | 201 | { |
202 | struct intel_gpio *gpio = container_of(adapter, | ||
203 | struct intel_gpio, | ||
204 | adapter); | ||
196 | int ret; | 205 | int ret; |
197 | 206 | ||
198 | intel_i2c_reset(dev_priv->dev); | 207 | intel_i2c_reset(dev_priv->dev); |
199 | 208 | ||
200 | intel_i2c_quirk_set(dev_priv, true); | 209 | intel_i2c_quirk_set(dev_priv, true); |
201 | ret = i2c_transfer(adapter, msgs, num); | 210 | set_data(gpio, 1); |
211 | set_clock(gpio, 1); | ||
212 | udelay(I2C_RISEFALL_TIME); | ||
213 | |||
214 | ret = adapter->algo->master_xfer(adapter, msgs, num); | ||
215 | |||
216 | set_data(gpio, 1); | ||
217 | set_clock(gpio, 1); | ||
202 | intel_i2c_quirk_set(dev_priv, false); | 218 | intel_i2c_quirk_set(dev_priv, false); |
203 | 219 | ||
204 | return ret; | 220 | return ret; |
@@ -213,21 +229,15 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
213 | struct intel_gmbus, | 229 | struct intel_gmbus, |
214 | adapter); | 230 | adapter); |
215 | struct drm_i915_private *dev_priv = adapter->algo_data; | 231 | struct drm_i915_private *dev_priv = adapter->algo_data; |
216 | int i, speed, reg_offset; | 232 | int i, reg_offset; |
217 | 233 | ||
218 | if (bus->force_bitbanging) | 234 | if (bus->force_bit) |
219 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | 235 | return intel_i2c_quirk_xfer(dev_priv, |
236 | bus->force_bit, msgs, num); | ||
220 | 237 | ||
221 | reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0; | 238 | reg_offset = HAS_PCH_SPLIT(dev_priv->dev) ? PCH_GMBUS0 - GMBUS0 : 0; |
222 | 239 | ||
223 | speed = GMBUS_RATE_100KHZ; | 240 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); |
224 | if (INTEL_INFO(dev_priv->dev)->gen > 4 || IS_G4X(dev_priv->dev)) { | ||
225 | if (bus->pin == GMBUS_PORT_DPB) /* SDVO only? */ | ||
226 | speed = GMBUS_RATE_1MHZ; | ||
227 | else | ||
228 | speed = GMBUS_RATE_400KHZ; | ||
229 | } | ||
230 | I915_WRITE(GMBUS0 + reg_offset, speed | bus->pin); | ||
231 | 241 | ||
232 | for (i = 0; i < num; i++) { | 242 | for (i = 0; i < num; i++) { |
233 | u16 len = msgs[i].len; | 243 | u16 len = msgs[i].len; |
@@ -239,6 +249,7 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
239 | (len << GMBUS_BYTE_COUNT_SHIFT) | | 249 | (len << GMBUS_BYTE_COUNT_SHIFT) | |
240 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | 250 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | |
241 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | 251 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); |
252 | POSTING_READ(GMBUS2+reg_offset); | ||
242 | do { | 253 | do { |
243 | u32 val, loop = 0; | 254 | u32 val, loop = 0; |
244 | 255 | ||
@@ -254,20 +265,35 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
254 | } while (--len && ++loop < 4); | 265 | } while (--len && ++loop < 4); |
255 | } while (len); | 266 | } while (len); |
256 | } else { | 267 | } else { |
257 | u32 val = 0, loop = 0; | 268 | u32 val, loop; |
258 | |||
259 | BUG_ON(msgs[i].len > 4); | ||
260 | 269 | ||
270 | val = loop = 0; | ||
261 | do { | 271 | do { |
262 | val |= *buf++ << (loop*8); | 272 | val |= *buf++ << (8 * loop); |
263 | } while (--len && +loop < 4); | 273 | } while (--len && ++loop < 4); |
264 | 274 | ||
265 | I915_WRITE(GMBUS3 + reg_offset, val); | 275 | I915_WRITE(GMBUS3 + reg_offset, val); |
266 | I915_WRITE(GMBUS1 + reg_offset, | 276 | I915_WRITE(GMBUS1 + reg_offset, |
267 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT ) | | 277 | (i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | |
268 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | | 278 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | |
269 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | 279 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | |
270 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | 280 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); |
281 | POSTING_READ(GMBUS2+reg_offset); | ||
282 | |||
283 | while (len) { | ||
284 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
285 | goto timeout; | ||
286 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
287 | return 0; | ||
288 | |||
289 | val = loop = 0; | ||
290 | do { | ||
291 | val |= *buf++ << (8 * loop); | ||
292 | } while (--len && ++loop < 4); | ||
293 | |||
294 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
295 | POSTING_READ(GMBUS2+reg_offset); | ||
296 | } | ||
271 | } | 297 | } |
272 | 298 | ||
273 | if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) | 299 | if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) |
@@ -279,17 +305,25 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
279 | return num; | 305 | return num; |
280 | 306 | ||
281 | timeout: | 307 | timeout: |
282 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d\n", bus->pin); | 308 | DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", |
309 | bus->reg0 & 0xff, bus->adapter.name); | ||
283 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ | 310 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ |
284 | bus->force_bitbanging = intel_gpio_create(dev_priv, bus->pin); | 311 | bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); |
285 | if (!bus->force_bitbanging) | 312 | if (!bus->force_bit) |
286 | return -ENOMEM; | 313 | return -ENOMEM; |
287 | 314 | ||
288 | return quirk_i2c_transfer(dev_priv, bus->force_bitbanging, msgs, num); | 315 | return intel_i2c_quirk_xfer(dev_priv, bus->force_bit, msgs, num); |
289 | } | 316 | } |
290 | 317 | ||
291 | static u32 gmbus_func(struct i2c_adapter *adapter) | 318 | static u32 gmbus_func(struct i2c_adapter *adapter) |
292 | { | 319 | { |
320 | struct intel_gmbus *bus = container_of(adapter, | ||
321 | struct intel_gmbus, | ||
322 | adapter); | ||
323 | |||
324 | if (bus->force_bit) | ||
325 | bus->force_bit->algo->functionality(bus->force_bit); | ||
326 | |||
293 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | 327 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
294 | /* I2C_FUNC_10BIT_ADDR | */ | 328 | /* I2C_FUNC_10BIT_ADDR | */ |
295 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | 329 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
@@ -307,15 +341,15 @@ static const struct i2c_algorithm gmbus_algorithm = { | |||
307 | */ | 341 | */ |
308 | int intel_setup_gmbus(struct drm_device *dev) | 342 | int intel_setup_gmbus(struct drm_device *dev) |
309 | { | 343 | { |
310 | static const char *names[] = { | 344 | static const char *names[GMBUS_NUM_PORTS] = { |
311 | "disabled", | 345 | "disabled", |
312 | "ssc", | 346 | "ssc", |
313 | "vga", | 347 | "vga", |
314 | "panel", | 348 | "panel", |
315 | "dpc", | 349 | "dpc", |
316 | "dpb", | 350 | "dpb", |
317 | "dpd", | ||
318 | "reserved" | 351 | "reserved" |
352 | "dpd", | ||
319 | }; | 353 | }; |
320 | struct drm_i915_private *dev_priv = dev->dev_private; | 354 | struct drm_i915_private *dev_priv = dev->dev_private; |
321 | int ret, i; | 355 | int ret, i; |
@@ -343,7 +377,8 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
343 | if (ret) | 377 | if (ret) |
344 | goto err; | 378 | goto err; |
345 | 379 | ||
346 | bus->pin = i; | 380 | /* By default use a conservative clock rate */ |
381 | bus->reg0 = i | GMBUS_RATE_100KHZ; | ||
347 | } | 382 | } |
348 | 383 | ||
349 | intel_i2c_reset(dev_priv->dev); | 384 | intel_i2c_reset(dev_priv->dev); |
@@ -360,6 +395,38 @@ err: | |||
360 | return ret; | 395 | return ret; |
361 | } | 396 | } |
362 | 397 | ||
398 | void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed) | ||
399 | { | ||
400 | struct intel_gmbus *bus = to_intel_gmbus(adapter); | ||
401 | |||
402 | /* speed: | ||
403 | * 0x0 = 100 KHz | ||
404 | * 0x1 = 50 KHz | ||
405 | * 0x2 = 400 KHz | ||
406 | * 0x3 = 1000 Khz | ||
407 | */ | ||
408 | bus->reg0 = (bus->reg0 & ~(0x3 << 8)) | (speed << 8); | ||
409 | } | ||
410 | |||
411 | void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) | ||
412 | { | ||
413 | struct intel_gmbus *bus = to_intel_gmbus(adapter); | ||
414 | |||
415 | if (force_bit) { | ||
416 | if (bus->force_bit == NULL) { | ||
417 | struct drm_i915_private *dev_priv = adapter->algo_data; | ||
418 | bus->force_bit = intel_gpio_create(dev_priv, | ||
419 | bus->reg0 & 0xff); | ||
420 | } | ||
421 | } else { | ||
422 | if (bus->force_bit) { | ||
423 | i2c_del_adapter(bus->force_bit); | ||
424 | kfree(bus->force_bit); | ||
425 | bus->force_bit = NULL; | ||
426 | } | ||
427 | } | ||
428 | } | ||
429 | |||
363 | void intel_teardown_gmbus(struct drm_device *dev) | 430 | void intel_teardown_gmbus(struct drm_device *dev) |
364 | { | 431 | { |
365 | struct drm_i915_private *dev_priv = dev->dev_private; | 432 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -370,9 +437,9 @@ void intel_teardown_gmbus(struct drm_device *dev) | |||
370 | 437 | ||
371 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 438 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
372 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 439 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
373 | if (bus->force_bitbanging) { | 440 | if (bus->force_bit) { |
374 | i2c_del_adapter(bus->force_bitbanging); | 441 | i2c_del_adapter(bus->force_bit); |
375 | kfree(bus->force_bitbanging); | 442 | kfree(bus->force_bit); |
376 | } | 443 | } |
377 | i2c_del_adapter(&bus->adapter); | 444 | i2c_del_adapter(&bus->adapter); |
378 | } | 445 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7cd2d9592d65..b684a405a05b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -68,6 +68,8 @@ struct intel_sdvo { | |||
68 | struct i2c_adapter *i2c; | 68 | struct i2c_adapter *i2c; |
69 | u8 slave_addr; | 69 | u8 slave_addr; |
70 | 70 | ||
71 | struct i2c_adapter ddc; | ||
72 | |||
71 | /* Register for the SDVO device: SDVOB or SDVOC */ | 73 | /* Register for the SDVO device: SDVOB or SDVOC */ |
72 | int sdvo_reg; | 74 | int sdvo_reg; |
73 | 75 | ||
@@ -247,49 +249,29 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) | |||
247 | 249 | ||
248 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) | 250 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
249 | { | 251 | { |
250 | u8 out_buf[2] = { addr, 0 }; | ||
251 | u8 buf[2]; | ||
252 | struct i2c_msg msgs[] = { | 252 | struct i2c_msg msgs[] = { |
253 | { | 253 | { |
254 | .addr = intel_sdvo->slave_addr >> 1, | 254 | .addr = intel_sdvo->slave_addr, |
255 | .flags = 0, | 255 | .flags = 0, |
256 | .len = 1, | 256 | .len = 1, |
257 | .buf = out_buf, | 257 | .buf = &addr, |
258 | }, | 258 | }, |
259 | { | 259 | { |
260 | .addr = intel_sdvo->slave_addr >> 1, | 260 | .addr = intel_sdvo->slave_addr, |
261 | .flags = I2C_M_RD, | 261 | .flags = I2C_M_RD, |
262 | .len = 1, | 262 | .len = 1, |
263 | .buf = buf, | 263 | .buf = ch, |
264 | } | 264 | } |
265 | }; | 265 | }; |
266 | int ret; | 266 | int ret; |
267 | 267 | ||
268 | if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2) | 268 | if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2) |
269 | { | ||
270 | *ch = buf[0]; | ||
271 | return true; | 269 | return true; |
272 | } | ||
273 | 270 | ||
274 | DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); | 271 | DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); |
275 | return false; | 272 | return false; |
276 | } | 273 | } |
277 | 274 | ||
278 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) | ||
279 | { | ||
280 | u8 out_buf[2] = { addr, ch }; | ||
281 | struct i2c_msg msgs[] = { | ||
282 | { | ||
283 | .addr = intel_sdvo->slave_addr >> 1, | ||
284 | .flags = 0, | ||
285 | .len = 2, | ||
286 | .buf = out_buf, | ||
287 | } | ||
288 | }; | ||
289 | |||
290 | return i2c_transfer(intel_sdvo->i2c, msgs, 1) == 1; | ||
291 | } | ||
292 | |||
293 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 275 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
294 | /** Mapping of command numbers to names, for debug output */ | 276 | /** Mapping of command numbers to names, for debug output */ |
295 | static const struct _sdvo_cmd_name { | 277 | static const struct _sdvo_cmd_name { |
@@ -434,32 +416,80 @@ static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
434 | DRM_LOG_KMS("\n"); | 416 | DRM_LOG_KMS("\n"); |
435 | } | 417 | } |
436 | 418 | ||
419 | static const char *cmd_status_names[] = { | ||
420 | "Power on", | ||
421 | "Success", | ||
422 | "Not supported", | ||
423 | "Invalid arg", | ||
424 | "Pending", | ||
425 | "Target not specified", | ||
426 | "Scaling not supported" | ||
427 | }; | ||
428 | |||
437 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | 429 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
438 | const void *args, int args_len) | 430 | const void *args, int args_len) |
439 | { | 431 | { |
440 | int i; | 432 | u8 buf[args_len*2 + 2], status; |
433 | struct i2c_msg msgs[args_len + 3]; | ||
434 | int i, ret; | ||
441 | 435 | ||
442 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 436 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
443 | 437 | ||
444 | for (i = 0; i < args_len; i++) { | 438 | for (i = 0; i < args_len; i++) { |
445 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, | 439 | msgs[i].addr = intel_sdvo->slave_addr; |
446 | ((u8*)args)[i])) | 440 | msgs[i].flags = 0; |
441 | msgs[i].len = 2; | ||
442 | msgs[i].buf = buf + 2 *i; | ||
443 | buf[2*i + 0] = SDVO_I2C_ARG_0 - i; | ||
444 | buf[2*i + 1] = ((u8*)args)[i]; | ||
445 | } | ||
446 | msgs[i].addr = intel_sdvo->slave_addr; | ||
447 | msgs[i].flags = 0; | ||
448 | msgs[i].len = 2; | ||
449 | msgs[i].buf = buf + 2*i; | ||
450 | buf[2*i + 0] = SDVO_I2C_OPCODE; | ||
451 | buf[2*i + 1] = cmd; | ||
452 | |||
453 | /* the following two are to read the response */ | ||
454 | status = SDVO_I2C_CMD_STATUS; | ||
455 | msgs[i+1].addr = intel_sdvo->slave_addr; | ||
456 | msgs[i+1].flags = 0; | ||
457 | msgs[i+1].len = 1; | ||
458 | msgs[i+1].buf = &status; | ||
459 | |||
460 | msgs[i+2].addr = intel_sdvo->slave_addr; | ||
461 | msgs[i+2].flags = I2C_M_RD; | ||
462 | msgs[i+2].len = 1; | ||
463 | msgs[i+2].buf = &status; | ||
464 | |||
465 | ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3); | ||
466 | if (ret < 0) { | ||
467 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | ||
468 | return false; | ||
469 | } | ||
470 | if (ret != i+3) { | ||
471 | /* failure in I2C transfer */ | ||
472 | DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); | ||
473 | return false; | ||
474 | } | ||
475 | |||
476 | i = 3; | ||
477 | while (status == SDVO_CMD_STATUS_PENDING && i--) { | ||
478 | if (!intel_sdvo_read_byte(intel_sdvo, | ||
479 | SDVO_I2C_CMD_STATUS, | ||
480 | &status)) | ||
447 | return false; | 481 | return false; |
448 | } | 482 | } |
483 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
484 | DRM_DEBUG_KMS("command returns response %s [%d]\n", | ||
485 | status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP ? cmd_status_names[status] : "???", | ||
486 | status); | ||
487 | return false; | ||
488 | } | ||
449 | 489 | ||
450 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); | 490 | return true; |
451 | } | 491 | } |
452 | 492 | ||
453 | static const char *cmd_status_names[] = { | ||
454 | "Power on", | ||
455 | "Success", | ||
456 | "Not supported", | ||
457 | "Invalid arg", | ||
458 | "Pending", | ||
459 | "Target not specified", | ||
460 | "Scaling not supported" | ||
461 | }; | ||
462 | |||
463 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | 493 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
464 | void *response, int response_len) | 494 | void *response, int response_len) |
465 | { | 495 | { |
@@ -497,13 +527,9 @@ static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
497 | SDVO_I2C_RETURN_0 + i, | 527 | SDVO_I2C_RETURN_0 + i, |
498 | &((u8 *)response)[i])) | 528 | &((u8 *)response)[i])) |
499 | goto log_fail; | 529 | goto log_fail; |
500 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | 530 | DRM_LOG_KMS(" %02X", ((u8 *)response)[i]); |
501 | } | 531 | } |
502 | |||
503 | for (; i < 8; i++) | ||
504 | DRM_LOG_KMS(" "); | ||
505 | DRM_LOG_KMS("\n"); | 532 | DRM_LOG_KMS("\n"); |
506 | |||
507 | return true; | 533 | return true; |
508 | 534 | ||
509 | log_fail: | 535 | log_fail: |
@@ -521,75 +547,17 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
521 | return 4; | 547 | return 4; |
522 | } | 548 | } |
523 | 549 | ||
524 | /** | 550 | static bool intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
525 | * Try to read the response after issuie the DDC switch command. But it | 551 | u8 ddc_bus) |
526 | * is noted that we must do the action of reading response and issuing DDC | ||
527 | * switch command in one I2C transaction. Otherwise when we try to start | ||
528 | * another I2C transaction after issuing the DDC bus switch, it will be | ||
529 | * switched to the internal SDVO register. | ||
530 | */ | ||
531 | static int intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | ||
532 | u8 target) | ||
533 | { | 552 | { |
534 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 553 | return intel_sdvo_write_cmd(intel_sdvo, |
535 | struct i2c_msg msgs[] = { | 554 | SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
536 | { | 555 | &ddc_bus, 1); |
537 | .addr = intel_sdvo->slave_addr >> 1, | ||
538 | .flags = 0, | ||
539 | .len = 2, | ||
540 | .buf = out_buf, | ||
541 | }, | ||
542 | /* the following two are to read the response */ | ||
543 | { | ||
544 | .addr = intel_sdvo->slave_addr >> 1, | ||
545 | .flags = 0, | ||
546 | .len = 1, | ||
547 | .buf = cmd_buf, | ||
548 | }, | ||
549 | { | ||
550 | .addr = intel_sdvo->slave_addr >> 1, | ||
551 | .flags = I2C_M_RD, | ||
552 | .len = 1, | ||
553 | .buf = ret_value, | ||
554 | }, | ||
555 | }; | ||
556 | |||
557 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | ||
558 | &target, 1); | ||
559 | /* write the DDC switch command argument */ | ||
560 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target)) | ||
561 | return -EIO; | ||
562 | |||
563 | out_buf[0] = SDVO_I2C_OPCODE; | ||
564 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | ||
565 | cmd_buf[0] = SDVO_I2C_CMD_STATUS; | ||
566 | cmd_buf[1] = 0; | ||
567 | ret_value[0] = 0; | ||
568 | ret_value[1] = 0; | ||
569 | |||
570 | ret = i2c_transfer(intel_sdvo->i2c, msgs, 3); | ||
571 | if (ret < 0) | ||
572 | return ret; | ||
573 | if (ret != 3) { | ||
574 | /* failure in I2C transfer */ | ||
575 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | ||
576 | return -EIO; | ||
577 | } | ||
578 | if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) { | ||
579 | DRM_DEBUG_KMS("DDC switch command returns response %d\n", | ||
580 | ret_value[0]); | ||
581 | return -EIO; | ||
582 | } | ||
583 | |||
584 | return 0; | ||
585 | } | 556 | } |
586 | 557 | ||
587 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) | 558 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
588 | { | 559 | { |
589 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) | 560 | return intel_sdvo_write_cmd(intel_sdvo, cmd, data, len); |
590 | return false; | ||
591 | |||
592 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
593 | } | 561 | } |
594 | 562 | ||
595 | static bool | 563 | static bool |
@@ -1272,7 +1240,38 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1272 | 1240 | ||
1273 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) | 1241 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
1274 | { | 1242 | { |
1275 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); | 1243 | if (!intel_sdvo_get_value(intel_sdvo, |
1244 | SDVO_CMD_GET_DEVICE_CAPS, | ||
1245 | caps, sizeof(*caps))) | ||
1246 | return false; | ||
1247 | |||
1248 | DRM_DEBUG_KMS("SDVO capabilities:\n" | ||
1249 | " vendor_id: %d\n" | ||
1250 | " device_id: %d\n" | ||
1251 | " device_rev_id: %d\n" | ||
1252 | " sdvo_version_major: %d\n" | ||
1253 | " sdvo_version_minor: %d\n" | ||
1254 | " sdvo_inputs_mask: %d\n" | ||
1255 | " smooth_scaling: %d\n" | ||
1256 | " sharp_scaling: %d\n" | ||
1257 | " up_scaling: %d\n" | ||
1258 | " down_scaling: %d\n" | ||
1259 | " stall_support: %d\n" | ||
1260 | " output_flags: %d\n", | ||
1261 | caps->vendor_id, | ||
1262 | caps->device_id, | ||
1263 | caps->device_rev_id, | ||
1264 | caps->sdvo_version_major, | ||
1265 | caps->sdvo_version_minor, | ||
1266 | caps->sdvo_inputs_mask, | ||
1267 | caps->smooth_scaling, | ||
1268 | caps->sharp_scaling, | ||
1269 | caps->up_scaling, | ||
1270 | caps->down_scaling, | ||
1271 | caps->stall_support, | ||
1272 | caps->output_flags); | ||
1273 | |||
1274 | return true; | ||
1276 | } | 1275 | } |
1277 | 1276 | ||
1278 | /* No use! */ | 1277 | /* No use! */ |
@@ -1377,16 +1376,10 @@ intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) | |||
1377 | } | 1376 | } |
1378 | 1377 | ||
1379 | static struct edid * | 1378 | static struct edid * |
1380 | intel_sdvo_get_edid(struct drm_connector *connector, int ddc) | 1379 | intel_sdvo_get_edid(struct drm_connector *connector) |
1381 | { | 1380 | { |
1382 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | 1381 | struct intel_sdvo *sdvo = intel_attached_sdvo(connector); |
1383 | int ret; | 1382 | return drm_get_edid(connector, &sdvo->ddc); |
1384 | |||
1385 | ret = intel_sdvo_set_control_bus_switch(intel_sdvo, ddc); | ||
1386 | if (ret) | ||
1387 | return NULL; | ||
1388 | |||
1389 | return drm_get_edid(connector, intel_sdvo->i2c); | ||
1390 | } | 1383 | } |
1391 | 1384 | ||
1392 | static struct drm_connector * | 1385 | static struct drm_connector * |
@@ -1447,26 +1440,27 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1447 | enum drm_connector_status status; | 1440 | enum drm_connector_status status; |
1448 | struct edid *edid; | 1441 | struct edid *edid; |
1449 | 1442 | ||
1450 | edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus); | 1443 | edid = intel_sdvo_get_edid(connector); |
1451 | 1444 | ||
1452 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { | 1445 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
1453 | u8 ddc; | 1446 | u8 ddc, saved_ddc = intel_sdvo->ddc_bus; |
1454 | 1447 | ||
1455 | /* | 1448 | /* |
1456 | * Don't use the 1 as the argument of DDC bus switch to get | 1449 | * Don't use the 1 as the argument of DDC bus switch to get |
1457 | * the EDID. It is used for SDVO SPD ROM. | 1450 | * the EDID. It is used for SDVO SPD ROM. |
1458 | */ | 1451 | */ |
1459 | for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { | 1452 | for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { |
1460 | edid = intel_sdvo_get_edid(connector, ddc); | 1453 | intel_sdvo->ddc_bus = ddc; |
1461 | if (edid) { | 1454 | edid = intel_sdvo_get_edid(connector); |
1462 | /* | 1455 | if (edid) |
1463 | * If we found the EDID on the other bus, | ||
1464 | * assume that is the correct DDC bus. | ||
1465 | */ | ||
1466 | intel_sdvo->ddc_bus = ddc; | ||
1467 | break; | 1456 | break; |
1468 | } | ||
1469 | } | 1457 | } |
1458 | /* | ||
1459 | * If we found the EDID on the other bus, | ||
1460 | * assume that is the correct DDC bus. | ||
1461 | */ | ||
1462 | if (edid == NULL) | ||
1463 | intel_sdvo->ddc_bus = saved_ddc; | ||
1470 | } | 1464 | } |
1471 | 1465 | ||
1472 | /* | 1466 | /* |
@@ -1499,7 +1493,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1499 | enum drm_connector_status ret; | 1493 | enum drm_connector_status ret; |
1500 | 1494 | ||
1501 | if (!intel_sdvo_write_cmd(intel_sdvo, | 1495 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1502 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) | 1496 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1503 | return connector_status_unknown; | 1497 | return connector_status_unknown; |
1504 | if (intel_sdvo->is_tv) { | 1498 | if (intel_sdvo->is_tv) { |
1505 | /* add 30ms delay when the output type is SDVO-TV */ | 1499 | /* add 30ms delay when the output type is SDVO-TV */ |
@@ -1508,7 +1502,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1508 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) | 1502 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1509 | return connector_status_unknown; | 1503 | return connector_status_unknown; |
1510 | 1504 | ||
1511 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1505 | DRM_DEBUG_KMS("SDVO response %d %d [%x]\n", |
1506 | response & 0xff, response >> 8, | ||
1507 | intel_sdvo_connector->output_flag); | ||
1512 | 1508 | ||
1513 | if (response == 0) | 1509 | if (response == 0) |
1514 | return connector_status_disconnected; | 1510 | return connector_status_disconnected; |
@@ -1541,11 +1537,10 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1541 | 1537 | ||
1542 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1538 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1543 | { | 1539 | { |
1544 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
1545 | struct edid *edid; | 1540 | struct edid *edid; |
1546 | 1541 | ||
1547 | /* set the bus switch and get the modes */ | 1542 | /* set the bus switch and get the modes */ |
1548 | edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus); | 1543 | edid = intel_sdvo_get_edid(connector); |
1549 | 1544 | ||
1550 | /* | 1545 | /* |
1551 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1546 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1647,7 +1642,8 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1647 | return; | 1642 | return; |
1648 | 1643 | ||
1649 | BUILD_BUG_ON(sizeof(tv_res) != 3); | 1644 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
1650 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1645 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1646 | SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | ||
1651 | &tv_res, sizeof(tv_res))) | 1647 | &tv_res, sizeof(tv_res))) |
1652 | return; | 1648 | return; |
1653 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | 1649 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) |
@@ -1924,6 +1920,7 @@ static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | |||
1924 | drm_mode_destroy(encoder->dev, | 1920 | drm_mode_destroy(encoder->dev, |
1925 | intel_sdvo->sdvo_lvds_fixed_mode); | 1921 | intel_sdvo->sdvo_lvds_fixed_mode); |
1926 | 1922 | ||
1923 | i2c_del_adapter(&intel_sdvo->ddc); | ||
1927 | intel_encoder_destroy(encoder); | 1924 | intel_encoder_destroy(encoder); |
1928 | } | 1925 | } |
1929 | 1926 | ||
@@ -1991,6 +1988,30 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
1991 | intel_sdvo_guess_ddc_bus(sdvo); | 1988 | intel_sdvo_guess_ddc_bus(sdvo); |
1992 | } | 1989 | } |
1993 | 1990 | ||
1991 | static void | ||
1992 | intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | ||
1993 | struct intel_sdvo *sdvo, u32 reg) | ||
1994 | { | ||
1995 | struct sdvo_device_mapping *mapping; | ||
1996 | u8 pin, speed; | ||
1997 | |||
1998 | if (IS_SDVOB(reg)) | ||
1999 | mapping = &dev_priv->sdvo_mappings[0]; | ||
2000 | else | ||
2001 | mapping = &dev_priv->sdvo_mappings[1]; | ||
2002 | |||
2003 | pin = GMBUS_PORT_DPB; | ||
2004 | speed = GMBUS_RATE_1MHZ >> 8; | ||
2005 | if (mapping->initialized) { | ||
2006 | pin = mapping->i2c_pin; | ||
2007 | speed = mapping->i2c_speed; | ||
2008 | } | ||
2009 | |||
2010 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; | ||
2011 | intel_gmbus_set_speed(sdvo->i2c, speed); | ||
2012 | intel_gmbus_force_bit(sdvo->i2c, true); | ||
2013 | } | ||
2014 | |||
1994 | static bool | 2015 | static bool |
1995 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) | 2016 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
1996 | { | 2017 | { |
@@ -2504,7 +2525,43 @@ static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | |||
2504 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); | 2525 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); |
2505 | else | 2526 | else |
2506 | return true; | 2527 | return true; |
2528 | } | ||
2529 | |||
2530 | static int intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, | ||
2531 | struct i2c_msg *msgs, | ||
2532 | int num) | ||
2533 | { | ||
2534 | struct intel_sdvo *sdvo = adapter->algo_data; | ||
2507 | 2535 | ||
2536 | if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus)) | ||
2537 | return -EIO; | ||
2538 | |||
2539 | return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num); | ||
2540 | } | ||
2541 | |||
2542 | static u32 intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter) | ||
2543 | { | ||
2544 | struct intel_sdvo *sdvo = adapter->algo_data; | ||
2545 | return sdvo->i2c->algo->functionality(sdvo->i2c); | ||
2546 | } | ||
2547 | |||
2548 | static const struct i2c_algorithm intel_sdvo_ddc_proxy = { | ||
2549 | .master_xfer = intel_sdvo_ddc_proxy_xfer, | ||
2550 | .functionality = intel_sdvo_ddc_proxy_func | ||
2551 | }; | ||
2552 | |||
2553 | static bool | ||
2554 | intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo, | ||
2555 | struct drm_device *dev) | ||
2556 | { | ||
2557 | sdvo->ddc.owner = THIS_MODULE; | ||
2558 | sdvo->ddc.class = I2C_CLASS_DDC; | ||
2559 | snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); | ||
2560 | sdvo->ddc.dev.parent = &dev->pdev->dev; | ||
2561 | sdvo->ddc.algo_data = sdvo; | ||
2562 | sdvo->ddc.algo = &intel_sdvo_ddc_proxy; | ||
2563 | |||
2564 | return i2c_add_adapter(&sdvo->ddc) == 0; | ||
2508 | } | 2565 | } |
2509 | 2566 | ||
2510 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2567 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
@@ -2518,6 +2575,11 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2518 | if (!intel_sdvo) | 2575 | if (!intel_sdvo) |
2519 | return false; | 2576 | return false; |
2520 | 2577 | ||
2578 | if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) { | ||
2579 | kfree(intel_sdvo); | ||
2580 | return false; | ||
2581 | } | ||
2582 | |||
2521 | intel_sdvo->sdvo_reg = sdvo_reg; | 2583 | intel_sdvo->sdvo_reg = sdvo_reg; |
2522 | 2584 | ||
2523 | intel_encoder = &intel_sdvo->base; | 2585 | intel_encoder = &intel_sdvo->base; |
@@ -2525,9 +2587,8 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2525 | /* encoder type will be decided later */ | 2587 | /* encoder type will be decided later */ |
2526 | drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); | 2588 | drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); |
2527 | 2589 | ||
2528 | intel_sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; | 2590 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1; |
2529 | 2591 | intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg); | |
2530 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | ||
2531 | 2592 | ||
2532 | /* Read the regs to test if we can talk to the device */ | 2593 | /* Read the regs to test if we can talk to the device */ |
2533 | for (i = 0; i < 0x40; i++) { | 2594 | for (i = 0; i < 0x40; i++) { |
@@ -2589,6 +2650,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2589 | 2650 | ||
2590 | err: | 2651 | err: |
2591 | drm_encoder_cleanup(&intel_encoder->base); | 2652 | drm_encoder_cleanup(&intel_encoder->base); |
2653 | i2c_del_adapter(&intel_sdvo->ddc); | ||
2592 | kfree(intel_sdvo); | 2654 | kfree(intel_sdvo); |
2593 | 2655 | ||
2594 | return false; | 2656 | return false; |