diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-08 14:20:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-08 14:20:47 -0400 |
commit | 789505b05752239d957dbfa84b183e0d7a641952 (patch) | |
tree | 726e3f1e17ec6a3d8c05739d9edf9534103b18fd | |
parent | 4ed6cedeefe8bbcad7c446db939450a6c902c16d (diff) | |
parent | ec9b3a9de6b2a8a08c5250b466db92adf82b8d65 (diff) |
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie:
"Two fixes from Intel, one a regression, one because I merged an early
version of a fix.
Also the nouveau revert of the i2c code that was tested on the list."
* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
drm/nouveau/i2c: resume use of i2c-algo-bit, rather than custom stack
drm/i915: Do no set Stencil Cache eviction LRA w/a on gen7+
drm/i915: disable sdvo hotplug on i945g/gm
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_i2c.c | 199 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_i2c.h | 1 |
4 files changed, 34 insertions, 181 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 80fce51e2f43..62892a826ede 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -398,10 +398,8 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
398 | return ret; | 398 | return ret; |
399 | } | 399 | } |
400 | 400 | ||
401 | if (INTEL_INFO(dev)->gen >= 6) { | ||
402 | I915_WRITE(INSTPM, | ||
403 | INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); | ||
404 | 401 | ||
402 | if (IS_GEN6(dev)) { | ||
405 | /* From the Sandybridge PRM, volume 1 part 3, page 24: | 403 | /* From the Sandybridge PRM, volume 1 part 3, page 24: |
406 | * "If this bit is set, STCunit will have LRA as replacement | 404 | * "If this bit is set, STCunit will have LRA as replacement |
407 | * policy. [...] This bit must be reset. LRA replacement | 405 | * policy. [...] This bit must be reset. LRA replacement |
@@ -411,6 +409,11 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
411 | CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); | 409 | CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); |
412 | } | 410 | } |
413 | 411 | ||
412 | if (INTEL_INFO(dev)->gen >= 6) { | ||
413 | I915_WRITE(INSTPM, | ||
414 | INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); | ||
415 | } | ||
416 | |||
414 | return ret; | 417 | return ret; |
415 | } | 418 | } |
416 | 419 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 232d77d07d8b..ae5e748f39bb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1220,8 +1220,14 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in | |||
1220 | 1220 | ||
1221 | static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) | 1221 | static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) |
1222 | { | 1222 | { |
1223 | struct drm_device *dev = intel_sdvo->base.base.dev; | ||
1223 | u8 response[2]; | 1224 | u8 response[2]; |
1224 | 1225 | ||
1226 | /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise | ||
1227 | * on the line. */ | ||
1228 | if (IS_I945G(dev) || IS_I945GM(dev)) | ||
1229 | return false; | ||
1230 | |||
1225 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, | 1231 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
1226 | &response, 2) && response[0]; | 1232 | &response, 2) && response[0]; |
1227 | } | 1233 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index e2be95af2e52..77e564667b5c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -29,10 +29,6 @@ | |||
29 | #include "nouveau_i2c.h" | 29 | #include "nouveau_i2c.h" |
30 | #include "nouveau_hw.h" | 30 | #include "nouveau_hw.h" |
31 | 31 | ||
32 | #define T_TIMEOUT 2200000 | ||
33 | #define T_RISEFALL 1000 | ||
34 | #define T_HOLD 5000 | ||
35 | |||
36 | static void | 32 | static void |
37 | i2c_drive_scl(void *data, int state) | 33 | i2c_drive_scl(void *data, int state) |
38 | { | 34 | { |
@@ -113,175 +109,6 @@ i2c_sense_sda(void *data) | |||
113 | return 0; | 109 | return 0; |
114 | } | 110 | } |
115 | 111 | ||
116 | static void | ||
117 | i2c_delay(struct nouveau_i2c_chan *port, u32 nsec) | ||
118 | { | ||
119 | udelay((nsec + 500) / 1000); | ||
120 | } | ||
121 | |||
122 | static bool | ||
123 | i2c_raise_scl(struct nouveau_i2c_chan *port) | ||
124 | { | ||
125 | u32 timeout = T_TIMEOUT / T_RISEFALL; | ||
126 | |||
127 | i2c_drive_scl(port, 1); | ||
128 | do { | ||
129 | i2c_delay(port, T_RISEFALL); | ||
130 | } while (!i2c_sense_scl(port) && --timeout); | ||
131 | |||
132 | return timeout != 0; | ||
133 | } | ||
134 | |||
135 | static int | ||
136 | i2c_start(struct nouveau_i2c_chan *port) | ||
137 | { | ||
138 | int ret = 0; | ||
139 | |||
140 | port->state = i2c_sense_scl(port); | ||
141 | port->state |= i2c_sense_sda(port) << 1; | ||
142 | if (port->state != 3) { | ||
143 | i2c_drive_scl(port, 0); | ||
144 | i2c_drive_sda(port, 1); | ||
145 | if (!i2c_raise_scl(port)) | ||
146 | ret = -EBUSY; | ||
147 | } | ||
148 | |||
149 | i2c_drive_sda(port, 0); | ||
150 | i2c_delay(port, T_HOLD); | ||
151 | i2c_drive_scl(port, 0); | ||
152 | i2c_delay(port, T_HOLD); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static void | ||
157 | i2c_stop(struct nouveau_i2c_chan *port) | ||
158 | { | ||
159 | i2c_drive_scl(port, 0); | ||
160 | i2c_drive_sda(port, 0); | ||
161 | i2c_delay(port, T_RISEFALL); | ||
162 | |||
163 | i2c_drive_scl(port, 1); | ||
164 | i2c_delay(port, T_HOLD); | ||
165 | i2c_drive_sda(port, 1); | ||
166 | i2c_delay(port, T_HOLD); | ||
167 | } | ||
168 | |||
169 | static int | ||
170 | i2c_bitw(struct nouveau_i2c_chan *port, int sda) | ||
171 | { | ||
172 | i2c_drive_sda(port, sda); | ||
173 | i2c_delay(port, T_RISEFALL); | ||
174 | |||
175 | if (!i2c_raise_scl(port)) | ||
176 | return -ETIMEDOUT; | ||
177 | i2c_delay(port, T_HOLD); | ||
178 | |||
179 | i2c_drive_scl(port, 0); | ||
180 | i2c_delay(port, T_HOLD); | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int | ||
185 | i2c_bitr(struct nouveau_i2c_chan *port) | ||
186 | { | ||
187 | int sda; | ||
188 | |||
189 | i2c_drive_sda(port, 1); | ||
190 | i2c_delay(port, T_RISEFALL); | ||
191 | |||
192 | if (!i2c_raise_scl(port)) | ||
193 | return -ETIMEDOUT; | ||
194 | i2c_delay(port, T_HOLD); | ||
195 | |||
196 | sda = i2c_sense_sda(port); | ||
197 | |||
198 | i2c_drive_scl(port, 0); | ||
199 | i2c_delay(port, T_HOLD); | ||
200 | return sda; | ||
201 | } | ||
202 | |||
203 | static int | ||
204 | i2c_get_byte(struct nouveau_i2c_chan *port, u8 *byte, bool last) | ||
205 | { | ||
206 | int i, bit; | ||
207 | |||
208 | *byte = 0; | ||
209 | for (i = 7; i >= 0; i--) { | ||
210 | bit = i2c_bitr(port); | ||
211 | if (bit < 0) | ||
212 | return bit; | ||
213 | *byte |= bit << i; | ||
214 | } | ||
215 | |||
216 | return i2c_bitw(port, last ? 1 : 0); | ||
217 | } | ||
218 | |||
219 | static int | ||
220 | i2c_put_byte(struct nouveau_i2c_chan *port, u8 byte) | ||
221 | { | ||
222 | int i, ret; | ||
223 | for (i = 7; i >= 0; i--) { | ||
224 | ret = i2c_bitw(port, !!(byte & (1 << i))); | ||
225 | if (ret < 0) | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | ret = i2c_bitr(port); | ||
230 | if (ret == 1) /* nack */ | ||
231 | ret = -EIO; | ||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static int | ||
236 | i2c_addr(struct nouveau_i2c_chan *port, struct i2c_msg *msg) | ||
237 | { | ||
238 | u32 addr = msg->addr << 1; | ||
239 | if (msg->flags & I2C_M_RD) | ||
240 | addr |= 1; | ||
241 | return i2c_put_byte(port, addr); | ||
242 | } | ||
243 | |||
244 | static int | ||
245 | i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
246 | { | ||
247 | struct nouveau_i2c_chan *port = (struct nouveau_i2c_chan *)adap; | ||
248 | struct i2c_msg *msg = msgs; | ||
249 | int ret = 0, mcnt = num; | ||
250 | |||
251 | while (!ret && mcnt--) { | ||
252 | u8 remaining = msg->len; | ||
253 | u8 *ptr = msg->buf; | ||
254 | |||
255 | ret = i2c_start(port); | ||
256 | if (ret == 0) | ||
257 | ret = i2c_addr(port, msg); | ||
258 | |||
259 | if (msg->flags & I2C_M_RD) { | ||
260 | while (!ret && remaining--) | ||
261 | ret = i2c_get_byte(port, ptr++, !remaining); | ||
262 | } else { | ||
263 | while (!ret && remaining--) | ||
264 | ret = i2c_put_byte(port, *ptr++); | ||
265 | } | ||
266 | |||
267 | msg++; | ||
268 | } | ||
269 | |||
270 | i2c_stop(port); | ||
271 | return (ret < 0) ? ret : num; | ||
272 | } | ||
273 | |||
274 | static u32 | ||
275 | i2c_bit_func(struct i2c_adapter *adap) | ||
276 | { | ||
277 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
278 | } | ||
279 | |||
280 | const struct i2c_algorithm nouveau_i2c_bit_algo = { | ||
281 | .master_xfer = i2c_bit_xfer, | ||
282 | .functionality = i2c_bit_func | ||
283 | }; | ||
284 | |||
285 | static const uint32_t nv50_i2c_port[] = { | 112 | static const uint32_t nv50_i2c_port[] = { |
286 | 0x00e138, 0x00e150, 0x00e168, 0x00e180, | 113 | 0x00e138, 0x00e150, 0x00e168, 0x00e180, |
287 | 0x00e254, 0x00e274, 0x00e764, 0x00e780, | 114 | 0x00e254, 0x00e274, 0x00e764, 0x00e780, |
@@ -384,12 +211,10 @@ nouveau_i2c_init(struct drm_device *dev) | |||
384 | case 0: /* NV04:NV50 */ | 211 | case 0: /* NV04:NV50 */ |
385 | port->drive = entry[0]; | 212 | port->drive = entry[0]; |
386 | port->sense = entry[1]; | 213 | port->sense = entry[1]; |
387 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
388 | break; | 214 | break; |
389 | case 4: /* NV4E */ | 215 | case 4: /* NV4E */ |
390 | port->drive = 0x600800 + entry[1]; | 216 | port->drive = 0x600800 + entry[1]; |
391 | port->sense = port->drive; | 217 | port->sense = port->drive; |
392 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
393 | break; | 218 | break; |
394 | case 5: /* NV50- */ | 219 | case 5: /* NV50- */ |
395 | port->drive = entry[0] & 0x0f; | 220 | port->drive = entry[0] & 0x0f; |
@@ -402,7 +227,6 @@ nouveau_i2c_init(struct drm_device *dev) | |||
402 | port->drive = 0x00d014 + (port->drive * 0x20); | 227 | port->drive = 0x00d014 + (port->drive * 0x20); |
403 | port->sense = port->drive; | 228 | port->sense = port->drive; |
404 | } | 229 | } |
405 | port->adapter.algo = &nouveau_i2c_bit_algo; | ||
406 | break; | 230 | break; |
407 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
408 | port->drive = entry[0]; | 232 | port->drive = entry[0]; |
@@ -413,7 +237,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
413 | break; | 237 | break; |
414 | } | 238 | } |
415 | 239 | ||
416 | if (!port->adapter.algo) { | 240 | if (!port->adapter.algo && !port->drive) { |
417 | NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", | 241 | NV_ERROR(dev, "I2C%d: type %d index %x/%x unknown\n", |
418 | i, port->type, port->drive, port->sense); | 242 | i, port->type, port->drive, port->sense); |
419 | kfree(port); | 243 | kfree(port); |
@@ -429,7 +253,26 @@ nouveau_i2c_init(struct drm_device *dev) | |||
429 | port->dcb = ROM32(entry[0]); | 253 | port->dcb = ROM32(entry[0]); |
430 | i2c_set_adapdata(&port->adapter, i2c); | 254 | i2c_set_adapdata(&port->adapter, i2c); |
431 | 255 | ||
432 | ret = i2c_add_adapter(&port->adapter); | 256 | if (port->adapter.algo != &nouveau_dp_i2c_algo) { |
257 | port->adapter.algo_data = &port->bit; | ||
258 | port->bit.udelay = 10; | ||
259 | port->bit.timeout = usecs_to_jiffies(2200); | ||
260 | port->bit.data = port; | ||
261 | port->bit.setsda = i2c_drive_sda; | ||
262 | port->bit.setscl = i2c_drive_scl; | ||
263 | port->bit.getsda = i2c_sense_sda; | ||
264 | port->bit.getscl = i2c_sense_scl; | ||
265 | |||
266 | i2c_drive_scl(port, 0); | ||
267 | i2c_drive_sda(port, 1); | ||
268 | i2c_drive_scl(port, 1); | ||
269 | |||
270 | ret = i2c_bit_add_bus(&port->adapter); | ||
271 | } else { | ||
272 | port->adapter.algo = &nouveau_dp_i2c_algo; | ||
273 | ret = i2c_add_adapter(&port->adapter); | ||
274 | } | ||
275 | |||
433 | if (ret) { | 276 | if (ret) { |
434 | NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); | 277 | NV_ERROR(dev, "I2C%d: failed register: %d\n", i, ret); |
435 | kfree(port); | 278 | kfree(port); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h index 4d2e4e9031be..1d083893a4d7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.h +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h | |||
@@ -34,6 +34,7 @@ | |||
34 | struct nouveau_i2c_chan { | 34 | struct nouveau_i2c_chan { |
35 | struct i2c_adapter adapter; | 35 | struct i2c_adapter adapter; |
36 | struct drm_device *dev; | 36 | struct drm_device *dev; |
37 | struct i2c_algo_bit_data bit; | ||
37 | struct list_head head; | 38 | struct list_head head; |
38 | u8 index; | 39 | u8 index; |
39 | u8 type; | 40 | u8 type; |