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_pm.h"
40
41
42
#include "nv50_display.h"

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

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;
56
57
58
59
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
60
		engine->instmem.flush		= nv04_instmem_flush;
61
62
63
64
65
66
67
68
69
		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;
70
		engine->fifo.takedown		= nv04_fifo_fini;
71
72
73
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
74
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
75
76
77
78
79
		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;
80
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.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
85
86
87
88
89
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= NULL;
		engine->gpio.set		= NULL;
		engine->gpio.irq_enable		= NULL;
90
91
92
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
93
		engine->vram.init		= nouveau_mem_detect;
94
		engine->vram.takedown		= nouveau_stub_takedown;
95
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
96
97
98
99
100
101
		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;
102
103
104
105
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
106
		engine->instmem.flush		= nv04_instmem_flush;
107
108
109
110
111
112
113
		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;
114
115
116
		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;
117
118
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
119
		engine->fifo.takedown		= nv04_fifo_fini;
120
121
122
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
123
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
124
125
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
126
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
127
128
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
129
130
131
132
133
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
134
135
136
137
138
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
139
140
141
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
142
		engine->vram.init		= nouveau_mem_detect;
143
		engine->vram.takedown		= nouveau_stub_takedown;
144
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
145
146
147
148
149
150
		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;
151
152
153
154
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
155
		engine->instmem.flush		= nv04_instmem_flush;
156
157
158
159
160
161
162
		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;
163
164
165
		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;
166
167
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
168
		engine->fifo.takedown		= nv04_fifo_fini;
169
170
171
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
172
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
173
174
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
175
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
176
177
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
178
179
180
181
182
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
183
184
185
186
187
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
188
189
190
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
191
		engine->vram.init		= nouveau_mem_detect;
192
		engine->vram.takedown		= nouveau_stub_takedown;
193
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
194
195
196
197
198
199
		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;
200
201
202
203
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
204
		engine->instmem.flush		= nv04_instmem_flush;
205
206
207
208
209
		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;
210
211
		engine->fb.init			= nv30_fb_init;
		engine->fb.takedown		= nv30_fb_takedown;
212
213
214
		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;
215
216
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv10_fifo_init;
217
		engine->fifo.takedown		= nv04_fifo_fini;
218
219
220
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
221
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
222
223
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv10_fifo_create_context;
224
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
225
226
		engine->fifo.load_context	= nv10_fifo_load_context;
		engine->fifo.unload_context	= nv10_fifo_unload_context;
227
228
229
230
231
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
232
233
234
235
236
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
237
238
239
240
241
		engine->pm.clock_get		= nv04_pm_clock_get;
		engine->pm.clock_pre		= nv04_pm_clock_pre;
		engine->pm.clock_set		= nv04_pm_clock_set;
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
242
		engine->vram.init		= nouveau_mem_detect;
243
		engine->vram.takedown		= nouveau_stub_takedown;
244
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
245
246
247
248
249
250
251
		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;
252
253
254
255
		engine->instmem.get		= nv04_instmem_get;
		engine->instmem.put		= nv04_instmem_put;
		engine->instmem.map		= nv04_instmem_map;
		engine->instmem.unmap		= nv04_instmem_unmap;
256
		engine->instmem.flush		= nv04_instmem_flush;
257
258
259
260
261
262
263
		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;
264
265
266
		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;
267
268
		engine->fifo.channels		= 32;
		engine->fifo.init		= nv40_fifo_init;
269
		engine->fifo.takedown		= nv04_fifo_fini;
270
271
272
		engine->fifo.disable		= nv04_fifo_disable;
		engine->fifo.enable		= nv04_fifo_enable;
		engine->fifo.reassign		= nv04_fifo_reassign;
273
		engine->fifo.cache_pull		= nv04_fifo_cache_pull;
274
275
		engine->fifo.channel_id		= nv10_fifo_channel_id;
		engine->fifo.create_context	= nv40_fifo_create_context;
276
		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
277
278
		engine->fifo.load_context	= nv40_fifo_load_context;
		engine->fifo.unload_context	= nv40_fifo_unload_context;
279
280
281
282
283
		engine->display.early_init	= nv04_display_early_init;
		engine->display.late_takedown	= nv04_display_late_takedown;
		engine->display.create		= nv04_display_create;
		engine->display.init		= nv04_display_init;
		engine->display.destroy		= nv04_display_destroy;
284
285
286
287
288
		engine->gpio.init		= nouveau_stub_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv10_gpio_get;
		engine->gpio.set		= nv10_gpio_set;
		engine->gpio.irq_enable		= NULL;
289
290
291
		engine->pm.clocks_get		= nv40_pm_clocks_get;
		engine->pm.clocks_pre		= nv40_pm_clocks_pre;
		engine->pm.clocks_set		= nv40_pm_clocks_set;
292
293
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
294
		engine->pm.temp_get		= nv40_temp_get;
295
		engine->vram.init		= nouveau_mem_detect;
296
		engine->vram.takedown		= nouveau_stub_takedown;
297
		engine->vram.flags_valid	= nouveau_mem_flags_valid;
298
299
300
301
		break;
	case 0x50:
	case 0x80: /* gotta love NVIDIA's consistency.. */
	case 0x90:
302
	case 0xa0:
303
304
305
306
		engine->instmem.init		= nv50_instmem_init;
		engine->instmem.takedown	= nv50_instmem_takedown;
		engine->instmem.suspend		= nv50_instmem_suspend;
		engine->instmem.resume		= nv50_instmem_resume;
307
308
309
310
		engine->instmem.get		= nv50_instmem_get;
		engine->instmem.put		= nv50_instmem_put;
		engine->instmem.map		= nv50_instmem_map;
		engine->instmem.unmap		= nv50_instmem_unmap;
311
312
313
314
		if (dev_priv->chipset == 0x50)
			engine->instmem.flush	= nv50_instmem_flush;
		else
			engine->instmem.flush	= nv84_instmem_flush;
315
316
317
318
319
		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;
320
321
		engine->fb.init			= nv50_fb_init;
		engine->fb.takedown		= nv50_fb_takedown;
322
323
324
325
326
327
328
329
330
331
332
		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;
333
		engine->fifo.tlb_flush		= nv50_fifo_tlb_flush;
334
335
336
337
338
		engine->display.early_init	= nv50_display_early_init;
		engine->display.late_takedown	= nv50_display_late_takedown;
		engine->display.create		= nv50_display_create;
		engine->display.init		= nv50_display_init;
		engine->display.destroy		= nv50_display_destroy;
339
		engine->gpio.init		= nv50_gpio_init;
340
		engine->gpio.takedown		= nv50_gpio_fini;
341
342
		engine->gpio.get		= nv50_gpio_get;
		engine->gpio.set		= nv50_gpio_set;
343
344
		engine->gpio.irq_register	= nv50_gpio_irq_register;
		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
345
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
346
		switch (dev_priv->chipset) {
347
348
349
350
351
352
353
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0x98:
		case 0xa0:
354
355
		case 0xaa:
		case 0xac:
356
		case 0x50:
357
358
359
360
			engine->pm.clock_get	= nv50_pm_clock_get;
			engine->pm.clock_pre	= nv50_pm_clock_pre;
			engine->pm.clock_set	= nv50_pm_clock_set;
			break;
361
		default:
362
363
364
			engine->pm.clocks_get	= nva3_pm_clocks_get;
			engine->pm.clocks_pre	= nva3_pm_clocks_pre;
			engine->pm.clocks_set	= nva3_pm_clocks_set;
365
			break;
366
		}
367
368
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
369
370
371
372
		if (dev_priv->chipset >= 0x84)
			engine->pm.temp_get	= nv84_temp_get;
		else
			engine->pm.temp_get	= nv40_temp_get;
373
		engine->vram.init		= nv50_vram_init;
374
		engine->vram.takedown		= nv50_vram_fini;
375
376
377
		engine->vram.get		= nv50_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nv50_vram_flags_valid;
378
		break;
379
	case 0xc0:
380
381
382
383
		engine->instmem.init		= nvc0_instmem_init;
		engine->instmem.takedown	= nvc0_instmem_takedown;
		engine->instmem.suspend		= nvc0_instmem_suspend;
		engine->instmem.resume		= nvc0_instmem_resume;
384
385
386
387
388
		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;
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
		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.init		= nv50_display_init;
		engine->display.destroy		= nv50_display_destroy;
		engine->gpio.init		= nv50_gpio_init;
		engine->gpio.takedown		= nouveau_stub_takedown;
		engine->gpio.get		= nv50_gpio_get;
		engine->gpio.set		= nv50_gpio_set;
416
417
		engine->gpio.irq_register	= nv50_gpio_irq_register;
		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
418
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
419
		engine->vram.init		= nvc0_vram_init;
420
		engine->vram.takedown		= nv50_vram_fini;
421
422
423
		engine->vram.get		= nvc0_vram_new;
		engine->vram.put		= nv50_vram_del;
		engine->vram.flags_valid	= nvc0_vram_flags_valid;
424
		engine->pm.temp_get		= nv84_temp_get;
425
		engine->pm.clocks_get		= nvc0_pm_clocks_get;
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
		break;
429
430
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
	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;
459
460
461
		engine->display.create		= nvd0_display_create;
		engine->display.init		= nvd0_display_init;
		engine->display.destroy		= nvd0_display_destroy;
462
		engine->gpio.init		= nv50_gpio_init;
463
		engine->gpio.takedown		= nouveau_stub_takedown;
464
465
466
467
468
		engine->gpio.get		= nvd0_gpio_get;
		engine->gpio.set		= nvd0_gpio_set;
		engine->gpio.irq_register	= nv50_gpio_irq_register;
		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
469
470
471
472
473
		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;
474
475
476
		engine->pm.clocks_get		= nvc0_pm_clocks_get;
		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
477
		break;
478
479
480
481
482
	default:
		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
		return 1;
	}

483
484
485
486
487
488
489
490
491
	/* 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;
	}

492
493
494
495
496
497
	return 0;
}

static unsigned int
nouveau_vga_set_decode(void *priv, bool state)
{
498
499
500
501
502
503
504
505
	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);

506
507
508
509
510
511
512
	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;
}

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

533
534
535
536
537
538
static void nouveau_switcheroo_reprobe(struct pci_dev *pdev)
{
	struct drm_device *dev = pci_get_drvdata(pdev);
	nouveau_fbcon_output_poll_changed(dev);
}

539
540
541
542
543
544
545
546
547
548
549
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;
}

550
551
552
553
554
int
nouveau_card_init(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine;
555
	int ret, e = 0;
556
557

	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
558
	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
559
				       nouveau_switcheroo_reprobe,
560
				       nouveau_switcheroo_can_switch);
561
562
563
564

	/* Initialise internal driver API hooks */
	ret = nouveau_init_engine_ptrs(dev);
	if (ret)
565
		goto out;
566
	engine = &dev_priv->engine;
567
	spin_lock_init(&dev_priv->channels.lock);
568
	spin_lock_init(&dev_priv->tile.lock);
569
	spin_lock_init(&dev_priv->context_switch_lock);
570
	spin_lock_init(&dev_priv->vm_lock);
571

572
573
574
575
576
	/* Make the CRTCs and I2C buses accessible */
	ret = engine->display.early_init(dev);
	if (ret)
		goto out;

577
	/* Parse BIOS tables / Run init tables if card not POSTed */
578
579
	ret = nouveau_bios_init(dev);
	if (ret)
580
		goto out_display_early;
581

582
583
	nouveau_pm_init(dev);

584
	ret = engine->vram.init(dev);
585
586
587
	if (ret)
		goto out_bios;

588
	ret = nouveau_gpuobj_init(dev);
589
	if (ret)
590
		goto out_vram;
591
592
593

	ret = engine->instmem.init(dev);
	if (ret)
594
		goto out_gpuobj;
595

596
	ret = nouveau_mem_vram_init(dev);
597
	if (ret)
598
		goto out_instmem;
599

600
601
602
603
	ret = nouveau_mem_gart_init(dev);
	if (ret)
		goto out_ttmvram;

604
605
606
	/* PMC */
	ret = engine->mc.init(dev);
	if (ret)
607
		goto out_gart;
608

609
610
611
612
613
	/* PGPIO */
	ret = engine->gpio.init(dev);
	if (ret)
		goto out_mc;

614
615
616
	/* PTIMER */
	ret = engine->timer.init(dev);
	if (ret)
617
		goto out_gpio;
618
619
620
621

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

624
	if (!dev_priv->noaccel) {
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
		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:
			nvc0_graph_create(dev);
			break;
		default:
			break;
		}
648

649
		switch (dev_priv->chipset) {
650
651
652
653
654
655
656
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0xa0:
			nv84_crypt_create(dev);
657
658
659
			break;
		}

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
		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;
		}

679
680
681
682
		if (dev_priv->card_type == NV_40 ||
		    dev_priv->chipset == 0x31 ||
		    dev_priv->chipset == 0x34 ||
		    dev_priv->chipset == 0x36)
683
			nv31_mpeg_create(dev);
684
685
686
687
		else
		if (dev_priv->card_type == NV_50 &&
		    (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
			nv50_mpeg_create(dev);
688

689
690
691
692
693
694
695
696
		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;
			}
		}

697
698
699
		/* PFIFO */
		ret = engine->fifo.init(dev);
		if (ret)
700
			goto out_engine;
701
	}
702

703
704
705
706
	ret = nouveau_irq_init(dev);
	if (ret)
		goto out_fifo;

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
	/* initialise general modesetting */
	drm_mode_config_init(dev);
	drm_mode_create_scaling_mode_property(dev);
	drm_mode_create_dithering_property(dev);
	dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
	dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);
	dev->mode_config.min_width = 0;
	dev->mode_config.min_height = 0;
	if (dev_priv->card_type < NV_10) {
		dev->mode_config.max_width = 2048;
		dev->mode_config.max_height = 2048;
	} else
	if (dev_priv->card_type < NV_50) {
		dev->mode_config.max_width = 4096;
		dev->mode_config.max_height = 4096;
	} else {
		dev->mode_config.max_width = 8192;
		dev->mode_config.max_height = 8192;
	}

727
	ret = engine->display.create(dev);
728
	if (ret)
729
		goto out_irq;
730

731
732
	nouveau_backlight_init(dev);

733
	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
734
		ret = nouveau_fence_init(dev);
735
		if (ret)
736
			goto out_disp;
737

738
739
		ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
					    NvDmaFB, NvDmaTT);
740
741
		if (ret)
			goto out_fence;
742
743
744
745
746
747
748
749
750
751
752

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

	if (dev->mode_config.num_crtc) {
		ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
		if (ret)
			goto out_chan;

		nouveau_fbcon_init(dev);
		drm_kms_helper_poll_init(dev);
753
754
755
	}

	return 0;
756

757
758
out_chan:
	nouveau_channel_put_unlocked(&dev_priv->channel);
759
760
out_fence:
	nouveau_fence_fini(dev);
761
out_disp:
762
	nouveau_backlight_exit(dev);
763
	engine->display.destroy(dev);
764
out_irq:
Ben Skeggs's avatar
Ben Skeggs committed
765
	nouveau_irq_fini(dev);
766
out_fifo:
767
	if (!dev_priv->noaccel)
768
		engine->fifo.takedown(dev);
769
out_engine:
770
	if (!dev_priv->noaccel) {
771
		for (e = e - 1; e >= 0; e--) {
772
773
			if (!dev_priv->eng[e])
				continue;
774
			dev_priv->eng[e]->fini(dev, e, false);
775
			dev_priv->eng[e]->destroy(dev,e );
776
777
778
		}
	}

779
780
781
	engine->fb.takedown(dev);
out_timer:
	engine->timer.takedown(dev);
782
783
out_gpio:
	engine->gpio.takedown(dev);
784
785
out_mc:
	engine->mc.takedown(dev);
786
787
out_gart:
	nouveau_mem_gart_fini(dev);
788
789
out_ttmvram:
	nouveau_mem_vram_fini(dev);
790
791
out_instmem:
	engine->instmem.takedown(dev);
792
793
794
out_gpuobj:
	nouveau_gpuobj_takedown(dev);
out_vram:
795
	engine->vram.takedown(dev);
796
out_bios:
797
	nouveau_pm_fini(dev);
798
	nouveau_bios_takedown(dev);
799
800
out_display_early:
	engine->display.late_takedown(dev);
801
802
803
out:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
	return ret;
804
805
806
807
808
809
}

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;
810
	int e;
811

812
813
814
815
816
	if (dev->mode_config.num_crtc) {
		drm_kms_helper_poll_fini(dev);
		nouveau_fbcon_fini(dev);
		drm_vblank_cleanup(dev);
	}
817

818
	if (dev_priv->channel) {
819
		nouveau_channel_put_unlocked(&dev_priv->channel);
820
		nouveau_fence_fini(dev);
821
	}
822

823
	nouveau_backlight_exit(dev);
824
	engine->display.destroy(dev);
825
	drm_mode_config_cleanup(dev);
826

827
	if (!dev_priv->noaccel) {
828
		engine->fifo.takedown(dev);
829
830
		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
			if (dev_priv->eng[e]) {
831
				dev_priv->eng[e]->fini(dev, e, false);
832
833
834
				dev_priv->eng[e]->destroy(dev,e );
			}
		}
835
836
837
	}
	engine->fb.takedown(dev);
	engine->timer.takedown(dev);
838
	engine->gpio.takedown(dev);
839
	engine->mc.takedown(dev);
840
	engine->display.late_takedown(dev);
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
	engine->vram.takedown(dev);
857

Ben Skeggs's avatar
Ben Skeggs committed
858
	nouveau_irq_fini(dev);
859

860
	nouveau_pm_fini(dev);
861
	nouveau_bios_takedown(dev);
862

863
	vga_client_register(dev->pdev, NULL, NULL, NULL);
864
865
}

866
867
868
int
nouveau_open(struct drm_device *dev, struct drm_file *file_priv)
{
869
	struct drm_nouveau_private *dev_priv = dev->dev_private;
870
	struct nouveau_fpriv *fpriv;
871
	int ret;
872
873
874
875
876
877

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

	spin_lock_init(&fpriv->lock);
878
879
	INIT_LIST_HEAD(&fpriv->channels);

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

897
898
899
900
	file_priv->driver_priv = fpriv;
	return 0;
}

901
902
903
904
905
906
907
/* 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);
}

908
909
910
911
void
nouveau_postclose(struct drm_device *dev, struct drm_file *file_priv)
{
	struct nouveau_fpriv *fpriv = nouveau_fpriv(file_priv);
912
	nouveau_vm_ref(NULL, &fpriv->vm, NULL);
913
914
915
	kfree(fpriv);
}

916
917
918
919
920
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
/* 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
}

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

980
981
982
#ifdef CONFIG_X86
	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
#endif
983

984
	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
985
986
987
	return 0;
}

988
989
990
int nouveau_load(struct drm_device *dev, unsigned long flags)
{
	struct drm_nouveau_private *dev_priv;
991
	uint32_t reg0, strap;
992
	resource_size_t mmio_start_offs;
993
	int ret;
994
995

	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
996
997
998
999
	if (!dev_priv) {
		ret = -ENOMEM;
		goto err_out;
	}
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
	dev->dev_private = dev_priv;
	dev_priv->dev = dev;

	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");
1019
		ret = -EINVAL;
1020
		goto err_priv;
1021
1022
1023
1024
1025
1026
	}
	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 */
1027
1028
	if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
		nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041

	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) {
1042
1043
1044
1045
		if (reg0 & 0x00f00000)
			dev_priv->chipset = 0x05;
		else
			dev_priv->chipset = 0x04;
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
	} 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;
1066
1067
1068
	case 0xc0:
		dev_priv->card_type = NV_C0;
		break;
1069
1070
1071
	case 0xd0:
		dev_priv->card_type = NV_D0;
		break;
1072
1073
	default:
		NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0);
1074
1075
		ret = -EINVAL;
		goto err_mmio;
1076
1077
1078
1079
1080
	}

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

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
	/* 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);

1098
1099
1100
1101
1102
1103
1104
1105
	/* 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) {
		case 0xc1: /* known broken */
1106
1107
			NV_INFO(dev, "acceleration disabled by default, pass "
				     "noaccel=0 to force enable\n");
1108
1109
1110
1111
1112
1113
1114
1115
			dev_priv->noaccel = true;
			break;
		default:
			dev_priv->noaccel = false;
			break;
		}
	}

1116
1117
	ret = nouveau_remove_conflicting_drivers(dev);
	if (ret)
1118
		goto err_mmio;
1119

Lucas De Marchi's avatar
Lucas De Marchi committed
1120
	/* Map PRAMIN BAR, or on older cards, the aperture within BAR0 */
1121
1122
1123
1124
1125
1126
	if (dev_priv->card_type >= NV_40) {
		int ramin_bar = 2;
		if (pci_resource_len(dev->pdev, ramin_bar) == 0)
			ramin_bar = 3;

		dev_priv->ramin_size = pci_resource_len(dev->pdev, ramin_bar);
1127
1128
		dev_priv->ramin =
			ioremap(pci_resource_start(dev->pdev, ramin_bar),
1129
1130
				dev_priv->ramin_size);
		if (!dev_priv->ramin) {
1131
			NV_ERROR(dev, "Failed to map PRAMIN BAR\n");
1132
1133
			ret = -ENOMEM;
			goto err_mmio;
1134
		}
1135
	} else {
1136
1137
		dev_priv->ramin_size = 1 * 1024 * 1024;
		dev_priv->ramin = ioremap(mmio_start_offs + NV_RAMIN,
1138
					  dev_priv->ramin_size);
1139
1140
		if (!dev_priv->ramin) {
			NV_ERROR(dev, "Failed to map BAR0 PRAMIN.\n");
1141
1142
			ret = -ENOMEM;
			goto err_mmio;
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
		}
	}

	nouveau_OF_copy_vbios_to_ramin(dev);

	/* Special flags */
	if (dev->pci_device == 0x01a0)
		dev_priv->flags |= NV_NFORCE;
	else if (dev->pci_device == 0x01f0)
		dev_priv->flags |= NV_NFORCE2;

	/* For kernel modesetting, init card now and bring up fbcon */