diff options
Diffstat (limited to 'meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch')
-rw-r--r-- | meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch b/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch new file mode 100644 index 0000000000..79f068f422 --- /dev/null +++ b/meta/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch | |||
@@ -0,0 +1,137 @@ | |||
1 | commit 75fed4ae8454aa975c274b2585ec2287dd15773d | ||
2 | Author: Keith Packard <keithp@keithp.com> | ||
3 | Date: Wed Jul 30 13:03:43 2008 -0700 | ||
4 | |||
5 | i915: Initialize hardware status page at device load when possible. | ||
6 | |||
7 | Some chips were unstable with repeated setup/teardown of the hardware status | ||
8 | page. | ||
9 | |||
10 | Signed-off-by: Eric Anholt <eric@anholt.net> | ||
11 | Signed-off-by: Dave Airlie <airlied@redhat.com> | ||
12 | |||
13 | diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c | ||
14 | index 4c72a01..b3c4ac9 100644 | ||
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 * dev, int n, const char *caller) | ||
18 | return -EBUSY; | ||
19 | } | ||
20 | |||
21 | +/** | ||
22 | + * Sets up the hardware status page for devices that need a physical address | ||
23 | + * in the register. | ||
24 | + */ | ||
25 | +int i915_init_phys_hws(struct drm_device *dev) | ||
26 | +{ | ||
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); | ||
31 | + | ||
32 | + if (!dev_priv->status_page_dmah) { | ||
33 | + DRM_ERROR("Can not allocate hardware status page\n"); | ||
34 | + return -ENOMEM; | ||
35 | + } | ||
36 | + dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
37 | + dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
38 | + | ||
39 | + memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
40 | + | ||
41 | + I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | ||
42 | + DRM_DEBUG("Enabled hardware status page\n"); | ||
43 | + return 0; | ||
44 | +} | ||
45 | + | ||
46 | +/** | ||
47 | + * Frees the hardware status page, whether it's a physical address or a virtual | ||
48 | + * address set up by the X Server. | ||
49 | + */ | ||
50 | +void i915_free_hws(struct drm_device *dev) | ||
51 | +{ | ||
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; | ||
56 | + } | ||
57 | + | ||
58 | + if (dev_priv->status_gfx_addr) { | ||
59 | + dev_priv->status_gfx_addr = 0; | ||
60 | + drm_core_ioremapfree(&dev_priv->hws_map, dev); | ||
61 | + } | ||
62 | + | ||
63 | + /* Need to rewrite hardware status page */ | ||
64 | + I915_WRITE(HWS_PGA, 0x1ffff000); | ||
65 | +} | ||
66 | + | ||
67 | void i915_kernel_lost_context(struct drm_device * dev) | ||
68 | { | ||
69 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
70 | @@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_device * dev) | ||
71 | dev_priv->ring.map.size = 0; | ||
72 | } | ||
73 | |||
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); | ||
79 | - } | ||
80 | - | ||
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); | ||
85 | - } | ||
86 | + /* Clear the HWS virtual address at teardown */ | ||
87 | + if (I915_NEED_GFX_HWS(dev)) | ||
88 | + i915_free_hws(dev); | ||
89 | |||
90 | return 0; | ||
91 | } | ||
92 | @@ -165,23 +202,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) | ||
93 | */ | ||
94 | dev_priv->allow_batchbuffer = 1; | ||
95 | |||
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); | ||
100 | - | ||
101 | - if (!dev_priv->status_page_dmah) { | ||
102 | - i915_dma_cleanup(dev); | ||
103 | - DRM_ERROR("Can not allocate hardware status page\n"); | ||
104 | - return -ENOMEM; | ||
105 | - } | ||
106 | - dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr; | ||
107 | - dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; | ||
108 | - | ||
109 | - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); | ||
110 | - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); | ||
111 | - } | ||
112 | - DRM_DEBUG("Enabled hardware status page\n"); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | @@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | ||
117 | _DRM_KERNEL | _DRM_DRIVER, | ||
118 | &dev_priv->mmio_map); | ||
119 | |||
120 | + /* Init HWS */ | ||
121 | + if (!I915_NEED_GFX_HWS(dev)) { | ||
122 | + ret = i915_init_phys_hws(dev); | ||
123 | + if (ret != 0) | ||
124 | + return ret; | ||
125 | + } | ||
126 | |||
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 *dev) | ||
130 | if (dev->pdev->msi_enabled) | ||
131 | pci_disable_msi(dev->pdev); | ||
132 | |||
133 | + i915_free_hws(dev); | ||
134 | + | ||
135 | if (dev_priv->mmio_map) | ||
136 | drm_rmmap(dev, dev_priv->mmio_map); | ||
137 | |||