diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 66 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lrc.c | 35 |
5 files changed, 95 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c24c3f1ff8a3..c302ffb5a168 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -1038,7 +1038,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv) | |||
| 1038 | s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4); | 1038 | s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4); |
| 1039 | 1039 | ||
| 1040 | s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); | 1040 | s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); |
| 1041 | s->gfx_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT); | 1041 | s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT); |
| 1042 | 1042 | ||
| 1043 | s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7); | 1043 | s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7); |
| 1044 | s->ecochk = I915_READ(GAM_ECOCHK); | 1044 | s->ecochk = I915_READ(GAM_ECOCHK); |
| @@ -1120,7 +1120,7 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv) | |||
| 1120 | I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]); | 1120 | I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]); |
| 1121 | 1121 | ||
| 1122 | I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); | 1122 | I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count); |
| 1123 | I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->gfx_max_req_count); | 1123 | I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count); |
| 1124 | 1124 | ||
| 1125 | I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); | 1125 | I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp); |
| 1126 | I915_WRITE(GAM_ECOCHK, s->ecochk); | 1126 | I915_WRITE(GAM_ECOCHK, s->ecochk); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d07c0b1fb498..53394f998a1f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -2377,10 +2377,11 @@ int __i915_add_request(struct intel_engine_cs *ring, | |||
| 2377 | ret = ring->add_request(ring); | 2377 | ret = ring->add_request(ring); |
| 2378 | if (ret) | 2378 | if (ret) |
| 2379 | return ret; | 2379 | return ret; |
| 2380 | |||
| 2381 | request->tail = intel_ring_get_tail(ringbuf); | ||
| 2380 | } | 2382 | } |
| 2381 | 2383 | ||
| 2382 | request->head = request_start; | 2384 | request->head = request_start; |
| 2383 | request->tail = intel_ring_get_tail(ringbuf); | ||
| 2384 | 2385 | ||
| 2385 | /* Whilst this request exists, batch_obj will be on the | 2386 | /* Whilst this request exists, batch_obj will be on the |
| 2386 | * active_list, and so will hold the active reference. Only when this | 2387 | * active_list, and so will hold the active reference. Only when this |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b522eb6e59a4..3da1af46625c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -1807,6 +1807,7 @@ enum skl_disp_power_wells { | |||
| 1807 | #define GMBUS_CYCLE_INDEX (2<<25) | 1807 | #define GMBUS_CYCLE_INDEX (2<<25) |
| 1808 | #define GMBUS_CYCLE_STOP (4<<25) | 1808 | #define GMBUS_CYCLE_STOP (4<<25) |
| 1809 | #define GMBUS_BYTE_COUNT_SHIFT 16 | 1809 | #define GMBUS_BYTE_COUNT_SHIFT 16 |
| 1810 | #define GMBUS_BYTE_COUNT_MAX 256U | ||
| 1810 | #define GMBUS_SLAVE_INDEX_SHIFT 8 | 1811 | #define GMBUS_SLAVE_INDEX_SHIFT 8 |
| 1811 | #define GMBUS_SLAVE_ADDR_SHIFT 1 | 1812 | #define GMBUS_SLAVE_ADDR_SHIFT 1 |
| 1812 | #define GMBUS_SLAVE_READ (1<<0) | 1813 | #define GMBUS_SLAVE_READ (1<<0) |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index b31088a551f2..56e437e31580 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
| @@ -270,18 +270,17 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv) | |||
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | static int | 272 | static int |
| 273 | gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | 273 | gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv, |
| 274 | u32 gmbus1_index) | 274 | unsigned short addr, u8 *buf, unsigned int len, |
| 275 | u32 gmbus1_index) | ||
| 275 | { | 276 | { |
| 276 | int reg_offset = dev_priv->gpio_mmio_base; | 277 | int reg_offset = dev_priv->gpio_mmio_base; |
| 277 | u16 len = msg->len; | ||
| 278 | u8 *buf = msg->buf; | ||
| 279 | 278 | ||
| 280 | I915_WRITE(GMBUS1 + reg_offset, | 279 | I915_WRITE(GMBUS1 + reg_offset, |
| 281 | gmbus1_index | | 280 | gmbus1_index | |
| 282 | GMBUS_CYCLE_WAIT | | 281 | GMBUS_CYCLE_WAIT | |
| 283 | (len << GMBUS_BYTE_COUNT_SHIFT) | | 282 | (len << GMBUS_BYTE_COUNT_SHIFT) | |
| 284 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | 283 | (addr << GMBUS_SLAVE_ADDR_SHIFT) | |
| 285 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | 284 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); |
| 286 | while (len) { | 285 | while (len) { |
| 287 | int ret; | 286 | int ret; |
| @@ -303,11 +302,35 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | |||
| 303 | } | 302 | } |
| 304 | 303 | ||
| 305 | static int | 304 | static int |
| 306 | gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) | 305 | gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, |
| 306 | u32 gmbus1_index) | ||
| 307 | { | 307 | { |
| 308 | int reg_offset = dev_priv->gpio_mmio_base; | ||
| 309 | u16 len = msg->len; | ||
| 310 | u8 *buf = msg->buf; | 308 | u8 *buf = msg->buf; |
| 309 | unsigned int rx_size = msg->len; | ||
| 310 | unsigned int len; | ||
| 311 | int ret; | ||
| 312 | |||
| 313 | do { | ||
| 314 | len = min(rx_size, GMBUS_BYTE_COUNT_MAX); | ||
| 315 | |||
| 316 | ret = gmbus_xfer_read_chunk(dev_priv, msg->addr, | ||
| 317 | buf, len, gmbus1_index); | ||
| 318 | if (ret) | ||
| 319 | return ret; | ||
| 320 | |||
| 321 | rx_size -= len; | ||
| 322 | buf += len; | ||
| 323 | } while (rx_size != 0); | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | static int | ||
| 329 | gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv, | ||
| 330 | unsigned short addr, u8 *buf, unsigned int len) | ||
| 331 | { | ||
| 332 | int reg_offset = dev_priv->gpio_mmio_base; | ||
| 333 | unsigned int chunk_size = len; | ||
| 311 | u32 val, loop; | 334 | u32 val, loop; |
| 312 | 335 | ||
| 313 | val = loop = 0; | 336 | val = loop = 0; |
| @@ -319,8 +342,8 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) | |||
| 319 | I915_WRITE(GMBUS3 + reg_offset, val); | 342 | I915_WRITE(GMBUS3 + reg_offset, val); |
| 320 | I915_WRITE(GMBUS1 + reg_offset, | 343 | I915_WRITE(GMBUS1 + reg_offset, |
| 321 | GMBUS_CYCLE_WAIT | | 344 | GMBUS_CYCLE_WAIT | |
| 322 | (msg->len << GMBUS_BYTE_COUNT_SHIFT) | | 345 | (chunk_size << GMBUS_BYTE_COUNT_SHIFT) | |
| 323 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | 346 | (addr << GMBUS_SLAVE_ADDR_SHIFT) | |
| 324 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | 347 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); |
| 325 | while (len) { | 348 | while (len) { |
| 326 | int ret; | 349 | int ret; |
| @@ -337,6 +360,29 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) | |||
| 337 | if (ret) | 360 | if (ret) |
| 338 | return ret; | 361 | return ret; |
| 339 | } | 362 | } |
| 363 | |||
| 364 | return 0; | ||
| 365 | } | ||
| 366 | |||
| 367 | static int | ||
| 368 | gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg) | ||
| 369 | { | ||
| 370 | u8 *buf = msg->buf; | ||
| 371 | unsigned int tx_size = msg->len; | ||
| 372 | unsigned int len; | ||
| 373 | int ret; | ||
| 374 | |||
| 375 | do { | ||
| 376 | len = min(tx_size, GMBUS_BYTE_COUNT_MAX); | ||
| 377 | |||
| 378 | ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len); | ||
| 379 | if (ret) | ||
| 380 | return ret; | ||
| 381 | |||
| 382 | buf += len; | ||
| 383 | tx_size -= len; | ||
| 384 | } while (tx_size != 0); | ||
| 385 | |||
| 340 | return 0; | 386 | return 0; |
| 341 | } | 387 | } |
| 342 | 388 | ||
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index fcb074bd55dc..09df74b8e917 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
| @@ -393,6 +393,26 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) | |||
| 393 | } | 393 | } |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) { | ||
| 397 | /* | ||
| 398 | * WaIdleLiteRestore: make sure we never cause a lite | ||
| 399 | * restore with HEAD==TAIL | ||
| 400 | */ | ||
| 401 | if (req0 && req0->elsp_submitted) { | ||
| 402 | /* | ||
| 403 | * Apply the wa NOOPS to prevent ring:HEAD == req:TAIL | ||
| 404 | * as we resubmit the request. See gen8_emit_request() | ||
| 405 | * for where we prepare the padding after the end of the | ||
| 406 | * request. | ||
| 407 | */ | ||
| 408 | struct intel_ringbuffer *ringbuf; | ||
| 409 | |||
| 410 | ringbuf = req0->ctx->engine[ring->id].ringbuf; | ||
| 411 | req0->tail += 8; | ||
| 412 | req0->tail &= ringbuf->size - 1; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 396 | WARN_ON(req1 && req1->elsp_submitted); | 416 | WARN_ON(req1 && req1->elsp_submitted); |
| 397 | 417 | ||
| 398 | execlists_submit_contexts(ring, req0->ctx, req0->tail, | 418 | execlists_submit_contexts(ring, req0->ctx, req0->tail, |
| @@ -1315,7 +1335,12 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf, | |||
| 1315 | u32 cmd; | 1335 | u32 cmd; |
| 1316 | int ret; | 1336 | int ret; |
| 1317 | 1337 | ||
| 1318 | ret = intel_logical_ring_begin(ringbuf, request->ctx, 6); | 1338 | /* |
| 1339 | * Reserve space for 2 NOOPs at the end of each request to be | ||
| 1340 | * used as a workaround for not being allowed to do lite | ||
| 1341 | * restore with HEAD==TAIL (WaIdleLiteRestore). | ||
| 1342 | */ | ||
| 1343 | ret = intel_logical_ring_begin(ringbuf, request->ctx, 8); | ||
| 1319 | if (ret) | 1344 | if (ret) |
| 1320 | return ret; | 1345 | return ret; |
| 1321 | 1346 | ||
| @@ -1333,6 +1358,14 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf, | |||
| 1333 | intel_logical_ring_emit(ringbuf, MI_NOOP); | 1358 | intel_logical_ring_emit(ringbuf, MI_NOOP); |
| 1334 | intel_logical_ring_advance_and_submit(ringbuf, request->ctx, request); | 1359 | intel_logical_ring_advance_and_submit(ringbuf, request->ctx, request); |
| 1335 | 1360 | ||
| 1361 | /* | ||
| 1362 | * Here we add two extra NOOPs as padding to avoid | ||
| 1363 | * lite restore of a context with HEAD==TAIL. | ||
| 1364 | */ | ||
| 1365 | intel_logical_ring_emit(ringbuf, MI_NOOP); | ||
| 1366 | intel_logical_ring_emit(ringbuf, MI_NOOP); | ||
| 1367 | intel_logical_ring_advance(ringbuf); | ||
| 1368 | |||
| 1336 | return 0; | 1369 | return 0; |
| 1337 | } | 1370 | } |
| 1338 | 1371 | ||
