nouveau_state.c 39.9 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
	default:
		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
		return 1;
	}

487
488
489
490
491
492
493
494
495
	/* 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;
	}

496
497
498
499
500
501
	return 0;
}

static unsigned int
nouveau_vga_set_decode(void *priv, bool state)
{
502
503
504
505
506
507
508
509
	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);

510
511
512
513
514
515
516
	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;
}

517
518
519
static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
					 enum vga_switcheroo_state state)
{
520
	struct drm_device *dev = pci_get_drvdata(pdev);
521
522
523
	pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
	if (state == VGA_SWITCHEROO_ON) {
		printk(KERN_ERR "VGA switcheroo: switched nouveau on\n");
524
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
525
		nouveau_pci_resume(pdev);
526
		drm_kms_helper_poll_enable(dev);
527
		dev->switch_power_state = DRM_SWITCH_POWER_ON;
528
529
	} else {
		printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
530
		dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
531
		drm_kms_helper_poll_disable(dev);
532
		nouveau_switcheroo_optimus_dsm();
533
		nouveau_pci_suspend(pdev, pmm);
534
		dev->switch_power_state = DRM_SWITCH_POWER_OFF;
535
536
537
	}
}

538
539
540
541
542
543
static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	nouveau_fbcon_output_poll_changed(dev);
}

544
545
546
547
548
549
550
551
552
553
554
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;
}

555
556
557
558
559
int
nouveau_card_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine;
560
	int ret, e = 0;
561
562

	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
563
	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
564
				       nouveau_switcheroo_reprobe,
565
				       nouveau_switcheroo_can_switch);
566
567
568
569

	/* Initialise internal driver API hooks */
	ret = nouveau_init_engine_ptrs(dev);
	if (ret)
570
		goto out;
571
	engine = &dev_priv->engine;
572
	spin_lock_init(&dev_priv->channels.lock);
573
	spin_lock_init(&dev_priv->tile.lock);
574
	spin_lock_init(&dev_priv->context_switch_lock);
575
	spin_lock_init(&dev_priv->vm_lock);
576

577
578
579
580
581
	/* Make the CRTCs and I2C buses accessible */
	ret = engine->display.early_init(dev);
	if (ret)
		goto out;

582
	/* Parse BIOS tables / Run init tables if card not POSTed */
583
584
	ret = nouveau_bios_init(dev);
	if (ret)
585
		goto out_display_early;
586

587
588
589
590
591
592
593
594
	/* 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);
	}

595
596
597
598
599
600
601
602
603
604
605
606
607
608
	/* 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;
609

610
	ret = engine->vram.init(dev);
611
	if (ret)
612
		goto out_fb;
613

614
615
	/* PGPIO */
	ret = nouveau_gpio_create(dev);
616
	if (ret)
617
		goto out_vram;
618

619
620
621
622
	ret = nouveau_gpuobj_init(dev);
	if (ret)
		goto out_gpio;

623
624
	ret = engine->instmem.init(dev);
	if (ret)
625
		goto out_gpuobj;
626

627
	ret = nouveau_mem_vram_init(dev);
628
	if (ret)
629
		goto out_instmem;
630

631
632
633
634
	ret = nouveau_mem_gart_init(dev);
	if (ret)
		goto out_ttmvram;

635
	if (!dev_priv->noaccel) {
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
		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:
654
		case NV_D0:
655
656
657
658
659
			nvc0_graph_create(dev);
			break;
		default:
			break;
		}
660

661
		switch (dev_priv->chipset) {
662
663
664
665
666
667
668
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0xa0:
			nv84_crypt_create(dev);
669
			break;
670
671
672
673
674
		case 0x98:
		case 0xaa:
		case 0xac:
			nv98_crypt_create(dev);
			break;
675
676
		}

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
		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;
		}

696
697
698
699
700
701
702
703
704
705
706
707
708
		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
709
710
711
		if (dev_priv->card_type == NV_40 ||
		    dev_priv->chipset == 0x31 ||
		    dev_priv->chipset == 0x34 ||
712
		    dev_priv->chipset == 0x36) {
713
			nv31_mpeg_create(dev);
714
		}
715

716
717
718
719
720
721
722
723
		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;
			}
		}

724
725
726
		/* PFIFO */
		ret = engine->fifo.init(dev);
		if (ret)
727
			goto out_engine;
728
	}
729

730
731
732
733
	ret = nouveau_irq_init(dev);
	if (ret)
		goto out_fifo;

734
	ret = nouveau_display_create(dev);
735
	if (ret)
736
		goto out_irq;
737

738
	nouveau_backlight_init(dev);
739
	nouveau_pm_init(dev);
740

741
	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
742
		ret = nouveau_fence_init(dev);
743
		if (ret)
744
			goto out_pm;
745

746
747
		ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
					    NvDmaFB, NvDmaTT);
748
749
		if (ret)
			goto out_fence;
750
751
752
753
754

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

	if (dev->mode_config.num_crtc) {
755
		ret = nouveau_display_init(dev);
756
757
758
759
		if (ret)
			goto out_chan;

		nouveau_fbcon_init(dev);
760
761
762
	}

	return 0;
763

764
765
out_chan:
	nouveau_channel_put_unlocked(&dev_priv->channel);
766
767
out_fence:
	nouveau_fence_fini(dev);
768
769
out_pm:
	nouveau_pm_fini(dev);
770
	nouveau_backlight_exit(dev);
771
	nouveau_display_destroy(dev);
772
out_irq:
Ben Skeggs's avatar
Ben Skeggs committed
773
	nouveau_irq_fini(dev);
774
out_fifo:
775
	if (!dev_priv->noaccel)
776
		engine->fifo.takedown(dev);
777
out_engine:
778
	if (!dev_priv->noaccel) {
779
		for (e = e - 1; e >= 0; e--) {
780
781
			if (!dev_priv->eng[e])
				continue;
782
			dev_priv->eng[e]->fini(dev, e, false);
783
			dev_priv->eng[e]->destroy(dev,e );
784
785
		}
	}
786
	nouveau_mem_gart_fini(dev);
787
788
out_ttmvram:
	nouveau_mem_vram_fini(dev);
789
790
out_instmem:
	engine->instmem.takedown(dev);
791
792
out_gpuobj:
	nouveau_gpuobj_takedown(dev);
793
794
out_gpio:
	nouveau_gpio_destroy(dev);
795
out_vram:
796
	engine->vram.takedown(dev);
797
798
799
800
801
802
out_fb:
	engine->fb.takedown(dev);
out_timer:
	engine->timer.takedown(dev);
out_mc:
	engine->mc.takedown(dev);
803
804
out_bios:
	nouveau_bios_takedown(dev);
805
806
out_display_early:
	engine->display.late_takedown(dev);
807
808
809
out:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
	return ret;
810
811
812
813
814
815
}

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;
816
	int e;
817

818
819
	if (dev->mode_config.num_crtc) {
		nouveau_fbcon_fini(dev);
820
		nouveau_display_fini(dev);
821
	}
822

823
	if (dev_priv->channel) {
824
		nouveau_channel_put_unlocked(&dev_priv->channel);
825
		nouveau_fence_fini(dev);
826
	}
827

828
	nouveau_pm_fini(dev);
829
	nouveau_backlight_exit(dev);
830
	nouveau_display_destroy(dev);
831

832
	if (!dev_priv->noaccel) {
833
		engine->fifo.takedown(dev);
834
835
		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
			if (dev_priv->eng[e]) {
836
				dev_priv->eng[e]->fini(dev, e, false);
837
838
839
				dev_priv->eng[e]->destroy(dev,e );
			}
		}
840
	}
841

842
843
844
845
846
	if (dev_priv->vga_ram) {
		nouveau_bo_unpin(dev_priv->vga_ram);
		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
	}

847
848
849
850
	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);
851
	nouveau_mem_gart_fini(dev);
852
	nouveau_mem_vram_fini(dev);
853

854
	engine->instmem.takedown(dev);
855
	nouveau_gpuobj_takedown(dev);
856

857
858
859
860
861
862
	nouveau_gpio_destroy(dev);
	engine->vram.takedown(dev);
	engine->fb.takedown(dev);
	engine->timer.takedown(dev);
	engine->mc.takedown(dev);

863
	nouveau_bios_takedown(dev);
864
865
866
	engine->display.late_takedown(dev);

	nouveau_irq_fini(dev);
867

868
	vga_client_register(dev->pdev, NULL, NULL, NULL);
869
870
}

871
872
873
int
nouveau_open(struct drm_device *dev, struct drm_file *file_priv)
{
874
	struct drm_nouveau_private *dev_priv = dev->dev_private;
875
	struct nouveau_fpriv *fpriv;
876
	int ret;
877
878
879
880
881
882

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

	spin_lock_init(&fpriv->lock);
883
884
	INIT_LIST_HEAD(&fpriv->channels);

885
886
887
888
889
890
891
892
893
	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) {
894
895
896
897
898
899
		ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL,
				     &fpriv->vm);
		if (ret) {
			kfree(fpriv);
			return ret;
		}
900
	}
901

902
903
904
905
	file_priv->driver_priv = fpriv;
	return 0;
}

906
907
908
909
910
911
912
/* 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);
}

913
914
915
916
void
nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv)
{
	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
917
	nouveau_vm_ref(NULL, &fpriv->vm, NULL);
918
919
920
	kfree(fpriv);
}

921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
/* 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
}

951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
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;
980
	bool primary = false;
981
982
983
984
	dev_priv->apertures = nouveau_get_apertures(dev);
	if (!dev_priv->apertures)
		return -ENOMEM;

985
986
987
#ifdef CONFIG_X86
	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
#endif
988

989
	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
990
991
992
	return 0;
}

993
994
995
int nouveau_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_nouveau_private *dev_priv;
996
	uint32_t reg0, strap;
997
	resource_size_t mmio_start_offs;
998
	int ret;
999
1000

	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
1001
1002
1003
1004
	if (!dev_priv) {
		ret = -ENOMEM;
		goto err_out;
	}
1005
1006
1007
	dev->dev_private = dev_priv;
	dev_priv->dev = dev;

1008
1009
	pci_set_master(dev->pdev);

1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
	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);

	/* resource 0 is mmio regs */
	/* resource 1 is linear FB */
	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
	/* resource 6 is bios */

	/* map the mmio regs */
	mmio_start_offs = pci_resource_start(dev->pdev, 0);
	dev_priv->mmio = ioremap(mmio_start_offs, 0x00800000);
	if (!dev_priv->mmio) {
		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
			 "Please report your setup to " DRIVER_EMAIL "\n");
1026
		ret = -EINVAL;
1027
		goto err_priv;
1028
1029
1030
1031
1032
1033
	}
	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
					(unsigned long long)mmio_start_offs);

#ifdef __BIG_ENDIAN
	/* Put the card in BE mode if it's not */
1034
1035
	if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
		nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

	DRM_MEMORYBARRIER();
#endif

	/* Time to determine the card architecture */
	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);

	/* We're dealing with >=NV10 */
	if ((reg0 & 0x0f000000) > 0) {
		/* Bit 27-20 contain the architecture in hex */
		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
	/* NV04 or NV05 */
	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
1049
1050
1051
1052
		if (reg0 & 0x00f00000)
			dev_priv->chipset = 0x05;
		else
			dev_priv->chipset = 0x04;
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
	} else
		dev_priv->chipset = 0xff;

	switch (dev_priv->chipset & 0xf0) {
	case 0x00:
	case 0x10:
	case 0x20:
	case 0x30:
		dev_priv->card_type = dev_priv->chipset & 0xf0;
		break;
	case 0x40:
	case 0x60:
		dev_priv->card_type = NV_40;
		break;
	case 0x50:
	case 0x80:
	case 0x90:
	case 0xa0:
		dev_priv->card_type = NV_50;
		break;
1073
1074
1075
	case 0xc0:
		dev_priv->card_type = NV_C0;
		break;
1076
1077
1078
	case 0xd0:
		dev_priv->card_type = NV_D0;
		break;
1079
1080
	default:
		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
1081
1082
		ret = -EINVAL;
		goto err_mmio;
1083
1084
1085
1086
1087
	}

	NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
		dev_priv->card_type, reg0);

1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
	/* determine frequency of timing crystal */
	strap = nv_rd32(dev, 0x101000);
	if ( dev_priv->chipset < 0x17 ||
	    (dev_priv->chipset >= 0x20 && dev_priv->chipset <= 0x25))
		strap &= 0x00000040;
	else
		strap &= 0x00400040;

	switch (strap) {
	case 0x00000000: dev_priv->crystal = 13500; break;
	case 0x00000040: dev_priv->crystal = 14318; break;
	case 0x00400000: dev_priv->crystal = 27000; break;
	case 0x00400040: dev_priv->crystal = 25000; break;
	}

	NV_DEBUG(dev, "crystal freq: %dKHz\n", dev_priv->crystal);

1105
1106
1107
1108
1109
1110
1111
	/* Determine whether we'll attempt acceleration or not, some
	 * cards are disabled by default here due to them being known
	 * non-functional, or never been tested due to lack of hw.
	 */
	dev_priv->noaccel = !!nouveau_noaccel;
	if (nouveau_noaccel == -1) {
		switch (dev_priv->chipset) {
1112
		case 0xd9: /* known broken */
1113
1114
			NV_INFO(dev, "acceleration disabled by default, pass "
				     "noaccel=0 to force enable\n");
1115
1116
1117
1118
1119
1120
1121
1122
			dev_priv->noaccel = true;
			break;
		default:
			dev_priv->noaccel = false;
			break;
		}
	}

1123
1124
	ret = nouveau_remove_conflicting_drivers(dev);