Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / nouveau / core / engine / device / base.c
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24
25 #include <core/object.h>
26 #include <core/device.h>
27 #include <core/client.h>
28 #include <core/option.h>
29 #include <nvif/unpack.h>
30 #include <nvif/class.h>
31
32 #include <subdev/fb.h>
33 #include <subdev/instmem.h>
34
35 #include "priv.h"
36 #include "acpi.h"
37
38 static DEFINE_MUTEX(nv_devices_mutex);
39 static LIST_HEAD(nv_devices);
40
41 struct nouveau_device *
42 nouveau_device_find(u64 name)
43 {
44         struct nouveau_device *device, *match = NULL;
45         mutex_lock(&nv_devices_mutex);
46         list_for_each_entry(device, &nv_devices, head) {
47                 if (device->handle == name) {
48                         match = device;
49                         break;
50                 }
51         }
52         mutex_unlock(&nv_devices_mutex);
53         return match;
54 }
55
56 int
57 nouveau_device_list(u64 *name, int size)
58 {
59         struct nouveau_device *device;
60         int nr = 0;
61         mutex_lock(&nv_devices_mutex);
62         list_for_each_entry(device, &nv_devices, head) {
63                 if (nr++ < size)
64                         name[nr - 1] = device->handle;
65         }
66         mutex_unlock(&nv_devices_mutex);
67         return nr;
68 }
69
70 /******************************************************************************
71  * nouveau_devobj (0x0080): class implementation
72  *****************************************************************************/
73
74 struct nouveau_devobj {
75         struct nouveau_parent base;
76         struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
77 };
78
79 static int
80 nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size)
81 {
82         struct nouveau_device *device = nv_device(object);
83         struct nouveau_fb *pfb = nouveau_fb(device);
84         struct nouveau_instmem *imem = nouveau_instmem(device);
85         union {
86                 struct nv_device_info_v0 v0;
87         } *args = data;
88         int ret;
89
90         nv_ioctl(object, "device info size %d\n", size);
91         if (nvif_unpack(args->v0, 0, 0, false)) {
92                 nv_ioctl(object, "device info vers %d\n", args->v0.version);
93         } else
94                 return ret;
95
96         switch (device->chipset) {
97         case 0x01a:
98         case 0x01f:
99         case 0x04c:
100         case 0x04e:
101         case 0x063:
102         case 0x067:
103         case 0x068:
104         case 0x0aa:
105         case 0x0ac:
106         case 0x0af:
107                 args->v0.platform = NV_DEVICE_INFO_V0_IGP;
108                 break;
109         default:
110                 if (device->pdev) {
111                         if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP))
112                                 args->v0.platform = NV_DEVICE_INFO_V0_AGP;
113                         else
114                         if (pci_is_pcie(device->pdev))
115                                 args->v0.platform = NV_DEVICE_INFO_V0_PCIE;
116                         else
117                                 args->v0.platform = NV_DEVICE_INFO_V0_PCI;
118                 } else {
119                         args->v0.platform = NV_DEVICE_INFO_V0_SOC;
120                 }
121                 break;
122         }
123
124         switch (device->card_type) {
125         case NV_04: args->v0.family = NV_DEVICE_INFO_V0_TNT; break;
126         case NV_10:
127         case NV_11: args->v0.family = NV_DEVICE_INFO_V0_CELSIUS; break;
128         case NV_20: args->v0.family = NV_DEVICE_INFO_V0_KELVIN; break;
129         case NV_30: args->v0.family = NV_DEVICE_INFO_V0_RANKINE; break;
130         case NV_40: args->v0.family = NV_DEVICE_INFO_V0_CURIE; break;
131         case NV_50: args->v0.family = NV_DEVICE_INFO_V0_TESLA; break;
132         case NV_C0: args->v0.family = NV_DEVICE_INFO_V0_FERMI; break;
133         case NV_E0: args->v0.family = NV_DEVICE_INFO_V0_KEPLER; break;
134         case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break;
135         default:
136                 args->v0.family = 0;
137                 break;
138         }
139
140         args->v0.chipset  = device->chipset;
141         args->v0.revision = device->chipset >= 0x10 ? nv_rd32(device, 0) : 0x00;
142         if (pfb)  args->v0.ram_size = args->v0.ram_user = pfb->ram->size;
143         else      args->v0.ram_size = args->v0.ram_user = 0;
144         if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved;
145         return 0;
146 }
147
148 static int
149 nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd,
150                     void *data, u32 size)
151 {
152         switch (mthd) {
153         case NV_DEVICE_V0_INFO:
154                 return nouveau_devobj_info(object, data, size);
155         default:
156                 break;
157         }
158         return -EINVAL;
159 }
160
161 static u8
162 nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
163 {
164         return nv_rd08(object->engine, addr);
165 }
166
167 static u16
168 nouveau_devobj_rd16(struct nouveau_object *object, u64 addr)
169 {
170         return nv_rd16(object->engine, addr);
171 }
172
173 static u32
174 nouveau_devobj_rd32(struct nouveau_object *object, u64 addr)
175 {
176         return nv_rd32(object->engine, addr);
177 }
178
179 static void
180 nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data)
181 {
182         nv_wr08(object->engine, addr, data);
183 }
184
185 static void
186 nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data)
187 {
188         nv_wr16(object->engine, addr, data);
189 }
190
191 static void
192 nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
193 {
194         nv_wr32(object->engine, addr, data);
195 }
196
197 static int
198 nouveau_devobj_map(struct nouveau_object *object, u64 *addr, u32 *size)
199 {
200         struct nouveau_device *device = nv_device(object);
201         *addr = nv_device_resource_start(device, 0);
202         *size = nv_device_resource_len(device, 0);
203         return 0;
204 }
205
206 static const u64 disable_map[] = {
207         [NVDEV_SUBDEV_VBIOS]    = NV_DEVICE_V0_DISABLE_VBIOS,
208         [NVDEV_SUBDEV_DEVINIT]  = NV_DEVICE_V0_DISABLE_CORE,
209         [NVDEV_SUBDEV_GPIO]     = NV_DEVICE_V0_DISABLE_CORE,
210         [NVDEV_SUBDEV_I2C]      = NV_DEVICE_V0_DISABLE_CORE,
211         [NVDEV_SUBDEV_CLOCK]    = NV_DEVICE_V0_DISABLE_CORE,
212         [NVDEV_SUBDEV_MXM]      = NV_DEVICE_V0_DISABLE_CORE,
213         [NVDEV_SUBDEV_MC]       = NV_DEVICE_V0_DISABLE_CORE,
214         [NVDEV_SUBDEV_BUS]      = NV_DEVICE_V0_DISABLE_CORE,
215         [NVDEV_SUBDEV_TIMER]    = NV_DEVICE_V0_DISABLE_CORE,
216         [NVDEV_SUBDEV_FB]       = NV_DEVICE_V0_DISABLE_CORE,
217         [NVDEV_SUBDEV_LTC]      = NV_DEVICE_V0_DISABLE_CORE,
218         [NVDEV_SUBDEV_IBUS]     = NV_DEVICE_V0_DISABLE_CORE,
219         [NVDEV_SUBDEV_INSTMEM]  = NV_DEVICE_V0_DISABLE_CORE,
220         [NVDEV_SUBDEV_VM]       = NV_DEVICE_V0_DISABLE_CORE,
221         [NVDEV_SUBDEV_BAR]      = NV_DEVICE_V0_DISABLE_CORE,
222         [NVDEV_SUBDEV_VOLT]     = NV_DEVICE_V0_DISABLE_CORE,
223         [NVDEV_SUBDEV_THERM]    = NV_DEVICE_V0_DISABLE_CORE,
224         [NVDEV_SUBDEV_PWR]      = NV_DEVICE_V0_DISABLE_CORE,
225         [NVDEV_ENGINE_DMAOBJ]   = NV_DEVICE_V0_DISABLE_CORE,
226         [NVDEV_ENGINE_PERFMON]  = NV_DEVICE_V0_DISABLE_CORE,
227         [NVDEV_ENGINE_FIFO]     = NV_DEVICE_V0_DISABLE_FIFO,
228         [NVDEV_ENGINE_SW]       = NV_DEVICE_V0_DISABLE_FIFO,
229         [NVDEV_ENGINE_GR]       = NV_DEVICE_V0_DISABLE_GRAPH,
230         [NVDEV_ENGINE_MPEG]     = NV_DEVICE_V0_DISABLE_MPEG,
231         [NVDEV_ENGINE_ME]       = NV_DEVICE_V0_DISABLE_ME,
232         [NVDEV_ENGINE_VP]       = NV_DEVICE_V0_DISABLE_VP,
233         [NVDEV_ENGINE_CRYPT]    = NV_DEVICE_V0_DISABLE_CRYPT,
234         [NVDEV_ENGINE_BSP]      = NV_DEVICE_V0_DISABLE_BSP,
235         [NVDEV_ENGINE_PPP]      = NV_DEVICE_V0_DISABLE_PPP,
236         [NVDEV_ENGINE_COPY0]    = NV_DEVICE_V0_DISABLE_COPY0,
237         [NVDEV_ENGINE_COPY1]    = NV_DEVICE_V0_DISABLE_COPY1,
238         [NVDEV_ENGINE_VIC]      = NV_DEVICE_V0_DISABLE_VIC,
239         [NVDEV_ENGINE_VENC]     = NV_DEVICE_V0_DISABLE_VENC,
240         [NVDEV_ENGINE_DISP]     = NV_DEVICE_V0_DISABLE_DISP,
241         [NVDEV_SUBDEV_NR]       = 0,
242 };
243
244 static void
245 nouveau_devobj_dtor(struct nouveau_object *object)
246 {
247         struct nouveau_devobj *devobj = (void *)object;
248         int i;
249
250         for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
251                 nouveau_object_ref(NULL, &devobj->subdev[i]);
252
253         nouveau_parent_destroy(&devobj->base);
254 }
255
256 static struct nouveau_oclass
257 nouveau_devobj_oclass_super = {
258         .handle = NV_DEVICE,
259         .ofuncs = &(struct nouveau_ofuncs) {
260                 .dtor = nouveau_devobj_dtor,
261                 .init = _nouveau_parent_init,
262                 .fini = _nouveau_parent_fini,
263                 .mthd = nouveau_devobj_mthd,
264                 .map  = nouveau_devobj_map,
265                 .rd08 = nouveau_devobj_rd08,
266                 .rd16 = nouveau_devobj_rd16,
267                 .rd32 = nouveau_devobj_rd32,
268                 .wr08 = nouveau_devobj_wr08,
269                 .wr16 = nouveau_devobj_wr16,
270                 .wr32 = nouveau_devobj_wr32,
271         }
272 };
273
274 static int
275 nouveau_devobj_ctor(struct nouveau_object *parent,
276                     struct nouveau_object *engine,
277                     struct nouveau_oclass *oclass, void *data, u32 size,
278                     struct nouveau_object **pobject)
279 {
280         union {
281                 struct nv_device_v0 v0;
282         } *args = data;
283         struct nouveau_client *client = nv_client(parent);
284         struct nouveau_device *device;
285         struct nouveau_devobj *devobj;
286         u32 boot0, strap;
287         u64 disable, mmio_base, mmio_size;
288         void __iomem *map;
289         int ret, i, c;
290
291         nv_ioctl(parent, "create device size %d\n", size);
292         if (nvif_unpack(args->v0, 0, 0, false)) {
293                 nv_ioctl(parent, "create device v%d device %016llx "
294                                  "disable %016llx debug0 %016llx\n",
295                          args->v0.version, args->v0.device,
296                          args->v0.disable, args->v0.debug0);
297         } else
298                 return ret;
299
300         /* give priviledged clients register access */
301         if (client->super)
302                 oclass = &nouveau_devobj_oclass_super;
303
304         /* find the device subdev that matches what the client requested */
305         device = nv_device(client->device);
306         if (args->v0.device != ~0) {
307                 device = nouveau_device_find(args->v0.device);
308                 if (!device)
309                         return -ENODEV;
310         }
311
312         ret = nouveau_parent_create(parent, nv_object(device), oclass, 0,
313                                     nouveau_control_oclass,
314                                     (1ULL << NVDEV_ENGINE_DMAOBJ) |
315                                     (1ULL << NVDEV_ENGINE_FIFO) |
316                                     (1ULL << NVDEV_ENGINE_DISP) |
317                                     (1ULL << NVDEV_ENGINE_PERFMON), &devobj);
318         *pobject = nv_object(devobj);
319         if (ret)
320                 return ret;
321
322         mmio_base = nv_device_resource_start(device, 0);
323         mmio_size = nv_device_resource_len(device, 0);
324
325         /* translate api disable mask into internal mapping */
326         disable = args->v0.debug0;
327         for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
328                 if (args->v0.disable & disable_map[i])
329                         disable |= (1ULL << i);
330         }
331
332         /* identify the chipset, and determine classes of subdev/engines */
333         if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY) &&
334             !device->card_type) {
335                 map = ioremap(mmio_base, 0x102000);
336                 if (map == NULL)
337                         return -ENOMEM;
338
339                 /* switch mmio to cpu's native endianness */
340 #ifndef __BIG_ENDIAN
341                 if (ioread32_native(map + 0x000004) != 0x00000000)
342 #else
343                 if (ioread32_native(map + 0x000004) == 0x00000000)
344 #endif
345                         iowrite32_native(0x01000001, map + 0x000004);
346
347                 /* read boot0 and strapping information */
348                 boot0 = ioread32_native(map + 0x000000);
349                 strap = ioread32_native(map + 0x101000);
350                 iounmap(map);
351
352                 /* determine chipset and derive architecture from it */
353                 if ((boot0 & 0x1f000000) > 0) {
354                         device->chipset = (boot0 & 0x1ff00000) >> 20;
355                         switch (device->chipset & 0x1f0) {
356                         case 0x010: {
357                                 if (0x461 & (1 << (device->chipset & 0xf)))
358                                         device->card_type = NV_10;
359                                 else
360                                         device->card_type = NV_11;
361                                 break;
362                         }
363                         case 0x020: device->card_type = NV_20; break;
364                         case 0x030: device->card_type = NV_30; break;
365                         case 0x040:
366                         case 0x060: device->card_type = NV_40; break;
367                         case 0x050:
368                         case 0x080:
369                         case 0x090:
370                         case 0x0a0: device->card_type = NV_50; break;
371                         case 0x0c0:
372                         case 0x0d0: device->card_type = NV_C0; break;
373                         case 0x0e0:
374                         case 0x0f0:
375                         case 0x100: device->card_type = NV_E0; break;
376                         case 0x110: device->card_type = GM100; break;
377                         default:
378                                 break;
379                         }
380                 } else
381                 if ((boot0 & 0xff00fff0) == 0x20004000) {
382                         if (boot0 & 0x00f00000)
383                                 device->chipset = 0x05;
384                         else
385                                 device->chipset = 0x04;
386                         device->card_type = NV_04;
387                 }
388
389                 switch (device->card_type) {
390                 case NV_04: ret = nv04_identify(device); break;
391                 case NV_10:
392                 case NV_11: ret = nv10_identify(device); break;
393                 case NV_20: ret = nv20_identify(device); break;
394                 case NV_30: ret = nv30_identify(device); break;
395                 case NV_40: ret = nv40_identify(device); break;
396                 case NV_50: ret = nv50_identify(device); break;
397                 case NV_C0: ret = nvc0_identify(device); break;
398                 case NV_E0: ret = nve0_identify(device); break;
399                 case GM100: ret = gm100_identify(device); break;
400                 default:
401                         ret = -EINVAL;
402                         break;
403                 }
404
405                 if (ret) {
406                         nv_error(device, "unknown chipset, 0x%08x\n", boot0);
407                         return ret;
408                 }
409
410                 nv_info(device, "BOOT0  : 0x%08x\n", boot0);
411                 nv_info(device, "Chipset: %s (NV%02X)\n",
412                         device->cname, device->chipset);
413                 nv_info(device, "Family : NV%02X\n", device->card_type);
414
415                 /* determine frequency of timing crystal */
416                 if ( device->card_type <= NV_10 || device->chipset < 0x17 ||
417                     (device->chipset >= 0x20 && device->chipset < 0x25))
418                         strap &= 0x00000040;
419                 else
420                         strap &= 0x00400040;
421
422                 switch (strap) {
423                 case 0x00000000: device->crystal = 13500; break;
424                 case 0x00000040: device->crystal = 14318; break;
425                 case 0x00400000: device->crystal = 27000; break;
426                 case 0x00400040: device->crystal = 25000; break;
427                 }
428
429                 nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
430         }
431
432         if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) &&
433             !nv_subdev(device)->mmio) {
434                 nv_subdev(device)->mmio  = ioremap(mmio_base, mmio_size);
435                 if (!nv_subdev(device)->mmio) {
436                         nv_error(device, "unable to map device registers\n");
437                         return -ENOMEM;
438                 }
439         }
440
441         /* ensure requested subsystems are available for use */
442         for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
443                 if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
444                         continue;
445
446                 if (device->subdev[i]) {
447                         nouveau_object_ref(device->subdev[i],
448                                           &devobj->subdev[i]);
449                         continue;
450                 }
451
452                 ret = nouveau_object_ctor(nv_object(device), NULL,
453                                           oclass, NULL, i,
454                                           &devobj->subdev[i]);
455                 if (ret == -ENODEV)
456                         continue;
457                 if (ret)
458                         return ret;
459
460                 device->subdev[i] = devobj->subdev[i];
461
462                 /* note: can't init *any* subdevs until devinit has been run
463                  * due to not knowing exactly what the vbios init tables will
464                  * mess with.  devinit also can't be run until all of its
465                  * dependencies have been created.
466                  *
467                  * this code delays init of any subdev until all of devinit's
468                  * dependencies have been created, and then initialises each
469                  * subdev in turn as they're created.
470                  */
471                 while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) {
472                         struct nouveau_object *subdev = devobj->subdev[c++];
473                         if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) {
474                                 ret = nouveau_object_inc(subdev);
475                                 if (ret)
476                                         return ret;
477                                 atomic_dec(&nv_object(device)->usecount);
478                         } else
479                         if (subdev) {
480                                 nouveau_subdev_reset(subdev);
481                         }
482                 }
483         }
484
485         return 0;
486 }
487
488 static struct nouveau_ofuncs
489 nouveau_devobj_ofuncs = {
490         .ctor = nouveau_devobj_ctor,
491         .dtor = nouveau_devobj_dtor,
492         .init = _nouveau_parent_init,
493         .fini = _nouveau_parent_fini,
494         .mthd = nouveau_devobj_mthd,
495 };
496
497 /******************************************************************************
498  * nouveau_device: engine functions
499  *****************************************************************************/
500
501 static struct nouveau_oclass
502 nouveau_device_sclass[] = {
503         { 0x0080, &nouveau_devobj_ofuncs },
504         {}
505 };
506
507 static int
508 nouveau_device_event_ctor(void *data, u32 size, struct nvkm_notify *notify)
509 {
510         if (!WARN_ON(size != 0)) {
511                 notify->size  = 0;
512                 notify->types = 1;
513                 notify->index = 0;
514                 return 0;
515         }
516         return -EINVAL;
517 }
518
519 static const struct nvkm_event_func
520 nouveau_device_event_func = {
521         .ctor = nouveau_device_event_ctor,
522 };
523
524 static int
525 nouveau_device_fini(struct nouveau_object *object, bool suspend)
526 {
527         struct nouveau_device *device = (void *)object;
528         struct nouveau_object *subdev;
529         int ret, i;
530
531         for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
532                 if ((subdev = device->subdev[i])) {
533                         if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
534                                 ret = nouveau_object_dec(subdev, suspend);
535                                 if (ret && suspend)
536                                         goto fail;
537                         }
538                 }
539         }
540
541         ret = nvkm_acpi_fini(device, suspend);
542 fail:
543         for (; ret && i < NVDEV_SUBDEV_NR; i++) {
544                 if ((subdev = device->subdev[i])) {
545                         if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
546                                 ret = nouveau_object_inc(subdev);
547                                 if (ret) {
548                                         /* XXX */
549                                 }
550                         }
551                 }
552         }
553
554         return ret;
555 }
556
557 static int
558 nouveau_device_init(struct nouveau_object *object)
559 {
560         struct nouveau_device *device = (void *)object;
561         struct nouveau_object *subdev;
562         int ret, i = 0;
563
564         ret = nvkm_acpi_init(device);
565         if (ret)
566                 goto fail;
567
568         for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
569                 if ((subdev = device->subdev[i])) {
570                         if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
571                                 ret = nouveau_object_inc(subdev);
572                                 if (ret)
573                                         goto fail;
574                         } else {
575                                 nouveau_subdev_reset(subdev);
576                         }
577                 }
578         }
579
580         ret = 0;
581 fail:
582         for (--i; ret && i >= 0; i--) {
583                 if ((subdev = device->subdev[i])) {
584                         if (!nv_iclass(subdev, NV_ENGINE_CLASS))
585                                 nouveau_object_dec(subdev, false);
586                 }
587         }
588
589         if (ret)
590                 nvkm_acpi_fini(device, false);
591         return ret;
592 }
593
594 static void
595 nouveau_device_dtor(struct nouveau_object *object)
596 {
597         struct nouveau_device *device = (void *)object;
598
599         nvkm_event_fini(&device->event);
600
601         mutex_lock(&nv_devices_mutex);
602         list_del(&device->head);
603         mutex_unlock(&nv_devices_mutex);
604
605         if (nv_subdev(device)->mmio)
606                 iounmap(nv_subdev(device)->mmio);
607
608         nouveau_engine_destroy(&device->base);
609 }
610
611 resource_size_t
612 nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
613 {
614         if (nv_device_is_pci(device)) {
615                 return pci_resource_start(device->pdev, bar);
616         } else {
617                 struct resource *res;
618                 res = platform_get_resource(device->platformdev,
619                                             IORESOURCE_MEM, bar);
620                 if (!res)
621                         return 0;
622                 return res->start;
623         }
624 }
625
626 resource_size_t
627 nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
628 {
629         if (nv_device_is_pci(device)) {
630                 return pci_resource_len(device->pdev, bar);
631         } else {
632                 struct resource *res;
633                 res = platform_get_resource(device->platformdev,
634                                             IORESOURCE_MEM, bar);
635                 if (!res)
636                         return 0;
637                 return resource_size(res);
638         }
639 }
640
641 int
642 nv_device_get_irq(struct nouveau_device *device, bool stall)
643 {
644         if (nv_device_is_pci(device)) {
645                 return device->pdev->irq;
646         } else {
647                 return platform_get_irq_byname(device->platformdev,
648                                                stall ? "stall" : "nonstall");
649         }
650 }
651
652 static struct nouveau_oclass
653 nouveau_device_oclass = {
654         .handle = NV_ENGINE(DEVICE, 0x00),
655         .ofuncs = &(struct nouveau_ofuncs) {
656                 .dtor = nouveau_device_dtor,
657                 .init = nouveau_device_init,
658                 .fini = nouveau_device_fini,
659         },
660 };
661
662 int
663 nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
664                        const char *sname, const char *cfg, const char *dbg,
665                        int length, void **pobject)
666 {
667         struct nouveau_device *device;
668         int ret = -EEXIST;
669
670         mutex_lock(&nv_devices_mutex);
671         list_for_each_entry(device, &nv_devices, head) {
672                 if (device->handle == name)
673                         goto done;
674         }
675
676         ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
677                                      "DEVICE", "device", length, pobject);
678         device = *pobject;
679         if (ret)
680                 goto done;
681
682         switch (type) {
683         case NOUVEAU_BUS_PCI:
684                 device->pdev = dev;
685                 break;
686         case NOUVEAU_BUS_PLATFORM:
687                 device->platformdev = dev;
688                 break;
689         }
690         device->handle = name;
691         device->cfgopt = cfg;
692         device->dbgopt = dbg;
693         device->name = sname;
694
695         nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
696         nv_engine(device)->sclass = nouveau_device_sclass;
697         list_add(&device->head, &nv_devices);
698
699         ret = nvkm_event_init(&nouveau_device_event_func, 1, 1,
700                               &device->event);
701 done:
702         mutex_unlock(&nv_devices_mutex);
703         return ret;
704 }