OSDN Git Service

nv50: support NV94 chipset
[android-x86/external-libdrm.git] / shared-core / nouveau_state.c
1 /*
2  * Copyright 2005 Stephane Marchesin
3  * Copyright 2008 Stuart Bennett
4  * All Rights Reserved.
5  *
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:
12  *
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
15  * Software.
16  *
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.
24  */
25
26 #include "drmP.h"
27 #include "drm.h"
28 #include "drm_sarea.h"
29 #include "nouveau_drv.h"
30 #include "nouveau_drm.h"
31
32 static int nouveau_init_card_mappings(struct drm_device *dev)
33 {
34         struct drm_nouveau_private *dev_priv = dev->dev_private;
35         int ret;
36
37         /* resource 0 is mmio regs */
38         /* resource 1 is linear FB */
39         /* resource 2 is RAMIN (mmio regs + 0x1000000) */
40         /* resource 6 is bios */
41
42         /* map the mmio regs */
43         ret = drm_addmap(dev, drm_get_resource_start(dev, 0),
44                               drm_get_resource_len(dev, 0),
45                               _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
46         if (ret) {
47                 DRM_ERROR("Unable to initialize the mmio mapping (%d). "
48                           "Please report your setup to " DRIVER_EMAIL "\n",
49                           ret);
50                 return -EINVAL;
51         }
52         DRM_DEBUG("regs mapped ok at 0x%lx\n", dev_priv->mmio->offset);
53
54         /* map larger RAMIN aperture on NV40 cards */
55         dev_priv->ramin = NULL;
56         if (dev_priv->card_type >= NV_40) {
57                 int ramin_resource = 2;
58                 if (drm_get_resource_len(dev, ramin_resource) == 0)
59                         ramin_resource = 3;
60
61                 ret = drm_addmap(dev,
62                                  drm_get_resource_start(dev, ramin_resource),
63                                  drm_get_resource_len(dev, ramin_resource),
64                                  _DRM_REGISTERS, _DRM_READ_ONLY,
65                                  &dev_priv->ramin);
66                 if (ret) {
67                         DRM_ERROR("Failed to init RAMIN mapping, "
68                                   "limited instance memory available\n");
69                         dev_priv->ramin = NULL;
70                 }
71         }
72
73         /* On older cards (or if the above failed), create a map covering
74          * the BAR0 PRAMIN aperture */
75         if (!dev_priv->ramin) {
76                 ret = drm_addmap(dev,
77                                  drm_get_resource_start(dev, 0) + NV_RAMIN,
78                                  (1*1024*1024),
79                                  _DRM_REGISTERS, _DRM_READ_ONLY,
80                                  &dev_priv->ramin);
81                 if (ret) {
82                         DRM_ERROR("Failed to map BAR0 PRAMIN: %d\n", ret);
83                         return ret;
84                 }
85         }
86
87         return 0;
88 }
89
90 static int nouveau_stub_init(struct drm_device *dev) { return 0; }
91 static void nouveau_stub_takedown(struct drm_device *dev) {}
92
93 static int nouveau_init_engine_ptrs(struct drm_device *dev)
94 {
95         struct drm_nouveau_private *dev_priv = dev->dev_private;
96         struct nouveau_engine *engine = &dev_priv->Engine;
97
98         switch (dev_priv->chipset & 0xf0) {
99         case 0x00:
100                 engine->instmem.init    = nv04_instmem_init;
101                 engine->instmem.takedown= nv04_instmem_takedown;
102                 engine->instmem.populate        = nv04_instmem_populate;
103                 engine->instmem.clear           = nv04_instmem_clear;
104                 engine->instmem.bind            = nv04_instmem_bind;
105                 engine->instmem.unbind          = nv04_instmem_unbind;
106                 engine->mc.init         = nv04_mc_init;
107                 engine->mc.takedown     = nv04_mc_takedown;
108                 engine->timer.init      = nv04_timer_init;
109                 engine->timer.read      = nv04_timer_read;
110                 engine->timer.takedown  = nv04_timer_takedown;
111                 engine->fb.init         = nv04_fb_init;
112                 engine->fb.takedown     = nv04_fb_takedown;
113                 engine->graph.init      = nv04_graph_init;
114                 engine->graph.takedown  = nv04_graph_takedown;
115                 engine->graph.create_context    = nv04_graph_create_context;
116                 engine->graph.destroy_context   = nv04_graph_destroy_context;
117                 engine->graph.load_context      = nv04_graph_load_context;
118                 engine->graph.save_context      = nv04_graph_save_context;
119                 engine->fifo.channels   = 16;
120                 engine->fifo.init       = nouveau_fifo_init;
121                 engine->fifo.takedown   = nouveau_stub_takedown;
122                 engine->fifo.channel_id         = nv04_fifo_channel_id;
123                 engine->fifo.create_context     = nv04_fifo_create_context;
124                 engine->fifo.destroy_context    = nv04_fifo_destroy_context;
125                 engine->fifo.load_context       = nv04_fifo_load_context;
126                 engine->fifo.save_context       = nv04_fifo_save_context;
127                 break;
128         case 0x10:
129                 engine->instmem.init    = nv04_instmem_init;
130                 engine->instmem.takedown= nv04_instmem_takedown;
131                 engine->instmem.populate        = nv04_instmem_populate;
132                 engine->instmem.clear           = nv04_instmem_clear;
133                 engine->instmem.bind            = nv04_instmem_bind;
134                 engine->instmem.unbind          = nv04_instmem_unbind;
135                 engine->mc.init         = nv04_mc_init;
136                 engine->mc.takedown     = nv04_mc_takedown;
137                 engine->timer.init      = nv04_timer_init;
138                 engine->timer.read      = nv04_timer_read;
139                 engine->timer.takedown  = nv04_timer_takedown;
140                 engine->fb.init         = nv10_fb_init;
141                 engine->fb.takedown     = nv10_fb_takedown;
142                 engine->graph.init      = nv10_graph_init;
143                 engine->graph.takedown  = nv10_graph_takedown;
144                 engine->graph.create_context    = nv10_graph_create_context;
145                 engine->graph.destroy_context   = nv10_graph_destroy_context;
146                 engine->graph.load_context      = nv10_graph_load_context;
147                 engine->graph.save_context      = nv10_graph_save_context;
148                 engine->fifo.channels   = 32;
149                 engine->fifo.init       = nouveau_fifo_init;
150                 engine->fifo.takedown   = nouveau_stub_takedown;
151                 engine->fifo.channel_id         = nv10_fifo_channel_id;
152                 engine->fifo.create_context     = nv10_fifo_create_context;
153                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
154                 engine->fifo.load_context       = nv10_fifo_load_context;
155                 engine->fifo.save_context       = nv10_fifo_save_context;
156                 break;
157         case 0x20:
158                 engine->instmem.init    = nv04_instmem_init;
159                 engine->instmem.takedown= nv04_instmem_takedown;
160                 engine->instmem.populate        = nv04_instmem_populate;
161                 engine->instmem.clear           = nv04_instmem_clear;
162                 engine->instmem.bind            = nv04_instmem_bind;
163                 engine->instmem.unbind          = nv04_instmem_unbind;
164                 engine->mc.init         = nv04_mc_init;
165                 engine->mc.takedown     = nv04_mc_takedown;
166                 engine->timer.init      = nv04_timer_init;
167                 engine->timer.read      = nv04_timer_read;
168                 engine->timer.takedown  = nv04_timer_takedown;
169                 engine->fb.init         = nv10_fb_init;
170                 engine->fb.takedown     = nv10_fb_takedown;
171                 engine->graph.init      = nv20_graph_init;
172                 engine->graph.takedown  = nv20_graph_takedown;
173                 engine->graph.create_context    = nv20_graph_create_context;
174                 engine->graph.destroy_context   = nv20_graph_destroy_context;
175                 engine->graph.load_context      = nv20_graph_load_context;
176                 engine->graph.save_context      = nv20_graph_save_context;
177                 engine->fifo.channels   = 32;
178                 engine->fifo.init       = nouveau_fifo_init;
179                 engine->fifo.takedown   = nouveau_stub_takedown;
180                 engine->fifo.channel_id         = nv10_fifo_channel_id;
181                 engine->fifo.create_context     = nv10_fifo_create_context;
182                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
183                 engine->fifo.load_context       = nv10_fifo_load_context;
184                 engine->fifo.save_context       = nv10_fifo_save_context;
185                 break;
186         case 0x30:
187                 engine->instmem.init    = nv04_instmem_init;
188                 engine->instmem.takedown= nv04_instmem_takedown;
189                 engine->instmem.populate        = nv04_instmem_populate;
190                 engine->instmem.clear           = nv04_instmem_clear;
191                 engine->instmem.bind            = nv04_instmem_bind;
192                 engine->instmem.unbind          = nv04_instmem_unbind;
193                 engine->mc.init         = nv04_mc_init;
194                 engine->mc.takedown     = nv04_mc_takedown;
195                 engine->timer.init      = nv04_timer_init;
196                 engine->timer.read      = nv04_timer_read;
197                 engine->timer.takedown  = nv04_timer_takedown;
198                 engine->fb.init         = nv10_fb_init;
199                 engine->fb.takedown     = nv10_fb_takedown;
200                 engine->graph.init      = nv30_graph_init;
201                 engine->graph.takedown  = nv20_graph_takedown;
202                 engine->graph.create_context    = nv20_graph_create_context;
203                 engine->graph.destroy_context   = nv20_graph_destroy_context;
204                 engine->graph.load_context      = nv20_graph_load_context;
205                 engine->graph.save_context      = nv20_graph_save_context;
206                 engine->fifo.channels   = 32;
207                 engine->fifo.init       = nouveau_fifo_init;
208                 engine->fifo.takedown   = nouveau_stub_takedown;
209                 engine->fifo.channel_id         = nv10_fifo_channel_id;
210                 engine->fifo.create_context     = nv10_fifo_create_context;
211                 engine->fifo.destroy_context    = nv10_fifo_destroy_context;
212                 engine->fifo.load_context       = nv10_fifo_load_context;
213                 engine->fifo.save_context       = nv10_fifo_save_context;
214                 break;
215         case 0x40:
216         case 0x60:
217                 engine->instmem.init    = nv04_instmem_init;
218                 engine->instmem.takedown= nv04_instmem_takedown;
219                 engine->instmem.populate        = nv04_instmem_populate;
220                 engine->instmem.clear           = nv04_instmem_clear;
221                 engine->instmem.bind            = nv04_instmem_bind;
222                 engine->instmem.unbind          = nv04_instmem_unbind;
223                 engine->mc.init         = nv40_mc_init;
224                 engine->mc.takedown     = nv40_mc_takedown;
225                 engine->timer.init      = nv04_timer_init;
226                 engine->timer.read      = nv04_timer_read;
227                 engine->timer.takedown  = nv04_timer_takedown;
228                 engine->fb.init         = nv40_fb_init;
229                 engine->fb.takedown     = nv40_fb_takedown;
230                 engine->graph.init      = nv40_graph_init;
231                 engine->graph.takedown  = nv40_graph_takedown;
232                 engine->graph.create_context    = nv40_graph_create_context;
233                 engine->graph.destroy_context   = nv40_graph_destroy_context;
234                 engine->graph.load_context      = nv40_graph_load_context;
235                 engine->graph.save_context      = nv40_graph_save_context;
236                 engine->fifo.channels   = 32;
237                 engine->fifo.init       = nv40_fifo_init;
238                 engine->fifo.takedown   = nouveau_stub_takedown;
239                 engine->fifo.channel_id         = nv10_fifo_channel_id;
240                 engine->fifo.create_context     = nv40_fifo_create_context;
241                 engine->fifo.destroy_context    = nv40_fifo_destroy_context;
242                 engine->fifo.load_context       = nv40_fifo_load_context;
243                 engine->fifo.save_context       = nv40_fifo_save_context;
244                 break;
245         case 0x50:
246         case 0x80: /* gotta love NVIDIA's consistency.. */
247         case 0x90:
248         case 0xA0:
249                 engine->instmem.init    = nv50_instmem_init;
250                 engine->instmem.takedown= nv50_instmem_takedown;
251                 engine->instmem.populate        = nv50_instmem_populate;
252                 engine->instmem.clear           = nv50_instmem_clear;
253                 engine->instmem.bind            = nv50_instmem_bind;
254                 engine->instmem.unbind          = nv50_instmem_unbind;
255                 engine->mc.init         = nv50_mc_init;
256                 engine->mc.takedown     = nv50_mc_takedown;
257                 engine->timer.init      = nv04_timer_init;
258                 engine->timer.read      = nv04_timer_read;
259                 engine->timer.takedown  = nv04_timer_takedown;
260                 engine->fb.init         = nouveau_stub_init;
261                 engine->fb.takedown     = nouveau_stub_takedown;
262                 engine->graph.init      = nv50_graph_init;
263                 engine->graph.takedown  = nv50_graph_takedown;
264                 engine->graph.create_context    = nv50_graph_create_context;
265                 engine->graph.destroy_context   = nv50_graph_destroy_context;
266                 engine->graph.load_context      = nv50_graph_load_context;
267                 engine->graph.save_context      = nv50_graph_save_context;
268                 engine->fifo.channels   = 128;
269                 engine->fifo.init       = nv50_fifo_init;
270                 engine->fifo.takedown   = nv50_fifo_takedown;
271                 engine->fifo.channel_id         = nv50_fifo_channel_id;
272                 engine->fifo.create_context     = nv50_fifo_create_context;
273                 engine->fifo.destroy_context    = nv50_fifo_destroy_context;
274                 engine->fifo.load_context       = nv50_fifo_load_context;
275                 engine->fifo.save_context       = nv50_fifo_save_context;
276                 break;
277         default:
278                 DRM_ERROR("NV%02x unsupported\n", dev_priv->chipset);
279                 return 1;
280         }
281
282         return 0;
283 }
284
285 int
286 nouveau_card_init(struct drm_device *dev)
287 {
288         struct drm_nouveau_private *dev_priv = dev->dev_private;
289         struct nouveau_engine *engine;
290         int ret;
291
292         DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
293
294         if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE)
295                 return 0;
296         dev_priv->ttm = 0;
297
298         /* Determine exact chipset we're running on */
299         if (dev_priv->card_type < NV_10)
300                 dev_priv->chipset = dev_priv->card_type;
301         else
302                 dev_priv->chipset =
303                         (NV_READ(NV03_PMC_BOOT_0) & 0x0ff00000) >> 20;
304
305         /* Initialise internal driver API hooks */
306         ret = nouveau_init_engine_ptrs(dev);
307         if (ret) return ret;
308         engine = &dev_priv->Engine;
309         dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
310
311         ret = nouveau_gpuobj_early_init(dev);
312         if (ret) return ret;
313
314         /* Initialise instance memory, must happen before mem_init so we
315          * know exactly how much VRAM we're able to use for "normal"
316          * purposes.
317          */
318         ret = engine->instmem.init(dev);
319         if (ret) return ret;
320
321         /* Setup the memory manager */
322         if (dev_priv->ttm) {
323                 ret = nouveau_mem_init_ttm(dev);
324                 if (ret) return ret;
325         } else {
326                 ret = nouveau_mem_init(dev);
327                 if (ret) return ret;
328         }
329
330         ret = nouveau_gpuobj_init(dev);
331         if (ret) return ret;
332
333         /* Parse BIOS tables / Run init tables? */
334
335         /* PMC */
336         ret = engine->mc.init(dev);
337         if (ret) return ret;
338
339         /* PTIMER */
340         ret = engine->timer.init(dev);
341         if (ret) return ret;
342
343         /* PFB */
344         ret = engine->fb.init(dev);
345         if (ret) return ret;
346
347         /* PGRAPH */
348         ret = engine->graph.init(dev);
349         if (ret) return ret;
350
351         /* PFIFO */
352         ret = engine->fifo.init(dev);
353         if (ret) return ret;
354
355         /* this call irq_preinstall, register irq handler and
356          * call irq_postinstall
357          */
358         ret = drm_irq_install(dev);
359         if (ret) return ret;
360
361         /* what about PVIDEO/PCRTC/PRAMDAC etc? */
362
363         ret = nouveau_dma_channel_init(dev);
364         if (ret) return ret;
365
366         dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
367         return 0;
368 }
369
370 static void nouveau_card_takedown(struct drm_device *dev)
371 {
372         struct drm_nouveau_private *dev_priv = dev->dev_private;
373         struct nouveau_engine *engine = &dev_priv->Engine;
374
375         DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
376
377         if (dev_priv->init_state != NOUVEAU_CARD_INIT_DOWN) {
378                 nouveau_dma_channel_takedown(dev);
379
380                 engine->fifo.takedown(dev);
381                 engine->graph.takedown(dev);
382                 engine->fb.takedown(dev);
383                 engine->timer.takedown(dev);
384                 engine->mc.takedown(dev);
385
386                 nouveau_sgdma_nottm_hack_takedown(dev);
387                 nouveau_sgdma_takedown(dev);
388
389                 nouveau_gpuobj_takedown(dev);
390                 nouveau_gpuobj_del(dev, &dev_priv->vm_vram_pt);
391
392                 nouveau_mem_close(dev);
393                 engine->instmem.takedown(dev);
394
395                 drm_irq_uninstall(dev);
396
397                 nouveau_gpuobj_late_takedown(dev);
398
399                 dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
400         }
401 }
402
403 /* here a client dies, release the stuff that was allocated for its
404  * file_priv */
405 void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
406 {
407         struct drm_nouveau_private *dev_priv = dev->dev_private;
408
409         nouveau_fifo_cleanup(dev, file_priv);
410         nouveau_mem_release(file_priv,dev_priv->fb_heap);
411         nouveau_mem_release(file_priv,dev_priv->agp_heap);
412         nouveau_mem_release(file_priv,dev_priv->pci_heap);
413 }
414
415 /* first module load, setup the mmio/fb mapping */
416 int nouveau_firstopen(struct drm_device *dev)
417 {
418 #if defined(__powerpc__)
419         struct drm_nouveau_private *dev_priv = dev->dev_private;
420         struct device_node *dn;
421 #endif
422         int ret;
423         /* Map any PCI resources we need on the card */
424         ret = nouveau_init_card_mappings(dev);
425         if (ret) return ret;
426
427 #if defined(__powerpc__)
428         /* Put the card in BE mode if it's not */
429         if (NV_READ(NV03_PMC_BOOT_1))
430                 NV_WRITE(NV03_PMC_BOOT_1,0x00000001);
431
432         DRM_MEMORYBARRIER();
433 #endif
434
435 #if defined(__linux__) && defined(__powerpc__)
436         /* if we have an OF card, copy vbios to RAMIN */
437         dn = pci_device_to_OF_node(dev->pdev);
438         if (dn)
439         {
440                 int size;
441 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
442                 const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size);
443 #else
444                 const uint32_t *bios = get_property(dn, "NVDA,BMP", &size);
445 #endif
446                 if (bios)
447                 {
448                         int i;
449                         for(i=0;i<size;i+=4)
450                                 NV_WI32(i, bios[i/4]);
451                         DRM_INFO("OF bios successfully copied (%d bytes)\n",size);
452                 }
453                 else
454                         DRM_INFO("Unable to get the OF bios\n");
455         }
456         else
457                 DRM_INFO("Unable to get the OF node\n");
458 #endif
459         return 0;
460 }
461
462 #define NV40_CHIPSET_MASK 0x00000baf
463 #define NV44_CHIPSET_MASK 0x00005450
464
465 int nouveau_load(struct drm_device *dev, unsigned long flags)
466 {
467         struct drm_nouveau_private *dev_priv;
468         void __iomem *regs;
469         uint32_t reg0,reg1;
470         uint8_t architecture = 0;
471
472         dev_priv = drm_calloc(1, sizeof(*dev_priv), DRM_MEM_DRIVER);
473         if (!dev_priv)
474                 return -ENOMEM;
475
476         dev_priv->flags = flags & NOUVEAU_FLAGS;
477         dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
478
479         DRM_DEBUG("vendor: 0x%X device: 0x%X class: 0x%X\n", dev->pci_vendor, dev->pci_device, dev->pdev->class);
480
481         /* Time to determine the card architecture */
482         regs = ioremap_nocache(pci_resource_start(dev->pdev, 0), 0x8);
483         if (!regs) {
484                 DRM_ERROR("Could not ioremap to determine register\n");
485                 return -ENOMEM;
486         }
487
488         reg0 = readl(regs+NV03_PMC_BOOT_0);
489         reg1 = readl(regs+NV03_PMC_BOOT_1);
490 #if defined(__powerpc__)
491         if (reg1)
492                 reg0=___swab32(reg0);
493 #endif
494
495         /* We're dealing with >=NV10 */
496         if ((reg0 & 0x0f000000) > 0 ) {
497                 /* Bit 27-20 contain the architecture in hex */
498                 architecture = (reg0 & 0xff00000) >> 20;
499         /* NV04 or NV05 */
500         } else if ((reg0 & 0xff00fff0) == 0x20004000) {
501                 architecture = 0x04;
502         }
503
504         iounmap(regs);
505
506         if (architecture >= 0x80) {
507                 dev_priv->card_type = NV_50;
508         } else if (architecture >= 0x60) {
509                 /* FIXME we need to figure out who's who for NV6x */
510                 dev_priv->card_type = NV_44;
511         } else if (architecture >= 0x50) {
512                 dev_priv->card_type = NV_50;
513         } else if (architecture >= 0x40) {
514                 uint8_t subarch = architecture & 0xf;
515                 /* Selection criteria borrowed from NV40EXA */
516                 if (NV40_CHIPSET_MASK & (1 << subarch)) {
517                         dev_priv->card_type = NV_40;
518                 } else if (NV44_CHIPSET_MASK & (1 << subarch)) {
519                         dev_priv->card_type = NV_44;
520                 } else {
521                         dev_priv->card_type = NV_UNKNOWN;
522                 }
523         } else if (architecture >= 0x30) {
524                 dev_priv->card_type = NV_30;
525         } else if (architecture >= 0x20) {
526                 dev_priv->card_type = NV_20;
527         } else if (architecture >= 0x17) {
528                 dev_priv->card_type = NV_17;
529         } else if (architecture >= 0x11) {
530                 dev_priv->card_type = NV_11;
531         } else if (architecture >= 0x10) {
532                 dev_priv->card_type = NV_10;
533         } else if (architecture >= 0x04) {
534                 dev_priv->card_type = NV_04;
535         } else {
536                 dev_priv->card_type = NV_UNKNOWN;
537         }
538
539         DRM_INFO("Detected an NV%d generation card (0x%08x)\n", dev_priv->card_type,reg0);
540
541         if (dev_priv->card_type == NV_UNKNOWN) {
542                 return -EINVAL;
543         }
544
545         /* Special flags */
546         if (dev->pci_device == 0x01a0) {
547                 dev_priv->flags |= NV_NFORCE;
548         } else if (dev->pci_device == 0x01f0) {
549                 dev_priv->flags |= NV_NFORCE2;
550         }
551
552         dev->dev_private = (void *)dev_priv;
553
554         return 0;
555 }
556
557 void nouveau_lastclose(struct drm_device *dev)
558 {
559         struct drm_nouveau_private *dev_priv = dev->dev_private;
560
561         /* In the case of an error dev_priv may not be be allocated yet */
562         if (dev_priv && dev_priv->card_type) {
563                 nouveau_card_takedown(dev);
564
565                 if(dev_priv->fb_mtrr>0)
566                 {
567                         drm_mtrr_del(dev_priv->fb_mtrr, drm_get_resource_start(dev, 1),nouveau_mem_fb_amount(dev), DRM_MTRR_WC);
568                         dev_priv->fb_mtrr=0;
569                 }
570         }
571 }
572
573 int nouveau_unload(struct drm_device *dev)
574 {
575         drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER);
576         dev->dev_private = NULL;
577         return 0;
578 }
579
580 int
581 nouveau_ioctl_card_init(struct drm_device *dev, void *data,
582                         struct drm_file *file_priv)
583 {
584         return nouveau_card_init(dev);
585 }
586
587 int nouveau_ioctl_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
588 {
589         struct drm_nouveau_private *dev_priv = dev->dev_private;
590         struct drm_nouveau_getparam *getparam = data;
591
592         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
593
594         switch (getparam->param) {
595         case NOUVEAU_GETPARAM_CHIPSET_ID:
596                 getparam->value = dev_priv->chipset;
597                 break;
598         case NOUVEAU_GETPARAM_PCI_VENDOR:
599                 getparam->value=dev->pci_vendor;
600                 break;
601         case NOUVEAU_GETPARAM_PCI_DEVICE:
602                 getparam->value=dev->pci_device;
603                 break;
604         case NOUVEAU_GETPARAM_BUS_TYPE:
605                 if (drm_device_is_agp(dev))
606                         getparam->value=NV_AGP;
607                 else if (drm_device_is_pcie(dev))
608                         getparam->value=NV_PCIE;
609                 else
610                         getparam->value=NV_PCI;
611                 break;
612         case NOUVEAU_GETPARAM_FB_PHYSICAL:
613                 getparam->value=dev_priv->fb_phys;
614                 break;
615         case NOUVEAU_GETPARAM_AGP_PHYSICAL:
616                 getparam->value=dev_priv->gart_info.aper_base;
617                 break;
618         case NOUVEAU_GETPARAM_PCI_PHYSICAL:
619                 if ( dev -> sg )
620                         getparam->value=(unsigned long)dev->sg->virtual;
621                 else
622                      {
623                      DRM_ERROR("Requested PCIGART address, while no PCIGART was created\n");
624                      return -EINVAL;
625                      }
626                 break;
627         case NOUVEAU_GETPARAM_FB_SIZE:
628                 getparam->value=dev_priv->fb_available_size;
629                 break;
630         case NOUVEAU_GETPARAM_AGP_SIZE:
631                 getparam->value=dev_priv->gart_info.aper_size;
632                 break;
633         default:
634                 DRM_ERROR("unknown parameter %lld\n", getparam->param);
635                 return -EINVAL;
636         }
637
638         return 0;
639 }
640
641 int nouveau_ioctl_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
642 {
643         struct drm_nouveau_private *dev_priv = dev->dev_private;
644         struct drm_nouveau_setparam *setparam = data;
645
646         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
647
648         switch (setparam->param) {
649         case NOUVEAU_SETPARAM_CMDBUF_LOCATION:
650                 switch (setparam->value) {
651                 case NOUVEAU_MEM_AGP:
652                 case NOUVEAU_MEM_FB:
653                 case NOUVEAU_MEM_PCI:
654                 case NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE:
655                         break;
656                 default:
657                         DRM_ERROR("invalid CMDBUF_LOCATION value=%lld\n",
658                                         setparam->value);
659                         return -EINVAL;
660                 }
661                 dev_priv->config.cmdbuf.location = setparam->value;
662                 break;
663         case NOUVEAU_SETPARAM_CMDBUF_SIZE:
664                 dev_priv->config.cmdbuf.size = setparam->value;
665                 break;
666         default:
667                 DRM_ERROR("unknown parameter %lld\n", setparam->param);
668                 return -EINVAL;
669         }
670
671         return 0;
672 }
673
674 /* waits for idle */
675 void nouveau_wait_for_idle(struct drm_device *dev)
676 {
677         struct drm_nouveau_private *dev_priv=dev->dev_private;
678         switch(dev_priv->card_type) {
679         case NV_50:
680                 break;
681         default: {
682                 /* This stuff is more or less a copy of what is seen
683                  * in nv28 kmmio dump.
684                  */
685                 uint64_t started = dev_priv->Engine.timer.read(dev);
686                 uint64_t stopped = started;
687                 uint32_t status;
688                 do {
689                         uint32_t pmc_e = NV_READ(NV03_PMC_ENABLE);
690                         (void)pmc_e;
691                         status = NV_READ(NV04_PGRAPH_STATUS);
692                         if (!status)
693                                 break;
694                         stopped = dev_priv->Engine.timer.read(dev);
695                 /* It'll never wrap anyway... */
696                 } while (stopped - started < 1000000000ULL);
697                 if (status)
698                         DRM_ERROR("timed out with status 0x%08x\n",
699                                   status);
700         }
701         }
702 }
703
704 static int nouveau_suspend(struct drm_device *dev)
705 {
706         struct mem_block *p;
707         struct drm_nouveau_private *dev_priv = dev->dev_private;
708         struct nouveau_suspend_resume *susres = &dev_priv->susres;
709         struct nouveau_engine *engine = &dev_priv->Engine;
710         int i;
711
712         drm_free(susres->ramin_copy, susres->ramin_size, DRM_MEM_DRIVER);
713         susres->ramin_size = 0;
714         list_for_each(p, dev_priv->ramin_heap)
715                 if (p->file_priv && (p->start + p->size) > susres->ramin_size)
716                         susres->ramin_size = p->start + p->size;
717         if (!(susres->ramin_copy = drm_alloc(susres->ramin_size, DRM_MEM_DRIVER))) {
718                 DRM_ERROR("Couldn't alloc RAMIN backing for suspend\n");
719                 return -ENOMEM;
720         }
721
722         for (i = 0; i < engine->fifo.channels; i++) {
723                 uint64_t t_start = engine->timer.read(dev);
724
725                 if (dev_priv->fifos[i] == NULL)
726                         continue;
727
728                 /* Give the channel a chance to idle, wait 2s (hopefully) */
729                 while (!nouveau_channel_idle(dev_priv->fifos[i]))
730                         if (engine->timer.read(dev) - t_start > 2000000000ULL) {
731                                 DRM_ERROR("Failed to idle channel %d before"
732                                           "suspend.", dev_priv->fifos[i]->id);
733                                 return -EBUSY;
734                         }
735         }
736         nouveau_wait_for_idle(dev);
737
738         NV_WRITE(NV04_PGRAPH_FIFO, 0);
739         /* disable the fifo caches */
740         NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
741         NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
742                  NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1);
743         NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
744         NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
745
746         susres->fifo_mode = NV_READ(NV04_PFIFO_MODE);
747
748         if (dev_priv->card_type >= NV_10) {
749                 susres->graph_state = NV_READ(NV10_PGRAPH_STATE);
750                 susres->graph_ctx_control = NV_READ(NV10_PGRAPH_CTX_CONTROL);
751         } else {
752                 susres->graph_state = NV_READ(NV04_PGRAPH_STATE);
753                 susres->graph_ctx_control = NV_READ(NV04_PGRAPH_CTX_CONTROL);
754         }
755
756         engine->fifo.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]);
757         engine->graph.save_context(dev_priv->fifos[engine->fifo.channel_id(dev)]);
758         nouveau_wait_for_idle(dev);
759
760         for (i = 0; i < susres->ramin_size / 4; i++)
761                 susres->ramin_copy[i] = NV_RI32(i << 2);
762
763         /* reenable the fifo caches */
764         NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
765                  NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
766         NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
767         NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
768         NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
769         NV_WRITE(NV04_PGRAPH_FIFO, 1);
770
771         return 0;
772 }
773
774 static int nouveau_resume(struct drm_device *dev)
775 {
776         struct drm_nouveau_private *dev_priv = dev->dev_private;
777         struct nouveau_suspend_resume *susres = &dev_priv->susres;
778         struct nouveau_engine *engine = &dev_priv->Engine;
779         int i;
780
781         if (!susres->ramin_copy)
782                 return -EINVAL;
783
784         DRM_DEBUG("Doing resume\n");
785
786         if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) {
787                 struct drm_agp_info info;
788                 struct drm_agp_mode mode;
789
790                 /* agp bridge drivers don't re-enable agp on resume. lame. */
791                 if ((i = drm_agp_info(dev, &info))) {
792                         DRM_ERROR("Unable to get AGP info: %d\n", i);
793                         return i;
794                 }
795                 mode.mode = info.mode;
796                 if ((i = drm_agp_enable(dev, mode))) {
797                         DRM_ERROR("Unable to enable AGP: %d\n", i);
798                         return i;
799                 }
800         }
801
802         for (i = 0; i < susres->ramin_size / 4; i++)
803                 NV_WI32(i << 2, susres->ramin_copy[i]);
804
805         engine->mc.init(dev);
806         engine->timer.init(dev);
807         engine->fb.init(dev);
808         engine->graph.init(dev);
809         engine->fifo.init(dev);
810
811         NV_WRITE(NV04_PGRAPH_FIFO, 0);
812         /* disable the fifo caches */
813         NV_WRITE(NV03_PFIFO_CACHES, 0x00000000);
814         NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
815                  NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) & ~1);
816         NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000000);
817         NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000000);
818
819         /* PMC power cycling PFIFO in init clobbers some of the stuff stored in
820          * PRAMIN (such as NV04_PFIFO_CACHE1_DMA_INSTANCE). this is unhelpful
821          */
822         for (i = 0; i < susres->ramin_size / 4; i++)
823                 NV_WI32(i << 2, susres->ramin_copy[i]);
824
825         engine->fifo.load_context(dev_priv->fifos[0]);
826         NV_WRITE(NV04_PFIFO_MODE, susres->fifo_mode);
827
828         engine->graph.load_context(dev_priv->fifos[0]);
829         nouveau_wait_for_idle(dev);
830
831         if (dev_priv->card_type >= NV_10) {
832                 NV_WRITE(NV10_PGRAPH_STATE, susres->graph_state);
833                 NV_WRITE(NV10_PGRAPH_CTX_CONTROL, susres->graph_ctx_control);
834         } else {
835                 NV_WRITE(NV04_PGRAPH_STATE, susres->graph_state);
836                 NV_WRITE(NV04_PGRAPH_CTX_CONTROL, susres->graph_ctx_control);
837         }
838
839         /* reenable the fifo caches */
840         NV_WRITE(NV04_PFIFO_CACHE1_DMA_PUSH,
841                  NV_READ(NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
842         NV_WRITE(NV03_PFIFO_CACHE1_PUSH0, 0x00000001);
843         NV_WRITE(NV04_PFIFO_CACHE1_PULL0, 0x00000001);
844         NV_WRITE(NV03_PFIFO_CACHES, 0x00000001);
845         NV_WRITE(NV04_PGRAPH_FIFO, 0x1);
846
847         if (dev->irq_enabled)
848                 nouveau_irq_postinstall(dev);
849
850         drm_free(susres->ramin_copy, susres->ramin_size, DRM_MEM_DRIVER);
851         susres->ramin_copy = NULL;
852         susres->ramin_size = 0;
853
854         return 0;
855 }
856
857 int nouveau_ioctl_suspend(struct drm_device *dev, void *data,
858                                  struct drm_file *file_priv)
859 {
860         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
861
862         return nouveau_suspend(dev);
863 }
864
865 int nouveau_ioctl_resume(struct drm_device *dev, void *data,
866                                 struct drm_file *file_priv)
867 {
868         NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
869
870         return nouveau_resume(dev);
871 }