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

關鍵字 :NXPi.MX8M Mini
1. 萬事俱備
  • Bring Up Master

? ? ? ? 上一篇文章提到,bring up master 的條件是所有的子元件都匹配成功。滿足此條件之後,會呼叫 master 的 imx_drm_ops 的 bind function。在這個 imx_drm_bind() 裡面除了會初始化〝mode config〞以及〝vblank〞,更重要的,因為子元件都已經準備好了,所以有辦法將所有的子元件綁定在一起。就在 component_bind_all() 裡面,會逐一掃過所有的 match 的元件,呼叫其各自的 bind function,讓 master 與子元件建立交互關係。最後,會初始化 fbdev(drm_fbdev_cma_init())完成 DRM 子系統的初始化過程。


  • 逐一呼叫各自的 bind function 進行綁定


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

? ? ? ? CRTC 主要負責接收來自多個 drm_plane 的 pixel data,並將它們做好疊圖的處理。另外也負責 maintain drm_display_mode,讓 panel 有正確的 resolution 以及 timing 的設定。下一步這些 pixel data 就可以餵給 drm_encoder 做下一步的處理。所以,lcdif_crtc_bind() 所進行的 drm_crtc 初始化,其中就包括了 plane、mode config function 等設定,完成之後的 CRTC 就 ready 好處於可等待上層指令的狀態。

  • CRTC 的 lcdif_crtc_bind()


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

? ? ? ? Encoder 主要連接 drm_crtc 跟 drm_connector,負責將 CRTC 過來的 pixel data 轉換成適合 Connector 的格式,再交給 Connector。所以在 imx_sec_dsim_bind() 裡,因為底層連接的介面是 MIPI DSI,所以自然就會選用 type 為 DRM_MODE_ENCODER_DSI 的 codec 為 drm_encoder 進行初始化。

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

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


  • bridge 的 bind function 會重複執行直到連接到 Connector 為止,被找到的 Connector 會進行初始化

?

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

  • 在 drm_fbdev_cma_init() 裡面,
  1. 首先會進行 CRTC 還有 Connector 的綁定,分別實作在 drm_fb_helper_init() 還有 drm_fb_helper_single_add_all_connectors() function
  2. 有了這個基礎,接下來會呼叫 drm_fb_helper_initial_config() 進行 best mode 的選定跟 fbdev 的創建。



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



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

?

  • 小結

? ? ? ? 流程至此,已經完成 DRM 子系統的初始化過程。表示 DRM driver 已經 ready 等待上層使用,所以在下一章節會簡單介紹上層如何使用 DRM。



2. DRM 應用程式開發

? ? ? ? 這個章節將說明如何開發一個 DRM 應用程式。關於應用程式與 kernel space 之間的交互關係,其實我們在 Chapter 1.3 有提到一點點,我們再把以下這張架構圖拿出來複習一下。這張架構圖說明了,在 user space 的應用程式會透過 libdrm 間接對 kernel space 進行 ioctrl 操作。而一般的 DRM 應用程式需要包含的基本內容有,

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

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

?

  1. drmModeGetResources(...)

? ? ? ? 利用 DRM_IOCTL_MODE_GETRESOURCES,取得 CRTC、Encoder、Connector 等 ID 以及個數。

?

  1. drmModeGetConnector(...)

? ? ? ? 利用上式內容,DRM_IOCTL_MODE_GETCONNECTOR 可取得 Connector 真實的資訊,包含 modes setting。

?

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

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

?

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

? ? ? ? 設定 CRTC 並連接到 dumb framebuffer,開始進行螢幕顯示。

?

? ? ? ? 基於上面的架構,我們在網路上找到一個範例程式,single buffer。這隻範例程式建立一個 dumb framebuffer,內容全部都是 0xFF(也就是白色),並把它顯示到螢幕上。參考範例程式碼連結以及實際上執行的結果如下:

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



0. 前提需要先關掉占用 DRM 的 device



此時,螢幕無輸出變為黑色,


1. 執行測試程式 ./modeset-single-buffer


此時,螢幕輸出 dumb framebuffer 內容,0xFF,為白色,

?

  • 小結

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


3. 參考文件

★博文內容均由個人提供,與平臺無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

參考來源

評論