尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

高通Adreno DPU显示链路全解析:从DRM/KMS到MIPI DSI实战

发布时间:2026/9/28 22:23:55

资讯中心
01
ARTICLE

高通Adreno DPU显示链路全解析:从DRM/KMS到MIPI DSI实战

高通Adreno DPU显示链路全解析:从DRM/KMS到MIPI DSI实战
1. 显示链路全景拆解从应用层到屏幕像素的完整路径高通Adreno DPUDisplay Processing Unit这套显示架构我第一次接触是在调试一块MIPI DSI屏幕的时候。当时屏幕能亮但画面撕裂、竖屏横显、色彩偏移各种问题轮番出现逼着我从应用层一路往下挖到寄存器级别才算把整条链路摸清楚。这篇文章就把我踩过的坑和梳理出来的完整链路分享出来适合做嵌入式显示驱动、Android底层开发、以及需要对接MIPI DSI屏幕的硬件工程师参考。先给不太熟悉的朋友一个整体认知DPU不是GPU。GPU负责渲染把画面画出来DPU负责把画好的画面搬运、合成、缩放、旋转最终通过MIPI DSI这类接口送到屏幕的像素点上。你可以把GPU理解成画师DPU理解成装裱工加快递员画师画完的画装裱工负责裁剪、拼接、调色快递员负责按屏幕能听懂的“语言”送过去。整条链路大致是这样的应用层通过SurfaceFlinger提交图层经过HWCHardware Composer决策哪些图层走GPU合成、哪些走DPU硬件合成然后通过DRM/KMS框架下发到内核态的MSM DRM驱动驱动配置DPU的各个硬件模块LM、DSPP、DSC、INTF等最后通过MIPI DSI控制器把像素数据串行化发送到屏幕。每一层都有它的脾气任何一层配置错了屏幕上的表现就是花屏、黑屏、撕裂或者颜色不对。为什么值得花时间搞懂这条链路因为现在越来越多的设备用MIPI DSI屏幕从手机、平板到车载中控、工业HMI而高通的DPU架构在Android设备里占有率极高。你如果只会调应用层遇到底层显示问题就只能干瞪眼。反过来如果你能把DRM/KMS到MIPI DSI这条链路吃透很多问题定位起来就是几分钟的事。2. DRM/KMS框架在高通平台上的落地方式2.1 为什么是DRM/KMS而不是老式Framebuffer早期嵌入式显示用的是Framebuffer框架简单粗暴一个fb设备对应一块显存应用直接往里面写像素。但它有个致命问题不支持多图层硬件合成不支持原子提交不支持动态分辨率切换。你想想现在的手机屏幕状态栏、导航栏、视频层、弹幕层叠在一起如果全靠GPU合成再拷贝功耗和带宽都扛不住。DRM/KMSDirect Rendering Manager / Kernel Mode Setting就是为了解决这些问题设计的。KMS负责显示模式设置包括分辨率、刷新率、时序参数DRM负责显存管理和命令提交。高通在DRM框架下实现了msm DRM驱动把DPU的硬件能力抽象成KMS的各个对象CRTC对应DPU的显示控制器Plane对应图层Encoder对应MIPI DSI控制器Connector对应物理屏幕接口。这里有个关键点很多人搞混在高通平台上一个CRTC通常绑定一个DPU的LMLayer Mixer而Plane对应DSPPDisplay Sub-Processor里的各个处理单元。你配置Plane的时候实际上是在告诉DPU这个图层从哪块内存取数据、用什么格式、放在屏幕的什么位置、要不要缩放旋转。2.2 设备树里的DPU节点长什么样高通平台的DPU配置大量依赖设备树Device Tree。你去看msm-xxx.dtsi文件会看到类似这样的结构mdss: mdssae00000 { compatible qcom,mdss; reg 0xae00000 0x1000; reg-names mdss_phys; mdp: mdpae01000 { compatible qcom,mdp5; reg 0xae01000 0x100000; interrupts 0 83 0; clocks clock_gcc GCC_MDSS_AHB_CLK, clock_gcc GCC_MDSS_AXI_CLK, clock_gcc GCC_MDSS_MDP_CLK; clock-names iface_clk, bus_clk, core_clk; }; dsi: dsiae94000 { compatible qcom,dsi-ctrl-6g-qcm2290; reg 0xae94000 0x400; clocks clock_gcc GCC_MDSS_BYTE0_CLK, clock_gcc GCC_MDSS_PCLK0_CLK; clock-names byte_clk, pixel_clk; }; };这段配置里mdp节点就是DPU的核心dsi节点是MIPI DSI控制器。clocks列表里的core_clk决定了DPU的工作频率直接影响它能支持的最大分辨率和刷新率。我实测过如果core_clk配低了4K分辨率下会出现underflow屏幕底部随机闪横线。注意设备树里的时钟频率不是随便填的要根据分辨率、刷新率、像素格式反推。后面我会给出计算公式。2.3 原子提交与异步更新的取舍DRM/KMS支持两种提交方式legacy的set_config和atomic的atomic_commit。高通平台现在基本都用atomic模式。atomic的好处是你可以把多个Plane的更新打包成一个commitDPU硬件会在同一个vblank周期内完成所有更新避免撕裂。但atomic也有坑。如果你在atomic_commit里配置了某个Plane的属性但没有正确设置CRTC的active状态内核会直接返回-EINVAL。我遇到过好几次应用层调了setPlane结果屏幕没反应dmesg里一堆“atomic commit failed”。后来发现是Plane的crtc_id没设对或者framebuffer的format和DPU支持的格式不匹配。异步更新async commit是另一个容易踩坑的地方。高通DPU支持在某些场景下不等vblank就提交比如光标移动。但如果你对主图层用了async而DPU的带宽不够就会出现撕裂。我的经验是除非你明确知道自己在做什么否则主图层一律用sync commit。3. DPU内部管线从Layer Mixer到MIPI DSI的硬件细节3.1 Layer Mixer与DSPP的分工DPU内部不是一个大一统的模块而是由多个子模块串联而成。以高通比较新的DPU版本为例一个典型的管线是Source Pipe (VIG/DMA) - DSPP - Layer Mixer - DSC - Interface (INTF) - MIPI DSISource Pipe负责从内存取数据。VIGVideo Integration Graphics支持缩放和旋转DMA只支持直接搬运。如果你要做竖屏转横屏就必须走VIG因为DMA不支持旋转。这也是为什么有些低端芯片竖屏横显会卡因为它没有足够的VIG pipe。DSPPDisplay Sub-Processor负责色彩处理包括gamma校正、色彩空间转换、锐化等。高通DPU的DSPP里有个叫PCCProgrammable Color Correction的模块可以调色温。如果你觉得屏幕偏黄可以在DSPP里调PCC而不是去改屏幕的初始化序列。Layer Mixer负责把多个图层的像素混合在一起。每个Layer Mixer有若干个输入每个输入可以绑定一个Source Pipe。混合的时候按照z-order从低到高叠加支持alpha blending。这里有个细节Layer Mixer的混合是在线性空间还是gamma空间做的不同DPU版本不一样。高通大部分版本是在gamma空间混合所以如果你做半透明叠加颜色可能会和预期有偏差。3.2 带宽计算与underflow预防DPU最怕的就是underflow也就是DPU取数据的速度跟不上屏幕消耗的速度。一旦underflow屏幕上就会出现闪烁、横线、甚至黑屏。预防underflow的核心是算清楚带宽需求。带宽计算公式大致是总带宽 分辨率宽 × 分辨率高 × 刷新率 × 每像素字节数 × 开销系数举个例子1920×108060HzRGB888格式每像素3字节开销系数取1.21920 × 1080 × 60 × 3 × 1.2 ≈ 447 Mbps但这只是单个图层。如果你有3个图层叠加每个图层都要从内存读一遍那就是1.3 Gbps左右。再加上写回内存的带宽如果用了writeback总带宽需求可能超过2 Gbps。高通DPU的带宽由AXI总线提供core_clk和bus_clk决定了总线频率。如果带宽不够DPU会触发underflow中断。你可以在dmesg里看到“mdss underflow”或者“dsi underflow”的报错。我的经验是在设备树里配置时钟的时候core_clk至少要给到带宽需求的1.5倍余量。比如算出来需要300MHz那就配450MHz。另外如果用了DSC压缩带宽需求可以降到原来的1/3左右因为DSC是有损压缩压缩比通常可以设到3:1。3.3 DSC压缩的启用与参数选择DSCDisplay Stream Compression是VESA制定的显示流压缩标准高通DPU从某个版本开始支持。启用DSC的好处是降低带宽和功耗坏处是引入压缩伪影。对于文字为主的界面DSC的伪影可能看不出来但对于渐变色的图片仔细看会有色带。启用DSC需要在设备树和驱动里同时配置。设备树里要声明DSC节点驱动里要设置压缩比、bits_per_pixel等参数。高通平台的DSC配置通常在dsi panel的初始化序列里通过DCS命令下发。// 典型的DSC配置参数 struct drm_dsc_config dsc_cfg { .slice_width 960, .slice_height 1080, .bits_per_component 8, .bits_per_pixel 8, // 压缩后每像素8bit .line_buf_depth 9, .block_pred_enable true, .convert_rgb true, .simple_422 false, };这里bits_per_pixel设成8意味着压缩比是3:1原始RGB888是24bit。如果你设成6压缩比是4:1画质会更差。我的建议是手机和平板用8车载和工业用10或12因为车载对画质要求更高。提示DSC的slice_width和slice_height必须能被屏幕的时序参数整除否则DSI控制器会报错。我踩过一次坑slice_width设了960但屏幕的hactive是1080结果DSC初始化失败屏幕直接黑屏。4. MIPI DSI链路从像素到差分信号的最后一公里4.1 DSI控制器的时钟计算MIPI DSI的时钟计算是很多人头疼的地方。DSI有两个时钟pixel_clk和byte_clk。pixel_clk是像素时钟决定了每秒传输多少像素byte_clk是字节时钟决定了DSI链路的传输速率。pixel_clk的计算公式pixel_clk (hactive hfp hbp hsync) × (vactive vfp vbp vsync) × 刷新率以1920×108060Hz为例假设hfp88, hbp148, hsync44, vfp4, vbp36, vsync5pixel_clk (1920 88 148 44) × (1080 4 36 5) × 60 2200 × 1125 × 60 148.5 MHzbyte_clk的计算要看DSI的lane数和像素格式。对于RGB888每个像素24bit如果用了4条lanebyte_clk pixel_clk × 24 / (4 × 8) pixel_clk × 0.75所以byte_clk 148.5 × 0.75 111.375 MHz。但DSI的实际传输速率是byte_clk的2倍DDR所以链路速率是222.75 Mbps per lane。如果你在设备树里把byte_clk配错了屏幕要么不亮要么花屏。我遇到过byte_clk配高了屏幕能亮但偶尔闪配低了直接黑屏。所以这个计算一定要仔细。4.2 竖屏改横屏的完整操作竖屏改横屏是热词里提到的高频需求。很多屏幕原生是竖屏比如800×1280但产品需要横屏显示1280×800。这个改动涉及多个层面第一层是设备树里的panel timing。你要把hactive和vactive对调同时调整hfp、hbp、vfp、vbp。注意不是简单对调就行因为屏幕的物理扫描方向没变你只是告诉DSI控制器按横屏的时序发送数据。第二层是DPU的旋转配置。如果你只是改了timing画面会变成横屏但内容是旋转90度的。你需要在DPU的VIG pipe里启用旋转或者用Layer Mixer的旋转功能。高通DPU支持90度、180度、270度旋转但旋转会消耗额外的带宽和硬件资源。第三层是应用层的适配。Android的SurfaceFlinger会根据屏幕的orientation来合成图层。如果你在驱动层做了旋转应用层就不需要再旋转反之亦然。我的建议是尽量在应用层做旋转驱动层只做timing调整。因为驱动层旋转会占用VIG pipe可能导致其他图层没有pipe可用。# 在adb里强制设置屏幕方向 adb shell settings put system user_rotation 1 adb shell settings put system accelerometer_rotation 0但这种方法只对Android应用有效如果屏幕本身是竖屏的你还需要改内核的panel驱动。4.3 DSI命令模式与视频模式的差异MIPI DSI有两种工作模式命令模式Command Mode和视频模式Video Mode。命令模式是DSI控制器把像素数据先写到屏幕的GRAM里屏幕自己刷新视频模式是DSI控制器持续不断地发送像素流屏幕实时显示。命令模式的好处是省电因为屏幕不需要持续接收数据坏处是有撕裂风险因为屏幕刷新和DSI发送不同步。视频模式的好处是无撕裂坏处是功耗高。高通DPU对两种模式的支持不一样。视频模式下DPU的INTF模块会持续输出像素命令模式下DPU会在tear check信号触发时才输出一帧。如果你用命令模式但没接tear check信号屏幕就会撕裂。我实测下来手机屏幕基本都用视频模式因为手机对撕裂很敏感手表和低功耗设备用命令模式因为省电优先。你在配置panel的时候一定要确认屏幕支持哪种模式配错了要么不亮要么撕裂。5. 常见问题排查与实战避坑指南5.1 屏幕不亮的分层排查法屏幕不亮是最常见的问题但原因可能出在链路的任何一层。我的排查顺序是从下往上先看DSI信号有没有出来。用示波器量DSI的clock lane和data lane如果有差分信号说明DSI控制器在工作如果没有问题在DSI控制器或更上层。再看DPU有没有输出。在dmesg里搜“mdss”和“dsi”看有没有报错。常见的报错有“dsi phy init failed”、“mdp underflow”、“atomic commit failed”。然后看panel初始化序列有没有发出去。DSI的命令模式下panel初始化是通过DCS命令发的。你可以在驱动里加打印看初始化命令有没有发成功。最后看背光。有时候屏幕其实亮了但背光没开看起来是黑的。检查backlight节点和pwm配置。我整理了一个排查表现象可能原因排查方法完全黑屏无背光背光电路或PWM配置错误量背光使能引脚检查pwm节点黑屏但有背光DSI信号未输出或panel未初始化量DSI差分信号查dmesg花屏时钟频率错误或lane数不匹配重新计算byte_clk检查lane配置撕裂命令模式未接tear check改用视频模式或接tear check颜色不对像素格式或色彩空间配置错误检查framebuffer格式和DSPP配置5.2 竖屏横显的时序陷阱竖屏改横屏的时候最容易踩的坑是时序参数没算对。比如原生竖屏是800×1280hactive800, vactive1280。你改成横屏后hactive1280, vactive800。但hfp、hbp、vfp、vbp不能简单对调因为屏幕的物理扫描电路是按竖屏设计的。正确的做法是查屏幕的datasheet找到横屏模式下的推荐时序。如果datasheet只给了竖屏时序你可以按比例调整。比如竖屏的hfp20横屏可以设成20×(1280/800)32。但这只是近似最好还是实测。我踩过一次坑竖屏改横屏后屏幕能亮但右边有一条黑边。后来发现是hbp设小了DSI在发送完一行像素后没有足够的blanking时间导致下一行的数据被截断。把hbp从40调到60就好了。5.3 带宽不足导致的随机闪线随机闪线是underflow的典型表现。你可能会看到屏幕底部偶尔闪一条白线或黑线尤其是在播放视频或滑动界面的时候。这是因为DPU取数据的速度偶尔跟不上屏幕消耗的速度。解决underflow有几个方向提高core_clk和bus_clk的频率。这是最直接的方法但会增加功耗。减少图层数量。每减少一个图层就少一份内存读取带宽。启用DSC压缩。压缩比3:1的话带宽需求降到1/3。优化内存访问模式。比如用UBWCUniversal Bandwidth Compression格式高通DPU对UBWC有硬件加速能显著降低带宽。我实测过在同一个平台上启用UBWC后4K视频播放的underflow概率从每天几次降到几乎为零。5.4 DSI链路训练失败的排查DSI链路训练Link Training是DSI控制器和屏幕之间协商链路速率的过程。如果训练失败屏幕就不亮。训练失败的原因通常是时钟频率不匹配。屏幕支持的速率范围和DSI控制器配的不一致。lane数不匹配。屏幕是4 lane你配了2 lane或者反过来。PHY配置错误。DSI PHY的驱动强度和预加重参数需要根据PCB走线调整。高通平台的DSI PHY配置在设备树里有一堆参数比如qcom,dsi-phy-xxx。这些参数通常由高通给参考值但如果你换了屏幕或改了PCB可能需要微调。我的经验是如果链路训练失败先把速率降到最低比如降到屏幕支持的最低速率如果最低速率能通再逐步往上调。这样能快速定位是速率问题还是其他问题。6. 调试工具与实战技巧6.1 用sysfs和debugfs查看DPU状态高通DRM驱动在debugfs里暴露了很多有用的信息。你可以这样查看# 查看DPU的时钟状态 cat /sys/kernel/debug/dri/0/msm_dpu/clk_status # 查看当前commit的状态 cat /sys/kernel/debug/dri/0/msm_dpu/commit_status # 查看underflow计数 cat /sys/kernel/debug/dri/0/msm_dpu/underflow_countunderflow_count是我最常用的。如果这个数字在持续增长说明带宽不够需要调时钟或减图层。6.2 用perfetto抓显示管线Perfetto是Android的系统级追踪工具可以抓SurfaceFlinger、HWC、DRM的调用链。你可以这样抓# 抓10秒的显示相关trace perfetto -c - --txt -o /data/misc/perfetto-traces/display.pftrace EOF buffers: { size_kb: 65536 } data_sources: { config { name: android.surfaceflinger.frametimeline } } duration_ms: 10000 EOF抓完后用Perfetto UI打开能看到每一帧的合成耗时、DPU提交耗时、DSI发送耗时。如果某一帧的DPU提交耗时突然变大说明那一帧的图层配置有问题。6.3 修改panel初始化序列的注意事项panel初始化序列是屏幕厂商给的通常是一堆DCS命令。你在修改的时候要注意命令的顺序不能乱。有些命令有依赖关系比如先要退出睡眠模式才能设分辨率。延时不能省。有些命令之间需要延时比如退出睡眠模式后要等120ms。参数不能改。除非你明确知道参数的含义否则不要改。我见过有人把gamma参数改了结果屏幕颜色完全不对。如果你要加自定义命令建议加在初始化序列的最后并且加打印方便排查。6.4 多屏异显的配置要点高通DPU支持多屏异显比如一个屏幕走DSI另一个走DP。配置多屏的时候要注意每个屏幕要有独立的CRTC和Encoder。带宽要算总和。两个4K屏幕的带宽需求是单个的两倍。时钟要独立配置。两个屏幕的pixel_clk可能不一样。我配过双屏一个1080p60一个720p60。总带宽大概1.5Gbpscore_clk给到400MHz才稳定。如果只给300MHz第二个屏幕就会闪。7. 性能优化与功耗平衡7.1 动态时钟调整的策略高通DPU支持动态时钟调整也就是根据当前负载调整core_clk。这个功能在驱动里叫“clock scaling”。启用后DPU会在负载低的时候降频省电负载高的时候升频保流畅。但clock scaling有个问题升频有延迟。如果负载突然变大DPU可能来不及升频导致短暂的underflow。我的做法是在视频播放、游戏这类高负载场景把clock scaling关掉固定在高频在待机、阅读这类低负载场景再打开。7.2 图层合并减少带宽Android的HWC会尽量把多个图层合并成一个减少DPU的图层数。但HWC的合并策略不一定最优。你可以通过dumpsys SurfaceFlinger查看当前的图层数adb shell dumpsys SurfaceFlinger | grep HWC layers如果图层数超过4个可以考虑手动合并。比如把状态栏和导航栏合并成一个图层或者把静态背景和动态内容分开。7.3 用UBWC降低内存带宽UBWC是高通的内存压缩格式对DPU有硬件加速。启用UBWC后DPU从内存读数据的时候会自动解压带宽需求降低30%到50%。启用UBWC需要在分配framebuffer的时候指定格式。在DRM里UBWC格式通常是带有“UBWC”后缀的fourcc比如DRM_FORMAT_ABGR8888_UBWC。你可以在HWC的配置里强制使用UBWC。但UBWC不是万能的。如果图像内容本身压缩率低比如随机噪声UBWC的效果就不明显。另外UBWC需要内存对齐如果framebuffer的stride没对齐UBWC会失效。8. 从寄存器级别理解DPU的工作机制8.1 关键寄存器的含义如果你想深入理解DPU看寄存器是最直接的。高通DPU的寄存器手册是NDA的但你可以从驱动代码里反推。比如msm_dpu的驱动里有这样的定义#define MDP_INTF_TIMING_ENGINE_EN 0x0 #define MDP_INTF_HSYNC_CTL 0x4 #define MDP_INTF_VSYNC_PERIOD_F0 0x8 #define MDP_INTF_VSYNC_PULSE_WIDTH_F0 0xC这些寄存器控制着INTF模块的时序。你写进去的值最终会变成DSI的时序信号。如果你把HSYNC_CTL配错了屏幕的同步信号就不对画面会偏移。8.2 中断处理与错误恢复DPU的中断处理是驱动里比较复杂的部分。常见的中断有INTF underflowINTF模块取数据太慢INTF vsync垂直同步中断DSI errorDSI链路错误WB donewriteback完成如果underflow中断频繁触发驱动会打印警告但不会自动恢复。你需要手动调时钟或减图层。如果DSI error中断触发驱动可能会尝试重新初始化DSI链路。我在调试的时候会在中断处理函数里加计数和打印这样能快速定位是哪个模块出了问题。8.3 电源管理与时序DPU的电源管理涉及多个电源域core power、DSI power、PHY power。上电顺序不能乱否则会烧芯片或者不工作。高通推荐的顺序是先开core power再开DSI power最后开PHY power。下电顺序反过来。时序上每个电源域之间要有延时。比如core power稳定后等1ms再开DSI power。这些延时在驱动里通常用udelay实现。如果你在调试的时候发现屏幕偶尔不亮但重启就好很可能是电源时序问题。用示波器量各个电源域的上升沿看是否符合datasheet的要求。9. 实战案例从零点亮一块MIPI DSI屏幕9.1 硬件连接检查拿到一块新屏幕先别急着写驱动。第一步是检查硬件连接DSI的lane数对不对。屏幕是4 lane你接的是4 lane吗差分对的极性对不对。DSI的P和N接反了信号是反的屏幕不亮。背光电路对不对。背光的使能引脚、PWM引脚、电源引脚都要确认。复位引脚对不对。屏幕的reset引脚通常需要拉低一段时间再拉高。我踩过一次坑屏幕的reset引脚接错了拉低拉高都没反应。后来查原理图发现reset引脚被接到了另一个GPIO上。9.2 设备树配置模板确认硬件没问题后开始配设备树。以下是一个典型的DSI panel配置模板dsi_panel: panel0 { compatible vendor,panel-name; reg 0; reset-gpios tlmm 60 GPIO_ACTIVE_LOW; backlight-gpios tlmm 61 GPIO_ACTIVE_HIGH; vdd-supply pm8953_l10; vddio-supply pm8953_l6; qcom,mdss-dsi-panel-width 1080; qcom,mdss-dsi-panel-height 1920; qcom,mdss-dsi-h-front-porch 88; qcom,mdss-dsi-h-back-porch 148; qcom,mdss-dsi-h-pulse-width 44; qcom,mdss-dsi-v-front-porch 4; qcom,mdss-dsi-v-back-porch 36; qcom,mdss-dsi-v-pulse-width 5; qcom,mdss-dsi-panel-framerate 60; qcom,mdss-dsi-panel-clockrate 742500000; qcom,mdss-dsi-on-command [ 05 01 00 00 78 00 01 11 05 01 00 00 14 00 01 29 ]; qcom,mdss-dsi-off-command [ 05 01 00 00 14 00 01 28 05 01 00 00 78 00 01 10 ]; };这里的on-command和off-command是屏幕的初始化序列。0x11是退出睡眠模式0x29是打开显示。延时参数0x78120ms0x1420ms要根据屏幕datasheet来。9.3 点亮后的验证步骤屏幕点亮后别急着庆祝。按以下步骤验证显示纯色画面检查有没有坏点、色偏。显示渐变画面检查有没有色带DSC伪影。播放视频检查有没有撕裂、卡顿。滑动界面检查有没有underflow闪线。反复开关屏幕检查初始化序列是否稳定。我一般会写一个测试脚本自动跑这些场景并记录underflow计数和帧率。10. 进阶话题DPU与GPU的协同工作10.1 合成策略的选择Android的HWC会根据图层属性决定用GPU合成还是DPU合成。一般来说视频层、游戏层用DPU合成因为DPU有硬件解码和缩放UI层用GPU合成因为GPU的混合更灵活。但HWC的决策不一定最优。你可以通过dumpsys SurfaceFlinger查看HWC的决策日志看哪些图层走了GPU哪些走了DPU。如果发现某个图层本可以走DPU但走了GPU可以调整图层的format或属性让HWC重新决策。10.2 共享内存与同步机制DPU和GPU共享内存的时候需要同步机制。Android用fence来同步。GPU渲染完一帧后会signal一个fenceDPU在提交之前会wait这个fence。如果fence没signalDPU就会等导致掉帧。fence的问题通常出在驱动层。如果GPU驱动没有正确signal fenceDPU就会一直等。你可以在dmesg里搜“fence”相关的报错。10.3 未来趋势DPU的AI加速高通最新的DPU开始集成AI加速功能比如用AI做超分辨率、画质增强。这些功能目前还在早期但值得关注。如果你在做车载或高端平板可以留意高通的新平台。我个人觉得DPU的AI加速最大的价值是降低GPU的负载。比如视频播放的时候GPU不需要做缩放DPU用AI做超分功耗和画质都能兼顾。11. 我踩过的那些坑与经验总结11.1 时钟配置的教训我最惨的一次是配错了byte_clk导致屏幕花屏。当时以为是屏幕坏了换了一块还是花屏。后来用示波器量DSI的clock lane发现频率是datasheet要求的两倍。原来是我把byte_clk和pixel_clk搞混了。byte_clk是pixel_clk的0.75倍4 lane RGB888我直接填了pixel_clk的值。教训时钟计算一定要写下来反复核对。最好在驱动里加打印把实际配置的时钟频率打出来。11.2 设备树覆盖的坑高通平台的设备树有多个层级比如msm-xxx.dtsi、msm-xxx-pinctrl.dtsi、msm-xxx-display.dtsi。如果你在错误的层级改了配置可能被上层覆盖。我遇到过改了panel timing但没生效后来发现是另一个dtsi文件里也定义了同样的panel而且后加载的覆盖了先加载的。解决方法是用“/delete-node/”删掉不需要的节点或者确保你的修改在最后加载的dtsi里。11.3 调试心态的调整显示调试是个耐心活。有时候一个问题要查好几天从应用层查到寄存器。我的经验是不要跳步按链路一层一层查。先确认DSI信号有没有再确认DPU有没有输出再确认panel有没有初始化。每一步都用工具验证不要靠猜。另外多和硬件工程师沟通。很多显示问题其实是硬件问题比如PCB走线阻抗不匹配、电源纹波太大。软件查半天不如硬件改一根线。11.4 文档与代码的交叉验证高通的文档有时候和代码不一致。比如文档说某个寄存器是只读的但代码里在写。遇到这种情况以代码为准因为代码是实际运行的。但也要小心代码可能有bug。最好的方法是看代码然后在硬件上验证。我一般会准备一个测试内核里面加了很多打印和调试接口。这样遇到问题可以快速定位不用反复编译。12. 写给刚入门的同行如果你刚开始接触高通DPU显示架构我的建议是先跑通一个最简单的panel不要一上来就搞4K、多屏、DSC。先把单屏1080p点亮理解DRM/KMS的基本概念再逐步加功能。调试的时候善用dmesg和debugfs。dmesg里的报错信息通常很直接比如“dsi phy init failed”就是PHY初始化失败“mdp underflow”就是带宽不够。debugfs里的underflow_count和clk_status能帮你快速判断问题方向。最后多动手。显示架构这东西看文档看十遍不如自己配一遍。配错了屏幕不亮你自然就会去查为什么。这种“被逼着学”的过程比被动看文档有效得多。我自己从第一次点亮屏幕到现在踩过的坑至少有几十个。每一个坑都让我对这条链路的理解更深一层。希望这篇文章能帮你少踩几个坑更快地把屏幕点亮。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。