diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-26 17:28:15 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-03 05:18:30 -0400 |
commit | 316d388450be37fedcf4b37cf211b2bdc7826bb8 (patch) | |
tree | 612fe444f92726f615abc03e7d0aaca587a3cbc3 | |
parent | 627965ad3e2f8aa9311f8b238060ddb648268f6b (diff) |
drm/i915: rework legacy GFX HWS handling
To get the fun stuff out of the way, the legacy hws is allocated by
userspace when the gpu needs a gfx hws. And there's no reference-counting
going on, so userspace can simply screw everyone over.
At least it's not as horrible as i810, where the ringbuffer is allocated
by userspace ...
We can't fix this disaster, but we can at least tidy up the code a
bit to make things clearer:
- Drop the drm ioremap indirection.
- Add a new new read_legacy_status_page to paper over the differences
between the legacy gfx hws and the physical hws shared with the
new ringbuffer code.
- Add a pointer in dev_priv->dri1 for the cpu addresses - that one is
an iomem remapping as opposed to all other hw status pages. This is
just prep work to make sparse happy.
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 |
2 files changed, 17 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1b1f8e70df8d..f0c0a7ed90e5 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -67,7 +67,16 @@ | |||
67 | LOCK_TEST_WITH_RETURN(dev, file); \ | 67 | LOCK_TEST_WITH_RETURN(dev, file); \ |
68 | } while (0) | 68 | } while (0) |
69 | 69 | ||
70 | #define READ_HWSP(dev_priv, reg) intel_read_status_page(LP_RING(dev_priv), reg) | 70 | static inline u32 |
71 | intel_read_legacy_status_page(struct drm_i915_private *dev_priv, int reg) | ||
72 | { | ||
73 | if (I915_NEED_GFX_HWS(dev_priv->dev)) | ||
74 | return ioread32(dev_priv->dri1.gfx_hws_cpu_addr + reg); | ||
75 | else | ||
76 | return intel_read_status_page(LP_RING(dev_priv), reg); | ||
77 | } | ||
78 | |||
79 | #define READ_HWSP(dev_priv, reg) intel_read_legacy_status_page(dev_priv, reg) | ||
71 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) | 80 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
72 | #define I915_BREADCRUMB_INDEX 0x21 | 81 | #define I915_BREADCRUMB_INDEX 0x21 |
73 | 82 | ||
@@ -137,7 +146,7 @@ static void i915_free_hws(struct drm_device *dev) | |||
137 | 146 | ||
138 | if (ring->status_page.gfx_addr) { | 147 | if (ring->status_page.gfx_addr) { |
139 | ring->status_page.gfx_addr = 0; | 148 | ring->status_page.gfx_addr = 0; |
140 | drm_core_ioremapfree(&dev_priv->hws_map, dev); | 149 | iounmap(dev_priv->dri1.gfx_hws_cpu_addr); |
141 | } | 150 | } |
142 | 151 | ||
143 | /* Need to rewrite hardware status page */ | 152 | /* Need to rewrite hardware status page */ |
@@ -1073,23 +1082,17 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
1073 | 1082 | ||
1074 | ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); | 1083 | ring->status_page.gfx_addr = hws->addr & (0x1ffff<<12); |
1075 | 1084 | ||
1076 | dev_priv->hws_map.offset = dev->agp->base + hws->addr; | 1085 | dev_priv->dri1.gfx_hws_cpu_addr = ioremap_wc(dev->agp->base + hws->addr, |
1077 | dev_priv->hws_map.size = 4*1024; | 1086 | 4096); |
1078 | dev_priv->hws_map.type = 0; | 1087 | if (dev_priv->dri1.gfx_hws_cpu_addr == NULL) { |
1079 | dev_priv->hws_map.flags = 0; | ||
1080 | dev_priv->hws_map.mtrr = 0; | ||
1081 | |||
1082 | drm_core_ioremap_wc(&dev_priv->hws_map, dev); | ||
1083 | if (dev_priv->hws_map.handle == NULL) { | ||
1084 | i915_dma_cleanup(dev); | 1088 | i915_dma_cleanup(dev); |
1085 | ring->status_page.gfx_addr = 0; | 1089 | ring->status_page.gfx_addr = 0; |
1086 | DRM_ERROR("can not ioremap virtual address for" | 1090 | DRM_ERROR("can not ioremap virtual address for" |
1087 | " G33 hw status page\n"); | 1091 | " G33 hw status page\n"); |
1088 | return -ENOMEM; | 1092 | return -ENOMEM; |
1089 | } | 1093 | } |
1090 | ring->status_page.page_addr = | 1094 | |
1091 | (void __force __iomem *)dev_priv->hws_map.handle; | 1095 | memset_io(dev_priv->dri1.gfx_hws_cpu_addr, 0, PAGE_SIZE); |
1092 | memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); | ||
1093 | I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); | 1096 | I915_WRITE(HWS_PGA, ring->status_page.gfx_addr); |
1094 | 1097 | ||
1095 | DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", | 1098 | DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7d48ae3d7678..1f2510931019 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -369,7 +369,6 @@ typedef struct drm_i915_private { | |||
369 | 369 | ||
370 | drm_dma_handle_t *status_page_dmah; | 370 | drm_dma_handle_t *status_page_dmah; |
371 | uint32_t counter; | 371 | uint32_t counter; |
372 | drm_local_map_t hws_map; | ||
373 | struct drm_i915_gem_object *pwrctx; | 372 | struct drm_i915_gem_object *pwrctx; |
374 | struct drm_i915_gem_object *renderctx; | 373 | struct drm_i915_gem_object *renderctx; |
375 | 374 | ||
@@ -743,6 +742,7 @@ typedef struct drm_i915_private { | |||
743 | * here! */ | 742 | * here! */ |
744 | struct { | 743 | struct { |
745 | unsigned allow_batchbuffer : 1; | 744 | unsigned allow_batchbuffer : 1; |
745 | u32 __iomem *gfx_hws_cpu_addr; | ||
746 | } dri1; | 746 | } dri1; |
747 | 747 | ||
748 | /* Kernel Modesetting */ | 748 | /* Kernel Modesetting */ |