在调试display的经历中,除了一些手持类设备以外其他机器基本都会外接HDMI屏幕,显示原理之前也提过:由模块发出的MIPI信号经过9611或者9611uxc芯片输出HDMI信号最后在屏幕进行显示。这两款芯片的最主要差别是9611uxc最高可以支持到4K60fps 的输出画面而9611是4K30fps。和调试9211的大致步骤完全一样,9611和9611uxc的芯片也是分为添加驱动,上电和配置屏幕,只不过需要具体修改配置屏幕的一些参数。所以请先熟悉9211的调试再阅读本篇文章。
本文基于高通845平台,首先大致讲解上电与添加驱动操作,配置屏幕方面在具体调试的过程中1080p与4k的区别会详细介绍。
首先还是阅读手上的一些材料:芯片数据手册、原理图以及驱动部分代码。这里不再具体介绍,和9211调试的步骤基本一致,而且芯片的上电脚也差不多。这里贴一下9611uxc的原理图与数据手册部分内容
阅读完芯片手册与原理图下面在驱动进行上电操作,首先还是在设备树配置对应的GPIO:
接下来添加驱动并且解析对应GPIO再按照时序上电,相关代码就不贴,和9211的是一样的,这一步最主要的还是I2C要调通,后面都相对简单。
这一部分主要讲4k屏幕的配置与1080p的区别,9611uxc最多可以支持4k60 fps的显示,所以向下可以兼容1080p60 fps和720p60 fps,AP的4k MIPI参数配置如下:
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
&mdss_mdp {
dsi_lt9611_4k_video: qcom,mdss_dsi_lt9611_4k_video {
qcom,mdss-dsi-panel-name ="lt9611 video mode dsi panel without DSC";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
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-lane-2-state;
qcom,mdss-dsi-lane-3-state;
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-reset-sequence = <1 200>, <0 200>, <1 200>;
qcom,mdss-pan-physical-width-dimension = <167>;
qcom,mdss-pan-physical-height-dimension = <131>;
qcom,mdss-dsi-tx-eot-append;
qcom,adjust-timer-wakeup-ms = <1>;
qcom,mdss-dsi-panel-peak-brightness = <4200000>;
qcom,mdss-dsi-panel-blackness-level = <3230>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-width = <1920>;
qcom,mdss-dsi-panel-height = <2160>;
qcom,mdss-dsi-h-front-porch = <176>;
qcom,mdss-dsi-h-back-porch = <298>;
qcom,mdss-dsi-h-pulse-width = <88>;
qcom,mdss-dsi-h-sync-skew = <0>;
qcom,mdss-dsi-v-back-porch = <72>;
qcom,mdss-dsi-v-front-porch = <8>;
qcom,mdss-dsi-v-pulse-width = <10>;
qcom,mdss-dsi-h-sync-pulse = <0>;
qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-on-command = [
05 01 00 00 78 00 02 11 00
05 01 00 00 78 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 78 00 02 28 00
05 01 00 00 14 00 02 10 00];
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,mdss-dsi-force-clock-lane-hs;
};
};
};
};
需要注意的是这里的width不是3840而是1920,因为9611uxc的输出是分两路port,也就是可以理解为一个4k屏幕是两个小屏拼凑出来的,而小屏的分辨率是1920x2160,一路port显示左半边一路显示右半边,当驱动来加载这里的参数时并且配置为两路port后会自动拼接,在这里只需要这样配置就可以了。
下面是配置背光以及kernel屏幕选择的设备树:
背光添加:
&dsi_lt9611_1080p_video {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
qcom,panel-mode-gpio = <&tlmm 99 0>;
qcom,platform-reset-gpio = <&tlmm 100 0>;
};
&dsi_lt9611_4k_video {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
qcom,panel-mode-gpio = <&tlmm 99 0>;
qcom,platform-reset-gpio = <&tlmm 100 0>;
};
&dsi_lt9611_720p_video {
qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <4095>;
qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
qcom,panel-mode-gpio = <&tlmm 99 0>;
qcom,platform-reset-gpio = <&tlmm 100 0>;
};
这边的reset脚和panel mode脚需要根据平台配置,另外在使用9611uxc时sel gpio state需要配置为dual_port代表两路port输出。
设置可选择显示的屏幕以及时钟pin脚等参数:
dsi_lt9611_1080p_video_display: qcom,dsi-display@21 {
compatible = "qcom,dsi-display";
label = "dsi_lt9611_1080p_video_display";
qcom,display-type = "primary";
qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
clock-names = "mux_byte_clk", "mux_pixel_clk";
pinctrl-names = "panel_active", "panel_suspend";
pinctrl-0 = <&sde_dsi_active &sde_te_active>;
pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
qcom,platform-te-gpio = <&tlmm 10 0>;
qcom,platform-reset-gpio = <&tlmm 6 0>;
qcom,panel-mode-gpio = <&tlmm 52 0>;
qcom,dsi-panel = <&dsi_lt9611_1080p_video>;
vddio-supply = <&pm8998_l14>;
lab-supply = <&lab_regulator>;
ibb-supply = <&ibb_regulator>;
};
dsi_lt9611_4k_video_display: qcom,dsi-display@22 {
compatible = "qcom,dsi-display";
label = "dsi_lt9611_4k_video_display";
qcom,display-type = "primary";
qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
clock-names = "mux_byte_clk", "mux_pixel_clk";
pinctrl-names = "panel_active", "panel_suspend";
pinctrl-0 = <&sde_dsi_active &sde_te_active>;
pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
qcom,platform-te-gpio = <&tlmm 10 0>;
qcom,platform-reset-gpio = <&tlmm 6 0>;
qcom,panel-mode-gpio = <&tlmm 52 0>;
qcom,dsi-panel = <&dsi_lt9611_4k_video>;
vddio-supply = <&pm8998_l14>;
lab-supply = <&lab_regulator>;
ibb-supply = <&ibb_regulator>;
};
dsi_lt9611_720p_video_display: qcom,dsi-display@20 {
compatible = "qcom,dsi-display";
label = "dsi_lt9611_720p_video_display";
qcom,display-type = "primary";
qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
<&mdss_dsi0_pll PCLK_MUX_0_CLK>;
clock-names = "mux_byte_clk", "mux_pixel_clk";
pinctrl-names = "panel_active", "panel_suspend";
pinctrl-0 = <&sde_dsi_active &sde_te_active>;
pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
qcom,platform-te-gpio = <&tlmm 10 0>;
qcom,platform-reset-gpio = <&tlmm 6 0>;
qcom,panel-mode-gpio = <&tlmm 52 0>;
qcom,dsi-panel = <&dsi_lt9611_720p_video>;
vddio-supply = <&pm8998_l14>;
lab-supply = <&lab_regulator>;
ibb-supply = <&ibb_regulator>;
};
计算时序并配置:
&dsi_lt9611_1080p_video {
qcom,mdss-dsi-t-clk-post = <0x0A>; //1920x2160 60 4lane
qcom,mdss-dsi-t-clk-pre = <0x20>; //1920x2160 60 4lane
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 13 04 04 1F 1E 05
05 03 02 04 00];
qcom,display-topology = <2 0 2>,<1 0 2>;
qcom,default-topology-index = <0>;
};
};
};
&dsi_lt9611_720p_video {
qcom,mdss-dsi-t-clk-post = <0x09>; //640x720 60 4lane
qcom,mdss-dsi-t-clk-pre = <0x17>;
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 0c 03 03 1d 1d 03
03 01 02 04 00];
qcom,display-topology = <2 0 2>,<1 0 2>;
qcom,default-topology-index = <0>;
};
};
};
&dsi_lt9611_4k_video {
qcom,mdss-dsi-t-clk-post = <0x15>; //1920x2160 60 4lane
qcom,mdss-dsi-t-clk-pre = <0x30>; //1920x2160 60 4lane
qcom,mdss-dsi-display-timings {
timing@0{
qcom,mdss-dsi-panel-phy-timings = [00 3E 11 11 30 2C 11
11 0C 02 04 00];
qcom,display-topology = <2 2 2>;
qcom,default-topology-index = <0>;
};
};
};
这一部分需要注意1080p与4k配置的区别,如分辨率1080p是正常配置而4k则需要将宽度减小一半并且时序也是用缩小的分辨率来计算。还需要注意display-topology这一项参数,官方文档给出的配置为4k应设置<2 2 2>.
如果需要添加pinctrl,先在pinctrl文件添加对应GPIO再引用。
BP的配置很简单,在MDDPlatformLib.c文件中添加三个不同分辨率的xml常量,再在.h文件添加你想要显示的三块屏幕,最后在逻辑代码中修改选择显示的屏幕即可,参考9211修改或者之前的提交记录即可。
本文大概介绍了9611与9611uxc的调试办法,很多细节在点亮LCD与LVDS的时候都已经写过了,如果有比较模糊的地方可以参考LVDS与LCD的调试文档,关于I2C的权限问题在GPIO的文档中也提过,但是在此之前的文章中没有具体介绍如何调试I2C与定位屏幕不显示的问题,在下一篇中将根据个人调试经验详细介绍I2C与屏幕不显示的调试办法。