本文以最近在QCM6490平台调试的一块FT8719为例,详细介绍点亮一块LCD屏幕的完整过程。
点亮屏幕的操作主要分两部分:上电和配置MIPI参数。上电保证屏幕可以有正常的背光,而MIPI参数保证有合适的清晰度,分辨率和画面。
一、上电
拿到调试任务先看原理图,以下为LCD的一些引脚。
从名称中可以了解我们需要对LCM_AVDD、LCM_AVEE以及VREG_L12C上电,LED_K和LED_A为PWM调光的引脚,最后还需要对RESET_N进行拉低高低电压初始化初始化。
如果是新手或者不确定上电是否正确,请先熟悉屏幕的数据手册再去和硬件交流,最后也可以和供应商确定一下以防万一。
(1)AVEE与AVDD上电
接下来我们需要在原理图中找这些脚是由QCM6490模块的哪些GPIO或者PMIC操作的。
搜索发现AVEE和AVDD的电来自一块调压芯片,并且该芯片由I2C控制电压。因为模块过来的电是恒压6v,而屏幕需要的电压在3.3v到5.5v之间,所以这块芯片的作用就是通过I2C控制电压使其输出3.3v至5.5v的电压,和硬件确认后明确了需要打开DRIVER_EN脚以及调通I2C,VPH_PWR是开机就有电。
首先需打开DRIVER_EN的电,在原理图上找到该电来自PM7250B的GPIO2
下面简单讲一下如何在kernel配置一个PMIC的GPIO:
1、 配置PM7250B的GPIO2为digital output
&pm7250b_gpios {
disp_lcd_bias_en {
disp_lcd_bias_en_default: disp_lcd_bias_en_default {
pins = "gpio2";
function = "func1";
input-disable;
output-enable;
bias-disable;
power-source = <0>;
qcom,drive-strength = <2>;
};
};
};
2、在你需要用到PM7250B的设备树添加pinctrl
your_dtsi {
compatible = "qcom,your_compatible";
pinctrl-names = "default";
pinctrl-0 = <&disp_lcd_bias_en_default>;
test-gpios = <&pm7250b_gpios 2 GPIO_ACTIVE_LOW>;
};
3、在驱动中添加逻辑代码拉高,以下代码作为测试
int pmic_gpio2_test;
pmic_gpio2_test = of_get_named_gpio(dev.of_node,"test-gpios", 0);
gpio_request(pmic_gpio2_test, “GPIO2”);
gpio_direction_output(pmic_gpio2_test, 1); //Output HIGH
gpio_direction_output(pmic_gpio2_test, 0); //Output LOW
请注意设备树与设备树以及设备树与驱动配置的关系,这里不再讲本次调试具体的配置,请各位自己尝试一下。
接下来是驱动添加。相关驱动供应商会提供,需要在对应的文件夹加上代码并修改Makefile:
驱动代码这边已经可以,但是还需要自己配置设备树,根据驱动代码的分析以及数据手册配置如下:
可以在设备树文件夹中搜索qupv3_se来确定在哪个文件配置i2c的根节点,根据原理图两个GPIO确定其在SE1,所以根节点配置为qupv3_se1_i2c,根据数据手册配置地址,compatible等参数,其余参数无法公开,都是一些电压配置,限制输出3.3-5.5v的参数。
都配置好之后编译烧录并且量电压,但是电压没有变,后来发现是因为芯片的外部使能不起作用,因为I2C通了,所以直接写寄存器用内部使能,最终电压控制在5.5v。
(2)VREG_L12C的上电
因为LCD开机就需要显示LOGO,所以我把VREG_L12C配置成开机常供电,了解上一篇文章后,我们直接找到VREG上电的地方将OFF改为ON:
根据最后的注释进行修改后直接编译aop,烧录进机器后1.8v正常,上电成功。
(3)RESET_N高低高上电初始化
屏幕相关操作并且在开机初始化需要在MDPPlatformLib.c中配置,因为之前讲过BP拉高拉低GPIO的操作,所以直接上代码,需要注意的是仔细阅读数据手册保证上电时序要正确:
#define FT8719_REST 44
在操作相关GPIO的函数添加:
if (EFI_SUCCESS != TLMMProtocol->ConfigGpio((UINT32)EFI_GPIO_CFG(FT8719_REST, 0, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_2MA), TLMM_GPIO_ENABLE))
{
DEBUG((EFI_D_WARN, "DisplayDxe: Configure GPIO %d for LT8911EXB Reset_N line Failed!\n", FT8719_REST));
}
/* Set Reset_N line HIGH */
if (EFI_SUCCESS != TLMMProtocol->GpioOut((UINT32)EFI_GPIO_CFG(FT8719_REST, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), GPIO_HIGH_VALUE))
{
DEBUG((EFI_D_WARN, "DisplayDxe: FT8719 Reset_N line HIGH failed!\n"));
}
MDP_OSAL_DELAYUS(100);
/* Pull Reset_N Low */
if (EFI_SUCCESS != TLMMProtocol->GpioOut((UINT32)EFI_GPIO_CFG(FT8719_REST, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), GPIO_LOW_VALUE))
{
DEBUG((EFI_D_WARN, "DisplayDxe: Pull FT8719 Reset_N Low Failed!\n"));
}
MDP_OSAL_DELAYUS(100);
/* Set Reset_N line HIGH */
if (EFI_SUCCESS != TLMMProtocol->GpioOut((UINT32)EFI_GPIO_CFG(FT8719_REST, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), GPIO_HIGH_VALUE))
{
DEBUG((EFI_D_WARN, "DisplayDxe: FT8719 Reset_N line HIGH failed!\n"));
}
MDP_OSAL_DELAYUS(100);
至此,上电操作已经全部结束,背光因为本次调试上电就有故先不做讲解,之后会有相关示例。
二、MIPI参数配置
本文开头已经了解到,MIPI参数决定显示屏的分辨率、画质、刷新率等。所以这部分配置尤其重要且需要耐心。
上一篇讲到MIPI参数在AP与BP是如何获取的,所以我们已经知道配置的位置在哪。在你调试之前屏幕厂商会给你几个文件来配置AP与BP的MIPI参数,接下来介绍一下如何具体配置:
1.BP侧的配置
Path: 一般在
QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\SocPkg\Kodiak\Library\MDPPlatformLib\MDPPlatformLib.c中配置
但是有的模块在这里配置:
QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\Settings\Panel
只是多了双引号与换行符的差别,本文的配置就在第二处地方
该文件为各个屏幕的XML文件,程序会解析XML文件生成其他设备树和头文件等,所以我们只需要修改此处的参数就可。参数文档中给出的几个参数含义如下:
-
vs:VerticalSyncPulse(表示垂直同步脉冲)
-
vbp:VerticalBackPorch(表示在一帧图像开始时,垂直同步信号开始以后的无效的TH个数)
-
vfp:VerticalFrontPorch(表示在一帧图像结束后,垂直同步信号开始以前的无效的TH个数)
-
hs:HorizontalSyncPulse(表示水平同步信号)
-
hbp:HorizontalBackPorch(表示从水平同步信号结束到一行的有效数据开始之间的DCLK的个数)
-
hfp:HorizontalFrontPorch(表示一行的有效数据结束到下一个水平同步信号开始之间的DCLK的个数)
根据供应商给的参数,本屏幕的配置如下:
<Group id="Active Timing">
<HorizontalActive>1080</HorizontalActive>
<HorizontalFrontPorch>16</HorizontalFrontPorch>
<HorizontalBackPorch>16</HorizontalBackPorch>
<HorizontalSyncPulse>4</HorizontalSyncPulse>
<HorizontalSyncSkew>0</HorizontalSyncSkew>
<HorizontalLeftBorder>0</HorizontalLeftBorder>
<HorizontalRightBorder>0</HorizontalRightBorder>
<VerticalActive>2340</VerticalActive>
<VerticalFrontPorch>112</VerticalFrontPorch>
<VerticalBackPorch>12</VerticalBackPorch>
<VerticalSyncPulse>4</VerticalSyncPulse>
<VerticalSyncSkew>0</VerticalSyncSkew>
<VerticalTopBorder>0</VerticalTopBorder>
<VerticalBottomBorder>0</VerticalBottomBorder>
<InvertDataPolarity>False</InvertDataPolarity>
<InvertVsyncPolairty>False</InvertVsyncPolairty>
<InvertHsyncPolarity>False</InvertHsyncPolarity>
<BorderColor>0x0</BorderColor>
</Group>
第二个需要修改的是寄存器写参数,文档给出的参数与Panel中XML文件里的格式不一样,文档参数格式如下:
CMD(一个字节)+数据个数(十进制数字)+数据内容,例如:
{B8 7 {57 3D 19 1E 0A 50 60}}
或者没有数据个数如
{B8 57 3D 19 1E 0A 50 60}
以上述代码段为例,在Panel中XML文件给的格式为
命令类型(一个字节)+CDM(一个字节)+数据内容,修改上面格式后:
29 B8 57 3D 19 1E 0A 50 50
本文档涉及命令类型有29、39、FF、05:
29h:Generic Long Write
39h:DCS Long Write/write_LUT Command Packet
13h:Generic Short Write(1个参数)
05h:DCS Short Write(没有参数)
FFh:睡眠
参考其余XML格式及参数文档进行修改,如果给出的参数文档中数据中带有0x和逗号,可以在文本文档中进行替换再复制粘贴来提高效率。
XML文件配置大致如下:
<?xml version="1.0" encoding="utf-8"?>
<PanelDescription>FT8719 DSI Video Mode Panel (1080x2340 24bpp)</PanelDescription>
<Group id="Active Timing">
...
...
</Group>
<Group id="Display Interface">
<InterfaceType>8</InterfaceType>
<InterfaceColorFormat>3</InterfaceColorFormat>
</Group>
<Group id="DSI Interface">
<DSIChannelId>1</DSIChannelId>
<DSIVirtualId>0</DSIVirtualId>
<DSIColorFormat>36</DSIColorFormat>
<DSITrafficMode>1</DSITrafficMode>
<DSILanes>4</DSILanes>
<DSIHsaHseAfterVsVe>False</DSIHsaHseAfterVsVe>
<DSILowPowerModeInHFP>False</DSILowPowerModeInHFP>
<DSILowPowerModeInHBP>False</DSILowPowerModeInHBP>
<DSILowPowerModeInHSA>False</DSILowPowerModeInHSA>
<DSIClockHSForceRequest>0</DSIClockHSForceRequest>
<DSILowPowerModeInBLLPEOF>True</DSILowPowerModeInBLLPEOF>
<DSILowPowerModeInBLLP>True</DSILowPowerModeInBLLP>
<DSIRefreshRate>0x3C0000</DSIRefreshRate>
<DSIControllerMapping>
00
</DSIControllerMapping>
</Group>
<DSIInitSequence>
29 00 00
29 ff 87 19 01
...
...
...
05 29
05 35 00
FF 20
</DSIInitSequence>
<DSITermSequence>
05 28
FF 10
05 10
FF 32
</DSITermSequence>
<Group id='Backlight Configuration'>
<BacklightType>1</BacklightType>
<BacklightPmicControlType>2</BacklightPmicControlType>
<DisplayResetInfo>0 10 1000 10000 0</DisplayResetInfo>
</Group>
有时屏幕需要打开告诉模式就需要把这一项改为1:
<DSIClockHSForceRequest>1</DSIClockHSForceRequest>
最后需要加上一些逻辑代码和其他配置让机器识别你配的屏幕:
首先在QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\Include\Library\MDPPlatformLib.h文件中添加你的屏幕选项:
然后去QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\SocPkg\Kodiak\Common\Core.fdf中添加:
FILE FREEFORM的参数可以在这个网址生成:Generate GUIDs online
保证屏幕识别的唯一性。
接下来在QCM6490_LA2.0_BP\boot_images\boot\QcomPkg\SocPkg\Kodiak\Library\MDPPlatformLib\MDPPlatformLibPanelConfig.h中添加屏幕入口:
最后在MDPPlatformLib.c中添加逻辑代码:
在panellist添加屏幕选项,再找到以下函数添加屏幕:
const PanelDTInfoType fastBootPanelList[] =
{
...
...
PANEL_CREATE_ENTRY("ft8719_1080p_vid", MDPPLATFORM_PANEL_FT8719_1080P_VIDEO, "qcom,mdss_dsi_ft8719_1080p_video:", DISP_INTF_DSI, DISP_TOPOLOGY_CONFIG_NONE, DISP_TIMING_CONFIG_NONE, PLL_OVERRIDE_NONE, DISP_MODE_SINGLE_DSI, DISP_MODE_SINGLE_DSI, DISP_MODE_SINGLE_DSI),
...
...
}
最后找到屏幕选择的代码,修改选择的屏幕:
索引为0是因为我上面配置的为panellist[0],需要注意,至此BP的屏幕配置已经结束,下面讲AP配置屏幕的操作。
2.AP侧的配置
首先创建自己屏幕的设备树文件,位置为:
QCM6490_LA2.0_AP\LA.UM_QSSI11\vendor\qcom\proprietary\devicetree\qcom\display
在该目录创建dsi-panel-ft8719-1080p-video.dtsi,名字可以自己定义。
内容如下:
/* 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_ft8719_1080p_video: qcom,mdss_dsi_ft8719_1080p_video {
qcom,mdss-dsi-panel-name ="ft8719 1080p video";
qcom,mdss-dsi-panel-type = "dsi_video_mode";
qcom,dsi-ctrl-num = <0>;
qcom,dsi-phy-num = <0>;
qcom,dsi-select-clocks = "mux_byte_clk0", "mux_pixel_clk0";
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-bpp = <24>;
qcom,mdss-dsi-underflow-color = <0xff>;
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 10>, <0 10>, <1 10>;
qcom,mdss-dsi-display-timings {
timing@0 {
qcom,mdss-dsi-panel-width = <1080>;
qcom,mdss-dsi-panel-height = <2340>;
qcom,mdss-dsi-h-front-porch = <16>;
qcom,mdss-dsi-h-back-porch = <16>;
qcom,mdss-dsi-h-pulse-width = <4>;
qcom,mdss-dsi-h-sync-skew = <0>;
qcom,mdss-dsi-v-back-porch = <12>;
qcom,mdss-dsi-v-front-porch = <112>;
qcom,mdss-dsi-v-pulse-width = <4>;
qcom,mdss-dsi-panel-framerate = <60>;
qcom,mdss-dsi-h-left-border = <0>;
qcom,mdss-dsi-h-right-border = <0>;
qcom,mdss-dsi-v-top-border = <0>;
qcom,mdss-dsi-v-bottom-border = <0>;
qcom,mdss-dsi-on-command =[
15 01 00 00 00 00 02 00 00
39 01 00 00 00 00 04 ff 87 19 01
...
...
...
05 01 00 00 78 00 02 11 00
05 01 00 00 20 00 02 29 00
];
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 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;
qcom,mdss-dsi-h-sync-pulse = <1>;
qcom,mdss-dsi-panel-phy-timings = [00 22 08 09 25 23 09
08 06 02 04 00 1c 19];
qcom,display-topology = <1 0 1>;
qcom,default-topology-index = <0>;
};
};
};
};
还是按照提供的参数修改VBP VFP HBP等参数,然后是将写寄存器的参数进行转换,方法如下:
CMD(一个字节)+数据个数(十进制数字)+数据内容,例如:
{B8 7 {57 3D 19 1E 0A 50 50}}
或者有些不带数据个数,如:
{B8 57 3D 19 1E 0A 50 50}
转换为:
寄存器(5个字节)+等待时间(1个字节)+CMD(1个字节)+数据
39 01 00 00 00 00 08 B8 57 3D 19 1E 0A 50 50
另外,该文件中的qcom,mdss-dsi-off-command一项需要看屏幕数据手册得出,qcom,mdss-dsi-panel-phy-timings这一项需要通过高通的时序文档计算得出,本屏幕的计算方式如下:
根据屏幕的参数输入对应方框,然后在下面找到4.0timings的文档得出时序参数:
将其填入设备树即可,项目不同timings的版本不同,需要注意。
如果需要打开高速模式,配置qcom,mdss-dsi-force-clock-lane-hs;这一条即可。
其余设备树的配置需要结合驱动代码来调,可以先参考平台其他屏幕的配置添加,改一下其中的参数即可,而且不同项目配置的文件位置也不同,这里就不展示文件位置了。
这里需要注意esd check这一项,得和供应商确认有这一项功能才可打开。
这里设置默认显示哪个屏幕,如果不确定改哪里,可以都改为你调试的屏幕。
最后添加背光控制即可,通过原理图配置8350c的GPIO8即可,其余的参数有需求时需要修改。
至此AP侧的屏幕添加也结束,AP BP编译烧录后可以显示,如果出现异常可以通过搜索panel的log来定位错误原因。
三、总结
本篇文章详细介绍了点亮一块LCD屏幕的步骤,因为AP侧的驱动代码是高通原生代码无需添加,所以本文没有与其联系,而且关于调试方法也较少,之后会总结一些示例来讲高通LCD逻辑代码和调试方法。