summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@openbsd.org>2013-02-20 14:22:47 +0100
committerMark Kettenis <kettenis@openbsd.org>2013-02-20 14:29:44 +0100
commit02fde5db1e420eef2e61b24693ff27a80230b9cb (patch)
tree1fc3d59774b0b3aba17a2b5254e134cf0480ec0c /sys/dev/pci
parenta21881aeee49d175169858834d6bde0f40ca8f28 (diff)
Bring handling of physical hardwarestatus page closer to the Linux code.
Fixes a panic on older hardware because we would accidentally run the cleanup code for newer chips.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/drm/i915_drv.h2
-rw-r--r--sys/dev/pci/drm/intel_ringbuffer.c32
-rw-r--r--sys/dev/pci/drm/intel_ringbuffer.h10
3 files changed, 17 insertions, 27 deletions
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 519f67a83c1..03f4f9ccd79 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -519,6 +519,8 @@ struct inteldrm_softc {
struct intel_ring_buffer rings[I915_NUM_RINGS];
uint32_t next_seqno;
+ struct drm_dmamem *status_page_dmah;
+
union flush {
struct {
bus_space_tag_t bst;
diff --git a/sys/dev/pci/drm/intel_ringbuffer.c b/sys/dev/pci/drm/intel_ringbuffer.c
index 603ceacfb46..25fd392837b 100644
--- a/sys/dev/pci/drm/intel_ringbuffer.c
+++ b/sys/dev/pci/drm/intel_ringbuffer.c
@@ -37,7 +37,7 @@
* over cache flushing.
*/
struct pipe_control {
- union hws hws;
+ struct drm_i915_gem_object *obj;
volatile u32 *cpu_page;
u32 gtt_offset;
};
@@ -502,7 +502,6 @@ out:
int
init_pipe_control(struct intel_ring_buffer *ring)
{
-// drm_i915_private_t *dev_priv = dev->dev_private;
struct pipe_control *pc;
struct drm_i915_gem_object *obj;
int ret;
@@ -546,7 +545,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
goto err_unpin;
}
- pc->hws_obj = obj;
+ pc->obj = obj;
ring->private = pc;
return 0;
@@ -1148,10 +1147,9 @@ i915_dispatch_execbuffer(struct intel_ring_buffer *ring,
void
cleanup_status_page(struct intel_ring_buffer *ring)
{
-// struct inteldrm_softc *dev_priv = ring->dev->dev_private;
struct drm_i915_gem_object *obj;
- obj = ring->status_page.hws_obj;
+ obj = ring->status_page.obj;
if (obj == NULL)
return;
@@ -1159,13 +1157,12 @@ cleanup_status_page(struct intel_ring_buffer *ring)
(vaddr_t)ring->status_page.page_addr + PAGE_SIZE);
i915_gem_object_unpin(obj);
drm_gem_object_unreference(&obj->base);
- ring->status_page.hws_obj = NULL;
+ ring->status_page.obj = NULL;
}
int
init_status_page(struct intel_ring_buffer *ring)
{
-// struct inteldrm_softc *dev_priv = ring->dev->dev_private;
struct drm_device *dev = ring->dev;
struct drm_i915_gem_object *obj;
int ret;
@@ -1202,8 +1199,7 @@ init_status_page(struct intel_ring_buffer *ring)
ret = -ENOMEM;
goto err_unpin;
}
-
- ring->status_page.hws_obj = obj;
+ ring->status_page.obj = obj;
memset(ring->status_page.page_addr, 0, PAGE_SIZE);
intel_ring_setup_status_page(ring);
@@ -1226,21 +1222,21 @@ init_phys_hws_pga(struct intel_ring_buffer *ring)
drm_i915_private_t *dev_priv = ring->dev->dev_private;
u32 addr;
- if (ring->status_page.hws_dmamem == NULL) {
- ring->status_page.hws_dmamem = drm_dmamem_alloc(dev_priv->dmat,
+ if (!dev_priv->status_page_dmah) {
+ dev_priv->status_page_dmah = drm_dmamem_alloc(dev_priv->dmat,
PAGE_SIZE, PAGE_SIZE, 1, PAGE_SIZE, 0, BUS_DMA_READ);
- if (ring->status_page.hws_dmamem == NULL)
+ if (!dev_priv->status_page_dmah)
return -ENOMEM;
}
- addr = ring->status_page.hws_dmamem->map->dm_segs[0].ds_addr;
+ addr = dev_priv->status_page_dmah->map->dm_segs[0].ds_addr;
if (INTEL_INFO(ring->dev)->gen >= 4)
- addr |= (ring->status_page.hws_dmamem->map->dm_segs[0].ds_addr >> 28) & 0xf0;
- bus_dmamap_sync(dev_priv->dmat, ring->status_page.hws_dmamem->map, 0,
+ addr |= (dev_priv->status_page_dmah->map->dm_segs[0].ds_addr >> 28) & 0xf0;
+ bus_dmamap_sync(dev_priv->dmat, dev_priv->status_page_dmah->map, 0,
PAGE_SIZE, BUS_DMASYNC_PREREAD);
I915_WRITE(HWS_PGA, addr);
- ring->status_page.page_addr = (u32 *)ring->status_page.hws_dmamem->kva;
+ ring->status_page.page_addr = (u32 *)dev_priv->status_page_dmah->kva;
memset(ring->status_page.page_addr, 0, PAGE_SIZE);
return 0;
@@ -1257,11 +1253,11 @@ intel_read_status_page(struct intel_ring_buffer *ring, int reg)
u32 val;
if (I915_NEED_GFX_HWS(dev)) {
- obj_priv = ring->status_page.hws_obj;
+ obj_priv = ring->status_page.obj;
map = obj_priv->dmamap;
tag = dev_priv->agpdmat;
} else {
- map = ring->status_page.hws_dmamem->map;
+ map = dev_priv->status_page_dmah->map;
tag = dev->dmat;
}
/* Ensure that the compiler doesn't optimize away the load. */
diff --git a/sys/dev/pci/drm/intel_ringbuffer.h b/sys/dev/pci/drm/intel_ringbuffer.h
index 8bda2ece499..3226cd0b64c 100644
--- a/sys/dev/pci/drm/intel_ringbuffer.h
+++ b/sys/dev/pci/drm/intel_ringbuffer.h
@@ -14,18 +14,10 @@
*/
#define I915_RING_FREE_SPACE 64
-union hws {
- struct drm_i915_gem_object *obj;
- struct drm_dmamem *dmamem;
-};
-#define hws_obj hws.obj
-#define hws_dmamem hws.dmamem
-
struct intel_hw_status_page {
u32 *page_addr;
unsigned int gfx_addr;
-
- union hws hws;
+ struct drm_i915_gem_object *obj;
};
#define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base))