Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59fd7e4b authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2015-04-25' of...

Merge tag 'drm-intel-next-fixes-2015-04-25' of git://anongit.freedesktop.org/drm-intel into drm-fixes

three fixes for i915.

* tag 'drm-intel-next-fixes-2015-04-25' of git://anongit.freedesktop.org/drm-intel:
  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
parents c8b3fd0c b5f1c97f
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -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);
+2 −1
Original line number Original line Diff line number Diff line
@@ -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
+1 −0
Original line number Original line Diff line number Diff line
@@ -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)
+56 −10
Original line number Original line Diff line number Diff line
@@ -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)
{
{
	int reg_offset = dev_priv->gpio_mmio_base;
	u16 len = msg->len;
	u8 *buf = msg->buf;
	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;
	unsigned int chunk_size = len;
	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;
}
}


+34 −1
Original line number Original line Diff line number Diff line
@@ -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;
}
}