2 * Copyright 2012 Red Hat Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <core/object.h>
26 #include <core/device.h>
27 #include <core/client.h>
28 #include <core/option.h>
30 #include <core/class.h>
32 #include <engine/device.h>
34 static DEFINE_MUTEX(nv_devices_mutex
);
35 static LIST_HEAD(nv_devices
);
37 struct nouveau_device
*
38 nouveau_device_find(u64 name
)
40 struct nouveau_device
*device
, *match
= NULL
;
41 mutex_lock(&nv_devices_mutex
);
42 list_for_each_entry(device
, &nv_devices
, head
) {
43 if (device
->handle
== name
) {
48 mutex_unlock(&nv_devices_mutex
);
52 /******************************************************************************
53 * nouveau_devobj (0x0080): class implementation
54 *****************************************************************************/
55 struct nouveau_devobj
{
56 struct nouveau_parent base
;
57 struct nouveau_object
*subdev
[NVDEV_SUBDEV_NR
];
60 static const u64 disable_map
[] = {
61 [NVDEV_SUBDEV_VBIOS
] = NV_DEVICE_DISABLE_VBIOS
,
62 [NVDEV_SUBDEV_DEVINIT
] = NV_DEVICE_DISABLE_CORE
,
63 [NVDEV_SUBDEV_GPIO
] = NV_DEVICE_DISABLE_CORE
,
64 [NVDEV_SUBDEV_I2C
] = NV_DEVICE_DISABLE_CORE
,
65 [NVDEV_SUBDEV_CLOCK
] = NV_DEVICE_DISABLE_CORE
,
66 [NVDEV_SUBDEV_MXM
] = NV_DEVICE_DISABLE_CORE
,
67 [NVDEV_SUBDEV_MC
] = NV_DEVICE_DISABLE_CORE
,
68 [NVDEV_SUBDEV_BUS
] = NV_DEVICE_DISABLE_CORE
,
69 [NVDEV_SUBDEV_TIMER
] = NV_DEVICE_DISABLE_CORE
,
70 [NVDEV_SUBDEV_FB
] = NV_DEVICE_DISABLE_CORE
,
71 [NVDEV_SUBDEV_LTCG
] = NV_DEVICE_DISABLE_CORE
,
72 [NVDEV_SUBDEV_IBUS
] = NV_DEVICE_DISABLE_CORE
,
73 [NVDEV_SUBDEV_INSTMEM
] = NV_DEVICE_DISABLE_CORE
,
74 [NVDEV_SUBDEV_VM
] = NV_DEVICE_DISABLE_CORE
,
75 [NVDEV_SUBDEV_BAR
] = NV_DEVICE_DISABLE_CORE
,
76 [NVDEV_SUBDEV_VOLT
] = NV_DEVICE_DISABLE_CORE
,
77 [NVDEV_SUBDEV_THERM
] = NV_DEVICE_DISABLE_CORE
,
78 [NVDEV_ENGINE_DMAOBJ
] = NV_DEVICE_DISABLE_CORE
,
79 [NVDEV_ENGINE_FIFO
] = NV_DEVICE_DISABLE_FIFO
,
80 [NVDEV_ENGINE_SW
] = NV_DEVICE_DISABLE_FIFO
,
81 [NVDEV_ENGINE_GR
] = NV_DEVICE_DISABLE_GRAPH
,
82 [NVDEV_ENGINE_MPEG
] = NV_DEVICE_DISABLE_MPEG
,
83 [NVDEV_ENGINE_ME
] = NV_DEVICE_DISABLE_ME
,
84 [NVDEV_ENGINE_VP
] = NV_DEVICE_DISABLE_VP
,
85 [NVDEV_ENGINE_CRYPT
] = NV_DEVICE_DISABLE_CRYPT
,
86 [NVDEV_ENGINE_BSP
] = NV_DEVICE_DISABLE_BSP
,
87 [NVDEV_ENGINE_PPP
] = NV_DEVICE_DISABLE_PPP
,
88 [NVDEV_ENGINE_COPY0
] = NV_DEVICE_DISABLE_COPY0
,
89 [NVDEV_ENGINE_COPY1
] = NV_DEVICE_DISABLE_COPY1
,
90 [NVDEV_ENGINE_VIC
] = NV_DEVICE_DISABLE_VIC
,
91 [NVDEV_ENGINE_VENC
] = NV_DEVICE_DISABLE_VENC
,
92 [NVDEV_ENGINE_DISP
] = NV_DEVICE_DISABLE_DISP
,
93 [NVDEV_SUBDEV_NR
] = 0,
97 nouveau_devobj_ctor(struct nouveau_object
*parent
,
98 struct nouveau_object
*engine
,
99 struct nouveau_oclass
*oclass
, void *data
, u32 size
,
100 struct nouveau_object
**pobject
)
102 struct nouveau_client
*client
= nv_client(parent
);
103 struct nouveau_device
*device
;
104 struct nouveau_devobj
*devobj
;
105 struct nv_device_class
*args
= data
;
107 u64 disable
, mmio_base
, mmio_size
;
111 if (size
< sizeof(struct nv_device_class
))
114 /* find the device subdev that matches what the client requested */
115 device
= nv_device(client
->device
);
116 if (args
->device
!= ~0) {
117 device
= nouveau_device_find(args
->device
);
122 ret
= nouveau_parent_create(parent
, nv_object(device
), oclass
, 0, NULL
,
123 (1ULL << NVDEV_ENGINE_DMAOBJ
) |
124 (1ULL << NVDEV_ENGINE_FIFO
) |
125 (1ULL << NVDEV_ENGINE_DISP
), &devobj
);
126 *pobject
= nv_object(devobj
);
130 mmio_base
= pci_resource_start(device
->pdev
, 0);
131 mmio_size
= pci_resource_len(device
->pdev
, 0);
133 /* translate api disable mask into internal mapping */
134 disable
= args
->debug0
;
135 for (i
= 0; i
< NVDEV_SUBDEV_NR
; i
++) {
136 if (args
->disable
& disable_map
[i
])
137 disable
|= (1ULL << i
);
140 /* identify the chipset, and determine classes of subdev/engines */
141 if (!(args
->disable
& NV_DEVICE_DISABLE_IDENTIFY
) &&
142 !device
->card_type
) {
143 map
= ioremap(mmio_base
, 0x102000);
147 /* switch mmio to cpu's native endianness */
149 if (ioread32_native(map
+ 0x000004) != 0x00000000)
151 if (ioread32_native(map
+ 0x000004) == 0x00000000)
153 iowrite32_native(0x01000001, map
+ 0x000004);
155 /* read boot0 and strapping information */
156 boot0
= ioread32_native(map
+ 0x000000);
157 strap
= ioread32_native(map
+ 0x101000);
160 /* determine chipset and derive architecture from it */
161 if ((boot0
& 0x0f000000) > 0) {
162 device
->chipset
= (boot0
& 0xff00000) >> 20;
163 switch (device
->chipset
& 0xf0) {
164 case 0x10: device
->card_type
= NV_10
; break;
165 case 0x20: device
->card_type
= NV_20
; break;
166 case 0x30: device
->card_type
= NV_30
; break;
168 case 0x60: device
->card_type
= NV_40
; break;
172 case 0xa0: device
->card_type
= NV_50
; break;
173 case 0xc0: device
->card_type
= NV_C0
; break;
174 case 0xd0: device
->card_type
= NV_D0
; break;
176 case 0xf0: device
->card_type
= NV_E0
; break;
181 if ((boot0
& 0xff00fff0) == 0x20004000) {
182 if (boot0
& 0x00f00000)
183 device
->chipset
= 0x05;
185 device
->chipset
= 0x04;
186 device
->card_type
= NV_04
;
189 switch (device
->card_type
) {
190 case NV_04
: ret
= nv04_identify(device
); break;
191 case NV_10
: ret
= nv10_identify(device
); break;
192 case NV_20
: ret
= nv20_identify(device
); break;
193 case NV_30
: ret
= nv30_identify(device
); break;
194 case NV_40
: ret
= nv40_identify(device
); break;
195 case NV_50
: ret
= nv50_identify(device
); break;
197 case NV_D0
: ret
= nvc0_identify(device
); break;
198 case NV_E0
: ret
= nve0_identify(device
); break;
205 nv_error(device
, "unknown chipset, 0x%08x\n", boot0
);
209 nv_info(device
, "BOOT0 : 0x%08x\n", boot0
);
210 nv_info(device
, "Chipset: %s (NV%02X)\n",
211 device
->cname
, device
->chipset
);
212 nv_info(device
, "Family : NV%02X\n", device
->card_type
);
214 /* determine frequency of timing crystal */
215 if ( device
->chipset
< 0x17 ||
216 (device
->chipset
>= 0x20 && device
->chipset
< 0x25))
222 case 0x00000000: device
->crystal
= 13500; break;
223 case 0x00000040: device
->crystal
= 14318; break;
224 case 0x00400000: device
->crystal
= 27000; break;
225 case 0x00400040: device
->crystal
= 25000; break;
228 nv_debug(device
, "crystal freq: %dKHz\n", device
->crystal
);
231 if (!(args
->disable
& NV_DEVICE_DISABLE_MMIO
) &&
232 !nv_subdev(device
)->mmio
) {
233 nv_subdev(device
)->mmio
= ioremap(mmio_base
, mmio_size
);
234 if (!nv_subdev(device
)->mmio
) {
235 nv_error(device
, "unable to map device registers\n");
240 /* ensure requested subsystems are available for use */
241 for (i
= 1, c
= 1; i
< NVDEV_SUBDEV_NR
; i
++) {
242 if (!(oclass
= device
->oclass
[i
]) || (disable
& (1ULL << i
)))
245 if (device
->subdev
[i
]) {
246 nouveau_object_ref(device
->subdev
[i
],
251 ret
= nouveau_object_ctor(nv_object(device
), NULL
,
259 /* note: can't init *any* subdevs until devinit has been run
260 * due to not knowing exactly what the vbios init tables will
261 * mess with. devinit also can't be run until all of its
262 * dependencies have been created.
264 * this code delays init of any subdev until all of devinit's
265 * dependencies have been created, and then initialises each
266 * subdev in turn as they're created.
268 while (i
>= NVDEV_SUBDEV_DEVINIT_LAST
&& c
<= i
) {
269 struct nouveau_object
*subdev
= devobj
->subdev
[c
++];
270 if (subdev
&& !nv_iclass(subdev
, NV_ENGINE_CLASS
)) {
271 ret
= nouveau_object_inc(subdev
);
274 atomic_dec(&nv_object(device
)->usecount
);
277 nouveau_subdev_reset(subdev
);
286 nouveau_devobj_dtor(struct nouveau_object
*object
)
288 struct nouveau_devobj
*devobj
= (void *)object
;
291 for (i
= NVDEV_SUBDEV_NR
- 1; i
>= 0; i
--)
292 nouveau_object_ref(NULL
, &devobj
->subdev
[i
]);
294 nouveau_parent_destroy(&devobj
->base
);
298 nouveau_devobj_rd08(struct nouveau_object
*object
, u64 addr
)
300 return nv_rd08(object
->engine
, addr
);
304 nouveau_devobj_rd16(struct nouveau_object
*object
, u64 addr
)
306 return nv_rd16(object
->engine
, addr
);
310 nouveau_devobj_rd32(struct nouveau_object
*object
, u64 addr
)
312 return nv_rd32(object
->engine
, addr
);
316 nouveau_devobj_wr08(struct nouveau_object
*object
, u64 addr
, u8 data
)
318 nv_wr08(object
->engine
, addr
, data
);
322 nouveau_devobj_wr16(struct nouveau_object
*object
, u64 addr
, u16 data
)
324 nv_wr16(object
->engine
, addr
, data
);
328 nouveau_devobj_wr32(struct nouveau_object
*object
, u64 addr
, u32 data
)
330 nv_wr32(object
->engine
, addr
, data
);
333 static struct nouveau_ofuncs
334 nouveau_devobj_ofuncs
= {
335 .ctor
= nouveau_devobj_ctor
,
336 .dtor
= nouveau_devobj_dtor
,
337 .init
= _nouveau_parent_init
,
338 .fini
= _nouveau_parent_fini
,
339 .rd08
= nouveau_devobj_rd08
,
340 .rd16
= nouveau_devobj_rd16
,
341 .rd32
= nouveau_devobj_rd32
,
342 .wr08
= nouveau_devobj_wr08
,
343 .wr16
= nouveau_devobj_wr16
,
344 .wr32
= nouveau_devobj_wr32
,
347 /******************************************************************************
348 * nouveau_device: engine functions
349 *****************************************************************************/
350 static struct nouveau_oclass
351 nouveau_device_sclass
[] = {
352 { 0x0080, &nouveau_devobj_ofuncs
},
357 nouveau_device_fini(struct nouveau_object
*object
, bool suspend
)
359 struct nouveau_device
*device
= (void *)object
;
360 struct nouveau_object
*subdev
;
363 for (i
= NVDEV_SUBDEV_NR
- 1; i
>= 0; i
--) {
364 if ((subdev
= device
->subdev
[i
])) {
365 if (!nv_iclass(subdev
, NV_ENGINE_CLASS
)) {
366 ret
= nouveau_object_dec(subdev
, suspend
);
375 for (; ret
&& i
< NVDEV_SUBDEV_NR
; i
++) {
376 if ((subdev
= device
->subdev
[i
])) {
377 if (!nv_iclass(subdev
, NV_ENGINE_CLASS
)) {
378 ret
= nouveau_object_inc(subdev
);
390 nouveau_device_init(struct nouveau_object
*object
)
392 struct nouveau_device
*device
= (void *)object
;
393 struct nouveau_object
*subdev
;
396 for (i
= 0; i
< NVDEV_SUBDEV_NR
; i
++) {
397 if ((subdev
= device
->subdev
[i
])) {
398 if (!nv_iclass(subdev
, NV_ENGINE_CLASS
)) {
399 ret
= nouveau_object_inc(subdev
);
403 nouveau_subdev_reset(subdev
);
410 for (--i
; ret
&& i
>= 0; i
--) {
411 if ((subdev
= device
->subdev
[i
])) {
412 if (!nv_iclass(subdev
, NV_ENGINE_CLASS
))
413 nouveau_object_dec(subdev
, false);
421 nouveau_device_dtor(struct nouveau_object
*object
)
423 struct nouveau_device
*device
= (void *)object
;
425 mutex_lock(&nv_devices_mutex
);
426 list_del(&device
->head
);
427 mutex_unlock(&nv_devices_mutex
);
429 if (nv_subdev(device
)->mmio
)
430 iounmap(nv_subdev(device
)->mmio
);
432 nouveau_engine_destroy(&device
->base
);
435 static struct nouveau_oclass
436 nouveau_device_oclass
= {
437 .handle
= NV_ENGINE(DEVICE
, 0x00),
438 .ofuncs
= &(struct nouveau_ofuncs
) {
439 .dtor
= nouveau_device_dtor
,
440 .init
= nouveau_device_init
,
441 .fini
= nouveau_device_fini
,
446 nouveau_device_create_(struct pci_dev
*pdev
, u64 name
, const char *sname
,
447 const char *cfg
, const char *dbg
,
448 int length
, void **pobject
)
450 struct nouveau_device
*device
;
453 mutex_lock(&nv_devices_mutex
);
454 list_for_each_entry(device
, &nv_devices
, head
) {
455 if (device
->handle
== name
)
459 ret
= nouveau_engine_create_(NULL
, NULL
, &nouveau_device_oclass
, true,
460 "DEVICE", "device", length
, pobject
);
466 device
->handle
= name
;
467 device
->cfgopt
= cfg
;
468 device
->dbgopt
= dbg
;
469 device
->name
= sname
;
471 nv_subdev(device
)->debug
= nouveau_dbgopt(device
->dbgopt
, "DEVICE");
472 nv_engine(device
)->sclass
= nouveau_device_sclass
;
473 list_add(&device
->head
, &nv_devices
);
475 mutex_unlock(&nv_devices_mutex
);