summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/i915_dma.c1
-rw-r--r--sys/dev/pci/drm/i915_drv.c39
-rw-r--r--sys/dev/pci/drm/i915_drv.h3
3 files changed, 31 insertions, 12 deletions
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c
index bf6694256f0..4e79f63ea4e 100644
--- a/sys/dev/pci/drm/i915_dma.c
+++ b/sys/dev/pci/drm/i915_dma.c
@@ -117,7 +117,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
}
dev_priv->ring.size = init->ring_size;
- dev_priv->ring.tail_mask = dev_priv->ring.size - 1;
if ((ret = bus_space_map(dev_priv->bst, init->ring_start,
init->ring_size, 0, &dev_priv->ring.bsh)) != 0) {
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 7e8ab1d0636..5dbe9bf574c 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -41,6 +41,8 @@ int inteldrm_detach(struct device *, int);
int inteldrm_ioctl(struct drm_device *, u_long, caddr_t, struct drm_file *);
int inteldrm_activate(struct device *, int);
+void inteldrm_wrap_ring(struct drm_i915_private *);
+
/* For reset and suspend */
int inteldrm_save_state(struct drm_i915_private *);
int inteldrm_restore_state(struct drm_i915_private *);
@@ -342,13 +344,35 @@ inteldrm_wait_ring(struct drm_i915_private *dev_priv, int n)
}
void
+inteldrm_wrap_ring(struct drm_i915_private *dev_priv)
+{
+ u_int32_t rem;;
+
+ rem = dev_priv->ring.size - dev_priv->ring.tail;
+ if (dev_priv->ring.space < rem &&
+ inteldrm_wait_ring(dev_priv, rem) != 0)
+ return; /* XXX */
+
+ bus_space_set_region_4(dev_priv->bst, dev_priv->ring.bsh,
+ dev_priv->ring.woffset, MI_NOOP, rem / 4);
+
+ dev_priv->ring.tail = 0;
+}
+
+void
inteldrm_begin_ring(struct drm_i915_private *dev_priv, int ncmd)
{
+ int bytes = 4 * ncmd;
+
INTELDRM_VPRINTF("%s: %d\n", __func__, ncmd);
- if (dev_priv->ring.space < ncmd * 4)
- inteldrm_wait_ring(dev_priv, ncmd * 4);
- dev_priv->ring.wspace = 0;
+ if (dev_priv->ring.tail + bytes > dev_priv->ring.size)
+ inteldrm_wrap_ring(dev_priv);
+ if (dev_priv->ring.space < bytes)
+ inteldrm_wait_ring(dev_priv, bytes);
dev_priv->ring.woffset = dev_priv->ring.tail;
+ dev_priv->ring.tail += bytes;
+ dev_priv->ring.tail &= dev_priv->ring.size - 1;
+ dev_priv->ring.space -= bytes;
}
void
@@ -357,10 +381,11 @@ inteldrm_out_ring(struct drm_i915_private *dev_priv, u_int32_t cmd)
INTELDRM_VPRINTF("%s: %x\n", __func__, cmd);
bus_space_write_4(dev_priv->bst, dev_priv->ring.bsh,
dev_priv->ring.woffset, cmd);
- dev_priv->ring.wspace++;
- /* deal with ring wrapping */
+ /*
+ * don't need to deal with wrap here because we padded
+ * the ring out if we would wrap
+ */
dev_priv->ring.woffset += 4;
- dev_priv->ring.woffset &= dev_priv->ring.tail_mask;
}
void
@@ -368,8 +393,6 @@ inteldrm_advance_ring(struct drm_i915_private *dev_priv)
{
INTELDRM_VPRINTF("%s: %x, %x\n", __func__, dev_priv->ring.wspace,
dev_priv->ring.woffset);
- dev_priv->ring.tail = dev_priv->ring.woffset;
- dev_priv->ring.space -= dev_priv->ring.wspace * 4;
I915_WRITE(PRB0_TAIL, dev_priv->ring.woffset);
}
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 30e8c6d99b3..eb1bf7ecaa7 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -59,15 +59,12 @@ enum pipe {
#define DRIVER_PATCHLEVEL 0
struct inteldrm_ring {
- u_int32_t *kva;
bus_space_handle_t bsh;
bus_size_t size;
u_int32_t head;
u_int32_t space;
u_int32_t tail;
- u_int32_t tail_mask;
u_int32_t woffset;
- u_int32_t wspace;
};
typedef struct drm_i915_private {