fix G33 hardware status page in modeset
authorHong Liu <hong.liu@intel.com>
Mon, 12 May 2008 06:38:49 +0000 (14:38 +0800)
committerJesse Barnes <jbarnes@nietzche.virtuousgeek.org>
Mon, 12 May 2008 19:04:02 +0000 (12:04 -0700)
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.

shared-core/i915_dma.c
shared-core/i915_drv.h
shared-core/i915_init.c

index fc9e0e4..9bec85a 100644 (file)
@@ -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);
index 2e7b6bd..10e08c5 100644 (file)
@@ -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;
index b9e7e17..7183f81 100644 (file)
@@ -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);
        }