diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_state.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 300 |
1 files changed, 199 insertions, 101 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 049f755567e5..a54fc431fe98 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -53,10 +53,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
53 | engine->instmem.takedown = nv04_instmem_takedown; | 53 | engine->instmem.takedown = nv04_instmem_takedown; |
54 | engine->instmem.suspend = nv04_instmem_suspend; | 54 | engine->instmem.suspend = nv04_instmem_suspend; |
55 | engine->instmem.resume = nv04_instmem_resume; | 55 | engine->instmem.resume = nv04_instmem_resume; |
56 | engine->instmem.populate = nv04_instmem_populate; | 56 | engine->instmem.get = nv04_instmem_get; |
57 | engine->instmem.clear = nv04_instmem_clear; | 57 | engine->instmem.put = nv04_instmem_put; |
58 | engine->instmem.bind = nv04_instmem_bind; | 58 | engine->instmem.map = nv04_instmem_map; |
59 | engine->instmem.unbind = nv04_instmem_unbind; | 59 | engine->instmem.unmap = nv04_instmem_unmap; |
60 | engine->instmem.flush = nv04_instmem_flush; | 60 | engine->instmem.flush = nv04_instmem_flush; |
61 | engine->mc.init = nv04_mc_init; | 61 | engine->mc.init = nv04_mc_init; |
62 | engine->mc.takedown = nv04_mc_takedown; | 62 | engine->mc.takedown = nv04_mc_takedown; |
@@ -65,7 +65,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
65 | engine->timer.takedown = nv04_timer_takedown; | 65 | engine->timer.takedown = nv04_timer_takedown; |
66 | engine->fb.init = nv04_fb_init; | 66 | engine->fb.init = nv04_fb_init; |
67 | engine->fb.takedown = nv04_fb_takedown; | 67 | engine->fb.takedown = nv04_fb_takedown; |
68 | engine->graph.grclass = nv04_graph_grclass; | ||
69 | engine->graph.init = nv04_graph_init; | 68 | engine->graph.init = nv04_graph_init; |
70 | engine->graph.takedown = nv04_graph_takedown; | 69 | engine->graph.takedown = nv04_graph_takedown; |
71 | engine->graph.fifo_access = nv04_graph_fifo_access; | 70 | engine->graph.fifo_access = nv04_graph_fifo_access; |
@@ -76,7 +75,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
76 | engine->graph.unload_context = nv04_graph_unload_context; | 75 | engine->graph.unload_context = nv04_graph_unload_context; |
77 | engine->fifo.channels = 16; | 76 | engine->fifo.channels = 16; |
78 | engine->fifo.init = nv04_fifo_init; | 77 | engine->fifo.init = nv04_fifo_init; |
79 | engine->fifo.takedown = nouveau_stub_takedown; | 78 | engine->fifo.takedown = nv04_fifo_fini; |
80 | engine->fifo.disable = nv04_fifo_disable; | 79 | engine->fifo.disable = nv04_fifo_disable; |
81 | engine->fifo.enable = nv04_fifo_enable; | 80 | engine->fifo.enable = nv04_fifo_enable; |
82 | engine->fifo.reassign = nv04_fifo_reassign; | 81 | engine->fifo.reassign = nv04_fifo_reassign; |
@@ -99,16 +98,20 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
99 | engine->pm.clock_get = nv04_pm_clock_get; | 98 | engine->pm.clock_get = nv04_pm_clock_get; |
100 | engine->pm.clock_pre = nv04_pm_clock_pre; | 99 | engine->pm.clock_pre = nv04_pm_clock_pre; |
101 | engine->pm.clock_set = nv04_pm_clock_set; | 100 | engine->pm.clock_set = nv04_pm_clock_set; |
101 | engine->crypt.init = nouveau_stub_init; | ||
102 | engine->crypt.takedown = nouveau_stub_takedown; | ||
103 | engine->vram.init = nouveau_mem_detect; | ||
104 | engine->vram.flags_valid = nouveau_mem_flags_valid; | ||
102 | break; | 105 | break; |
103 | case 0x10: | 106 | case 0x10: |
104 | engine->instmem.init = nv04_instmem_init; | 107 | engine->instmem.init = nv04_instmem_init; |
105 | engine->instmem.takedown = nv04_instmem_takedown; | 108 | engine->instmem.takedown = nv04_instmem_takedown; |
106 | engine->instmem.suspend = nv04_instmem_suspend; | 109 | engine->instmem.suspend = nv04_instmem_suspend; |
107 | engine->instmem.resume = nv04_instmem_resume; | 110 | engine->instmem.resume = nv04_instmem_resume; |
108 | engine->instmem.populate = nv04_instmem_populate; | 111 | engine->instmem.get = nv04_instmem_get; |
109 | engine->instmem.clear = nv04_instmem_clear; | 112 | engine->instmem.put = nv04_instmem_put; |
110 | engine->instmem.bind = nv04_instmem_bind; | 113 | engine->instmem.map = nv04_instmem_map; |
111 | engine->instmem.unbind = nv04_instmem_unbind; | 114 | engine->instmem.unmap = nv04_instmem_unmap; |
112 | engine->instmem.flush = nv04_instmem_flush; | 115 | engine->instmem.flush = nv04_instmem_flush; |
113 | engine->mc.init = nv04_mc_init; | 116 | engine->mc.init = nv04_mc_init; |
114 | engine->mc.takedown = nv04_mc_takedown; | 117 | engine->mc.takedown = nv04_mc_takedown; |
@@ -117,8 +120,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
117 | engine->timer.takedown = nv04_timer_takedown; | 120 | engine->timer.takedown = nv04_timer_takedown; |
118 | engine->fb.init = nv10_fb_init; | 121 | engine->fb.init = nv10_fb_init; |
119 | engine->fb.takedown = nv10_fb_takedown; | 122 | engine->fb.takedown = nv10_fb_takedown; |
120 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | 123 | engine->fb.init_tile_region = nv10_fb_init_tile_region; |
121 | engine->graph.grclass = nv10_graph_grclass; | 124 | engine->fb.set_tile_region = nv10_fb_set_tile_region; |
125 | engine->fb.free_tile_region = nv10_fb_free_tile_region; | ||
122 | engine->graph.init = nv10_graph_init; | 126 | engine->graph.init = nv10_graph_init; |
123 | engine->graph.takedown = nv10_graph_takedown; | 127 | engine->graph.takedown = nv10_graph_takedown; |
124 | engine->graph.channel = nv10_graph_channel; | 128 | engine->graph.channel = nv10_graph_channel; |
@@ -127,17 +131,17 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
127 | engine->graph.fifo_access = nv04_graph_fifo_access; | 131 | engine->graph.fifo_access = nv04_graph_fifo_access; |
128 | engine->graph.load_context = nv10_graph_load_context; | 132 | engine->graph.load_context = nv10_graph_load_context; |
129 | engine->graph.unload_context = nv10_graph_unload_context; | 133 | engine->graph.unload_context = nv10_graph_unload_context; |
130 | engine->graph.set_region_tiling = nv10_graph_set_region_tiling; | 134 | engine->graph.set_tile_region = nv10_graph_set_tile_region; |
131 | engine->fifo.channels = 32; | 135 | engine->fifo.channels = 32; |
132 | engine->fifo.init = nv10_fifo_init; | 136 | engine->fifo.init = nv10_fifo_init; |
133 | engine->fifo.takedown = nouveau_stub_takedown; | 137 | engine->fifo.takedown = nv04_fifo_fini; |
134 | engine->fifo.disable = nv04_fifo_disable; | 138 | engine->fifo.disable = nv04_fifo_disable; |
135 | engine->fifo.enable = nv04_fifo_enable; | 139 | engine->fifo.enable = nv04_fifo_enable; |
136 | engine->fifo.reassign = nv04_fifo_reassign; | 140 | engine->fifo.reassign = nv04_fifo_reassign; |
137 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | 141 | engine->fifo.cache_pull = nv04_fifo_cache_pull; |
138 | engine->fifo.channel_id = nv10_fifo_channel_id; | 142 | engine->fifo.channel_id = nv10_fifo_channel_id; |
139 | engine->fifo.create_context = nv10_fifo_create_context; | 143 | engine->fifo.create_context = nv10_fifo_create_context; |
140 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 144 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
141 | engine->fifo.load_context = nv10_fifo_load_context; | 145 | engine->fifo.load_context = nv10_fifo_load_context; |
142 | engine->fifo.unload_context = nv10_fifo_unload_context; | 146 | engine->fifo.unload_context = nv10_fifo_unload_context; |
143 | engine->display.early_init = nv04_display_early_init; | 147 | engine->display.early_init = nv04_display_early_init; |
@@ -153,16 +157,20 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
153 | engine->pm.clock_get = nv04_pm_clock_get; | 157 | engine->pm.clock_get = nv04_pm_clock_get; |
154 | engine->pm.clock_pre = nv04_pm_clock_pre; | 158 | engine->pm.clock_pre = nv04_pm_clock_pre; |
155 | engine->pm.clock_set = nv04_pm_clock_set; | 159 | engine->pm.clock_set = nv04_pm_clock_set; |
160 | engine->crypt.init = nouveau_stub_init; | ||
161 | engine->crypt.takedown = nouveau_stub_takedown; | ||
162 | engine->vram.init = nouveau_mem_detect; | ||
163 | engine->vram.flags_valid = nouveau_mem_flags_valid; | ||
156 | break; | 164 | break; |
157 | case 0x20: | 165 | case 0x20: |
158 | engine->instmem.init = nv04_instmem_init; | 166 | engine->instmem.init = nv04_instmem_init; |
159 | engine->instmem.takedown = nv04_instmem_takedown; | 167 | engine->instmem.takedown = nv04_instmem_takedown; |
160 | engine->instmem.suspend = nv04_instmem_suspend; | 168 | engine->instmem.suspend = nv04_instmem_suspend; |
161 | engine->instmem.resume = nv04_instmem_resume; | 169 | engine->instmem.resume = nv04_instmem_resume; |
162 | engine->instmem.populate = nv04_instmem_populate; | 170 | engine->instmem.get = nv04_instmem_get; |
163 | engine->instmem.clear = nv04_instmem_clear; | 171 | engine->instmem.put = nv04_instmem_put; |
164 | engine->instmem.bind = nv04_instmem_bind; | 172 | engine->instmem.map = nv04_instmem_map; |
165 | engine->instmem.unbind = nv04_instmem_unbind; | 173 | engine->instmem.unmap = nv04_instmem_unmap; |
166 | engine->instmem.flush = nv04_instmem_flush; | 174 | engine->instmem.flush = nv04_instmem_flush; |
167 | engine->mc.init = nv04_mc_init; | 175 | engine->mc.init = nv04_mc_init; |
168 | engine->mc.takedown = nv04_mc_takedown; | 176 | engine->mc.takedown = nv04_mc_takedown; |
@@ -171,8 +179,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
171 | engine->timer.takedown = nv04_timer_takedown; | 179 | engine->timer.takedown = nv04_timer_takedown; |
172 | engine->fb.init = nv10_fb_init; | 180 | engine->fb.init = nv10_fb_init; |
173 | engine->fb.takedown = nv10_fb_takedown; | 181 | engine->fb.takedown = nv10_fb_takedown; |
174 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | 182 | engine->fb.init_tile_region = nv10_fb_init_tile_region; |
175 | engine->graph.grclass = nv20_graph_grclass; | 183 | engine->fb.set_tile_region = nv10_fb_set_tile_region; |
184 | engine->fb.free_tile_region = nv10_fb_free_tile_region; | ||
176 | engine->graph.init = nv20_graph_init; | 185 | engine->graph.init = nv20_graph_init; |
177 | engine->graph.takedown = nv20_graph_takedown; | 186 | engine->graph.takedown = nv20_graph_takedown; |
178 | engine->graph.channel = nv10_graph_channel; | 187 | engine->graph.channel = nv10_graph_channel; |
@@ -181,17 +190,17 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
181 | engine->graph.fifo_access = nv04_graph_fifo_access; | 190 | engine->graph.fifo_access = nv04_graph_fifo_access; |
182 | engine->graph.load_context = nv20_graph_load_context; | 191 | engine->graph.load_context = nv20_graph_load_context; |
183 | engine->graph.unload_context = nv20_graph_unload_context; | 192 | engine->graph.unload_context = nv20_graph_unload_context; |
184 | engine->graph.set_region_tiling = nv20_graph_set_region_tiling; | 193 | engine->graph.set_tile_region = nv20_graph_set_tile_region; |
185 | engine->fifo.channels = 32; | 194 | engine->fifo.channels = 32; |
186 | engine->fifo.init = nv10_fifo_init; | 195 | engine->fifo.init = nv10_fifo_init; |
187 | engine->fifo.takedown = nouveau_stub_takedown; | 196 | engine->fifo.takedown = nv04_fifo_fini; |
188 | engine->fifo.disable = nv04_fifo_disable; | 197 | engine->fifo.disable = nv04_fifo_disable; |
189 | engine->fifo.enable = nv04_fifo_enable; | 198 | engine->fifo.enable = nv04_fifo_enable; |
190 | engine->fifo.reassign = nv04_fifo_reassign; | 199 | engine->fifo.reassign = nv04_fifo_reassign; |
191 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | 200 | engine->fifo.cache_pull = nv04_fifo_cache_pull; |
192 | engine->fifo.channel_id = nv10_fifo_channel_id; | 201 | engine->fifo.channel_id = nv10_fifo_channel_id; |
193 | engine->fifo.create_context = nv10_fifo_create_context; | 202 | engine->fifo.create_context = nv10_fifo_create_context; |
194 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 203 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
195 | engine->fifo.load_context = nv10_fifo_load_context; | 204 | engine->fifo.load_context = nv10_fifo_load_context; |
196 | engine->fifo.unload_context = nv10_fifo_unload_context; | 205 | engine->fifo.unload_context = nv10_fifo_unload_context; |
197 | engine->display.early_init = nv04_display_early_init; | 206 | engine->display.early_init = nv04_display_early_init; |
@@ -207,16 +216,20 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
207 | engine->pm.clock_get = nv04_pm_clock_get; | 216 | engine->pm.clock_get = nv04_pm_clock_get; |
208 | engine->pm.clock_pre = nv04_pm_clock_pre; | 217 | engine->pm.clock_pre = nv04_pm_clock_pre; |
209 | engine->pm.clock_set = nv04_pm_clock_set; | 218 | engine->pm.clock_set = nv04_pm_clock_set; |
219 | engine->crypt.init = nouveau_stub_init; | ||
220 | engine->crypt.takedown = nouveau_stub_takedown; | ||
221 | engine->vram.init = nouveau_mem_detect; | ||
222 | engine->vram.flags_valid = nouveau_mem_flags_valid; | ||
210 | break; | 223 | break; |
211 | case 0x30: | 224 | case 0x30: |
212 | engine->instmem.init = nv04_instmem_init; | 225 | engine->instmem.init = nv04_instmem_init; |
213 | engine->instmem.takedown = nv04_instmem_takedown; | 226 | engine->instmem.takedown = nv04_instmem_takedown; |
214 | engine->instmem.suspend = nv04_instmem_suspend; | 227 | engine->instmem.suspend = nv04_instmem_suspend; |
215 | engine->instmem.resume = nv04_instmem_resume; | 228 | engine->instmem.resume = nv04_instmem_resume; |
216 | engine->instmem.populate = nv04_instmem_populate; | 229 | engine->instmem.get = nv04_instmem_get; |
217 | engine->instmem.clear = nv04_instmem_clear; | 230 | engine->instmem.put = nv04_instmem_put; |
218 | engine->instmem.bind = nv04_instmem_bind; | 231 | engine->instmem.map = nv04_instmem_map; |
219 | engine->instmem.unbind = nv04_instmem_unbind; | 232 | engine->instmem.unmap = nv04_instmem_unmap; |
220 | engine->instmem.flush = nv04_instmem_flush; | 233 | engine->instmem.flush = nv04_instmem_flush; |
221 | engine->mc.init = nv04_mc_init; | 234 | engine->mc.init = nv04_mc_init; |
222 | engine->mc.takedown = nv04_mc_takedown; | 235 | engine->mc.takedown = nv04_mc_takedown; |
@@ -225,8 +238,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
225 | engine->timer.takedown = nv04_timer_takedown; | 238 | engine->timer.takedown = nv04_timer_takedown; |
226 | engine->fb.init = nv30_fb_init; | 239 | engine->fb.init = nv30_fb_init; |
227 | engine->fb.takedown = nv30_fb_takedown; | 240 | engine->fb.takedown = nv30_fb_takedown; |
228 | engine->fb.set_region_tiling = nv10_fb_set_region_tiling; | 241 | engine->fb.init_tile_region = nv30_fb_init_tile_region; |
229 | engine->graph.grclass = nv30_graph_grclass; | 242 | engine->fb.set_tile_region = nv10_fb_set_tile_region; |
243 | engine->fb.free_tile_region = nv30_fb_free_tile_region; | ||
230 | engine->graph.init = nv30_graph_init; | 244 | engine->graph.init = nv30_graph_init; |
231 | engine->graph.takedown = nv20_graph_takedown; | 245 | engine->graph.takedown = nv20_graph_takedown; |
232 | engine->graph.fifo_access = nv04_graph_fifo_access; | 246 | engine->graph.fifo_access = nv04_graph_fifo_access; |
@@ -235,17 +249,17 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
235 | engine->graph.destroy_context = nv20_graph_destroy_context; | 249 | engine->graph.destroy_context = nv20_graph_destroy_context; |
236 | engine->graph.load_context = nv20_graph_load_context; | 250 | engine->graph.load_context = nv20_graph_load_context; |
237 | engine->graph.unload_context = nv20_graph_unload_context; | 251 | engine->graph.unload_context = nv20_graph_unload_context; |
238 | engine->graph.set_region_tiling = nv20_graph_set_region_tiling; | 252 | engine->graph.set_tile_region = nv20_graph_set_tile_region; |
239 | engine->fifo.channels = 32; | 253 | engine->fifo.channels = 32; |
240 | engine->fifo.init = nv10_fifo_init; | 254 | engine->fifo.init = nv10_fifo_init; |
241 | engine->fifo.takedown = nouveau_stub_takedown; | 255 | engine->fifo.takedown = nv04_fifo_fini; |
242 | engine->fifo.disable = nv04_fifo_disable; | 256 | engine->fifo.disable = nv04_fifo_disable; |
243 | engine->fifo.enable = nv04_fifo_enable; | 257 | engine->fifo.enable = nv04_fifo_enable; |
244 | engine->fifo.reassign = nv04_fifo_reassign; | 258 | engine->fifo.reassign = nv04_fifo_reassign; |
245 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | 259 | engine->fifo.cache_pull = nv04_fifo_cache_pull; |
246 | engine->fifo.channel_id = nv10_fifo_channel_id; | 260 | engine->fifo.channel_id = nv10_fifo_channel_id; |
247 | engine->fifo.create_context = nv10_fifo_create_context; | 261 | engine->fifo.create_context = nv10_fifo_create_context; |
248 | engine->fifo.destroy_context = nv10_fifo_destroy_context; | 262 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
249 | engine->fifo.load_context = nv10_fifo_load_context; | 263 | engine->fifo.load_context = nv10_fifo_load_context; |
250 | engine->fifo.unload_context = nv10_fifo_unload_context; | 264 | engine->fifo.unload_context = nv10_fifo_unload_context; |
251 | engine->display.early_init = nv04_display_early_init; | 265 | engine->display.early_init = nv04_display_early_init; |
@@ -263,6 +277,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
263 | engine->pm.clock_set = nv04_pm_clock_set; | 277 | engine->pm.clock_set = nv04_pm_clock_set; |
264 | engine->pm.voltage_get = nouveau_voltage_gpio_get; | 278 | engine->pm.voltage_get = nouveau_voltage_gpio_get; |
265 | engine->pm.voltage_set = nouveau_voltage_gpio_set; | 279 | engine->pm.voltage_set = nouveau_voltage_gpio_set; |
280 | engine->crypt.init = nouveau_stub_init; | ||
281 | engine->crypt.takedown = nouveau_stub_takedown; | ||
282 | engine->vram.init = nouveau_mem_detect; | ||
283 | engine->vram.flags_valid = nouveau_mem_flags_valid; | ||
266 | break; | 284 | break; |
267 | case 0x40: | 285 | case 0x40: |
268 | case 0x60: | 286 | case 0x60: |
@@ -270,10 +288,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
270 | engine->instmem.takedown = nv04_instmem_takedown; | 288 | engine->instmem.takedown = nv04_instmem_takedown; |
271 | engine->instmem.suspend = nv04_instmem_suspend; | 289 | engine->instmem.suspend = nv04_instmem_suspend; |
272 | engine->instmem.resume = nv04_instmem_resume; | 290 | engine->instmem.resume = nv04_instmem_resume; |
273 | engine->instmem.populate = nv04_instmem_populate; | 291 | engine->instmem.get = nv04_instmem_get; |
274 | engine->instmem.clear = nv04_instmem_clear; | 292 | engine->instmem.put = nv04_instmem_put; |
275 | engine->instmem.bind = nv04_instmem_bind; | 293 | engine->instmem.map = nv04_instmem_map; |
276 | engine->instmem.unbind = nv04_instmem_unbind; | 294 | engine->instmem.unmap = nv04_instmem_unmap; |
277 | engine->instmem.flush = nv04_instmem_flush; | 295 | engine->instmem.flush = nv04_instmem_flush; |
278 | engine->mc.init = nv40_mc_init; | 296 | engine->mc.init = nv40_mc_init; |
279 | engine->mc.takedown = nv40_mc_takedown; | 297 | engine->mc.takedown = nv40_mc_takedown; |
@@ -282,8 +300,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
282 | engine->timer.takedown = nv04_timer_takedown; | 300 | engine->timer.takedown = nv04_timer_takedown; |
283 | engine->fb.init = nv40_fb_init; | 301 | engine->fb.init = nv40_fb_init; |
284 | engine->fb.takedown = nv40_fb_takedown; | 302 | engine->fb.takedown = nv40_fb_takedown; |
285 | engine->fb.set_region_tiling = nv40_fb_set_region_tiling; | 303 | engine->fb.init_tile_region = nv30_fb_init_tile_region; |
286 | engine->graph.grclass = nv40_graph_grclass; | 304 | engine->fb.set_tile_region = nv40_fb_set_tile_region; |
305 | engine->fb.free_tile_region = nv30_fb_free_tile_region; | ||
287 | engine->graph.init = nv40_graph_init; | 306 | engine->graph.init = nv40_graph_init; |
288 | engine->graph.takedown = nv40_graph_takedown; | 307 | engine->graph.takedown = nv40_graph_takedown; |
289 | engine->graph.fifo_access = nv04_graph_fifo_access; | 308 | engine->graph.fifo_access = nv04_graph_fifo_access; |
@@ -292,17 +311,17 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
292 | engine->graph.destroy_context = nv40_graph_destroy_context; | 311 | engine->graph.destroy_context = nv40_graph_destroy_context; |
293 | engine->graph.load_context = nv40_graph_load_context; | 312 | engine->graph.load_context = nv40_graph_load_context; |
294 | engine->graph.unload_context = nv40_graph_unload_context; | 313 | engine->graph.unload_context = nv40_graph_unload_context; |
295 | engine->graph.set_region_tiling = nv40_graph_set_region_tiling; | 314 | engine->graph.set_tile_region = nv40_graph_set_tile_region; |
296 | engine->fifo.channels = 32; | 315 | engine->fifo.channels = 32; |
297 | engine->fifo.init = nv40_fifo_init; | 316 | engine->fifo.init = nv40_fifo_init; |
298 | engine->fifo.takedown = nouveau_stub_takedown; | 317 | engine->fifo.takedown = nv04_fifo_fini; |
299 | engine->fifo.disable = nv04_fifo_disable; | 318 | engine->fifo.disable = nv04_fifo_disable; |
300 | engine->fifo.enable = nv04_fifo_enable; | 319 | engine->fifo.enable = nv04_fifo_enable; |
301 | engine->fifo.reassign = nv04_fifo_reassign; | 320 | engine->fifo.reassign = nv04_fifo_reassign; |
302 | engine->fifo.cache_pull = nv04_fifo_cache_pull; | 321 | engine->fifo.cache_pull = nv04_fifo_cache_pull; |
303 | engine->fifo.channel_id = nv10_fifo_channel_id; | 322 | engine->fifo.channel_id = nv10_fifo_channel_id; |
304 | engine->fifo.create_context = nv40_fifo_create_context; | 323 | engine->fifo.create_context = nv40_fifo_create_context; |
305 | engine->fifo.destroy_context = nv40_fifo_destroy_context; | 324 | engine->fifo.destroy_context = nv04_fifo_destroy_context; |
306 | engine->fifo.load_context = nv40_fifo_load_context; | 325 | engine->fifo.load_context = nv40_fifo_load_context; |
307 | engine->fifo.unload_context = nv40_fifo_unload_context; | 326 | engine->fifo.unload_context = nv40_fifo_unload_context; |
308 | engine->display.early_init = nv04_display_early_init; | 327 | engine->display.early_init = nv04_display_early_init; |
@@ -321,6 +340,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
321 | engine->pm.voltage_get = nouveau_voltage_gpio_get; | 340 | engine->pm.voltage_get = nouveau_voltage_gpio_get; |
322 | engine->pm.voltage_set = nouveau_voltage_gpio_set; | 341 | engine->pm.voltage_set = nouveau_voltage_gpio_set; |
323 | engine->pm.temp_get = nv40_temp_get; | 342 | engine->pm.temp_get = nv40_temp_get; |
343 | engine->crypt.init = nouveau_stub_init; | ||
344 | engine->crypt.takedown = nouveau_stub_takedown; | ||
345 | engine->vram.init = nouveau_mem_detect; | ||
346 | engine->vram.flags_valid = nouveau_mem_flags_valid; | ||
324 | break; | 347 | break; |
325 | case 0x50: | 348 | case 0x50: |
326 | case 0x80: /* gotta love NVIDIA's consistency.. */ | 349 | case 0x80: /* gotta love NVIDIA's consistency.. */ |
@@ -330,10 +353,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
330 | engine->instmem.takedown = nv50_instmem_takedown; | 353 | engine->instmem.takedown = nv50_instmem_takedown; |
331 | engine->instmem.suspend = nv50_instmem_suspend; | 354 | engine->instmem.suspend = nv50_instmem_suspend; |
332 | engine->instmem.resume = nv50_instmem_resume; | 355 | engine->instmem.resume = nv50_instmem_resume; |
333 | engine->instmem.populate = nv50_instmem_populate; | 356 | engine->instmem.get = nv50_instmem_get; |
334 | engine->instmem.clear = nv50_instmem_clear; | 357 | engine->instmem.put = nv50_instmem_put; |
335 | engine->instmem.bind = nv50_instmem_bind; | 358 | engine->instmem.map = nv50_instmem_map; |
336 | engine->instmem.unbind = nv50_instmem_unbind; | 359 | engine->instmem.unmap = nv50_instmem_unmap; |
337 | if (dev_priv->chipset == 0x50) | 360 | if (dev_priv->chipset == 0x50) |
338 | engine->instmem.flush = nv50_instmem_flush; | 361 | engine->instmem.flush = nv50_instmem_flush; |
339 | else | 362 | else |
@@ -345,7 +368,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
345 | engine->timer.takedown = nv04_timer_takedown; | 368 | engine->timer.takedown = nv04_timer_takedown; |
346 | engine->fb.init = nv50_fb_init; | 369 | engine->fb.init = nv50_fb_init; |
347 | engine->fb.takedown = nv50_fb_takedown; | 370 | engine->fb.takedown = nv50_fb_takedown; |
348 | engine->graph.grclass = nv50_graph_grclass; | ||
349 | engine->graph.init = nv50_graph_init; | 371 | engine->graph.init = nv50_graph_init; |
350 | engine->graph.takedown = nv50_graph_takedown; | 372 | engine->graph.takedown = nv50_graph_takedown; |
351 | engine->graph.fifo_access = nv50_graph_fifo_access; | 373 | engine->graph.fifo_access = nv50_graph_fifo_access; |
@@ -381,24 +403,32 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
381 | engine->display.init = nv50_display_init; | 403 | engine->display.init = nv50_display_init; |
382 | engine->display.destroy = nv50_display_destroy; | 404 | engine->display.destroy = nv50_display_destroy; |
383 | engine->gpio.init = nv50_gpio_init; | 405 | engine->gpio.init = nv50_gpio_init; |
384 | engine->gpio.takedown = nouveau_stub_takedown; | 406 | engine->gpio.takedown = nv50_gpio_fini; |
385 | engine->gpio.get = nv50_gpio_get; | 407 | engine->gpio.get = nv50_gpio_get; |
386 | engine->gpio.set = nv50_gpio_set; | 408 | engine->gpio.set = nv50_gpio_set; |
409 | engine->gpio.irq_register = nv50_gpio_irq_register; | ||
410 | engine->gpio.irq_unregister = nv50_gpio_irq_unregister; | ||
387 | engine->gpio.irq_enable = nv50_gpio_irq_enable; | 411 | engine->gpio.irq_enable = nv50_gpio_irq_enable; |
388 | switch (dev_priv->chipset) { | 412 | switch (dev_priv->chipset) { |
389 | case 0xa3: | 413 | case 0x84: |
390 | case 0xa5: | 414 | case 0x86: |
391 | case 0xa8: | 415 | case 0x92: |
392 | case 0xaf: | 416 | case 0x94: |
393 | engine->pm.clock_get = nva3_pm_clock_get; | 417 | case 0x96: |
394 | engine->pm.clock_pre = nva3_pm_clock_pre; | 418 | case 0x98: |
395 | engine->pm.clock_set = nva3_pm_clock_set; | 419 | case 0xa0: |
396 | break; | 420 | case 0xaa: |
397 | default: | 421 | case 0xac: |
422 | case 0x50: | ||
398 | engine->pm.clock_get = nv50_pm_clock_get; | 423 | engine->pm.clock_get = nv50_pm_clock_get; |
399 | engine->pm.clock_pre = nv50_pm_clock_pre; | 424 | engine->pm.clock_pre = nv50_pm_clock_pre; |
400 | engine->pm.clock_set = nv50_pm_clock_set; | 425 | engine->pm.clock_set = nv50_pm_clock_set; |
401 | break; | 426 | break; |
427 | default: | ||
428 | engine->pm.clock_get = nva3_pm_clock_get; | ||
429 | engine->pm.clock_pre = nva3_pm_clock_pre; | ||
430 | engine->pm.clock_set = nva3_pm_clock_set; | ||
431 | break; | ||
402 | } | 432 | } |
403 | engine->pm.voltage_get = nouveau_voltage_gpio_get; | 433 | engine->pm.voltage_get = nouveau_voltage_gpio_get; |
404 | engine->pm.voltage_set = nouveau_voltage_gpio_set; | 434 | engine->pm.voltage_set = nouveau_voltage_gpio_set; |
@@ -406,17 +436,39 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
406 | engine->pm.temp_get = nv84_temp_get; | 436 | engine->pm.temp_get = nv84_temp_get; |
407 | else | 437 | else |
408 | engine->pm.temp_get = nv40_temp_get; | 438 | engine->pm.temp_get = nv40_temp_get; |
439 | switch (dev_priv->chipset) { | ||
440 | case 0x84: | ||
441 | case 0x86: | ||
442 | case 0x92: | ||
443 | case 0x94: | ||
444 | case 0x96: | ||
445 | case 0xa0: | ||
446 | engine->crypt.init = nv84_crypt_init; | ||
447 | engine->crypt.takedown = nv84_crypt_fini; | ||
448 | engine->crypt.create_context = nv84_crypt_create_context; | ||
449 | engine->crypt.destroy_context = nv84_crypt_destroy_context; | ||
450 | engine->crypt.tlb_flush = nv84_crypt_tlb_flush; | ||
451 | break; | ||
452 | default: | ||
453 | engine->crypt.init = nouveau_stub_init; | ||
454 | engine->crypt.takedown = nouveau_stub_takedown; | ||
455 | break; | ||
456 | } | ||
457 | engine->vram.init = nv50_vram_init; | ||
458 | engine->vram.get = nv50_vram_new; | ||
459 | engine->vram.put = nv50_vram_del; | ||
460 | engine->vram.flags_valid = nv50_vram_flags_valid; | ||
409 | break; | 461 | break; |
410 | case 0xC0: | 462 | case 0xC0: |
411 | engine->instmem.init = nvc0_instmem_init; | 463 | engine->instmem.init = nvc0_instmem_init; |
412 | engine->instmem.takedown = nvc0_instmem_takedown; | 464 | engine->instmem.takedown = nvc0_instmem_takedown; |
413 | engine->instmem.suspend = nvc0_instmem_suspend; | 465 | engine->instmem.suspend = nvc0_instmem_suspend; |
414 | engine->instmem.resume = nvc0_instmem_resume; | 466 | engine->instmem.resume = nvc0_instmem_resume; |
415 | engine->instmem.populate = nvc0_instmem_populate; | 467 | engine->instmem.get = nv50_instmem_get; |
416 | engine->instmem.clear = nvc0_instmem_clear; | 468 | engine->instmem.put = nv50_instmem_put; |
417 | engine->instmem.bind = nvc0_instmem_bind; | 469 | engine->instmem.map = nv50_instmem_map; |
418 | engine->instmem.unbind = nvc0_instmem_unbind; | 470 | engine->instmem.unmap = nv50_instmem_unmap; |
419 | engine->instmem.flush = nvc0_instmem_flush; | 471 | engine->instmem.flush = nv84_instmem_flush; |
420 | engine->mc.init = nv50_mc_init; | 472 | engine->mc.init = nv50_mc_init; |
421 | engine->mc.takedown = nv50_mc_takedown; | 473 | engine->mc.takedown = nv50_mc_takedown; |
422 | engine->timer.init = nv04_timer_init; | 474 | engine->timer.init = nv04_timer_init; |
@@ -424,7 +476,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
424 | engine->timer.takedown = nv04_timer_takedown; | 476 | engine->timer.takedown = nv04_timer_takedown; |
425 | engine->fb.init = nvc0_fb_init; | 477 | engine->fb.init = nvc0_fb_init; |
426 | engine->fb.takedown = nvc0_fb_takedown; | 478 | engine->fb.takedown = nvc0_fb_takedown; |
427 | engine->graph.grclass = NULL; //nvc0_graph_grclass; | ||
428 | engine->graph.init = nvc0_graph_init; | 479 | engine->graph.init = nvc0_graph_init; |
429 | engine->graph.takedown = nvc0_graph_takedown; | 480 | engine->graph.takedown = nvc0_graph_takedown; |
430 | engine->graph.fifo_access = nvc0_graph_fifo_access; | 481 | engine->graph.fifo_access = nvc0_graph_fifo_access; |
@@ -453,7 +504,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
453 | engine->gpio.takedown = nouveau_stub_takedown; | 504 | engine->gpio.takedown = nouveau_stub_takedown; |
454 | engine->gpio.get = nv50_gpio_get; | 505 | engine->gpio.get = nv50_gpio_get; |
455 | engine->gpio.set = nv50_gpio_set; | 506 | engine->gpio.set = nv50_gpio_set; |
507 | engine->gpio.irq_register = nv50_gpio_irq_register; | ||
508 | engine->gpio.irq_unregister = nv50_gpio_irq_unregister; | ||
456 | engine->gpio.irq_enable = nv50_gpio_irq_enable; | 509 | engine->gpio.irq_enable = nv50_gpio_irq_enable; |
510 | engine->crypt.init = nouveau_stub_init; | ||
511 | engine->crypt.takedown = nouveau_stub_takedown; | ||
512 | engine->vram.init = nvc0_vram_init; | ||
513 | engine->vram.get = nvc0_vram_new; | ||
514 | engine->vram.put = nv50_vram_del; | ||
515 | engine->vram.flags_valid = nvc0_vram_flags_valid; | ||
457 | break; | 516 | break; |
458 | default: | 517 | default: |
459 | NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); | 518 | NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); |
@@ -493,9 +552,13 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
493 | if (ret) | 552 | if (ret) |
494 | return ret; | 553 | return ret; |
495 | 554 | ||
555 | /* no dma objects on fermi... */ | ||
556 | if (dev_priv->card_type >= NV_C0) | ||
557 | goto out_done; | ||
558 | |||
496 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, | 559 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, |
497 | 0, dev_priv->vram_size, | 560 | 0, dev_priv->vram_size, |
498 | NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, | 561 | NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, |
499 | &gpuobj); | 562 | &gpuobj); |
500 | if (ret) | 563 | if (ret) |
501 | goto out_err; | 564 | goto out_err; |
@@ -505,9 +568,10 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
505 | if (ret) | 568 | if (ret) |
506 | goto out_err; | 569 | goto out_err; |
507 | 570 | ||
508 | ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, | 571 | ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, |
509 | dev_priv->gart_info.aper_size, | 572 | 0, dev_priv->gart_info.aper_size, |
510 | NV_DMA_ACCESS_RW, &gpuobj, NULL); | 573 | NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART, |
574 | &gpuobj); | ||
511 | if (ret) | 575 | if (ret) |
512 | goto out_err; | 576 | goto out_err; |
513 | 577 | ||
@@ -516,11 +580,12 @@ nouveau_card_init_channel(struct drm_device *dev) | |||
516 | if (ret) | 580 | if (ret) |
517 | goto out_err; | 581 | goto out_err; |
518 | 582 | ||
583 | out_done: | ||
584 | mutex_unlock(&dev_priv->channel->mutex); | ||
519 | return 0; | 585 | return 0; |
520 | 586 | ||
521 | out_err: | 587 | out_err: |
522 | nouveau_channel_free(dev_priv->channel); | 588 | nouveau_channel_put(&dev_priv->channel); |
523 | dev_priv->channel = NULL; | ||
524 | return ret; | 589 | return ret; |
525 | } | 590 | } |
526 | 591 | ||
@@ -531,15 +596,25 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev, | |||
531 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | 596 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
532 | if (state == VGA_SWITCHEROO_ON) { | 597 | if (state == VGA_SWITCHEROO_ON) { |
533 | printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); | 598 | printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); |
599 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
534 | nouveau_pci_resume(pdev); | 600 | nouveau_pci_resume(pdev); |
535 | drm_kms_helper_poll_enable(dev); | 601 | drm_kms_helper_poll_enable(dev); |
602 | dev->switch_power_state = DRM_SWITCH_POWER_ON; | ||
536 | } else { | 603 | } else { |
537 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); | 604 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); |
605 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | ||
538 | drm_kms_helper_poll_disable(dev); | 606 | drm_kms_helper_poll_disable(dev); |
539 | nouveau_pci_suspend(pdev, pmm); | 607 | nouveau_pci_suspend(pdev, pmm); |
608 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | ||
540 | } | 609 | } |
541 | } | 610 | } |
542 | 611 | ||
612 | static void nouveau_switcheroo_reprobe(struct pci_dev *pdev) | ||
613 | { | ||
614 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
615 | nouveau_fbcon_output_poll_changed(dev); | ||
616 | } | ||
617 | |||
543 | static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) | 618 | static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) |
544 | { | 619 | { |
545 | struct drm_device *dev = pci_get_drvdata(pdev); | 620 | struct drm_device *dev = pci_get_drvdata(pdev); |
@@ -560,6 +635,7 @@ nouveau_card_init(struct drm_device *dev) | |||
560 | 635 | ||
561 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); | 636 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); |
562 | vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, | 637 | vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, |
638 | nouveau_switcheroo_reprobe, | ||
563 | nouveau_switcheroo_can_switch); | 639 | nouveau_switcheroo_can_switch); |
564 | 640 | ||
565 | /* Initialise internal driver API hooks */ | 641 | /* Initialise internal driver API hooks */ |
@@ -567,6 +643,8 @@ nouveau_card_init(struct drm_device *dev) | |||
567 | if (ret) | 643 | if (ret) |
568 | goto out; | 644 | goto out; |
569 | engine = &dev_priv->engine; | 645 | engine = &dev_priv->engine; |
646 | spin_lock_init(&dev_priv->channels.lock); | ||
647 | spin_lock_init(&dev_priv->tile.lock); | ||
570 | spin_lock_init(&dev_priv->context_switch_lock); | 648 | spin_lock_init(&dev_priv->context_switch_lock); |
571 | 649 | ||
572 | /* Make the CRTCs and I2C buses accessible */ | 650 | /* Make the CRTCs and I2C buses accessible */ |
@@ -625,26 +703,28 @@ nouveau_card_init(struct drm_device *dev) | |||
625 | if (ret) | 703 | if (ret) |
626 | goto out_fb; | 704 | goto out_fb; |
627 | 705 | ||
706 | /* PCRYPT */ | ||
707 | ret = engine->crypt.init(dev); | ||
708 | if (ret) | ||
709 | goto out_graph; | ||
710 | |||
628 | /* PFIFO */ | 711 | /* PFIFO */ |
629 | ret = engine->fifo.init(dev); | 712 | ret = engine->fifo.init(dev); |
630 | if (ret) | 713 | if (ret) |
631 | goto out_graph; | 714 | goto out_crypt; |
632 | } | 715 | } |
633 | 716 | ||
634 | ret = engine->display.create(dev); | 717 | ret = engine->display.create(dev); |
635 | if (ret) | 718 | if (ret) |
636 | goto out_fifo; | 719 | goto out_fifo; |
637 | 720 | ||
638 | /* this call irq_preinstall, register irq handler and | 721 | ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1); |
639 | * call irq_postinstall | ||
640 | */ | ||
641 | ret = drm_irq_install(dev); | ||
642 | if (ret) | 722 | if (ret) |
643 | goto out_display; | 723 | goto out_vblank; |
644 | 724 | ||
645 | ret = drm_vblank_init(dev, 0); | 725 | ret = nouveau_irq_init(dev); |
646 | if (ret) | 726 | if (ret) |
647 | goto out_irq; | 727 | goto out_vblank; |
648 | 728 | ||
649 | /* what about PVIDEO/PCRTC/PRAMDAC etc? */ | 729 | /* what about PVIDEO/PCRTC/PRAMDAC etc? */ |
650 | 730 | ||
@@ -669,12 +749,16 @@ nouveau_card_init(struct drm_device *dev) | |||
669 | out_fence: | 749 | out_fence: |
670 | nouveau_fence_fini(dev); | 750 | nouveau_fence_fini(dev); |
671 | out_irq: | 751 | out_irq: |
672 | drm_irq_uninstall(dev); | 752 | nouveau_irq_fini(dev); |
673 | out_display: | 753 | out_vblank: |
754 | drm_vblank_cleanup(dev); | ||
674 | engine->display.destroy(dev); | 755 | engine->display.destroy(dev); |
675 | out_fifo: | 756 | out_fifo: |
676 | if (!nouveau_noaccel) | 757 | if (!nouveau_noaccel) |
677 | engine->fifo.takedown(dev); | 758 | engine->fifo.takedown(dev); |
759 | out_crypt: | ||
760 | if (!nouveau_noaccel) | ||
761 | engine->crypt.takedown(dev); | ||
678 | out_graph: | 762 | out_graph: |
679 | if (!nouveau_noaccel) | 763 | if (!nouveau_noaccel) |
680 | engine->graph.takedown(dev); | 764 | engine->graph.takedown(dev); |
@@ -713,12 +797,12 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
713 | 797 | ||
714 | if (!engine->graph.accel_blocked) { | 798 | if (!engine->graph.accel_blocked) { |
715 | nouveau_fence_fini(dev); | 799 | nouveau_fence_fini(dev); |
716 | nouveau_channel_free(dev_priv->channel); | 800 | nouveau_channel_put_unlocked(&dev_priv->channel); |
717 | dev_priv->channel = NULL; | ||
718 | } | 801 | } |
719 | 802 | ||
720 | if (!nouveau_noaccel) { | 803 | if (!nouveau_noaccel) { |
721 | engine->fifo.takedown(dev); | 804 | engine->fifo.takedown(dev); |
805 | engine->crypt.takedown(dev); | ||
722 | engine->graph.takedown(dev); | 806 | engine->graph.takedown(dev); |
723 | } | 807 | } |
724 | engine->fb.takedown(dev); | 808 | engine->fb.takedown(dev); |
@@ -737,7 +821,8 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
737 | nouveau_gpuobj_takedown(dev); | 821 | nouveau_gpuobj_takedown(dev); |
738 | nouveau_mem_vram_fini(dev); | 822 | nouveau_mem_vram_fini(dev); |
739 | 823 | ||
740 | drm_irq_uninstall(dev); | 824 | nouveau_irq_fini(dev); |
825 | drm_vblank_cleanup(dev); | ||
741 | 826 | ||
742 | nouveau_pm_fini(dev); | 827 | nouveau_pm_fini(dev); |
743 | nouveau_bios_takedown(dev); | 828 | nouveau_bios_takedown(dev); |
@@ -980,6 +1065,7 @@ err_out: | |||
980 | 1065 | ||
981 | void nouveau_lastclose(struct drm_device *dev) | 1066 | void nouveau_lastclose(struct drm_device *dev) |
982 | { | 1067 | { |
1068 | vga_switcheroo_process_delayed_switch(); | ||
983 | } | 1069 | } |
984 | 1070 | ||
985 | int nouveau_unload(struct drm_device *dev) | 1071 | int nouveau_unload(struct drm_device *dev) |
@@ -1024,21 +1110,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
1024 | else | 1110 | else |
1025 | getparam->value = NV_PCI; | 1111 | getparam->value = NV_PCI; |
1026 | break; | 1112 | break; |
1027 | case NOUVEAU_GETPARAM_FB_PHYSICAL: | ||
1028 | getparam->value = dev_priv->fb_phys; | ||
1029 | break; | ||
1030 | case NOUVEAU_GETPARAM_AGP_PHYSICAL: | ||
1031 | getparam->value = dev_priv->gart_info.aper_base; | ||
1032 | break; | ||
1033 | case NOUVEAU_GETPARAM_PCI_PHYSICAL: | ||
1034 | if (dev->sg) { | ||
1035 | getparam->value = (unsigned long)dev->sg->virtual; | ||
1036 | } else { | ||
1037 | NV_ERROR(dev, "Requested PCIGART address, " | ||
1038 | "while no PCIGART was created\n"); | ||
1039 | return -EINVAL; | ||
1040 | } | ||
1041 | break; | ||
1042 | case NOUVEAU_GETPARAM_FB_SIZE: | 1113 | case NOUVEAU_GETPARAM_FB_SIZE: |
1043 | getparam->value = dev_priv->fb_available_size; | 1114 | getparam->value = dev_priv->fb_available_size; |
1044 | break; | 1115 | break; |
@@ -1046,7 +1117,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
1046 | getparam->value = dev_priv->gart_info.aper_size; | 1117 | getparam->value = dev_priv->gart_info.aper_size; |
1047 | break; | 1118 | break; |
1048 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: | 1119 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: |
1049 | getparam->value = dev_priv->vm_vram_base; | 1120 | getparam->value = 0; /* deprecated */ |
1050 | break; | 1121 | break; |
1051 | case NOUVEAU_GETPARAM_PTIMER_TIME: | 1122 | case NOUVEAU_GETPARAM_PTIMER_TIME: |
1052 | getparam->value = dev_priv->engine.timer.read(dev); | 1123 | getparam->value = dev_priv->engine.timer.read(dev); |
@@ -1054,6 +1125,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
1054 | case NOUVEAU_GETPARAM_HAS_BO_USAGE: | 1125 | case NOUVEAU_GETPARAM_HAS_BO_USAGE: |
1055 | getparam->value = 1; | 1126 | getparam->value = 1; |
1056 | break; | 1127 | break; |
1128 | case NOUVEAU_GETPARAM_HAS_PAGEFLIP: | ||
1129 | getparam->value = (dev_priv->card_type < NV_50); | ||
1130 | break; | ||
1057 | case NOUVEAU_GETPARAM_GRAPH_UNITS: | 1131 | case NOUVEAU_GETPARAM_GRAPH_UNITS: |
1058 | /* NV40 and NV50 versions are quite different, but register | 1132 | /* NV40 and NV50 versions are quite different, but register |
1059 | * address is the same. User is supposed to know the card | 1133 | * address is the same. User is supposed to know the card |
@@ -1087,8 +1161,9 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, | |||
1087 | } | 1161 | } |
1088 | 1162 | ||
1089 | /* Wait until (value(reg) & mask) == val, up until timeout has hit */ | 1163 | /* Wait until (value(reg) & mask) == val, up until timeout has hit */ |
1090 | bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, | 1164 | bool |
1091 | uint32_t reg, uint32_t mask, uint32_t val) | 1165 | nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, |
1166 | uint32_t reg, uint32_t mask, uint32_t val) | ||
1092 | { | 1167 | { |
1093 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 1168 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
1094 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | 1169 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; |
@@ -1102,10 +1177,33 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, | |||
1102 | return false; | 1177 | return false; |
1103 | } | 1178 | } |
1104 | 1179 | ||
1180 | /* Wait until (value(reg) & mask) != val, up until timeout has hit */ | ||
1181 | bool | ||
1182 | nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, | ||
1183 | uint32_t reg, uint32_t mask, uint32_t val) | ||
1184 | { | ||
1185 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1186 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | ||
1187 | uint64_t start = ptimer->read(dev); | ||
1188 | |||
1189 | do { | ||
1190 | if ((nv_rd32(dev, reg) & mask) != val) | ||
1191 | return true; | ||
1192 | } while (ptimer->read(dev) - start < timeout); | ||
1193 | |||
1194 | return false; | ||
1195 | } | ||
1196 | |||
1105 | /* Waits for PGRAPH to go completely idle */ | 1197 | /* Waits for PGRAPH to go completely idle */ |
1106 | bool nouveau_wait_for_idle(struct drm_device *dev) | 1198 | bool nouveau_wait_for_idle(struct drm_device *dev) |
1107 | { | 1199 | { |
1108 | if (!nv_wait(dev, NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { | 1200 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
1201 | uint32_t mask = ~0; | ||
1202 | |||
1203 | if (dev_priv->card_type == NV_40) | ||
1204 | mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL; | ||
1205 | |||
1206 | if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) { | ||
1109 | NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", | 1207 | NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", |
1110 | nv_rd32(dev, NV04_PGRAPH_STATUS)); | 1208 | nv_rd32(dev, NV04_PGRAPH_STATUS)); |
1111 | return false; | 1209 | return false; |