Linux驱动开发之DRM驱动

作者

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介绍

架构

20150930192518294
重要概念:

  • 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驱动架构,
Xlnx DRM KMS
Xilinx DRM SDI Tx驱动架构,可以看到有Bridge这个桥接设备,但这个桥接设备无需任何操作,
SDI Tx

驱动

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 tree

	hdcp_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具体的时序信息。

  • 0
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux DRM(Direct Rendering Manager)驱动Linux操作系统中用于显卡和显示设备管理的驱动程序。它提供了一套统一的接口,使得用户可以通过应用程序直接访问显卡硬件,实现图形渲染和硬件加速等功能。 Linux DRM驱动包括了核心驱动模块和设备驱动模块。核心驱动模块负责提供基本的显卡管理功能,如内存分配、模式设置和渲染命令队列等。设备驱动模块负责支持特定显卡和显示设备的硬件特性和功能。通过这种模块化的设计,Linux DRM驱动能够支持多种显卡和显示设备。 在分析Linux DRM驱动时,可以从以下几个方面入手: 1. 驱动架构:了解Linux DRM驱动的整体架构,包括核心驱动模块和设备驱动模块的功能和交互方式。 2. 设备支持:分析特定显卡和显示设备的驱动模块,了解其支持的硬件特性和功能。 3. 内存管理:了解Linux DRM驱动中的内存管理机制,包括内存分配、显存管理和页面交换等。 4. 渲染和硬件加速:分析Linux DRM驱动中的渲染命令队列和硬件加速功能的实现方式。 5. 显示管道:了解Linux DRM驱动中的显示管道管理机制,包括模式设置和输出控制等。 通过对Linux DRM驱动的分析,可以更深入地理解显卡和显示设备的工作原理,为开发应用程序和调优系统性能提供指导和参考。此外,还可以通过分析和改进Linux DRM驱动来实现新的显卡和显示设备的支持,提升系统的兼容性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值