Nouveau源码分析(三):NVIDIA设备初始化之nouveau_drm_probe

本文深入解析Nouveau驱动中的nouveau_drm_probe函数,详述NVIDIA设备初始化过程。从PCI模块扫描、设备匹配到nouveau_drm_probe的调用,探讨NV设备结构体创建、engine和object结构的初始化,以及Bus-Mastering的启用和DRM设备注册等关键步骤。
摘要由CSDN通过智能技术生成

Nouveau源码分析(三)

向DRM注册了Nouveau驱动之后,内核中的PCI模块就会扫描所有没有对应驱动的设备,然后和nouveau_drm_pci_table对照.

对于匹配的设备,PCI模块就调用对应的probe函数,也就是nouveau_drm_probe.

// /drivers/gpu/drm/nouveau/nouveau_drm.c
281 static int nouveau_drm_probe(struct pci_dev *pdev,
282                              const struct pci_device_id *pent)
283 {
284         struct nouveau_device *device;
285         struct apertures_struct *aper;
286         bool boot = false;
287         int ret;
288 
289         /* remove conflicting drivers (vesafb, efifb etc) */
290         aper = alloc_apertures(3);
291         if (!aper)
292                 return -ENOMEM;
293 
294         aper->ranges[0].base = pci_resource_start(pdev, 1);
295         aper->ranges[0].size = pci_resource_len(pdev, 1);
296         aper->count = 1;
297 
298         if (pci_resource_len(pdev, 2)) {
299                 aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
300                 aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
301                 aper->count++;
302         }
303 
304         if (pci_resource_len(pdev, 3)) {
305                 aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
306                 aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
307                 aper->count++;
308         }
309 
310 #ifdef CONFIG_X86
311         boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
312 #endif
313         if (nouveau_modeset != 2)
314                 remove_conflicting_framebuffers(aper, "nouveaufb", boot);
315         kfree(aper);
316 
317         ret = nouveau_device_create(pdev, NOUVEAU_BUS_PCI,
318                                     nouveau_pci_name(pdev), pci_name(pdev),
319                                     nouveau_config, nouveau_debug, &device);
320         if (ret)
321                 return ret;
322 
323         pci_set_master(pdev);
324 
325         ret = drm_get_pci_dev(pdev, pent, &driver);
326         if (ret) {
327                 nouveau_object_ref(NULL, (struct nouveau_object **)&device);
328                 return ret;
329         }
330 
331         return 0;
332 }

第290~315行,分配了一个aper,把资源位置写进去,调用了remove_conflicting_framebuffer,接着释放这个aper.

一行注释和函数名已经说的很明白,就是移除冲突的framebuffer.


第317行,创建一个NV设备的结构体,这个函数我们要仔细看

// /drivers/gpu/drm/nouveau/core/include/engine/device.h
 13 #define nouveau_device_create(p,t,n,s,c,d,u)                                   \
 14         nouveau_device_create_((void *)(p), (t), (n), (s), (c), (d),           \
 15                                sizeof(**u), (void **)u)
 16 
 17 int  nouveau_device_create_(void *, enum nv_bus_type type, u64 name,
 18                             const char *sname, const char *cfg, const char *dbg,
 19                             int, void **);
想起了什么? 对,就是上一节讲的内容,我们还是先来看结构体.

// /drivers/gpu/drm/nouveau/core/include/core/device.h
 65 struct nouveau_device {
 66         struct nouveau_engine base;
 67         struct list_head head;
 68 
 69         struct pci_dev *pdev;
 70         struct platform_device *platformdev;
 71         u64 handle;
 72 
 73         struct nvkm_event event;
 74 
 75         const char *cfgopt;
 76         const char *dbgopt;
 77         const char *name;
 78         const char *cname;
 79         u64 disable_mask;
 80 
 81         enum {
 82                 NV_04    = 0x04,
 83                 NV_10    = 0x10,
 84                 NV_11    = 0x11,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值