Nouveau源码分析(四):NVIDIA设备初始化之nouveau_drm_load (1)

Nouveau源码分析(四)

probe函数成功返回之后,DRM模块就会调用struct drm_driver的load函数,对应nouveau的nouveau_drm_load.
这个函数虽然看起来不是特别长,但每一个调用的函数展开后就会变得非常长了!

// /drivers/gpu/drm/nouveau/nouveau_drm.c
364 static int
365 nouveau_drm_load(struct drm_device *dev, unsigned long flags)
366 {
367         struct pci_dev *pdev = dev->pdev;
368         struct nouveau_drm *drm;
369         int ret;
370 
371         ret = nouveau_cli_create(nouveau_name(dev), "DRM", sizeof(*drm),
372                                  (void **)&drm);
373         if (ret)
374                 return ret;
375 
376         dev->dev_private = drm;
377         drm->dev = dev;
378         nvkm_client(&drm->client.base)->debug =
379                 nouveau_dbgopt(nouveau_debug, "DRM");
380 
381         INIT_LIST_HEAD(&drm->clients);
382         spin_lock_init(&drm->tile.lock);
383 
384         nouveau_get_hdmi_dev(drm);
385 
386         /* make sure AGP controller is in a consistent state before we
387          * (possibly) execute vbios init tables (see nouveau_agp.h)
388          */
389         if (pdev && drm_pci_device_is_agp(dev) && dev->agp) {
390                 const u64 enables = NV_DEVICE_V0_DISABLE_IDENTIFY |
391                                     NV_DEVICE_V0_DISABLE_MMIO;
392                 /* dummy device object, doesn't init anything, but allows
393                  * agp code access to registers
394                  */
395                 ret = nvif_device_init(&drm->client.base.base, NULL,
396                                        NVDRM_DEVICE, NV_DEVICE,
397                                        &(struct nv_device_v0) {
398                                                 .device = ~0,
399                                                 .disable = ~enables,
400                                                 .debug0 = ~0,
401                                        }, sizeof(struct nv_device_v0),
402                                        &drm->device);
403                 if (ret)
404                         goto fail_device;
405 
406                 nouveau_agp_reset(drm);
407                 nvif_device_fini(&drm->device);
408         }
409 
410         ret = nvif_device_init(&drm->client.base.base, NULL, NVDRM_DEVICE,
411                                NV_DEVICE,
412                                &(struct nv_device_v0) {
413                                         .device = ~0,
414                                         .disable = 0,
415                                         .debug0 = 0,
416                                }, sizeof(struct nv_device_v0),
417                                &drm->device);
418         if (ret)
419                 goto fail_device;
420 
421         dev->irq_enabled = true;
422 
423         /* workaround an odd issue on nvc1 by disabling the device's
424          * nosnoop capability.  hopefully won't cause issues until a
425          * better fix is found - assuming there is one...
426          */
427         if (drm->device.info.chipset == 0xc1)
428                 nvif_mask(&drm->device, 0x00088080, 0x00000800, 0x00000000);
429 
430         nouveau_vga_init(drm);
431         nouveau_agp_init(drm);
432 
433         if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
434                 ret = nouveau_vm_new(nvkm_device(&drm->device), 0, (1ULL << 40),
435                                      0x1000, &drm->client.vm);
436                 if (ret)
437                         goto fail_device;
438 
439                 nvkm_client(&drm->client.base)->vm = drm->client.vm;
440         }
441 
442         ret = nouveau_ttm_init(drm);
443         if (ret)
444                 goto fail_ttm;
445 
446         ret = nouveau_bios_init(dev);
447         if (ret)
448                 goto fail_bios;
449 
450         ret = nouveau_display_create(dev);
451         if (ret)
452                 goto fail_dispctor;
453 
454         if (dev->mode_config.num_crtc) {
455                 ret = nouveau_display_init(dev);
456                 if (ret)
457                         goto fail_dispinit;
458         }
459 
460         nouveau_sysfs_init(dev);
461         nouveau_hwmon_init(dev);
462         nouveau_accel_init(drm);
463         nouveau_fbcon_init(dev);
464 
465         if (nouveau_runtime_pm != 0) {
466                 pm_runtime_use_autosuspend(dev->dev);
467                 pm_runtime_set_autosuspend_delay(dev->dev, 5000);
468                 pm_runtime_set_active(dev->dev);
469                 pm_runtime_allow(dev->dev);
470                 pm_runtime_mark_last_busy(dev->dev);
471                 pm_runtime_put(dev->dev);
472         }
473         retu
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值