summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHong Liu <hong.liu@intel.com>2008-05-12 14:38:49 +0800
committerJesse Barnes <jbarnes@nietzche.virtuousgeek.org>2008-05-12 12:04:02 -0700
commitaf60d87869303d7f17352c82d2fb1cebb9a8f7ff (patch)
tree0ea18768d4020f5256ab12a091bde428c2e912f2
parent3f66a0005c1273b0fc935b9bd62a6fabaf99c2be (diff)
fix G33 hardware status page in modeset
We need to alloc a hw status page bo for G33 if modeset is enabled since the 2D driver can't alloc gfx memory when working in drm modeset.
-rw-r--r--shared-core/i915_dma.c4
-rw-r--r--shared-core/i915_drv.h1
-rw-r--r--shared-core/i915_init.c33
3 files changed, 38 insertions, 0 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index fc9e0e49..9bec85a1 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -997,6 +997,10 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 2e7b6bd2..10e08c55 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -124,6 +124,7 @@ struct drm_i915_private {
uint32_t counter;
unsigned int status_gfx_addr;
drm_local_map_t hws_map;
+ struct drm_buffer_object *hws_bo;
unsigned int cpp;
int use_mi_batchbuffer_start;
diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c
index b9e7e17b..7183f81f 100644
--- a/shared-core/i915_init.c
+++ b/shared-core/i915_init.c
@@ -252,6 +252,38 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
I915_WRITE(I915REG_HWS_PGA, dev_priv->dma_status_page);
+ } else {
+ size = 4 * 1024;
+ ret = drm_buffer_object_create(dev, size,
+ drm_bo_type_kernel,
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_NO_EVICT,
+ DRM_BO_HINT_DONT_FENCE, 0x1, 0,
+ &dev_priv->hws_bo);
+ if (ret < 0) {
+ DRM_ERROR("Unable to allocate or pin ring buffer\n");
+ return -EINVAL;
+ }
+ dev_priv->status_gfx_addr =
+ dev_priv->hws_bo->offset & (0x1ffff << 12);
+ dev_priv->hws_map.offset = dev->agp->base +
+ dev_priv->hws_bo->offset;
+ dev_priv->hws_map.size = size;
+ dev_priv->hws_map.type = 0;
+ dev_priv->hws_map.flags = 0;
+ dev_priv->hws_map.mtrr = 0;
+
+ drm_core_ioremap(&dev_priv->hws_map, dev);
+ if (dev_priv->hws_map.handle == NULL) {
+ dev_priv->status_gfx_addr = 0;
+ DRM_ERROR("can not ioremap virtual addr"
+ " for G33 hw status page\n");
+ return -ENOMEM;
+ }
+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
+ memset(dev_priv->hw_status_page, 0, size);
+ I915_WRITE(I915REG_HWS_PGA, dev_priv->status_gfx_addr);
}
DRM_DEBUG("Enabled hardware status page\n");
@@ -324,6 +356,7 @@ int i915_driver_unload(struct drm_device *dev)
if (dev_priv->status_gfx_addr) {
dev_priv->status_gfx_addr = 0;
drm_core_ioremapfree(&dev_priv->hws_map, dev);
+ drm_bo_usage_deref_unlocked(&dev_priv->hws_bo);
I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
}