【ATU Book-i.MX8系列】 NXP i.MX8M Mini DRM driver解析(Part 2)

關(guān)鍵字 :NXPi.MX8M Mini
1. 萬(wàn)事俱備
  • Bring Up Master

? ? ? ? 上一篇文章提到,bring up master 的條件是所有的子元件都匹配成功。滿足此條件之後,會(huì)呼叫 master 的 imx_drm_ops 的 bind function。在這個(gè) imx_drm_bind() 裡面除了會(huì)初始化〝mode config〞以及〝vblank〞,更重要的,因?yàn)樽釉家呀?jīng)準(zhǔn)備好了,所以有辦法將所有的子元件綁定在一起。就在 component_bind_all() 裡面,會(huì)逐一掃過所有的 match 的元件,呼叫其各自的 bind function,讓 master 與子元件建立交互關(guān)係。最後,會(huì)初始化 fbdev(drm_fbdev_cma_init())完成 DRM 子系統(tǒng)的初始化過程。


  • 逐一呼叫各自的 bind function 進(jìn)行綁定


? ? ? ? 以我們舉的例子來看,會(huì)呼叫的 bind function 有兩個(gè),一個(gè)是 CRTC 的 lcdif_crtc_bind(),還有另一個(gè)是 Encoder 的 imx_sec_dsim_bind()。

? ? ? ? CRTC 主要負(fù)責(zé)接收來自多個(gè) drm_plane 的 pixel data,並將它們做好疊圖的處理。另外也負(fù)責(zé) maintain drm_display_mode,讓 panel 有正確的 resolution 以及 timing 的設(shè)定。下一步這些 pixel data 就可以餵給 drm_encoder 做下一步的處理。所以,lcdif_crtc_bind() 所進(jìn)行的 drm_crtc 初始化,其中就包括了 plane、mode config function 等設(shè)定,完成之後的 CRTC 就 ready 好處?kù)犊傻却蠈又噶畹臓顟B(tài)。

  • CRTC 的 lcdif_crtc_bind()


  • drm_crtc 初始化,其中就包括了 plane、mode config function 等設(shè)定

? ? ? ? Encoder 主要連接 drm_crtc 跟 drm_connector,負(fù)責(zé)將 CRTC 過來的 pixel data 轉(zhuǎn)換成適合 Connector 的格式,再交給 Connector。所以在 imx_sec_dsim_bind() 裡,因?yàn)榈讓舆B接的介面是 MIPI DSI,所以自然就會(huì)選用 type 為 DRM_MODE_ENCODER_DSI 的 codec 為 drm_encoder 進(jìn)行初始化。

? ? ? ? 另外,有一個(gè)子元件〝bridge〞前面沒有提到,是一個(gè)鏈狀的結(jié)構(gòu),可以視為 Encoder 的延伸,最終才會(huì)接到 Connector(panel)。因此,會(huì)進(jìn)行延伸 bridge 的 bind function,而且此動(dòng)作會(huì)重複直到連接到 Connector 為止。在 Connector 完成 drm_connector_init()、drm_mode_connector_attach_encoder()、還有 drm_panel_attach() 之後,Encoder 跟 Connector 也完成它們的初始化等待上層指令。

  • Encoder 的 imx_sec_dsim_bind(),選用 DRM_MODE_ENCODER_DSI,並開始嘗試進(jìn)行 bridge bind


  • bridge 的 bind function 會(huì)重複執(zhí)行直到連接到 Connector 為止,被找到的 Connector 會(huì)進(jìn)行初始化

?

? ? ? ? Frame Buffer 主要功能為提供一塊記憶體來儲(chǔ)存要秀出的圖像資料,而 DRM 的 Frame Buffer 是由 GEM 來管理。在談 drm_framebuffer 之前,系統(tǒng)需要開啟 CONFIG_DRM_FBDEV_EMULATION 的功能。開啟這個(gè)功能後,表示 DRM 將可以模擬一個(gè) Frame Buffer 設(shè)備,如此上層便可使用基於 fbdev 的顯示框架。於是乎,drm_framebuffer 的初始化,drm_fbdev_cma_init(),這個(gè) function 也成為我們最後一個(gè)在 imx_drm_bind() 裡面要分析的。

  • 在 drm_fbdev_cma_init() 裡面,
  1. 首先會(huì)進(jìn)行 CRTC 還有 Connector 的綁定,分別實(shí)作在 drm_fb_helper_init() 還有 drm_fb_helper_single_add_all_connectors() function
  2. 有了這個(gè)基礎(chǔ),接下來會(huì)呼叫 drm_fb_helper_initial_config() 進(jìn)行 best mode 的選定跟 fbdev 的創(chuàng)建。



  • drm_fb_helper_initial_config(),可分解為 CRTC 的設(shè)置以及 drm frame buffer 的建立。



  • drm_setup_crtcs() 會(huì)設(shè)置好每一個(gè) CRTC,方法是從每個(gè) Connector 得到所有的 mode,並以此為每一個(gè) CRTC 挑選計(jì)算出來分?jǐn)?shù)最好的,建立出一個(gè) CRTC 跟 Connector 之間的 mapping。
  • drm_fb_helper_single_fb_probe() 則會(huì)初始化 drm_framebuffer,其過程與一般的 Frame Buffer初始化過程差不多,最後呼叫 register_framebuffer() 完成 Frame Buffer 的註冊(cè)之後,F(xiàn)rame Buffer 就可以使用了。

?

  • 小結(jié)

? ? ? ? 流程至此,已經(jīng)完成 DRM 子系統(tǒng)的初始化過程。表示 DRM driver 已經(jīng) ready 等待上層使用,所以在下一章節(jié)會(huì)簡(jiǎn)單介紹上層如何使用 DRM。



2. DRM 應(yīng)用程式開發(fā)

? ? ? ? 這個(gè)章節(jié)將說明如何開發(fā)一個(gè) DRM 應(yīng)用程式。關(guān)於應(yīng)用程式與 kernel space 之間的交互關(guān)係,其實(shí)我們?cè)?Chapter 1.3 有提到一點(diǎn)點(diǎn),我們?cè)侔岩韵逻@張架構(gòu)圖拿出來複習(xí)一下。這張架構(gòu)圖說明了,在 user space 的應(yīng)用程式會(huì)透過 libdrm 間接對(duì) kernel space 進(jìn)行 ioctrl 操作。而一般的 DRM 應(yīng)用程式需要包含的基本內(nèi)容有,

  1. open("/dev/dri/card0")

? ? ? ? 最基本的 open file node 取得 handle。

?

  1. drmModeGetResources(...)

? ? ? ? 利用 DRM_IOCTL_MODE_GETRESOURCES,取得 CRTC、Encoder、Connector 等 ID 以及個(gè)數(shù)。

?

  1. drmModeGetConnector(...)

? ? ? ? 利用上式內(nèi)容,DRM_IOCTL_MODE_GETCONNECTOR 可取得 Connector 真實(shí)的資訊,包含 modes setting。

?

  1. DRM_IOCTL_MODE_CREATE_DUMBdrmModeAddFB(...)drmIoctl(DRM_IOCTL_MODE_MAP_DUMB)mmap(...)

? ? ? ? 以上 function 可建立一個(gè) dumb framebuffer 並完成映射。

?

  1. drmModeSetCrtc(crtc_id, fb_id, connector_id, mode)

? ? ? ? 設(shè)定 CRTC 並連接到 dumb framebuffer,開始進(jìn)行螢?zāi)伙@示。

?

? ? ? ? 基於上面的架構(gòu),我們?cè)诰W(wǎng)路上找到一個(gè)範(fàn)例程式,single buffer。這隻範(fàn)例程式建立一個(gè) dumb framebuffer,內(nèi)容全部都是 0xFF(也就是白色),並把它顯示到螢?zāi)簧稀⒖脊?fàn)例程式碼連結(jié)以及實(shí)際上執(zhí)行的結(jié)果如下:

https://blog.csdn.net/hexiaolong2009/article/details/83721242



0. 前提需要先關(guān)掉占用 DRM 的 device



此時(shí),螢?zāi)粺o(wú)輸出變?yōu)楹谏?br/>


1. 執(zhí)行測(cè)試程式 ./modeset-single-buffer


此時(shí),螢?zāi)惠敵?dumb framebuffer 內(nèi)容,0xFF,為白色,

?

  • 小結(jié)

? ? ? ?以上我們整篇文章從 device tree 開始,一路介紹到 kernel space 的 DRM driver 的初始化流程,然後更進(jìn)一步完成 user space 的 DRM 應(yīng)用程式範(fàn)例。從下到上,對(duì)於 Linux Display 可說是有了一個(gè)整體性的概念,基於此概念往上延伸不論是 Android 的 display 子系統(tǒng)或是 Wayland等 framework 可說是打下了深厚的基礎(chǔ)。因此,各位開發(fā)者在未來遇到 display 的問題時(shí),對(duì)於如何排錯(cuò)就擁有了一個(gè)好的起手式,不至於毫無(wú)頭緒。完成 DRM 之後,後續(xù)我們將繼續(xù)深究其它在 i.MX8M Mini 上的 Linux driver,一塊一塊的組合出整個(gè) i.MX8M Mini EVK 指日可待。TBC…


3. 參考文件

★博文內(nèi)容均由個(gè)人提供,與平臺(tái)無(wú)關(guān),如有違法或侵權(quán),請(qǐng)與網(wǎng)站管理員聯(lián)繫。

★文明上網(wǎng),請(qǐng)理性發(fā)言。內(nèi)容一周內(nèi)被舉報(bào)5次,發(fā)文人進(jìn)小黑屋喔~

參考來源

評(píng)論