https://blog.****.net/tamell5555/article/details/52129984
一. DSI简介
DSI全称是 Display Serial Interface,是mipi协议的一个规范。它定义了一个在平台端和panel之间的串行总线和通信协议,总线包括一条 Clock lane和 1~4条 Date lane。每条 lane有两条 line(lane+和lane-),差分信号。在高通的 display框架里是 mdp的一部分,用来手机平台端和LCD传送 command和 data。HS mode lanes最大能支持到 1.5Gbps。
二. DSI的 layer及其作用
DSI Layer:
(1)Application layer:数据的转换,将pixel data、signal event和 command都转为 bytes
的格式。
(2) Protocol layer:将data bytes打包成 dsi packet,并生成/检验 ECC和 checksum。
(3)Lane management layer:分配发出的data到一条或者多条 Lane上。Data Lane0是
可以 HS的向前数据传送和 LP的双向传送,data Lane1-3只能是单向的 HS向前数据传送。
(4)PHY layer:dsi physical(D-PHY)layer。
Application,low-level protocol和 lane-management是在 dsi controller里面的。
三. DSI的操作模式
DSI只有两种操作模式 command和 video。
(1)command mode从 host端获取 command和 data。但是这个使用 command mode
的 LCD有自己的 RAM和 LCD controller,它会自刷新静态图片。MSM能直接进入休眠,
节约电量。可会多出来 RAM和 Controller的成本。
Command mode的信息是双向的,host能从 panel上读和写数据。Host能同步数据
通过从 panel中读取 Tearing Effect(TE)信号(Vsync)去避免TE。
(2)video mode获取实时的 pixel stream。DSI Controller必须不停的刷新 image data,
这个模式一般用于没有 RAM的panel。Host提供 video data和同步信息。同步信息有Vsync、
Hsync、data enable和 pixel clock。Video mode操作与 RGB接口很类似,但是使用的 pin
脚更少,所以 EMI和无线电干扰更小。
但是目前来说,video模式使用的比较广泛。使用 Command模式的项目还是比较少的。
四. Clock时钟
Dsi core会受到一些 clocks去驱动不同的 logic blocks,然而用户只要关注基于panel特性
的 bitclk就行了。通过确定的 fps、lcd的分辨率、Lane的数量等,真实的 clock会被计算
出来,高通提供了个 excel文档可以去计算这个 timing,这个 timing就是个数组,要填
写到 panel的 dtsi文件中。平台通过解析这个 dtsi文件,将数组的值写入寄存器中。
(1)计算 Timing的 excel工具的介绍
在高通的 CreatPoint网站搜索关键字“dsi_timing_program”,就能下载到这个
excel计算 timing的工具。在这个表格工具中的 sheet1需要填写的是帧率、分辨率、
lane的数量、panel的位数,porch值(如图 1)。然后点击“ctrl+L”,到sheet2中,
在空白处点击 ctrl+J,接着点击 ctrl+K。这样 timing的值就自动生成了(如图 2)。
(2)有些客户会做这个 mipi的规格报告,表格的一些参数可能和 panel的要求不
符合,这个时候就需要进行一些修改了。例如:T_CLK_TRAIL、T_HS_TRAIL、T_HS_EXIT
等。可以通过修改相应的 Timing值达到修改这些参数的效果,已达到 panel要求的
时序的要求。
图 1
图 2
(3)一些时钟的计算:
H-total = HorizontalActive + HorizontalFrontPorch + HorizontalBackPorch +
+ HorizontalSyncSkew
HorizontalSyncPulse
V-total = VerticalActive + VerticalFrontPorch + VerticalBackPorch + VerticalSyncPulse +
VerticalSyncSkew
Total pixel = H-total x V-total x 60 (Hz)
Bitclk = Total pixel x bpp (byte) x 8/lane number
Byteclk = bitclk/8
Dsipclk = (Byteclk x lane number )/bpp (byte)
有些 case会询问这个使用多少条 lane比较合适。就可以通过以上的计算来给出答案。图 3
是根据分辨率推荐 lane的配置。
图 3
五.Dtsi文件关于 dsi配置部分
5.1 Dtsi的代码如下:
dsi_hx8379a_fwvga_video: qcom,mdss_dsi_hx8379a_fwvga_video { //从 lk传递过来的 panel
name来寻找这个 LCD
驱动
qcom,mdss-dsi-panel-name = "HX8379A fwvga video mode dsi panel";
qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;
qcom,mdss-dsi-panel-type = "dsi_video_mode"; //选择video或者 cmd模式
qcom,mdss-dsi-panel-destination = "display_1";
qcom,mdss-dsi-panel-framerate = <60>;//帧率
qcom,mdss-dsi-virtual-channel-id = <0>;
qcom,mdss-dsi-stream = <0>;
qcom,mdss-dsi-panel-width = <480>;
qcom,mdss-dsi-panel-height = <854>;
LCD分辨率
qcom,mdss-dsi-h-front-porch = <100>;
qcom,mdss-dsi-h-back-porch = <94>;
qcom,mdss-dsi-h-pulse-width = <40>;
qcom,mdss-dsi-h-sync-skew = <0>;
qcom,mdss-dsi-v-back-porch = <4>;
qcom,mdss-dsi-v-front-porch = <6>;
qcom,mdss-dsi-v-pulse-width = <6>;
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>;
LCD的 porch值,panel的厂家提供
LCD垂直和水平的边界,修改这个可
规避边界有线条的问题
qcom,mdss-dsi-bpp = <24>; //LCD的位数,高通建议使用 24bit
qcom,mdss-dsi-color-order = "rgb_swap_rgb";//rgb的颜色转换
qcom,mdss-dsi-underflow-color = <0xff>;//当出现underrun时,可通过修改这个值,
来确定是否是 underrun
qcom,mdss-dsi-border-color = <0>;
qcom,mdss-dsi-on-command = [
………………
05 01 00 00 96 00 02
11 00
05 01 00 00 0A 00 02
29 00
];//LCD的初始化命令
qcom,mdss-dsi-off-command = [05 01 00 00 32 00 02 28 00
05 01 00 00 78 00 02 10 00];//lcd suspend的命令
qcom,mdss-dsi-on-command-state = "dsi_lp_mode";
qcom,mdss-dsi-off-command-state = "dsi_hs_mode";
qcom,mdss-dsi-h-sync-pulse = <1>;
qcom,mdss-dsi-traffic-mode = "burst_mode";
qcom,mdss-dsi-lane-map = "lane_map_3012";
qcom,mdss-dsi-bllp-eof-power-mode; //保持和lk一致
qcom,mdss-dsi-bllp-power-mode;
qcom,mdss-dsi-lane-0-state;//lane的状态,这个 panel是 2条 lane
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-panel-timings = [8B 1f 14 00 45 4A 19 23 23 03 04 00];//timing
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1D>;
qcom,mdss-dsi-bl-min-level = <1>;
qcom,mdss-dsi-bl-max-level = <255>;
qcom,mdss-dsi-dma-trigger = "trigger_sw";
qcom,mdss-dsi-mdp-trigger = "none";
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 = <&pm8916_mpps 4 0>;
qcom,mdss-dsi-reset-sequence = <1 20>, <0 2>, <1 20>;//reset的时序
};
};
Kernel中 dtsi的配置大部分是在 dtsi中可以找到。
5.2 panel_vendor.h的配置
进入 device/qcom/common/display/tools中,将配置好的 dtsi文件中的参数写入到
panel_vendor.xml中,然后运行命令#perl parser.pl panel_vendor.xml panel,通过这个命令会
生成 dsi_panel_vendor.dtsi文件和 panel_vendor.h文件。Panel_vendor.h文件就是我们需要的
在 lk中的配置文件。注意检查该文件中的参数要和 panel保持一致。
很多 panel需要平台这边提供的 dsi特性,在 lk中是不在 panel_vendor.h中配置的。
在 bootable/bootloader/lk/platform/msm_shared /mipi_dsi.c文件中的 config_dsi_video_mode
函数中配置:
Int config_dsi_video_mode(unsigned short disp_width, unsigned short disp_height,
unsigned short img_width, unsigned short img_height,
unsigned short hsync_porch0_fp,
unsigned short hsync_porch0_bp,
unsigned short vsync_porch0_fp,
unsigned short vsync_porch0_bp,
unsigned short hsync_width,
unsigned short vsync_width, unsigned short dst_format,
unsigned short traffic_mode, unsigned short datalane_num)
{
unsigned char DST_FORMAT;
unsigned char TRAFIC_MODE;
unsigned char DLNx_EN;
// video mode data ctrl
int status = 0;
unsigned long low_pwr_stop_mode = 0;
unsigned char eof_bllp_pwr = 0x9;
unsigned char interleav = 0;
// disable mdp first
mdp_disable();
writel(0x00000000, DSI_CLK_CTRL);
writel(0x00000000, DSI_CLK_CTRL);
writel(0x00000000, DSI_CLK_CTRL);
writel(0x00000000, DSI_CLK_CTRL);
writel(0x00000002, DSI_CLK_CTRL);
writel(0x00000006, DSI_CLK_CTRL);
writel(0x0000000e, DSI_CLK_CTRL);
writel(0x0000001e, DSI_CLK_CTRL);
writel(0x0000003e, DSI_CLK_CTRL);
writel(0, DSI_CTRL);
writel(0x13ff3fe0, DSI_ERR_INT_MASK0);
DST_FORMAT = 0;
// RGB565
dprintf(SPEW, "DSI_Video_Mode - Dst Format: RGB565\n");
DLNx_EN = 1;
// 1 lane with clk programming
dprintf(SPEW, "Data Lane: 1 lane\n");
TRAFIC_MODE = 0; // non burst mode with sync pulses
dprintf(SPEW, "Traffic mode: non burst mode with sync pulses\n");
writel(0x02020202, DSI_INT_CTRL);
writel(((hsync_width + img_width + hsync_porch0_bp) << 16)
| (hsync_width + hsync_porch0_bp),
DSI_VIDEO_MODE_ACTIVE_H);
writel(((vsync_width + img_height + vsync_porch0_bp) << 16)
| (vsync_width + vsync_porch0_bp),
DSI_VIDEO_MODE_ACTIVE_V);
writel(((vsync_width + img_height + vsync_porch0_fp + vsync_porch0_bp - 1) << 16)
| (hsync_width + img_width + hsync_porch0_fp + hsync_porch0_bp - 1),
DSI_VIDEO_MODE_TOTAL);
writel((hsync_width << 16) | 0, DSI_VIDEO_MODE_HSYNC);
writel(0 << 16 | 0, DSI_VIDEO_MODE_VSYNC);
writel(vsync_width << 16 | 0, DSI_VIDEO_MODE_VSYNC_VPOS);
writel(1, DSI_EOT_PACKET_CTRL);
writel(0x00000100, DSI_MISR_VIDEO_CTRL);
writel(low_pwr_stop_mode << 16 | eof_bllp_pwr << 12 | TRAFIC_MODE << 8
| DST_FORMAT << 4 | 0x0, DSI_VIDEO_MODE_CTRL); //lk和 kernel的显示不
一致,问题大多出现在这里。Lk的显示异常的问题,大多可以在这个地方修改解决。
writel(0x67, DSI_CAL_STRENGTH_CTRL);
writel(0x80006711, DSI_CAL_CTRL);
writel(0x00010100, DSI_MISR_VIDEO_CTRL);
writel(0x00010100, DSI_INT_CTRL);
writel(0x02010202, DSI_INT_CTRL);
writel(0x02030303, DSI_INT_CTRL);
writel(interleav << 30 | 0 << 24 | 0 << 20 | DLNx_EN << 4
| 0x103, DSI_CTRL);
mdelay(10);
return status;
}
5.3 dsi问题
Dsi出现的问题一般都是在 ESD、display异常、中断报错等。
5.3.1 display异常
有些客户使用的 panel对于 dsi有特殊的要求,如果没有按照 panel的要求来设置,
会造成显示的异常,例如:LCD底部有白线、会有概率性唤不醒 panel、花屏等。
1)添加下面的代码到 dtsi文件中可以 fix这个 LCD底部有白线的问题:
qcom,mdss-dsi-hfp-power-mode
qcom,mdss-dsi-hbp-power-mode
qcom,mdss-dsi-hsa-power-mode
2)修改如下代码可保持 clk连续 hs:
在 kernel display, mdss_dsi.c文件中, mdss_dsi_on函数:
+++ mipi->force_clk_lane_hs = 1; //强制 HS mode
if (mipi->force_clk_lane_hs)
{
tmp = MIPI_INP((ctrl_pdata->ctrl_base) + 0xac);
tmp |= (1<<28);
MIPI_OUTP((ctrl_pdata->ctrl_base) + 0xac, tmp);
wmb();
}
在 LK display, mipi_dsi.c文件中, mdss_dsi_host_init函数:
writel(broadcast << 31 | EMBED_MODE1 << 28 | POWER_MODE2 << 26
| PACK_TYPE1 << 24 | VC1 << 22 | DT1 << 16 | WC1 ,
MIPI_DSI0_BASE + COMMAND_MODE_DMA_CTRL);
+++ writel(1 << 28, MIPI_DSI0_BASE + 0xac); //强制 HS mode,
writel(lane_swap, MIPI_DSI0_BASE + LANE_SWAP_CTL);
3)DSI的驱动能力 LP mode可以从软件去调节,而 HS mode则不能从软件层面去调
节。从软件角度, LP mode可以调节,如下:
对于 MSM8916,在文件 msm8916-mdss.dtsi中
qcom,platform-strength-ctrl = [ff 06]; // [DSIPHY_STR_LP_N, DSIPHY_STR_LP_P]
对应的寄存器为 0x01A98684 MDSS_DSI_0_PHY_DSIPHY_STRENGTH_CTRL_0
从软件角度, HS mode不可以调节,一般都是通过硬件去调节 PCB的阻抗匹配。
5.3.2中断报错
经常会有客户提出,中断报错的问题。一般都是 mdss_dsi_error()这个函数
报错了,也就是 dsi出了问题,在 ESD的时候比较经常出现。通过在 dtsi文件中添
加一些 flag可以解决这问题。但是这个问题出现时,可以先去查一下寄存器,看看
具体是哪个寄存器出问题了,可以有针对性的解决这个问题。
一般都是在 ESD的时候,下图这个寄存器中断报错了。根据具体的报错信息
去确定问题。