https://zhuanlan.zhihu.com/p/341895843
https://zhuanlan.zhihu.com/p/75321245
编写最简单的 DRM 应用
主程序:
int main(int argc, char **argv)
{
int fd;
drmModeConnector *conn;
drmModeRes *res;
uint32_t conn_id;
uint32_t crtc_id;
// 1. 打开设备
fd = open(“/dev/dri/card0”, O_RDWR | O_CLOEXEC);
// 2. 获得 crtc 和 connector 的 id
res = drmModeGetResources(fd);
crtc_id = res->crtcs[0];
conn_id = res->connectors[0];
// 3. 获得 connector
conn = drmModeGetConnector(fd, conn_id);
buf.width = conn->modes[0].hdisplay;
buf.height = conn->modes[0].vdisplay;
// 4. 创建 framebuffer
modeset_create_fb(fd, &buf);
// 5. Sets a CRTC configuration,这之后就会开始在 crtc0 + connector0 pipeline 上进行以 mode0 输出显示
drmModeSetCrtc(fd, crtc_id, buf.fb_id, 0, 0, &conn_id, 1, &conn->modes[0]);
getchar();
// 6. cleanup
…
return 0;
}
modeset_create_fb():
该函数用于分配 framebuffer,目前不需要太关心,大致就是 3 个步骤:
Allocating memory;
Preparing a mapping;
Mapping memory;
运行效果:
程序运行后,eDP 屏显示全屏白色,等待用户输入按键;当用户按下任意按键后,程序退出,显示黑屏。
drm设备不工作
在设备升级新版内核后,发现没有 fb0 设备,开机没有打印 drm 相关的信息
首先是检查设备树,确认加入 panel 节点
panel: panel {
compatible = "lg,lb070wv8”, “simple-panel";
#address-cells = <1>;
#size-cells = <0>;
enable-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
panel_input: endpoint@0 {
reg = <0>;
remote-endpoint = <&tcon0_out_lcd>;
};
};
};
其次是检查内核是否开启了相关的驱动,这里使用的是 lichepi nano,依赖的驱动是 SUN4I 系列的驱动
CONFIG_DRM_SUN4I=y
CONFIG_DRM_SUN4I_HDMI=y
CONFIG_DRM_SUN4I_BACKEND=y
不过在检查完上面两个地方没有问题后,还是没有解决问题
为了获取 drm 启动过程中的更多信息,在 uboot 的 bootargs 中加入 drm.debug=0x1f debug ,让内核打印 drm 的更多信息
[ 1.079849] [drm:drm_core_init] Initialized
[ 1.084524] [drm:sun4i_drv_probe] Adding component /soc/display-backend@1e60000
[ 1.092143] [drm:sun4i_drv_probe] Adding component /soc/lcd-controller@1c0c000
[ 1.099606] [drm:sun4i_drv_probe] Adding component /panel
[ 1.105025] [drm:sun4i_drv_traverse_endpoints] No output to bind on port 1
[ 1.124695] [drm:compare_of] Comparing of node /soc/lcd-controller@1c0c000 with /soc/display-backend@1e60000
…
发现内核尝试着挂载 /panel 节点,这个本来是不用挂载的
修改 suniv_quirks,加上 has_channel_0 的配置。缺少 has_channel_0 会让内核认为这个 TCON 没有 RGB 口
static const struct sun4i_tcon_quirks suniv_quirks = {
.has_channel_0 = true,
.has_channel_1 = true,
};
重新编译烧录后,drm 的启动信息如下。内核没有再去挂载 /panel 节点了,不过 drm 的启动还是没有成功
[ 1.079943] [drm:drm_core_init] Initialized
[ 1.084616] [drm:sun4i_drv_probe] Adding component /soc/display-backend@1e60000
[ 1.092235] [drm:sun4i_drv_probe] Adding component /soc/lcd-controller@1c0c000
[ 1.099662] [drm:sun4i_drv_traverse_endpoints] Endpoint is our panel… skipping
[ 1.121843] [drm:compare_of] Comparing of node /soc/display-backend@1e60000 with /soc/display-backend@1e60000
[ 1.131931] [drm:compare_of] Comparing of node /soc/display-backend@1e60000 with /soc/lcd-controller@1c0c000
后来在看到了这份 commit 中说的内容,将 .has_channel_1 屏蔽掉,drm 正常工作了
static const struct sun4i_tcon_quirks suniv_f1c100s_quirks = {
/*
* The F1C100s SoC has a second channel in TCON, but the clock input of
* it is not documented.
/
.has_channel_0 = true,
/ .has_channel_1 = true, */
};
感谢
非常感谢这两位大神给我的帮助
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)