diff options
author | Hong Liu <hong.liu@intel.com> | 2008-05-12 14:38:49 +0800 |
---|---|---|
committer | Jesse Barnes <jbarnes@nietzche.virtuousgeek.org> | 2008-05-12 12:04:02 -0700 |
commit | af60d87869303d7f17352c82d2fb1cebb9a8f7ff (patch) | |
tree | 0ea18768d4020f5256ab12a091bde428c2e912f2 | |
parent | 3f66a0005c1273b0fc935b9bd62a6fabaf99c2be (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.c | 4 | ||||
-rw-r--r-- | shared-core/i915_drv.h | 1 | ||||
-rw-r--r-- | shared-core/i915_init.c | 33 |
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); } |