当前位置: 首页 > news >正文

MTK Linux DRM分析(十四)- Mediatek KMS实现mtk_drm_drv.c(Part.2)

一、MTK KMS分析

mtk_drm_kms_init 函数分析

mtk_drm_kms_init 是 MediaTek DRM 驱动程序中的一个静态函数(static int mtk_drm_kms_init(struct drm_device *drm)),位于 mtk_drm_drv.c 文件中。该函数的主要作用是初始化 DRM 设备的 Kernel Mode Setting (KMS) 子系统,包括配置显示模式、绑定硬件组件、创建 CRTC(Controller)、设置 DMA 参数、初始化各种辅助结构和工作队列等。它是驱动从硬件抽象层过渡到 DRM 框架的核心入口点,通常在组件绑定(component_bind_all)后调用,确保显示管道(display pipeline)准备就绪,支持用户空间的图形渲染和模式设置。

函数的输入是一个已分配的 drm_device 结构(包含 MediaTek 特定的私有数据 mtk_drm_private)。输出为 0(成功)或负错误码(失败)。整个函数逻辑严谨,包含多个错误处理路径(使用 goto 跳转清理资源)。下面我基于提供的代码,按步骤详细分析其执行流程、关键操作和潜在逻辑。

1. 准备阶段:获取私有数据和检查依赖
  • struct mtk_drm_private *private = drm->dev_private;
    • 从 drm_device 中提取 MediaTek 特定的私有数据结构 mtk_drm_private,其中包含设备树节点、寄存器映射、helper_opt 等信息(这些在 mtk_drm_probe 中已初始化)。
  • 检查 M4U (Memory Management Unit) 支持:
    • if (mtk_drm_helper_get_opt(private->helper_opt, MTK_DRM_OPT_USE_M4U)) { ... }
      • 如果启用 M4U(IOMMU 相关的内存管理选项),检查 IOMMU 是否就绪(iommu_present(&platform_bus_type))。
      • 如果 IOMMU 未准备好,返回 -EPROBE_DEFER,延迟驱动探测(probe),等待 IOMMU 驱动加载。这确保了 DMA 内存分配的安全性和连续性(防止内存碎片)。
  • 日志记录:DDPINFO("%s+\n", __func__); – 输出调试信息,表示函数开始。
2. 初始化 DRM Mode Config
  • drm_mode_config_init(drm);
    • 初始化 DRM 的模式配置结构(drm_mode_config),设置默认的模式设置回调(如 atomic_check、atomic_commit),启用原子模式设置支持。
  • 设置默认分辨率限制:
    • drm->mode_config.min_width = 1; drm->mode_config.min_height = 1;
      • 最小分辨率设置为 1x1(默认最小值,避免无效模式)。
    • drm->mode_config.max_width = 4096; drm->mode_config.max_height = 4096;
      • 最大分辨率设置为 4096x4096(默认值,用于检查帧缓冲区大小限制,在 drm_mode_addfb 中使用)。
  • 设置模式配置函数:drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
    • 关联 MediaTek 特定的模式配置函数(未在代码中显示,但可能是自定义的页面翻转、属性处理等)。
3. 绑定组件和初始化 VBlank
  • ret = component_bind_all(drm->dev, drm);
    • 绑定所有显示组件(通过 mtk_drm_ops 中的 bind 函数),这些组件在 mtk_drm_probe 中已添加到 match 列表中(如 OVL、RDMA、DSI 等)。
    • 如果绑定失败,跳转到 err_config_cleanup 清理 mode config。
  • ret = drm_vblank_init(drm, MAX_CRTC);
    • 初始化 VBlank(垂直同步)支持,最多支持 MAX_CRTC 个 CRTC(通常为 3 或 4,根据 SoC)。
    • VBlank 用于同步帧渲染和显示,避免撕裂(tearing)。失败则跳转到 err_component_unbind 解绑组件。
4. 创建 CRTC(显示控制器)
  • ret = mtk_drm_crtc_create(drm, private->data->main_path_data);
    • 创建主路径 CRTC(OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 等)。
    • main_path_data 来自 SoC 特定的数据(如 mt6885_mmsys_driver_data)。
  • 根据设备树属性和阶段(disp_helper_get_stage())创建扩展路径:
    • 如果是正常阶段(DISP_HELPER_STAGE_NORMAL):
      • 检查 "enable_ext_alter_path" 属性,如果启用,使用 ext_alter_path_data 创建扩展路径 CRTC(OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0)。
      • 否则,使用 ext_path_data。
    • 创建第三个 CRTC(third_path_data 或变体,根据 "condition-num" 属性调整路径,如是否包含 TDSHP)。
    • 创建第四个 CRTC(如果启用 "enable_secondary_path" 或 "enable_discrete_path",使用 fourth_path_data_secondary 或 fourth_path_data_discrete)。
  • 这些 CRTC 代表不同的显示管道,支持多屏输出(如主屏、扩展屏)。
  • 失败则跳转到 err_component_unbind。
  • 注释:/*TODO: Need to check path rule*/ – 表示路径规则检查待实现,可能涉及硬件兼容性。
5. 设置 DMA 和内存分配
  • 选择 OVL 设备作为 DMA 分配设备:
    • 从主路径或扩展路径的第一个组件节点获取 OVL 设备(private->comp_node[...])。
    • private->dma_dev = &pdev->dev;
      • 使用 OVL 设备进行所有 DMA 内存分配,确保连续 IOVA(IO Virtual Address)用于 PRIME 缓冲区导入。
  • 配置 DMA 参数:
    • 如果 dma_dev->dma_parms 未分配,动态分配(devm_kzalloc)。
    • ret = dma_set_max_seg_size(dma_dev, (unsigned int)DMA_BIT_MASK(32));
      • 设置 DMA 段最大大小为 32-bit(4GB),确保 PRIME 缓冲区导入时的连续性。
    • 失败则清理并返回。
  • drm_mode_config_reset(drm);
    • 重置模式配置到默认状态。
6. <
http://www.dtcms.com/a/355626.html

相关文章:

  • 工业机器人如何通过Modbus TCP转CanOpen网关高效通信!
  • 机器学习基本介绍
  • 【练习九】Java实现加油站支付小程序:存款与消费
  • 健永科技RFID技术在高压电厂机器狗巡检中的应用
  • Access token(访问令牌:以JWT格式无状态存储)和Refresh token(刷新令牌:有状态存储于Redis/DB)区别与联系、Redis黑名单
  • C#-mqtt通讯,服务端和客户端,以及esp32-mqtt
  • 第二十节:3D文本渲染 - 字体几何体生成与特效
  • 神经网络 | 基于matlab的LSTM详解
  • 3D高斯溅射实现医疗影像内部场景渲染
  • 【论文阅读】Object Detection in Adverse Weather for Autonomous Driving through Data Merging and YOLOv8
  • ConceptGraphs: Open-Vocabulary 3D Scene Graphs for Perception and Planning
  • 第八章:《性能优化技巧》——深入讲解预分配容量、移动语义、避免频繁拼接等优化策略,以及C++17的`string_view`如何减少拷贝开
  • 三电平逆变器SVPWM控制(无解耦功能)与谐波分析
  • gpt-5生成圆柱blockmesh脚本
  • UDS NRC24
  • 修改win11任务栏时间字体和小图标颜色
  • Graphpad Prism Mac医学绘图工具
  • GraphRAG技术深度解析:重新定义智能问答的未来
  • 数据结构初阶:详解顺序表OJ题
  • CUDA 矩阵分块乘法
  • Rust Web开发指南 第六章(动态网页模板技术-MiniJinja速成教程)
  • Docker 核心技术:Union File System
  • 知微集:梯度下降详解
  • 编写TreeMap自定义排序的插曲
  • 信号量使用流程
  • 多媒体内容智能检索技术进展
  • [特殊字符] ​​MySQL性能参数查询总结​
  • 146-延长无线传感器网络生命周期的睡眠调度机制的混合元启发式优化方法!
  • [RK3576][Android14] Android->添加以太网MAC地址选项
  • Spring Boot 实战:接入 DeepSeek API 实现问卷文本优化