1 From: Keith Packard <keithp@keithp.com>
2 Date: Wed, 30 Jul 2008 20:03:43 +0000 (-0700)
3 Subject: i915: Initialize hardware status page at device load when possible.
5 X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=ddb354254f88965f5f057e67ef775fbb4b35fef8
7 i915: Initialize hardware status page at device load when possible.
9 Some chips were unstable with repeated setup/teardown of the hardware status
12 Signed-off-by: Eric Anholt <eric@anholt.net>
15 --- a/drivers/gpu/drm/i915/i915_dma.c
16 +++ b/drivers/gpu/drm/i915/i915_dma.c
17 @@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * d
22 + * Sets up the hardware status page for devices that need a physical address
25 +int i915_init_phys_hws(struct drm_device *dev)
27 + drm_i915_private_t *dev_priv = dev->dev_private;
28 + /* Program Hardware Status Page */
29 + dev_priv->status_page_dmah =
30 + drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
32 + if (!dev_priv->status_page_dmah) {
33 + DRM_ERROR("Can not allocate hardware status page\n");
36 + dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37 + dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
39 + memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
41 + I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42 + DRM_DEBUG("Enabled hardware status page\n");
47 + * Frees the hardware status page, whether it's a physical address or a virtual
48 + * address set up by the X Server.
50 +void i915_free_hws(struct drm_device *dev)
52 + drm_i915_private_t *dev_priv = dev->dev_private;
53 + if (dev_priv->status_page_dmah) {
54 + drm_pci_free(dev, dev_priv->status_page_dmah);
55 + dev_priv->status_page_dmah = NULL;
58 + if (dev_priv->status_gfx_addr) {
59 + dev_priv->status_gfx_addr = 0;
60 + drm_core_ioremapfree(&dev_priv->hws_map, dev);
63 + /* Need to rewrite hardware status page */
64 + I915_WRITE(HWS_PGA, 0x1ffff000);
67 void i915_kernel_lost_context(struct drm_device * dev)
69 drm_i915_private_t *dev_priv = dev->dev_private;
70 @@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_d
71 dev_priv->ring.map.size = 0;
74 - if (dev_priv->status_page_dmah) {
75 - drm_pci_free(dev, dev_priv->status_page_dmah);
76 - dev_priv->status_page_dmah = NULL;
77 - /* Need to rewrite hardware status page */
78 - I915_WRITE(HWS_PGA, 0x1ffff000);
81 - if (dev_priv->status_gfx_addr) {
82 - dev_priv->status_gfx_addr = 0;
83 - drm_core_ioremapfree(&dev_priv->hws_map, dev);
84 - I915_WRITE(HWS_PGA, 0x1ffff000);
86 + /* Clear the HWS virtual address at teardown */
87 + if (I915_NEED_GFX_HWS(dev))
92 @@ -165,23 +202,6 @@ static int i915_initialize(struct drm_de
94 dev_priv->allow_batchbuffer = 1;
96 - /* Program Hardware Status Page */
97 - if (!I915_NEED_GFX_HWS(dev)) {
98 - dev_priv->status_page_dmah =
99 - drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
101 - if (!dev_priv->status_page_dmah) {
102 - i915_dma_cleanup(dev);
103 - DRM_ERROR("Can not allocate hardware status page\n");
106 - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107 - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
109 - memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110 - I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
112 - DRM_DEBUG("Enabled hardware status page\n");
116 @@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
121 + if (!I915_NEED_GFX_HWS(dev)) {
122 + ret = i915_init_phys_hws(dev);
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129 @@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
133 + i915_free_hws(dev);
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);