DRM几个重要的结构体及panel开发

news2024/9/21 14:52:14

一、DRM

        Linux下的DRM框架内容众多,结构复杂。本文将简单介绍下开发过程中用到的几个结构体。这几个结构体都在之前文章里面开发DRM驱动时用到的,未用到的暂不介绍。

        DRM中的KMS包含Framebuffer、CRTC,ENCODER,CONNECTOR,PLANE,VBLANK,property。因此,开发DMR驱动也是围绕这几个部分展开。驱动的逻辑部分需要包含这些。开发DRM驱动可以简化为如下操作。

1、初始化结构体

 2、注册

3、 给 driver_features 添加上 DRIVER_MODESET,告诉 DRM Core 当前驱动支持 modesetting 操作,创建plane、crtc、encoder、connector 这4个 drm_mode_object。

4、给 driver_features 添加上 DRIVER_GEM 标志位,告诉 DRM Core 该驱动支持 GEM 操作。添加 FB 和 GEM 支持:dumb_create 回调接口用于创建 gem object,并分配物理 buffer。这里直接使用 CMA helper 函数来实现;fb_create 回调接口用于创建 framebuffer object,并绑定 gem objects。这里直接使用 CMA helper 函数实现。fops 中的 mmap 接口,用于将 dumb buffer 映射到 userspace,它依赖 drm driver 中的 gem_vm_ops 实现。这里也直接使用 CMA helper 函数来实现。

DRIVER_MODESET:表示支持modesetting 操作

DRIVER_GEM:表示支持GEM 操作,用于操作对内存的分配、释放

DRIVER_ATOMIC:支持 Atomic 操作,用于操作各种属性

.fops = &drv_driver_fops,驱动的fops结构体

.dumb_create = stm_gem_cma_dumb_create,创建gem object,分配屋里buffer,可以使用CMA helper函数实现

 其中,

1)xxx_funcs 必须有,xxx_helper_funcs 可以没有。

2)drm_xxx_init() 必须有,drm_xxx_helper_add() 可以没有。

3)只有当 xxx_funcs 采用 DRM 标准的 helper 函数实现时,才有可能 需要定义 xxx_helper_funcs 接口。

4xxx_funcs.destroy() 接口必须实现

helper 函数的作用:drm_xxx_funcs 是 drm ioctl 操作的最终入口,但是对于大多数 SoC 厂商来说,它们的 drm_xxx_funcs 操作流程基本相同(你抄我,我抄你),只是在寄存器配置上存在差异,因此开发者们将那些 common 的操作流程做成了 helper 函数,而将那些厂商差异化的代码放到了 drm_xxx_helper_funcs 中去,由 SoC 厂商自己实现。

        开发一个DRM驱动大致流程如上所述。总之,就是实现KMS中的各个部分。GEM中的部分可以使用CAM中的接口完成。

二、几个结构体

        1、struct drm_plane_funcs结构体

        plane是图层相关部分。结构体部分成员如下:

struct drm_plane_funcs 结构体成员:
1、	update_plane:为给定的CRTC和framebuffer启用并配置平面
2、	disable_plane:关闭plane
3、	destroy:清除plane所有的资源
4、	reset:复位软硬件状态为关闭
5、	set_property:更新plane的property
6、	atomic_duplicate_state:复制当前的plane状态并返回
7、	atomic_destroy_state:销毁当前的plane状态
8、	atomic_set/get_property:原子操作设置/获得property
9、	format_mod_supported:该可选挂钩用于DRM,以确定给定的格式/修饰符组合是否对平面有效

struct drm_plane_helper_funcs部分成员如下:

struct drm_plane_helper_funcs结构体成员:
1、	prepare_fb:该钩子通过固定其后备存储器或将其重新定位到连续的VRAM块,为扫描准备帧缓冲区。其他可能的准备工作包括冲洗缓存。
2、	cleanup_fb:清除在prepare_fb分配的给framebuffer和plane的资源
3、	atomic_check:检查该挂钩中的plane特定约束
4、	atomic_update:更新plane状态
5、	atomic_disable:关闭
6、	atomic_async_check:异步检查
7、	atomic_async_update:异步更新状态

使用示例:

static const struct drm_plane_funcs ltdc_plane_funcs = {
    .update_plane = drm_atomic_helper_update_plane,
    .disable_plane = drm_atomic_helper_disable_plane,
    .destroy = drm_plane_cleanup,
    .reset = drm_atomic_helper_plane_reset,
    .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
    .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
    .atomic_print_state = ltdc_plane_atomic_print_state,
    .format_mod_supported = ltdc_plane_format_mod_supported,
};


static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
	.prepare_fb = drm_gem_fb_prepare_fb,       //准备分配资源
	.atomic_check = ltdc_plane_atomic_check,   //检查驱动
	.atomic_update = ltdc_plane_atomic_update,   //更新plane状态
	.atomic_disable = ltdc_plane_atomic_disable,  //关闭
};

     2、struct drm_crtc_funcs结构体

        部分结构体成员如下:

struct drm_crtc_funcs结构体成员:
1、	reset;复位,设置为关闭状态
2、	destroy:清除CRTC资源
3、	cursor_set:更新鼠标图像
4、	cursor_move:更新光标位置
5、	gamma_set:gamma设置
6、	set_config:修改配置
7、	page_flip:修改帧缓冲页,避免垂直消影期间用新的缓冲区替代时产生撕裂
8、	set_property:设置property
9、	atomic_duplicate_state:复制当前的状态
10、	atomic_destroy_state:销毁复制的状态
11、	atomic_get_property:获取atomic_get_property
12、	set_crc_source:更改CRC的来源
13、	get_vblank_counter 获取CRTC的vblank计数器
14、	disable_vblank:关闭消影

struct drm_crtc_helper_funcs结构体成员
1、	dpms:控制CRTC电源功率
2、	commit:提交新的模式
3、	mode_valid:用于检查特定模式在此crtc中是否有效
4、	mode_fixup:用于验证模式
5、	mode_set:设置模式
6、	mode_set_nofb:用于更新CRTC的显示模式,而不更改主平面配置的任何内容
7、	mode_set_base:设置新的帧缓冲区和扫描位置
8、	atomic_flush:完成CRTC上多个平面的更新
9、	atomic_enable/disable:打开/关闭

使用示例如下:

static const struct drm_crtc_funcs ltdc_crtc_funcs = {
	.destroy = drm_crtc_cleanup,  //清除CRTC资源
	.set_config = drm_atomic_helper_set_config,  //设置配置
	.page_flip = drm_atomic_helper_page_flip,  //修改帧缓冲页,避免垂直消影期间用新的缓冲区替代时产生撕裂
	.reset = drm_atomic_helper_crtc_reset,  // 复位,设置为关闭状态
	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,   // 复制当前状态
	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,  //  销毁当前状态
	.enable_vblank = ltdc_crtc_enable_vblank,    //  使能消影
	.disable_vblank = ltdc_crtc_disable_vblank,   // 关闭消影
	.gamma_set = drm_atomic_helper_legacy_gamma_set,   //gamma设置
}; 


struct drm_crtc_helper_funcs ltdc_crtc_helper_funcs = {
	.mode_valid = ltdc_crtc_mode_valid,  //用于检查特定模式红CRTC是否有效
	.mode_fixup = ltdc_crtc_mode_fixup,    //用于验证模式  
	.mode_set_nofb = ltdc_crtc_mode_set_nofb,   //用于更新CRTC的显示模式,而不更改主平面配置的任何内容
	.atomic_flush = ltdc_crtc_atomic_flush,   //完成CRTC上多个平面的更新
	.atomic_enable = ltdc_crtc_atomic_enable,  // 打开
	.atomic_disable = ltdc_crtc_atomic_disable,  //关闭
};

3、struct drm_encoder_helper_funcs结构体:

static const struct drm_encoder_funcs ltdc_encoder_funcs = {
	.destroy = drm_encoder_cleanup,
};

static const struct drm_encoder_helper_funcs ltdc_encoder_helper_funcs = {
	.disable = ltdc_encoder_disable,
	.enable = ltdc_encoder_enable,
	.mode_set = ltdc_encoder_mode_set,
};

4、drm_panel相关

drm_panel这部分是在drivers\gpu\drm\panel\panel-simple.c添加。具体则是:

static const struct of_device_id platform_of_match[]下面添加一个自己的of_device_id。

{
		.compatible = "alientek,lcd-rgb",
		 .data = &HTQ_alientek_desc,
},

HTQ_alientek_desc结构体描述的是所用屏幕的信息,包括显示模式、像素格式等。

static const struct panel_desc HTQ_alientek_desc = { 
	.modes = &HTQ_ATK7016_mode, 
	.num_modes = 1, 
	.bus_format = MEDIA_BUS_FMT_RGB888_1X24, 
};

显示模式在HTQ_ATK7016_mode这个结构体里面具体描述,如时钟、分辨率、刷新率等等。

static const struct drm_display_mode HTQ_ATK7016_mode = { 
	.clock = 51200, /* LCD像素时钟,单位KHz */ 
	.hdisplay = 1024, /* LCD X轴像素个数 */
	.hsync_start = 1024 + 140, /* LCD X轴+hbp的像素个数 */ 
	.hsync_end = 1024 + 140 + 20, /* LCD X轴+hbp+hspw的像素个数 */ 
	.htotal = 1024 + 140 + 20 + 160,/* LCD X轴+hbp+hspw+hfp */
	.vdisplay = 600, /* LCD Y轴像素个数 */ 
	.vsync_start = 600 + 20, /* LCD Y轴+vbp的像素个数 */ 
	.vsync_end = 600 + 20 + 3, /* LCD Y轴+vbp+vspw的像素个数 */ 
	.vtotal = 600 + 20 + 3 + 12,/* LCD Y轴+vbp+vspw+vfp */  
	.vrefresh = 60, /* LCD的刷新频率为60HZ */ 12 
}; 

添加上这些,就能将设备树上的屏幕信息和驱动对应上。DRM框架就能驱动屏幕。

以上几个结构体分别对应KMS里面的crtc、plane、encoder、panel几个部分。对应着写好代码即可。都比较简单。最后一个是drm_panel相关的,屏幕这部分可以使用已经定义好的struct panel_desc结构体去描述,struct panel_desc结构体里面有drm_panel,struct panel_desc可以看作是drm_panel的继承。

panel-simple.c里面实际上使用的是struct mipi_dsi_driver panel_simple_dsi_driver结构体作为驱动描述结构体。

static struct mipi_dsi_driver panel_simple_dsi_driver = {
	.driver = {
		.name = "panel-simple-dsi",
		.of_match_table = dsi_of_match,
	},
	.probe = panel_simple_dsi_probe,
	.remove = panel_simple_dsi_remove,
	.shutdown = panel_simple_dsi_shutdown,
};

本质上依然是个platform驱动。在panel_simple_init函数里面可以看到

static int __init panel_simple_init(void)
{
	int err;

	err = platform_driver_register(&panel_simple_platform_driver);
	if (err < 0)
		return err;

	if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
		err = mipi_dsi_driver_register(&panel_simple_dsi_driver);
		if (err < 0)
			return err;
	}

	return 0;
}
module_init(panel_simple_init);

注册一个platform驱动,在panel_simple_dsi_probe函数中进行匹配,根据上面static const struct of_device_id platform_of_match[]中已经定义的数组数据。

三、总结

        DRM驱动是目前Linux内核主流的显示框架,支持现代的显示技术,社区参与度、活跃度都很高,传统的framebuffer基本上已经处于半废弃状态。DRM驱动开发离不开KMS中的几个模块,按照定义好的结构体填充代码,完成开发,还算比较方面。

相关链接:

linux驱动系列学习之DRM(十)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/821576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM处理器 指令(读写内存、状态寄存器、软中断、协处理器……)

一、数据处理指令1&#xff09;数学运算数据运算指令的格式数据搬移指令立即数伪指令加法指令带进位的加法指令减法指令带借位的减法指令逆向加法指令乘法指令数据运算指令的扩展 2&#xff09;逻辑运算按位与指令按位或指令按位异或指令左移指令右移指令位清零指令 3&#xff…

弱监督语义分割伪标签可视化(把单通道灰度图转为voc格式语义分割标签的彩色形式)

一、目的 以图片2007_001960为例&#xff0c;voc数据集中的原图和对应的语义分割标签分别如下&#xff1a; 图1 图2 图像级标签WSSS任务第一阶段最后生成的pseudo mask如下&#xff1a; 图3 我们的…

【100天精通python】Day22:字符串常用操作大全

目录 专栏导读 一、 字符串常用操作 1 拼接字符串 2 计算字符串长度 3 截取字符串 4 分割合并字符串 5 检索字符串 6 字母的大小写转换 7 去除字符串的空格和特殊字符 8 格式化字符串 二 、字符串编码转换 2.1 使用encode()方法编码 2.2 使用decoder()方法编码 专栏…

深度学习笔记-暂退法(Drop out)

背景 在机器学习的模型中&#xff0c;如果模型的参数太多&#xff0c;而训练样本又太少&#xff0c;训练出来的模型很容易产生过拟合的现象。在训练神经网络的时候经常会遇到过拟合的问题&#xff0c;过拟合具体表现在&#xff1a;模型在训练数据上损失函数较小&#xff0c;预…

Grandle安装配置(8.2.1)-windows环境

一、官网地址 https://gradle.org/releases/ 下载链接&#xff1a; https://downloads.gradle.org/distributions/gradle-8.2.1-bin.zip 下载后解压到指定文件夹,实例安装目录为&#xff1a; D:\ProgramFiles\gradle-8.2.1 二、配置环境变量 示例中配置的目录为&#xff1a…

二十一章:PUZZLE-CAM:通过匹配局部和全局特征来改进定位

0.摘要 弱监督语义分割&#xff08;WSSS&#xff09;被引入来缩小从像素级监督到图像级监督的语义分割性能差距。大多数先进的方法是基于类激活图&#xff08;CAM&#xff09;来生成伪标签以训练分割网络。WSSS的主要局限性在于从使用图像分类器的CAM生成伪标签的过程主要集中在…

【测试设计】基于正交法的测试用例设计工具--PICT

目录 前言 下载安装 用例生成 使用示例 具体操作&#xff1a; 资料获取方法 前言 我们都知道成对组合覆盖是一种非常有效的测试用例设计方法&#xff0c;但是实际工作过程中当成对组合量太大&#xff0c;我们往往很难做到有效的用例覆盖。 PICT是微软公司出品的一款成对…

spark-sql数据重复之File Output Committer问题

前言 我们先来回顾下之前介绍过的三种Committer&#xff1a;FileOutputCommitter V1、FileOutputCommitter V2、S3A Committer&#xff0c;其基本代表了整体的演进趋势。 核心代码讲解详细参照&#xff1a;Spark CommitCoordinator 保证数据一致性 OutputCommitter commitTask…

集群部署dolphinscheduler踩坑

本文主要总结一下最新版dolphinscheduler3.1.5的安装过程中遇到的坑。 dolphinscheduler启动报错 Exception in thread "Master-Server" org.springframework.beans.factory.BeanCreationException: Error creating bean with name masterServer: Invocation of in…

先进先出法与加权平均法的比较

加权平均法 加权平均的成本核算方法在计算销货成本和期末库存价值时使用每个库存物料的平均成本。企业将使用以下公式计算每个库存单位&#xff08;在特定会计期间内&#xff09;的平均成本&#xff1a; 平均库存成本 &#xff08;所有采购商品的总成本&#xff09;/&#xff…

Matlab Optimization Toolbox中的遗传算法工具包(GA)

matlab optimization 中使用了GA求解器 默认的是小于等于 找到GA 工具包 找到 APP选择 Optimization Tool 选择Solver ga - Genetic Algorithm 应用GA solver 定义适应度函数(Fitness function)与问题约束(Constraints) example one 优化函数 sin(x) 2 * cos(x)极其重要的…

【原创】IPTVC2实现方案(文末有demo)

前言: 名词解释: IPTVC2, 全称: 央视国际节目定价发布接口规范,标准版本当前最新为2.7.12 附赠资源链接&#xff0c;侵删:规范 规范中提供的样例&#xff0c;实现基于axis1.4(2006的时代宠物) 基于axis1版本的实现参考: Spring boot 集成Axis1.4 &#xff0c;使用wsdd文件发…

C语言每日一题:12《数据结构》相交链表。

题目&#xff1a; 题目链接 思路一&#xff1a; 1.如果最后一个节点相同说明一定有交点。 2.使用两个循环获取一下长度&#xff0c;同时可以获取到尾节点。 3。注意初始化lenA和lenB为1&#xff0c;判断下一个节点是空是可以保留尾节点的。长度会少一个&#xff0c;尾节点没有…

【C++修炼之路】多态

&#x1f451;作者主页&#xff1a;安 度 因 &#x1f3e0;学习社区&#xff1a;StackFrame &#x1f4d6;专栏链接&#xff1a;C修炼之路 文章目录 一、概念二、定义和实现1、虚函数2、虚函数的重写3、多态的构成条件4、重写的例外5、C11 override 和 final6、不能被继承的类7…

RxJava异步编程初探

RxJava 其实就是提供一套异步编程的 API&#xff0c;这套 API 是基于观察者模式的&#xff0c;而且是链式调用的&#xff0c;所以使用 RxJava 编写的代码的逻辑会非常简洁。 RxJava 有以下三个基本的元素&#xff1a; 被观察者&#xff08;Observable&#xff09;观察者&…

prometheus+grafana进行服务器资源监控

在性能测试中&#xff0c;服务器资源是值得关注一项内容&#xff0c;目前&#xff0c;市面上已经有很多的服务器资 源监控方法和各种不同的监控工具&#xff0c;方便在各个项目中使用。 但是&#xff0c;在性能测试中&#xff0c;究竟哪些指标值得被关注呢&#xff1f; 监控有…

SqlSugar、Freesql、Dos.ORM、EF、四种ORM框架的对比

SqlSugar、Freesql、Dos.ORM、EF、四种ORM框架的对比 一、默认情况下,导航属性是延迟查询; 答:ORM(Object-relational mapping)即对象关系映射,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。也就是说,ORM是通过使用描述对象和数据库之间映射的元数据…

线程状态

从卖包子的案例学习进程间的通信 public class Test {public static void main(String[] args) {Object objnew Object();Thread th1new Thread(){Overridepublic void run() {synchronized (obj){System.out.println("来三个包子&#xff01;");try {obj.wait(); /…

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传

IDEA删除本地git仓库、创建本地git仓库、关联其他仓库并上传 删除本地Git仓库 创建本地Git仓库 关联其他仓库并上传 要在IntelliJ IDEA中删除本地Git仓库并创建新的本地Git仓库&#xff0c;以及关联其他仓库并上传&#xff0c;请按照以下步骤进行操作&#xff1a; 删除本地G…

【笔记】数据结构与算法 python-03-列表查找

列表查找 在一个数据结构中&#xff0c;通过一定的方法找出与给定关键字相同的数据元素的过程。 列表查找&#xff08;线性表查找&#xff09;&#xff1a;从列表&#xff08;一种线性数据结构&#xff0c;元素按照一定的顺序存储&#xff0c;每个元素都有一个唯一的位置索引…