双屏的模式有很多种,本篇文章介绍的是用于AR/VR场景的双目同步异显。
我们使用的是两个规格完全一样的显示屏,分辨率为640*480,RGB565(bpp16),刷新率为60fps。
这种方式在显示内容上具有很强的相关性。从上层的角度看只创建了一个buffer(1280*480),硬件上连接了两路mipi dsi,且每路都使用了两lane数据线。SOC上对buffer数据采用的是左右切割的模式,就是说同一张图,左半边用一路mipi dsi传输,同时右半边用另一路mipi dsi传输,如下图:
以下分别从UEFI和kernel两个方面讲讲这种连接的软件配置。
建议优先配置UEFI,因为
①UEFI中的phy timing是自动计算的,这就解决了因为timing不对导致的异常问题。
②UEFI在开机阶段就可以验证屏幕是否正常显示,不用等开机或开机后亮灭屏这么久。
一、UEFI
①在 boot_images/QcomPkg/SDM670Pkg/Library/MDPPlatformLib/MDPPlatformLib.c 中找个高通默认dual dsi video的屏幕配置,这里我选的是Truly_TFT2P2827_E_video_xmldata。
②根据自己实际屏幕参数修改分辨率和porch大小,因为我们要求Vbalnk和Hblank时mipi要在LP模式,且时间要足够长,所以Hblank配置的很大。要注意的是UEFI里面配置dual dsi要把分辨率配置成(W*2) * H,我们的项目配成1280*480。porch暂且按照单屏的配置,后续验证过程中如果有问题,我再来修改文章。
" <HorizontalActive units=\"Dot Clocks\">1280</HorizontalActive>"
" <HorizontalFrontPorch units=\"Dot Clocks\">640</HorizontalFrontPorch>"
" <HorizontalBackPorch units=\"Dot Clocks\">640</HorizontalBackPorch>"
" <HorizontalSyncPulse units=\"Dot Clocks\">12</HorizontalSyncPulse>"
" <VerticalActive units=\"Dot Clocks\">480</VerticalActive>"
" <VerticalFrontPorch units=\"Lines\">16</VerticalFrontPorch>"
" <VerticalBackPorch units=\"Lines\">16</VerticalBackPorch>"
" <VerticalSyncPulse units=\"Lines\">8</VerticalSyncPulse>"
③根据屏幕参数修改其他配置信息,我做的主要有
a. 配置mipi 2lane传输和bpp16模式
" <InterfaceColorFormat units=\"QDI_PixelFormatType\">1</InterfaceColorFormat>"
" <DSIColorFormat units=\"DSI_ColorFormatType\">18</DSIColorFormat>"
" <DSILanes units=\"integer\">2</DSILanes>"
b. 配置Hblank和Vblank的LP模式
" <DSILowPowerModeInHFP units='Bool'>True</DSILowPowerModeInHFP>\n"
" <DSILowPowerModeInHBP units='Bool'>True</DSILowPowerModeInHBP>\n"
" <DSILowPowerModeInHSA units='Bool'>True</DSILowPowerModeInHSA>\n"
" <DSILowPowerModeInBLLPEOF units='Bool'>True</DSILowPowerModeInBLLPEOF>\n"
" <DSILowPowerModeInBLLP units='Bool'>True</DSILowPowerModeInBLLP>\n"
c. 配置mipi clk的强制高速模式
" <DSIClockHSForceRequest>1</DSIClockHSForceRequest>"
二、kernel
kernel中的配置稍微复杂一点,因为要牵扯到phy timing的计算问题。
① 根据实际的屏幕参数配置arch/arm64/boot/dts/qcom/dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi文件
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
qcom,mdss-dsi-lane-0-state;
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-hbp-power-mode;
qcom,mdss-dsi-hfp-power-mode;
qcom,mdss-dsi-hsa-power-mode;
qcom,mdss-dsi-force-clock-lane-hs;
qcom,mdss-dsi-bpp = <16>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-width = <640>;
qcom,mdss-dsi-panel-height = <480>;
qcom,mdss-dsi-h-front-porch = <640>;
qcom,mdss-dsi-h-back-porch = <640>;
qcom,mdss-dsi-h-pulse-width = <12>;
qcom,mdss-dsi-h-sync-skew = <0>;
qcom,mdss-dsi-v-back-porch = <16>;
qcom,mdss-dsi-v-front-porch = <16>;
qcom,mdss-dsi-v-pulse-width = <8>; }
}
② 填写高通mipi phy timing计算表格,获取phy timing参数
这里需要注意的是分辨率和porch都按照单屏的配置填写。
③ 修改arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi文件,把计算好的timing数据填进去。
Mark: 结合第④第⑤点,这里配置的是表格中DSI PHY 2.0.0 timing setting参数
qcom,mdss-dsi-t-clk-post = <0x0a>;
qcom,mdss-dsi-t-clk-pre = <0x20>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 0f 04 05 1f 1c 04
06 03 02 04 00];
};
};
④ 解bug
调试过程中发现kernel里会报错"dsi FIFO OVERFLOW error"、"dsi FIFO UNDERFLOW error",初步定位是phy timing相关的问题。尝试调试porch和timing后错误并没有得到解决,但是同样的配置在UEFI中是正常的,遂在UEFI自动计算phy timing的位置添加log跟kernel计算值进行对比。
log添加位置:boot_images/QcomPkg/Library/HALDSILib/HALdsi_Phy_2_0_0.c
对比后发现UEFI中用的是phy timing 2.0的参数,而kernel中配置的是phy timing 3.0 的参数,且dtsi中配置走3.0的代码。
⑤ 修改arch/arm64/boot/dts/qcom/sdm670-sde.dtsi文件强制配置phy timing 2.0
mdss_dsi_phy0 和 mdss_dsi_phy1 都要改。