練與EDID調(diào)試)
DisplayPort 這套協(xié)議里大家平時盯得最多的往往是主鏈路的帶寬——HBR2、HBR3、UHBR 這些名詞一出來討論就熱鬧了。但真正讓一根 DP 線插上就能用、拔了還能重連、顯示器型號自動識別、固件還能在線升級的其實是那條不起眼的邊帶通道AUX Channel。它只有 1Mbps 左右的速率一根線里就一對差分對卻承擔(dān)了鏈路訓(xùn)練、EDID 讀取、DPCD 寄存器訪問、熱插拔事件上報這些關(guān)鍵活兒。可以說主鏈路負責(zé)搬像素AUX Channel 負責(zé)談條件沒有它主鏈路連該用幾個 lane、跑多快都定不下來。這篇內(nèi)容我打算把 AUX Channel 從物理層到協(xié)議層、從寄存器到實際抓包調(diào)試完整地捋一遍。適合正在做 DP 驅(qū)動開發(fā)、顯示器固件、Type-C/DP 轉(zhuǎn)接方案或者單純想搞明白為什么我的顯示器偶爾識別不出來的硬件和嵌入式工程師。文中會涉及 EDID 解析、DPCD 地址空間、鏈路訓(xùn)練流程、以及用 Linux 側(cè)工具提取 EDID 的實操盡量做到看完能上手、能排錯。1. 為什么一條 1Mbps 的邊帶通道能決定整條鏈路的成敗1.1 AUX Channel 到底在 DP 協(xié)議棧里扮演什么角色先把概念擺正。DisplayPort 的物理連接里其實有兩套獨立的通道一套是主鏈路Main Link負責(zé)高速視頻數(shù)據(jù)傳輸速率從 RBR 的 1.62Gbps 一路到 UHBR20 的 20Gbps per lane另一套就是AUX Channel輔助通道是一對雙向、半雙工的差分線速率標稱 1Mbps實際工作在 Manchester 編碼下有效載荷速率大約 720kbps 左右。很多人第一次接觸會以為 AUX 只是讀個 EDID 用的這個理解太窄了。AUX 承擔(dān)的事情至少包括這幾類鏈路訓(xùn)練與維護Source 和 Sink 通過 AUX 讀寫 DPCD 寄存器協(xié)商 lane 數(shù)量、電壓擺幅、預(yù)加重、速率等級訓(xùn)練失敗還要重試。EDID/E-EDID 讀取顯示器能力描述包括支持的分辨率、刷新率、色深、音頻格式等全部通過 AUX 從 Sink 的 EDID 存儲里讀出來。DPCD 寄存器訪問這是 DP 的控制面板鏈路狀態(tài)、錯誤計數(shù)、電源管理、音頻配置、PSR 狀態(tài)都在這里。熱插拔檢測HPD配合HPD 是獨立的一根信號線但事件發(fā)生后具體發(fā)生了什么還是要靠 AUX 去讀狀態(tài)。固件升級與擴展功能比如 NVIDIA 那個 DisplayPort 固件更新工具本質(zhì)上就是通過 AUX 訪問 Sink 或 Source 側(cè)的固件更新寄存器來完成。所以 AUX 更像是 DP 鏈路的控制平面主鏈路是數(shù)據(jù)平面??刂破矫鎾炝藬?shù)據(jù)平面再寬也沒用。1.2 從一次插拔看 AUX 的完整工作鏈路我拿一次典型的顯示器插入過程來串一遍這樣比干講協(xié)議清楚得多。物理插入HPD 拉高顯示器檢測到線纜接入把 HPD 信號拉高Source 側(cè)收到中斷。Source 讀取 DPCD 0x00000-0x0000F這是 Receiver Capability 字段包含 DPCD 版本、最大鏈路速率、最大 lane 數(shù)、是否支持增強幀模式等。這一步全靠 AUX 的 native read。讀取 EDID從 Sink 的 EDID 地址通常映射到 I2C over AUX 的 0x50讀取 128 字節(jié)基礎(chǔ)塊如果支持擴展還要讀 extension block。這里用的是I2C-over-AUX事務(wù)不是 native AUX。鏈路訓(xùn)練Source 寫 DPCD 的 Link Configuration 字段0x00100 起設(shè)置 lane 數(shù)、速率、擺幅然后啟動 TPS1/TPS2/TPS3 訓(xùn)練序列通過 AUX 讀 Lane Status 判斷是否 CR/EQ 完成。進入正常傳輸訓(xùn)練成功后主鏈路開始送視頻流AUX 轉(zhuǎn)入低頻維護監(jiān)控錯誤計數(shù)和 PSR 狀態(tài)。整個流程里只要 AUX 有一次事務(wù)失敗鏈路就可能停在某個中間狀態(tài)表現(xiàn)出來就是黑屏閃屏分辨率不對。1.3 為什么 AUX 的可靠性設(shè)計比速率更重要AUX 速率低是刻意的。它要的是確定性而不是吞吐。協(xié)議里給 AUX 設(shè)計了一套相當嚴謹?shù)氖聞?wù)機制每個事務(wù)有Command地址 讀寫 長度和Data兩個階段。支持Native AUX直接訪問 DPCD和I2C-over-AUX訪問 EDID 等 I2C 設(shè)備兩種模式。有ACK/NACK/Defer三種響應(yīng)Defer 表示 Sink 暫時忙Source 需要重試。有超時和重試計數(shù)通常 Source 側(cè)會重試 3 次以上。提示很多顯示器偶發(fā)識別失敗的問題根因不是主鏈路而是 AUX 事務(wù)在某個環(huán)節(jié)被 Defer 或超時Source 重試次數(shù)不夠就放棄了。調(diào)這類問題一定要抓 AUX 波形或看內(nèi)核日志里的 AUX 事務(wù)記錄。2. DPCD 寄存器空間AUX 真正操作的那張地圖2.1 DPCD 地址空間的整體布局DPCDDisplayPort Configuration Data是一塊標準化的寄存器空間地址從 0x00000 開始通過 AUX native 事務(wù)訪問。它的布局大致是這樣地址范圍名稱作用0x00000-0x0000FReceiver CapabilityDPCD 版本、鏈路速率、lane 數(shù)等能力0x00010-0x000FF保留/擴展能力部分版本用于擴展字段0x00100-0x0010FLink Configurationlane 數(shù)、速率、擺幅、預(yù)加重設(shè)置0x00110-0x0011FLink/Sink StatusCR/EQ 完成狀態(tài)、lane 狀態(tài)0x00200-0x002FF錯誤計數(shù)與狀態(tài)CRC 錯誤、lane 錯誤計數(shù)0x00300-0x003FF音頻相關(guān)音頻配置與狀態(tài)0x00600-0x006FFPSR 相關(guān)面板自刷新狀態(tài)0x00700-0x007FF擴展與固件固件更新、擴展功能這張表是排錯的核心。你遇到任何鏈路問題第一步基本都是讀 DPCD 看狀態(tài)。2.2 Receiver Capability 字段的逐字節(jié)解讀0x00000 開始的 16 個字節(jié)是每次插拔后 Source 必讀的。挑幾個關(guān)鍵字節(jié)說0x00000DPCD 版本號比如 0x14 表示 1.40x13 表示 1.3。0x00001最大鏈路速率。0x06RBR0x0AHBR0x14HBR20x1EHBR3。0x00002最大 lane 數(shù)0x01/0x02/0x04 分別對應(yīng) 1/2/4 lane。0x00003是否支持增強幀模式、是否支持 TPS3 等能力位。0x00004是否支持下行端口、是否支持 MS 訓(xùn)練等。讀這幾個字節(jié)就能判斷這條鏈路理論上能跑多快。比如讀到 0x14 0x04說明 Sink 支持 HBR2 四 lane理論帶寬 21.6Gbps夠跑 4K60 8bit。2.3 Link Configuration 與訓(xùn)練狀態(tài)寄存器0x00100 開始的字段是 Source 寫、Sink 讀的配置區(qū)0x00100lane 數(shù)設(shè)置。0x00101鏈路速率設(shè)置。0x00102-0x00103電壓擺幅和預(yù)加重每個 lane 4 bit。0x00104-0x00105訓(xùn)練模式TPS1/TPS2/TPS3。對應(yīng)的狀態(tài)在 0x00110 起0x00102的鏡像狀態(tài)在0x00202Lane 0-1 狀態(tài)和0x00203Lane 2-3 狀態(tài)。0x00110-0x00111CRClock Recovery和 EQEqualization完成標志每個 lane 2 bit。訓(xùn)練流程就是寫配置 → 讀狀態(tài) → 判斷是否完成 → 不完成就調(diào)整擺幅/預(yù)加重重試。2.4 用 AUX 讀 DPCD 的實際操作示例在 Linux 側(cè)如果驅(qū)動暴露了 debugfs可以直接讀 DPCD。以常見的 i915 驅(qū)動為例# 查看 DP 連接器狀態(tài) cat /sys/kernel/debug/dri/0/DP-1/dpcd # 或者用 drm 工具 modetest -c如果沒有 debugfs 接口可以用 I2C 工具通過 AUX 橋接讀但更通用的做法是寫個小程序調(diào)用drmModeGetConnector拿 EDIDDPCD 則依賴驅(qū)動日志。內(nèi)核日志里搜dp_aux或aux能看到事務(wù)記錄dmesg | grep -i aux dmesg | grep -i dp link注意不同 SoC 和 GPU 廠商的 AUX 控制器實現(xiàn)差異很大有的把 AUX 事務(wù)抽象成 I2C 控制器有的直接暴露 native 接口。排錯前先確認你手上的平臺走的是哪條路徑。3. EDID 與 I2C-over-AUX顯示器自我介紹的完整機制3.1 EDID 為什么必須走 I2C-over-AUXEDID 本質(zhì)上是顯示器里的一顆 I2C EEPROM地址 0x50。DP 協(xié)議沒有為 EDID 單獨設(shè)計 native 事務(wù)而是定義了I2C-over-AUX把 I2C 的讀寫時序封裝進 AUX 事務(wù)里。一個 I2C-over-AUX 事務(wù)的結(jié)構(gòu)是Command 階段地址字段填 I2C 設(shè)備地址0x50 左移一位命令類型標記為 I2C 讀寫。Data 階段傳輸實際數(shù)據(jù)長度受 AUX 事務(wù)最大長度限制通常 16 字節(jié)。讀 128 字節(jié) EDID 需要拆成 8 次 16 字節(jié)事務(wù)或者用 offset 遞增的方式連續(xù)讀。3.2 EDID 基礎(chǔ)塊的字段結(jié)構(gòu)128 字節(jié)的 EDID 基礎(chǔ)塊關(guān)鍵字段分布偏移長度內(nèi)容0x00-0x078頭信息固定 00 FF FF FF FF FF FF 000x08-0x1110廠商 ID、產(chǎn)品代碼、序列號0x12-0x132生產(chǎn)周/年0x14-0x185EDID 版本與修訂0x19-0x2210基本顯示參數(shù)尺寸、gamma、特性0x23-0x3519色度坐標0x36-0x4718已建立時序Established Timings0x48-0x5918標準時序Standard Timings0x5A-0x7D36詳細時序描述符DTD0x7E1擴展塊數(shù)量0x7F1校驗和校驗和算法很簡單前 127 字節(jié)求和取低 8 位加上第 128 字節(jié)應(yīng)該等于 0模 256。3.3 在 Linux 上提取并解析 EDID 的實操最直接的方式是從 sysfs 讀# 找到連接器對應(yīng)的 edid 文件 ls /sys/class/drm/ # 例如 card0-DP-1 cat /sys/class/drm/card0-DP-1/edid edid.bin # 用 edid-decode 解析 edid-decode edid.binedid-decode會輸出廠商、型號、支持的分辨率、色深、音頻能力等。如果 edid.bin 是空的或者全 0說明 AUX 讀 EDID 失敗了問題在 AUX 鏈路或 HPD。也可以用parse-edidread-edid 包sudo apt install read-edid parse-edid edid.bin3.4 EDID 解析中的常見坑擴展塊沒讀全4K 高刷顯示器通常有 CTA-861 擴展塊只讀基礎(chǔ)塊會漏掉 HDR、音頻、高刷時序。要讀 0x7E 指示的擴展塊數(shù)量。校驗和錯誤有些廉價顯示器 EDID 校驗和是錯的Source 側(cè)嚴格校驗就會拒絕表現(xiàn)是識別成默認分辨率。DTD 解析錯誤詳細時序描述符里的像素時鐘、水平/垂直消隱參數(shù)如果算錯會導(dǎo)致模式設(shè)置失敗。AUX Defer 導(dǎo)致讀中斷讀 EDID 過程中 Sink 返回 Defer如果驅(qū)動沒重試EDID 就是殘缺的。提示遇到顯示器型號識別不對或者支持的分辨率列表不全先 dump 原始 EDID 二進制手動核對校驗和和擴展塊比盲目換線有效得多。4. 鏈路訓(xùn)練AUX 事務(wù)最密集、最容易出問題的階段4.1 鏈路訓(xùn)練的三個階段DP 鏈路訓(xùn)練分三步TPS1 - Clock RecoverySource 發(fā)送 TPS1 訓(xùn)練圖案Sink 調(diào)整 CDR 鎖定時鐘通過 AUX 寫 Lane Status 反饋 CR 是否完成。TPS2 - Channel Equalization發(fā)送 TPS2Sink 調(diào)整均衡器反饋 EQ 完成狀態(tài)。TPS3 - 可選部分版本用于進一步優(yōu)化HBR3 及以上常用。每個階段 Source 都要反復(fù)寫配置 → 等一段時間 → 讀狀態(tài)直到所有 lane 都報告完成或者達到重試上限。4.2 訓(xùn)練失敗的典型表現(xiàn)與 AUX 側(cè)線索訓(xùn)練失敗在用戶側(cè)的表現(xiàn)是黑屏、閃屏、降分辨率。在 AUX 側(cè)能看到的是Lane Status 一直不報 CR 完成。錯誤計數(shù)寄存器0x00200 起持續(xù)增長。AUX 事務(wù)本身超時或 NACK。排查順序建議是先確認 AUX 事務(wù)本身是否正常能讀到 DPCD 就說明 AUX 物理層 OK。讀 Receiver Capability確認協(xié)商的速率和 lane 數(shù)沒超過 Sink 能力。讀 Lane Status看是哪幾個 lane 沒完成。調(diào)整擺幅和預(yù)加重重試訓(xùn)練。如果都不行降速率或降 lane 數(shù)看是否能穩(wěn)定。4.3 擺幅與預(yù)加重的調(diào)整邏輯0x00102 和 0x00103 每個 lane 占 4 bit高 2 bit 是電壓擺幅低 2 bit 是預(yù)加重。調(diào)整邏輯是CR 階段失敗優(yōu)先加擺幅。EQ 階段失敗優(yōu)先加預(yù)加重。都失敗降速率。這套邏輯在 DP 規(guī)范里有推薦表格不同速率等級對應(yīng)的擺幅/預(yù)加重組合是有限的不能隨便填。4.4 用日志定位訓(xùn)練卡在哪一步Linux 內(nèi)核里 i915 和 amdgpu 都會打印鏈路訓(xùn)練日志dmesg | grep -iE link training|clock recovery|equalization|CR|EQ典型輸出會顯示每個 lane 的 CR/EQ 狀態(tài)和重試次數(shù)??吹侥硞€ lane 一直 EQ 失敗基本可以判斷是線纜或連接器的問題而不是 Sink 芯片。5. 從固件更新到 PSRAUX 在進階場景里的延伸用法5.1 DisplayPort 固件更新的 AUX 路徑NVIDIA 那個 DisplayPort 固件更新工具做的事情本質(zhì)上是通過 AUX 訪問特定 DPCD 地址把新固件寫入 Sink 或 Source 側(cè)的更新寄存器然后觸發(fā)校驗和重啟。流程大致是讀固件版本寄存器確認當前版本。進入更新模式寫特定 magic 值。分塊寫入固件數(shù)據(jù)。觸發(fā)校驗。重啟鏈路。這類操作對 AUX 事務(wù)的穩(wěn)定性要求極高中途一次失敗就可能導(dǎo)致固件損壞。所以工具通常會先做一輪 AUX 壓力測試。5.2 PSR 與 AUX 的低頻交互PSRPanel Self Refresh是省電特性讓面板在畫面不變時自己刷新Source 側(cè)關(guān)閉主鏈路。PSR 的狀態(tài)切換全靠 AUXSource 寫 DPCD 0x00600 進入 PSR。Sink 在需要更新時通過 HPD 或 AUX 通知 Source 退出 PSR。錯誤計數(shù)和狀態(tài)都在 0x00600 區(qū)間。PSR 出問題的典型表現(xiàn)是畫面卡住不更新或閃一下排查同樣從 AUX 事務(wù)和 DPCD 狀態(tài)入手。5.3 Type-C 場景下 AUX 的復(fù)用與切換在 Type-C 上DP 的 AUX 會復(fù)用到 CC 或 SBU 線上具體走哪對線由 Type-C 的 Alt Mode 協(xié)商決定。這里容易出現(xiàn)的問題是Alt Mode 協(xié)商失敗AUX 根本沒接通。線纜只支持 USB 2.0沒有 SBU 線AUX 走不了。轉(zhuǎn)接芯片的 AUX 方向控制錯誤。排查 Type-C DP 問題時先確認 Alt Mode 進入成功再確認 AUX 物理通路最后才看協(xié)議層。6. 實戰(zhàn)排錯AUX 相關(guān)問題的完整排查鏈路6.1 第一步永遠是確認 AUX 物理層是否通不管問題表現(xiàn)是什么先確認 AUX 能不能讀到 DPCD。讀不到后面全是空談。方法看內(nèi)核日志有沒有 AUX 事務(wù)超時。用示波器抓 AUX 差分對看有沒有 Manchester 編碼的波形。檢查 HPD 是否正常拉高。6.2 區(qū)分是 EDID 問題還是鏈路訓(xùn)練問題能讀到 EDID 但顯示異常問題在鏈路訓(xùn)練讀不到 EDID問題在 AUX 或 HPD。這個二分法能省很多時間。6.3 常見問題與對應(yīng)線索對照表現(xiàn)象可能原因排查線索完全無顯示AUX 不通或 HPD 異常讀不到 DPCD無 AUX 波形識別成默認分辨率EDID 讀取失敗或校驗錯edid.bin 為空或校驗和錯閃屏/黑屏間歇鏈路訓(xùn)練不穩(wěn)定Lane Status 反復(fù)失敗錯誤計數(shù)增長高刷模式不可用帶寬協(xié)商不足Receiver Capability 讀到的速率偏低PSR 下畫面卡住PSR 狀態(tài)機異常DPCD 0x00600 狀態(tài)不對6.4 幾個我踩過的坑線纜質(zhì)量對 AUX 的影響被嚴重低估AUX 雖然慢但對差分阻抗和屏蔽很敏感劣質(zhì)線纜經(jīng)常表現(xiàn)為 EDID 能讀但訓(xùn)練失敗。某些 Sink 的 AUX Defer 處理很激進讀 EDID 時頻繁 Defer驅(qū)動重試次數(shù)不夠就會讀到殘缺 EDID。轉(zhuǎn)接芯片的 AUX 時序一些 DP 轉(zhuǎn) HDMI 芯片在 AUX 事務(wù)上加了額外延遲導(dǎo)致 Source 側(cè)超時需要調(diào)大超時閾值。固件更新后 AUX 行為變化個別顯示器固件更新后會改變 AUX 響應(yīng)時序需要重新驗證鏈路訓(xùn)練。AUX Channel 這條 1Mbps 的邊帶通道看起來是配角實際上握著整條 DP 鏈路的控制權(quán)。把 DPCD 地圖、EDID 解析、鏈路訓(xùn)練流程這三塊吃透再配合日志和波形絕大多數(shù) DP 顯示問題都能定位到具體環(huán)節(jié)。我個人的經(jīng)驗是遇到 DP 問題先別急著換線換顯示器先把 AUX 事務(wù)和 DPCD 狀態(tài)讀出來答案往往就在那幾個寄存器里。