作者

QQ群:852283276
微信:arm80x86
微信公众号:青儿创客基地
B站:主页 https://space.bilibili.com/208826118

参考

Linux DRM Graphic 显示简单介绍
linux DRM driver 使用示例
DRM实例教程
DRM 驱动程序开发(开篇)
DRM 驱动程序开发(VKMS)
最简单的DRM应用程序 (single-buffer)
drm 驱动是如何创建 fb device 的
Linux中的DRM 介绍
Linux Graphic DRI 显示子系统 介绍1
Xilinx DRM KMS driver
赛灵思xilinx平台drm分析
Linux_GUI加速(1)——GUI系统概述
Linux_GUI加速(2)——Linux中的DRM-KMS分析
Linux_GUI加速(3)——加速模块设计
Getting simple output with Xilinx DRM KMS framework
RK3399 探索之旅 / Display 子系统 / 基础概念
Rockchip DRM主驱动流程梳理
嵌入式linux hdmi分辨率,【Firefly3399Pro】rk3399pro在Framebuffer状态命令行模式中强制HDMI输出固定分辨率…
tools:modetest代码逻辑
VGA学习之EDID 那些事
如何获取显示器的EDID信息
windows——TV中的DDC和EDID介绍

架构


重要概念:

  • Planes:图层,例如在 rockchip 平台里对应 SOC 内部 VOP 模块的 win 图层;
  • CRTC:显示控制器,例如在 rockchip 平台里对应 SOC 内部的 VOP 模块;
  • Encoder:输出转换器,指 RGB、LVDS、DSI、eDP、HDMI、CVBS、VGA 等显示接口;
  • Connector:连接器,指 encoder 和 panel 之间交互的接口部分;
  • Bridge:桥接设备,一般用于注册 encoder 后面另外再接的转换芯片,如 DSI2HDMI 转换芯片;
  • Panel:泛指屏,各种 LCD、HDMI 等显示设备的抽象;

Xilinx DRM驱动架构,

Xilinx DRM SDI Tx驱动架构,可以看到有Bridge这个桥接设备,但这个桥接设备无需任何操作,

驱动

DRM驱动架构好像都是分辨率固定了,就那么几种,这也符合实际情况,比如某款屏幕支持的分辨率,可以在代码里写死,也可以放到eeprom中,以edid的格式,DRM驱动架构定义了一些默认的drm_display_modedrivers\gpu\drm\drm_edid.c中,比如,

/** Probably taken from CEA-861 spec.* This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c.** Index using the VIC.*/
static const struct drm_display_mode edid_cea_modes[] = {/* 0 - dummy, VICs start at 1 */{ },/* 1 - 640x480@60Hz 4:3 */{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,752, 800, 0, 480, 490, 492, 525, 0,DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),.vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },/* 2 - 720x480@60Hz 4:3 */{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,798, 858, 0, 480, 489, 495, 525, 0,DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),.vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
...
}

这里只有常用的分辨率,可以直接用这里的,也可以生成自己的分辨率,drm_display_mode定义如下,

#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \.name = nm, .status = 0, .type = (t), .clock = (c), \.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \.vscan = (vs), .flags = (f), \.base.type = DRM_MODE_OBJECT_MODE/*** struct drm_display_mode - DRM kernel-internal display mode structure* @hdisplay: horizontal display size* @hsync_start: horizontal sync start* @hsync_end: horizontal sync end* @htotal: horizontal total size* @hskew: horizontal skew?!* @vdisplay: vertical display size* @vsync_start: vertical sync start* @vsync_end: vertical sync end* @vtotal: vertical total size* @vscan: vertical scan?!* @crtc_hdisplay: hardware mode horizontal display size* @crtc_hblank_start: hardware mode horizontal blank start* @crtc_hblank_end: hardware mode horizontal blank end* @crtc_hsync_start: hardware mode horizontal sync start* @crtc_hsync_end: hardware mode horizontal sync end* @crtc_htotal: hardware mode horizontal total size* @crtc_hskew: hardware mode horizontal skew?!* @crtc_vdisplay: hardware mode vertical display size* @crtc_vblank_start: hardware mode vertical blank start* @crtc_vblank_end: hardware mode vertical blank end* @crtc_vsync_start: hardware mode vertical sync start* @crtc_vsync_end: hardware mode vertical sync end* @crtc_vtotal: hardware mode vertical total size** The horizontal and vertical timings are defined per the following diagram.** ::***               Active                 Front           Sync           Back*              Region                 Porch                          Porch*     <-----------------------><----------------><-------------><-------------->*       //|*      // |*     //  |..................               ................*                                                _______________*     <----- [hv]display ----->*     <------------- [hv]sync_start ------------>*     <--------------------- [hv]sync_end --------------------->*     <-------------------------------- [hv]total ----------------------------->*** This structure contains two copies of timings. First are the plain timings,* which specify the logical mode, as it would be for a progressive 1:1 scanout* at the refresh rate userspace can observe through vblank timestamps. Then* there's the hardware timings, which are corrected for interlacing,* double-clocking and similar things. They are provided as a convenience, and* can be appropriately computed using drm_mode_set_crtcinfo().** For printing you can use %DRM_MODE_FMT and DRM_MODE_ARG().*/
struct drm_display_mode {...
}

设备树

以HDMI为参考,

If hdcp1.4 is included in the design then key management block node should be
added to the device treehdcp_keymngmt_blk_0: hdcp_keymngmt_blk_top@90000000 {clock-names = "s_axi_aclk", "m_axis_aclk";clocks = <&zynqmp_clk 71>, <&misc_clk_0>;compatible = "xlnx,hdcp-keymngmt-blk-top-1.0";reg = <0x0 0x90000000 0x0 0x10000>;};hdmi_acr_ctrl_0: hdmi_acr_ctrl@a0059000 {/* This is a place holder node for a custom IP, user may need to update the entries */compatible = "xlnx,hdmi-acr-ctrl-1.0";reg = <0x0 0xa0059000 0x0 0x1000>;};v_hdmi_tx_ss: v_hdmi_tx_ss@80080000 {compatible = "xlnx,v-hdmi-tx-ss-3.1";reg = <0x0 0xa0080000 0x0 0x80000>, <0x0 0xa0280000 0x0 0x10000>;reg-names = "hdmi-txss", "hdcp1x-keymngmt";interrupt-parent = <&gic>;interrupts = <0 91 4 0 106 4 0 107 4 0 110 4 0 111 4>;interrupt-names = "irq", "hdcp14_irq", "hdcp14_timer_irq", "hdcp22_irq", "hdcp22_timer_irq";clock-names = "s_axi_cpu_aclk", "link_clk", "s_axis_audio_aclk", "video_clk", "s_axis_video_aclk", "txref-clk", "retimer-clk";clocks = <&zynqmp_clk 71>, <&misc_clk_1>, <&zynqmp_clk 71>, <&misc_clk_2>, <&zynqmp_clk 72>, <&si5324 0>, <&dp159>;phy-names = "hdmi-phy0", "hdmi-phy1", "hdmi-phy2";phys = <&vphy_lane0 0 1 1 1>, <&vphy_lane1 0 1 1 1>, <&vphy_lane2 0 1 1 1>;xlnx,input-pixels-per-clock = <0x2>;xlnx,max-bits-per-component = <0xa>;xlnx,include-hdcp-1-4;xlnx,include-hdcp-2-2;/* settings for HDCP */xlnx,hdcp-authenticate = <0x1>;xlnx,hdcp-encrypt = <0x1>;xlnx,audio-enabled;xlnx,xlnx-hdmi-acr-ctrl = <&hdmi_acr_ctrl_0>;xlnx,snd-pcm = <&audio_ss_0_audio_formatter_0>;xlnx,vid-interface = <0x1>;ports {#address-cells = <1>;#size-cells = <0>;encoder_hdmi_port: port@0 {reg = <0>;hdmi_encoder: endpoint {remote-endpoint = <&dmaengine_crtc>;};};};};v_drm_dmaengine_drv: drm-dmaengine-drv {compatible = "xlnx,pl-disp";dmas = <&hdmi_output_v_frmbuf_rd_0 0>;dma-names = "dma0";xlnx,vformat = "BG24";#address-cells = <1>;#size-cells = <0>;dmaengine_port: port@0 {reg = <0>;dmaengine_crtc: endpoint {remote-endpoint = <&hdmi_encoder>;};};};

modetest

DRM实例教程
linux DRM/KMS 测试工具 modetest、kmscude、igt-gpu-tools (一)

modetest代码在libdrm中,下载链接,https://dri.freedesktop.org/libdrm/libdrm-2.4.100.tar.bz2

# ./configure
# make -j4

编译完成后会在目录libdrm-2.4.100/tests/modetest下生成modetest可执行文件。

EDID

EDID的全称是Extended Display Identification Data,扩展显示标识数据,共有128字节。其中包含有关显示器及其性能的参数,包括供应商信息、最大图像大小、颜色设置、厂商预设置、频率范围的限制以及显示器名和序列号的字符串。DDC的全称是Display Data Channel,显示数据通道,顾名思义,它是一个通道,DDC是用来传送EDID信息的。EDID信息包含了显示器需要的128字节,128个字节的附加块可以存储在初始的EDID块之后的EDID扩展块VDIF,这些块包含addtional具体的时序信息。

Linux驱动开发之DRM驱动相关推荐

  1. Linux驱动开发之IIC驱动实验【完整教程】

    本实验基于正点原子ALPHT开发板上的AP3216C作为实验开展对象 基础知识 1.IIC总线驱动   IIC总线驱动是对IIC硬件体系结构中适配器端的实现,适配器可由CPU控制,甚至可以直接集成在C ...

  2. Linux驱动开发之USB驱动深入学习(三)——USB2.0ECHI驱动注册

    一.前言 本篇博客仅对ECHI主机控制器驱动的注册部分进行简要叙述,后面再对一些重要的接口进行分析讲解. 二.USB 1.概述 USB(Universal Serial Bus)即"通用外部 ...

  3. linux内核单步调试,Linux内核驱动开发之KGDB单步调试内核(kgdboc方式)

    如何单步调试Linux内核一直困扰着linux驱动开发人员,内核有其代码量大.逻辑复杂.与硬件交互的特性.因此,有着不同于应用程序的调试方法,据统计Linux内核开 Linux内核驱动开发之KGDB原 ...

  4. Android驱动开发之Hello实例(基于高通msm8909)

    点击打开链接 Android驱动开发之Hello实例: 驱动部分 modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_de ...

  5. Android驱动开发之Hello实例

    Android驱动开发之Hello实例: 驱动部分 modified:   kernel/arch/arm/configs/msm8909-1gb_w100_hd720p-perf_defconfig ...

  6. ⑭tiny4412 Linux驱动开发之cpufreq子系统驱动程序

    本次我们来说一下CPU动态调频子系统. 首先来看一下三星Exynos 4412的datasheet,如下: 上图就是Exynos 4412的时钟分布图,可以看到CPU的频率可以在1.4GHz~200M ...

  7. linux驱动开发之spi-omap-100k.c源码分析

    代码分析 对于linux的驱动代码来说,我们要从后往前分析: /** OMAP7xx SPI 100k controller driver* Author: Fabrice Crohas <fc ...

  8. linux 驱动开发之platform设备驱动一(4)

    前言 Linux 设备和驱动通常都需要挂接在一种总线上,例如PCI.USB.I2C.SPI 等的设备存在真实的总线,这自然不是问题,但是SOC上的外设控制器.挂接在SoC内存空间的外设等却不依附于此类 ...

  9. linux设备驱动开发之udev用户空间设备管理

    什么是udev? 这章我们来讨论一下udev这个玩意.它是什么呢?我们可以看下它的使用文档: NAME// udev-动态设备的管理功能udev - Dynamic device management ...

最新文章

  1. 阿里云ECS上环境搭建(virtualenv+flask+gunicorn+supervisor+nginx)
  2. jQuery的Accordion插件
  3. JAVA 虚拟机 (SE 7)【待更】
  4. 增益比值 dB 以及 dBw-dBmv 等之详解
  5. CVPR 2019 神奇的超分辨率算法DPSR:应对图像模糊降质
  6. docker pull 私有_Docker系列教程03Docker私有仓库搭建(registry)
  7. 《四海小记c++学习之路》队列/银行叫号系统
  8. .9图片处理报错Error: java.lang.RuntimeException: Crunching Cruncher ic_coupon2.9.png failed, see logs
  9. VS LNK2001--链接器工具错误
  10. 修改游戏存档之植物大战僵尸
  11. python文件及目录操作(copytree)
  12. 2D/3D视图变换、canvas画布
  13. 激光雷达:点云语义分割算法
  14. GIS领域常用软件工具(框架)介绍与推荐
  15. Java NIO与IO比较总结
  16. 计算机谣言之网线的做法
  17. 影响域名解析生效的原因有哪些?
  18. 自己觉得喜欢的2个项目,慢慢进步吧,呵呵
  19. vb.net2008下载地址
  20. 华为“天才少年”有多牛?入职不到一年,算法就用于千万台华为手机

热门文章

  1. LRU缓存实现与原理
  2. idea自动补全忽略大小写
  3. vue官方示例__todomvc总结
  4. 机顶盒能用鸿蒙吗,网络机顶盒怎么选?避坑必看的三大实用选购技巧
  5. nginx 部署vue项目
  6. 如何恢复台式计算机出厂设置,如何将电脑恢复出厂设置【具体方法操作】
  7. 杨幂刘诗诗吴奇隆唐嫣 明星戴眼镜卖萌PK文艺范
  8. -webkit-box-reflect属性简介及元素镜像倒影实现
  9. 编程参考 - 编程中给变量起名时如何选择前缀,以及匈牙利命名法等
  10. python读取文件按行分割字符串_python在TXT文件中按照某一字符串取出该字符串所在的行方法...