• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/gpu/drm/nouveau/
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 "nv50_display.h"
39
40static void nouveau_stub_takedown(struct drm_device *dev) {}
41static int nouveau_stub_init(struct drm_device *dev) { return 0; }
42
43static int nouveau_init_engine_ptrs(struct drm_device *dev)
44{
45	struct drm_nouveau_private *dev_priv = dev->dev_private;
46	struct nouveau_engine *engine = &dev_priv->engine;
47
48	switch (dev_priv->chipset & 0xf0) {
49	case 0x00:
50		engine->instmem.init		= nv04_instmem_init;
51		engine->instmem.takedown	= nv04_instmem_takedown;
52		engine->instmem.suspend		= nv04_instmem_suspend;
53		engine->instmem.resume		= nv04_instmem_resume;
54		engine->instmem.populate	= nv04_instmem_populate;
55		engine->instmem.clear		= nv04_instmem_clear;
56		engine->instmem.bind		= nv04_instmem_bind;
57		engine->instmem.unbind		= nv04_instmem_unbind;
58		engine->instmem.flush		= nv04_instmem_flush;
59		engine->mc.init			= nv04_mc_init;
60		engine->mc.takedown		= nv04_mc_takedown;
61		engine->timer.init		= nv04_timer_init;
62		engine->timer.read		= nv04_timer_read;
63		engine->timer.takedown		= nv04_timer_takedown;
64		engine->fb.init			= nv04_fb_init;
65		engine->fb.takedown		= nv04_fb_takedown;
66		engine->graph.grclass		= nv04_graph_grclass;
67		engine->graph.init		= nv04_graph_init;
68		engine->graph.takedown		= nv04_graph_takedown;
69		engine->graph.fifo_access	= nv04_graph_fifo_access;
70		engine->graph.channel		= nv04_graph_channel;
71		engine->graph.create_context	= nv04_graph_create_context;
72		engine->graph.destroy_context	= nv04_graph_destroy_context;
73		engine->graph.load_context	= nv04_graph_load_context;
74		engine->graph.unload_context	= nv04_graph_unload_context;
75		engine->fifo.channels		= 16;
76		engine->fifo.init		= nv04_fifo_init;
77		engine->fifo.takedown		= nouveau_stub_takedown;
78		engine->fifo.disable		= nv04_fifo_disable;
79		engine->fifo.enable		= nv04_fifo_enable;
80		engine->fifo.reassign		= nv04_fifo_reassign;
81		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
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		break;
99	case 0x10:
100		engine->instmem.init		= nv04_instmem_init;
101		engine->instmem.takedown	= nv04_instmem_takedown;
102		engine->instmem.suspend		= nv04_instmem_suspend;
103		engine->instmem.resume		= nv04_instmem_resume;
104		engine->instmem.populate	= nv04_instmem_populate;
105		engine->instmem.clear		= nv04_instmem_clear;
106		engine->instmem.bind		= nv04_instmem_bind;
107		engine->instmem.unbind		= nv04_instmem_unbind;
108		engine->instmem.flush		= nv04_instmem_flush;
109		engine->mc.init			= nv04_mc_init;
110		engine->mc.takedown		= nv04_mc_takedown;
111		engine->timer.init		= nv04_timer_init;
112		engine->timer.read		= nv04_timer_read;
113		engine->timer.takedown		= nv04_timer_takedown;
114		engine->fb.init			= nv10_fb_init;
115		engine->fb.takedown		= nv10_fb_takedown;
116		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
117		engine->graph.grclass		= nv10_graph_grclass;
118		engine->graph.init		= nv10_graph_init;
119		engine->graph.takedown		= nv10_graph_takedown;
120		engine->graph.channel		= nv10_graph_channel;
121		engine->graph.create_context	= nv10_graph_create_context;
122		engine->graph.destroy_context	= nv10_graph_destroy_context;
123		engine->graph.fifo_access	= nv04_graph_fifo_access;
124		engine->graph.load_context	= nv10_graph_load_context;
125		engine->graph.unload_context	= nv10_graph_unload_context;
126		engine->graph.set_region_tiling	= nv10_graph_set_region_tiling;
127		engine->fifo.channels		= 32;
128		engine->fifo.init		= nv10_fifo_init;
129		engine->fifo.takedown		= nouveau_stub_takedown;
130		engine->fifo.disable		= nv04_fifo_disable;
131		engine->fifo.enable		= nv04_fifo_enable;
132		engine->fifo.reassign		= nv04_fifo_reassign;
133		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
134		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
135		engine->fifo.channel_id		= nv10_fifo_channel_id;
136		engine->fifo.create_context	= nv10_fifo_create_context;
137		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
138		engine->fifo.load_context	= nv10_fifo_load_context;
139		engine->fifo.unload_context	= nv10_fifo_unload_context;
140		engine->display.early_init	= nv04_display_early_init;
141		engine->display.late_takedown	= nv04_display_late_takedown;
142		engine->display.create		= nv04_display_create;
143		engine->display.init		= nv04_display_init;
144		engine->display.destroy		= nv04_display_destroy;
145		engine->gpio.init		= nouveau_stub_init;
146		engine->gpio.takedown		= nouveau_stub_takedown;
147		engine->gpio.get		= nv10_gpio_get;
148		engine->gpio.set		= nv10_gpio_set;
149		engine->gpio.irq_enable		= NULL;
150		break;
151	case 0x20:
152		engine->instmem.init		= nv04_instmem_init;
153		engine->instmem.takedown	= nv04_instmem_takedown;
154		engine->instmem.suspend		= nv04_instmem_suspend;
155		engine->instmem.resume		= nv04_instmem_resume;
156		engine->instmem.populate	= nv04_instmem_populate;
157		engine->instmem.clear		= nv04_instmem_clear;
158		engine->instmem.bind		= nv04_instmem_bind;
159		engine->instmem.unbind		= nv04_instmem_unbind;
160		engine->instmem.flush		= nv04_instmem_flush;
161		engine->mc.init			= nv04_mc_init;
162		engine->mc.takedown		= nv04_mc_takedown;
163		engine->timer.init		= nv04_timer_init;
164		engine->timer.read		= nv04_timer_read;
165		engine->timer.takedown		= nv04_timer_takedown;
166		engine->fb.init			= nv10_fb_init;
167		engine->fb.takedown		= nv10_fb_takedown;
168		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
169		engine->graph.grclass		= nv20_graph_grclass;
170		engine->graph.init		= nv20_graph_init;
171		engine->graph.takedown		= nv20_graph_takedown;
172		engine->graph.channel		= nv10_graph_channel;
173		engine->graph.create_context	= nv20_graph_create_context;
174		engine->graph.destroy_context	= nv20_graph_destroy_context;
175		engine->graph.fifo_access	= nv04_graph_fifo_access;
176		engine->graph.load_context	= nv20_graph_load_context;
177		engine->graph.unload_context	= nv20_graph_unload_context;
178		engine->graph.set_region_tiling	= nv20_graph_set_region_tiling;
179		engine->fifo.channels		= 32;
180		engine->fifo.init		= nv10_fifo_init;
181		engine->fifo.takedown		= nouveau_stub_takedown;
182		engine->fifo.disable		= nv04_fifo_disable;
183		engine->fifo.enable		= nv04_fifo_enable;
184		engine->fifo.reassign		= nv04_fifo_reassign;
185		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
186		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
187		engine->fifo.channel_id		= nv10_fifo_channel_id;
188		engine->fifo.create_context	= nv10_fifo_create_context;
189		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
190		engine->fifo.load_context	= nv10_fifo_load_context;
191		engine->fifo.unload_context	= nv10_fifo_unload_context;
192		engine->display.early_init	= nv04_display_early_init;
193		engine->display.late_takedown	= nv04_display_late_takedown;
194		engine->display.create		= nv04_display_create;
195		engine->display.init		= nv04_display_init;
196		engine->display.destroy		= nv04_display_destroy;
197		engine->gpio.init		= nouveau_stub_init;
198		engine->gpio.takedown		= nouveau_stub_takedown;
199		engine->gpio.get		= nv10_gpio_get;
200		engine->gpio.set		= nv10_gpio_set;
201		engine->gpio.irq_enable		= NULL;
202		break;
203	case 0x30:
204		engine->instmem.init		= nv04_instmem_init;
205		engine->instmem.takedown	= nv04_instmem_takedown;
206		engine->instmem.suspend		= nv04_instmem_suspend;
207		engine->instmem.resume		= nv04_instmem_resume;
208		engine->instmem.populate	= nv04_instmem_populate;
209		engine->instmem.clear		= nv04_instmem_clear;
210		engine->instmem.bind		= nv04_instmem_bind;
211		engine->instmem.unbind		= nv04_instmem_unbind;
212		engine->instmem.flush		= nv04_instmem_flush;
213		engine->mc.init			= nv04_mc_init;
214		engine->mc.takedown		= nv04_mc_takedown;
215		engine->timer.init		= nv04_timer_init;
216		engine->timer.read		= nv04_timer_read;
217		engine->timer.takedown		= nv04_timer_takedown;
218		engine->fb.init			= nv30_fb_init;
219		engine->fb.takedown		= nv30_fb_takedown;
220		engine->fb.set_region_tiling	= nv10_fb_set_region_tiling;
221		engine->graph.grclass		= nv30_graph_grclass;
222		engine->graph.init		= nv30_graph_init;
223		engine->graph.takedown		= nv20_graph_takedown;
224		engine->graph.fifo_access	= nv04_graph_fifo_access;
225		engine->graph.channel		= nv10_graph_channel;
226		engine->graph.create_context	= nv20_graph_create_context;
227		engine->graph.destroy_context	= nv20_graph_destroy_context;
228		engine->graph.load_context	= nv20_graph_load_context;
229		engine->graph.unload_context	= nv20_graph_unload_context;
230		engine->graph.set_region_tiling	= nv20_graph_set_region_tiling;
231		engine->fifo.channels		= 32;
232		engine->fifo.init		= nv10_fifo_init;
233		engine->fifo.takedown		= nouveau_stub_takedown;
234		engine->fifo.disable		= nv04_fifo_disable;
235		engine->fifo.enable		= nv04_fifo_enable;
236		engine->fifo.reassign		= nv04_fifo_reassign;
237		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
238		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
239		engine->fifo.channel_id		= nv10_fifo_channel_id;
240		engine->fifo.create_context	= nv10_fifo_create_context;
241		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
242		engine->fifo.load_context	= nv10_fifo_load_context;
243		engine->fifo.unload_context	= nv10_fifo_unload_context;
244		engine->display.early_init	= nv04_display_early_init;
245		engine->display.late_takedown	= nv04_display_late_takedown;
246		engine->display.create		= nv04_display_create;
247		engine->display.init		= nv04_display_init;
248		engine->display.destroy		= nv04_display_destroy;
249		engine->gpio.init		= nouveau_stub_init;
250		engine->gpio.takedown		= nouveau_stub_takedown;
251		engine->gpio.get		= nv10_gpio_get;
252		engine->gpio.set		= nv10_gpio_set;
253		engine->gpio.irq_enable		= NULL;
254		break;
255	case 0x40:
256	case 0x60:
257		engine->instmem.init		= nv04_instmem_init;
258		engine->instmem.takedown	= nv04_instmem_takedown;
259		engine->instmem.suspend		= nv04_instmem_suspend;
260		engine->instmem.resume		= nv04_instmem_resume;
261		engine->instmem.populate	= nv04_instmem_populate;
262		engine->instmem.clear		= nv04_instmem_clear;
263		engine->instmem.bind		= nv04_instmem_bind;
264		engine->instmem.unbind		= nv04_instmem_unbind;
265		engine->instmem.flush		= nv04_instmem_flush;
266		engine->mc.init			= nv40_mc_init;
267		engine->mc.takedown		= nv40_mc_takedown;
268		engine->timer.init		= nv04_timer_init;
269		engine->timer.read		= nv04_timer_read;
270		engine->timer.takedown		= nv04_timer_takedown;
271		engine->fb.init			= nv40_fb_init;
272		engine->fb.takedown		= nv40_fb_takedown;
273		engine->fb.set_region_tiling	= nv40_fb_set_region_tiling;
274		engine->graph.grclass		= nv40_graph_grclass;
275		engine->graph.init		= nv40_graph_init;
276		engine->graph.takedown		= nv40_graph_takedown;
277		engine->graph.fifo_access	= nv04_graph_fifo_access;
278		engine->graph.channel		= nv40_graph_channel;
279		engine->graph.create_context	= nv40_graph_create_context;
280		engine->graph.destroy_context	= nv40_graph_destroy_context;
281		engine->graph.load_context	= nv40_graph_load_context;
282		engine->graph.unload_context	= nv40_graph_unload_context;
283		engine->graph.set_region_tiling	= nv40_graph_set_region_tiling;
284		engine->fifo.channels		= 32;
285		engine->fifo.init		= nv40_fifo_init;
286		engine->fifo.takedown		= nouveau_stub_takedown;
287		engine->fifo.disable		= nv04_fifo_disable;
288		engine->fifo.enable		= nv04_fifo_enable;
289		engine->fifo.reassign		= nv04_fifo_reassign;
290		engine->fifo.cache_flush	= nv04_fifo_cache_flush;
291		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
292		engine->fifo.channel_id		= nv10_fifo_channel_id;
293		engine->fifo.create_context	= nv40_fifo_create_context;
294		engine->fifo.destroy_context	= nv40_fifo_destroy_context;
295		engine->fifo.load_context	= nv40_fifo_load_context;
296		engine->fifo.unload_context	= nv40_fifo_unload_context;
297		engine->display.early_init	= nv04_display_early_init;
298		engine->display.late_takedown	= nv04_display_late_takedown;
299		engine->display.create		= nv04_display_create;
300		engine->display.init		= nv04_display_init;
301		engine->display.destroy		= nv04_display_destroy;
302		engine->gpio.init		= nouveau_stub_init;
303		engine->gpio.takedown		= nouveau_stub_takedown;
304		engine->gpio.get		= nv10_gpio_get;
305		engine->gpio.set		= nv10_gpio_set;
306		engine->gpio.irq_enable		= NULL;
307		break;
308	case 0x50:
309	case 0x80: /* gotta love NVIDIA's consistency.. */
310	case 0x90:
311	case 0xA0:
312		engine->instmem.init		= nv50_instmem_init;
313		engine->instmem.takedown	= nv50_instmem_takedown;
314		engine->instmem.suspend		= nv50_instmem_suspend;
315		engine->instmem.resume		= nv50_instmem_resume;
316		engine->instmem.populate	= nv50_instmem_populate;
317		engine->instmem.clear		= nv50_instmem_clear;
318		engine->instmem.bind		= nv50_instmem_bind;
319		engine->instmem.unbind		= nv50_instmem_unbind;
320		if (dev_priv->chipset == 0x50)
321			engine->instmem.flush	= nv50_instmem_flush;
322		else
323			engine->instmem.flush	= nv84_instmem_flush;
324		engine->mc.init			= nv50_mc_init;
325		engine->mc.takedown		= nv50_mc_takedown;
326		engine->timer.init		= nv04_timer_init;
327		engine->timer.read		= nv04_timer_read;
328		engine->timer.takedown		= nv04_timer_takedown;
329		engine->fb.init			= nv50_fb_init;
330		engine->fb.takedown		= nv50_fb_takedown;
331		engine->graph.grclass		= nv50_graph_grclass;
332		engine->graph.init		= nv50_graph_init;
333		engine->graph.takedown		= nv50_graph_takedown;
334		engine->graph.fifo_access	= nv50_graph_fifo_access;
335		engine->graph.channel		= nv50_graph_channel;
336		engine->graph.create_context	= nv50_graph_create_context;
337		engine->graph.destroy_context	= nv50_graph_destroy_context;
338		engine->graph.load_context	= nv50_graph_load_context;
339		engine->graph.unload_context	= nv50_graph_unload_context;
340		engine->fifo.channels		= 128;
341		engine->fifo.init		= nv50_fifo_init;
342		engine->fifo.takedown		= nv50_fifo_takedown;
343		engine->fifo.disable		= nv04_fifo_disable;
344		engine->fifo.enable		= nv04_fifo_enable;
345		engine->fifo.reassign		= nv04_fifo_reassign;
346		engine->fifo.channel_id		= nv50_fifo_channel_id;
347		engine->fifo.create_context	= nv50_fifo_create_context;
348		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
349		engine->fifo.load_context	= nv50_fifo_load_context;
350		engine->fifo.unload_context	= nv50_fifo_unload_context;
351		engine->display.early_init	= nv50_display_early_init;
352		engine->display.late_takedown	= nv50_display_late_takedown;
353		engine->display.create		= nv50_display_create;
354		engine->display.init		= nv50_display_init;
355		engine->display.destroy		= nv50_display_destroy;
356		engine->gpio.init		= nv50_gpio_init;
357		engine->gpio.takedown		= nouveau_stub_takedown;
358		engine->gpio.get		= nv50_gpio_get;
359		engine->gpio.set		= nv50_gpio_set;
360		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
361		break;
362	case 0xC0:
363		engine->instmem.init		= nvc0_instmem_init;
364		engine->instmem.takedown	= nvc0_instmem_takedown;
365		engine->instmem.suspend		= nvc0_instmem_suspend;
366		engine->instmem.resume		= nvc0_instmem_resume;
367		engine->instmem.populate	= nvc0_instmem_populate;
368		engine->instmem.clear		= nvc0_instmem_clear;
369		engine->instmem.bind		= nvc0_instmem_bind;
370		engine->instmem.unbind		= nvc0_instmem_unbind;
371		engine->instmem.flush		= nvc0_instmem_flush;
372		engine->mc.init			= nv50_mc_init;
373		engine->mc.takedown		= nv50_mc_takedown;
374		engine->timer.init		= nv04_timer_init;
375		engine->timer.read		= nv04_timer_read;
376		engine->timer.takedown		= nv04_timer_takedown;
377		engine->fb.init			= nvc0_fb_init;
378		engine->fb.takedown		= nvc0_fb_takedown;
379		engine->graph.grclass		= NULL;  //nvc0_graph_grclass;
380		engine->graph.init		= nvc0_graph_init;
381		engine->graph.takedown		= nvc0_graph_takedown;
382		engine->graph.fifo_access	= nvc0_graph_fifo_access;
383		engine->graph.channel		= nvc0_graph_channel;
384		engine->graph.create_context	= nvc0_graph_create_context;
385		engine->graph.destroy_context	= nvc0_graph_destroy_context;
386		engine->graph.load_context	= nvc0_graph_load_context;
387		engine->graph.unload_context	= nvc0_graph_unload_context;
388		engine->fifo.channels		= 128;
389		engine->fifo.init		= nvc0_fifo_init;
390		engine->fifo.takedown		= nvc0_fifo_takedown;
391		engine->fifo.disable		= nvc0_fifo_disable;
392		engine->fifo.enable		= nvc0_fifo_enable;
393		engine->fifo.reassign		= nvc0_fifo_reassign;
394		engine->fifo.channel_id		= nvc0_fifo_channel_id;
395		engine->fifo.create_context	= nvc0_fifo_create_context;
396		engine->fifo.destroy_context	= nvc0_fifo_destroy_context;
397		engine->fifo.load_context	= nvc0_fifo_load_context;
398		engine->fifo.unload_context	= nvc0_fifo_unload_context;
399		engine->display.early_init	= nv50_display_early_init;
400		engine->display.late_takedown	= nv50_display_late_takedown;
401		engine->display.create		= nv50_display_create;
402		engine->display.init		= nv50_display_init;
403		engine->display.destroy		= nv50_display_destroy;
404		engine->gpio.init		= nv50_gpio_init;
405		engine->gpio.takedown		= nouveau_stub_takedown;
406		engine->gpio.get		= nv50_gpio_get;
407		engine->gpio.set		= nv50_gpio_set;
408		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
409		break;
410	default:
411		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
412		return 1;
413	}
414
415	return 0;
416}
417
418static unsigned int
419nouveau_vga_set_decode(void *priv, bool state)
420{
421	struct drm_device *dev = priv;
422	struct drm_nouveau_private *dev_priv = dev->dev_private;
423
424	if (dev_priv->chipset >= 0x40)
425		nv_wr32(dev, 0x88054, state);
426	else
427		nv_wr32(dev, 0x1854, state);
428
429	if (state)
430		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
431		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
432	else
433		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
434}
435
436static int
437nouveau_card_init_channel(struct drm_device *dev)
438{
439	struct drm_nouveau_private *dev_priv = dev->dev_private;
440	struct nouveau_gpuobj *gpuobj;
441	int ret;
442
443	ret = nouveau_channel_alloc(dev, &dev_priv->channel,
444				    (struct drm_file *)-2,
445				    NvDmaFB, NvDmaTT);
446	if (ret)
447		return ret;
448
449	gpuobj = NULL;
450	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
451				     0, dev_priv->vram_size,
452				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
453				     &gpuobj);
454	if (ret)
455		goto out_err;
456
457	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
458				     gpuobj, NULL);
459	if (ret)
460		goto out_err;
461
462	gpuobj = NULL;
463	ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0,
464					  dev_priv->gart_info.aper_size,
465					  NV_DMA_ACCESS_RW, &gpuobj, NULL);
466	if (ret)
467		goto out_err;
468
469	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
470				     gpuobj, NULL);
471	if (ret)
472		goto out_err;
473
474	return 0;
475out_err:
476	nouveau_gpuobj_del(dev, &gpuobj);
477	nouveau_channel_free(dev_priv->channel);
478	dev_priv->channel = NULL;
479	return ret;
480}
481
482static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
483					 enum vga_switcheroo_state state)
484{
485	struct drm_device *dev = pci_get_drvdata(pdev);
486	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
487	if (state == VGA_SWITCHEROO_ON) {
488		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
489		nouveau_pci_resume(pdev);
490		drm_kms_helper_poll_enable(dev);
491	} else {
492		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
493		drm_kms_helper_poll_disable(dev);
494		nouveau_pci_suspend(pdev, pmm);
495	}
496}
497
498static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
499{
500	struct drm_device *dev = pci_get_drvdata(pdev);
501	bool can_switch;
502
503	spin_lock(&dev->count_lock);
504	can_switch = (dev->open_count == 0);
505	spin_unlock(&dev->count_lock);
506	return can_switch;
507}
508
509int
510nouveau_card_init(struct drm_device *dev)
511{
512	struct drm_nouveau_private *dev_priv = dev->dev_private;
513	struct nouveau_engine *engine;
514	int ret;
515
516	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
517	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
518				       nouveau_switcheroo_can_switch);
519
520	/* Initialise internal driver API hooks */
521	ret = nouveau_init_engine_ptrs(dev);
522	if (ret)
523		goto out;
524	engine = &dev_priv->engine;
525	spin_lock_init(&dev_priv->context_switch_lock);
526
527	/* Make the CRTCs and I2C buses accessible */
528	ret = engine->display.early_init(dev);
529	if (ret)
530		goto out;
531
532	/* Parse BIOS tables / Run init tables if card not POSTed */
533	ret = nouveau_bios_init(dev);
534	if (ret)
535		goto out_display_early;
536
537	ret = nouveau_mem_detect(dev);
538	if (ret)
539		goto out_bios;
540
541	ret = nouveau_gpuobj_early_init(dev);
542	if (ret)
543		goto out_bios;
544
545	/* Initialise instance memory, must happen before mem_init so we
546	 * know exactly how much VRAM we're able to use for "normal"
547	 * purposes.
548	 */
549	ret = engine->instmem.init(dev);
550	if (ret)
551		goto out_gpuobj_early;
552
553	/* Setup the memory manager */
554	ret = nouveau_mem_init(dev);
555	if (ret)
556		goto out_instmem;
557
558	ret = nouveau_gpuobj_init(dev);
559	if (ret)
560		goto out_mem;
561
562	/* PMC */
563	ret = engine->mc.init(dev);
564	if (ret)
565		goto out_gpuobj;
566
567	/* PGPIO */
568	ret = engine->gpio.init(dev);
569	if (ret)
570		goto out_mc;
571
572	/* PTIMER */
573	ret = engine->timer.init(dev);
574	if (ret)
575		goto out_gpio;
576
577	/* PFB */
578	ret = engine->fb.init(dev);
579	if (ret)
580		goto out_timer;
581
582	if (nouveau_noaccel)
583		engine->graph.accel_blocked = true;
584	else {
585		/* PGRAPH */
586		ret = engine->graph.init(dev);
587		if (ret)
588			goto out_fb;
589
590		/* PFIFO */
591		ret = engine->fifo.init(dev);
592		if (ret)
593			goto out_graph;
594	}
595
596	ret = engine->display.create(dev);
597	if (ret)
598		goto out_fifo;
599
600	/* this call irq_preinstall, register irq handler and
601	 * call irq_postinstall
602	 */
603	ret = drm_irq_install(dev);
604	if (ret)
605		goto out_display;
606
607	ret = drm_vblank_init(dev, 0);
608	if (ret)
609		goto out_irq;
610
611	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
612
613	if (!engine->graph.accel_blocked) {
614		ret = nouveau_card_init_channel(dev);
615		if (ret)
616			goto out_irq;
617	}
618
619	ret = nouveau_backlight_init(dev);
620	if (ret)
621		NV_ERROR(dev, "Error %d registering backlight\n", ret);
622
623	nouveau_fbcon_init(dev);
624	drm_kms_helper_poll_init(dev);
625	return 0;
626
627out_irq:
628	drm_irq_uninstall(dev);
629out_display:
630	engine->display.destroy(dev);
631out_fifo:
632	if (!nouveau_noaccel)
633		engine->fifo.takedown(dev);
634out_graph:
635	if (!nouveau_noaccel)
636		engine->graph.takedown(dev);
637out_fb:
638	engine->fb.takedown(dev);
639out_timer:
640	engine->timer.takedown(dev);
641out_gpio:
642	engine->gpio.takedown(dev);
643out_mc:
644	engine->mc.takedown(dev);
645out_gpuobj:
646	nouveau_gpuobj_takedown(dev);
647out_mem:
648	nouveau_sgdma_takedown(dev);
649	nouveau_mem_close(dev);
650out_instmem:
651	engine->instmem.takedown(dev);
652out_gpuobj_early:
653	nouveau_gpuobj_late_takedown(dev);
654out_bios:
655	nouveau_bios_takedown(dev);
656out_display_early:
657	engine->display.late_takedown(dev);
658out:
659	vga_client_register(dev->pdev, NULL, NULL, NULL);
660	return ret;
661}
662
663static void nouveau_card_takedown(struct drm_device *dev)
664{
665	struct drm_nouveau_private *dev_priv = dev->dev_private;
666	struct nouveau_engine *engine = &dev_priv->engine;
667
668	nouveau_backlight_exit(dev);
669
670	if (dev_priv->channel) {
671		nouveau_channel_free(dev_priv->channel);
672		dev_priv->channel = NULL;
673	}
674
675	if (!nouveau_noaccel) {
676		engine->fifo.takedown(dev);
677		engine->graph.takedown(dev);
678	}
679	engine->fb.takedown(dev);
680	engine->timer.takedown(dev);
681	engine->gpio.takedown(dev);
682	engine->mc.takedown(dev);
683	engine->display.late_takedown(dev);
684
685	mutex_lock(&dev->struct_mutex);
686	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
687	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
688	mutex_unlock(&dev->struct_mutex);
689	nouveau_sgdma_takedown(dev);
690
691	nouveau_gpuobj_takedown(dev);
692	nouveau_mem_close(dev);
693	engine->instmem.takedown(dev);
694
695	drm_irq_uninstall(dev);
696
697	nouveau_gpuobj_late_takedown(dev);
698	nouveau_bios_takedown(dev);
699
700	vga_client_register(dev->pdev, NULL, NULL, NULL);
701}
702
703/* here a client dies, release the stuff that was allocated for its
704 * file_priv */
705void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
706{
707	nouveau_channel_cleanup(dev, file_priv);
708}
709
710/* first module load, setup the mmio/fb mapping */
711/* KMS: we need mmio at load time, not when the first drm client opens. */
712int nouveau_firstopen(struct drm_device *dev)
713{
714	return 0;
715}
716
717/* if we have an OF card, copy vbios to RAMIN */
718static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
719{
720#if defined(__powerpc__)
721	int size, i;
722	const uint32_t *bios;
723	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
724	if (!dn) {
725		NV_INFO(dev, "Unable to get the OF node\n");
726		return;
727	}
728
729	bios = of_get_property(dn, "NVDA,BMP", &size);
730	if (bios) {
731		for (i = 0; i < size; i += 4)
732			nv_wi32(dev, i, bios[i/4]);
733		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
734	} else {
735		NV_INFO(dev, "Unable to get the OF bios\n");
736	}
737#endif
738}
739
740static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
741{
742	struct pci_dev *pdev = dev->pdev;
743	struct apertures_struct *aper = alloc_apertures(3);
744	if (!aper)
745		return NULL;
746
747	aper->ranges[0].base = pci_resource_start(pdev, 1);
748	aper->ranges[0].size = pci_resource_len(pdev, 1);
749	aper->count = 1;
750
751	if (pci_resource_len(pdev, 2)) {
752		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
753		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
754		aper->count++;
755	}
756
757	if (pci_resource_len(pdev, 3)) {
758		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
759		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
760		aper->count++;
761	}
762
763	return aper;
764}
765
766static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
767{
768	struct drm_nouveau_private *dev_priv = dev->dev_private;
769	bool primary = false;
770	dev_priv->apertures = nouveau_get_apertures(dev);
771	if (!dev_priv->apertures)
772		return -ENOMEM;
773
774#ifdef CONFIG_X86
775	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
776#endif
777
778	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
779	return 0;
780}
781
782int nouveau_load(struct drm_device *dev, unsigned long flags)
783{
784	struct drm_nouveau_private *dev_priv;
785	uint32_t reg0;
786	resource_size_t mmio_start_offs;
787	int ret;
788
789	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
790	if (!dev_priv) {
791		ret = -ENOMEM;
792		goto err_out;
793	}
794	dev->dev_private = dev_priv;
795	dev_priv->dev = dev;
796
797	dev_priv->flags = flags & NOUVEAU_FLAGS;
798
799	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
800		 dev->pci_vendor, dev->pci_device, dev->pdev->class);
801
802	dev_priv->wq = create_workqueue("nouveau");
803	if (!dev_priv->wq) {
804		ret = -EINVAL;
805		goto err_priv;
806	}
807
808	/* resource 0 is mmio regs */
809	/* resource 1 is linear FB */
810	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
811	/* resource 6 is bios */
812
813	/* map the mmio regs */
814	mmio_start_offs = pci_resource_start(dev->pdev, 0);
815	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
816	if (!dev_priv->mmio) {
817		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
818			 "Please report your setup to " DRIVER_EMAIL "\n");
819		ret = -EINVAL;
820		goto err_wq;
821	}
822	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
823					(unsigned long long)mmio_start_offs);
824
825#ifdef __BIG_ENDIAN
826	/* Put the card in BE mode if it's not */
827	if (nv_rd32(dev, NV03_PMC_BOOT_1))
828		nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
829
830	DRM_MEMORYBARRIER();
831#endif
832
833	/* Time to determine the card architecture */
834	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
835
836	/* We're dealing with >=NV10 */
837	if ((reg0 & 0x0f000000) > 0) {
838		/* Bit 27-20 contain the architecture in hex */
839		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
840	/* NV04 or NV05 */
841	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
842		if (reg0 & 0x00f00000)
843			dev_priv->chipset = 0x05;
844		else
845			dev_priv->chipset = 0x04;
846	} else
847		dev_priv->chipset = 0xff;
848
849	switch (dev_priv->chipset & 0xf0) {
850	case 0x00:
851	case 0x10:
852	case 0x20:
853	case 0x30:
854		dev_priv->card_type = dev_priv->chipset & 0xf0;
855		break;
856	case 0x40:
857	case 0x60:
858		dev_priv->card_type = NV_40;
859		break;
860	case 0x50:
861	case 0x80:
862	case 0x90:
863	case 0xa0:
864		dev_priv->card_type = NV_50;
865		break;
866	case 0xc0:
867		dev_priv->card_type = NV_C0;
868		break;
869	default:
870		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
871		ret = -EINVAL;
872		goto err_mmio;
873	}
874
875	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
876		dev_priv->card_type, reg0);
877
878	ret = nouveau_remove_conflicting_drivers(dev);
879	if (ret)
880		goto err_mmio;
881
882	/* Map PRAMIN BAR, or on older cards, the aperture withing BAR0 */
883	if (dev_priv->card_type >= NV_40) {
884		int ramin_bar = 2;
885		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
886			ramin_bar = 3;
887
888		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
889		dev_priv->ramin =
890			ioremap(pci_resource_start(dev->pdev, ramin_bar),
891				dev_priv->ramin_size);
892		if (!dev_priv->ramin) {
893			NV_ERROR(dev, "Failed to PRAMIN BAR");
894			ret = -ENOMEM;
895			goto err_mmio;
896		}
897	} else {
898		dev_priv->ramin_size = 1 * 1024 * 1024;
899		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
900					  dev_priv->ramin_size);
901		if (!dev_priv->ramin) {
902			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
903			ret = -ENOMEM;
904			goto err_mmio;
905		}
906	}
907
908	nouveau_OF_copy_vbios_to_ramin(dev);
909
910	/* Special flags */
911	if (dev->pci_device == 0x01a0)
912		dev_priv->flags |= NV_NFORCE;
913	else if (dev->pci_device == 0x01f0)
914		dev_priv->flags |= NV_NFORCE2;
915
916	/* For kernel modesetting, init card now and bring up fbcon */
917	ret = nouveau_card_init(dev);
918	if (ret)
919		goto err_ramin;
920
921	return 0;
922
923err_ramin:
924	iounmap(dev_priv->ramin);
925err_mmio:
926	iounmap(dev_priv->mmio);
927err_wq:
928	destroy_workqueue(dev_priv->wq);
929err_priv:
930	kfree(dev_priv);
931	dev->dev_private = NULL;
932err_out:
933	return ret;
934}
935
936void nouveau_lastclose(struct drm_device *dev)
937{
938}
939
940int nouveau_unload(struct drm_device *dev)
941{
942	struct drm_nouveau_private *dev_priv = dev->dev_private;
943	struct nouveau_engine *engine = &dev_priv->engine;
944
945	drm_kms_helper_poll_fini(dev);
946	nouveau_fbcon_fini(dev);
947	engine->display.destroy(dev);
948	nouveau_card_takedown(dev);
949
950	iounmap(dev_priv->mmio);
951	iounmap(dev_priv->ramin);
952
953	kfree(dev_priv);
954	dev->dev_private = NULL;
955	return 0;
956}
957
958int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
959						struct drm_file *file_priv)
960{
961	struct drm_nouveau_private *dev_priv = dev->dev_private;
962	struct drm_nouveau_getparam *getparam = data;
963
964	switch (getparam->param) {
965	case NOUVEAU_GETPARAM_CHIPSET_ID:
966		getparam->value = dev_priv->chipset;
967		break;
968	case NOUVEAU_GETPARAM_PCI_VENDOR:
969		getparam->value = dev->pci_vendor;
970		break;
971	case NOUVEAU_GETPARAM_PCI_DEVICE:
972		getparam->value = dev->pci_device;
973		break;
974	case NOUVEAU_GETPARAM_BUS_TYPE:
975		if (drm_device_is_agp(dev))
976			getparam->value = NV_AGP;
977		else if (drm_device_is_pcie(dev))
978			getparam->value = NV_PCIE;
979		else
980			getparam->value = NV_PCI;
981		break;
982	case NOUVEAU_GETPARAM_FB_PHYSICAL:
983		getparam->value = dev_priv->fb_phys;
984		break;
985	case NOUVEAU_GETPARAM_AGP_PHYSICAL:
986		getparam->value = dev_priv->gart_info.aper_base;
987		break;
988	case NOUVEAU_GETPARAM_PCI_PHYSICAL:
989		if (dev->sg) {
990			getparam->value = (unsigned long)dev->sg->virtual;
991		} else {
992			NV_ERROR(dev, "Requested PCIGART address, "
993					"while no PCIGART was created\n");
994			return -EINVAL;
995		}
996		break;
997	case NOUVEAU_GETPARAM_FB_SIZE:
998		getparam->value = dev_priv->fb_available_size;
999		break;
1000	case NOUVEAU_GETPARAM_AGP_SIZE:
1001		getparam->value = dev_priv->gart_info.aper_size;
1002		break;
1003	case NOUVEAU_GETPARAM_VM_VRAM_BASE:
1004		getparam->value = dev_priv->vm_vram_base;
1005		break;
1006	case NOUVEAU_GETPARAM_PTIMER_TIME:
1007		getparam->value = dev_priv->engine.timer.read(dev);
1008		break;
1009	case NOUVEAU_GETPARAM_GRAPH_UNITS:
1010		/* NV40 and NV50 versions are quite different, but register
1011		 * address is the same. User is supposed to know the card
1012		 * family anyway... */
1013		if (dev_priv->chipset >= 0x40) {
1014			getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS);
1015			break;
1016		}
1017		/* FALLTHRU */
1018	default:
1019		NV_ERROR(dev, "unknown parameter %lld\n", getparam->param);
1020		return -EINVAL;
1021	}
1022
1023	return 0;
1024}
1025
1026int
1027nouveau_ioctl_setparam(struct drm_device *dev, void *data,
1028		       struct drm_file *file_priv)
1029{
1030	struct drm_nouveau_setparam *setparam = data;
1031
1032	switch (setparam->param) {
1033	default:
1034		NV_ERROR(dev, "unknown parameter %lld\n", setparam->param);
1035		return -EINVAL;
1036	}
1037
1038	return 0;
1039}
1040
1041/* Wait until (value(reg) & mask) == val, up until timeout has hit */
1042bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout,
1043			uint32_t reg, uint32_t mask, uint32_t val)
1044{
1045	struct drm_nouveau_private *dev_priv = dev->dev_private;
1046	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
1047	uint64_t start = ptimer->read(dev);
1048
1049	do {
1050		if ((nv_rd32(dev, reg) & mask) == val)
1051			return true;
1052	} while (ptimer->read(dev) - start < timeout);
1053
1054	return false;
1055}
1056
1057/* Waits for PGRAPH to go completely idle */
1058bool nouveau_wait_for_idle(struct drm_device *dev)
1059{
1060	if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) {
1061		NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n",
1062			 nv_rd32(dev, NV04_PGRAPH_STATUS));
1063		return false;
1064	}
1065
1066	return true;
1067}
1068