base.c revision fd1496a0fc77f955317d6ca511f66a9e788e7e02
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 "priv.h" 33#include "acpi.h" 34 35static DEFINE_MUTEX(nv_devices_mutex); 36static LIST_HEAD(nv_devices); 37 38struct nouveau_device * 39nouveau_device_find(u64 name) 40{ 41 struct nouveau_device *device, *match = NULL; 42 mutex_lock(&nv_devices_mutex); 43 list_for_each_entry(device, &nv_devices, head) { 44 if (device->handle == name) { 45 match = device; 46 break; 47 } 48 } 49 mutex_unlock(&nv_devices_mutex); 50 return match; 51} 52 53/****************************************************************************** 54 * nouveau_devobj (0x0080): class implementation 55 *****************************************************************************/ 56struct nouveau_devobj { 57 struct nouveau_parent base; 58 struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; 59}; 60 61static const u64 disable_map[] = { 62 [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS, 63 [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE, 64 [NVDEV_SUBDEV_GPIO] = NV_DEVICE_DISABLE_CORE, 65 [NVDEV_SUBDEV_I2C] = NV_DEVICE_DISABLE_CORE, 66 [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE, 67 [NVDEV_SUBDEV_MXM] = NV_DEVICE_DISABLE_CORE, 68 [NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE, 69 [NVDEV_SUBDEV_BUS] = NV_DEVICE_DISABLE_CORE, 70 [NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE, 71 [NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE, 72 [NVDEV_SUBDEV_LTCG] = NV_DEVICE_DISABLE_CORE, 73 [NVDEV_SUBDEV_IBUS] = NV_DEVICE_DISABLE_CORE, 74 [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_DISABLE_CORE, 75 [NVDEV_SUBDEV_VM] = NV_DEVICE_DISABLE_CORE, 76 [NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE, 77 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE, 78 [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, 79 [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, 80 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, 81 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE, 82 [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, 83 [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, 84 [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, 85 [NVDEV_ENGINE_MPEG] = NV_DEVICE_DISABLE_MPEG, 86 [NVDEV_ENGINE_ME] = NV_DEVICE_DISABLE_ME, 87 [NVDEV_ENGINE_VP] = NV_DEVICE_DISABLE_VP, 88 [NVDEV_ENGINE_CRYPT] = NV_DEVICE_DISABLE_CRYPT, 89 [NVDEV_ENGINE_BSP] = NV_DEVICE_DISABLE_BSP, 90 [NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP, 91 [NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0, 92 [NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1, 93 [NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC, 94 [NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC, 95 [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP, 96 [NVDEV_SUBDEV_NR] = 0, 97}; 98 99static int 100nouveau_devobj_ctor(struct nouveau_object *parent, 101 struct nouveau_object *engine, 102 struct nouveau_oclass *oclass, void *data, u32 size, 103 struct nouveau_object **pobject) 104{ 105 struct nouveau_client *client = nv_client(parent); 106 struct nouveau_device *device; 107 struct nouveau_devobj *devobj; 108 struct nv_device_class *args = data; 109 u32 boot0, strap; 110 u64 disable, mmio_base, mmio_size; 111 void __iomem *map; 112 int ret, i, c; 113 114 if (size < sizeof(struct nv_device_class)) 115 return -EINVAL; 116 117 /* find the device subdev that matches what the client requested */ 118 device = nv_device(client->device); 119 if (args->device != ~0) { 120 device = nouveau_device_find(args->device); 121 if (!device) 122 return -ENODEV; 123 } 124 125 ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, 126 nouveau_control_oclass, 127 (1ULL << NVDEV_ENGINE_DMAOBJ) | 128 (1ULL << NVDEV_ENGINE_FIFO) | 129 (1ULL << NVDEV_ENGINE_DISP) | 130 (1ULL << NVDEV_ENGINE_PERFMON), &devobj); 131 *pobject = nv_object(devobj); 132 if (ret) 133 return ret; 134 135 mmio_base = nv_device_resource_start(device, 0); 136 mmio_size = nv_device_resource_len(device, 0); 137 138 /* translate api disable mask into internal mapping */ 139 disable = args->debug0; 140 for (i = 0; i < NVDEV_SUBDEV_NR; i++) { 141 if (args->disable & disable_map[i]) 142 disable |= (1ULL << i); 143 } 144 145 /* identify the chipset, and determine classes of subdev/engines */ 146 if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) && 147 !device->card_type) { 148 map = ioremap(mmio_base, 0x102000); 149 if (map == NULL) 150 return -ENOMEM; 151 152 /* switch mmio to cpu's native endianness */ 153#ifndef __BIG_ENDIAN 154 if (ioread32_native(map + 0x000004) != 0x00000000) 155#else 156 if (ioread32_native(map + 0x000004) == 0x00000000) 157#endif 158 iowrite32_native(0x01000001, map + 0x000004); 159 160 /* read boot0 and strapping information */ 161 boot0 = ioread32_native(map + 0x000000); 162 strap = ioread32_native(map + 0x101000); 163 iounmap(map); 164 165 /* determine chipset and derive architecture from it */ 166 if ((boot0 & 0x1f000000) > 0) { 167 device->chipset = (boot0 & 0x1ff00000) >> 20; 168 switch (device->chipset & 0x1f0) { 169 case 0x010: { 170 if (0x461 & (1 << (device->chipset & 0xf))) 171 device->card_type = NV_10; 172 else 173 device->card_type = NV_11; 174 break; 175 } 176 case 0x020: device->card_type = NV_20; break; 177 case 0x030: device->card_type = NV_30; break; 178 case 0x040: 179 case 0x060: device->card_type = NV_40; break; 180 case 0x050: 181 case 0x080: 182 case 0x090: 183 case 0x0a0: device->card_type = NV_50; break; 184 case 0x0c0: device->card_type = NV_C0; break; 185 case 0x0d0: device->card_type = NV_D0; break; 186 case 0x0e0: 187 case 0x0f0: 188 case 0x100: device->card_type = NV_E0; break; 189 case 0x110: device->card_type = GM100; break; 190 default: 191 break; 192 } 193 } else 194 if ((boot0 & 0xff00fff0) == 0x20004000) { 195 if (boot0 & 0x00f00000) 196 device->chipset = 0x05; 197 else 198 device->chipset = 0x04; 199 device->card_type = NV_04; 200 } 201 202 switch (device->card_type) { 203 case NV_04: ret = nv04_identify(device); break; 204 case NV_10: 205 case NV_11: ret = nv10_identify(device); break; 206 case NV_20: ret = nv20_identify(device); break; 207 case NV_30: ret = nv30_identify(device); break; 208 case NV_40: ret = nv40_identify(device); break; 209 case NV_50: ret = nv50_identify(device); break; 210 case NV_C0: 211 case NV_D0: ret = nvc0_identify(device); break; 212 case NV_E0: ret = nve0_identify(device); break; 213 case GM100: ret = gm100_identify(device); break; 214 default: 215 ret = -EINVAL; 216 break; 217 } 218 219 if (ret) { 220 nv_error(device, "unknown chipset, 0x%08x\n", boot0); 221 return ret; 222 } 223 224 nv_info(device, "BOOT0 : 0x%08x\n", boot0); 225 nv_info(device, "Chipset: %s (NV%02X)\n", 226 device->cname, device->chipset); 227 nv_info(device, "Family : NV%02X\n", device->card_type); 228 229 /* determine frequency of timing crystal */ 230 if ( device->card_type <= NV_10 || device->chipset < 0x17 || 231 (device->chipset >= 0x20 && device->chipset < 0x25)) 232 strap &= 0x00000040; 233 else 234 strap &= 0x00400040; 235 236 switch (strap) { 237 case 0x00000000: device->crystal = 13500; break; 238 case 0x00000040: device->crystal = 14318; break; 239 case 0x00400000: device->crystal = 27000; break; 240 case 0x00400040: device->crystal = 25000; break; 241 } 242 243 nv_debug(device, "crystal freq: %dKHz\n", device->crystal); 244 } 245 246 if (!(args->disable & NV_DEVICE_DISABLE_MMIO) && 247 !nv_subdev(device)->mmio) { 248 nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size); 249 if (!nv_subdev(device)->mmio) { 250 nv_error(device, "unable to map device registers\n"); 251 return -ENOMEM; 252 } 253 } 254 255 /* ensure requested subsystems are available for use */ 256 for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) { 257 if (!(oclass = device->oclass[i]) || (disable & (1ULL << i))) 258 continue; 259 260 if (device->subdev[i]) { 261 nouveau_object_ref(device->subdev[i], 262 &devobj->subdev[i]); 263 continue; 264 } 265 266 ret = nouveau_object_ctor(nv_object(device), NULL, 267 oclass, NULL, i, 268 &devobj->subdev[i]); 269 if (ret == -ENODEV) 270 continue; 271 if (ret) 272 return ret; 273 274 device->subdev[i] = devobj->subdev[i]; 275 276 /* note: can't init *any* subdevs until devinit has been run 277 * due to not knowing exactly what the vbios init tables will 278 * mess with. devinit also can't be run until all of its 279 * dependencies have been created. 280 * 281 * this code delays init of any subdev until all of devinit's 282 * dependencies have been created, and then initialises each 283 * subdev in turn as they're created. 284 */ 285 while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) { 286 struct nouveau_object *subdev = devobj->subdev[c++]; 287 if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) { 288 ret = nouveau_object_inc(subdev); 289 if (ret) 290 return ret; 291 atomic_dec(&nv_object(device)->usecount); 292 } else 293 if (subdev) { 294 nouveau_subdev_reset(subdev); 295 } 296 } 297 } 298 299 return 0; 300} 301 302static void 303nouveau_devobj_dtor(struct nouveau_object *object) 304{ 305 struct nouveau_devobj *devobj = (void *)object; 306 int i; 307 308 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) 309 nouveau_object_ref(NULL, &devobj->subdev[i]); 310 311 nouveau_parent_destroy(&devobj->base); 312} 313 314static u8 315nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) 316{ 317 return nv_rd08(object->engine, addr); 318} 319 320static u16 321nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) 322{ 323 return nv_rd16(object->engine, addr); 324} 325 326static u32 327nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) 328{ 329 return nv_rd32(object->engine, addr); 330} 331 332static void 333nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) 334{ 335 nv_wr08(object->engine, addr, data); 336} 337 338static void 339nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) 340{ 341 nv_wr16(object->engine, addr, data); 342} 343 344static void 345nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) 346{ 347 nv_wr32(object->engine, addr, data); 348} 349 350static struct nouveau_ofuncs 351nouveau_devobj_ofuncs = { 352 .ctor = nouveau_devobj_ctor, 353 .dtor = nouveau_devobj_dtor, 354 .init = _nouveau_parent_init, 355 .fini = _nouveau_parent_fini, 356 .rd08 = nouveau_devobj_rd08, 357 .rd16 = nouveau_devobj_rd16, 358 .rd32 = nouveau_devobj_rd32, 359 .wr08 = nouveau_devobj_wr08, 360 .wr16 = nouveau_devobj_wr16, 361 .wr32 = nouveau_devobj_wr32, 362}; 363 364/****************************************************************************** 365 * nouveau_device: engine functions 366 *****************************************************************************/ 367static struct nouveau_oclass 368nouveau_device_sclass[] = { 369 { 0x0080, &nouveau_devobj_ofuncs }, 370 {} 371}; 372 373static int 374nouveau_device_fini(struct nouveau_object *object, bool suspend) 375{ 376 struct nouveau_device *device = (void *)object; 377 struct nouveau_object *subdev; 378 int ret, i; 379 380 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) { 381 if ((subdev = device->subdev[i])) { 382 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 383 ret = nouveau_object_dec(subdev, suspend); 384 if (ret && suspend) 385 goto fail; 386 } 387 } 388 } 389 390 ret = nvkm_acpi_fini(device, suspend); 391fail: 392 for (; ret && i < NVDEV_SUBDEV_NR; i++) { 393 if ((subdev = device->subdev[i])) { 394 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 395 ret = nouveau_object_inc(subdev); 396 if (ret) { 397 /* XXX */ 398 } 399 } 400 } 401 } 402 403 return ret; 404} 405 406static int 407nouveau_device_init(struct nouveau_object *object) 408{ 409 struct nouveau_device *device = (void *)object; 410 struct nouveau_object *subdev; 411 int ret, i = 0; 412 413 ret = nvkm_acpi_init(device); 414 if (ret) 415 goto fail; 416 417 for (i = 0; i < NVDEV_SUBDEV_NR; i++) { 418 if ((subdev = device->subdev[i])) { 419 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 420 ret = nouveau_object_inc(subdev); 421 if (ret) 422 goto fail; 423 } else { 424 nouveau_subdev_reset(subdev); 425 } 426 } 427 } 428 429 ret = 0; 430fail: 431 for (--i; ret && i >= 0; i--) { 432 if ((subdev = device->subdev[i])) { 433 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) 434 nouveau_object_dec(subdev, false); 435 } 436 } 437 438 if (ret) 439 nvkm_acpi_fini(device, false); 440 return ret; 441} 442 443static void 444nouveau_device_dtor(struct nouveau_object *object) 445{ 446 struct nouveau_device *device = (void *)object; 447 448 nouveau_event_destroy(&device->ntfy); 449 450 mutex_lock(&nv_devices_mutex); 451 list_del(&device->head); 452 mutex_unlock(&nv_devices_mutex); 453 454 if (nv_subdev(device)->mmio) 455 iounmap(nv_subdev(device)->mmio); 456 457 nouveau_engine_destroy(&device->base); 458} 459 460resource_size_t 461nv_device_resource_start(struct nouveau_device *device, unsigned int bar) 462{ 463 if (nv_device_is_pci(device)) { 464 return pci_resource_start(device->pdev, bar); 465 } else { 466 struct resource *res; 467 res = platform_get_resource(device->platformdev, 468 IORESOURCE_MEM, bar); 469 if (!res) 470 return 0; 471 return res->start; 472 } 473} 474 475resource_size_t 476nv_device_resource_len(struct nouveau_device *device, unsigned int bar) 477{ 478 if (nv_device_is_pci(device)) { 479 return pci_resource_len(device->pdev, bar); 480 } else { 481 struct resource *res; 482 res = platform_get_resource(device->platformdev, 483 IORESOURCE_MEM, bar); 484 if (!res) 485 return 0; 486 return resource_size(res); 487 } 488} 489 490int 491nv_device_get_irq(struct nouveau_device *device, bool stall) 492{ 493 if (nv_device_is_pci(device)) { 494 return device->pdev->irq; 495 } else { 496 return platform_get_irq_byname(device->platformdev, 497 stall ? "stall" : "nonstall"); 498 } 499} 500 501static struct nouveau_oclass 502nouveau_device_oclass = { 503 .handle = NV_ENGINE(DEVICE, 0x00), 504 .ofuncs = &(struct nouveau_ofuncs) { 505 .dtor = nouveau_device_dtor, 506 .init = nouveau_device_init, 507 .fini = nouveau_device_fini, 508 }, 509}; 510 511int 512nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name, 513 const char *sname, const char *cfg, const char *dbg, 514 int length, void **pobject) 515{ 516 struct nouveau_device *device; 517 int ret = -EEXIST; 518 519 mutex_lock(&nv_devices_mutex); 520 list_for_each_entry(device, &nv_devices, head) { 521 if (device->handle == name) 522 goto done; 523 } 524 525 ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true, 526 "DEVICE", "device", length, pobject); 527 device = *pobject; 528 if (ret) 529 goto done; 530 531 switch (type) { 532 case NOUVEAU_BUS_PCI: 533 device->pdev = dev; 534 break; 535 case NOUVEAU_BUS_PLATFORM: 536 device->platformdev = dev; 537 break; 538 } 539 device->handle = name; 540 device->cfgopt = cfg; 541 device->dbgopt = dbg; 542 device->name = sname; 543 544 nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE"); 545 nv_engine(device)->sclass = nouveau_device_sclass; 546 list_add(&device->head, &nv_devices); 547 548 ret = nouveau_event_create(1, NVKM_DEVICE_NTFY, &device->ntfy); 549done: 550 mutex_unlock(&nv_devices_mutex); 551 return ret; 552} 553