MIPI相关知识
D-PHY的物理层支持HS(High Speed)和LP(Low Power)两种工作模式
HS模式:低压查分信号 功耗大 高速率(80M -1Gbps) 信号幅值(100mv-300mv)
LP模式:单端信号 功耗小,速率低(< 10Mbps) 信号幅值(0-1.2V)
在高速模式下,通道状态是差分的0或1,定义P比N高时定义为1,P比N低时定义为0,此时线上典型电压为差分200mv
在LP模式下,只用lane0传输数据和时钟,双向数据传输。
链路层的模式分为:Command模式和Video模式。
链路层选择Command模式时,物理层可以为HS模式,也可以为LP模式;(LCD上面有RAM,只需要发送更改RAM内容的命令,LCD上的IC负责刷屏)
链路层选择Video模式时,物理层只能选择HS模式。(LCD上没有RAM,需要定时刷新屏幕内容)
LittleKernel
boot_linux
update_cmdline
target_display_panel_node(device.display_panel,display_panel_buf, MAX_PANEL_BUF_SIZE)
gcdb_display_cmdline_arg //"mdss_mdp3.panel=1:dsi:0:panel_node"
panel_node = panelstruct.paneldata->panel_node_id;//因此lk里面的panel id应该跟dts中名字匹配
Kernel
/drivers/video/msm/mdss/mdp3.c(匹配msm8909-mdss.dtsi) 初始化芯片内部的显示控制器
mdp3_res->mdss_util->panel_intf_type = mdp3_panel_intf_type;
return &mdp3_res->pan_cfg(MDSS_PANEL_INTF_DSI) //获取DSI接口的配置
mdp3_parse_dt
mdp3_get_cmdline_config
mdp3_get_pan_cfg//从module_param中分析出pan_cfg的信息,包括从LittleKernel传过来的panel名字
//格式为0:dsi:0:xxx,第一个参数为是否从lk/gcdb获取,第二个参数dsi接口,第三个参数为panel名
mdp3_parse_dt_pan_intf //从mdss_mdp节点中获取设备的接口类型(“dsi”=>MDSS_PANEL_INTF_DSI)
of_property_read_string(pdev->dev.of_node,"qcom,mdss-pref-prim-intf", &prim_intf)
mdp3_get_pan_intf
/drivers/video/msm/mdss/mdss_dsi.c(匹配msm8909-mdss.dtsi) 初始化传输协议层的设备
mdss_dsi_ctrl_probe
mdss_dsi_get_panel_cfg//获得MDSS_PANEL_INTF_DSI接口的cfg
mdss_dsi_find_panel_of_node
of_parse_phandle(pdev->dev.of_node,"qcom,mdss-mdp", 0);//从mdss_dsi的qcom,mdss-mdp属性中找到mdss_mdp设备节点
of_find_node_by_name //找到mdss_mdp下panel name对应的dts节点
mdss_dsi_pref_prim_panel
of_parse_phandle(pdev->dev.of_node,"qcom,dsi-pref-prim-pan", 0); //如果lk没有传入配置信息,则使用dts中这个节点的panel
寄存器读写初始化技巧:
可以在mdss_dsi_panel.c文件的mdss_dsi_panel_on后面,添加mdss_dsi_panel_cmd_read函数,读取写入的
寄存器值是否正确,如读取LCM的ID(0xA1):
memset(read_tmp_buff, 0, sizeof(read_tmp_buff));
mdss_dsi_panel_cmd_read(ctrl, 0xa1, 0x00, NULL, read_tmp_buff, 5);
printk(KERN_CRIT “%s:read cmd:\n”, func);
for(i=0 ; i<5 ; i++){
printk(KERN_CRIT "0x%02x ", read_tmp_buff[i]);
}
printk(KERN_CRIT “\n”);
时钟调试技巧:
系统通过lk初始化时钟,如果时钟(根据帧率自动计算)不符合要求,会导致直接跳过该屏幕,
选取下一个备选屏幕
对bclk的要求,可以查看gcdb_autopll.c中的calculate_div1,bclk/2至少大于40MHZ
且时钟太低有可能精度出现问题,导致通讯失败,所以时钟在屏幕支持的情况下选更高
LCM驱动的dtsi和lk的头文件快速生成
sudo apt-get install libxml-libxml-perl
sudo apt-get install libxml-perl
在./device/qcom/common/display/tools/目录下找到panel_*.xml参考文件和parser.pl工具
cp panel_nt35596_1080p_video.xml panel_tm5075_720x720-video.xml
修改xml的PanelID(dtsi文件名)和PanelH(h文件名)名字
perl parser.pl panel_tm5075_720x720-video.xml panel
把生成的.h放到bootable/bootloader/lk/dev/gcdb/display/include/
生成的.dtsi文件放到kernel/arch/arm/boot/dts/qcom/
常修改的参数:
PanelName label名字
PanelType 0为Video 1为Cmd
PanelOrientation 0旋转0度 1旋转180度
PanelFrameRate 帧率
ColorFormat 24=888_RGB;
18=666_RGB;
16=565_RGB;
12=444_RGB;
8=332_RGB;
3=111_RGB
ColorOrder 0 = DSI_RGB_SWAP_RGB;
1 = DSI_RGB_SWAP_RBG;
2 = DSI_RGB_SWAP_BGR;
3 = DSI_RGB_SWAP_BRG;
4 = DSI_RGB_SWAP_GRB;
5 = DSI_RGB_SWAP_GBR;
OnCommandState/OffCommandState 0 = DSI_LP_MODE
1 = DSI_HP_MODE
TrafficMode 0 = non burst with sync pulses
1 = non burst with sync start event
2 = burst mode
HSyncPulse 0 = Sync pulse disable
1 = Sync pulse enable(在vertical blanking期间是否发送Hsync Pulse)
DSILanes DSI线数
DSILaneMap 0 = DLANE_SWAP_0123
1 = DLANE_SWAP_3012
2 = DLANE_SWAP_2301
3 = DLANE_SWAP_1230
4 = DLANE_SWAP_0321
5 = DLANE_SWAP_1032
6 = DLANE_SWAP_2103
7 = DLANE_SWAP_3210
Lane0(123)State 1=Enable 2=Disable
PanelTimings/TClkPost/TClkPre 使用Tools目录下的80-NH713-1_DSI.zip工具计算得出
BLMinLevel 背光最小值
BLMaxLevel 背光最大值
BLPMICControlType 背光控制模式
0 = PWM GPIO
1 = WLED
2 = DCS COMMANDS
3 = LPG
命令格式
-------------------------------------------------------------------------------------
Subentry | Description | Byte Length
-------------------------------------------------------------------------------------
CommandType | Data type of command | 1
Last | Specifies if this command packet is individual or not. | 1
VC | Virtual channel used to send this command. | 1
Ack | Needs acknowledgement from the panel. | 1
Wait | Sleep in microseconds before sending next command. | 1
PayloadSize | Size of payload | 2
Payload | Actual command | Based on PayloadSize
--------------------------------------------------------------------------------------
通常初始化序列以0x11(Sleep Out)和0x29(Display On)结束
常用的CommandType对照表(mdss_dsi_cmd.h)
DSC_Long_Write 0x39 //mdss_dsi_dcs_lwrite
DSC_Short_Write(no param) 0x05 //mdss_dsi_dcs_swrite
DSC_Short_Write(1 param) 0x15 //mdss_dsi_dcs_swrite1
DSC_Read 0x06 //mdss_dsi_dcs_read
Generic_Long_Write 0x29 //mdss_dsi_generic_lwrite
下面三个指令效果一样,都是mdss_dsi_generic_swrite
Generic_Short_Write(no param) 0x03
Generic_Short_Write(1 param) 0x13
Generic_Short_Write(2 param) 0x23
下面三个指令效果一样,都是mdss_dsi_generic_read
Generic_Read(0 param) 0x04
Generic_Read(1 param) 0x14
Generic_Read(2 param) 0x24
80-NH713-1_G_DSI_Timing_Parameters.xlsm工具使用
1.打开后点击上方“启用内容”
2.打开DSI and MDP registers页面,按照LCM参数填写
3.打开DSI PHY timing setting页面
4.连续按动Ctrl+J,然后按下Ctrl+K,中间Check for T_CLK_ZERO将变为VALID
5.将计算得来的 DSI PHY registers填到PanelTimings,T_CLK_POST/T_CLK_PRE分别填到TClkPost/TClkPre
1.为LittleKernel添加新的LCM
在bootable/bootloader/lk/target/msm8909/oem_panel.c添加
#include “include/panel_tm5075_720x720-video.h”
仿照其他LCM,在enum 、supp_panels和init_panel_data中添加枚举和相关结构体赋值
在oem_panel_select函数中选择panel_id为TM5075_720X720_VIDEO_PANEL
2.为Kernel添加新的LCM
在msm8909-mtp.dtsi中添加
#include “dsi-panel-tm5075_720x720-video.dtsi”
&dsi_tm5075_720x720_video {
qcom,mdss-dsi-bl-pmic-control-type = “bl_ctrl_pwm”;
qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;
qcom,mdss-dsi-bl-pmic-bank-select = <0>;
qcom,mdss-dsi-pwm-gpio = <&pm8909_mpps 2 0>;
qcom,cont-splash-enabled;
};
其中
“bl_ctrl_pwm” = Backlight controlled by PWM GPIO
“bl_ctrl_wled” = Backlight controlled by WLED
“bl_ctrl_dcs” = Backlight controlled by DCS commands
另外可以根据实际情况,修改pmx_mdss,pmx_mdss_te和mdss_dsi0节点中的引脚