OSDN Git Service

i915: setup hardware status page if physical addrs are required
authorJesse Barnes <jbarnes@virtuousgeek.org>
Wed, 13 Aug 2008 18:39:22 +0000 (11:39 -0700)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Wed, 13 Aug 2008 18:39:22 +0000 (11:39 -0700)
Needed for the modesetting case where we initialize the ring at load time.

shared-core/i915_init.c

index 4f2d3a4..b21351c 100644 (file)
@@ -100,6 +100,32 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
        return 0;
 }
 
+static int
+i915_init_hws_phys(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret = 0;
+
+       dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE,
+                                                  0xffffffff);
+
+       if (!dev_priv->status_page_dmah) {
+               DRM_ERROR("Can not allocate hardware status page\n");
+               ret = -ENOMEM;
+               goto out;
+       }
+       dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+       dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
+
+       memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+
+       I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
+       DRM_DEBUG("hws kernel virt: 0x%p\n", dev_priv->hw_status_page);
+
+out:
+       return ret;
+}
+
 static int i915_load_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -113,6 +139,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
        /* Let GEM Manage from end of prealloc space to end of aperture */
        i915_gem_do_init(dev, prealloc_size, agp_size);
 
+       if (!I915_NEED_GFX_HWS(dev))
+               i915_init_hws_phys(dev);
+
        ret = i915_gem_init_ringbuffer(dev);
        if (ret)
                goto out;
@@ -354,6 +383,8 @@ int i915_driver_unload(struct drm_device *dev)
                mutex_unlock(&dev->struct_mutex);
                drm_mm_takedown(&dev_priv->vram);
                i915_gem_lastclose(dev);
+               if (!I915_NEED_GFX_HWS(dev))
+                       drm_pci_free(dev, dev_priv->status_page_dmah);
        }
 
         drm_rmmap(dev, dev_priv->mmio_map);