Qualcomm DragonBoard 410c Display之DSI浅析

时间:2024-05-19 21:27:55

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及其作用

 

Qualcomm DragonBoard 410c Display之DSI浅析

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和无线电干扰更小。

Qualcomm DragonBoard 410c Display之DSI浅析

但是目前来说,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要求的

时序的要求。

  Qualcomm DragonBoard 410c Display之DSI浅析

 

                                                                                                  图 1

                                                Qualcomm DragonBoard 410c Display之DSI浅析

                                                                                                   图 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的配置。

  Qualcomm DragonBoard 410c Display之DSI浅析

                                                                                                    图 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的时候,下图这个寄存器中断报错了。根据具体的报错信息

去确定问题。

  

  Qualcomm DragonBoard 410c Display之DSI浅析