base.c revision c42a7aec12c893c55b9aa8de02f9f1de767be8a5
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 30#include <core/class.h> 31 32#include <engine/device.h> 33 34static DEFINE_MUTEX(nv_devices_mutex); 35static LIST_HEAD(nv_devices); 36 37struct nouveau_device * 38nouveau_device_find(u64 name) 39{ 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) { 44 match = device; 45 break; 46 } 47 } 48 mutex_unlock(&nv_devices_mutex); 49 return match; 50} 51 52/****************************************************************************** 53 * nouveau_devobj (0x0080): class implementation 54 *****************************************************************************/ 55struct nouveau_devobj { 56 struct nouveau_parent base; 57 struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; 58}; 59 60static 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, 94}; 95 96static int 97nouveau_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) 101{ 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; 106 u32 boot0, strap; 107 u64 disable, mmio_base, mmio_size; 108 void __iomem *map; 109 int ret, i, c; 110 111 if (size < sizeof(struct nv_device_class)) 112 return -EINVAL; 113 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); 118 if (!device) 119 return -ENODEV; 120 } 121 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); 127 if (ret) 128 return ret; 129 130 mmio_base = pci_resource_start(device->pdev, 0); 131 mmio_size = pci_resource_len(device->pdev, 0); 132 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); 138 } 139 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); 144 if (map == NULL) 145 return -ENOMEM; 146 147 /* switch mmio to cpu's native endianness */ 148#ifndef __BIG_ENDIAN 149 if (ioread32_native(map + 0x000004) != 0x00000000) 150#else 151 if (ioread32_native(map + 0x000004) == 0x00000000) 152#endif 153 iowrite32_native(0x01000001, map + 0x000004); 154 155 /* read boot0 and strapping information */ 156 boot0 = ioread32_native(map + 0x000000); 157 strap = ioread32_native(map + 0x101000); 158 iounmap(map); 159 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; 167 case 0x40: 168 case 0x60: device->card_type = NV_40; break; 169 case 0x50: 170 case 0x80: 171 case 0x90: 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; 175 case 0xe0: 176 case 0xf0: device->card_type = NV_E0; break; 177 default: 178 break; 179 } 180 } else 181 if ((boot0 & 0xff00fff0) == 0x20004000) { 182 if (boot0 & 0x00f00000) 183 device->chipset = 0x05; 184 else 185 device->chipset = 0x04; 186 device->card_type = NV_04; 187 } 188 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; 196 case NV_C0: 197 case NV_D0: ret = nvc0_identify(device); break; 198 case NV_E0: ret = nve0_identify(device); break; 199 default: 200 ret = -EINVAL; 201 break; 202 } 203 204 if (ret) { 205 nv_error(device, "unknown chipset, 0x%08x\n", boot0); 206 return ret; 207 } 208 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); 213 214 /* determine frequency of timing crystal */ 215 if ( device->chipset < 0x17 || 216 (device->chipset >= 0x20 && device->chipset < 0x25)) 217 strap &= 0x00000040; 218 else 219 strap &= 0x00400040; 220 221 switch (strap) { 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; 226 } 227 228 nv_debug(device, "crystal freq: %dKHz\n", device->crystal); 229 } 230 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"); 236 return -ENOMEM; 237 } 238 } 239 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))) 243 continue; 244 245 if (device->subdev[i]) { 246 nouveau_object_ref(device->subdev[i], 247 &devobj->subdev[i]); 248 continue; 249 } 250 251 ret = nouveau_object_ctor(nv_object(device), NULL, 252 oclass, NULL, i, 253 &devobj->subdev[i]); 254 if (ret == -ENODEV) 255 continue; 256 if (ret) 257 return ret; 258 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. 263 * 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. 267 */ 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); 272 if (ret) 273 return ret; 274 atomic_dec(&nv_object(device)->usecount); 275 } else 276 if (subdev) { 277 nouveau_subdev_reset(subdev); 278 } 279 } 280 } 281 282 return 0; 283} 284 285static void 286nouveau_devobj_dtor(struct nouveau_object *object) 287{ 288 struct nouveau_devobj *devobj = (void *)object; 289 int i; 290 291 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) 292 nouveau_object_ref(NULL, &devobj->subdev[i]); 293 294 nouveau_parent_destroy(&devobj->base); 295} 296 297static u8 298nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) 299{ 300 return nv_rd08(object->engine, addr); 301} 302 303static u16 304nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) 305{ 306 return nv_rd16(object->engine, addr); 307} 308 309static u32 310nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) 311{ 312 return nv_rd32(object->engine, addr); 313} 314 315static void 316nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) 317{ 318 nv_wr08(object->engine, addr, data); 319} 320 321static void 322nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) 323{ 324 nv_wr16(object->engine, addr, data); 325} 326 327static void 328nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) 329{ 330 nv_wr32(object->engine, addr, data); 331} 332 333static struct nouveau_ofuncs 334nouveau_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, 345}; 346 347/****************************************************************************** 348 * nouveau_device: engine functions 349 *****************************************************************************/ 350static struct nouveau_oclass 351nouveau_device_sclass[] = { 352 { 0x0080, &nouveau_devobj_ofuncs }, 353 {} 354}; 355 356static int 357nouveau_device_fini(struct nouveau_object *object, bool suspend) 358{ 359 struct nouveau_device *device = (void *)object; 360 struct nouveau_object *subdev; 361 int ret, i; 362 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); 367 if (ret && suspend) 368 goto fail; 369 } 370 } 371 } 372 373 ret = 0; 374fail: 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); 379 if (ret) { 380 /* XXX */ 381 } 382 } 383 } 384 } 385 386 return ret; 387} 388 389static int 390nouveau_device_init(struct nouveau_object *object) 391{ 392 struct nouveau_device *device = (void *)object; 393 struct nouveau_object *subdev; 394 int ret, i; 395 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); 400 if (ret) 401 goto fail; 402 } else { 403 nouveau_subdev_reset(subdev); 404 } 405 } 406 } 407 408 ret = 0; 409fail: 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); 414 } 415 } 416 417 return ret; 418} 419 420static void 421nouveau_device_dtor(struct nouveau_object *object) 422{ 423 struct nouveau_device *device = (void *)object; 424 425 mutex_lock(&nv_devices_mutex); 426 list_del(&device->head); 427 mutex_unlock(&nv_devices_mutex); 428 429 if (nv_subdev(device)->mmio) 430 iounmap(nv_subdev(device)->mmio); 431 432 nouveau_engine_destroy(&device->base); 433} 434 435static struct nouveau_oclass 436nouveau_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, 442 }, 443}; 444 445int 446nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, 447 const char *cfg, const char *dbg, 448 int length, void **pobject) 449{ 450 struct nouveau_device *device; 451 int ret = -EEXIST; 452 453 mutex_lock(&nv_devices_mutex); 454 list_for_each_entry(device, &nv_devices, head) { 455 if (device->handle == name) 456 goto done; 457 } 458 459 ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true, 460 "DEVICE", "device", length, pobject); 461 device = *pobject; 462 if (ret) 463 goto done; 464 465 device->pdev = pdev; 466 device->handle = name; 467 device->cfgopt = cfg; 468 device->dbgopt = dbg; 469 device->name = sname; 470 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); 474done: 475 mutex_unlock(&nv_devices_mutex); 476 return ret; 477} 478