1. 程式人生 > 其它 >Linux 中基於 DRM 的圖形顯示系統概述

Linux 中基於 DRM 的圖形顯示系統概述

Linux系統中圖形顯示方案

1

FBDEV

Framebuffer device

社群參與度不高,基本轉移到了DRM。

DRM/KMS

Direct Rendering Manager / KernelMode Setting

主流的圖形顯示方法,社群參與度高,支援圖形系統精細化操作,基本形成了一套圖顯系統開發的生態標準。

V4L2

Video For Linux 2

主要用於視訊捕獲的應用場景,並且需要特定輸出裝置,對複雜圖顯控制器的支援不佳

DRM系統組成

2kernel層面的DRM系統包含兩大部分,一部分是圖顯裝置的DRM抽象,另外一部分是圖顯裝置的視訊記憶體控制。

圖片來源於網路

========================

圖片來源於網路

========================

上圖涵蓋了linux系統中DRM系統組成,kernel為使用者層提供標準的DRM介面,在使用者層依據DRM庫構建各種圖顯協議,圖顯應用層基於這些中介軟體完成應用程式的開發。

##視訊記憶體Framebuffer

申請的一塊用於儲存顯示資料的記憶體區域,主要包括:
1)記憶體區域大小範圍
2)記憶體中待顯示資料的幀格式
3)記憶體中有效的區域,該部分是待顯示資料


其實現方法主要有3種:
1)基於CMA的
drivers/gpu/drm/drm_fb_cma_helper.c
2)基於Scatter Gather
drivers/gpu/drm/tegra/
3)基於IOMMU
drivers/gpu/drm/exynos/exynos_drm_iommu.c

視訊記憶體區域定義

幀格式定義

支援的幀格式以FOURCC格式來呈現,其定義形式如下:

1/*24bppRGB*/
2#defineDRM_FORMAT_RGB888fourcc_code('R','G','2','4')
3#defineDRM_FORMAT_BGR888fourcc_code('B','G','2','4')
4
5/*32bppRGB*/
6#defineDRM_FORMAT_XRGB8888fourcc_code('X','R','2','4')
7#defineDRM_FORMAT_XBGR8888fourcc_code('X','B','2','4')
8#defineDRM_FORMAT_RGBX8888fourcc_code('R','X','2','4')
9#defineDRM_FORMAT_BGRX8888fourcc_code('B','X','2','4')

建立FRAME BUFFER

建立成功可在dev下看見fb裝置


##CRTC

CRT Controller, 陰極射線管控制,對顯示buffer進行掃描,併產生時序訊號。

CRTC funcs

 1staticconststructdrm_crtc_funcsade_crtc_funcs={
2.destroy=drm_crtc_cleanup,
3.set_config=drm_atomic_helper_set_config,
4.page_flip=drm_atomic_helper_page_flip,
5.reset=drm_atomic_helper_crtc_reset,
6 .atomic_duplicate_state=drm_atomic_helper_crtc_duplicate_state,
7.atomic_destroy_state=drm_atomic_helper_crtc_destroy_state,
8.enable_vblank=ade_crtc_enable_vblank,
9.disable_vblank=ade_crtc_disable_vblank,
10};

CRTC helper funcs

1staticconststructdrm_crtc_helper_funcsade_crtc_helper_funcs={
2.mode_fixup=ade_crtc_mode_fixup,
3.mode_set_nofb=ade_crtc_mode_set_nofb,
4.atomic_begin=ade_crtc_atomic_begin,
5.atomic_flush=ade_crtc_atomic_flush,
6.atomic_enable=ade_crtc_atomic_enable,
7.atomic_disable=ade_crtc_atomic_disable,
8};

##PLANE

圖片來源於網路

========================

PLANE funcs

1staticstructdrm_plane_funcsade_plane_funcs={
2.update_plane=drm_atomic_helper_update_plane,
3.disable_plane=drm_atomic_helper_disable_plane,
4.destroy=drm_plane_cleanup,
5.reset=drm_atomic_helper_plane_reset,
6.atomic_duplicate_state=drm_atomic_helper_plane_duplicate_state,
7.atomic_destroy_state=drm_atomic_helper_plane_destroy_state,
8};

PLANE helper funcs

1staticconststructdrm_plane_helper_funcsade_plane_helper_funcs={
2.atomic_check=ade_plane_atomic_check,
3.atomic_update=ade_plane_atomic_update,
4.atomic_disable=ade_plane_atomic_disable,
5};

##ENCODER/CONNECTOR

ENCODER負責將CRTC輸出的timing時序轉換成外部裝置所需要的訊號的模組,如HDMI轉換器。CONNECTOR 連線物理顯示裝置的聯結器,如HDMI、DisplayPort、DSI匯流排,通常和Encoder驅動繫結在一起。

圖片來源於網路

========================

ENCODER/helper funcs

 1staticconststructdrm_encoder_helper_funcsdw_encoder_helper_funcs={
2.atomic_check=dsi_encoder_atomic_check,
3.mode_valid=dsi_encoder_mode_valid,
4.mode_set=dsi_encoder_mode_set,
5.enable=dsi_encoder_enable,
6.disable=dsi_encoder_disable
7};
8
9staticconststructdrm_encoder_funcsdw_encoder_funcs={
10.destroy=drm_encoder_cleanup,
11};

CONNECTOR/helper funcs

 1staticconststructdrm_connector_helper_funcs
2panel_bridge_connector_helper_funcs={
3.get_modes=panel_bridge_connector_get_modes,
4};
5
6staticconststructdrm_connector_funcspanel_bridge_connector_funcs={
7.reset=drm_atomic_helper_connector_reset,
8.fill_modes=drm_helper_probe_single_connector_modes,
9.destroy=drm_connector_cleanup,
10.atomic_duplicate_state=drm_atomic_helper_connector_duplicate_state,
11.atomic_destroy_state=drm_atomic_helper_connector_destroy_state,
12};

##ioctl註冊

component元件系統
3kernel中的component框架是為了subsystem能夠按照一定的順序初始化裝置而提出的架構。
subsystem中由較多裝置模組組成,而QQ購買核心載入每個模組時間不定。則需要component框架來保證需最後初始化的裝置載入前,所需裝置全部載入完畢。

在component中,包含兩個基本概念,master和component。

master是裝置樹中的“超級裝置(superdevice)”,負責管理該超級裝置下的普通裝置。component是由master管理的普通裝置,要先初始化。

#初始化分為兩部分

master即超級裝置,執行probe使用component_master_add_with_match函式註冊自己到component框架中。

component即普通裝置,執行probe使用component_add函式註冊自己到component框架中。

##Master初始化

 1staticintkirin_drm_platform_probe(structplatform_device*pdev)
2{
3structdevice*dev=&pdev->dev;
4structdevice_node*np=dev->of_node;
5structcomponent_match*match=NULL;
6structdevice_node*remote;
7
8remote=of_graph_get_remote_node(np,,);
9if(!remote)
10return-ENODEV;
11
12drm_of_component_match_add(dev,&match,compare_of,remote);
13of_node_put(remote);
14
15returncomponent_master_add_with_match(dev,&kirin_drm_ops,match);
16}


##Component初始化

 1staticintdsi_probe(structplatform_device*pdev)
2{
3structdsi_data*data;
4structdw_dsi*dsi;
5structdsi_hw_ctx*ctx;
6intret;
7
8data=devm_kzalloc(&pdev->dev,sizeof(*data),GFP_KERNEL);
9if(!data){
10DRM_ERROR("failedtoallocatedsidata.\n");
11return-ENOMEM;
12}
13dsi=&data->dsi;
14ctx=&data->ctx;
15dsi->ctx=ctx;
16
17ret=dsi_parse_dt(pdev,dsi);
18if(ret)
19returnret;
20
21platform_set_drvdata(pdev,data);
22
23returncomponent_add(&pdev->dev,&dsi_ops);
24}

##裝置樹定義

圖顯系統裝置樹定義要遵循component框架的定義,使得各個元件能夠組成一個完成的拓撲結構。

 1ade:ade@f4100000{
2compatible="hisilicon,hi6220-ade";
3reg=<0x00xf41000000x00x7800>;
4reg-names="ade_base";
5hisilicon,noc-syscon=<&medianoc_ade>;
6resets=<&media_ctrlMEDIA_ADE>;
7interrupts=<1154>;/*ldiinterrupt*/
8
9clocks=<&media_ctrlHI6220_ADE_CORE>,
10<&media_ctrlHI6220_CODEC_JPEG>,
11<&media_ctrlHI6220_ADE_PIX_SRC>;
12/*clockname*/
13clock-names="clk_ade_core",
14"clk_codec_jpeg",
15"clk_ade_pix";
16
17assigned-clocks=<&media_ctrlHI6220_ADE_CORE>,
18<&media_ctrlHI6220_CODEC_JPEG>;
19assigned-clock-rates=<360000000>,<288000000>;
20dma-coherent;
21status="disabled";
22
23port{
24ade_out:endpoint{
25remote-endpoint=<&dsi_in>;
26};
27};
28};
29
30dsi:dsi@f4107800{
31compatible="hisilicon,hi6220-dsi";
32reg=<0x00xf41078000x00x100>;
33clocks=<&media_ctrlHI6220_DSI_PCLK>;
34clock-names="pclk";
35status="disabled";
36
37ports{
38#address-cells=<1>;
39#size-cells=<>;
40
41/*0forinputport*/
42port@{
43reg=<>;
44dsi_in:endpoint{
45remote-endpoint=<&ade_out>;
46};
47};
48};
49};

modetest
4是由libdrm提供的測試程式,可以查詢顯示裝置的支援狀況,進行基本的顯示測試,以及設定顯示的模式。

填充不同的資料格式顯示結果如下:

- EOF -