動(dòng)發(fā)布:支持2048寬與2560x1080超寬屏)
顯示器驅(qū)動(dòng)這類東西平時(shí)不太會(huì)被普通用戶注意到但負(fù)責(zé)嵌入式設(shè)備、瘦客戶機(jī)或老式商用主板的人大概率見過 SM750 這個(gè)芯片。它是一顆很常見的 2D 顯示控制芯片經(jīng)常出現(xiàn)在國(guó)產(chǎn)工控主板、云終端、醫(yī)院掛號(hào)機(jī)、銀行排隊(duì)機(jī)這類設(shè)備里。這類設(shè)備的通病是Windows 下驅(qū)動(dòng)好找Linux 下就比較尷尬以前要么靠?jī)?nèi)核里已經(jīng)很邊緣的 framebuffer 路徑要么找第三方閉源包湊合。這次 SM750 的 HDMI DRM 驅(qū)動(dòng)發(fā)布支持 2048 寬輸出和 2560x1080 超寬屏分辨率對(duì)還在維護(hù)這類設(shè)備的人來說是一個(gè)值得跟進(jìn)的改變。這篇文章不打算只復(fù)述發(fā)布信息。我會(huì)把 SM750 的顯示鏈路、DRM 驅(qū)動(dòng)的作用、2560x1080 這類超寬分辨率是怎么被支持的、以及拿到驅(qū)動(dòng)后怎么驗(yàn)證、出問題怎么排查一次講清楚。如果你正在做嵌入式 Linux 開發(fā)、顯示驅(qū)動(dòng)移植或者手頭正好有一臺(tái)帶 SM750 的設(shè)備需要接 2K 級(jí)別顯示器下面這些內(nèi)容可以給你省點(diǎn)時(shí)間。1. SM750 這個(gè)芯片和 DRM 驅(qū)動(dòng)到底解決了誰(shuí)的痛點(diǎn)1.1 先搞清楚 SM750 是哪類芯片SM750 不是 CPU也不是主力顯卡它是一顆負(fù)責(zé)顯示輸出的控制芯片。在很多商業(yè)整機(jī)里主板上的處理器可能很弱板載一顆顯示芯片專門承擔(dān)像素輸出和簡(jiǎn)單的 2D 加速把主 CPU 從顯示任務(wù)里解放出來。SM750 就是這類角色。它的典型特征有三個(gè)2D 能力為主能處理 framebuffer、窗口疊加、基本 2D 加速但 3D 能力很弱。顯存獨(dú)立但不大常見板載版本配的是獨(dú)立顯存容量通常在幾十 MB 這個(gè)量級(jí)不像桌面顯卡那樣有幾個(gè) GB。接口多樣具體板卡上可能是 VGA、DVI、LVDS、HDMI 或其中幾種組合。標(biāo)題里提到的 HDMI 輸出要看板上實(shí)際引出的接口和物理層方案。這類芯片之所以在國(guó)內(nèi)設(shè)備里出現(xiàn)頻率高是因?yàn)樗銐虮阋朔€(wěn)定性也經(jīng)過了相當(dāng)長(zhǎng)時(shí)間的市場(chǎng)驗(yàn)證。對(duì)商用設(shè)備來說顯示不追求炫追求的是穩(wěn)定、低成本、能長(zhǎng)時(shí)間開機(jī)不花屏。1.2 以前 Linux 下驅(qū)動(dòng)為什么讓人頭疼如果只是跑 WindowsSM750 的驅(qū)動(dòng)基本不用操心廠商會(huì)提供安裝包。但 Linux 環(huán)境就復(fù)雜了。老一代的方案是走內(nèi)核的 sm750fb framebuffer 驅(qū)動(dòng)配合 Xorg 里的老模塊使用。這套東西在 2020 年之前的發(fā)行版里還能湊合但這些年 Linux 顯示棧已經(jīng)明顯轉(zhuǎn)向 DRM/KMS 體系。KMS 的意思是 Kernel Mode Setting由內(nèi)核統(tǒng)一管理顯示模式、顯存、連接器狀態(tài)。fbdev 老路徑在新內(nèi)核里越來越邊緣化。這帶來的實(shí)際問題是新內(nèi)核的某些特性兼容不上或者需要額外補(bǔ)丁。桌面環(huán)境、Qt 應(yīng)用、Wayland 合成器對(duì)新驅(qū)動(dòng)的適配越來越依賴 KMS 接口。出問題時(shí)日志不直觀很難判斷到底是芯片沒啟動(dòng)、模式?jīng)]設(shè)對(duì)還是上層合成器沒收到信號(hào)。這次發(fā)布的 SM750 HDMI DRM 驅(qū)動(dòng)本質(zhì)上就是給這顆芯片補(bǔ)上了通往現(xiàn)代 Linux 顯示棧的接口。1.3 誰(shuí)最需要關(guān)注這個(gè)發(fā)布我認(rèn)為主力受益者有三類維護(hù)存量設(shè)備的人手里有大量 SM750 工控板在跑 Linux需要在新內(nèi)核上繼續(xù)穩(wěn)定輸出。做嵌入式 Linux 產(chǎn)品的人正在選型顯示方案希望芯片能被內(nèi)核主線 DRM 框架接管而不是依賴廠商私有補(bǔ)丁。學(xué)習(xí) Linux 驅(qū)動(dòng)開發(fā)的人SM750 的驅(qū)動(dòng)結(jié)構(gòu)不算臃腫作為 KMS 驅(qū)動(dòng)學(xué)習(xí)樣本很合適能看清 connector、encoder、crtc 之間的關(guān)系。如果你只是臺(tái)式機(jī)用戶手頭也沒有 SM750 設(shè)備那這篇內(nèi)容可以當(dāng)作顯示棧知識(shí)看不需要真的去刷驅(qū)動(dòng)。2. 2048 寬輸出和 2560x1080 超寬屏背后靠的是顯示時(shí)序能力2.1 分辨率的本質(zhì)不是“加一行設(shè)置”很多人以為支持某個(gè)分辨率就是把分辨率數(shù)值寫進(jìn)某個(gè)列表然后重啟。實(shí)際上顯示分辨率背后是一整套時(shí)序參數(shù)通常用一個(gè)叫 modeline 的東西表示。它包含有效圖像的寬度和高度比如 2560x1080。像素時(shí)鐘頻率也就是每秒要輸出多少個(gè)像素點(diǎn)。水平前肩、水平同步、水平后肩。垂直前肩、垂直同步、垂直后肩。刷新率。顯示器不會(huì)自己產(chǎn)生一張完整的畫面它會(huì)按固定的節(jié)奏刷新。顯卡或顯示控制芯片負(fù)責(zé)在正確的時(shí)刻把像素?cái)?shù)據(jù)送到接口上。這個(gè)節(jié)奏如果和顯示器對(duì)不上要么黑屏要么畫面閃爍撕裂要么直接無(wú)法點(diǎn)亮。所以DRM 驅(qū)動(dòng)支持 2560x1080不只是把分辨率數(shù)值暴露出來而是要保證芯片的顯示控制器能夠生成符合這個(gè)分辨率的時(shí)序并且把足夠大的 framebuffer 分配好。2.2 2048 寬這條線有什么講究這次發(fā)布里提到“2048 寬輸出”這個(gè)數(shù)字很關(guān)鍵。很多老一代顯示控制芯片有一個(gè)隱形的寬度邊界超過一定寬度之后內(nèi)部 FIFO 帶寬、行緩沖對(duì)齊、內(nèi)存訪問策略就會(huì)出問題。2048 這個(gè)數(shù)值在顯示領(lǐng)域經(jīng)常作為一個(gè)分界點(diǎn)出現(xiàn)因?yàn)樗?2 的冪對(duì)齊友好。支持 2048 寬輸出意味著顯示控制器在寬度大于 1920 的范圍內(nèi)能穩(wěn)定分配行緩存。超過 2048 的桌面尺寸不再必須走裁剪或縮放路徑。驅(qū)動(dòng)會(huì)為寬屏模式準(zhǔn)備合適的 framebuffer 對(duì)齊策略。這不是一個(gè)單純“把上限調(diào)大”的操作它涉及內(nèi)存帶寬的驗(yàn)證和模式表的擴(kuò)展。2.3 2560x1080 是超寬屏里的特殊檔位2560x1080 是 21:9 超寬屏像素量大約是 1920x1080 的 1.33 倍。它在帶寬需求上已經(jīng)接近 2K 級(jí)別對(duì)顯示控制芯片的像素時(shí)鐘要求比 1080p 高出一截。如果芯片的 PLL 或時(shí)鐘源不能輸出足夠高的像素時(shí)鐘單靠軟件改 modeline 是點(diǎn)不亮的。所以這次驅(qū)動(dòng)能支持 2560x1080背后至少意味著三件事驅(qū)動(dòng)里的模式生成邏輯已經(jīng)能構(gòu)造出 2560x1080 的時(shí)序參數(shù)。芯片的時(shí)鐘能力足夠覆蓋這個(gè)分辨率所需的像素時(shí)鐘。framebuffer 的尺寸計(jì)算、行偏移和內(nèi)存對(duì)齊邏輯已經(jīng)能處理 2560 寬度的場(chǎng)景。不過要注意一點(diǎn)驅(qū)動(dòng)支持這個(gè)模式不代表任何一塊 SM750 板子都能穩(wěn)定輸出。具體能不能點(diǎn)亮還取決于板載輸出接口、轉(zhuǎn)接芯片、線材和顯示器本身。尤其是 HDMI 接口如果板卡是從 DVI 物理層轉(zhuǎn)接出來的那么信號(hào)在帶寬和 EDID 傳達(dá)上會(huì)有限制。這個(gè)坑后面單獨(dú)說。2.4 模式列表從哪來EDID 和內(nèi)置模式表DRM 驅(qū)動(dòng)獲取可用分辨率的方式主要有兩種從顯示器讀取 EDID顯示器通過 DDC 通道把支持的模式列表發(fā)給驅(qū)動(dòng)這是最常見的路徑。驅(qū)動(dòng)內(nèi)置模式表當(dāng) EDID 缺失、損壞或顯示器不帶 EDID 時(shí)驅(qū)動(dòng)根據(jù)硬件能力提供一個(gè)固定模式列表。這次發(fā)布里強(qiáng)調(diào)支持 2560x1080更多是指驅(qū)動(dòng)層面具備生成這個(gè)模式的能力。實(shí)際插上顯示器后是否自動(dòng)出現(xiàn)在模式列表里要看你插的顯示器 EDID 是否完整地支持這個(gè)分辨率。如果顯示器 EDID 正常通常不需要手動(dòng)干預(yù)。如果 EDID 缺失你就得靠驅(qū)動(dòng)內(nèi)置模式表或者手動(dòng)添加 modeline。這個(gè)操作后面會(huì)提到。3. 從 DRM 內(nèi)核到 Qt 應(yīng)用顯示鏈路里的每一次中轉(zhuǎn)3.1 完整鏈路是什么在 Linux 桌面環(huán)境下一個(gè) Qt 窗口最終顯示在屏幕上要經(jīng)過很多層。SM750 的 DRM 驅(qū)動(dòng)處于最底層但如果你要調(diào)試為什么畫面不對(duì)光看驅(qū)動(dòng)不夠。完整的鏈路是這樣的屏幕硬件 ← DRM 內(nèi)核驅(qū)動(dòng) ← X server(Xorg) ← X11 協(xié)議 ← Qt(xcb 插件) ← 你的 Qt 程序如果用的是 Wayland鏈路則是屏幕硬件 ← DRM 內(nèi)核驅(qū)動(dòng) ← Weston/Sway 等合成器 ← Wayland 協(xié)議 ← Qt(wayland 插件) ← 你的 Qt 程序每一層都在上一層的輸出上做處理。DRM 驅(qū)動(dòng)負(fù)責(zé)把最底層的模式設(shè)置好Xorg 選一個(gè)分辨率、組織 framebufferX11 協(xié)議負(fù)責(zé)窗口、繪制和事件分發(fā)Qt 通過 xcb 插件和 X server 通信。只要顯示模式不匹配任何一層都可能出現(xiàn)問題。3.2 DRM/KMS 到底在鏈路里扮演什么角色DRM 驅(qū)動(dòng)在 Linux 顯示體系里是內(nèi)核和用戶的邊界。它提供幾個(gè)核心對(duì)象CRTC掃描輸出控制器決定從 framebuffer 里怎么讀出數(shù)據(jù)并產(chǎn)生時(shí)序信號(hào)。Encoder把像素信號(hào)編碼成特定接口協(xié)議比如 HDMI、DVI、LVDS。Connector物理連接器檢測(cè)是否有顯示器接入維護(hù) EDID 和當(dāng)前模式狀態(tài)。Plane顯示平面負(fù)責(zé)把 framebuffer 內(nèi)容合成到輸出上。KMS 的價(jià)值在于上面這些對(duì)象全部由內(nèi)核統(tǒng)一管理。用戶空間的 Xorg、Wayland 合成器不用直接去操作寄存器而是通過 DRM 提供的接口來設(shè)置 mode、提交 framebuffer。這帶來的好處是只要 SM750 驅(qū)動(dòng)把 KMS 接口實(shí)現(xiàn)好上層的 Xorg、Qt、GTK 都無(wú)需專門適配這顆芯片。這也是為什么現(xiàn)在很多人強(qiáng)調(diào) KMS而不是繼續(xù)維護(hù)老 fbdev。3.3 用戶空間怎么操作 DRM 設(shè)備驅(qū)動(dòng)加載成功后系統(tǒng)會(huì)產(chǎn)生 /dev/dri/card0 之類的設(shè)備節(jié)點(diǎn)。用戶空間的工具和庫(kù)通過這個(gè)節(jié)點(diǎn)訪問顯示能力libdrm 是底層庫(kù)提供 ioctl 封裝。modetest 可以查看連接器狀態(tài)、模式列表和 framebuffer 信息。xrandr 是 Xorg 環(huán)境下的分辨率管理工具。weston 或 sway 這類合成器直接走 DRM/KMS。這意味著即使你沒有圖形界面也可以先用命令行工具驗(yàn)證 SM750 驅(qū)動(dòng)是否正常工作。圖形界面出問題時(shí)先用 modetest 排除內(nèi)核驅(qū)動(dòng)下面的問題再往上檢查 Xorg 或合成器效率要高得多。3.4 為什么鏈路長(zhǎng)出問題時(shí)要分層看待很多人在顯示出問題時(shí)第一反應(yīng)是“驅(qū)動(dòng)壞了”。但實(shí)際上顯示鏈路每一層都有可能出現(xiàn)兼容性問題驅(qū)動(dòng)層模式設(shè)置失敗、連接器檢測(cè)不到、顯存分配失敗。Xorg 層配置錯(cuò)誤、驅(qū)動(dòng)加載順序不對(duì)、分辨率列表沒刷新。應(yīng)用層Qt 的 xcb 插件沒有拿到正確的屏幕縮放窗口畫不出來。所以排查時(shí)要先確認(rèn) DRM 層正常再用 xrandr 確認(rèn) Xorg 層最后再去看 Qt 或者具體應(yīng)用。不要一上來就懷疑驅(qū)動(dòng)也不要一黑屏就去改源碼。4. 拿到驅(qū)動(dòng)后怎么驗(yàn)證 2560x1080 能不能開出來4.1 建議先做一輪最小驗(yàn)證如果你手里有一套帶 SM750 的設(shè)備想驗(yàn)證這次發(fā)布的能力我建議不要直接接上超寬屏就開搞。先把環(huán)境固定下來做一輪最小驗(yàn)證。需要準(zhǔn)備的東西帶 SM750 的主板或整機(jī)。一根可靠的 HDMI 或 DVI 線根據(jù)板卡的實(shí)際接口來。一臺(tái)支持 2560x1080 的顯示器最好確認(rèn)顯示器本身的 EDID 信息是完整的。Linux 系統(tǒng)內(nèi)核版本要足夠新才能包含或加載這個(gè) DRM 驅(qū)動(dòng)。modetest、dmesg 這些基本維護(hù)工具。如果內(nèi)核里還沒有集成這個(gè)驅(qū)動(dòng)需要先按模組或補(bǔ)丁方式把它裝進(jìn)去。加載方式取決于驅(qū)動(dòng)是編譯進(jìn)內(nèi)核還是作為外部模塊不同環(huán)境不一樣。建議先看驅(qū)動(dòng)發(fā)布說明里給的加載路徑。4.2 第一步確認(rèn)驅(qū)動(dòng)是否加載成功開機(jī)之后先看內(nèi)核日志里有沒有對(duì)應(yīng)的驅(qū)動(dòng)信息dmesg | grep -i sm750如果驅(qū)動(dòng)正常加載應(yīng)該能看到設(shè)備識(shí)別、連接器掃描或者模式列表初始化的日志。如果沒有輸出先確認(rèn)驅(qū)動(dòng)模塊是否被加載lsmod | grep sm750再檢查設(shè)備節(jié)點(diǎn)是否創(chuàng)建ls -l /dev/dri/正常情況下會(huì)有 card0 或者 card1。如果設(shè)備節(jié)點(diǎn)不存在多半是驅(qū)動(dòng)沒有編譯進(jìn)去或者設(shè)備樹、PCI 枚舉階段沒有識(shí)別到硬件。4.3 第二步用 modetest 查看模式列表modetest 是 DRM 調(diào)試中最直接的工具。先列出所有設(shè)備modetest -M sm750或者先不管驅(qū)動(dòng)名直接掃描modetest -p重點(diǎn)看連接器部分的輸出。正常情況下會(huì)列出連接器狀態(tài)、物理接口類型和所有可用模式。如果連接器狀態(tài)是 connected并且模式列表里有 2560x1080 或 2560x108060Hz說明驅(qū)動(dòng)已經(jīng)把這個(gè)模式暴露出來了。如果連接器狀態(tài)是 disconnected先檢查線材、接口和顯示器電源。4.4 第三步在 Xorg 下切換分辨率如果你的系統(tǒng)跑的是 Xorg可以先用 xrandr 確認(rèn)當(dāng)前輸出xrandr輸出里會(huì)列出顯示器名稱和可用分辨率列表。如果 2560x1080 在列表里直接切換xrandr --output HDMI-1 --mode 2560x1080注意輸出名稱不一定是 HDMI-1要以 xrandr 實(shí)際顯示為準(zhǔn)。切換之后觀察畫面是否正常鋪滿有沒有黑邊、花屏或閃爍。如果 xrandr 列表里沒有 2560x1080但顯示器確實(shí)支持可能是 EDID 沒有把這個(gè)模式傳回來??梢試L試手動(dòng)添加 modeline。具體做法是先用 cvt 生成時(shí)序參數(shù)再用 xrandr --newmode 和 --addmode 注入比如cvt 2560 1080 60 xrandr --newmode 2560x1080_60.00 實(shí)際時(shí)序參數(shù) xrandr --addmode HDMI-1 2560x1080_60.00 xrandr --output HDMI-1 --mode 2560x1080_60.00這種方式在驅(qū)動(dòng)層已經(jīng)支持、只是 EDID 未上報(bào)時(shí)比較有用。如果驅(qū)動(dòng)層本身沒有這個(gè)模式能力手動(dòng)注入也不一定能點(diǎn)亮。4.5 第四步用 Qt 或通用圖形程序驗(yàn)證分辨率切換成功后還需要確認(rèn)上層應(yīng)用能正常適配。Qt 程序在 X11 下走 xcb 插件它會(huì)讀取 X server 提供的屏幕尺寸。如果 Xorg 已經(jīng)在 2560x1080 下工作Qt 應(yīng)用一般會(huì)自動(dòng)填滿屏幕。你可以在普通程序里放一個(gè)全屏窗口或者在終端里查看顯示服務(wù)器報(bào)告的屏幕尺寸xdpyinfo | grep dimensions如果 dimensions 顯示的是 2560x1080說明鏈路已經(jīng)通到 X11 層。Qt 程序的窗口布局、鼠標(biāo)坐標(biāo)、縮放比例都以這個(gè)尺寸為準(zhǔn)。如果里面某個(gè) Qt 應(yīng)用在超寬屏下布局錯(cuò)亂不要先怪 SM750 驅(qū)動(dòng)。先確認(rèn) X11 層尺寸是否正確再用 QT_SCALE_FACTOR 或 Qt 的屏幕縮放機(jī)制去調(diào)應(yīng)用。問題大概率出在應(yīng)用對(duì)寬屏適配而不是顯示驅(qū)動(dòng)。4.6 驗(yàn)證結(jié)果怎么判斷可以按下面的表來判斷每一層是否正常驗(yàn)證層命令或位置正常結(jié)果異常表現(xiàn)驅(qū)動(dòng)加載dmesg能看到 SM750 設(shè)備識(shí)別無(wú)日志設(shè)備節(jié)點(diǎn)缺失DRM 設(shè)備/dev/dri/card0存在且可讀設(shè)備不存在連接器狀態(tài)modetest -pconnected有模式列表disconnected模式列表為空模式設(shè)置xrandr2560x1080 可用并可切換模式缺失切換后黑屏X11 尺寸xdpyinfodimensions 為 2560x1080尺寸仍為舊分辨率Qt 應(yīng)用窗口顯示全屏鋪滿文字不糊布局錯(cuò)亂窗口越界這一套走完基本能確定 SM750 DRM 驅(qū)動(dòng)在你手頭這塊板子上是否正常工作。5. 黑屏、分辨率缺失、輸出空白按這個(gè)順序排查5.1 容易誤判的幾個(gè)點(diǎn)SM750 這類嵌入式顯示芯片的調(diào)試同樣一個(gè)黑屏現(xiàn)象原因可能差得很遠(yuǎn)。我建議不要上來就改驅(qū)動(dòng)源碼先按下面的順序過一遍很多時(shí)候問題根本不在驅(qū)動(dòng)本身。常見的誤判有這些“驅(qū)動(dòng)沒加載”實(shí)際上是內(nèi)核沒有把硬件枚舉出來?!膀?qū)動(dòng)不支持 2K”實(shí)際上是 EDID 沒讀到顯示器模式?jīng)]上報(bào)?!癏DMI 壞了”實(shí)際上線材或轉(zhuǎn)接頭的 DDC 通道有問題導(dǎo)致 EDID 傳輸失敗。“Qt 顯示不了”實(shí)際上是 Xorg 層的分辨率沒有切換成功。排查的第一步永遠(yuǎn)是把現(xiàn)象寫清楚是完全沒有信號(hào)還是畫面閃、花屏還是只有部分分辨率不可用。5.2 排查順序先物理再 EDID再內(nèi)核再上層我從實(shí)際經(jīng)驗(yàn)里總結(jié)的排查鏈路是這樣的物理接口確認(rèn)板卡輸出接口和顯示器輸入接口一致。SM750 板卡如果是 DVI 轉(zhuǎn) HDMI 座要理解它的信號(hào)本質(zhì)是 DVI帶寬上限和 EDID 特點(diǎn)會(huì)和原生 HDMI 不同。線材和供電換一根短一點(diǎn)的線排除線材損耗。HDMI 線的質(zhì)量對(duì)高分辨率影響很明顯尤其是 2560x1080 這種接近 2K 帶寬的場(chǎng)景。EDID用 modetest 看連接器是否 connected看模式列表里有沒有 2560x1080。如果沒有多半是 EDID 沒讀到或顯示器的 EDID 不完整。內(nèi)核日志dmesg 里看有沒有和 SM750、DRM、HDMI 相關(guān)的錯(cuò)誤。驅(qū)動(dòng)參數(shù)有些板卡需要額外指定輸出類型或初始化方式看發(fā)布說明里有沒有相關(guān)參數(shù)。上層顯示服務(wù)器確認(rèn) X org 或合成器有沒有接住驅(qū)動(dòng)提供的模式xrandr 能不能切到目標(biāo)分辨率。應(yīng)用層適配最后才考慮 Qt、GTK 或者其他應(yīng)用對(duì)超寬屏的適配問題。下面是常見問題和排查方向現(xiàn)象優(yōu)先排查方向次要排查方向完全無(wú)信號(hào)線材、接口、顯示器輸入源驅(qū)動(dòng)是否加載連接器狀態(tài)連接器 disconnectedEDID 通道、線材、物理接口驅(qū)動(dòng)對(duì)連接器檢測(cè)是否正常模式列表為空EDID 缺失顯示器是否上電驅(qū)動(dòng)內(nèi)置模式表是否啟用有模式但切換黑屏像素時(shí)鐘是否足夠時(shí)序是否匹配線材帶寬刷新率是否過高切換后不斷閃爍線材質(zhì)量、刷新率、HDMI 時(shí)鐘穩(wěn)定性顯示器內(nèi)部縮放是否觸發(fā)分辨率超過 2048 后花屏行緩存、framebuffer 對(duì)齊驅(qū)動(dòng)是否有寬度限制遺漏重啟后分辨率丟失Xorg 配置沒有保存顯示器 EDID 在上電時(shí)序上不穩(wěn)定5.3 關(guān)于“EDID 沒讀到”這件事EDID 是顯示器和驅(qū)動(dòng)之間溝通的“身份信息”它是一段 128 字節(jié)或更長(zhǎng)的數(shù)據(jù)存放在顯示器內(nèi)部的存儲(chǔ)芯片里通過 DDC 通道傳輸。DDC 通道依賴物理引腳的連通性HDMI 線里如果有一根針接觸不良、轉(zhuǎn)接頭質(zhì)量問題都可能導(dǎo)致驅(qū)動(dòng)讀不到 EDID進(jìn)而拿不到 2560x1080 模式。讀不到 EDID 時(shí)modetest 里連接器狀態(tài)通常會(huì)變成 disconnected或者模式列表為空。這時(shí)可以先強(qiáng)制指定一個(gè) EDID 或 modeline 來驗(yàn)證硬件本身能不能輸出。不過要注意強(qiáng)制的 modeline 如果和顯示器內(nèi)部時(shí)序不能對(duì)上畫面可能依然無(wú)信號(hào)。更穩(wěn)妥的做法是換線。換顯示器。檢查轉(zhuǎn)接頭是否支持高帶寬。如果這些都不行再考慮驅(qū)動(dòng)層面強(qiáng)制注入模式。不要一開始就懷疑 SM750 驅(qū)動(dòng)對(duì)超寬屏支持有問題。5.4 關(guān)于轉(zhuǎn)接和物理層差異的提醒SM750 這顆芯片歷史悠久不同板卡對(duì) HDMI 的實(shí)現(xiàn)方式不一樣。有的板子引出的是原生 HDMI 信號(hào)有的則是 DVI 信號(hào)通過轉(zhuǎn)接芯片變成 HDMI 座。兩種方案對(duì)調(diào)試的影響不太一樣原生 HDMI 支持音頻和完整 EDID 通道更接近普通顯示器場(chǎng)景。DVI 轉(zhuǎn) HDMI 通常不支持 HDMI 音頻EDID 也可能只暴露 DVI 模式這時(shí) 2560x1080 這種依賴高帶寬的模式可能不會(huì)自動(dòng)出現(xiàn)。判斷方法很簡(jiǎn)單看板卡資料里 HDMI 是否支持音頻傳輸。如果資料沒寫清楚可以用 edid-decode 工具讀取 EDID 內(nèi)容看里面的接口類型標(biāo)識(shí)。注意如果板卡是 DVI 物理層遇到 2560x1080 點(diǎn)不亮不要急著罵驅(qū)動(dòng)。先確認(rèn)物理層方案是否支持這個(gè)帶寬。另外熱詞里提到的“edp 轉(zhuǎn) hdmi out 時(shí) panel 時(shí)序、lane 和速率等參數(shù)要求”對(duì) SM750 場(chǎng)景也有參考意義。顯示接口轉(zhuǎn)換時(shí)最終輸出的時(shí)序要以目標(biāo)接口的帶寬和時(shí)鐘為準(zhǔn)不是輸入源多少分辨率輸出就一定能按多少分辨率跑。中間多一個(gè)轉(zhuǎn)接芯片就多一個(gè)帶寬瓶頸和時(shí)序校準(zhǔn)環(huán)節(jié)。5.5 什么時(shí)候才需要去動(dòng)驅(qū)動(dòng)或設(shè)備樹如果你已經(jīng)確認(rèn)物理接口、線材、顯示器都沒問題EDID 也能正常讀取但模式列表里就是沒有 2560x1080這時(shí)才考慮驅(qū)動(dòng)或設(shè)備樹層面的處理。驅(qū)動(dòng)層面常見做法是在驅(qū)動(dòng)內(nèi)置 mode table 中追加上目標(biāo) modeline。檢查 framebuffer 最大寬度限制必要時(shí)修改寬度判斷邏輯。確保像素時(shí)鐘計(jì)算支持目標(biāo)頻率。設(shè)備樹層面常見做法是檢查輸出接口類型是否與硬件對(duì)應(yīng)。確認(rèn)連接器默認(rèn)狀態(tài)避免熱插拔檢測(cè)異常。如果板卡有多個(gè)顯示輸出確認(rèn)路由是否正確。這些操作需要對(duì) DRM 框架和具體板卡硬件都比較熟悉新手建議先拿 modetest 和 xrandr 把問題定位到具體層次再?zèng)Q定要不要改內(nèi)核層。不要一上來就找驅(qū)動(dòng)源碼改那樣容易把簡(jiǎn)單問題復(fù)雜化。6. 開源驅(qū)動(dòng)不只是一份源碼更是一條可以長(zhǎng)期維護(hù)的路徑6.1 閉源驅(qū)動(dòng)的老問題還在在 SM750 這類芯片上廠商通常會(huì)提供 Windows 驅(qū)動(dòng)Linux 支持則不一定完整。有些廠商會(huì)提供預(yù)編譯的二進(jìn)制模塊但二進(jìn)制模塊有幾個(gè)長(zhǎng)期痛點(diǎn)內(nèi)核版本升級(jí)后模塊可能加載失敗或需要重新編譯適配。出現(xiàn)問題時(shí)沒有源碼可查只能靠日志猜。用戶空間和內(nèi)核接口變化時(shí)廠商更新速度不一定跟得上。無(wú)法深度定制比如加一個(gè)自定義分辨率、改某種時(shí)序輸出。對(duì)消費(fèi)級(jí)用戶來說閉源驅(qū)動(dòng)勉強(qiáng)夠用。但對(duì)嵌入式產(chǎn)品和個(gè)人開發(fā)者來說閉源驅(qū)動(dòng)意味著一種不可控你依賴廠商的更新節(jié)奏依賴它愿意支持的內(nèi)核版本依賴它在安全補(bǔ)丁上的態(tài)度。6.2 開源 DRM 驅(qū)動(dòng)帶來的改變這次 SM750 的 DRM 驅(qū)動(dòng)以開源方式發(fā)布最大價(jià)值不是“免費(fèi)”而是把顯示控制能力納入到 Linux 內(nèi)核的公開框架里。具體能帶來這些實(shí)際好處可讀源碼出現(xiàn)問題時(shí)可以打開源碼看寄存器操作、模式設(shè)置和連接器檢測(cè)邏輯??杉尤罩究梢杂?printk、dev_dbg 等手段在關(guān)鍵路徑上打印信息幫助定位??筛膮?shù)如果你想增加分辨率、調(diào)整時(shí)序、適配特殊面板可以在源碼層面修改并重新編譯。可跟主線如果驅(qū)動(dòng)進(jìn)入內(nèi)核主線后續(xù)內(nèi)核升級(jí)會(huì)有更持續(xù)的維護(hù)??蓞⒖紝W(xué)習(xí)DRM 驅(qū)動(dòng)開發(fā)門檻不低一套簡(jiǎn)潔的 2D 驅(qū)動(dòng)實(shí)現(xiàn)可以讓學(xué)習(xí)者更快理解 KMS 對(duì)象關(guān)系。6.3 開源不代表零維護(hù)這里要說一句不那么樂觀的話開源驅(qū)動(dòng)發(fā)布不等于裝上之后就一勞永逸。DRM 內(nèi)核 API 也會(huì)演進(jìn)驅(qū)動(dòng)需要跟著調(diào)整。如果你的產(chǎn)品要長(zhǎng)期維護(hù)不能只下載一次源碼就丟在那里要關(guān)注內(nèi)核版本變化對(duì)驅(qū)動(dòng)的影響。另外開源驅(qū)動(dòng)只是把能力開放出來具體到某個(gè)板卡上的初始化時(shí)序、供電要求、接口物理層可能還需要板卡廠商提供補(bǔ)充信息。開源解決了“有路可走”的問題但不等于每個(gè)硬件細(xì)節(jié)都自動(dòng)對(duì)齊。所以我的建議是把驅(qū)動(dòng)源碼納入到你的鏡像構(gòu)建體系里方便重復(fù)構(gòu)建和保存補(bǔ)丁。記錄板卡型號(hào)、內(nèi)核版本、顯示接口、面板參數(shù)。每次換內(nèi)核大版本時(shí)先跑一輪單分辨率和多分辨率切換驗(yàn)證。對(duì)于從產(chǎn)品選型角度考慮的人開源驅(qū)動(dòng)還意味著供應(yīng)鏈上的選擇更自由。你不一定非要用某家廠商封裝的私有顯示方案可以按 DRM 框架選擇適合自己的顯示控制芯片。6.4 對(duì) Linux 驅(qū)動(dòng)學(xué)習(xí)者的意義如果你正在學(xué) DRM 驅(qū)動(dòng)開發(fā)SM750 的驅(qū)動(dòng)是一個(gè)不錯(cuò)的入門觀察對(duì)象。它不像那些復(fù)雜的 GPU 驅(qū)動(dòng)那樣有海量調(diào)度、顯存管理、固件加載邏輯但它把 KMS 的骨架體現(xiàn)得比較清楚。你可以重點(diǎn)看這些部分驅(qū)動(dòng)如何注冊(cè) DRM 設(shè)備。連接器的檢測(cè)函數(shù)怎么寫。CRTC 的 mode_set 如何處理分辨率變化。像素時(shí)鐘和 mode 參數(shù)的計(jì)算路徑??炊@些小而完整的實(shí)現(xiàn)再回頭去讀更復(fù)雜的驅(qū)動(dòng)比如各種 SoC 內(nèi)置顯示控制器或獨(dú)立顯卡驅(qū)動(dòng)會(huì)輕松不少。7. 什么情況下用得上什么情況下別指望太多7.1 很適合用的場(chǎng)景你可以在這些場(chǎng)景里放心考慮 SM750 DRM 驅(qū)動(dòng)的支持Linux 桌面的商業(yè)終端云終端、前臺(tái)展示機(jī)、信息查詢機(jī)。這些設(shè)備不追求 3D 性能只要穩(wěn)定輸出文字和視頻即可。嵌入式 Linux 產(chǎn)品需要長(zhǎng)期固定顯示界面希望顯示輸出由內(nèi)核統(tǒng)一管理。超寬屏商務(wù)展示需要輸出 21:9 內(nèi)容的設(shè)備比如接待臺(tái)、大屏信息終端。驅(qū)動(dòng)學(xué)習(xí)和科研環(huán)境想研究 DRM/KMS 的人手頭正好有 SM750 板卡。7.2 不太適合指望的場(chǎng)景以下場(chǎng)景就不要對(duì) SM750 抱太多期望3D 游戲SM750 的 2D 定位決定了它不是為 OpenGL 游戲性能設(shè)計(jì)的。4K 高刷這次發(fā)布支持到 2048 寬和 2560x1080它并不等于支持所有 4K 高刷模式。芯片內(nèi)部帶寬和顯存規(guī)格本來就不是為 4K 高刷準(zhǔn)備的。多屏復(fù)雜組合如果產(chǎn)品需要多路 4K 輸出應(yīng)該選更現(xiàn)代的顯示控制方案。完全不懂 Linux 的命令行環(huán)境DRM 驅(qū)動(dòng)只解決 Linux 顯示鏈路底層能力系統(tǒng)集成和調(diào)試仍然需要基本的 Linux 操作知識(shí)。7.3 我的實(shí)際建議不管你是設(shè)備維護(hù)者還是產(chǎn)品開發(fā)人員這個(gè)發(fā)布都值得關(guān)注但不值得立刻把現(xiàn)有穩(wěn)定方案推翻。更穩(wěn)妥的做法是先拿一塊閑置板卡搭一個(gè)最小驗(yàn)證環(huán)境確認(rèn)驅(qū)動(dòng)在你要用的內(nèi)核版本上能編譯、加載、輸出。單獨(dú)接一臺(tái) 2560x1080 顯示器把模式列表、xrandr 切換、Qt 全屏顯示這三個(gè)環(huán)節(jié)驗(yàn)證通過。之后再考慮是否把驅(qū)動(dòng)納入生產(chǎn)鏡像。如果只是學(xué)習(xí)默認(rèn)配置和文檔足夠入門。如果要投入生產(chǎn)就要把驅(qū)動(dòng)版本、內(nèi)核版本、發(fā)行版構(gòu)建方式、輸出接口物理方案全都記錄歸檔。這樣后續(xù)內(nèi)核升級(jí)或硬件批次變化時(shí)你有一個(gè)可以快速定位問題的基線。踩過幾次顯示棧的坑之后我最大的感受是很多黑屏和分辨率問題不是驅(qū)動(dòng)能力不夠而是前置環(huán)境和輸入材料沒有處理干凈。先確認(rèn)物理輸出鏈路再確認(rèn) EDID然后看內(nèi)核日志最后才有必要去動(dòng)源碼。這套順序在 SM750 上適用在其它 DRM 驅(qū)動(dòng)上同樣適用。