Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull intel drm fixes from Dave Airlie. * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/i915: vlv: fix save/restore of GFX_MAX_REQ_COUNT reg drm/i915: Workaround to avoid lite restore with HEAD==TAIL drm/i915: cope with large i2c transfers
This commit is contained in:
commit
1190944f4b
|
@ -1038,7 +1038,7 @@ static void vlv_save_gunit_s0ix_state(struct drm_i915_private *dev_priv)
|
||||||
s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4);
|
s->lra_limits[i] = I915_READ(GEN7_LRA_LIMITS_BASE + i * 4);
|
||||||
|
|
||||||
s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
|
s->media_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
|
||||||
s->gfx_max_req_count = I915_READ(GEN7_MEDIA_MAX_REQ_COUNT);
|
s->gfx_max_req_count = I915_READ(GEN7_GFX_MAX_REQ_COUNT);
|
||||||
|
|
||||||
s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7);
|
s->render_hwsp = I915_READ(RENDER_HWS_PGA_GEN7);
|
||||||
s->ecochk = I915_READ(GAM_ECOCHK);
|
s->ecochk = I915_READ(GAM_ECOCHK);
|
||||||
|
@ -1120,7 +1120,7 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *dev_priv)
|
||||||
I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]);
|
I915_WRITE(GEN7_LRA_LIMITS_BASE + i * 4, s->lra_limits[i]);
|
||||||
|
|
||||||
I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count);
|
I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->media_max_req_count);
|
||||||
I915_WRITE(GEN7_MEDIA_MAX_REQ_COUNT, s->gfx_max_req_count);
|
I915_WRITE(GEN7_GFX_MAX_REQ_COUNT, s->gfx_max_req_count);
|
||||||
|
|
||||||
I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp);
|
I915_WRITE(RENDER_HWS_PGA_GEN7, s->render_hwsp);
|
||||||
I915_WRITE(GAM_ECOCHK, s->ecochk);
|
I915_WRITE(GAM_ECOCHK, s->ecochk);
|
||||||
|
|
|
@ -2377,10 +2377,11 @@ int __i915_add_request(struct intel_engine_cs *ring,
|
||||||
ret = ring->add_request(ring);
|
ret = ring->add_request(ring);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
request->tail = intel_ring_get_tail(ringbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
request->head = request_start;
|
request->head = request_start;
|
||||||
request->tail = intel_ring_get_tail(ringbuf);
|
|
||||||
|
|
||||||
/* Whilst this request exists, batch_obj will be on the
|
/* Whilst this request exists, batch_obj will be on the
|
||||||
* active_list, and so will hold the active reference. Only when this
|
* active_list, and so will hold the active reference. Only when this
|
||||||
|
|
|
@ -1807,6 +1807,7 @@ enum skl_disp_power_wells {
|
||||||
#define GMBUS_CYCLE_INDEX (2<<25)
|
#define GMBUS_CYCLE_INDEX (2<<25)
|
||||||
#define GMBUS_CYCLE_STOP (4<<25)
|
#define GMBUS_CYCLE_STOP (4<<25)
|
||||||
#define GMBUS_BYTE_COUNT_SHIFT 16
|
#define GMBUS_BYTE_COUNT_SHIFT 16
|
||||||
|
#define GMBUS_BYTE_COUNT_MAX 256U
|
||||||
#define GMBUS_SLAVE_INDEX_SHIFT 8
|
#define GMBUS_SLAVE_INDEX_SHIFT 8
|
||||||
#define GMBUS_SLAVE_ADDR_SHIFT 1
|
#define GMBUS_SLAVE_ADDR_SHIFT 1
|
||||||
#define GMBUS_SLAVE_READ (1<<0)
|
#define GMBUS_SLAVE_READ (1<<0)
|
||||||
|
|
|
@ -270,18 +270,17 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||||
|
unsigned short addr, u8 *buf, unsigned int len,
|
||||||
u32 gmbus1_index)
|
u32 gmbus1_index)
|
||||||
{
|
{
|
||||||
int reg_offset = dev_priv->gpio_mmio_base;
|
int reg_offset = dev_priv->gpio_mmio_base;
|
||||||
u16 len = msg->len;
|
|
||||||
u8 *buf = msg->buf;
|
|
||||||
|
|
||||||
I915_WRITE(GMBUS1 + reg_offset,
|
I915_WRITE(GMBUS1 + reg_offset,
|
||||||
gmbus1_index |
|
gmbus1_index |
|
||||||
GMBUS_CYCLE_WAIT |
|
GMBUS_CYCLE_WAIT |
|
||||||
(len << GMBUS_BYTE_COUNT_SHIFT) |
|
(len << GMBUS_BYTE_COUNT_SHIFT) |
|
||||||
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||||
GMBUS_SLAVE_READ | GMBUS_SW_RDY);
|
GMBUS_SLAVE_READ | GMBUS_SW_RDY);
|
||||||
while (len) {
|
while (len) {
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -303,11 +302,35 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||||
|
u32 gmbus1_index)
|
||||||
|
{
|
||||||
|
u8 *buf = msg->buf;
|
||||||
|
unsigned int rx_size = msg->len;
|
||||||
|
unsigned int len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
len = min(rx_size, GMBUS_BYTE_COUNT_MAX);
|
||||||
|
|
||||||
|
ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
|
||||||
|
buf, len, gmbus1_index);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
rx_size -= len;
|
||||||
|
buf += len;
|
||||||
|
} while (rx_size != 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||||
|
unsigned short addr, u8 *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
int reg_offset = dev_priv->gpio_mmio_base;
|
int reg_offset = dev_priv->gpio_mmio_base;
|
||||||
u16 len = msg->len;
|
unsigned int chunk_size = len;
|
||||||
u8 *buf = msg->buf;
|
|
||||||
u32 val, loop;
|
u32 val, loop;
|
||||||
|
|
||||||
val = loop = 0;
|
val = loop = 0;
|
||||||
|
@ -319,8 +342,8 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
||||||
I915_WRITE(GMBUS3 + reg_offset, val);
|
I915_WRITE(GMBUS3 + reg_offset, val);
|
||||||
I915_WRITE(GMBUS1 + reg_offset,
|
I915_WRITE(GMBUS1 + reg_offset,
|
||||||
GMBUS_CYCLE_WAIT |
|
GMBUS_CYCLE_WAIT |
|
||||||
(msg->len << GMBUS_BYTE_COUNT_SHIFT) |
|
(chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
|
||||||
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||||
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
|
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
|
||||||
while (len) {
|
while (len) {
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -337,6 +360,29 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
||||||
|
{
|
||||||
|
u8 *buf = msg->buf;
|
||||||
|
unsigned int tx_size = msg->len;
|
||||||
|
unsigned int len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
|
||||||
|
|
||||||
|
ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
buf += len;
|
||||||
|
tx_size -= len;
|
||||||
|
} while (tx_size != 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,26 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_GEN8(ring->dev) || IS_GEN9(ring->dev)) {
|
||||||
|
/*
|
||||||
|
* WaIdleLiteRestore: make sure we never cause a lite
|
||||||
|
* restore with HEAD==TAIL
|
||||||
|
*/
|
||||||
|
if (req0 && req0->elsp_submitted) {
|
||||||
|
/*
|
||||||
|
* Apply the wa NOOPS to prevent ring:HEAD == req:TAIL
|
||||||
|
* as we resubmit the request. See gen8_emit_request()
|
||||||
|
* for where we prepare the padding after the end of the
|
||||||
|
* request.
|
||||||
|
*/
|
||||||
|
struct intel_ringbuffer *ringbuf;
|
||||||
|
|
||||||
|
ringbuf = req0->ctx->engine[ring->id].ringbuf;
|
||||||
|
req0->tail += 8;
|
||||||
|
req0->tail &= ringbuf->size - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WARN_ON(req1 && req1->elsp_submitted);
|
WARN_ON(req1 && req1->elsp_submitted);
|
||||||
|
|
||||||
execlists_submit_contexts(ring, req0->ctx, req0->tail,
|
execlists_submit_contexts(ring, req0->ctx, req0->tail,
|
||||||
|
@ -1315,7 +1335,12 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf,
|
||||||
u32 cmd;
|
u32 cmd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = intel_logical_ring_begin(ringbuf, request->ctx, 6);
|
/*
|
||||||
|
* Reserve space for 2 NOOPs at the end of each request to be
|
||||||
|
* used as a workaround for not being allowed to do lite
|
||||||
|
* restore with HEAD==TAIL (WaIdleLiteRestore).
|
||||||
|
*/
|
||||||
|
ret = intel_logical_ring_begin(ringbuf, request->ctx, 8);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1333,6 +1358,14 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf,
|
||||||
intel_logical_ring_emit(ringbuf, MI_NOOP);
|
intel_logical_ring_emit(ringbuf, MI_NOOP);
|
||||||
intel_logical_ring_advance_and_submit(ringbuf, request->ctx, request);
|
intel_logical_ring_advance_and_submit(ringbuf, request->ctx, request);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here we add two extra NOOPs as padding to avoid
|
||||||
|
* lite restore of a context with HEAD==TAIL.
|
||||||
|
*/
|
||||||
|
intel_logical_ring_emit(ringbuf, MI_NOOP);
|
||||||
|
intel_logical_ring_emit(ringbuf, MI_NOOP);
|
||||||
|
intel_logical_ring_advance(ringbuf);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue