nouveau_state.c 44 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * Copyright 2005 Stephane Marchesin
 * Copyright 2008 Stuart Bennett
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <linux/swab.h>
27
#include <linux/slab.h>
28
29
30
31
32
#include "drmP.h"
#include "drm.h"
#include "drm_sarea.h"
#include "drm_crtc_helper.h"
#include <linux/vgaarb.h>
33
#include <linux/vga_switcheroo.h>
34
35
36

#include "nouveau_drv.h"
#include "nouveau_drm.h"
37
#include "nouveau_fbcon.h"
38
#include "nouveau_ramht.h"
39
#include "nouveau_gpio.h"
40
#include "nouveau_pm.h"
41
42
43
#include "nv50_display.h"

static void nouveau_stub_takedown(struct drm_device *dev) {}
44
static int nouveau_stub_init(struct drm_device *dev) { return 0; }
45
46
47
48
49
50
51
52
53
54
55
56

static int nouveau_init_engine_ptrs(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;

	switch (dev_priv->chipset & 0xf0) {
	case 0x00:
		engine->instmem.init		= nv04_instmem_init;
		engine->instmem.takedown	= nv04_instmem_takedown;
		engine->instmem.suspend		= nv04_instmem_suspend;
		engine->instmem.resume		= nv04_instmem_resume;
57
58
59
60
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
61
		engine->instmem.flush		= nv04_instmem_flush;
62
63
64
65
66
67
68
69
70
		engine->mc.init			= nv04_mc_init;
		engine->mc.takedown		= nv04_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nv04_fb_init;
		engine->fb.takedown		= nv04_fb_takedown;
		engine->fifo.channels		= 16;
		engine->fifo.init		= nv04_fifo_init;
71
		engine->fifo.takedown		= nv04_fifo_fini;
72
73
74
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
75
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
76
77
78
79
80
		engine->fifo.channel_id		= nv04_fifo_channel_id;
		engine->fifo.create_context	= nv04_fifo_create_context;
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
		engine->fifo.load_context	= nv04_fifo_load_context;
		engine->fifo.unload_context	= nv04_fifo_unload_context;
81
82
83
84
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.destroy		= nv04_display_destroy;
85
86
		engine->display.init		= nv04_display_init;
		engine->display.fini		= nv04_display_fini;
87
88
89
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
90
		engine->vram.init		= nv04_fb_vram_init;
91
		engine->vram.takedown		= nouveau_stub_takedown;
92
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
93
94
95
96
97
98
		break;
	case 0x10:
		engine->instmem.init		= nv04_instmem_init;
		engine->instmem.takedown	= nv04_instmem_takedown;
		engine->instmem.suspend		= nv04_instmem_suspend;
		engine->instmem.resume		= nv04_instmem_resume;
99
100
101
102
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
103
		engine->instmem.flush		= nv04_instmem_flush;
104
105
106
107
108
109
110
		engine->mc.init			= nv04_mc_init;
		engine->mc.takedown		= nv04_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nv10_fb_init;
		engine->fb.takedown		= nv10_fb_takedown;
111
112
113
		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
114
115
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
116
		engine->fifo.takedown		= nv04_fifo_fini;
117
118
119
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
120
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
121
122
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
123
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
124
125
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
126
127
128
129
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.destroy		= nv04_display_destroy;
130
131
		engine->display.init		= nv04_display_init;
		engine->display.fini		= nv04_display_fini;
132
133
		engine->gpio.drive		= nv10_gpio_drive;
		engine->gpio.sense		= nv10_gpio_sense;
134
135
136
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
137
138
139
140
141
		if (dev_priv->chipset == 0x1a ||
		    dev_priv->chipset == 0x1f)
			engine->vram.init	= nv1a_fb_vram_init;
		else
			engine->vram.init	= nv10_fb_vram_init;
142
		engine->vram.takedown		= nouveau_stub_takedown;
143
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
144
145
146
147
148
149
		break;
	case 0x20:
		engine->instmem.init		= nv04_instmem_init;
		engine->instmem.takedown	= nv04_instmem_takedown;
		engine->instmem.suspend		= nv04_instmem_suspend;
		engine->instmem.resume		= nv04_instmem_resume;
150
151
152
153
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
154
		engine->instmem.flush		= nv04_instmem_flush;
155
156
157
158
159
		engine->mc.init			= nv04_mc_init;
		engine->mc.takedown		= nv04_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
160
161
162
163
164
		engine->fb.init			= nv20_fb_init;
		engine->fb.takedown		= nv20_fb_takedown;
		engine->fb.init_tile_region	= nv20_fb_init_tile_region;
		engine->fb.set_tile_region	= nv20_fb_set_tile_region;
		engine->fb.free_tile_region	= nv20_fb_free_tile_region;
165
166
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
167
		engine->fifo.takedown		= nv04_fifo_fini;
168
169
170
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
171
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
172
173
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
174
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
175
176
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
177
178
179
180
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.destroy		= nv04_display_destroy;
181
182
		engine->display.init		= nv04_display_init;
		engine->display.fini		= nv04_display_fini;
183
184
		engine->gpio.drive		= nv10_gpio_drive;
		engine->gpio.sense		= nv10_gpio_sense;
185
186
187
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
188
		engine->vram.init		= nv20_fb_vram_init;
189
		engine->vram.takedown		= nouveau_stub_takedown;
190
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
191
192
193
194
195
196
		break;
	case 0x30:
		engine->instmem.init		= nv04_instmem_init;
		engine->instmem.takedown	= nv04_instmem_takedown;
		engine->instmem.suspend		= nv04_instmem_suspend;
		engine->instmem.resume		= nv04_instmem_resume;
197
198
199
200
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
201
		engine->instmem.flush		= nv04_instmem_flush;
202
203
204
205
206
		engine->mc.init			= nv04_mc_init;
		engine->mc.takedown		= nv04_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
207
208
		engine->fb.init			= nv30_fb_init;
		engine->fb.takedown		= nv30_fb_takedown;
209
210
211
		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
212
213
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
214
		engine->fifo.takedown		= nv04_fifo_fini;
215
216
217
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
218
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
219
220
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
221
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
222
223
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
224
225
226
227
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.destroy		= nv04_display_destroy;
228
229
		engine->display.init		= nv04_display_init;
		engine->display.fini		= nv04_display_fini;
230
231
		engine->gpio.drive		= nv10_gpio_drive;
		engine->gpio.sense		= nv10_gpio_sense;
232
233
234
		engine->pm.clocks_get		= nv04_pm_clocks_get;
		engine->pm.clocks_pre		= nv04_pm_clocks_pre;
		engine->pm.clocks_set		= nv04_pm_clocks_set;
235
236
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
237
		engine->vram.init		= nv20_fb_vram_init;
238
		engine->vram.takedown		= nouveau_stub_takedown;
239
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
240
241
242
243
244
245
246
		break;
	case 0x40:
	case 0x60:
		engine->instmem.init		= nv04_instmem_init;
		engine->instmem.takedown	= nv04_instmem_takedown;
		engine->instmem.suspend		= nv04_instmem_suspend;
		engine->instmem.resume		= nv04_instmem_resume;
247
248
249
250
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
251
		engine->instmem.flush		= nv04_instmem_flush;
252
253
254
255
256
257
258
		engine->mc.init			= nv40_mc_init;
		engine->mc.takedown		= nv40_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nv40_fb_init;
		engine->fb.takedown		= nv40_fb_takedown;
259
260
261
		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
		engine->fb.set_tile_region	= nv40_fb_set_tile_region;
		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
262
263
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv40_fifo_init;
264
		engine->fifo.takedown		= nv04_fifo_fini;
265
266
267
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
268
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
269
270
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv40_fifo_create_context;
271
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
272
273
		engine->fifo.load_context	= nv40_fifo_load_context;
		engine->fifo.unload_context	= nv40_fifo_unload_context;
274
275
276
277
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.destroy		= nv04_display_destroy;
278
279
		engine->display.init		= nv04_display_init;
		engine->display.fini		= nv04_display_fini;
280
281
		engine->gpio.init		= nv10_gpio_init;
		engine->gpio.fini		= nv10_gpio_fini;
282
283
		engine->gpio.drive		= nv10_gpio_drive;
		engine->gpio.sense		= nv10_gpio_sense;
284
		engine->gpio.irq_enable		= nv10_gpio_irq_enable;
285
286
287
		engine->pm.clocks_get		= nv40_pm_clocks_get;
		engine->pm.clocks_pre		= nv40_pm_clocks_pre;
		engine->pm.clocks_set		= nv40_pm_clocks_set;
288
289
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
290
		engine->pm.temp_get		= nv40_temp_get;
291
292
		engine->pm.pwm_get		= nv40_pm_pwm_get;
		engine->pm.pwm_set		= nv40_pm_pwm_set;
293
		engine->vram.init		= nv40_fb_vram_init;
294
		engine->vram.takedown		= nouveau_stub_takedown;
295
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
296
297
298
299
		break;
	case 0x50:
	case 0x80: /* gotta love NVIDIA's consistency.. */
	case 0x90:
300
	case 0xa0:
301
302
303
304
		engine->instmem.init		= nv50_instmem_init;
		engine->instmem.takedown	= nv50_instmem_takedown;
		engine->instmem.suspend		= nv50_instmem_suspend;
		engine->instmem.resume		= nv50_instmem_resume;
305
306
307
308
		engine->instmem.get		= nv50_instmem_get;
		engine->instmem.put		= nv50_instmem_put;
		engine->instmem.map		= nv50_instmem_map;
		engine->instmem.unmap		= nv50_instmem_unmap;
309
310
311
312
		if (dev_priv->chipset == 0x50)
			engine->instmem.flush	= nv50_instmem_flush;
		else
			engine->instmem.flush	= nv84_instmem_flush;
313
314
315
316
317
		engine->mc.init			= nv50_mc_init;
		engine->mc.takedown		= nv50_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
318
319
		engine->fb.init			= nv50_fb_init;
		engine->fb.takedown		= nv50_fb_takedown;
320
321
322
323
324
325
326
327
328
329
330
		engine->fifo.channels		= 128;
		engine->fifo.init		= nv50_fifo_init;
		engine->fifo.takedown		= nv50_fifo_takedown;
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
		engine->fifo.channel_id		= nv50_fifo_channel_id;
		engine->fifo.create_context	= nv50_fifo_create_context;
		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
		engine->fifo.load_context	= nv50_fifo_load_context;
		engine->fifo.unload_context	= nv50_fifo_unload_context;
331
		engine->fifo.tlb_flush		= nv50_fifo_tlb_flush;
332
333
334
335
		engine->display.early_init	= nv50_display_early_init;
		engine->display.late_takedown	= nv50_display_late_takedown;
		engine->display.create		= nv50_display_create;
		engine->display.destroy		= nv50_display_destroy;
336
337
		engine->display.init		= nv50_display_init;
		engine->display.fini		= nv50_display_fini;
338
		engine->gpio.init		= nv50_gpio_init;
339
340
341
		engine->gpio.fini		= nv50_gpio_fini;
		engine->gpio.drive		= nv50_gpio_drive;
		engine->gpio.sense		= nv50_gpio_sense;
342
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
343
		switch (dev_priv->chipset) {
344
345
346
347
348
349
350
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0x98:
		case 0xa0:
351
352
		case 0xaa:
		case 0xac:
353
		case 0x50:
354
355
356
			engine->pm.clocks_get	= nv50_pm_clocks_get;
			engine->pm.clocks_pre	= nv50_pm_clocks_pre;
			engine->pm.clocks_set	= nv50_pm_clocks_set;
357
			break;
358
		default:
359
360
361
			engine->pm.clocks_get	= nva3_pm_clocks_get;
			engine->pm.clocks_pre	= nva3_pm_clocks_pre;
			engine->pm.clocks_set	= nva3_pm_clocks_set;
362
			break;
363
		}
364
365
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
366
367
368
369
		if (dev_priv->chipset >= 0x84)
			engine->pm.temp_get	= nv84_temp_get;
		else
			engine->pm.temp_get	= nv40_temp_get;
370
371
		engine->pm.pwm_get		= nv50_pm_pwm_get;
		engine->pm.pwm_set		= nv50_pm_pwm_set;
372
		engine->vram.init		= nv50_vram_init;
373
		engine->vram.takedown		= nv50_vram_fini;
374
375
376
		engine->vram.get		= nv50_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nv50_vram_flags_valid;
377
		break;
378
	case 0xc0:
379
380
381
382
		engine->instmem.init		= nvc0_instmem_init;
		engine->instmem.takedown	= nvc0_instmem_takedown;
		engine->instmem.suspend		= nvc0_instmem_suspend;
		engine->instmem.resume		= nvc0_instmem_resume;
383
384
385
386
387
		engine->instmem.get		= nv50_instmem_get;
		engine->instmem.put		= nv50_instmem_put;
		engine->instmem.map		= nv50_instmem_map;
		engine->instmem.unmap		= nv50_instmem_unmap;
		engine->instmem.flush		= nv84_instmem_flush;
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
		engine->mc.init			= nv50_mc_init;
		engine->mc.takedown		= nv50_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nvc0_fb_init;
		engine->fb.takedown		= nvc0_fb_takedown;
		engine->fifo.channels		= 128;
		engine->fifo.init		= nvc0_fifo_init;
		engine->fifo.takedown		= nvc0_fifo_takedown;
		engine->fifo.disable		= nvc0_fifo_disable;
		engine->fifo.enable		= nvc0_fifo_enable;
		engine->fifo.reassign		= nvc0_fifo_reassign;
		engine->fifo.channel_id		= nvc0_fifo_channel_id;
		engine->fifo.create_context	= nvc0_fifo_create_context;
		engine->fifo.destroy_context	= nvc0_fifo_destroy_context;
		engine->fifo.load_context	= nvc0_fifo_load_context;
		engine->fifo.unload_context	= nvc0_fifo_unload_context;
		engine->display.early_init	= nv50_display_early_init;
		engine->display.late_takedown	= nv50_display_late_takedown;
		engine->display.create		= nv50_display_create;
		engine->display.destroy		= nv50_display_destroy;
410
411
		engine->display.init		= nv50_display_init;
		engine->display.fini		= nv50_display_fini;
412
		engine->gpio.init		= nv50_gpio_init;
413
414
415
		engine->gpio.fini		= nv50_gpio_fini;
		engine->gpio.drive		= nv50_gpio_drive;
		engine->gpio.sense		= nv50_gpio_sense;
416
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
417
		engine->vram.init		= nvc0_vram_init;
418
		engine->vram.takedown		= nv50_vram_fini;
419
420
421
		engine->vram.get		= nvc0_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nvc0_vram_flags_valid;
422
		engine->pm.temp_get		= nv84_temp_get;
423
		engine->pm.clocks_get		= nvc0_pm_clocks_get;
424
425
		engine->pm.clocks_pre		= nvc0_pm_clocks_pre;
		engine->pm.clocks_set		= nvc0_pm_clocks_set;
Ben Skeggs's avatar
Ben Skeggs committed
426
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
427
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
428
429
		engine->pm.pwm_get		= nv50_pm_pwm_get;
		engine->pm.pwm_set		= nv50_pm_pwm_set;
430
		break;
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
	case 0xd0:
		engine->instmem.init		= nvc0_instmem_init;
		engine->instmem.takedown	= nvc0_instmem_takedown;
		engine->instmem.suspend		= nvc0_instmem_suspend;
		engine->instmem.resume		= nvc0_instmem_resume;
		engine->instmem.get		= nv50_instmem_get;
		engine->instmem.put		= nv50_instmem_put;
		engine->instmem.map		= nv50_instmem_map;
		engine->instmem.unmap		= nv50_instmem_unmap;
		engine->instmem.flush		= nv84_instmem_flush;
		engine->mc.init			= nv50_mc_init;
		engine->mc.takedown		= nv50_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nvc0_fb_init;
		engine->fb.takedown		= nvc0_fb_takedown;
		engine->fifo.channels		= 128;
		engine->fifo.init		= nvc0_fifo_init;
		engine->fifo.takedown		= nvc0_fifo_takedown;
		engine->fifo.disable		= nvc0_fifo_disable;
		engine->fifo.enable		= nvc0_fifo_enable;
		engine->fifo.reassign		= nvc0_fifo_reassign;
		engine->fifo.channel_id		= nvc0_fifo_channel_id;
		engine->fifo.create_context	= nvc0_fifo_create_context;
		engine->fifo.destroy_context	= nvc0_fifo_destroy_context;
		engine->fifo.load_context	= nvc0_fifo_load_context;
		engine->fifo.unload_context	= nvc0_fifo_unload_context;
		engine->display.early_init	= nouveau_stub_init;
		engine->display.late_takedown	= nouveau_stub_takedown;
461
462
		engine->display.create		= nvd0_display_create;
		engine->display.destroy		= nvd0_display_destroy;
463
464
		engine->display.init		= nvd0_display_init;
		engine->display.fini		= nvd0_display_fini;
465
		engine->gpio.init		= nv50_gpio_init;
466
467
468
		engine->gpio.fini		= nv50_gpio_fini;
		engine->gpio.drive		= nvd0_gpio_drive;
		engine->gpio.sense		= nvd0_gpio_sense;
469
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
470
471
472
473
474
		engine->vram.init		= nvc0_vram_init;
		engine->vram.takedown		= nv50_vram_fini;
		engine->vram.get		= nvc0_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nvc0_vram_flags_valid;
475
		engine->pm.temp_get		= nv84_temp_get;
476
		engine->pm.clocks_get		= nvc0_pm_clocks_get;
477
478
		engine->pm.clocks_pre		= nvc0_pm_clocks_pre;
		engine->pm.clocks_set		= nvc0_pm_clocks_set;
479
480
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
481
		break;
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
	case 0xe0:
		engine->instmem.init		= nvc0_instmem_init;
		engine->instmem.takedown	= nvc0_instmem_takedown;
		engine->instmem.suspend		= nvc0_instmem_suspend;
		engine->instmem.resume		= nvc0_instmem_resume;
		engine->instmem.get		= nv50_instmem_get;
		engine->instmem.put		= nv50_instmem_put;
		engine->instmem.map		= nv50_instmem_map;
		engine->instmem.unmap		= nv50_instmem_unmap;
		engine->instmem.flush		= nv84_instmem_flush;
		engine->mc.init			= nv50_mc_init;
		engine->mc.takedown		= nv50_mc_takedown;
		engine->timer.init		= nv04_timer_init;
		engine->timer.read		= nv04_timer_read;
		engine->timer.takedown		= nv04_timer_takedown;
		engine->fb.init			= nvc0_fb_init;
		engine->fb.takedown		= nvc0_fb_takedown;
499
500
501
		engine->fifo.channels		= 4096;
		engine->fifo.init		= nve0_fifo_init;
		engine->fifo.takedown		= nve0_fifo_takedown;
502
503
504
		engine->fifo.disable		= nvc0_fifo_disable;
		engine->fifo.enable		= nvc0_fifo_enable;
		engine->fifo.reassign		= nvc0_fifo_reassign;
505
506
507
508
509
		engine->fifo.channel_id		= nve0_fifo_channel_id;
		engine->fifo.create_context	= nve0_fifo_create_context;
		engine->fifo.destroy_context	= nve0_fifo_destroy_context;
		engine->fifo.load_context	= nvc0_fifo_load_context;
		engine->fifo.unload_context	= nve0_fifo_unload_context;
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
		engine->display.early_init	= nouveau_stub_init;
		engine->display.late_takedown	= nouveau_stub_takedown;
		engine->display.create		= nvd0_display_create;
		engine->display.destroy		= nvd0_display_destroy;
		engine->display.init		= nvd0_display_init;
		engine->display.fini		= nvd0_display_fini;
		engine->gpio.init		= nv50_gpio_init;
		engine->gpio.fini		= nv50_gpio_fini;
		engine->gpio.drive		= nvd0_gpio_drive;
		engine->gpio.sense		= nvd0_gpio_sense;
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
		engine->vram.init		= nvc0_vram_init;
		engine->vram.takedown		= nv50_vram_fini;
		engine->vram.get		= nvc0_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nvc0_vram_flags_valid;
		break;
527
528
529
530
531
	default:
		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
		return 1;
	}

532
533
534
535
536
537
538
539
540
	/* headless mode */
	if (nouveau_modeset == 2) {
		engine->display.early_init = nouveau_stub_init;
		engine->display.late_takedown = nouveau_stub_takedown;
		engine->display.create = nouveau_stub_init;
		engine->display.init = nouveau_stub_init;
		engine->display.destroy = nouveau_stub_takedown;
	}

541
542
543
544
545
546
	return 0;
}

static unsigned int
nouveau_vga_set_decode(void *priv, bool state)
{
547
548
549
550
551
552
553
554
	struct drm_device *dev = priv;
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->chipset >= 0x40)
		nv_wr32(dev, 0x88054, state);
	else
		nv_wr32(dev, 0x1854, state);

555
556
557
558
559
560
561
	if (state)
		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
	else
		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
}

562
563
564
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
					 enum vga_switcheroo_state state)
{
565
	struct drm_device *dev = pci_get_drvdata(pdev);
566
567
568
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	if (state == VGA_SWITCHEROO_ON) {
		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
569
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
570
		nouveau_pci_resume(pdev);
571
		drm_kms_helper_poll_enable(dev);
572
		dev->switch_power_state = DRM_SWITCH_POWER_ON;
573
574
	} else {
		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
575
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
576
		drm_kms_helper_poll_disable(dev);
577
		nouveau_switcheroo_optimus_dsm();
578
		nouveau_pci_suspend(pdev, pmm);
579
		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
580
581
582
	}
}

583
584
585
586
587
588
static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	nouveau_fbcon_output_poll_changed(dev);
}

589
590
591
592
593
594
595
596
597
598
599
static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	bool can_switch;

	spin_lock(&dev->count_lock);
	can_switch = (dev->open_count == 0);
	spin_unlock(&dev->count_lock);
	return can_switch;
}

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
static void
nouveau_card_channel_fini(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->channel)
		nouveau_channel_put_unlocked(&dev_priv->channel);
}

static int
nouveau_card_channel_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_channel *chan;
	int ret, oclass;

	ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT);
	dev_priv->channel = chan;
	if (ret)
		return ret;

	mutex_unlock(&dev_priv->channel->mutex);

	if (dev_priv->card_type <= NV_50) {
		if (dev_priv->card_type < NV_50)
			oclass = 0x0039;
		else
			oclass = 0x5039;

		ret = nouveau_gpuobj_gr_new(chan, NvM2MF, oclass);
		if (ret)
			goto error;

		ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000,
					     &chan->m2mf_ntfy);
		if (ret)
			goto error;

		ret = RING_SPACE(chan, 6);
		if (ret)
			goto error;

		BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1);
		OUT_RING  (chan, NvM2MF);
		BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
		OUT_RING  (chan, NvNotify0);
		OUT_RING  (chan, chan->vram_handle);
		OUT_RING  (chan, chan->gart_handle);
	} else
649
	if (dev_priv->card_type <= NV_D0) {
650
651
652
653
654
655
656
657
658
659
		ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039);
		if (ret)
			goto error;

		ret = RING_SPACE(chan, 2);
		if (ret)
			goto error;

		BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1);
		OUT_RING  (chan, 0x00009039);
660
661
662
663
664
665
666
667
668
669
670
671
672
673
	} else
	if (dev_priv->card_type <= NV_E0) {
		/* not used, but created to get a graph context */
		ret = nouveau_gpuobj_gr_new(chan, 0xa040, 0xa040);
		if (ret)
			goto error;

		/* bind strange copy engine to subchannel 4 (fixed...) */
		ret = RING_SPACE(chan, 2);
		if (ret)
			goto error;

		BEGIN_NVC0(chan, 2, NvSubCopy, 0x0000, 1);
		OUT_RING  (chan, 0x0000a0b5);
674
675
676
677
678
679
680
681
682
	}

	FIRE_RING (chan);
error:
	if (ret)
		nouveau_card_channel_fini(dev);
	return ret;
}

683
684
685
686
687
688
static const struct vga_switcheroo_client_ops nouveau_switcheroo_ops = {
	.set_gpu_state = nouveau_switcheroo_set_state,
	.reprobe = nouveau_switcheroo_reprobe,
	.can_switch = nouveau_switcheroo_can_switch,
};

689
690
691
692
693
int
nouveau_card_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine;
694
	int ret, e = 0;
695
696

	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
697
	vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops);
698
699
700
701

	/* Initialise internal driver API hooks */
	ret = nouveau_init_engine_ptrs(dev);
	if (ret)
702
		goto out;
703
	engine = &dev_priv->engine;
704
	spin_lock_init(&dev_priv->channels.lock);
705
	spin_lock_init(&dev_priv->tile.lock);
706
	spin_lock_init(&dev_priv->context_switch_lock);
707
	spin_lock_init(&dev_priv->vm_lock);
708

709
710
711
712
713
	/* Make the CRTCs and I2C buses accessible */
	ret = engine->display.early_init(dev);
	if (ret)
		goto out;

714
	/* Parse BIOS tables / Run init tables if card not POSTed */
715
716
	ret = nouveau_bios_init(dev);
	if (ret)
717
		goto out_display_early;
718

719
720
721
722
723
724
725
726
	/* workaround an odd issue on nvc1 by disabling the device's
	 * nosnoop capability.  hopefully won't cause issues until a
	 * better fix is found - assuming there is one...
	 */
	if (dev_priv->chipset == 0xc1) {
		nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
	}

727
728
729
730
731
732
733
734
735
736
737
738
739
740
	/* PMC */
	ret = engine->mc.init(dev);
	if (ret)
		goto out_bios;

	/* PTIMER */
	ret = engine->timer.init(dev);
	if (ret)
		goto out_mc;

	/* PFB */
	ret = engine->fb.init(dev);
	if (ret)
		goto out_timer;
741

742
	ret = engine->vram.init(dev);
743
	if (ret)
744
		goto out_fb;
745

746
747
	/* PGPIO */
	ret = nouveau_gpio_create(dev);
748
	if (ret)
749
		goto out_vram;
750

751
752
753
754
	ret = nouveau_gpuobj_init(dev);
	if (ret)
		goto out_gpio;

755
756
	ret = engine->instmem.init(dev);
	if (ret)
757
		goto out_gpuobj;
758

759
	ret = nouveau_mem_vram_init(dev);
760
	if (ret)
761
		goto out_instmem;
762

763
764
765
766
	ret = nouveau_mem_gart_init(dev);
	if (ret)
		goto out_ttmvram;

767
	if (!dev_priv->noaccel) {
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
		switch (dev_priv->card_type) {
		case NV_04:
			nv04_graph_create(dev);
			break;
		case NV_10:
			nv10_graph_create(dev);
			break;
		case NV_20:
		case NV_30:
			nv20_graph_create(dev);
			break;
		case NV_40:
			nv40_graph_create(dev);
			break;
		case NV_50:
			nv50_graph_create(dev);
			break;
		case NV_C0:
786
		case NV_D0:
787
788
			nvc0_graph_create(dev);
			break;
789
790
791
		case NV_E0:
			nve0_graph_create(dev);
			break;
792
793
794
		default:
			break;
		}
795

796
		switch (dev_priv->chipset) {
797
798
799
800
801
802
803
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0xa0:
			nv84_crypt_create(dev);
804
			break;
805
806
807
808
809
		case 0x98:
		case 0xaa:
		case 0xac:
			nv98_crypt_create(dev);
			break;
810
811
		}

812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
		switch (dev_priv->card_type) {
		case NV_50:
			switch (dev_priv->chipset) {
			case 0xa3:
			case 0xa5:
			case 0xa8:
			case 0xaf:
				nva3_copy_create(dev);
				break;
			}
			break;
		case NV_C0:
			nvc0_copy_create(dev, 0);
			nvc0_copy_create(dev, 1);
			break;
		default:
			break;
		}

831
832
833
834
835
836
837
838
839
840
841
842
843
		if (dev_priv->chipset >= 0xa3 || dev_priv->chipset == 0x98) {
			nv84_bsp_create(dev);
			nv84_vp_create(dev);
			nv98_ppp_create(dev);
		} else
		if (dev_priv->chipset >= 0x84) {
			nv50_mpeg_create(dev);
			nv84_bsp_create(dev);
			nv84_vp_create(dev);
		} else
		if (dev_priv->chipset >= 0x50) {
			nv50_mpeg_create(dev);
		} else
844
845
846
		if (dev_priv->card_type == NV_40 ||
		    dev_priv->chipset == 0x31 ||
		    dev_priv->chipset == 0x34 ||
847
		    dev_priv->chipset == 0x36) {
848
			nv31_mpeg_create(dev);
849
		}
850

851
852
853
854
855
856
857
858
		for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
			if (dev_priv->eng[e]) {
				ret = dev_priv->eng[e]->init(dev, e);
				if (ret)
					goto out_engine;
			}
		}

859
860
861
		/* PFIFO */
		ret = engine->fifo.init(dev);
		if (ret)
862
			goto out_engine;
863
	}
864

865
866
867
868
	ret = nouveau_irq_init(dev);
	if (ret)
		goto out_fifo;

869
	ret = nouveau_display_create(dev);
870
	if (ret)
871
		goto out_irq;
872

873
	nouveau_backlight_init(dev);
874
	nouveau_pm_init(dev);
875

876
877
878
	ret = nouveau_fence_init(dev);
	if (ret)
		goto out_pm;
879

880
	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
881
		ret = nouveau_card_channel_init(dev);
882
883
		if (ret)
			goto out_fence;
884
885
886
	}

	if (dev->mode_config.num_crtc) {
887
		ret = nouveau_display_init(dev);
888
889
890
891
		if (ret)
			goto out_chan;

		nouveau_fbcon_init(dev);
892
893
894
	}

	return 0;
895

896
out_chan:
897
	nouveau_card_channel_fini(dev);
898
899
out_fence:
	nouveau_fence_fini(dev);
900
901
out_pm:
	nouveau_pm_fini(dev);
902
	nouveau_backlight_exit(dev);
903
	nouveau_display_destroy(dev);
904
out_irq:
Ben Skeggs's avatar
Ben Skeggs committed
905
	nouveau_irq_fini(dev);
906
out_fifo:
907
	if (!dev_priv->noaccel)
908
		engine->fifo.takedown(dev);
909
out_engine:
910
	if (!dev_priv->noaccel) {
911
		for (e = e - 1; e >= 0; e--) {
912
913
			if (!dev_priv->eng[e])
				continue;
914
			dev_priv->eng[e]->fini(dev, e, false);
915
			dev_priv->eng[e]->destroy(dev,e );
916
917
		}
	}
918
	nouveau_mem_gart_fini(dev);
919
920
out_ttmvram:
	nouveau_mem_vram_fini(dev);
921
922
out_instmem:
	engine->instmem.takedown(dev);
923
924
out_gpuobj:
	nouveau_gpuobj_takedown(dev);
925
926
out_gpio:
	nouveau_gpio_destroy(dev);
927
out_vram:
928
	engine->vram.takedown(dev);
929
930
931
932
933
934
out_fb:
	engine->fb.takedown(dev);
out_timer:
	engine->timer.takedown(dev);
out_mc:
	engine->mc.takedown(dev);
935
936
out_bios:
	nouveau_bios_takedown(dev);
937
938
out_display_early:
	engine->display.late_takedown(dev);
939
940
941
out:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
	return ret;
942
943
944
945
946
947
}

static void nouveau_card_takedown(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
948
	int e;
949

950
951
	if (dev->mode_config.num_crtc) {
		nouveau_fbcon_fini(dev);
952
		nouveau_display_fini(dev);
953
	}
954

955
956
	nouveau_card_channel_fini(dev);
	nouveau_fence_fini(dev);
957
	nouveau_pm_fini(dev);
958
	nouveau_backlight_exit(dev);
959
	nouveau_display_destroy(dev);
960

961
	if (!dev_priv->noaccel) {
962
		engine->fifo.takedown(dev);
963
964
		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
			if (dev_priv->eng[e]) {
965
				dev_priv->eng[e]->fini(dev, e, false);
966
967
968
				dev_priv->eng[e]->destroy(dev,e );
			}
		}
969
	}
970

971
972
973
974
975
	if (dev_priv->vga_ram) {
		nouveau_bo_unpin(dev_priv->vga_ram);
		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
	}

976
977
978
979
	mutex_lock(&dev->struct_mutex);
	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
	mutex_unlock(&dev->struct_mutex);
980
	nouveau_mem_gart_fini(dev);
981
	nouveau_mem_vram_fini(dev);
982

983
	engine->instmem.takedown(dev);
984
	nouveau_gpuobj_takedown(dev);
985

986
987
988
989
990
991
	nouveau_gpio_destroy(dev);
	engine->vram.takedown(dev);
	engine->fb.takedown(dev);
	engine->timer.takedown(dev);
	engine->mc.takedown(dev);

992
	nouveau_bios_takedown(dev);
993
994
995
	engine->display.late_takedown(dev);

	nouveau_irq_fini(dev);
996

997
	vga_client_register(dev->pdev, NULL, NULL, NULL);
998
999
}

1000
1001
1002
int
nouveau_open(struct drm_device *dev, struct drm_file *file_priv)
{
1003
	struct drm_nouveau_private *dev_priv = dev->dev_private;
1004
	struct nouveau_fpriv *fpriv;
1005
	int ret;
1006
1007
1008
1009
1010
1011

	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
	if (unlikely(!fpriv))
		return -ENOMEM;

	spin_lock_init(&fpriv->lock);
1012
1013
	INIT_LIST_HEAD(&fpriv->channels);

1014
1015
1016
1017
1018
1019
1020
1021
1022
	if (dev_priv->card_type == NV_50) {
		ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL,
				     &fpriv->vm);
		if (ret) {
			kfree(fpriv);
			return ret;
		}
	} else
	if (dev_priv->card_type >= NV_C0) {
1023
1024
1025
1026
1027
1028
		ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL,
				     &fpriv->vm);
		if (ret) {
			kfree(fpriv);
			return ret;
		}
1029
	}
1030

1031
1032
1033
1034
	file_priv->driver_priv = fpriv;
	return 0;
}

1035
1036
1037
1038
1039
1040
1041
/* here a client dies, release the stuff that was allocated for its
 * file_priv */
void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
{
	nouveau_channel_cleanup(dev, file_priv);
}

1042
1043
1044
1045
void
nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv)
{
	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
1046
	nouveau_vm_ref(NULL, &fpriv->vm, NULL);
1047
1048
1049
	kfree(fpriv);
}

1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
/* first module load, setup the mmio/fb mapping */
/* KMS: we need mmio at load time, not when the first drm client opens. */
int nouveau_firstopen(struct drm_device *dev)
{
	return 0;
}

/* if we have an OF card, copy vbios to RAMIN */
static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
{
#if defined(__powerpc__)
	int size, i;
	const uint32_t *bios;
	struct device_node *dn = pci_device_to_OF_node(dev->pdev);
	if (!dn) {
		NV_INFO(dev, "Unable to get the OF node\n");
		return;
	}

	bios = of_get_property(dn, "NVDA,BMP", &size);
	if (bios) {
		for (i = 0; i < size; i += 4)
			nv_wi32(dev, i, bios[i/4]);
		NV_INFO(dev, "OF bios successfully copied (%d bytes)\n", size);
	} else {
		NV_INFO(dev, "Unable to get the OF bios\n");
	}
#endif
}

1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
{
	struct pci_dev *pdev = dev->pdev;
	struct apertures_struct *aper = alloc_apertures(3);
	if (!aper)
		return NULL;

	aper->ranges[0].base = pci_resource_start(pdev, 1);
	aper->ranges[0].size = pci_resource_len(pdev, 1);
	aper->count = 1;

	if (pci_resource_len(pdev, 2)) {
		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
		aper->count++;
	}

	if (pci_resource_len(pdev, 3)) {
		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
		aper->count++;
	}

	return aper;
}

static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
1109
	bool primary = false;
1110
1111
1112
1113
	dev_priv->apertures = nouveau_get_apertures(dev);
	if (!dev_priv->apertures)
		return -ENOMEM;

1114
1115
1116
#ifdef CONFIG_X86
	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
#endif
1117

1118
	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
1119
1120
1121
	return 0;
}

1122
1123
1124
int nouveau_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_nouveau_private *dev_priv;
1125
	unsigned long long offset, length;
1126
	uint32_t reg0 = ~0, strap;
1127
	int ret;
1128
1129

	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
1130
1131
1132
1133
	if (!dev_priv) {
		ret = -ENOMEM;
		goto err_out;
	}
1134
1135
1136
	dev->dev_private = dev_priv;
	dev_priv->dev = dev;

1137
1138
	pci_set_master(dev->pdev);

1139
1140
1141
1142
1143
	dev_priv->flags = flags & NOUVEAU_FLAGS;

	NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
		 dev->pci_vendor, dev->pci_device, dev->pdev->class);

1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172