OSDN Git Service

nouveau: fix return from function..
[android-x86/external-libdrm.git] / shared-core / nouveau_state.c
1 /*
2  * Copyright 2005 Stephane Marchesin
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include "drmP.h"
26 #include "drm.h"
27 #include "drm_sarea.h"
28 #include "nouveau_drv.h"
29 #include "nouveau_drm.h"
30
31 static int nouveau_init_card_mappings(struct drm_device *dev)
32 {
33         struct drm_nouveau_private *dev_priv = dev->dev_private;
34         int ret;
35
36         /* resource 0 is mmio regs */
37         /* resource 1 is linear FB */
38         /* resource 2 is RAMIN (mmio regs + 0x1000000) */
39         /* resource 6 is bios */
40
41         /* map the mmio regs */
42         ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
43                               drm_get_resource_len(dev, 0),
44                               _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
45         if (ret) {
46                 DRM_ERROR("Unable to initialize the mmio mapping (%d). "
47                           "Please report your setup to " DRIVER_EMAIL "\n",
48                           ret);
49                 return -EINVAL;
50         }
51         DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset);
52
53         /* map larger RAMIN aperture on NV40 cards */
54         dev_priv->ramin = NULL;
55         if (dev_priv->card_type >= NV_40) {
56                 int ramin_resource = 2;
57                 if (drm_get_resource_len(dev, ramin_resource) == 0)
58                         ramin_resource = 3;
59
60                 ret = drm_addmap(dev,
61                                  drm_get_resource_start(dev, ramin_resource),
62                                  drm_get_resource_len(dev, ramin_resource),
63                                  _DRM_REGISTERS, _DRM_READ_ONLY,
64                                  &dev_priv->ramin);
65                 if (ret) {
66                         DRM_ERROR("Failed to init RAMIN mapping, "
67                                   "limited instance memory available\n");
68                         dev_priv->ramin = NULL;
69                 }
70         }
71
72         /* On older cards (or if the above failed), create a map covering
73          * the BAR0 PRAMIN aperture */
74         if (!dev_priv->ramin) {
75                 ret = drm_addmap(dev,
76                                  drm_get_resource_start(dev, 0) + NV_RAMIN,
77                                  (1*1024*1024),
78                                  _DRM_REGISTERS, _DRM_READ_ONLY,
79                                  &dev_priv->ramin);
80                 if (ret) {
81                         DRM_ERROR("Failed to map BAR0 PRAMIN: %d\n", ret);
82                         return ret;
83                 }
84         }
85
86         return 0;
87 }
88
89 static int nouveau_stub_init(struct drm_device *dev) { return 0; }
90 static void nouveau_stub_takedown(struct drm_device *dev) {}
91
92 static int nouveau_init_engine_ptrs(struct drm_device *dev)
93 {
94         struct drm_nouveau_private *dev_priv = dev->dev_private;
95         struct nouveau_engine *engine = &dev_priv->Engine;
96
97         switch (dev_priv->chipset & 0xf0) {
98         case 0x00:
99                 engine->instmem.init    = nv04_instmem_init;
100                 engine->instmem.takedown= nv04_instmem_takedown;
101                 engine->instmem.populate        = nv04_instmem_populate;
102                 engine->instmem.clear           = nv04_instmem_clear;
103                 engine->instmem.bind            = nv04_instmem_bind;
104                 engine->instmem.unbind          = nv04_instmem_unbind;
105                 engine->mc.init         = nv04_mc_init;
106                 engine->mc.takedown     = nv04_mc_takedown;
107                 engine->timer.init      = nv04_timer_init;
108                 engine->timer.read      = nv04_timer_read;
109                 engine->timer.takedown  = nv04_timer_takedown;
110                 engine->fb.init         = nv04_fb_init;
111                 engine->fb.takedown     = nv04_fb_takedown;
112                 engine->graph.init      = nv04_graph_init;
113                 engine->graph.takedown  = nv04_graph_takedown;
114                 engine->graph.create_context    = nv04_graph_create_context;
115                 engine->graph.destroy_context   = nv04_graph_destroy_context;
116                 engine->graph.load_context      = nv04_graph_load_context;
117                 engine->graph.save_context      = nv04_graph_save_context;
118                 engine->fifo.channels   = 16;
119                 engine->fifo.init       = nouveau_fifo_init;
120                 engine->fifo.takedown   = nouveau_stub_takedown;
121                 engine->fifo.channel_id         = nv04_fifo_channel_id;
122                 engine->fifo.create_context     = nv04_fifo_create_context;
123                 engine->fifo.destroy_context    = nv04_fifo_destroy_context;
124                 engine->fifo.load_context       = nv04_fifo_load_context;
125                 engine->fifo.save_context       = nv04_fifo_save_context;
126                 break;
127         case 0x10:
128                 engine->instmem.init    = nv04_instmem_init;
129                 engine->instmem.takedown= nv04_instmem_takedown;
130                 engine->instmem.populate        = nv04_instmem_populate;
131                 engine->instmem.clear           = nv04_instmem_clear;
132                 engine->instmem.bind            = nv04_instmem_bind;
133                 engine->instmem.unbind          = nv04_instmem_unbind;
134                 engine->mc.init         = nv04_mc_init;
135                 engine->mc.takedown     = nv04_mc_takedown;
136                 engine->timer.init      = nv04_timer_init;
137                 engine->timer.read      = nv04_timer_read;
138                 engine->timer.takedown  = nv04_timer_takedown;
139                 engine->fb.init         = nv10_fb_init;
140                 engine->fb.takedown     = nv10_fb_takedown;
141                 engine->graph.init      = nv10_graph_init;
142                 engine->graph.takedown  = nv10_graph_takedown;
143                 engine->graph.create_context    = nv10_graph_create_context;
144                 engine->graph.destroy_context   = nv10_graph_destroy_context;
145                 engine->graph.load_context      = nv10_graph_load_context;
146                 engine->graph.save_context      = nv10_graph_save_context;
147                 engine->fifo.channels   = 32;
148                 engine->fifo.init       = nouveau_fifo_init;
149                 engine->fifo.takedown   = nouveau_stub_takedown;
150                 engine->fifo.channel_id         = nv10_fifo_channel_id;
151                 engine->fifo.create_context     = nv10_fifo_create_context;
152                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
153                 engine->fifo.load_context       = nv10_fifo_load_context;
154                 engine->fifo.save_context       = nv10_fifo_save_context;
155                 break;
156         case 0x20:
157                 engine->instmem.init    = nv04_instmem_init;
158                 engine->instmem.takedown= nv04_instmem_takedown;
159                 engine->instmem.populate        = nv04_instmem_populate;
160                 engine->instmem.clear           = nv04_instmem_clear;
161                 engine->instmem.bind            = nv04_instmem_bind;
162                 engine->instmem.unbind          = nv04_instmem_unbind;
163                 engine->mc.init         = nv04_mc_init;
164                 engine->mc.takedown     = nv04_mc_takedown;
165                 engine->timer.init      = nv04_timer_init;
166                 engine->timer.read      = nv04_timer_read;
167                 engine->timer.takedown  = nv04_timer_takedown;
168                 engine->fb.init         = nv10_fb_init;
169                 engine->fb.takedown     = nv10_fb_takedown;
170                 engine->graph.init      = nv20_graph_init;
171                 engine->graph.takedown  = nv20_graph_takedown;
172                 engine->graph.create_context    = nv20_graph_create_context;
173                 engine->graph.destroy_context   = nv20_graph_destroy_context;
174                 engine->graph.load_context      = nv20_graph_load_context;
175                 engine->graph.save_context      = nv20_graph_save_context;
176                 engine->fifo.channels   = 32;
177                 engine->fifo.init       = nouveau_fifo_init;
178                 engine->fifo.takedown   = nouveau_stub_takedown;
179                 engine->fifo.channel_id         = nv10_fifo_channel_id;
180                 engine->fifo.create_context     = nv10_fifo_create_context;
181                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
182                 engine->fifo.load_context       = nv10_fifo_load_context;
183                 engine->fifo.save_context       = nv10_fifo_save_context;
184                 break;
185         case 0x30:
186                 engine->instmem.init    = nv04_instmem_init;
187                 engine->instmem.takedown= nv04_instmem_takedown;
188                 engine->instmem.populate        = nv04_instmem_populate;
189                 engine->instmem.clear           = nv04_instmem_clear;
190                 engine->instmem.bind            = nv04_instmem_bind;
191                 engine->instmem.unbind          = nv04_instmem_unbind;
192                 engine->mc.init         = nv04_mc_init;
193                 engine->mc.takedown     = nv04_mc_takedown;
194                 engine->timer.init      = nv04_timer_init;
195                 engine->timer.read      = nv04_timer_read;
196                 engine->timer.takedown  = nv04_timer_takedown;
197                 engine->fb.init         = nv10_fb_init;
198                 engine->fb.takedown     = nv10_fb_takedown;
199                 engine->graph.init      = nv30_graph_init;
200                 engine->graph.takedown  = nv20_graph_takedown;
201                 engine->graph.create_context    = nv20_graph_create_context;
202                 engine->graph.destroy_context   = nv20_graph_destroy_context;
203                 engine->graph.load_context      = nv20_graph_load_context;
204                 engine->graph.save_context      = nv20_graph_save_context;
205                 engine->fifo.channels   = 32;
206                 engine->fifo.init       = nouveau_fifo_init;
207                 engine->fifo.takedown   = nouveau_stub_takedown;
208                 engine->fifo.channel_id         = nv10_fifo_channel_id;
209                 engine->fifo.create_context     = nv10_fifo_create_context;
210                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
211                 engine->fifo.load_context       = nv10_fifo_load_context;
212                 engine->fifo.save_context       = nv10_fifo_save_context;
213                 break;
214         case 0x40:
215         case 0x60:
216                 engine->instmem.init    = nv04_instmem_init;
217                 engine->instmem.takedown= nv04_instmem_takedown;
218                 engine->instmem.populate        = nv04_instmem_populate;
219                 engine->instmem.clear           = nv04_instmem_clear;
220                 engine->instmem.bind            = nv04_instmem_bind;
221                 engine->instmem.unbind          = nv04_instmem_unbind;
222                 engine->mc.init         = nv40_mc_init;
223                 engine->mc.takedown     = nv40_mc_takedown;
224                 engine->timer.init      = nv04_timer_init;
225                 engine->timer.read      = nv04_timer_read;
226                 engine->timer.takedown  = nv04_timer_takedown;
227                 engine->fb.init         = nv40_fb_init;
228                 engine->fb.takedown     = nv40_fb_takedown;
229                 engine->graph.init      = nv40_graph_init;
230                 engine->graph.takedown  = nv40_graph_takedown;
231                 engine->graph.create_context    = nv40_graph_create_context;
232                 engine->graph.destroy_context   = nv40_graph_destroy_context;
233                 engine->graph.load_context      = nv40_graph_load_context;
234                 engine->graph.save_context      = nv40_graph_save_context;
235                 engine->fifo.channels   = 32;
236                 engine->fifo.init       = nv40_fifo_init;
237                 engine->fifo.takedown   = nouveau_stub_takedown;
238                 engine->fifo.channel_id         = nv10_fifo_channel_id;
239                 engine->fifo.create_context     = nv40_fifo_create_context;
240                 engine->fifo.destroy_context    = nv40_fifo_destroy_context;
241                 engine->fifo.load_context       = nv40_fifo_load_context;
242                 engine->fifo.save_context       = nv40_fifo_save_context;
243                 break;
244         case 0x50:
245         case 0x80: /* gotta love NVIDIA's consistency.. */
246                 engine->instmem.init    = nv50_instmem_init;
247                 engine->instmem.takedown= nv50_instmem_takedown;
248                 engine->instmem.populate        = nv50_instmem_populate;
249                 engine->instmem.clear           = nv50_instmem_clear;
250                 engine->instmem.bind            = nv50_instmem_bind;
251                 engine->instmem.unbind          = nv50_instmem_unbind;
252                 engine->mc.init         = nv50_mc_init;
253                 engine->mc.takedown     = nv50_mc_takedown;
254                 engine->timer.init      = nv04_timer_init;
255                 engine->timer.read      = nv04_timer_read;
256                 engine->timer.takedown  = nv04_timer_takedown;
257                 engine->fb.init         = nouveau_stub_init;
258                 engine->fb.takedown     = nouveau_stub_takedown;
259                 engine->graph.init      = nv50_graph_init;
260                 engine->graph.takedown  = nv50_graph_takedown;
261                 engine->graph.create_context    = nv50_graph_create_context;
262                 engine->graph.destroy_context   = nv50_graph_destroy_context;
263                 engine->graph.load_context      = nv50_graph_load_context;
264                 engine->graph.save_context      = nv50_graph_save_context;
265                 engine->fifo.channels   = 128;
266                 engine->fifo.init       = nv50_fifo_init;
267                 engine->fifo.takedown   = nv50_fifo_takedown;
268                 engine->fifo.channel_id         = nv50_fifo_channel_id;
269                 engine->fifo.create_context     = nv50_fifo_create_context;
270                 engine->fifo.destroy_context    = nv50_fifo_destroy_context;
271                 engine->fifo.load_context       = nv50_fifo_load_context;
272                 engine->fifo.save_context       = nv50_fifo_save_context;
273                 break;
274         default:
275                 DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset);
276                 return 1;
277         }
278
279         return 0;
280 }
281
282 int
283 nouveau_card_init(struct drm_device *dev)
284 {
285         struct drm_nouveau_private *dev_priv = dev->dev_private;
286         struct nouveau_engine *engine;
287         int ret;
288
289         DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
290
291         if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
292                 return 0;
293         dev_priv->ttm = 0;
294
295         /* Determine exact chipset we're running on */
296         if (dev_priv->card_type < NV_10)
297                 dev_priv->chipset = dev_priv->card_type;
298         else
299                 dev_priv->chipset =
300                         (NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20;
301
302         /* Initialise internal driver API hooks */
303         ret = nouveau_init_engine_ptrs(dev);
304         if (ret) return ret;
305         engine = &dev_priv->Engine;
306         dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
307
308         ret = nouveau_gpuobj_early_init(dev);
309         if (ret) return ret;
310
311         /* Initialise instance memory, must happen before mem_init so we
312          * know exactly how much VRAM we're able to use for "normal"
313          * purposes.
314          */
315         ret = engine->instmem.init(dev);
316         if (ret) return ret;
317
318         /* Setup the memory manager */
319         if (dev_priv->ttm) {
320                 ret = nouveau_mem_init_ttm(dev);
321                 if (ret) return ret;
322         } else {
323                 ret = nouveau_mem_init(dev);
324                 if (ret) return ret;
325         }
326
327         ret = nouveau_gpuobj_init(dev);
328         if (ret) return ret;
329
330         /* Parse BIOS tables / Run init tables? */
331
332         /* PMC */
333         ret = engine->mc.init(dev);
334         if (ret) return ret;
335
336         /* PTIMER */
337         ret = engine->timer.init(dev);
338         if (ret) return ret;
339
340         /* PFB */
341         ret = engine->fb.init(dev);
342         if (ret) return ret;
343
344         /* PGRAPH */
345         ret = engine->graph.init(dev);
346         if (ret) return ret;
347
348         /* PFIFO */
349         ret = engine->fifo.init(dev);
350         if (ret) return ret;
351
352         /* this call irq_preinstall, register irq handler and
353          * call irq_postinstall
354          */
355         ret = drm_irq_install(dev);
356         if (ret) return ret;
357
358         /* what about PVIDEO/PCRTC/PRAMDAC etc? */
359
360         ret = nouveau_dma_channel_init(dev);
361         if (ret) return ret;
362
363         dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
364         return 0;
365 }
366
367 static void nouveau_card_takedown(struct drm_device *dev)
368 {
369         struct drm_nouveau_private *dev_priv = dev->dev_private;
370         struct nouveau_engine *engine = &dev_priv->Engine;
371
372         DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
373
374         if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
375                 nouveau_dma_channel_takedown(dev);
376
377                 engine->fifo.takedown(dev);
378                 engine->graph.takedown(dev);
379                 engine->fb.takedown(dev);
380                 engine->timer.takedown(dev);
381                 engine->mc.takedown(dev);
382
383                 nouveau_sgdma_nottm_hack_takedown(dev);
384                 nouveau_sgdma_takedown(dev);
385
386                 nouveau_gpuobj_takedown(dev);
387                 nouveau_gpuobj_del(dev, &dev_priv->vm_vram_pt);
388
389                 nouveau_mem_close(dev);
390                 engine->instmem.takedown(dev);
391
392                 drm_irq_uninstall(dev);
393
394                 nouveau_gpuobj_late_takedown(dev);
395
396                 dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
397         }
398 }
399
400 /* here a client dies, release the stuff that was allocated for its
401  * file_priv */
402 void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
403 {
404         struct drm_nouveau_private *dev_priv = dev->dev_private;
405
406         nouveau_fifo_cleanup(dev, file_priv);
407         nouveau_mem_release(file_priv,dev_priv->fb_heap);
408         nouveau_mem_release(file_priv,dev_priv->agp_heap);
409         nouveau_mem_release(file_priv,dev_priv->pci_heap);
410 }
411
412 /* first module load, setup the mmio/fb mapping */
413 int nouveau_firstopen(struct drm_device *dev)
414 {
415 #if defined(__powerpc__)
416         struct drm_nouveau_private *dev_priv = dev->dev_private;
417         struct device_node *dn;
418 #endif
419         int ret;
420         /* Map any PCI resources we need on the card */
421         ret = nouveau_init_card_mappings(dev);
422         if (ret) return ret;
423
424 #if defined(__powerpc__)
425         /* Put the card in BE mode if it's not */
426         if (NV_READ(NV03_PMC_BOOT_1))
427                 NV_WRITE(NV03_PMC_BOOT_1,0x00000001);
428
429         DRM_MEMORYBARRIER();
430 #endif
431
432 #if defined(__linux__) && defined(__powerpc__)
433         /* if we have an OF card, copy vbios to RAMIN */
434         dn = pci_device_to_OF_node(dev->pdev);
435         if (dn)
436         {
437                 int size;
438 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
439                 const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size);
440 #else
441                 const uint32_t *bios = get_property(dn, "NVDA,BMP", &size);
442 #endif
443                 if (bios)
444                 {
445                         int i;
446                         for(i=0;i<size;i+=4)
447                                 NV_WI32(i, bios[i/4]);
448                         DRM_INFO("OF bios successfully copied (%d bytes)\n",size);
449                 }
450                 else
451                         DRM_INFO("Unable to get the OF bios\n");
452         }
453         else
454                 DRM_INFO("Unable to get the OF node\n");
455 #endif
456         return 0;
457 }
458
459 #define NV40_CHIPSET_MASK 0x00000baf
460 #define NV44_CHIPSET_MASK 0x00005450
461
462 int nouveau_load(struct drm_device *dev, unsigned long flags)
463 {
464         struct drm_nouveau_private *dev_priv;
465         void __iomem *regs;
466         uint32_t reg0,reg1;
467         uint8_t architecture = 0;
468
469         dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
470         if (!dev_priv)
471                 return -ENOMEM;
472
473         dev_priv->flags = flags & NOUVEAU_FLAGS;
474         dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
475
476         DRM_DEBUG("vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class);
477
478         /* Time to determine the card architecture */
479         regs = ioremap_nocache(pci_resource_start(dev->pdev, 0), 0x8);
480         if (!regs) {
481                 DRM_ERROR("Could not ioremap to determine register\n");
482                 return -ENOMEM;
483         }
484
485         reg0 = readl(regs+NV03_PMC_BOOT_0);
486         reg1 = readl(regs+NV03_PMC_BOOT_1);
487 #if defined(__powerpc__)
488         if (reg1)
489                 reg0=___swab32(reg0);
490 #endif
491
492         /* We're dealing with >=NV10 */
493         if ((reg0 & 0x0f000000) > 0 ) {
494                 /* Bit 27-20 contain the architecture in hex */
495                 architecture = (reg0 & 0xff00000) >> 20;
496         /* NV04 or NV05 */
497         } else if ((reg0 & 0xff00fff0) == 0x20004000) {
498                 architecture = 0x04;
499         }
500
501         iounmap(regs);
502
503         if (architecture >= 0x80) {
504                 dev_priv->card_type = NV_50;
505         } else if (architecture >= 0x60) {
506                 /* FIXME we need to figure out who's who for NV6x */
507                 dev_priv->card_type = NV_44;
508         } else if (architecture >= 0x50) {
509                 dev_priv->card_type = NV_50;
510         } else if (architecture >= 0x40) {
511                 uint8_t subarch = architecture & 0xf;
512                 /* Selection criteria borrowed from NV40EXA */
513                 if (NV40_CHIPSET_MASK & (1 << subarch)) {
514                         dev_priv->card_type = NV_40;
515                 } else if (NV44_CHIPSET_MASK & (1 << subarch)) {
516                         dev_priv->card_type = NV_44;
517                 } else {
518                         dev_priv->card_type = NV_UNKNOWN;
519                 }
520         } else if (architecture >= 0x30) {
521                 dev_priv->card_type = NV_30;
522         } else if (architecture >= 0x20) {
523                 dev_priv->card_type = NV_20;
524         } else if (architecture >= 0x17) {
525                 dev_priv->card_type = NV_17;
526         } else if (architecture >= 0x11) {
527                 dev_priv->card_type = NV_11;
528         } else if (architecture >= 0x10) {
529                 dev_priv->card_type = NV_10;
530         } else if (architecture >= 0x04) {
531                 dev_priv->card_type = NV_04;
532         } else {
533                 dev_priv->card_type = NV_UNKNOWN;
534         }
535
536         DRM_INFO("Detected an NV%d generation card (0x%08x)\n", dev_priv->card_type,reg0);
537
538         if (dev_priv->card_type == NV_UNKNOWN) {
539                 return -EINVAL;
540         }
541
542         /* Special flags */
543         if (dev->pci_device == 0x01a0) {
544                 dev_priv->flags |= NV_NFORCE;
545         } else if (dev->pci_device == 0x01f0) {
546                 dev_priv->flags |= NV_NFORCE2;
547         }
548
549         dev->dev_private = (void *)dev_priv;
550
551         return 0;
552 }
553
554 void nouveau_lastclose(struct drm_device *dev)
555 {
556         struct drm_nouveau_private *dev_priv = dev->dev_private;
557
558         /* In the case of an error dev_priv may not be be allocated yet */
559         if (dev_priv && dev_priv->card_type) {
560                 nouveau_card_takedown(dev);
561
562                 if(dev_priv->fb_mtrr>0)
563                 {
564                         drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
565                         dev_priv->fb_mtrr=0;
566                 }
567         }
568 }
569
570 int nouveau_unload(struct drm_device *dev)
571 {
572         drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER);
573         dev->dev_private = NULL;
574         return 0;
575 }
576
577 int
578 nouveau_ioctl_card_init(struct drm_device *dev, void *data,
579                         struct drm_file *file_priv)
580 {
581         return nouveau_card_init(dev);
582 }
583
584 int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
585 {
586         struct drm_nouveau_private *dev_priv = dev->dev_private;
587         struct drm_nouveau_getparam *getparam = data;
588
589         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
590
591         switch (getparam->param) {
592         case NOUVEAU_GETPARAM_CHIPSET_ID:
593                 getparam->value = dev_priv->chipset;
594                 break;
595         case NOUVEAU_GETPARAM_PCI_VENDOR:
596                 getparam->value=dev->pci_vendor;
597                 break;
598         case NOUVEAU_GETPARAM_PCI_DEVICE:
599                 getparam->value=dev->pci_device;
600                 break;
601         case NOUVEAU_GETPARAM_BUS_TYPE:
602                 if (drm_device_is_agp(dev))
603                         getparam->value=NV_AGP;
604                 else if (drm_device_is_pcie(dev))
605                         getparam->value=NV_PCIE;
606                 else
607                         getparam->value=NV_PCI;
608                 break;
609         case NOUVEAU_GETPARAM_FB_PHYSICAL:
610                 getparam->value=dev_priv->fb_phys;
611                 break;
612         case NOUVEAU_GETPARAM_AGP_PHYSICAL:
613                 getparam->value=dev_priv->gart_info.aper_base;
614                 break;
615         case NOUVEAU_GETPARAM_PCI_PHYSICAL:
616                 if ( dev -> sg )
617                         getparam->value=(uint64_t) dev->sg->virtual;
618                 else
619                      {
620                      DRM_ERROR("Requested PCIGART address, while no PCIGART was created\n");
621                      return -EINVAL;
622                      }
623                 break;
624         case NOUVEAU_GETPARAM_FB_SIZE:
625                 getparam->value=dev_priv->fb_available_size;
626                 break;
627         case NOUVEAU_GETPARAM_AGP_SIZE:
628                 getparam->value=dev_priv->gart_info.aper_size;
629                 break;
630         default:
631                 DRM_ERROR("unknown parameter %lld\n", getparam->param);
632                 return -EINVAL;
633         }
634
635         return 0;
636 }
637
638 int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
639 {
640         struct drm_nouveau_private *dev_priv = dev->dev_private;
641         struct drm_nouveau_setparam *setparam = data;
642
643         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
644
645         switch (setparam->param) {
646         case NOUVEAU_SETPARAM_CMDBUF_LOCATION:
647                 switch (setparam->value) {
648                 case NOUVEAU_MEM_AGP:
649                 case NOUVEAU_MEM_FB:
650                 case NOUVEAU_MEM_PCI:
651                 case NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE:
652                         break;
653                 default:
654                         DRM_ERROR("invalid CMDBUF_LOCATION value=%lld\n",
655                                         setparam->value);
656                         return -EINVAL;
657                 }
658                 dev_priv->config.cmdbuf.location = setparam->value;
659                 break;
660         case NOUVEAU_SETPARAM_CMDBUF_SIZE:
661                 dev_priv->config.cmdbuf.size = setparam->value;
662                 break;
663         default:
664                 DRM_ERROR("unknown parameter %lld\n", setparam->param);
665                 return -EINVAL;
666         }
667
668         return 0;
669 }
670
671 /* waits for idle */
672 void nouveau_wait_for_idle(struct drm_device *dev)
673 {
674         struct drm_nouveau_private *dev_priv=dev->dev_private;
675         switch(dev_priv->card_type) {
676         case NV_50:
677                 break;
678         default: {
679                 /* This stuff is more or less a copy of what is seen
680                  * in nv28 kmmio dump.
681                  */
682                 uint64_t started = dev_priv->Engine.timer.read(dev);
683                 uint64_t stopped = started;
684                 uint32_t status;
685                 do {
686                         uint32_t pmc_e = NV_READ(NV03_PMC_ENABLE);
687                         (void)pmc_e;
688                         status = NV_READ(NV04_PGRAPH_STATUS);
689                         if (!status)
690                                 break;
691                         stopped = dev_priv->Engine.timer.read(dev);
692                 /* It'll never wrap anyway... */
693                 } while (stopped - started < 1000000000ULL);
694                 if (status)
695                         DRM_ERROR("timed out with status 0x%08x\n",
696                                   status);
697         }
698         }
699 }