2 * Copyright 2005 Stephane Marchesin
3 * Copyright 2008 Stuart Bennett
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
26 #include <linux/swab.h>
29 #include "drm_sarea.h"
30 #include "drm_crtc_helper.h"
31 #include <linux/vgaarb.h>
33 #include "nouveau_drv.h"
34 #include "nouveau_drm.h"
35 #include "nv50_display.h"
37 static int nouveau_stub_init(struct drm_device
*dev
) { return 0; }
38 static void nouveau_stub_takedown(struct drm_device
*dev
) {}
40 static int nouveau_init_engine_ptrs(struct drm_device
*dev
)
42 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
43 struct nouveau_engine
*engine
= &dev_priv
->engine
;
45 switch (dev_priv
->chipset
& 0xf0) {
47 engine
->instmem
.init
= nv04_instmem_init
;
48 engine
->instmem
.takedown
= nv04_instmem_takedown
;
49 engine
->instmem
.suspend
= nv04_instmem_suspend
;
50 engine
->instmem
.resume
= nv04_instmem_resume
;
51 engine
->instmem
.populate
= nv04_instmem_populate
;
52 engine
->instmem
.clear
= nv04_instmem_clear
;
53 engine
->instmem
.bind
= nv04_instmem_bind
;
54 engine
->instmem
.unbind
= nv04_instmem_unbind
;
55 engine
->instmem
.prepare_access
= nv04_instmem_prepare_access
;
56 engine
->instmem
.finish_access
= nv04_instmem_finish_access
;
57 engine
->mc
.init
= nv04_mc_init
;
58 engine
->mc
.takedown
= nv04_mc_takedown
;
59 engine
->timer
.init
= nv04_timer_init
;
60 engine
->timer
.read
= nv04_timer_read
;
61 engine
->timer
.takedown
= nv04_timer_takedown
;
62 engine
->fb
.init
= nv04_fb_init
;
63 engine
->fb
.takedown
= nv04_fb_takedown
;
64 engine
->graph
.grclass
= nv04_graph_grclass
;
65 engine
->graph
.init
= nv04_graph_init
;
66 engine
->graph
.takedown
= nv04_graph_takedown
;
67 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
68 engine
->graph
.channel
= nv04_graph_channel
;
69 engine
->graph
.create_context
= nv04_graph_create_context
;
70 engine
->graph
.destroy_context
= nv04_graph_destroy_context
;
71 engine
->graph
.load_context
= nv04_graph_load_context
;
72 engine
->graph
.unload_context
= nv04_graph_unload_context
;
73 engine
->fifo
.channels
= 16;
74 engine
->fifo
.init
= nv04_fifo_init
;
75 engine
->fifo
.takedown
= nouveau_stub_takedown
;
76 engine
->fifo
.disable
= nv04_fifo_disable
;
77 engine
->fifo
.enable
= nv04_fifo_enable
;
78 engine
->fifo
.reassign
= nv04_fifo_reassign
;
79 engine
->fifo
.cache_flush
= nv04_fifo_cache_flush
;
80 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
81 engine
->fifo
.channel_id
= nv04_fifo_channel_id
;
82 engine
->fifo
.create_context
= nv04_fifo_create_context
;
83 engine
->fifo
.destroy_context
= nv04_fifo_destroy_context
;
84 engine
->fifo
.load_context
= nv04_fifo_load_context
;
85 engine
->fifo
.unload_context
= nv04_fifo_unload_context
;
88 engine
->instmem
.init
= nv04_instmem_init
;
89 engine
->instmem
.takedown
= nv04_instmem_takedown
;
90 engine
->instmem
.suspend
= nv04_instmem_suspend
;
91 engine
->instmem
.resume
= nv04_instmem_resume
;
92 engine
->instmem
.populate
= nv04_instmem_populate
;
93 engine
->instmem
.clear
= nv04_instmem_clear
;
94 engine
->instmem
.bind
= nv04_instmem_bind
;
95 engine
->instmem
.unbind
= nv04_instmem_unbind
;
96 engine
->instmem
.prepare_access
= nv04_instmem_prepare_access
;
97 engine
->instmem
.finish_access
= nv04_instmem_finish_access
;
98 engine
->mc
.init
= nv04_mc_init
;
99 engine
->mc
.takedown
= nv04_mc_takedown
;
100 engine
->timer
.init
= nv04_timer_init
;
101 engine
->timer
.read
= nv04_timer_read
;
102 engine
->timer
.takedown
= nv04_timer_takedown
;
103 engine
->fb
.init
= nv10_fb_init
;
104 engine
->fb
.takedown
= nv10_fb_takedown
;
105 engine
->fb
.set_region_tiling
= nv10_fb_set_region_tiling
;
106 engine
->graph
.grclass
= nv10_graph_grclass
;
107 engine
->graph
.init
= nv10_graph_init
;
108 engine
->graph
.takedown
= nv10_graph_takedown
;
109 engine
->graph
.channel
= nv10_graph_channel
;
110 engine
->graph
.create_context
= nv10_graph_create_context
;
111 engine
->graph
.destroy_context
= nv10_graph_destroy_context
;
112 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
113 engine
->graph
.load_context
= nv10_graph_load_context
;
114 engine
->graph
.unload_context
= nv10_graph_unload_context
;
115 engine
->graph
.set_region_tiling
= nv10_graph_set_region_tiling
;
116 engine
->fifo
.channels
= 32;
117 engine
->fifo
.init
= nv10_fifo_init
;
118 engine
->fifo
.takedown
= nouveau_stub_takedown
;
119 engine
->fifo
.disable
= nv04_fifo_disable
;
120 engine
->fifo
.enable
= nv04_fifo_enable
;
121 engine
->fifo
.reassign
= nv04_fifo_reassign
;
122 engine
->fifo
.cache_flush
= nv04_fifo_cache_flush
;
123 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
124 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
125 engine
->fifo
.create_context
= nv10_fifo_create_context
;
126 engine
->fifo
.destroy_context
= nv10_fifo_destroy_context
;
127 engine
->fifo
.load_context
= nv10_fifo_load_context
;
128 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
131 engine
->instmem
.init
= nv04_instmem_init
;
132 engine
->instmem
.takedown
= nv04_instmem_takedown
;
133 engine
->instmem
.suspend
= nv04_instmem_suspend
;
134 engine
->instmem
.resume
= nv04_instmem_resume
;
135 engine
->instmem
.populate
= nv04_instmem_populate
;
136 engine
->instmem
.clear
= nv04_instmem_clear
;
137 engine
->instmem
.bind
= nv04_instmem_bind
;
138 engine
->instmem
.unbind
= nv04_instmem_unbind
;
139 engine
->instmem
.prepare_access
= nv04_instmem_prepare_access
;
140 engine
->instmem
.finish_access
= nv04_instmem_finish_access
;
141 engine
->mc
.init
= nv04_mc_init
;
142 engine
->mc
.takedown
= nv04_mc_takedown
;
143 engine
->timer
.init
= nv04_timer_init
;
144 engine
->timer
.read
= nv04_timer_read
;
145 engine
->timer
.takedown
= nv04_timer_takedown
;
146 engine
->fb
.init
= nv10_fb_init
;
147 engine
->fb
.takedown
= nv10_fb_takedown
;
148 engine
->fb
.set_region_tiling
= nv10_fb_set_region_tiling
;
149 engine
->graph
.grclass
= nv20_graph_grclass
;
150 engine
->graph
.init
= nv20_graph_init
;
151 engine
->graph
.takedown
= nv20_graph_takedown
;
152 engine
->graph
.channel
= nv10_graph_channel
;
153 engine
->graph
.create_context
= nv20_graph_create_context
;
154 engine
->graph
.destroy_context
= nv20_graph_destroy_context
;
155 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
156 engine
->graph
.load_context
= nv20_graph_load_context
;
157 engine
->graph
.unload_context
= nv20_graph_unload_context
;
158 engine
->graph
.set_region_tiling
= nv20_graph_set_region_tiling
;
159 engine
->fifo
.channels
= 32;
160 engine
->fifo
.init
= nv10_fifo_init
;
161 engine
->fifo
.takedown
= nouveau_stub_takedown
;
162 engine
->fifo
.disable
= nv04_fifo_disable
;
163 engine
->fifo
.enable
= nv04_fifo_enable
;
164 engine
->fifo
.reassign
= nv04_fifo_reassign
;
165 engine
->fifo
.cache_flush
= nv04_fifo_cache_flush
;
166 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
167 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
168 engine
->fifo
.create_context
= nv10_fifo_create_context
;
169 engine
->fifo
.destroy_context
= nv10_fifo_destroy_context
;
170 engine
->fifo
.load_context
= nv10_fifo_load_context
;
171 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
174 engine
->instmem
.init
= nv04_instmem_init
;
175 engine
->instmem
.takedown
= nv04_instmem_takedown
;
176 engine
->instmem
.suspend
= nv04_instmem_suspend
;
177 engine
->instmem
.resume
= nv04_instmem_resume
;
178 engine
->instmem
.populate
= nv04_instmem_populate
;
179 engine
->instmem
.clear
= nv04_instmem_clear
;
180 engine
->instmem
.bind
= nv04_instmem_bind
;
181 engine
->instmem
.unbind
= nv04_instmem_unbind
;
182 engine
->instmem
.prepare_access
= nv04_instmem_prepare_access
;
183 engine
->instmem
.finish_access
= nv04_instmem_finish_access
;
184 engine
->mc
.init
= nv04_mc_init
;
185 engine
->mc
.takedown
= nv04_mc_takedown
;
186 engine
->timer
.init
= nv04_timer_init
;
187 engine
->timer
.read
= nv04_timer_read
;
188 engine
->timer
.takedown
= nv04_timer_takedown
;
189 engine
->fb
.init
= nv10_fb_init
;
190 engine
->fb
.takedown
= nv10_fb_takedown
;
191 engine
->fb
.set_region_tiling
= nv10_fb_set_region_tiling
;
192 engine
->graph
.grclass
= nv30_graph_grclass
;
193 engine
->graph
.init
= nv30_graph_init
;
194 engine
->graph
.takedown
= nv20_graph_takedown
;
195 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
196 engine
->graph
.channel
= nv10_graph_channel
;
197 engine
->graph
.create_context
= nv20_graph_create_context
;
198 engine
->graph
.destroy_context
= nv20_graph_destroy_context
;
199 engine
->graph
.load_context
= nv20_graph_load_context
;
200 engine
->graph
.unload_context
= nv20_graph_unload_context
;
201 engine
->graph
.set_region_tiling
= nv20_graph_set_region_tiling
;
202 engine
->fifo
.channels
= 32;
203 engine
->fifo
.init
= nv10_fifo_init
;
204 engine
->fifo
.takedown
= nouveau_stub_takedown
;
205 engine
->fifo
.disable
= nv04_fifo_disable
;
206 engine
->fifo
.enable
= nv04_fifo_enable
;
207 engine
->fifo
.reassign
= nv04_fifo_reassign
;
208 engine
->fifo
.cache_flush
= nv04_fifo_cache_flush
;
209 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
210 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
211 engine
->fifo
.create_context
= nv10_fifo_create_context
;
212 engine
->fifo
.destroy_context
= nv10_fifo_destroy_context
;
213 engine
->fifo
.load_context
= nv10_fifo_load_context
;
214 engine
->fifo
.unload_context
= nv10_fifo_unload_context
;
218 engine
->instmem
.init
= nv04_instmem_init
;
219 engine
->instmem
.takedown
= nv04_instmem_takedown
;
220 engine
->instmem
.suspend
= nv04_instmem_suspend
;
221 engine
->instmem
.resume
= nv04_instmem_resume
;
222 engine
->instmem
.populate
= nv04_instmem_populate
;
223 engine
->instmem
.clear
= nv04_instmem_clear
;
224 engine
->instmem
.bind
= nv04_instmem_bind
;
225 engine
->instmem
.unbind
= nv04_instmem_unbind
;
226 engine
->instmem
.prepare_access
= nv04_instmem_prepare_access
;
227 engine
->instmem
.finish_access
= nv04_instmem_finish_access
;
228 engine
->mc
.init
= nv40_mc_init
;
229 engine
->mc
.takedown
= nv40_mc_takedown
;
230 engine
->timer
.init
= nv04_timer_init
;
231 engine
->timer
.read
= nv04_timer_read
;
232 engine
->timer
.takedown
= nv04_timer_takedown
;
233 engine
->fb
.init
= nv40_fb_init
;
234 engine
->fb
.takedown
= nv40_fb_takedown
;
235 engine
->fb
.set_region_tiling
= nv40_fb_set_region_tiling
;
236 engine
->graph
.grclass
= nv40_graph_grclass
;
237 engine
->graph
.init
= nv40_graph_init
;
238 engine
->graph
.takedown
= nv40_graph_takedown
;
239 engine
->graph
.fifo_access
= nv04_graph_fifo_access
;
240 engine
->graph
.channel
= nv40_graph_channel
;
241 engine
->graph
.create_context
= nv40_graph_create_context
;
242 engine
->graph
.destroy_context
= nv40_graph_destroy_context
;
243 engine
->graph
.load_context
= nv40_graph_load_context
;
244 engine
->graph
.unload_context
= nv40_graph_unload_context
;
245 engine
->graph
.set_region_tiling
= nv40_graph_set_region_tiling
;
246 engine
->fifo
.channels
= 32;
247 engine
->fifo
.init
= nv40_fifo_init
;
248 engine
->fifo
.takedown
= nouveau_stub_takedown
;
249 engine
->fifo
.disable
= nv04_fifo_disable
;
250 engine
->fifo
.enable
= nv04_fifo_enable
;
251 engine
->fifo
.reassign
= nv04_fifo_reassign
;
252 engine
->fifo
.cache_flush
= nv04_fifo_cache_flush
;
253 engine
->fifo
.cache_pull
= nv04_fifo_cache_pull
;
254 engine
->fifo
.channel_id
= nv10_fifo_channel_id
;
255 engine
->fifo
.create_context
= nv40_fifo_create_context
;
256 engine
->fifo
.destroy_context
= nv40_fifo_destroy_context
;
257 engine
->fifo
.load_context
= nv40_fifo_load_context
;
258 engine
->fifo
.unload_context
= nv40_fifo_unload_context
;
261 case 0x80: /* gotta love NVIDIA's consistency.. */
264 engine
->instmem
.init
= nv50_instmem_init
;
265 engine
->instmem
.takedown
= nv50_instmem_takedown
;
266 engine
->instmem
.suspend
= nv50_instmem_suspend
;
267 engine
->instmem
.resume
= nv50_instmem_resume
;
268 engine
->instmem
.populate
= nv50_instmem_populate
;
269 engine
->instmem
.clear
= nv50_instmem_clear
;
270 engine
->instmem
.bind
= nv50_instmem_bind
;
271 engine
->instmem
.unbind
= nv50_instmem_unbind
;
272 engine
->instmem
.prepare_access
= nv50_instmem_prepare_access
;
273 engine
->instmem
.finish_access
= nv50_instmem_finish_access
;
274 engine
->mc
.init
= nv50_mc_init
;
275 engine
->mc
.takedown
= nv50_mc_takedown
;
276 engine
->timer
.init
= nv04_timer_init
;
277 engine
->timer
.read
= nv04_timer_read
;
278 engine
->timer
.takedown
= nv04_timer_takedown
;
279 engine
->fb
.init
= nouveau_stub_init
;
280 engine
->fb
.takedown
= nouveau_stub_takedown
;
281 engine
->graph
.grclass
= nv50_graph_grclass
;
282 engine
->graph
.init
= nv50_graph_init
;
283 engine
->graph
.takedown
= nv50_graph_takedown
;
284 engine
->graph
.fifo_access
= nv50_graph_fifo_access
;
285 engine
->graph
.channel
= nv50_graph_channel
;
286 engine
->graph
.create_context
= nv50_graph_create_context
;
287 engine
->graph
.destroy_context
= nv50_graph_destroy_context
;
288 engine
->graph
.load_context
= nv50_graph_load_context
;
289 engine
->graph
.unload_context
= nv50_graph_unload_context
;
290 engine
->fifo
.channels
= 128;
291 engine
->fifo
.init
= nv50_fifo_init
;
292 engine
->fifo
.takedown
= nv50_fifo_takedown
;
293 engine
->fifo
.disable
= nv04_fifo_disable
;
294 engine
->fifo
.enable
= nv04_fifo_enable
;
295 engine
->fifo
.reassign
= nv04_fifo_reassign
;
296 engine
->fifo
.channel_id
= nv50_fifo_channel_id
;
297 engine
->fifo
.create_context
= nv50_fifo_create_context
;
298 engine
->fifo
.destroy_context
= nv50_fifo_destroy_context
;
299 engine
->fifo
.load_context
= nv50_fifo_load_context
;
300 engine
->fifo
.unload_context
= nv50_fifo_unload_context
;
303 NV_ERROR(dev
, "NV%02x unsupported\n", dev_priv
->chipset
);
311 nouveau_vga_set_decode(void *priv
, bool state
)
313 struct drm_device
*dev
= priv
;
314 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
316 if (dev_priv
->chipset
>= 0x40)
317 nv_wr32(dev
, 0x88054, state
);
319 nv_wr32(dev
, 0x1854, state
);
322 return VGA_RSRC_LEGACY_IO
| VGA_RSRC_LEGACY_MEM
|
323 VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
325 return VGA_RSRC_NORMAL_IO
| VGA_RSRC_NORMAL_MEM
;
329 nouveau_card_init_channel(struct drm_device
*dev
)
331 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
332 struct nouveau_gpuobj
*gpuobj
;
335 ret
= nouveau_channel_alloc(dev
, &dev_priv
->channel
,
336 (struct drm_file
*)-2,
342 ret
= nouveau_gpuobj_dma_new(dev_priv
->channel
, NV_CLASS_DMA_IN_MEMORY
,
343 0, nouveau_mem_fb_amount(dev
),
344 NV_DMA_ACCESS_RW
, NV_DMA_TARGET_VIDMEM
,
349 ret
= nouveau_gpuobj_ref_add(dev
, dev_priv
->channel
, NvDmaVRAM
,
355 ret
= nouveau_gpuobj_gart_dma_new(dev_priv
->channel
, 0,
356 dev_priv
->gart_info
.aper_size
,
357 NV_DMA_ACCESS_RW
, &gpuobj
, NULL
);
361 ret
= nouveau_gpuobj_ref_add(dev
, dev_priv
->channel
, NvDmaGART
,
368 nouveau_gpuobj_del(dev
, &gpuobj
);
369 nouveau_channel_free(dev_priv
->channel
);
370 dev_priv
->channel
= NULL
;
375 nouveau_card_init(struct drm_device
*dev
)
377 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
378 struct nouveau_engine
*engine
;
381 NV_DEBUG(dev
, "prev state = %d\n", dev_priv
->init_state
);
383 if (dev_priv
->init_state
== NOUVEAU_CARD_INIT_DONE
)
386 vga_client_register(dev
->pdev
, dev
, NULL
, nouveau_vga_set_decode
);
388 /* Initialise internal driver API hooks */
389 ret
= nouveau_init_engine_ptrs(dev
);
392 engine
= &dev_priv
->engine
;
393 dev_priv
->init_state
= NOUVEAU_CARD_INIT_FAILED
;
394 spin_lock_init(&dev_priv
->context_switch_lock
);
396 /* Parse BIOS tables / Run init tables if card not POSTed */
397 if (drm_core_check_feature(dev
, DRIVER_MODESET
)) {
398 ret
= nouveau_bios_init(dev
);
403 ret
= nouveau_gpuobj_early_init(dev
);
407 /* Initialise instance memory, must happen before mem_init so we
408 * know exactly how much VRAM we're able to use for "normal"
411 ret
= engine
->instmem
.init(dev
);
413 goto out_gpuobj_early
;
415 /* Setup the memory manager */
416 ret
= nouveau_mem_init(dev
);
420 ret
= nouveau_gpuobj_init(dev
);
425 ret
= engine
->mc
.init(dev
);
430 ret
= engine
->timer
.init(dev
);
435 ret
= engine
->fb
.init(dev
);
440 engine
->graph
.accel_blocked
= true;
443 ret
= engine
->graph
.init(dev
);
448 ret
= engine
->fifo
.init(dev
);
453 /* this call irq_preinstall, register irq handler and
454 * call irq_postinstall
456 ret
= drm_irq_install(dev
);
460 ret
= drm_vblank_init(dev
, 0);
464 /* what about PVIDEO/PCRTC/PRAMDAC etc? */
466 if (!engine
->graph
.accel_blocked
) {
467 ret
= nouveau_card_init_channel(dev
);
472 if (drm_core_check_feature(dev
, DRIVER_MODESET
)) {
473 if (dev_priv
->card_type
>= NV_50
)
474 ret
= nv50_display_create(dev
);
476 ret
= nv04_display_create(dev
);
481 ret
= nouveau_backlight_init(dev
);
483 NV_ERROR(dev
, "Error %d registering backlight\n", ret
);
485 dev_priv
->init_state
= NOUVEAU_CARD_INIT_DONE
;
487 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
488 drm_helper_initial_config(dev
);
493 drm_irq_uninstall(dev
);
495 if (!nouveau_noaccel
)
496 engine
->fifo
.takedown(dev
);
498 if (!nouveau_noaccel
)
499 engine
->graph
.takedown(dev
);
501 engine
->fb
.takedown(dev
);
503 engine
->timer
.takedown(dev
);
505 engine
->mc
.takedown(dev
);
507 nouveau_gpuobj_takedown(dev
);
509 nouveau_mem_close(dev
);
511 engine
->instmem
.takedown(dev
);
513 nouveau_gpuobj_late_takedown(dev
);
515 nouveau_bios_takedown(dev
);
517 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
521 static void nouveau_card_takedown(struct drm_device
*dev
)
523 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
524 struct nouveau_engine
*engine
= &dev_priv
->engine
;
526 NV_DEBUG(dev
, "prev state = %d\n", dev_priv
->init_state
);
528 if (dev_priv
->init_state
!= NOUVEAU_CARD_INIT_DOWN
) {
529 nouveau_backlight_exit(dev
);
531 if (dev_priv
->channel
) {
532 nouveau_channel_free(dev_priv
->channel
);
533 dev_priv
->channel
= NULL
;
536 if (!nouveau_noaccel
) {
537 engine
->fifo
.takedown(dev
);
538 engine
->graph
.takedown(dev
);
540 engine
->fb
.takedown(dev
);
541 engine
->timer
.takedown(dev
);
542 engine
->mc
.takedown(dev
);
544 mutex_lock(&dev
->struct_mutex
);
545 ttm_bo_clean_mm(&dev_priv
->ttm
.bdev
, TTM_PL_VRAM
);
546 ttm_bo_clean_mm(&dev_priv
->ttm
.bdev
, TTM_PL_TT
);
547 mutex_unlock(&dev
->struct_mutex
);
548 nouveau_sgdma_takedown(dev
);
550 nouveau_gpuobj_takedown(dev
);
551 nouveau_mem_close(dev
);
552 engine
->instmem
.takedown(dev
);
554 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
555 drm_irq_uninstall(dev
);
557 nouveau_gpuobj_late_takedown(dev
);
558 nouveau_bios_takedown(dev
);
560 vga_client_register(dev
->pdev
, NULL
, NULL
, NULL
);
562 dev_priv
->init_state
= NOUVEAU_CARD_INIT_DOWN
;
566 /* here a client dies, release the stuff that was allocated for its
568 void nouveau_preclose(struct drm_device
*dev
, struct drm_file
*file_priv
)
570 nouveau_channel_cleanup(dev
, file_priv
);
573 /* first module load, setup the mmio/fb mapping */
574 /* KMS: we need mmio at load time, not when the first drm client opens. */
575 int nouveau_firstopen(struct drm_device
*dev
)
580 /* if we have an OF card, copy vbios to RAMIN */
581 static void nouveau_OF_copy_vbios_to_ramin(struct drm_device
*dev
)
583 #if defined(__powerpc__)
585 const uint32_t *bios
;
586 struct device_node
*dn
= pci_device_to_OF_node(dev
->pdev
);
588 NV_INFO(dev
, "Unable to get the OF node\n");
592 bios
= of_get_property(dn
, "NVDA,BMP", &size
);
594 for (i
= 0; i
< size
; i
+= 4)
595 nv_wi32(dev
, i
, bios
[i
/4]);
596 NV_INFO(dev
, "OF bios successfully copied (%d bytes)\n", size
);
598 NV_INFO(dev
, "Unable to get the OF bios\n");
603 int nouveau_load(struct drm_device
*dev
, unsigned long flags
)
605 struct drm_nouveau_private
*dev_priv
;
607 resource_size_t mmio_start_offs
;
609 dev_priv
= kzalloc(sizeof(*dev_priv
), GFP_KERNEL
);
612 dev
->dev_private
= dev_priv
;
615 dev_priv
->flags
= flags
& NOUVEAU_FLAGS
;
616 dev_priv
->init_state
= NOUVEAU_CARD_INIT_DOWN
;
618 NV_DEBUG(dev
, "vendor: 0x%X device: 0x%X class: 0x%X\n",
619 dev
->pci_vendor
, dev
->pci_device
, dev
->pdev
->class);
621 dev_priv
->acpi_dsm
= nouveau_dsm_probe(dev
);
623 if (dev_priv
->acpi_dsm
)
624 nouveau_hybrid_setup(dev
);
626 dev_priv
->wq
= create_workqueue("nouveau");
630 /* resource 0 is mmio regs */
631 /* resource 1 is linear FB */
632 /* resource 2 is RAMIN (mmio regs + 0x1000000) */
633 /* resource 6 is bios */
635 /* map the mmio regs */
636 mmio_start_offs
= pci_resource_start(dev
->pdev
, 0);
637 dev_priv
->mmio
= ioremap(mmio_start_offs
, 0x00800000);
638 if (!dev_priv
->mmio
) {
639 NV_ERROR(dev
, "Unable to initialize the mmio mapping. "
640 "Please report your setup to " DRIVER_EMAIL
"\n");
643 NV_DEBUG(dev
, "regs mapped ok at 0x%llx\n",
644 (unsigned long long)mmio_start_offs
);
647 /* Put the card in BE mode if it's not */
648 if (nv_rd32(dev
, NV03_PMC_BOOT_1
))
649 nv_wr32(dev
, NV03_PMC_BOOT_1
, 0x00000001);
654 /* Time to determine the card architecture */
655 reg0
= nv_rd32(dev
, NV03_PMC_BOOT_0
);
657 /* We're dealing with >=NV10 */
658 if ((reg0
& 0x0f000000) > 0) {
659 /* Bit 27-20 contain the architecture in hex */
660 dev_priv
->chipset
= (reg0
& 0xff00000) >> 20;
662 } else if ((reg0
& 0xff00fff0) == 0x20004000) {
663 if (reg0
& 0x00f00000)
664 dev_priv
->chipset
= 0x05;
666 dev_priv
->chipset
= 0x04;
668 dev_priv
->chipset
= 0xff;
670 switch (dev_priv
->chipset
& 0xf0) {
675 dev_priv
->card_type
= dev_priv
->chipset
& 0xf0;
679 dev_priv
->card_type
= NV_40
;
685 dev_priv
->card_type
= NV_50
;
688 NV_INFO(dev
, "Unsupported chipset 0x%08x\n", reg0
);
692 NV_INFO(dev
, "Detected an NV%2x generation card (0x%08x)\n",
693 dev_priv
->card_type
, reg0
);
695 /* map larger RAMIN aperture on NV40 cards */
696 dev_priv
->ramin
= NULL
;
697 if (dev_priv
->card_type
>= NV_40
) {
699 if (pci_resource_len(dev
->pdev
, ramin_bar
) == 0)
702 dev_priv
->ramin_size
= pci_resource_len(dev
->pdev
, ramin_bar
);
703 dev_priv
->ramin
= ioremap(
704 pci_resource_start(dev
->pdev
, ramin_bar
),
705 dev_priv
->ramin_size
);
706 if (!dev_priv
->ramin
) {
707 NV_ERROR(dev
, "Failed to init RAMIN mapping, "
708 "limited instance memory available\n");
712 /* On older cards (or if the above failed), create a map covering
713 * the BAR0 PRAMIN aperture */
714 if (!dev_priv
->ramin
) {
715 dev_priv
->ramin_size
= 1 * 1024 * 1024;
716 dev_priv
->ramin
= ioremap(mmio_start_offs
+ NV_RAMIN
,
717 dev_priv
->ramin_size
);
718 if (!dev_priv
->ramin
) {
719 NV_ERROR(dev
, "Failed to map BAR0 PRAMIN.\n");
724 nouveau_OF_copy_vbios_to_ramin(dev
);
727 if (dev
->pci_device
== 0x01a0)
728 dev_priv
->flags
|= NV_NFORCE
;
729 else if (dev
->pci_device
== 0x01f0)
730 dev_priv
->flags
|= NV_NFORCE2
;
732 /* For kernel modesetting, init card now and bring up fbcon */
733 if (drm_core_check_feature(dev
, DRIVER_MODESET
)) {
734 int ret
= nouveau_card_init(dev
);
742 static void nouveau_close(struct drm_device
*dev
)
744 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
746 /* In the case of an error dev_priv may not be allocated yet */
748 nouveau_card_takedown(dev
);
751 /* KMS: we need mmio at load time, not when the first drm client opens. */
752 void nouveau_lastclose(struct drm_device
*dev
)
754 if (drm_core_check_feature(dev
, DRIVER_MODESET
))
760 int nouveau_unload(struct drm_device
*dev
)
762 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
764 if (drm_core_check_feature(dev
, DRIVER_MODESET
)) {
765 if (dev_priv
->card_type
>= NV_50
)
766 nv50_display_destroy(dev
);
768 nv04_display_destroy(dev
);
772 iounmap(dev_priv
->mmio
);
773 iounmap(dev_priv
->ramin
);
776 dev
->dev_private
= NULL
;
780 int nouveau_ioctl_getparam(struct drm_device
*dev
, void *data
,
781 struct drm_file
*file_priv
)
783 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
784 struct drm_nouveau_getparam
*getparam
= data
;
786 NOUVEAU_CHECK_INITIALISED_WITH_RETURN
;
788 switch (getparam
->param
) {
789 case NOUVEAU_GETPARAM_CHIPSET_ID
:
790 getparam
->value
= dev_priv
->chipset
;
792 case NOUVEAU_GETPARAM_PCI_VENDOR
:
793 getparam
->value
= dev
->pci_vendor
;
795 case NOUVEAU_GETPARAM_PCI_DEVICE
:
796 getparam
->value
= dev
->pci_device
;
798 case NOUVEAU_GETPARAM_BUS_TYPE
:
799 if (drm_device_is_agp(dev
))
800 getparam
->value
= NV_AGP
;
801 else if (drm_device_is_pcie(dev
))
802 getparam
->value
= NV_PCIE
;
804 getparam
->value
= NV_PCI
;
806 case NOUVEAU_GETPARAM_FB_PHYSICAL
:
807 getparam
->value
= dev_priv
->fb_phys
;
809 case NOUVEAU_GETPARAM_AGP_PHYSICAL
:
810 getparam
->value
= dev_priv
->gart_info
.aper_base
;
812 case NOUVEAU_GETPARAM_PCI_PHYSICAL
:
814 getparam
->value
= (unsigned long)dev
->sg
->virtual;
816 NV_ERROR(dev
, "Requested PCIGART address, "
817 "while no PCIGART was created\n");
821 case NOUVEAU_GETPARAM_FB_SIZE
:
822 getparam
->value
= dev_priv
->fb_available_size
;
824 case NOUVEAU_GETPARAM_AGP_SIZE
:
825 getparam
->value
= dev_priv
->gart_info
.aper_size
;
827 case NOUVEAU_GETPARAM_VM_VRAM_BASE
:
828 getparam
->value
= dev_priv
->vm_vram_base
;
830 case NOUVEAU_GETPARAM_GRAPH_UNITS
:
831 /* NV40 and NV50 versions are quite different, but register
832 * address is the same. User is supposed to know the card
833 * family anyway... */
834 if (dev_priv
->chipset
>= 0x40) {
835 getparam
->value
= nv_rd32(dev
, NV40_PMC_GRAPH_UNITS
);
840 NV_ERROR(dev
, "unknown parameter %lld\n", getparam
->param
);
848 nouveau_ioctl_setparam(struct drm_device
*dev
, void *data
,
849 struct drm_file
*file_priv
)
851 struct drm_nouveau_setparam
*setparam
= data
;
853 NOUVEAU_CHECK_INITIALISED_WITH_RETURN
;
855 switch (setparam
->param
) {
857 NV_ERROR(dev
, "unknown parameter %lld\n", setparam
->param
);
864 /* Wait until (value(reg) & mask) == val, up until timeout has hit */
865 bool nouveau_wait_until(struct drm_device
*dev
, uint64_t timeout
,
866 uint32_t reg
, uint32_t mask
, uint32_t val
)
868 struct drm_nouveau_private
*dev_priv
= dev
->dev_private
;
869 struct nouveau_timer_engine
*ptimer
= &dev_priv
->engine
.timer
;
870 uint64_t start
= ptimer
->read(dev
);
873 if ((nv_rd32(dev
, reg
) & mask
) == val
)
875 } while (ptimer
->read(dev
) - start
< timeout
);
880 /* Waits for PGRAPH to go completely idle */
881 bool nouveau_wait_for_idle(struct drm_device
*dev
)
883 if (!nv_wait(NV04_PGRAPH_STATUS
, 0xffffffff, 0x00000000)) {
884 NV_ERROR(dev
, "PGRAPH idle timed out with status 0x%08x\n",
885 nv_rd32(dev
, NV04_PGRAPH_STATUS
));