nouveau_state.c revision 16cd399c65bc68332a860b0b572079d0316df3ca
1/*
2 * Copyright 2005 Stephane Marchesin
3 * Copyright 2008 Stuart Bennett
4 * All Rights Reserved.
5 *
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:
12 *
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
15 * Software.
16 *
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.
24 */
25
26#include <linux/swab.h>
27#include <linux/slab.h>
28#include "drmP.h"
29#include "drm.h"
30#include "drm_sarea.h"
31#include "drm_crtc_helper.h"
32#include <linux/vgaarb.h>
33#include <linux/vga_switcheroo.h>
34
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"
41
42static void nouveau_stub_takedown(struct drm_device *dev) {}
43static int nouveau_stub_init(struct drm_device *dev) { return 0; }
44
45static int nouveau_init_engine_ptrs(struct drm_device *dev)
46{
47	struct drm_nouveau_private *dev_priv = dev->dev_private;
48	struct nouveau_engine *engine = &dev_priv->engine;
49
50	switch (dev_priv->chipset & 0xf0) {
51	case 0x00:
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->fifo.channels		= 16;
69		engine->fifo.init		= nv04_fifo_init;
70		engine->fifo.takedown		= nv04_fifo_fini;
71		engine->fifo.disable		= nv04_fifo_disable;
72		engine->fifo.enable		= nv04_fifo_enable;
73		engine->fifo.reassign		= nv04_fifo_reassign;
74		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
75		engine->fifo.channel_id		= nv04_fifo_channel_id;
76		engine->fifo.create_context	= nv04_fifo_create_context;
77		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
78		engine->fifo.load_context	= nv04_fifo_load_context;
79		engine->fifo.unload_context	= nv04_fifo_unload_context;
80		engine->display.early_init	= nv04_display_early_init;
81		engine->display.late_takedown	= nv04_display_late_takedown;
82		engine->display.create		= nv04_display_create;
83		engine->display.init		= nv04_display_init;
84		engine->display.destroy		= nv04_display_destroy;
85		engine->gpio.init		= nouveau_stub_init;
86		engine->gpio.takedown		= nouveau_stub_takedown;
87		engine->gpio.get		= NULL;
88		engine->gpio.set		= NULL;
89		engine->gpio.irq_enable		= NULL;
90		engine->pm.clock_get		= nv04_pm_clock_get;
91		engine->pm.clock_pre		= nv04_pm_clock_pre;
92		engine->pm.clock_set		= nv04_pm_clock_set;
93		engine->vram.init		= nouveau_mem_detect;
94		engine->vram.takedown		= nouveau_stub_takedown;
95		engine->vram.flags_valid	= nouveau_mem_flags_valid;
96		break;
97	case 0x10:
98		engine->instmem.init		= nv04_instmem_init;
99		engine->instmem.takedown	= nv04_instmem_takedown;
100		engine->instmem.suspend		= nv04_instmem_suspend;
101		engine->instmem.resume		= nv04_instmem_resume;
102		engine->instmem.get		= nv04_instmem_get;
103		engine->instmem.put		= nv04_instmem_put;
104		engine->instmem.map		= nv04_instmem_map;
105		engine->instmem.unmap		= nv04_instmem_unmap;
106		engine->instmem.flush		= nv04_instmem_flush;
107		engine->mc.init			= nv04_mc_init;
108		engine->mc.takedown		= nv04_mc_takedown;
109		engine->timer.init		= nv04_timer_init;
110		engine->timer.read		= nv04_timer_read;
111		engine->timer.takedown		= nv04_timer_takedown;
112		engine->fb.init			= nv10_fb_init;
113		engine->fb.takedown		= nv10_fb_takedown;
114		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
115		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
116		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
117		engine->fifo.channels		= 32;
118		engine->fifo.init		= nv10_fifo_init;
119		engine->fifo.takedown		= nv04_fifo_fini;
120		engine->fifo.disable		= nv04_fifo_disable;
121		engine->fifo.enable		= nv04_fifo_enable;
122		engine->fifo.reassign		= nv04_fifo_reassign;
123		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
124		engine->fifo.channel_id		= nv10_fifo_channel_id;
125		engine->fifo.create_context	= nv10_fifo_create_context;
126		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
127		engine->fifo.load_context	= nv10_fifo_load_context;
128		engine->fifo.unload_context	= nv10_fifo_unload_context;
129		engine->display.early_init	= nv04_display_early_init;
130		engine->display.late_takedown	= nv04_display_late_takedown;
131		engine->display.create		= nv04_display_create;
132		engine->display.init		= nv04_display_init;
133		engine->display.destroy		= nv04_display_destroy;
134		engine->gpio.init		= nouveau_stub_init;
135		engine->gpio.takedown		= nouveau_stub_takedown;
136		engine->gpio.get		= nv10_gpio_get;
137		engine->gpio.set		= nv10_gpio_set;
138		engine->gpio.irq_enable		= NULL;
139		engine->pm.clock_get		= nv04_pm_clock_get;
140		engine->pm.clock_pre		= nv04_pm_clock_pre;
141		engine->pm.clock_set		= nv04_pm_clock_set;
142		engine->vram.init		= nouveau_mem_detect;
143		engine->vram.takedown		= nouveau_stub_takedown;
144		engine->vram.flags_valid	= nouveau_mem_flags_valid;
145		break;
146	case 0x20:
147		engine->instmem.init		= nv04_instmem_init;
148		engine->instmem.takedown	= nv04_instmem_takedown;
149		engine->instmem.suspend		= nv04_instmem_suspend;
150		engine->instmem.resume		= nv04_instmem_resume;
151		engine->instmem.get		= nv04_instmem_get;
152		engine->instmem.put		= nv04_instmem_put;
153		engine->instmem.map		= nv04_instmem_map;
154		engine->instmem.unmap		= nv04_instmem_unmap;
155		engine->instmem.flush		= nv04_instmem_flush;
156		engine->mc.init			= nv04_mc_init;
157		engine->mc.takedown		= nv04_mc_takedown;
158		engine->timer.init		= nv04_timer_init;
159		engine->timer.read		= nv04_timer_read;
160		engine->timer.takedown		= nv04_timer_takedown;
161		engine->fb.init			= nv10_fb_init;
162		engine->fb.takedown		= nv10_fb_takedown;
163		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
164		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
165		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
166		engine->fifo.channels		= 32;
167		engine->fifo.init		= nv10_fifo_init;
168		engine->fifo.takedown		= nv04_fifo_fini;
169		engine->fifo.disable		= nv04_fifo_disable;
170		engine->fifo.enable		= nv04_fifo_enable;
171		engine->fifo.reassign		= nv04_fifo_reassign;
172		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
173		engine->fifo.channel_id		= nv10_fifo_channel_id;
174		engine->fifo.create_context	= nv10_fifo_create_context;
175		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
176		engine->fifo.load_context	= nv10_fifo_load_context;
177		engine->fifo.unload_context	= nv10_fifo_unload_context;
178		engine->display.early_init	= nv04_display_early_init;
179		engine->display.late_takedown	= nv04_display_late_takedown;
180		engine->display.create		= nv04_display_create;
181		engine->display.init		= nv04_display_init;
182		engine->display.destroy		= nv04_display_destroy;
183		engine->gpio.init		= nouveau_stub_init;
184		engine->gpio.takedown		= nouveau_stub_takedown;
185		engine->gpio.get		= nv10_gpio_get;
186		engine->gpio.set		= nv10_gpio_set;
187		engine->gpio.irq_enable		= NULL;
188		engine->pm.clock_get		= nv04_pm_clock_get;
189		engine->pm.clock_pre		= nv04_pm_clock_pre;
190		engine->pm.clock_set		= nv04_pm_clock_set;
191		engine->vram.init		= nouveau_mem_detect;
192		engine->vram.takedown		= nouveau_stub_takedown;
193		engine->vram.flags_valid	= nouveau_mem_flags_valid;
194		break;
195	case 0x30:
196		engine->instmem.init		= nv04_instmem_init;
197		engine->instmem.takedown	= nv04_instmem_takedown;
198		engine->instmem.suspend		= nv04_instmem_suspend;
199		engine->instmem.resume		= nv04_instmem_resume;
200		engine->instmem.get		= nv04_instmem_get;
201		engine->instmem.put		= nv04_instmem_put;
202		engine->instmem.map		= nv04_instmem_map;
203		engine->instmem.unmap		= nv04_instmem_unmap;
204		engine->instmem.flush		= nv04_instmem_flush;
205		engine->mc.init			= nv04_mc_init;
206		engine->mc.takedown		= nv04_mc_takedown;
207		engine->timer.init		= nv04_timer_init;
208		engine->timer.read		= nv04_timer_read;
209		engine->timer.takedown		= nv04_timer_takedown;
210		engine->fb.init			= nv30_fb_init;
211		engine->fb.takedown		= nv30_fb_takedown;
212		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
213		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
214		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
215		engine->fifo.channels		= 32;
216		engine->fifo.init		= nv10_fifo_init;
217		engine->fifo.takedown		= nv04_fifo_fini;
218		engine->fifo.disable		= nv04_fifo_disable;
219		engine->fifo.enable		= nv04_fifo_enable;
220		engine->fifo.reassign		= nv04_fifo_reassign;
221		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
222		engine->fifo.channel_id		= nv10_fifo_channel_id;
223		engine->fifo.create_context	= nv10_fifo_create_context;
224		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
225		engine->fifo.load_context	= nv10_fifo_load_context;
226		engine->fifo.unload_context	= nv10_fifo_unload_context;
227		engine->display.early_init	= nv04_display_early_init;
228		engine->display.late_takedown	= nv04_display_late_takedown;
229		engine->display.create		= nv04_display_create;
230		engine->display.init		= nv04_display_init;
231		engine->display.destroy		= nv04_display_destroy;
232		engine->gpio.init		= nouveau_stub_init;
233		engine->gpio.takedown		= nouveau_stub_takedown;
234		engine->gpio.get		= nv10_gpio_get;
235		engine->gpio.set		= nv10_gpio_set;
236		engine->gpio.irq_enable		= NULL;
237		engine->pm.clock_get		= nv04_pm_clock_get;
238		engine->pm.clock_pre		= nv04_pm_clock_pre;
239		engine->pm.clock_set		= nv04_pm_clock_set;
240		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
241		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
242		engine->vram.init		= nouveau_mem_detect;
243		engine->vram.takedown		= nouveau_stub_takedown;
244		engine->vram.flags_valid	= nouveau_mem_flags_valid;
245		break;
246	case 0x40:
247	case 0x60:
248		engine->instmem.init		= nv04_instmem_init;
249		engine->instmem.takedown	= nv04_instmem_takedown;
250		engine->instmem.suspend		= nv04_instmem_suspend;
251		engine->instmem.resume		= nv04_instmem_resume;
252		engine->instmem.get		= nv04_instmem_get;
253		engine->instmem.put		= nv04_instmem_put;
254		engine->instmem.map		= nv04_instmem_map;
255		engine->instmem.unmap		= nv04_instmem_unmap;
256		engine->instmem.flush		= nv04_instmem_flush;
257		engine->mc.init			= nv40_mc_init;
258		engine->mc.takedown		= nv40_mc_takedown;
259		engine->timer.init		= nv04_timer_init;
260		engine->timer.read		= nv04_timer_read;
261		engine->timer.takedown		= nv04_timer_takedown;
262		engine->fb.init			= nv40_fb_init;
263		engine->fb.takedown		= nv40_fb_takedown;
264		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
265		engine->fb.set_tile_region	= nv40_fb_set_tile_region;
266		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
267		engine->fifo.channels		= 32;
268		engine->fifo.init		= nv40_fifo_init;
269		engine->fifo.takedown		= nv04_fifo_fini;
270		engine->fifo.disable		= nv04_fifo_disable;
271		engine->fifo.enable		= nv04_fifo_enable;
272		engine->fifo.reassign		= nv04_fifo_reassign;
273		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
274		engine->fifo.channel_id		= nv10_fifo_channel_id;
275		engine->fifo.create_context	= nv40_fifo_create_context;
276		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
277		engine->fifo.load_context	= nv40_fifo_load_context;
278		engine->fifo.unload_context	= nv40_fifo_unload_context;
279		engine->display.early_init	= nv04_display_early_init;
280		engine->display.late_takedown	= nv04_display_late_takedown;
281		engine->display.create		= nv04_display_create;
282		engine->display.init		= nv04_display_init;
283		engine->display.destroy		= nv04_display_destroy;
284		engine->gpio.init		= nouveau_stub_init;
285		engine->gpio.takedown		= nouveau_stub_takedown;
286		engine->gpio.get		= nv10_gpio_get;
287		engine->gpio.set		= nv10_gpio_set;
288		engine->gpio.irq_enable		= NULL;
289		engine->pm.clock_get		= nv04_pm_clock_get;
290		engine->pm.clock_pre		= nv04_pm_clock_pre;
291		engine->pm.clock_set		= nv04_pm_clock_set;
292		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
293		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
294		engine->pm.temp_get		= nv40_temp_get;
295		engine->vram.init		= nouveau_mem_detect;
296		engine->vram.takedown		= nouveau_stub_takedown;
297		engine->vram.flags_valid	= nouveau_mem_flags_valid;
298		break;
299	case 0x50:
300	case 0x80: /* gotta love NVIDIA's consistency.. */
301	case 0x90:
302	case 0xA0:
303		engine->instmem.init		= nv50_instmem_init;
304		engine->instmem.takedown	= nv50_instmem_takedown;
305		engine->instmem.suspend		= nv50_instmem_suspend;
306		engine->instmem.resume		= nv50_instmem_resume;
307		engine->instmem.get		= nv50_instmem_get;
308		engine->instmem.put		= nv50_instmem_put;
309		engine->instmem.map		= nv50_instmem_map;
310		engine->instmem.unmap		= nv50_instmem_unmap;
311		if (dev_priv->chipset == 0x50)
312			engine->instmem.flush	= nv50_instmem_flush;
313		else
314			engine->instmem.flush	= nv84_instmem_flush;
315		engine->mc.init			= nv50_mc_init;
316		engine->mc.takedown		= nv50_mc_takedown;
317		engine->timer.init		= nv04_timer_init;
318		engine->timer.read		= nv04_timer_read;
319		engine->timer.takedown		= nv04_timer_takedown;
320		engine->fb.init			= nv50_fb_init;
321		engine->fb.takedown		= nv50_fb_takedown;
322		engine->fifo.channels		= 128;
323		engine->fifo.init		= nv50_fifo_init;
324		engine->fifo.takedown		= nv50_fifo_takedown;
325		engine->fifo.disable		= nv04_fifo_disable;
326		engine->fifo.enable		= nv04_fifo_enable;
327		engine->fifo.reassign		= nv04_fifo_reassign;
328		engine->fifo.channel_id		= nv50_fifo_channel_id;
329		engine->fifo.create_context	= nv50_fifo_create_context;
330		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
331		engine->fifo.load_context	= nv50_fifo_load_context;
332		engine->fifo.unload_context	= nv50_fifo_unload_context;
333		engine->fifo.tlb_flush		= nv50_fifo_tlb_flush;
334		engine->display.early_init	= nv50_display_early_init;
335		engine->display.late_takedown	= nv50_display_late_takedown;
336		engine->display.create		= nv50_display_create;
337		engine->display.init		= nv50_display_init;
338		engine->display.destroy		= nv50_display_destroy;
339		engine->gpio.init		= nv50_gpio_init;
340		engine->gpio.takedown		= nv50_gpio_fini;
341		engine->gpio.get		= nv50_gpio_get;
342		engine->gpio.set		= nv50_gpio_set;
343		engine->gpio.irq_register	= nv50_gpio_irq_register;
344		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
345		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
346		switch (dev_priv->chipset) {
347		case 0x84:
348		case 0x86:
349		case 0x92:
350		case 0x94:
351		case 0x96:
352		case 0x98:
353		case 0xa0:
354		case 0xaa:
355		case 0xac:
356		case 0x50:
357			engine->pm.clock_get	= nv50_pm_clock_get;
358			engine->pm.clock_pre	= nv50_pm_clock_pre;
359			engine->pm.clock_set	= nv50_pm_clock_set;
360			break;
361		default:
362			engine->pm.clocks_get	= nva3_pm_clocks_get;
363			engine->pm.clocks_pre	= nva3_pm_clocks_pre;
364			engine->pm.clocks_set	= nva3_pm_clocks_set;
365			break;
366		}
367		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
368		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
369		if (dev_priv->chipset >= 0x84)
370			engine->pm.temp_get	= nv84_temp_get;
371		else
372			engine->pm.temp_get	= nv40_temp_get;
373		engine->vram.init		= nv50_vram_init;
374		engine->vram.takedown		= nv50_vram_fini;
375		engine->vram.get		= nv50_vram_new;
376		engine->vram.put		= nv50_vram_del;
377		engine->vram.flags_valid	= nv50_vram_flags_valid;
378		break;
379	case 0xC0:
380		engine->instmem.init		= nvc0_instmem_init;
381		engine->instmem.takedown	= nvc0_instmem_takedown;
382		engine->instmem.suspend		= nvc0_instmem_suspend;
383		engine->instmem.resume		= nvc0_instmem_resume;
384		engine->instmem.get		= nv50_instmem_get;
385		engine->instmem.put		= nv50_instmem_put;
386		engine->instmem.map		= nv50_instmem_map;
387		engine->instmem.unmap		= nv50_instmem_unmap;
388		engine->instmem.flush		= nv84_instmem_flush;
389		engine->mc.init			= nv50_mc_init;
390		engine->mc.takedown		= nv50_mc_takedown;
391		engine->timer.init		= nv04_timer_init;
392		engine->timer.read		= nv04_timer_read;
393		engine->timer.takedown		= nv04_timer_takedown;
394		engine->fb.init			= nvc0_fb_init;
395		engine->fb.takedown		= nvc0_fb_takedown;
396		engine->fifo.channels		= 128;
397		engine->fifo.init		= nvc0_fifo_init;
398		engine->fifo.takedown		= nvc0_fifo_takedown;
399		engine->fifo.disable		= nvc0_fifo_disable;
400		engine->fifo.enable		= nvc0_fifo_enable;
401		engine->fifo.reassign		= nvc0_fifo_reassign;
402		engine->fifo.channel_id		= nvc0_fifo_channel_id;
403		engine->fifo.create_context	= nvc0_fifo_create_context;
404		engine->fifo.destroy_context	= nvc0_fifo_destroy_context;
405		engine->fifo.load_context	= nvc0_fifo_load_context;
406		engine->fifo.unload_context	= nvc0_fifo_unload_context;
407		engine->display.early_init	= nv50_display_early_init;
408		engine->display.late_takedown	= nv50_display_late_takedown;
409		engine->display.create		= nv50_display_create;
410		engine->display.init		= nv50_display_init;
411		engine->display.destroy		= nv50_display_destroy;
412		engine->gpio.init		= nv50_gpio_init;
413		engine->gpio.takedown		= nouveau_stub_takedown;
414		engine->gpio.get		= nv50_gpio_get;
415		engine->gpio.set		= nv50_gpio_set;
416		engine->gpio.irq_register	= nv50_gpio_irq_register;
417		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
418		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
419		engine->vram.init		= nvc0_vram_init;
420		engine->vram.takedown		= nv50_vram_fini;
421		engine->vram.get		= nvc0_vram_new;
422		engine->vram.put		= nv50_vram_del;
423		engine->vram.flags_valid	= nvc0_vram_flags_valid;
424		engine->pm.temp_get		= nv84_temp_get;
425		engine->pm.clocks_get		= nvc0_pm_clocks_get;
426		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
427		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
428		break;
429	default:
430		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
431		return 1;
432	}
433
434	return 0;
435}
436
437static unsigned int
438nouveau_vga_set_decode(void *priv, bool state)
439{
440	struct drm_device *dev = priv;
441	struct drm_nouveau_private *dev_priv = dev->dev_private;
442
443	if (dev_priv->chipset >= 0x40)
444		nv_wr32(dev, 0x88054, state);
445	else
446		nv_wr32(dev, 0x1854, state);
447
448	if (state)
449		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
450		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
451	else
452		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
453}
454
455static int
456nouveau_card_init_channel(struct drm_device *dev)
457{
458	struct drm_nouveau_private *dev_priv = dev->dev_private;
459	int ret;
460
461	ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
462				    NvDmaFB, NvDmaTT);
463	if (ret)
464		return ret;
465
466	mutex_unlock(&dev_priv->channel->mutex);
467	return 0;
468}
469
470static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
471					 enum vga_switcheroo_state state)
472{
473	struct drm_device *dev = pci_get_drvdata(pdev);
474	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
475	if (state == VGA_SWITCHEROO_ON) {
476		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
477		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
478		nouveau_pci_resume(pdev);
479		drm_kms_helper_poll_enable(dev);
480		dev->switch_power_state = DRM_SWITCH_POWER_ON;
481	} else {
482		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
483		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
484		drm_kms_helper_poll_disable(dev);
485		nouveau_pci_suspend(pdev, pmm);
486		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
487	}
488}
489
490static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
491{
492	struct drm_device *dev = pci_get_drvdata(pdev);
493	nouveau_fbcon_output_poll_changed(dev);
494}
495
496static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
497{
498	struct drm_device *dev = pci_get_drvdata(pdev);
499	bool can_switch;
500
501	spin_lock(&dev->count_lock);
502	can_switch = (dev->open_count == 0);
503	spin_unlock(&dev->count_lock);
504	return can_switch;
505}
506
507int
508nouveau_card_init(struct drm_device *dev)
509{
510	struct drm_nouveau_private *dev_priv = dev->dev_private;
511	struct nouveau_engine *engine;
512	int ret, e = 0;
513
514	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
515	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
516				       nouveau_switcheroo_reprobe,
517				       nouveau_switcheroo_can_switch);
518
519	/* Initialise internal driver API hooks */
520	ret = nouveau_init_engine_ptrs(dev);
521	if (ret)
522		goto out;
523	engine = &dev_priv->engine;
524	spin_lock_init(&dev_priv->channels.lock);
525	spin_lock_init(&dev_priv->tile.lock);
526	spin_lock_init(&dev_priv->context_switch_lock);
527	spin_lock_init(&dev_priv->vm_lock);
528
529	/* Make the CRTCs and I2C buses accessible */
530	ret = engine->display.early_init(dev);
531	if (ret)
532		goto out;
533
534	/* Parse BIOS tables / Run init tables if card not POSTed */
535	ret = nouveau_bios_init(dev);
536	if (ret)
537		goto out_display_early;
538
539	nouveau_pm_init(dev);
540
541	ret = engine->vram.init(dev);
542	if (ret)
543		goto out_bios;
544
545	ret = nouveau_gpuobj_init(dev);
546	if (ret)
547		goto out_vram;
548
549	ret = engine->instmem.init(dev);
550	if (ret)
551		goto out_gpuobj;
552
553	ret = nouveau_mem_vram_init(dev);
554	if (ret)
555		goto out_instmem;
556
557	ret = nouveau_mem_gart_init(dev);
558	if (ret)
559		goto out_ttmvram;
560
561	/* PMC */
562	ret = engine->mc.init(dev);
563	if (ret)
564		goto out_gart;
565
566	/* PGPIO */
567	ret = engine->gpio.init(dev);
568	if (ret)
569		goto out_mc;
570
571	/* PTIMER */
572	ret = engine->timer.init(dev);
573	if (ret)
574		goto out_gpio;
575
576	/* PFB */
577	ret = engine->fb.init(dev);
578	if (ret)
579		goto out_timer;
580
581	if (!dev_priv->noaccel) {
582		switch (dev_priv->card_type) {
583		case NV_04:
584			nv04_graph_create(dev);
585			break;
586		case NV_10:
587			nv10_graph_create(dev);
588			break;
589		case NV_20:
590		case NV_30:
591			nv20_graph_create(dev);
592			break;
593		case NV_40:
594			nv40_graph_create(dev);
595			break;
596		case NV_50:
597			nv50_graph_create(dev);
598			break;
599		case NV_C0:
600			nvc0_graph_create(dev);
601			break;
602		default:
603			break;
604		}
605
606		switch (dev_priv->chipset) {
607		case 0x84:
608		case 0x86:
609		case 0x92:
610		case 0x94:
611		case 0x96:
612		case 0xa0:
613			nv84_crypt_create(dev);
614			break;
615		}
616
617		switch (dev_priv->card_type) {
618		case NV_50:
619			switch (dev_priv->chipset) {
620			case 0xa3:
621			case 0xa5:
622			case 0xa8:
623			case 0xaf:
624				nva3_copy_create(dev);
625				break;
626			}
627			break;
628		case NV_C0:
629			nvc0_copy_create(dev, 0);
630			nvc0_copy_create(dev, 1);
631			break;
632		default:
633			break;
634		}
635
636		if (dev_priv->card_type == NV_40 ||
637		    dev_priv->chipset == 0x31 ||
638		    dev_priv->chipset == 0x34 ||
639		    dev_priv->chipset == 0x36)
640			nv31_mpeg_create(dev);
641		else
642		if (dev_priv->card_type == NV_50 &&
643		    (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
644			nv50_mpeg_create(dev);
645
646		for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
647			if (dev_priv->eng[e]) {
648				ret = dev_priv->eng[e]->init(dev, e);
649				if (ret)
650					goto out_engine;
651			}
652		}
653
654		/* PFIFO */
655		ret = engine->fifo.init(dev);
656		if (ret)
657			goto out_engine;
658	}
659
660	ret = engine->display.create(dev);
661	if (ret)
662		goto out_fifo;
663
664	ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1);
665	if (ret)
666		goto out_vblank;
667
668	ret = nouveau_irq_init(dev);
669	if (ret)
670		goto out_vblank;
671
672	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
673
674	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
675		ret = nouveau_fence_init(dev);
676		if (ret)
677			goto out_irq;
678
679		ret = nouveau_card_init_channel(dev);
680		if (ret)
681			goto out_fence;
682	}
683
684	nouveau_fbcon_init(dev);
685	drm_kms_helper_poll_init(dev);
686	return 0;
687
688out_fence:
689	nouveau_fence_fini(dev);
690out_irq:
691	nouveau_irq_fini(dev);
692out_vblank:
693	drm_vblank_cleanup(dev);
694	engine->display.destroy(dev);
695out_fifo:
696	if (!dev_priv->noaccel)
697		engine->fifo.takedown(dev);
698out_engine:
699	if (!dev_priv->noaccel) {
700		for (e = e - 1; e >= 0; e--) {
701			if (!dev_priv->eng[e])
702				continue;
703			dev_priv->eng[e]->fini(dev, e, false);
704			dev_priv->eng[e]->destroy(dev,e );
705		}
706	}
707
708	engine->fb.takedown(dev);
709out_timer:
710	engine->timer.takedown(dev);
711out_gpio:
712	engine->gpio.takedown(dev);
713out_mc:
714	engine->mc.takedown(dev);
715out_gart:
716	nouveau_mem_gart_fini(dev);
717out_ttmvram:
718	nouveau_mem_vram_fini(dev);
719out_instmem:
720	engine->instmem.takedown(dev);
721out_gpuobj:
722	nouveau_gpuobj_takedown(dev);
723out_vram:
724	engine->vram.takedown(dev);
725out_bios:
726	nouveau_pm_fini(dev);
727	nouveau_bios_takedown(dev);
728out_display_early:
729	engine->display.late_takedown(dev);
730out:
731	vga_client_register(dev->pdev, NULL, NULL, NULL);
732	return ret;
733}
734
735static void nouveau_card_takedown(struct drm_device *dev)
736{
737	struct drm_nouveau_private *dev_priv = dev->dev_private;
738	struct nouveau_engine *engine = &dev_priv->engine;
739	int e;
740
741	drm_kms_helper_poll_fini(dev);
742	nouveau_fbcon_fini(dev);
743
744	if (dev_priv->channel) {
745		nouveau_channel_put_unlocked(&dev_priv->channel);
746		nouveau_fence_fini(dev);
747	}
748
749	engine->display.destroy(dev);
750
751	if (!dev_priv->noaccel) {
752		engine->fifo.takedown(dev);
753		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
754			if (dev_priv->eng[e]) {
755				dev_priv->eng[e]->fini(dev, e, false);
756				dev_priv->eng[e]->destroy(dev,e );
757			}
758		}
759	}
760	engine->fb.takedown(dev);
761	engine->timer.takedown(dev);
762	engine->gpio.takedown(dev);
763	engine->mc.takedown(dev);
764	engine->display.late_takedown(dev);
765
766	if (dev_priv->vga_ram) {
767		nouveau_bo_unpin(dev_priv->vga_ram);
768		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
769	}
770
771	mutex_lock(&dev->struct_mutex);
772	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
773	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
774	mutex_unlock(&dev->struct_mutex);
775	nouveau_mem_gart_fini(dev);
776	nouveau_mem_vram_fini(dev);
777
778	engine->instmem.takedown(dev);
779	nouveau_gpuobj_takedown(dev);
780	engine->vram.takedown(dev);
781
782	nouveau_irq_fini(dev);
783	drm_vblank_cleanup(dev);
784
785	nouveau_pm_fini(dev);
786	nouveau_bios_takedown(dev);
787
788	vga_client_register(dev->pdev, NULL, NULL, NULL);
789}
790
791int
792nouveau_open(struct drm_device *dev, struct drm_file *file_priv)
793{
794	struct drm_nouveau_private *dev_priv = dev->dev_private;
795	struct nouveau_fpriv *fpriv;
796	int ret;
797
798	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
799	if (unlikely(!fpriv))
800		return -ENOMEM;
801
802	spin_lock_init(&fpriv->lock);
803	INIT_LIST_HEAD(&fpriv->channels);
804
805	if (dev_priv->card_type == NV_50) {
806		ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
807				     &fpriv->vm);
808		if (ret) {
809			kfree(fpriv);
810			return ret;
811		}
812	} else
813	if (dev_priv->card_type >= NV_C0) {
814		ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL,
815				     &fpriv->vm);
816		if (ret) {
817			kfree(fpriv);
818			return ret;
819		}
820	}
821
822	file_priv->driver_priv = fpriv;
823	return 0;
824}
825
826/* here a client dies, release the stuff that was allocated for its
827 * file_priv */
828void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
829{
830	nouveau_channel_cleanup(dev, file_priv);
831}
832
833void
834nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv)
835{
836	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
837	nouveau_vm_ref(NULL, &fpriv->vm, NULL);
838	kfree(fpriv);
839}
840
841/* first module load, setup the mmio/fb mapping */
842/* KMS: we need mmio at load time, not when the first drm client opens. */
843int nouveau_firstopen(struct drm_device *dev)
844{
845	return 0;
846}
847
848/* if we have an OF card, copy vbios to RAMIN */
849static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
850{
851#if defined(__powerpc__)
852	int size, i;
853	const uint32_t *bios;
854	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
855	if (!dn) {
856		NV_INFO(dev, "Unable to get the OF node\n");
857		return;
858	}
859
860	bios = of_get_property(dn, "NVDA,BMP", &size);
861	if (bios) {
862		for (i = 0; i < size; i += 4)
863			nv_wi32(dev, i, bios[i/4]);
864		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
865	} else {
866		NV_INFO(dev, "Unable to get the OF bios\n");
867	}
868#endif
869}
870
871static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
872{
873	struct pci_dev *pdev = dev->pdev;
874	struct apertures_struct *aper = alloc_apertures(3);
875	if (!aper)
876		return NULL;
877
878	aper->ranges[0].base = pci_resource_start(pdev, 1);
879	aper->ranges[0].size = pci_resource_len(pdev, 1);
880	aper->count = 1;
881
882	if (pci_resource_len(pdev, 2)) {
883		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
884		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
885		aper->count++;
886	}
887
888	if (pci_resource_len(pdev, 3)) {
889		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
890		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
891		aper->count++;
892	}
893
894	return aper;
895}
896
897static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
898{
899	struct drm_nouveau_private *dev_priv = dev->dev_private;
900	bool primary = false;
901	dev_priv->apertures = nouveau_get_apertures(dev);
902	if (!dev_priv->apertures)
903		return -ENOMEM;
904
905#ifdef CONFIG_X86
906	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
907#endif
908
909	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
910	return 0;
911}
912
913int nouveau_load(struct drm_device *dev, unsigned long flags)
914{
915	struct drm_nouveau_private *dev_priv;
916	uint32_t reg0;
917	resource_size_t mmio_start_offs;
918	int ret;
919
920	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
921	if (!dev_priv) {
922		ret = -ENOMEM;
923		goto err_out;
924	}
925	dev->dev_private = dev_priv;
926	dev_priv->dev = dev;
927
928	dev_priv->flags = flags & NOUVEAU_FLAGS;
929
930	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
931		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
932
933	/* resource 0 is mmio regs */
934	/* resource 1 is linear FB */
935	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
936	/* resource 6 is bios */
937
938	/* map the mmio regs */
939	mmio_start_offs = pci_resource_start(dev->pdev, 0);
940	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
941	if (!dev_priv->mmio) {
942		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
943			 "Please report your setup to " DRIVER_EMAIL "\n");
944		ret = -EINVAL;
945		goto err_priv;
946	}
947	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
948					(unsigned long long)mmio_start_offs);
949
950#ifdef __BIG_ENDIAN
951	/* Put the card in BE mode if it's not */
952	if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
953		nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
954
955	DRM_MEMORYBARRIER();
956#endif
957
958	/* Time to determine the card architecture */
959	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
960	dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
961
962	/* We're dealing with >=NV10 */
963	if ((reg0 & 0x0f000000) > 0) {
964		/* Bit 27-20 contain the architecture in hex */
965		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
966		dev_priv->stepping = (reg0 & 0xff);
967	/* NV04 or NV05 */
968	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
969		if (reg0 & 0x00f00000)
970			dev_priv->chipset = 0x05;
971		else
972			dev_priv->chipset = 0x04;
973	} else
974		dev_priv->chipset = 0xff;
975
976	switch (dev_priv->chipset & 0xf0) {
977	case 0x00:
978	case 0x10:
979	case 0x20:
980	case 0x30:
981		dev_priv->card_type = dev_priv->chipset & 0xf0;
982		break;
983	case 0x40:
984	case 0x60:
985		dev_priv->card_type = NV_40;
986		break;
987	case 0x50:
988	case 0x80:
989	case 0x90:
990	case 0xa0:
991		dev_priv->card_type = NV_50;
992		break;
993	case 0xc0:
994		dev_priv->card_type = NV_C0;
995		break;
996	default:
997		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
998		ret = -EINVAL;
999		goto err_mmio;
1000	}
1001
1002	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
1003		dev_priv->card_type, reg0);
1004
1005	/* Determine whether we'll attempt acceleration or not, some
1006	 * cards are disabled by default here due to them being known
1007	 * non-functional, or never been tested due to lack of hw.
1008	 */
1009	dev_priv->noaccel = !!nouveau_noaccel;
1010	if (nouveau_noaccel == -1) {
1011		switch (dev_priv->chipset) {
1012		case 0xc1: /* known broken */
1013		case 0xc8: /* never tested */
1014			NV_INFO(dev, "acceleration disabled by default, pass "
1015				     "noaccel=0 to force enable\n");
1016			dev_priv->noaccel = true;
1017			break;
1018		default:
1019			dev_priv->noaccel = false;
1020			break;
1021		}
1022	}
1023
1024	ret = nouveau_remove_conflicting_drivers(dev);
1025	if (ret)
1026		goto err_mmio;
1027
1028	/* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */
1029	if (dev_priv->card_type >= NV_40) {
1030		int ramin_bar = 2;
1031		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
1032			ramin_bar = 3;
1033
1034		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
1035		dev_priv->ramin =
1036			ioremap(pci_resource_start(dev->pdev, ramin_bar),
1037				dev_priv->ramin_size);
1038		if (!dev_priv->ramin) {
1039			NV_ERROR(dev, "Failed to PRAMIN BAR");
1040			ret = -ENOMEM;
1041			goto err_mmio;
1042		}
1043	} else {
1044		dev_priv->ramin_size = 1 * 1024 * 1024;
1045		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
1046					  dev_priv->ramin_size);
1047		if (!dev_priv->ramin) {
1048			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
1049			ret = -ENOMEM;
1050			goto err_mmio;
1051		}
1052	}
1053
1054	nouveau_OF_copy_vbios_to_ramin(dev);
1055
1056	/* Special flags */
1057	if (dev->pci_device == 0x01a0)
1058		dev_priv->flags |= NV_NFORCE;
1059	else if (dev->pci_device == 0x01f0)
1060		dev_priv->flags |= NV_NFORCE2;
1061
1062	/* For kernel modesetting, init card now and bring up fbcon */
1063	ret = nouveau_card_init(dev);
1064	if (ret)
1065		goto err_ramin;
1066
1067	return 0;
1068
1069err_ramin:
1070	iounmap(dev_priv->ramin);
1071err_mmio:
1072	iounmap(dev_priv->mmio);
1073err_priv:
1074	kfree(dev_priv);
1075	dev->dev_private = NULL;
1076err_out:
1077	return ret;
1078}
1079
1080void nouveau_lastclose(struct drm_device *dev)
1081{
1082	vga_switcheroo_process_delayed_switch();
1083}
1084
1085int nouveau_unload(struct drm_device *dev)
1086{
1087	struct drm_nouveau_private *dev_priv = dev->dev_private;
1088
1089	nouveau_card_takedown(dev);
1090
1091	iounmap(dev_priv->mmio);
1092	iounmap(dev_priv->ramin);
1093
1094	kfree(dev_priv);
1095	dev->dev_private = NULL;
1096	return 0;
1097}
1098
1099int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
1100						struct drm_file *file_priv)
1101{
1102	struct drm_nouveau_private *dev_priv = dev->dev_private;
1103	struct drm_nouveau_getparam *getparam = data;
1104
1105	switch (getparam->param) {
1106	case NOUVEAU_GETPARAM_CHIPSET_ID:
1107		getparam->value = dev_priv->chipset;
1108		break;
1109	case NOUVEAU_GETPARAM_PCI_VENDOR:
1110		getparam->value = dev->pci_vendor;
1111		break;
1112	case NOUVEAU_GETPARAM_PCI_DEVICE:
1113		getparam->value = dev->pci_device;
1114		break;
1115	case NOUVEAU_GETPARAM_BUS_TYPE:
1116		if (drm_pci_device_is_agp(dev))
1117			getparam->value = NV_AGP;
1118		else if (pci_is_pcie(dev->pdev))
1119			getparam->value = NV_PCIE;
1120		else
1121			getparam->value = NV_PCI;
1122		break;
1123	case NOUVEAU_GETPARAM_FB_SIZE:
1124		getparam->value = dev_priv->fb_available_size;
1125		break;
1126	case NOUVEAU_GETPARAM_AGP_SIZE:
1127		getparam->value = dev_priv->gart_info.aper_size;
1128		break;
1129	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
1130		getparam->value = 0; /* deprecated */
1131		break;
1132	case NOUVEAU_GETPARAM_PTIMER_TIME:
1133		getparam->value = dev_priv->engine.timer.read(dev);
1134		break;
1135	case NOUVEAU_GETPARAM_HAS_BO_USAGE:
1136		getparam->value = 1;
1137		break;
1138	case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
1139		getparam->value = 1;
1140		break;
1141	case NOUVEAU_GETPARAM_GRAPH_UNITS:
1142		/* NV40 and NV50 versions are quite different, but register
1143		 * address is the same. User is supposed to know the card
1144		 * family anyway... */
1145		if (dev_priv->chipset >= 0x40) {
1146			getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
1147			break;
1148		}
1149		/* FALLTHRU */
1150	default:
1151		NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param);
1152		return -EINVAL;
1153	}
1154
1155	return 0;
1156}
1157
1158int
1159nouveau_ioctl_setparam(struct drm_device *dev, void *data,
1160		       struct drm_file *file_priv)
1161{
1162	struct drm_nouveau_setparam *setparam = data;
1163
1164	switch (setparam->param) {
1165	default:
1166		NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param);
1167		return -EINVAL;
1168	}
1169
1170	return 0;
1171}
1172
1173/* Wait until (value(reg) & mask) == val, up until timeout has hit */
1174bool
1175nouveau_wait_eq(struct drm_device *dev, uint64_t timeout,
1176		uint32_t reg, uint32_t mask, uint32_t val)
1177{
1178	struct drm_nouveau_private *dev_priv = dev->dev_private;
1179	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1180	uint64_t start = ptimer->read(dev);
1181
1182	do {
1183		if ((nv_rd32(dev, reg) & mask) == val)
1184			return true;
1185	} while (ptimer->read(dev) - start < timeout);
1186
1187	return false;
1188}
1189
1190/* Wait until (value(reg) & mask) != val, up until timeout has hit */
1191bool
1192nouveau_wait_ne(struct drm_device *dev, uint64_t timeout,
1193		uint32_t reg, uint32_t mask, uint32_t val)
1194{
1195	struct drm_nouveau_private *dev_priv = dev->dev_private;
1196	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1197	uint64_t start = ptimer->read(dev);
1198
1199	do {
1200		if ((nv_rd32(dev, reg) & mask) != val)
1201			return true;
1202	} while (ptimer->read(dev) - start < timeout);
1203
1204	return false;
1205}
1206
1207/* Wait until cond(data) == true, up until timeout has hit */
1208bool
1209nouveau_wait_cb(struct drm_device *dev, u64 timeout,
1210		bool (*cond)(void *), void *data)
1211{
1212	struct drm_nouveau_private *dev_priv = dev->dev_private;
1213	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1214	u64 start = ptimer->read(dev);
1215
1216	do {
1217		if (cond(data) == true)
1218			return true;
1219	} while (ptimer->read(dev) - start < timeout);
1220
1221	return false;
1222}
1223
1224/* Waits for PGRAPH to go completely idle */
1225bool nouveau_wait_for_idle(struct drm_device *dev)
1226{
1227	struct drm_nouveau_private *dev_priv = dev->dev_private;
1228	uint32_t mask = ~0;
1229
1230	if (dev_priv->card_type == NV_40)
1231		mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL;
1232
1233	if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) {
1234		NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
1235			 nv_rd32(dev, NV04_PGRAPH_STATUS));
1236		return false;
1237	}
1238
1239	return true;
1240}
1241
1242