summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ringbuffer.c
diff options
context:
space:
mode:
authorOscar Mateo <oscar.mateo@intel.com>2014-05-22 14:13:34 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-05-22 23:02:16 +0200
commit8ee149756e4fbaf4462cf3f7377456ec5fff8b63 (patch)
tree13eedaf2b463f0cf21d76cfa559e087ac2fb3647 /drivers/gpu/drm/i915/intel_ringbuffer.c
parenta4872ba6d01454dfeb251d96f623ab5d1b0666a4 (diff)
downloadop-kernel-dev-8ee149756e4fbaf4462cf3f7377456ec5fff8b63.zip
op-kernel-dev-8ee149756e4fbaf4462cf3f7377456ec5fff8b63.tar.gz
drm/i915: Split the ringbuffers from the rings (1/3)
As advanced by the previous patch, the ringbuffers and the engine command streamers belong in different structs. This is so because, while they used to be tightly coupled together, the new Logical Ring Contexts (LRC for short) have a ringbuffer each. In legacy code, we will use the buffer* pointer inside each ring to get to the pertaining ringbuffer (the actual switch will be done in the next patch). In the new Execlists code, this pointer will be NULL and we will use instead the one inside the context instead. Signed-off-by: Oscar Mateo <oscar.mateo@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ringbuffer.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 748041a..9b406e42 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1422,8 +1422,16 @@ err_unref:
static int intel_init_ring_buffer(struct drm_device *dev,
struct intel_engine_cs *ring)
{
+ struct intel_ringbuffer *ringbuf = ring->buffer;
int ret;
+ if (ringbuf == NULL) {
+ ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
+ if (!ringbuf)
+ return -ENOMEM;
+ ring->buffer = ringbuf;
+ }
+
ring->dev = dev;
INIT_LIST_HEAD(&ring->active_list);
INIT_LIST_HEAD(&ring->request_list);
@@ -1435,18 +1443,18 @@ static int intel_init_ring_buffer(struct drm_device *dev,
if (I915_NEED_GFX_HWS(dev)) {
ret = init_status_page(ring);
if (ret)
- return ret;
+ goto error;
} else {
BUG_ON(ring->id != RCS);
ret = init_phys_status_page(ring);
if (ret)
- return ret;
+ goto error;
}
ret = allocate_ring_buffer(ring);
if (ret) {
DRM_ERROR("Failed to allocate ringbuffer %s: %d\n", ring->name, ret);
- return ret;
+ goto error;
}
/* Workaround an erratum on the i830 which causes a hang if
@@ -1459,9 +1467,18 @@ static int intel_init_ring_buffer(struct drm_device *dev,
ret = i915_cmd_parser_init_ring(ring);
if (ret)
- return ret;
+ goto error;
+
+ ret = ring->init(ring);
+ if (ret)
+ goto error;
+
+ return 0;
- return ring->init(ring);
+error:
+ kfree(ringbuf);
+ ring->buffer = NULL;
+ return ret;
}
void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
@@ -1488,6 +1505,9 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
cleanup_status_page(ring);
i915_cmd_parser_fini_ring(ring);
+
+ kfree(ring->buffer);
+ ring->buffer = NULL;
}
static int intel_ring_wait_request(struct intel_engine_cs *ring, int n)
@@ -2022,15 +2042,24 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_engine_cs *ring = &dev_priv->ring[RCS];
+ struct intel_ringbuffer *ringbuf = ring->buffer;
int ret;
+ if (ringbuf == NULL) {
+ ringbuf = kzalloc(sizeof(*ringbuf), GFP_KERNEL);
+ if (!ringbuf)
+ return -ENOMEM;
+ ring->buffer = ringbuf;
+ }
+
ring->name = "render ring";
ring->id = RCS;
ring->mmio_base = RENDER_RING_BASE;
if (INTEL_INFO(dev)->gen >= 6) {
/* non-kms not supported on gen6+ */
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_ringbuf;
}
/* Note: gem is not supported on gen5/ilk without kms (the corresponding
@@ -2074,16 +2103,24 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
if (ring->virtual_start == NULL) {
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_ringbuf;
}
if (!I915_NEED_GFX_HWS(dev)) {
ret = init_phys_status_page(ring);
if (ret)
- return ret;
+ goto err_vstart;
}
return 0;
+
+err_vstart:
+ iounmap(ring->virtual_start);
+err_ringbuf:
+ kfree(ringbuf);
+ ring->buffer = NULL;
+ return ret;
}
int intel_init_bsd_ring_buffer(struct drm_device *dev)
OpenPOWER on IntegriCloud