2 * Copyright 2005 Stephane Marchesin
3 * Copyright 2008 Stuart Bennett
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include <linux/swab.h>
27 #include <linux/slab.h>
30 #include "drm_sarea.h"
31 #include "drm_crtc_helper.h"
32 #include <linux/vgaarb.h>
33 #include <linux/vga_switcheroo.h>
35 #include "nouveau_drv.h"
36 #include "nouveau_drm.h"
37 #include "nouveau_fbcon.h"
38 #include "nouveau_ramht.h"
39 #include "nouveau_pm.h"
40 #include "nv50_display.h"
42 static void nouveau_stub_takedown(struct drm_device
*dev
) {}
43 static int nouveau_stub_init(struct drm_device
*dev
) { return 0; }
45 static int nouveau_init_engine_ptrs(struct drm_device
*dev
)
47 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
48 struct nouveau_engine
*engine
= &dev_priv
->engine
;
50 switch (dev_priv
->chipset
& 0xf0) {
52 engine
->instmem
.init
= nv04_instmem_init
;
53 engine
->instmem
.takedown
= nv04_instmem_takedown
;
54 engine
->instmem
.suspend
= nv04_instmem_suspend
;
55 engine
->instmem
.resume
= nv04_instmem_resume
;
56 engine
->instmem
.get
= nv04_instmem_get
;
57 engine
->instmem
.put
= nv04_instmem_put
;
58 engine
->instmem
.map
= nv04_instmem_map
;
59 engine
->instmem
.unmap
= nv04_instmem_unmap
;
60 engine
->instmem
.flush
= nv04_instmem_flush
;
61 engine
->mc
.init
= nv04_mc_init
;
62 engine
->mc
.takedown
= nv04_mc_takedown
;
63 engine
->timer
.init
= nv04_timer_init
;
64 engine
->timer
.read
= nv04_timer_read
;
65 engine
->timer
.takedown
= nv04_timer_takedown
;
66 engine
->fb
.init
= nv04_fb_init
;
67 engine
->fb
.takedown
= nv04_fb_takedown
;
68 engine
->graph
.init
= nv04_graph_init
;
69 engine
->graph
.takedown
= nv04_graph_takedown
;
70 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
71 engine
->graph
.channel
= nv04_graph_channel
;
72 engine
->graph
.create_context
= nv04_graph_create_context
;
73 engine
->graph
.destroy_context
= nv04_graph_destroy_context
;
74 engine
->graph
.load_context
= nv04_graph_load_context
;
75 engine
->graph
.unload_context
= nv04_graph_unload_context
;
76 engine
->fifo
.channels
= 16;
77 engine
->fifo
.init
= nv04_fifo_init
;
78 engine
->fifo
.takedown
= nv04_fifo_fini
;
79 engine
->fifo
.disable
= nv04_fifo_disable
;
80 engine
->fifo
.enable
= nv04_fifo_enable
;
81 engine
->fifo
.reassign
= nv04_fifo_reassign
;
82 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
83 engine
->fifo
.channel_id
= nv04_fifo_channel_id
;
84 engine
->fifo
.create_context
= nv04_fifo_create_context
;
85 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
86 engine
->fifo
.load_context
= nv04_fifo_load_context
;
87 engine
->fifo
.unload_context
= nv04_fifo_unload_context
;
88 engine
->display
.early_init
= nv04_display_early_init
;
89 engine
->display
.late_takedown
= nv04_display_late_takedown
;
90 engine
->display
.create
= nv04_display_create
;
91 engine
->display
.init
= nv04_display_init
;
92 engine
->display
.destroy
= nv04_display_destroy
;
93 engine
->gpio
.init
= nouveau_stub_init
;
94 engine
->gpio
.takedown
= nouveau_stub_takedown
;
95 engine
->gpio
.get
= NULL
;
96 engine
->gpio
.set
= NULL
;
97 engine
->gpio
.irq_enable
= NULL
;
98 engine
->pm
.clock_get
= nv04_pm_clock_get
;
99 engine
->pm
.clock_pre
= nv04_pm_clock_pre
;
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
;
107 engine
->instmem
.init
= nv04_instmem_init
;
108 engine
->instmem
.takedown
= nv04_instmem_takedown
;
109 engine
->instmem
.suspend
= nv04_instmem_suspend
;
110 engine
->instmem
.resume
= nv04_instmem_resume
;
111 engine
->instmem
.get
= nv04_instmem_get
;
112 engine
->instmem
.put
= nv04_instmem_put
;
113 engine
->instmem
.map
= nv04_instmem_map
;
114 engine
->instmem
.unmap
= nv04_instmem_unmap
;
115 engine
->instmem
.flush
= nv04_instmem_flush
;
116 engine
->mc
.init
= nv04_mc_init
;
117 engine
->mc
.takedown
= nv04_mc_takedown
;
118 engine
->timer
.init
= nv04_timer_init
;
119 engine
->timer
.read
= nv04_timer_read
;
120 engine
->timer
.takedown
= nv04_timer_takedown
;
121 engine
->fb
.init
= nv10_fb_init
;
122 engine
->fb
.takedown
= nv10_fb_takedown
;
123 engine
->fb
.init_tile_region
= nv10_fb_init_tile_region
;
124 engine
->fb
.set_tile_region
= nv10_fb_set_tile_region
;
125 engine
->fb
.free_tile_region
= nv10_fb_free_tile_region
;
126 engine
->graph
.init
= nv10_graph_init
;
127 engine
->graph
.takedown
= nv10_graph_takedown
;
128 engine
->graph
.channel
= nv10_graph_channel
;
129 engine
->graph
.create_context
= nv10_graph_create_context
;
130 engine
->graph
.destroy_context
= nv10_graph_destroy_context
;
131 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
132 engine
->graph
.load_context
= nv10_graph_load_context
;
133 engine
->graph
.unload_context
= nv10_graph_unload_context
;
134 engine
->graph
.set_tile_region
= nv10_graph_set_tile_region
;
135 engine
->fifo
.channels
= 32;
136 engine
->fifo
.init
= nv10_fifo_init
;
137 engine
->fifo
.takedown
= nv04_fifo_fini
;
138 engine
->fifo
.disable
= nv04_fifo_disable
;
139 engine
->fifo
.enable
= nv04_fifo_enable
;
140 engine
->fifo
.reassign
= nv04_fifo_reassign
;
141 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
142 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
143 engine
->fifo
.create_context
= nv10_fifo_create_context
;
144 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
145 engine
->fifo
.load_context
= nv10_fifo_load_context
;
146 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
147 engine
->display
.early_init
= nv04_display_early_init
;
148 engine
->display
.late_takedown
= nv04_display_late_takedown
;
149 engine
->display
.create
= nv04_display_create
;
150 engine
->display
.init
= nv04_display_init
;
151 engine
->display
.destroy
= nv04_display_destroy
;
152 engine
->gpio
.init
= nouveau_stub_init
;
153 engine
->gpio
.takedown
= nouveau_stub_takedown
;
154 engine
->gpio
.get
= nv10_gpio_get
;
155 engine
->gpio
.set
= nv10_gpio_set
;
156 engine
->gpio
.irq_enable
= NULL
;
157 engine
->pm
.clock_get
= nv04_pm_clock_get
;
158 engine
->pm
.clock_pre
= nv04_pm_clock_pre
;
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
;
166 engine
->instmem
.init
= nv04_instmem_init
;
167 engine
->instmem
.takedown
= nv04_instmem_takedown
;
168 engine
->instmem
.suspend
= nv04_instmem_suspend
;
169 engine
->instmem
.resume
= nv04_instmem_resume
;
170 engine
->instmem
.get
= nv04_instmem_get
;
171 engine
->instmem
.put
= nv04_instmem_put
;
172 engine
->instmem
.map
= nv04_instmem_map
;
173 engine
->instmem
.unmap
= nv04_instmem_unmap
;
174 engine
->instmem
.flush
= nv04_instmem_flush
;
175 engine
->mc
.init
= nv04_mc_init
;
176 engine
->mc
.takedown
= nv04_mc_takedown
;
177 engine
->timer
.init
= nv04_timer_init
;
178 engine
->timer
.read
= nv04_timer_read
;
179 engine
->timer
.takedown
= nv04_timer_takedown
;
180 engine
->fb
.init
= nv10_fb_init
;
181 engine
->fb
.takedown
= nv10_fb_takedown
;
182 engine
->fb
.init_tile_region
= nv10_fb_init_tile_region
;
183 engine
->fb
.set_tile_region
= nv10_fb_set_tile_region
;
184 engine
->fb
.free_tile_region
= nv10_fb_free_tile_region
;
185 engine
->graph
.init
= nv20_graph_init
;
186 engine
->graph
.takedown
= nv20_graph_takedown
;
187 engine
->graph
.channel
= nv10_graph_channel
;
188 engine
->graph
.create_context
= nv20_graph_create_context
;
189 engine
->graph
.destroy_context
= nv20_graph_destroy_context
;
190 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
191 engine
->graph
.load_context
= nv20_graph_load_context
;
192 engine
->graph
.unload_context
= nv20_graph_unload_context
;
193 engine
->graph
.set_tile_region
= nv20_graph_set_tile_region
;
194 engine
->fifo
.channels
= 32;
195 engine
->fifo
.init
= nv10_fifo_init
;
196 engine
->fifo
.takedown
= nv04_fifo_fini
;
197 engine
->fifo
.disable
= nv04_fifo_disable
;
198 engine
->fifo
.enable
= nv04_fifo_enable
;
199 engine
->fifo
.reassign
= nv04_fifo_reassign
;
200 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
201 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
202 engine
->fifo
.create_context
= nv10_fifo_create_context
;
203 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
204 engine
->fifo
.load_context
= nv10_fifo_load_context
;
205 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
206 engine
->display
.early_init
= nv04_display_early_init
;
207 engine
->display
.late_takedown
= nv04_display_late_takedown
;
208 engine
->display
.create
= nv04_display_create
;
209 engine
->display
.init
= nv04_display_init
;
210 engine
->display
.destroy
= nv04_display_destroy
;
211 engine
->gpio
.init
= nouveau_stub_init
;
212 engine
->gpio
.takedown
= nouveau_stub_takedown
;
213 engine
->gpio
.get
= nv10_gpio_get
;
214 engine
->gpio
.set
= nv10_gpio_set
;
215 engine
->gpio
.irq_enable
= NULL
;
216 engine
->pm
.clock_get
= nv04_pm_clock_get
;
217 engine
->pm
.clock_pre
= nv04_pm_clock_pre
;
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
;
225 engine
->instmem
.init
= nv04_instmem_init
;
226 engine
->instmem
.takedown
= nv04_instmem_takedown
;
227 engine
->instmem
.suspend
= nv04_instmem_suspend
;
228 engine
->instmem
.resume
= nv04_instmem_resume
;
229 engine
->instmem
.get
= nv04_instmem_get
;
230 engine
->instmem
.put
= nv04_instmem_put
;
231 engine
->instmem
.map
= nv04_instmem_map
;
232 engine
->instmem
.unmap
= nv04_instmem_unmap
;
233 engine
->instmem
.flush
= nv04_instmem_flush
;
234 engine
->mc
.init
= nv04_mc_init
;
235 engine
->mc
.takedown
= nv04_mc_takedown
;
236 engine
->timer
.init
= nv04_timer_init
;
237 engine
->timer
.read
= nv04_timer_read
;
238 engine
->timer
.takedown
= nv04_timer_takedown
;
239 engine
->fb
.init
= nv30_fb_init
;
240 engine
->fb
.takedown
= nv30_fb_takedown
;
241 engine
->fb
.init_tile_region
= nv30_fb_init_tile_region
;
242 engine
->fb
.set_tile_region
= nv10_fb_set_tile_region
;
243 engine
->fb
.free_tile_region
= nv30_fb_free_tile_region
;
244 engine
->graph
.init
= nv30_graph_init
;
245 engine
->graph
.takedown
= nv20_graph_takedown
;
246 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
247 engine
->graph
.channel
= nv10_graph_channel
;
248 engine
->graph
.create_context
= nv20_graph_create_context
;
249 engine
->graph
.destroy_context
= nv20_graph_destroy_context
;
250 engine
->graph
.load_context
= nv20_graph_load_context
;
251 engine
->graph
.unload_context
= nv20_graph_unload_context
;
252 engine
->graph
.set_tile_region
= nv20_graph_set_tile_region
;
253 engine
->fifo
.channels
= 32;
254 engine
->fifo
.init
= nv10_fifo_init
;
255 engine
->fifo
.takedown
= nv04_fifo_fini
;
256 engine
->fifo
.disable
= nv04_fifo_disable
;
257 engine
->fifo
.enable
= nv04_fifo_enable
;
258 engine
->fifo
.reassign
= nv04_fifo_reassign
;
259 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
260 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
261 engine
->fifo
.create_context
= nv10_fifo_create_context
;
262 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
263 engine
->fifo
.load_context
= nv10_fifo_load_context
;
264 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
265 engine
->display
.early_init
= nv04_display_early_init
;
266 engine
->display
.late_takedown
= nv04_display_late_takedown
;
267 engine
->display
.create
= nv04_display_create
;
268 engine
->display
.init
= nv04_display_init
;
269 engine
->display
.destroy
= nv04_display_destroy
;
270 engine
->gpio
.init
= nouveau_stub_init
;
271 engine
->gpio
.takedown
= nouveau_stub_takedown
;
272 engine
->gpio
.get
= nv10_gpio_get
;
273 engine
->gpio
.set
= nv10_gpio_set
;
274 engine
->gpio
.irq_enable
= NULL
;
275 engine
->pm
.clock_get
= nv04_pm_clock_get
;
276 engine
->pm
.clock_pre
= nv04_pm_clock_pre
;
277 engine
->pm
.clock_set
= nv04_pm_clock_set
;
278 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
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
;
287 engine
->instmem
.init
= nv04_instmem_init
;
288 engine
->instmem
.takedown
= nv04_instmem_takedown
;
289 engine
->instmem
.suspend
= nv04_instmem_suspend
;
290 engine
->instmem
.resume
= nv04_instmem_resume
;
291 engine
->instmem
.get
= nv04_instmem_get
;
292 engine
->instmem
.put
= nv04_instmem_put
;
293 engine
->instmem
.map
= nv04_instmem_map
;
294 engine
->instmem
.unmap
= nv04_instmem_unmap
;
295 engine
->instmem
.flush
= nv04_instmem_flush
;
296 engine
->mc
.init
= nv40_mc_init
;
297 engine
->mc
.takedown
= nv40_mc_takedown
;
298 engine
->timer
.init
= nv04_timer_init
;
299 engine
->timer
.read
= nv04_timer_read
;
300 engine
->timer
.takedown
= nv04_timer_takedown
;
301 engine
->fb
.init
= nv40_fb_init
;
302 engine
->fb
.takedown
= nv40_fb_takedown
;
303 engine
->fb
.init_tile_region
= nv30_fb_init_tile_region
;
304 engine
->fb
.set_tile_region
= nv40_fb_set_tile_region
;
305 engine
->fb
.free_tile_region
= nv30_fb_free_tile_region
;
306 engine
->graph
.init
= nv40_graph_init
;
307 engine
->graph
.takedown
= nv40_graph_takedown
;
308 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
309 engine
->graph
.channel
= nv40_graph_channel
;
310 engine
->graph
.create_context
= nv40_graph_create_context
;
311 engine
->graph
.destroy_context
= nv40_graph_destroy_context
;
312 engine
->graph
.load_context
= nv40_graph_load_context
;
313 engine
->graph
.unload_context
= nv40_graph_unload_context
;
314 engine
->graph
.set_tile_region
= nv40_graph_set_tile_region
;
315 engine
->fifo
.channels
= 32;
316 engine
->fifo
.init
= nv40_fifo_init
;
317 engine
->fifo
.takedown
= nv04_fifo_fini
;
318 engine
->fifo
.disable
= nv04_fifo_disable
;
319 engine
->fifo
.enable
= nv04_fifo_enable
;
320 engine
->fifo
.reassign
= nv04_fifo_reassign
;
321 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
322 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
323 engine
->fifo
.create_context
= nv40_fifo_create_context
;
324 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
325 engine
->fifo
.load_context
= nv40_fifo_load_context
;
326 engine
->fifo
.unload_context
= nv40_fifo_unload_context
;
327 engine
->display
.early_init
= nv04_display_early_init
;
328 engine
->display
.late_takedown
= nv04_display_late_takedown
;
329 engine
->display
.create
= nv04_display_create
;
330 engine
->display
.init
= nv04_display_init
;
331 engine
->display
.destroy
= nv04_display_destroy
;
332 engine
->gpio
.init
= nouveau_stub_init
;
333 engine
->gpio
.takedown
= nouveau_stub_takedown
;
334 engine
->gpio
.get
= nv10_gpio_get
;
335 engine
->gpio
.set
= nv10_gpio_set
;
336 engine
->gpio
.irq_enable
= NULL
;
337 engine
->pm
.clock_get
= nv04_pm_clock_get
;
338 engine
->pm
.clock_pre
= nv04_pm_clock_pre
;
339 engine
->pm
.clock_set
= nv04_pm_clock_set
;
340 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
341 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
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
;
349 case 0x80: /* gotta love NVIDIA's consistency.. */
352 engine
->instmem
.init
= nv50_instmem_init
;
353 engine
->instmem
.takedown
= nv50_instmem_takedown
;
354 engine
->instmem
.suspend
= nv50_instmem_suspend
;
355 engine
->instmem
.resume
= nv50_instmem_resume
;
356 engine
->instmem
.get
= nv50_instmem_get
;
357 engine
->instmem
.put
= nv50_instmem_put
;
358 engine
->instmem
.map
= nv50_instmem_map
;
359 engine
->instmem
.unmap
= nv50_instmem_unmap
;
360 if (dev_priv
->chipset
== 0x50)
361 engine
->instmem
.flush
= nv50_instmem_flush
;
363 engine
->instmem
.flush
= nv84_instmem_flush
;
364 engine
->mc
.init
= nv50_mc_init
;
365 engine
->mc
.takedown
= nv50_mc_takedown
;
366 engine
->timer
.init
= nv04_timer_init
;
367 engine
->timer
.read
= nv04_timer_read
;
368 engine
->timer
.takedown
= nv04_timer_takedown
;
369 engine
->fb
.init
= nv50_fb_init
;
370 engine
->fb
.takedown
= nv50_fb_takedown
;
371 engine
->graph
.init
= nv50_graph_init
;
372 engine
->graph
.takedown
= nv50_graph_takedown
;
373 engine
->graph
.fifo_access
= nv50_graph_fifo_access
;
374 engine
->graph
.channel
= nv50_graph_channel
;
375 engine
->graph
.create_context
= nv50_graph_create_context
;
376 engine
->graph
.destroy_context
= nv50_graph_destroy_context
;
377 engine
->graph
.load_context
= nv50_graph_load_context
;
378 engine
->graph
.unload_context
= nv50_graph_unload_context
;
379 if (dev_priv
->chipset
!= 0x86)
380 engine
->graph
.tlb_flush
= nv50_graph_tlb_flush
;
382 /* from what i can see nvidia do this on every
383 * pre-NVA3 board except NVAC, but, we've only
384 * ever seen problems on NV86
386 engine
->graph
.tlb_flush
= nv86_graph_tlb_flush
;
388 engine
->fifo
.channels
= 128;
389 engine
->fifo
.init
= nv50_fifo_init
;
390 engine
->fifo
.takedown
= nv50_fifo_takedown
;
391 engine
->fifo
.disable
= nv04_fifo_disable
;
392 engine
->fifo
.enable
= nv04_fifo_enable
;
393 engine
->fifo
.reassign
= nv04_fifo_reassign
;
394 engine
->fifo
.channel_id
= nv50_fifo_channel_id
;
395 engine
->fifo
.create_context
= nv50_fifo_create_context
;
396 engine
->fifo
.destroy_context
= nv50_fifo_destroy_context
;
397 engine
->fifo
.load_context
= nv50_fifo_load_context
;
398 engine
->fifo
.unload_context
= nv50_fifo_unload_context
;
399 engine
->fifo
.tlb_flush
= nv50_fifo_tlb_flush
;
400 engine
->display
.early_init
= nv50_display_early_init
;
401 engine
->display
.late_takedown
= nv50_display_late_takedown
;
402 engine
->display
.create
= nv50_display_create
;
403 engine
->display
.init
= nv50_display_init
;
404 engine
->display
.destroy
= nv50_display_destroy
;
405 engine
->gpio
.init
= nv50_gpio_init
;
406 engine
->gpio
.takedown
= nv50_gpio_fini
;
407 engine
->gpio
.get
= nv50_gpio_get
;
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
;
411 engine
->gpio
.irq_enable
= nv50_gpio_irq_enable
;
412 switch (dev_priv
->chipset
) {
423 engine
->pm
.clock_get
= nv50_pm_clock_get
;
424 engine
->pm
.clock_pre
= nv50_pm_clock_pre
;
425 engine
->pm
.clock_set
= nv50_pm_clock_set
;
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
;
433 engine
->pm
.voltage_get
= nouveau_voltage_gpio_get
;
434 engine
->pm
.voltage_set
= nouveau_voltage_gpio_set
;
435 if (dev_priv
->chipset
>= 0x84)
436 engine
->pm
.temp_get
= nv84_temp_get
;
438 engine
->pm
.temp_get
= nv40_temp_get
;
439 switch (dev_priv
->chipset
) {
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
;
453 engine
->crypt
.init
= nouveau_stub_init
;
454 engine
->crypt
.takedown
= nouveau_stub_takedown
;
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
;
463 engine
->instmem
.init
= nvc0_instmem_init
;
464 engine
->instmem
.takedown
= nvc0_instmem_takedown
;
465 engine
->instmem
.suspend
= nvc0_instmem_suspend
;
466 engine
->instmem
.resume
= nvc0_instmem_resume
;
467 engine
->instmem
.get
= nv50_instmem_get
;
468 engine
->instmem
.put
= nv50_instmem_put
;
469 engine
->instmem
.map
= nv50_instmem_map
;
470 engine
->instmem
.unmap
= nv50_instmem_unmap
;
471 engine
->instmem
.flush
= nv84_instmem_flush
;
472 engine
->mc
.init
= nv50_mc_init
;
473 engine
->mc
.takedown
= nv50_mc_takedown
;
474 engine
->timer
.init
= nv04_timer_init
;
475 engine
->timer
.read
= nv04_timer_read
;
476 engine
->timer
.takedown
= nv04_timer_takedown
;
477 engine
->fb
.init
= nvc0_fb_init
;
478 engine
->fb
.takedown
= nvc0_fb_takedown
;
479 engine
->graph
.init
= nvc0_graph_init
;
480 engine
->graph
.takedown
= nvc0_graph_takedown
;
481 engine
->graph
.fifo_access
= nvc0_graph_fifo_access
;
482 engine
->graph
.channel
= nvc0_graph_channel
;
483 engine
->graph
.create_context
= nvc0_graph_create_context
;
484 engine
->graph
.destroy_context
= nvc0_graph_destroy_context
;
485 engine
->graph
.load_context
= nvc0_graph_load_context
;
486 engine
->graph
.unload_context
= nvc0_graph_unload_context
;
487 engine
->fifo
.channels
= 128;
488 engine
->fifo
.init
= nvc0_fifo_init
;
489 engine
->fifo
.takedown
= nvc0_fifo_takedown
;
490 engine
->fifo
.disable
= nvc0_fifo_disable
;
491 engine
->fifo
.enable
= nvc0_fifo_enable
;
492 engine
->fifo
.reassign
= nvc0_fifo_reassign
;
493 engine
->fifo
.channel_id
= nvc0_fifo_channel_id
;
494 engine
->fifo
.create_context
= nvc0_fifo_create_context
;
495 engine
->fifo
.destroy_context
= nvc0_fifo_destroy_context
;
496 engine
->fifo
.load_context
= nvc0_fifo_load_context
;
497 engine
->fifo
.unload_context
= nvc0_fifo_unload_context
;
498 engine
->display
.early_init
= nv50_display_early_init
;
499 engine
->display
.late_takedown
= nv50_display_late_takedown
;
500 engine
->display
.create
= nv50_display_create
;
501 engine
->display
.init
= nv50_display_init
;
502 engine
->display
.destroy
= nv50_display_destroy
;
503 engine
->gpio
.init
= nv50_gpio_init
;
504 engine
->gpio
.takedown
= nouveau_stub_takedown
;
505 engine
->gpio
.get
= nv50_gpio_get
;
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
;
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
;
518 NV_ERROR(dev
, "NV%02x unsupported\n", dev_priv
->chipset
);
526 nouveau_vga_set_decode(void *priv
, bool state
)
528 struct drm_device
*dev
= priv
;
529 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
531 if (dev_priv
->chipset
>= 0x40)
532 nv_wr32(dev
, 0x88054, state
);
534 nv_wr32(dev
, 0x1854, state
);
537 return VGA_RSRC_LEGACY_IO
| VGA_RSRC_LEGACY_MEM
|
538 VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
540 return VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
544 nouveau_card_init_channel(struct drm_device
*dev
)
546 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
547 struct nouveau_gpuobj
*gpuobj
= NULL
;
550 ret
= nouveau_channel_alloc(dev
, &dev_priv
->channel
,
551 (struct drm_file
*)-2, NvDmaFB
, NvDmaTT
);
555 /* no dma objects on fermi... */
556 if (dev_priv
->card_type
>= NV_C0
)
559 ret
= nouveau_gpuobj_dma_new(dev_priv
->channel
, NV_CLASS_DMA_IN_MEMORY
,
560 0, dev_priv
->vram_size
,
561 NV_MEM_ACCESS_RW
, NV_MEM_TARGET_VRAM
,
566 ret
= nouveau_ramht_insert(dev_priv
->channel
, NvDmaVRAM
, gpuobj
);
567 nouveau_gpuobj_ref(NULL
, &gpuobj
);
571 ret
= nouveau_gpuobj_dma_new(dev_priv
->channel
, NV_CLASS_DMA_IN_MEMORY
,
572 0, dev_priv
->gart_info
.aper_size
,
573 NV_MEM_ACCESS_RW
, NV_MEM_TARGET_GART
,
578 ret
= nouveau_ramht_insert(dev_priv
->channel
, NvDmaGART
, gpuobj
);
579 nouveau_gpuobj_ref(NULL
, &gpuobj
);
584 mutex_unlock(&dev_priv
->channel
->mutex
);
588 nouveau_channel_put(&dev_priv
->channel
);
592 static void nouveau_switcheroo_set_state(struct pci_dev
*pdev
,
593 enum vga_switcheroo_state state
)
595 struct drm_device
*dev
= pci_get_drvdata(pdev
);
596 pm_message_t pmm
= { .event
= PM_EVENT_SUSPEND
};
597 if (state
== VGA_SWITCHEROO_ON
) {
598 printk(KERN_ERR
"VGA switcheroo: switched nouveau on\n");
599 nouveau_pci_resume(pdev
);
600 drm_kms_helper_poll_enable(dev
);
602 printk(KERN_ERR
"VGA switcheroo: switched nouveau off\n");
603 drm_kms_helper_poll_disable(dev
);
604 nouveau_pci_suspend(pdev
, pmm
);
608 static bool nouveau_switcheroo_can_switch(struct pci_dev
*pdev
)
610 struct drm_device
*dev
= pci_get_drvdata(pdev
);
613 spin_lock(&dev
->count_lock
);
614 can_switch
= (dev
->open_count
== 0);
615 spin_unlock(&dev
->count_lock
);
620 nouveau_card_init(struct drm_device
*dev
)
622 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
623 struct nouveau_engine
*engine
;
626 vga_client_register(dev
->pdev
, dev
, NULL
, nouveau_vga_set_decode
);
627 vga_switcheroo_register_client(dev
->pdev
, nouveau_switcheroo_set_state
,
628 nouveau_switcheroo_can_switch
);
630 /* Initialise internal driver API hooks */
631 ret
= nouveau_init_engine_ptrs(dev
);
634 engine
= &dev_priv
->engine
;
635 spin_lock_init(&dev_priv
->channels
.lock
);
636 spin_lock_init(&dev_priv
->tile
.lock
);
637 spin_lock_init(&dev_priv
->context_switch_lock
);
639 /* Make the CRTCs and I2C buses accessible */
640 ret
= engine
->display
.early_init(dev
);
644 /* Parse BIOS tables / Run init tables if card not POSTed */
645 ret
= nouveau_bios_init(dev
);
647 goto out_display_early
;
649 nouveau_pm_init(dev
);
651 ret
= nouveau_mem_vram_init(dev
);
655 ret
= nouveau_gpuobj_init(dev
);
659 ret
= engine
->instmem
.init(dev
);
663 ret
= nouveau_mem_gart_init(dev
);
668 ret
= engine
->mc
.init(dev
);
673 ret
= engine
->gpio
.init(dev
);
678 ret
= engine
->timer
.init(dev
);
683 ret
= engine
->fb
.init(dev
);
688 engine
->graph
.accel_blocked
= true;
691 ret
= engine
->graph
.init(dev
);
696 ret
= engine
->crypt
.init(dev
);
701 ret
= engine
->fifo
.init(dev
);
706 ret
= engine
->display
.create(dev
);
710 ret
= drm_vblank_init(dev
, nv_two_heads(dev
) ? 2 : 1);
714 ret
= nouveau_irq_init(dev
);
718 /* what about PVIDEO/PCRTC/PRAMDAC etc? */
720 if (!engine
->graph
.accel_blocked
) {
721 ret
= nouveau_fence_init(dev
);
725 ret
= nouveau_card_init_channel(dev
);
730 ret
= nouveau_backlight_init(dev
);
732 NV_ERROR(dev
, "Error %d registering backlight\n", ret
);
734 nouveau_fbcon_init(dev
);
735 drm_kms_helper_poll_init(dev
);
739 nouveau_fence_fini(dev
);
741 nouveau_irq_fini(dev
);
743 drm_vblank_cleanup(dev
);
744 engine
->display
.destroy(dev
);
746 if (!nouveau_noaccel
)
747 engine
->fifo
.takedown(dev
);
749 if (!nouveau_noaccel
)
750 engine
->crypt
.takedown(dev
);
752 if (!nouveau_noaccel
)
753 engine
->graph
.takedown(dev
);
755 engine
->fb
.takedown(dev
);
757 engine
->timer
.takedown(dev
);
759 engine
->gpio
.takedown(dev
);
761 engine
->mc
.takedown(dev
);
763 nouveau_mem_gart_fini(dev
);
765 engine
->instmem
.takedown(dev
);
767 nouveau_gpuobj_takedown(dev
);
769 nouveau_mem_vram_fini(dev
);
771 nouveau_pm_fini(dev
);
772 nouveau_bios_takedown(dev
);
774 engine
->display
.late_takedown(dev
);
776 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
780 static void nouveau_card_takedown(struct drm_device
*dev
)
782 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
783 struct nouveau_engine
*engine
= &dev_priv
->engine
;
785 nouveau_backlight_exit(dev
);
787 if (!engine
->graph
.accel_blocked
) {
788 nouveau_fence_fini(dev
);
789 nouveau_channel_put_unlocked(&dev_priv
->channel
);
792 if (!nouveau_noaccel
) {
793 engine
->fifo
.takedown(dev
);
794 engine
->crypt
.takedown(dev
);
795 engine
->graph
.takedown(dev
);
797 engine
->fb
.takedown(dev
);
798 engine
->timer
.takedown(dev
);
799 engine
->gpio
.takedown(dev
);
800 engine
->mc
.takedown(dev
);
801 engine
->display
.late_takedown(dev
);
803 mutex_lock(&dev
->struct_mutex
);
804 ttm_bo_clean_mm(&dev_priv
->ttm
.bdev
, TTM_PL_VRAM
);
805 ttm_bo_clean_mm(&dev_priv
->ttm
.bdev
, TTM_PL_TT
);
806 mutex_unlock(&dev
->struct_mutex
);
807 nouveau_mem_gart_fini(dev
);
809 engine
->instmem
.takedown(dev
);
810 nouveau_gpuobj_takedown(dev
);
811 nouveau_mem_vram_fini(dev
);
813 nouveau_irq_fini(dev
);
814 drm_vblank_cleanup(dev
);
816 nouveau_pm_fini(dev
);
817 nouveau_bios_takedown(dev
);
819 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
822 /* here a client dies, release the stuff that was allocated for its
824 void nouveau_preclose(struct drm_device
*dev
, struct drm_file
*file_priv
)
826 nouveau_channel_cleanup(dev
, file_priv
);
829 /* first module load, setup the mmio/fb mapping */
830 /* KMS: we need mmio at load time, not when the first drm client opens. */
831 int nouveau_firstopen(struct drm_device
*dev
)
836 /* if we have an OF card, copy vbios to RAMIN */
837 static void nouveau_OF_copy_vbios_to_ramin(struct drm_device
*dev
)
839 #if defined(__powerpc__)
841 const uint32_t *bios
;
842 struct device_node
*dn
= pci_device_to_OF_node(dev
->pdev
);
844 NV_INFO(dev
, "Unable to get the OF node\n");
848 bios
= of_get_property(dn
, "NVDA,BMP", &size
);
850 for (i
= 0; i
< size
; i
+= 4)
851 nv_wi32(dev
, i
, bios
[i
/4]);
852 NV_INFO(dev
, "OF bios successfully copied (%d bytes)\n", size
);
854 NV_INFO(dev
, "Unable to get the OF bios\n");
859 static struct apertures_struct
*nouveau_get_apertures(struct drm_device
*dev
)
861 struct pci_dev
*pdev
= dev
->pdev
;
862 struct apertures_struct
*aper
= alloc_apertures(3);
866 aper
->ranges
[0].base
= pci_resource_start(pdev
, 1);
867 aper
->ranges
[0].size
= pci_resource_len(pdev
, 1);
870 if (pci_resource_len(pdev
, 2)) {
871 aper
->ranges
[aper
->count
].base
= pci_resource_start(pdev
, 2);
872 aper
->ranges
[aper
->count
].size
= pci_resource_len(pdev
, 2);
876 if (pci_resource_len(pdev
, 3)) {
877 aper
->ranges
[aper
->count
].base
= pci_resource_start(pdev
, 3);
878 aper
->ranges
[aper
->count
].size
= pci_resource_len(pdev
, 3);
885 static int nouveau_remove_conflicting_drivers(struct drm_device
*dev
)
887 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
888 bool primary
= false;
889 dev_priv
->apertures
= nouveau_get_apertures(dev
);
890 if (!dev_priv
->apertures
)
894 primary
= dev
->pdev
->resource
[PCI_ROM_RESOURCE
].flags
& IORESOURCE_ROM_SHADOW
;
897 remove_conflicting_framebuffers(dev_priv
->apertures
, "nouveaufb", primary
);
901 int nouveau_load(struct drm_device
*dev
, unsigned long flags
)
903 struct drm_nouveau_private
*dev_priv
;
905 resource_size_t mmio_start_offs
;
908 dev_priv
= kzalloc(sizeof(*dev_priv
), GFP_KERNEL
);
913 dev
->dev_private
= dev_priv
;
916 dev_priv
->flags
= flags
& NOUVEAU_FLAGS
;
918 NV_DEBUG(dev
, "vendor: 0x%X device: 0x%X class: 0x%X\n",
919 dev
->pci_vendor
, dev
->pci_device
, dev
->pdev
->class);
921 dev_priv
->wq
= create_workqueue("nouveau");
927 /* resource 0 is mmio regs */
928 /* resource 1 is linear FB */
929 /* resource 2 is RAMIN (mmio regs + 0x1000000) */
930 /* resource 6 is bios */
932 /* map the mmio regs */
933 mmio_start_offs
= pci_resource_start(dev
->pdev
, 0);
934 dev_priv
->mmio
= ioremap(mmio_start_offs
, 0x00800000);
935 if (!dev_priv
->mmio
) {
936 NV_ERROR(dev
, "Unable to initialize the mmio mapping. "
937 "Please report your setup to " DRIVER_EMAIL
"\n");
941 NV_DEBUG(dev
, "regs mapped ok at 0x%llx\n",
942 (unsigned long long)mmio_start_offs
);
945 /* Put the card in BE mode if it's not */
946 if (nv_rd32(dev
, NV03_PMC_BOOT_1
))
947 nv_wr32(dev
, NV03_PMC_BOOT_1
, 0x00000001);
952 /* Time to determine the card architecture */
953 reg0
= nv_rd32(dev
, NV03_PMC_BOOT_0
);
955 /* We're dealing with >=NV10 */
956 if ((reg0
& 0x0f000000) > 0) {
957 /* Bit 27-20 contain the architecture in hex */
958 dev_priv
->chipset
= (reg0
& 0xff00000) >> 20;
960 } else if ((reg0
& 0xff00fff0) == 0x20004000) {
961 if (reg0
& 0x00f00000)
962 dev_priv
->chipset
= 0x05;
964 dev_priv
->chipset
= 0x04;
966 dev_priv
->chipset
= 0xff;
968 switch (dev_priv
->chipset
& 0xf0) {
973 dev_priv
->card_type
= dev_priv
->chipset
& 0xf0;
977 dev_priv
->card_type
= NV_40
;
983 dev_priv
->card_type
= NV_50
;
986 dev_priv
->card_type
= NV_C0
;
989 NV_INFO(dev
, "Unsupported chipset 0x%08x\n", reg0
);
994 NV_INFO(dev
, "Detected an NV%2x generation card (0x%08x)\n",
995 dev_priv
->card_type
, reg0
);
997 ret
= nouveau_remove_conflicting_drivers(dev
);
1001 /* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
1002 if (dev_priv
->card_type
>= NV_40
) {
1004 if (pci_resource_len(dev
->pdev
, ramin_bar
) == 0)
1007 dev_priv
->ramin_size
= pci_resource_len(dev
->pdev
, ramin_bar
);
1009 ioremap(pci_resource_start(dev
->pdev
, ramin_bar
),
1010 dev_priv
->ramin_size
);
1011 if (!dev_priv
->ramin
) {
1012 NV_ERROR(dev
, "Failed to PRAMIN BAR");
1017 dev_priv
->ramin_size
= 1 * 1024 * 1024;
1018 dev_priv
->ramin
= ioremap(mmio_start_offs
+ NV_RAMIN
,
1019 dev_priv
->ramin_size
);
1020 if (!dev_priv
->ramin
) {
1021 NV_ERROR(dev
, "Failed to map BAR0 PRAMIN.\n");
1027 nouveau_OF_copy_vbios_to_ramin(dev
);
1030 if (dev
->pci_device
== 0x01a0)
1031 dev_priv
->flags
|= NV_NFORCE
;
1032 else if (dev
->pci_device
== 0x01f0)
1033 dev_priv
->flags
|= NV_NFORCE2
;
1035 /* For kernel modesetting, init card now and bring up fbcon */
1036 ret
= nouveau_card_init(dev
);
1043 iounmap(dev_priv
->ramin
);
1045 iounmap(dev_priv
->mmio
);
1047 destroy_workqueue(dev_priv
->wq
);
1050 dev
->dev_private
= NULL
;
1055 void nouveau_lastclose(struct drm_device
*dev
)
1059 int nouveau_unload(struct drm_device
*dev
)
1061 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1062 struct nouveau_engine
*engine
= &dev_priv
->engine
;
1064 drm_kms_helper_poll_fini(dev
);
1065 nouveau_fbcon_fini(dev
);
1066 engine
->display
.destroy(dev
);
1067 nouveau_card_takedown(dev
);
1069 iounmap(dev_priv
->mmio
);
1070 iounmap(dev_priv
->ramin
);
1073 dev
->dev_private
= NULL
;
1077 int nouveau_ioctl_getparam(struct drm_device
*dev
, void *data
,
1078 struct drm_file
*file_priv
)
1080 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1081 struct drm_nouveau_getparam
*getparam
= data
;
1083 switch (getparam
->param
) {
1084 case NOUVEAU_GETPARAM_CHIPSET_ID
:
1085 getparam
->value
= dev_priv
->chipset
;
1087 case NOUVEAU_GETPARAM_PCI_VENDOR
:
1088 getparam
->value
= dev
->pci_vendor
;
1090 case NOUVEAU_GETPARAM_PCI_DEVICE
:
1091 getparam
->value
= dev
->pci_device
;
1093 case NOUVEAU_GETPARAM_BUS_TYPE
:
1094 if (drm_device_is_agp(dev
))
1095 getparam
->value
= NV_AGP
;
1096 else if (drm_device_is_pcie(dev
))
1097 getparam
->value
= NV_PCIE
;
1099 getparam
->value
= NV_PCI
;
1101 case NOUVEAU_GETPARAM_FB_SIZE
:
1102 getparam
->value
= dev_priv
->fb_available_size
;
1104 case NOUVEAU_GETPARAM_AGP_SIZE
:
1105 getparam
->value
= dev_priv
->gart_info
.aper_size
;
1107 case NOUVEAU_GETPARAM_VM_VRAM_BASE
:
1108 getparam
->value
= 0; /* deprecated */
1110 case NOUVEAU_GETPARAM_PTIMER_TIME
:
1111 getparam
->value
= dev_priv
->engine
.timer
.read(dev
);
1113 case NOUVEAU_GETPARAM_HAS_BO_USAGE
:
1114 getparam
->value
= 1;
1116 case NOUVEAU_GETPARAM_HAS_PAGEFLIP
:
1117 getparam
->value
= (dev_priv
->card_type
< NV_50
);
1119 case NOUVEAU_GETPARAM_GRAPH_UNITS
:
1120 /* NV40 and NV50 versions are quite different, but register
1121 * address is the same. User is supposed to know the card
1122 * family anyway... */
1123 if (dev_priv
->chipset
>= 0x40) {
1124 getparam
->value
= nv_rd32(dev
, NV40_PMC_GRAPH_UNITS
);
1129 NV_DEBUG(dev
, "unknown parameter %lld\n", getparam
->param
);
1137 nouveau_ioctl_setparam(struct drm_device
*dev
, void *data
,
1138 struct drm_file
*file_priv
)
1140 struct drm_nouveau_setparam
*setparam
= data
;
1142 switch (setparam
->param
) {
1144 NV_DEBUG(dev
, "unknown parameter %lld\n", setparam
->param
);
1151 /* Wait until (value(reg) & mask) == val, up until timeout has hit */
1153 nouveau_wait_eq(struct drm_device
*dev
, uint64_t timeout
,
1154 uint32_t reg
, uint32_t mask
, uint32_t val
)
1156 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1157 struct nouveau_timer_engine
*ptimer
= &dev_priv
->engine
.timer
;
1158 uint64_t start
= ptimer
->read(dev
);
1161 if ((nv_rd32(dev
, reg
) & mask
) == val
)
1163 } while (ptimer
->read(dev
) - start
< timeout
);
1168 /* Wait until (value(reg) & mask) != val, up until timeout has hit */
1170 nouveau_wait_ne(struct drm_device
*dev
, uint64_t timeout
,
1171 uint32_t reg
, uint32_t mask
, uint32_t val
)
1173 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1174 struct nouveau_timer_engine
*ptimer
= &dev_priv
->engine
.timer
;
1175 uint64_t start
= ptimer
->read(dev
);
1178 if ((nv_rd32(dev
, reg
) & mask
) != val
)
1180 } while (ptimer
->read(dev
) - start
< timeout
);
1185 /* Waits for PGRAPH to go completely idle */
1186 bool nouveau_wait_for_idle(struct drm_device
*dev
)
1188 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
1191 if (dev_priv
->card_type
== NV_40
)
1192 mask
&= ~NV40_PGRAPH_STATUS_SYNC_STALL
;
1194 if (!nv_wait(dev
, NV04_PGRAPH_STATUS
, mask
, 0)) {
1195 NV_ERROR(dev
, "PGRAPH idle timed out with status 0x%08x\n",
1196 nv_rd32(dev
, NV04_PGRAPH_STATUS
));