diff options
author | Dave Airlie <airlied@redhat.com> | 2009-08-03 21:43:41 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-07 21:45:15 -0400 |
commit | ec2a4c3fdc8e82fe82a25d800e85c1ea06b74372 (patch) | |
tree | b49f3ebe3e356fa8d17f15e9a5421851cb90024b | |
parent | f1938cd6e900a85de64184e46d841efc9efd3484 (diff) |
drm/i915: get the bridge device once.
The driver gets the bridge device in a number of places, upcoming
vga arb code paths need the bridge device, however they need it in
under a lock, and the pci lookup can allocate memory. So clean
this code up before then and get the bridge once for the driver lifetime.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_tiling.c | 65 |
3 files changed, 44 insertions, 55 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 91ef4c150193..9909505d070a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -898,6 +898,18 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
898 | return 0; | 898 | return 0; |
899 | } | 899 | } |
900 | 900 | ||
901 | static int i915_get_bridge_dev(struct drm_device *dev) | ||
902 | { | ||
903 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
904 | |||
905 | dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | ||
906 | if (!dev_priv->bridge_dev) { | ||
907 | DRM_ERROR("bridge device not found\n"); | ||
908 | return -1; | ||
909 | } | ||
910 | return 0; | ||
911 | } | ||
912 | |||
901 | /** | 913 | /** |
902 | * i915_probe_agp - get AGP bootup configuration | 914 | * i915_probe_agp - get AGP bootup configuration |
903 | * @pdev: PCI device | 915 | * @pdev: PCI device |
@@ -911,20 +923,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
911 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, | 923 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, |
912 | uint32_t *preallocated_size) | 924 | uint32_t *preallocated_size) |
913 | { | 925 | { |
914 | struct pci_dev *bridge_dev; | 926 | struct drm_i915_private *dev_priv = dev->dev_private; |
915 | u16 tmp = 0; | 927 | u16 tmp = 0; |
916 | unsigned long overhead; | 928 | unsigned long overhead; |
917 | unsigned long stolen; | 929 | unsigned long stolen; |
918 | 930 | ||
919 | bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | ||
920 | if (!bridge_dev) { | ||
921 | DRM_ERROR("bridge device not found\n"); | ||
922 | return -1; | ||
923 | } | ||
924 | |||
925 | /* Get the fb aperture size and "stolen" memory amount. */ | 931 | /* Get the fb aperture size and "stolen" memory amount. */ |
926 | pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); | 932 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp); |
927 | pci_dev_put(bridge_dev); | ||
928 | 933 | ||
929 | *aperture_size = 1024 * 1024; | 934 | *aperture_size = 1024 * 1024; |
930 | *preallocated_size = 1024 * 1024; | 935 | *preallocated_size = 1024 * 1024; |
@@ -1176,11 +1181,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1176 | base = drm_get_resource_start(dev, mmio_bar); | 1181 | base = drm_get_resource_start(dev, mmio_bar); |
1177 | size = drm_get_resource_len(dev, mmio_bar); | 1182 | size = drm_get_resource_len(dev, mmio_bar); |
1178 | 1183 | ||
1184 | if (i915_get_bridge_dev(dev)) { | ||
1185 | ret = -EIO; | ||
1186 | goto free_priv; | ||
1187 | } | ||
1188 | |||
1179 | dev_priv->regs = ioremap(base, size); | 1189 | dev_priv->regs = ioremap(base, size); |
1180 | if (!dev_priv->regs) { | 1190 | if (!dev_priv->regs) { |
1181 | DRM_ERROR("failed to map registers\n"); | 1191 | DRM_ERROR("failed to map registers\n"); |
1182 | ret = -EIO; | 1192 | ret = -EIO; |
1183 | goto free_priv; | 1193 | goto put_bridge; |
1184 | } | 1194 | } |
1185 | 1195 | ||
1186 | dev_priv->mm.gtt_mapping = | 1196 | dev_priv->mm.gtt_mapping = |
@@ -1292,6 +1302,8 @@ out_iomapfree: | |||
1292 | io_mapping_free(dev_priv->mm.gtt_mapping); | 1302 | io_mapping_free(dev_priv->mm.gtt_mapping); |
1293 | out_rmmap: | 1303 | out_rmmap: |
1294 | iounmap(dev_priv->regs); | 1304 | iounmap(dev_priv->regs); |
1305 | put_bridge: | ||
1306 | pci_dev_put(dev_priv->bridge_dev); | ||
1295 | free_priv: | 1307 | free_priv: |
1296 | kfree(dev_priv); | 1308 | kfree(dev_priv); |
1297 | return ret; | 1309 | return ret; |
@@ -1335,6 +1347,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
1335 | i915_gem_lastclose(dev); | 1347 | i915_gem_lastclose(dev); |
1336 | } | 1348 | } |
1337 | 1349 | ||
1350 | pci_dev_put(dev_priv->bridge_dev); | ||
1338 | kfree(dev->dev_private); | 1351 | kfree(dev->dev_private); |
1339 | 1352 | ||
1340 | return 0; | 1353 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2d5bce643e6a..77ed060b4292 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -155,6 +155,7 @@ typedef struct drm_i915_private { | |||
155 | 155 | ||
156 | void __iomem *regs; | 156 | void __iomem *regs; |
157 | 157 | ||
158 | struct pci_dev *bridge_dev; | ||
158 | drm_i915_ring_buffer_t ring; | 159 | drm_i915_ring_buffer_t ring; |
159 | 160 | ||
160 | drm_dma_handle_t *status_page_dmah; | 161 | drm_dma_handle_t *status_page_dmah; |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index e774a4a1a503..200e398453ca 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -94,23 +94,15 @@ | |||
94 | static int | 94 | static int |
95 | intel_alloc_mchbar_resource(struct drm_device *dev) | 95 | intel_alloc_mchbar_resource(struct drm_device *dev) |
96 | { | 96 | { |
97 | struct pci_dev *bridge_dev; | ||
98 | drm_i915_private_t *dev_priv = dev->dev_private; | 97 | drm_i915_private_t *dev_priv = dev->dev_private; |
99 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 98 | int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
100 | u32 temp_lo, temp_hi = 0; | 99 | u32 temp_lo, temp_hi = 0; |
101 | u64 mchbar_addr; | 100 | u64 mchbar_addr; |
102 | int ret = 0; | 101 | int ret = 0; |
103 | 102 | ||
104 | bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | ||
105 | if (!bridge_dev) { | ||
106 | DRM_DEBUG("no bridge dev?!\n"); | ||
107 | ret = -ENODEV; | ||
108 | goto out; | ||
109 | } | ||
110 | |||
111 | if (IS_I965G(dev)) | 103 | if (IS_I965G(dev)) |
112 | pci_read_config_dword(bridge_dev, reg + 4, &temp_hi); | 104 | pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); |
113 | pci_read_config_dword(bridge_dev, reg, &temp_lo); | 105 | pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); |
114 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; | 106 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; |
115 | 107 | ||
116 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 108 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
118 | if (mchbar_addr && | 110 | if (mchbar_addr && |
119 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 111 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { |
120 | ret = 0; | 112 | ret = 0; |
121 | goto out_put; | 113 | goto out; |
122 | } | 114 | } |
123 | #endif | 115 | #endif |
124 | 116 | ||
125 | /* Get some space for it */ | 117 | /* Get some space for it */ |
126 | ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, | 118 | ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, |
127 | MCHBAR_SIZE, MCHBAR_SIZE, | 119 | MCHBAR_SIZE, MCHBAR_SIZE, |
128 | PCIBIOS_MIN_MEM, | 120 | PCIBIOS_MIN_MEM, |
129 | 0, pcibios_align_resource, | 121 | 0, pcibios_align_resource, |
130 | bridge_dev); | 122 | dev_priv->bridge_dev); |
131 | if (ret) { | 123 | if (ret) { |
132 | DRM_DEBUG("failed bus alloc: %d\n", ret); | 124 | DRM_DEBUG("failed bus alloc: %d\n", ret); |
133 | dev_priv->mch_res.start = 0; | 125 | dev_priv->mch_res.start = 0; |
134 | goto out_put; | 126 | goto out; |
135 | } | 127 | } |
136 | 128 | ||
137 | if (IS_I965G(dev)) | 129 | if (IS_I965G(dev)) |
138 | pci_write_config_dword(bridge_dev, reg + 4, | 130 | pci_write_config_dword(dev_priv->bridge_dev, reg + 4, |
139 | upper_32_bits(dev_priv->mch_res.start)); | 131 | upper_32_bits(dev_priv->mch_res.start)); |
140 | 132 | ||
141 | pci_write_config_dword(bridge_dev, reg, | 133 | pci_write_config_dword(dev_priv->bridge_dev, reg, |
142 | lower_32_bits(dev_priv->mch_res.start)); | 134 | lower_32_bits(dev_priv->mch_res.start)); |
143 | out_put: | ||
144 | pci_dev_put(bridge_dev); | ||
145 | out: | 135 | out: |
146 | return ret; | 136 | return ret; |
147 | } | 137 | } |
@@ -150,44 +140,36 @@ out: | |||
150 | static bool | 140 | static bool |
151 | intel_setup_mchbar(struct drm_device *dev) | 141 | intel_setup_mchbar(struct drm_device *dev) |
152 | { | 142 | { |
153 | struct pci_dev *bridge_dev; | 143 | drm_i915_private_t *dev_priv = dev->dev_private; |
154 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 144 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
155 | u32 temp; | 145 | u32 temp; |
156 | bool need_disable = false, enabled; | 146 | bool need_disable = false, enabled; |
157 | 147 | ||
158 | bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | ||
159 | if (!bridge_dev) { | ||
160 | DRM_DEBUG("no bridge dev?!\n"); | ||
161 | goto out; | ||
162 | } | ||
163 | |||
164 | if (IS_I915G(dev) || IS_I915GM(dev)) { | 148 | if (IS_I915G(dev) || IS_I915GM(dev)) { |
165 | pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); | 149 | pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); |
166 | enabled = !!(temp & DEVEN_MCHBAR_EN); | 150 | enabled = !!(temp & DEVEN_MCHBAR_EN); |
167 | } else { | 151 | } else { |
168 | pci_read_config_dword(bridge_dev, mchbar_reg, &temp); | 152 | pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); |
169 | enabled = temp & 1; | 153 | enabled = temp & 1; |
170 | } | 154 | } |
171 | 155 | ||
172 | /* If it's already enabled, don't have to do anything */ | 156 | /* If it's already enabled, don't have to do anything */ |
173 | if (enabled) | 157 | if (enabled) |
174 | goto out_put; | 158 | goto out; |
175 | 159 | ||
176 | if (intel_alloc_mchbar_resource(dev)) | 160 | if (intel_alloc_mchbar_resource(dev)) |
177 | goto out_put; | 161 | goto out; |
178 | 162 | ||
179 | need_disable = true; | 163 | need_disable = true; |
180 | 164 | ||
181 | /* Space is allocated or reserved, so enable it. */ | 165 | /* Space is allocated or reserved, so enable it. */ |
182 | if (IS_I915G(dev) || IS_I915GM(dev)) { | 166 | if (IS_I915G(dev) || IS_I915GM(dev)) { |
183 | pci_write_config_dword(bridge_dev, DEVEN_REG, | 167 | pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, |
184 | temp | DEVEN_MCHBAR_EN); | 168 | temp | DEVEN_MCHBAR_EN); |
185 | } else { | 169 | } else { |
186 | pci_read_config_dword(bridge_dev, mchbar_reg, &temp); | 170 | pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); |
187 | pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1); | 171 | pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); |
188 | } | 172 | } |
189 | out_put: | ||
190 | pci_dev_put(bridge_dev); | ||
191 | out: | 173 | out: |
192 | return need_disable; | 174 | return need_disable; |
193 | } | 175 | } |
@@ -196,25 +178,18 @@ static void | |||
196 | intel_teardown_mchbar(struct drm_device *dev, bool disable) | 178 | intel_teardown_mchbar(struct drm_device *dev, bool disable) |
197 | { | 179 | { |
198 | drm_i915_private_t *dev_priv = dev->dev_private; | 180 | drm_i915_private_t *dev_priv = dev->dev_private; |
199 | struct pci_dev *bridge_dev; | ||
200 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; | 181 | int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; |
201 | u32 temp; | 182 | u32 temp; |
202 | 183 | ||
203 | bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | ||
204 | if (!bridge_dev) { | ||
205 | DRM_DEBUG("no bridge dev?!\n"); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | if (disable) { | 184 | if (disable) { |
210 | if (IS_I915G(dev) || IS_I915GM(dev)) { | 185 | if (IS_I915G(dev) || IS_I915GM(dev)) { |
211 | pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); | 186 | pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); |
212 | temp &= ~DEVEN_MCHBAR_EN; | 187 | temp &= ~DEVEN_MCHBAR_EN; |
213 | pci_write_config_dword(bridge_dev, DEVEN_REG, temp); | 188 | pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); |
214 | } else { | 189 | } else { |
215 | pci_read_config_dword(bridge_dev, mchbar_reg, &temp); | 190 | pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); |
216 | temp &= ~1; | 191 | temp &= ~1; |
217 | pci_write_config_dword(bridge_dev, mchbar_reg, temp); | 192 | pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); |
218 | } | 193 | } |
219 | } | 194 | } |
220 | 195 | ||