summaryrefslogtreecommitdiff
path: root/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch')
-rw-r--r--meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch138
1 files changed, 138 insertions, 0 deletions
diff --git a/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
new file mode 100644
index 000000000..cf646f01c
--- /dev/null
+++ b/meta/packages/linux/linux-moblin2-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
@@ -0,0 +1,138 @@
+From: Keith Packard <keithp@keithp.com>
+Date: Wed, 30 Jul 2008 20:03:43 +0000 (-0700)
+Subject: i915: Initialize hardware status page at device load when possible.
+X-Git-Tag: v2.6.12-rc2
+X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=ddb354254f88965f5f057e67ef775fbb4b35fef8
+
+i915: Initialize hardware status page at device load when possible.
+
+Some chips were unstable with repeated setup/teardown of the hardware status
+page.
+
+Signed-off-by: Eric Anholt <eric@anholt.net>
+---
+
+--- a/drivers/gpu/drm/i915/i915_dma.c
++++ b/drivers/gpu/drm/i915/i915_dma.c
+@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * d
+ return -EBUSY;
+ }
+
++/**
++ * Sets up the hardware status page for devices that need a physical address
++ * in the register.
++ */
++int i915_init_phys_hws(struct drm_device *dev)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++ /* Program Hardware Status Page */
++ 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");
++ return -ENOMEM;
++ }
++ 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("Enabled hardware status page\n");
++ return 0;
++}
++
++/**
++ * Frees the hardware status page, whether it's a physical address or a virtual
++ * address set up by the X Server.
++ */
++void i915_free_hws(struct drm_device *dev)
++{
++ drm_i915_private_t *dev_priv = dev->dev_private;
++ if (dev_priv->status_page_dmah) {
++ drm_pci_free(dev, dev_priv->status_page_dmah);
++ dev_priv->status_page_dmah = NULL;
++ }
++
++ if (dev_priv->status_gfx_addr) {
++ dev_priv->status_gfx_addr = 0;
++ drm_core_ioremapfree(&dev_priv->hws_map, dev);
++ }
++
++ /* Need to rewrite hardware status page */
++ I915_WRITE(HWS_PGA, 0x1ffff000);
++}
++
+ void i915_kernel_lost_context(struct drm_device * dev)
+ {
+ drm_i915_private_t *dev_priv = dev->dev_private;
+@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_d
+ dev_priv->ring.map.size = 0;
+ }
+
+- if (dev_priv->status_page_dmah) {
+- drm_pci_free(dev, dev_priv->status_page_dmah);
+- dev_priv->status_page_dmah = NULL;
+- /* Need to rewrite hardware status page */
+- I915_WRITE(HWS_PGA, 0x1ffff000);
+- }
+-
+- if (dev_priv->status_gfx_addr) {
+- dev_priv->status_gfx_addr = 0;
+- drm_core_ioremapfree(&dev_priv->hws_map, dev);
+- I915_WRITE(HWS_PGA, 0x1ffff000);
+- }
++ /* Clear the HWS virtual address at teardown */
++ if (I915_NEED_GFX_HWS(dev))
++ i915_free_hws(dev);
+
+ return 0;
+ }
+@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_de
+ */
+ dev_priv->allow_batchbuffer = 1;
+
+- /* Program Hardware Status Page */
+- if (!I915_NEED_GFX_HWS(dev)) {
+- dev_priv->status_page_dmah =
+- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+-
+- if (!dev_priv->status_page_dmah) {
+- i915_dma_cleanup(dev);
+- DRM_ERROR("Can not allocate hardware status page\n");
+- return -ENOMEM;
+- }
+- 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("Enabled hardware status page\n");
+ return 0;
+ }
+
+@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *
+ _DRM_KERNEL | _DRM_DRIVER,
+ &dev_priv->mmio_map);
+
++ /* Init HWS */
++ if (!I915_NEED_GFX_HWS(dev)) {
++ ret = i915_init_phys_hws(dev);
++ if (ret != 0)
++ return ret;
++ }
+
+ /* On the 945G/GM, the chipset reports the MSI capability on the
+ * integrated graphics even though the support isn't actually there
+@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device
+ if (dev->pdev->msi_enabled)
+ pci_disable_msi(dev->pdev);
+
++ i915_free_hws(dev);
++
+ if (dev_priv->mmio_map)
+ drm_rmmap(dev, dev_priv->mmio_map);
+
+