linux drm子设备号,Linux DRM (三) RK 平台 DRM 代码分析 · Rockchip

本篇是 DRM 的第三篇文章。

在 《Linux DRM (一) Display Server》 中我们了解了 DRM 诞生的历史。

在 《Linux DRM (二) 基本概念和特性》 中我们了解了一些基本的概念。

现在,我们终于要向 DRM 源码进军了。

+

一、概览

不知大家是否还记得,之前我有引用 Wiki 中对 DRM 的介绍,这里我们再回顾一下:

DRM 由两个部分组成:

一是 Kernel 的子系统,这个子系统对硬件 GPU 操作进行了一层框架封装。

二是 提供了一个 libdrm 库,里面封装了一系列 API,用来进行图像显示。

整体来看和 Android 上所采用的 Direct Frame Buffer 差不多。

Android Kernel 走的是 FB 的框架,并在 HAL 抽象出一个 FBDEV,来进行 FB IOCTL 统一管理。

DRM 就相当于直接对图形设备集中处理,并且多出了一个 libdrm 库。

+

其整体脉络如下:

+

171872157_1_20190926093339503.jpg

源码文件

171872157_2_20190926093340144.jpg

component framework

在讲述启动过程之前,先简单了解一下 component framework。

+

因为 drm下挂了许多的设备, 启动顺序经常会引发各种问题:

+一个驱动完全有可能因为等另一个资源的准备, 而probe deferral, 导致顺序不定

子设备没有加载好, 主设备就加载了, 导致设备无法工作

子设备相互之间可能有时序关系,不定的加载顺序,可能带来有些时候设备能工作,有些时候又不能工作

现在编kernel是多线程编译的,编译的前后顺序也会影响驱动的加载顺序.

这时就需要有一个统一管理的机制, 将所有设备统合起来, 按照一个统一的顺序加载,

Display-subsystem正是用来解决这个问题的, 依赖于component的驱动, 通过这个驱动,

可以把所有的设备以组件的形式加在一起, 等所有的组件加载完毕后, 统一进行bind/unbind.

+

代码路径 drivers/base/component.c

+

以下为rockchip drm master probe阶段component 主要逻辑, 为了减小篇幅, 去掉了无关的代码:

+static int rockchip_drm_platform_probe(struct platform_device *pdev)

{

for (i = 0;; i++) {

/* ports指向了vop的设备节点 */

port = of_parse_phandle(np, "ports", i);

component_match_add(dev, &match, compare_of, port->parent);

}

for (i = 0;; i++) {

port = of_parse_phandle(np, "ports", i);

/* 搜查port下的各个endpoint, 将它们也加入到match列表 */

rockchip_add_endpoints(dev, &match, port);

}

return component_master_add_with_match(dev, &rockchip_drm_ops, match);

}

static void rockchip_a

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 `rockchip_drm_init` 函数的代码框图及详细说明: ```mermaid graph TB A[rockchip_drm_init] --> B[drm_dev_init] B --> C[drm_mode_config_init] B --> D[drm_vblank_init] A --> E[rockchip_drm_encoder_init] A --> F[rockchip_drm_connector_init] A --> G[rockchip_drm_crtc_init] A --> H[drm_irq_install] A --> I[drm_dev_register] subgraph 编码器初始化 E --> E1[HDMI编码器初始化] E --> E2[LVDS编码器初始化] E --> E3[DP编码器初始化] end subgraph 连接器初始化 F --> F1[HDMI连接器初始化] F --> F2[LVDS连接器初始化] F --> F3[DP连接器初始化] end subgraph CRTC初始化 G --> G1[HDMI CRTC初始化] G --> G2[LVDS CRTC初始化] G --> G3[DP CRTC初始化] end ``` 详细说明如下: 1. `rockchip_drm_init` 函数首先调用 `drm_dev_init` 函数来初始化 DRM 设备结构体 `drm_device`。该函数会创建并初始化一个 `drm_device` 结构体,并为其分配设备节点和设备文件操作集等资源。 2. 接着,`rockchip_drm_init` 函数调用 `drm_mode_config_init` 函数来初始化 `drm_device` 中的 `mode_config` 数据结构,该结构体用于管理显示模式信息。该函数会创建并初始化一个 `drm_mode_config` 结构体,并为其分配显示模式信息等资源。 3. `rockchip_drm_init` 函数接着调用 `drm_vblank_init` 函数来初始化 `drm_device` 中的垂直同步信(VBlank)管理器。该管理器用于处理垂直同步信相关的事件,例如垂直同步中断和垂直同步定时器。 4. `rockchip_drm_init` 函数接着调用 `rockchip_drm_encoder_init` 函数来初始化所有的编码器。该函数会遍历所有支持的编码器,并分别调用对应的初始化函数来初始化编码器相关的数据结构。 5. `rockchip_drm_init` 函数接着调用 `rockchip_drm_connector_init` 函数来初始化所有的连接器。该函数会遍历所有支持的连接器,并分别调用对应的初始化函数来初始化连接器相关的数据结构。 6. `rockchip_drm_init` 函数接着调用 `rockchip_drm_crtc_init` 函数来初始化所有的 CRTC。该函数会遍历所有支持的 CRTC,并分别调用对应的初始化函数来初始化 CRTC 相关的数据结构。 7. `rockchip_drm_init` 函数接着调用 `drm_irq_install` 函数来注册中断处理程序。该函数会向内核注册一个中断处理函数,用于处理显示器相关的中断事件。 8. 最后,`rockchip_drm_init` 函数调用 `drm_dev_register` 函数来注册 DRM 设备。该函数会创建 `/dev/dri/cardX` 设备文件,并将其挂载到文件系统中,以便用户空间程序可以使用标准的文件操作接口来访问 DRM 设备。 需要注意的是,上述代码框图只是对 `rockchip_drm_init` 函数的主要流程进行了概括,实际上该函数还包括了一些错误处理、内存释放等操作。在实际使用中,需要仔细阅读该函数的源代码,以便了解其具体实现和细节。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值