summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-02-15 20:33:05 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-02-15 20:33:05 +0000
commit74feca93240143f54c80e1215bab92b4763b4fb7 (patch)
tree7cbe5126154cf67b7d7f51d66850f65cdbfb0db0
parent11b653c4562312a54ce0d4e467e5d9d84693ef7a (diff)
for the sake of correctness bus_dmamap_sync when necessary for the
hardware-status-page.
-rw-r--r--sys/dev/pci/drm/i915_dma.c7
-rw-r--r--sys/dev/pci/drm/i915_drv.c22
-rw-r--r--sys/dev/pci/drm/i915_drv.h3
3 files changed, 30 insertions, 2 deletions
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c
index 79959d9e264..e3da1437e7a 100644
--- a/sys/dev/pci/drm/i915_dma.c
+++ b/sys/dev/pci/drm/i915_dma.c
@@ -86,6 +86,8 @@ i915_init_phys_hws(drm_i915_private_t *dev_priv, bus_dma_tag_t dmat)
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ bus_dmamap_sync(dmat, dev_priv->hws_dmamem->map, 0, PAGE_SIZE,
+ BUS_DMASYNC_PREREAD);
I915_WRITE(HWS_PGA, dev_priv->hws_dmamem->map->dm_segs[0].ds_addr);
DRM_DEBUG("Enabled hardware status page\n");
return (0);
@@ -221,9 +223,12 @@ static int i915_dma_resume(struct drm_device * dev)
if (dev_priv->status_gfx_addr != 0)
I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
- else
+ else {
+ bus_dmamap_sync(dev->dmat, dev_priv->hws_dmamem->map, 0,
+ PAGE_SIZE, BUS_DMASYNC_PREREAD);
I915_WRITE(HWS_PGA,
dev_priv->hws_dmamem->map->dm_segs[0].ds_addr);
+ }
DRM_DEBUG("Enabled hardware status page\n");
return 0;
diff --git a/sys/dev/pci/drm/i915_drv.c b/sys/dev/pci/drm/i915_drv.c
index 3a63b4d29e9..96ec2ce995a 100644
--- a/sys/dev/pci/drm/i915_drv.c
+++ b/sys/dev/pci/drm/i915_drv.c
@@ -244,3 +244,25 @@ inteldrm_ioctl(struct drm_device *dev, u_long cmd, caddr_t data,
}
return (EINVAL);
}
+
+u_int32_t
+inteldrm_read_hws(struct drm_i915_private *dev_priv, int reg)
+{
+ struct drm_device *dev = (struct drm_device *)dev_priv->drmdev;
+ u_int32_t val;
+
+ /*
+ * When we eventually go GEM only we'll always have a dmamap, so this
+ * madness won't be for long.
+ */
+ if (dev_priv->hws_dmamem)
+ bus_dmamap_sync(dev->dmat, dev_priv->hws_dmamem->map, 0,
+ PAGE_SIZE, BUS_DMASYNC_POSTREAD);
+
+ val = ((volatile u_int32_t *)(dev_priv->hw_status_page))[reg];
+
+ if (dev_priv->hws_dmamem)
+ bus_dmamap_sync(dev->dmat, dev_priv->hws_dmamem->map, 0,
+ PAGE_SIZE, BUS_DMASYNC_PREREAD);
+ return (val);
+}
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index 382521738a7..e3e4cdfce81 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -214,6 +214,7 @@ typedef struct drm_i915_private {
#define CHIP_HWS 0x8000
/* i915_dma.c */
+u_int32_t inteldrm_read_hws(struct drm_i915_private *, int);
extern void i915_kernel_lost_context(struct drm_device * dev);
extern void i915_driver_lastclose(struct drm_device * dev);
extern void i915_driver_close(struct drm_device *dev,
@@ -446,7 +447,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
*
* The area from dword 0x20 to 0x3ff is available for driver usage.
*/
-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
+#define READ_HWSP(dev_priv, reg) inteldrm_read_hws(dev_priv, reg)
#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX)
#define I915_GEM_HWS_INDEX 0x20
#define I915_BREADCRUMB_INDEX 0x21