mipi转lvds芯片GM877C使用参考


1. 用户需求

  1. Takoyaki需要点LVDS panel,只支持TTL and MIPI 接口。

  2. 根据需求选用外围器件GM877C做mipi2lvds转换,间接点LVDS panel。

  3. 用户A需要点的lvds panel为960X1280分辨率。

  4. 用户B需要点的lvds panel为1920X1080分辨率。


2. 公版状态

  1. 公版mi panel owner之前已经用GM877C点过lvds panel,已经有base code。

  2. 对应屏参给到用户,用户反馈没有作用。

  3. 需要进到具体问题分析具体状态。


3. 调试过程

  1. 硬件连接

  2. 调试过程

    1. 根据调试过程的经验来看,首先需要请GM877C的芯片抛开主芯片,来点亮lvds panel确定GM芯片和panle电路是OK的。这部分需要硬件在开始设计的时候板子预留GM的I2C接口和外部晶振接口。这步骤是很重要的,是一定要做的,方便梳理清楚问题。

      这部分可以请用户找GM的人配合调试,如下是用到的工具,GM调试PC工具可以自动生成参数,通过USB2IIC写入GM芯片点亮LVDS panle。

      这里在实际调试过程中有如下注意点:

      通过这个工具write之后,可以通过read看是否写的正确?如果不正确,可以通过单独命令w,0xxx,0xxxx,然后单独命令R,0xxx来确认是否写的正确,如果单独命令正确,有可能是I2C速度太快造成写很多不正确,可以手动一条条的单独写,然后再read,看是否正确,这样就用最简单的方法点亮panel。

      GM8775C_A1.1工具下载

    2. 以上步骤点亮panel之后,就大致确认到GM+panel电路正确,LVDS panel 参数大致OK。我们通过GM的工具切换到"MIPI命令",生成命令参数添加到,注意刚开始点的时候,生成测试命令建议打开测试pattern,如下:

    3. 修改stPanelParam内容,按照panel spec填写。

      MI_PANEL_ParamConfig_t stPanelParam =
      {
      "GM8775C_960x1280", //const char *pPanelName; ///< PanelName
      0, //MI_U8 MI_U8Dither; ///< Diether On?off
      E_MI_PNL_LINK_MIPI_DSI, //MIPnlLinkType_e eLinkType; ///< Panel LinkType
      0, //MI_U8 MI_U8DualPort :1; ///< DualPort on/off
      0, //MI_U8 MI_U8SwapPort :1; ///< Swap Port on/off
      0, //MI_U8 MI_U8SwapOdd_ML :1; ///< Swap Odd ML
      0, //MI_U8 MI_U8SwapEven_ML :1; ///< Swap Even ML
      0, //MI_U8 MI_U8SwapOdd_RB :1; ///< Swap Odd RB
      0, //MI_U8 MI_U8SwapEven_RB :1; ///< Swap Even RB
      0, //MI_U8 MI_U8SwapLVDS_POL :1; ///< Swap LVDS Channel Polairyt
      0, //MI_U8 MI_U8SwapLVDS_CH :1; ///< Swap LVDS channel
      0, //MI_U8 MI_U8PDP10BIT :1; ///< PDP 10bits on/off
      0, //MI_U8 MI_U8LVDS_TI_MODE :1; ///< Ti Mode On/Off
      
      0, //MI_U8 MI_U8DCLKDelay; ///< DCLK Delay
      0, //MI_U8 MI_U8InvDCLK :1; ///< CLK Invert
      0, //MI_U8 MI_U8InvDE :1; ///< DE Invert
      0, //MI_U8 MI_U8InvHSync :1; ///< HSync Invert
      0, //MI_U8 MI_U8InvVSync :1; ///< VSync Invert
      0, //MI_U8 MI_U8DCKLCurrent; ///< PANEL_DCLK_CURRENT
      0, //MI_U8 MI_U8DECurrent; ///< PANEL_DE_CURRENT
      0, //MI_U8 MI_U8ODDDataCurrent; ///< PANEL_ODD_DATA_CURRENT
      0, //MI_U8 MI_U8EvenDataCurrent; ///< PANEL_EVEN_DATA_CURRENT
      0, //u16 u16OnTiming1; ///< time between panel & data while turn on power
      0, //u16 u16OnTiming2; ///< time between data & back light while turn on power
      0, //u16 u16OffTiming1; ///< time between back light & data while turn off power
      0, //u16 u16OffTiming2; ///< time between data & panel while turn off power
      20, //u16 u16HSyncWidth; ///< Hsync Width
      20, //u16 u16HSyncBackPorch; ///< Hsync back porch
      10, //u16 u16VSyncWidth; ///< Vsync width
      10, //u16 u16VSyncBackPorch; ///< Vsync back porch
      0, //u16 u16HStart; ///< HDe start
      0, //u16 u16VStart; ///< VDe start
      960, //u16 u16Width; ///< Panel Width
      1280, //u16 u16Height; ///< Panel Height
      0, //u16 u16MaxHTotal; ///< Max H Total
      1020, //u16 u16HTotal; ///< H Total
      0, //u16 u16MinHTotal; ///< Min H Total
      0, //u16 u16MaxVTotal; ///< Max V Total
      1320, //u16 u16VTotal; ///< V Total
      0, //u16 u16MinVTotal; ///< Min V Total
      0, //u16 u16MaxDCLK; ///< Max DCLK
      81, //u16 u16DCLK; ///< DCLK ( Htt * Vtt * Fps)
      0, //u16 u16MinDCLK; ///< Min DCLK
      0, //u16 u16SpreadSpectrumStep; ///< Step of SSC
      0, //u16 u16SpreadSpectrumSpan; ///< Span of SSC
      0, //MI_U8 MI_U8DimmingCtl; ///< Dimming Value
      0, //MI_U8 MI_U8MaxPWMVal; ///< Max Dimming Value
      0, //MI_U8 MI_U8MinPWMVal; ///< Min Dimming Value
      0, //MI_U8 MI_U8DeinterMode :1; ///< DeInter Mode
      E_MI_PNL_ASPECT_RATIO_WIDE, //MIPnlAspectRatio_e ePanelAspectRatio; ///< Aspec Ratio
      0, //u16 u16LVDSTxSwapValue; // LVDS Swap Value
      E_MI_PNL_TI_8BIT_MODE, //MIPnlTiBitMode_e eTiBitMode; // Ti Bit Mode
      E_MI_PNL_OUTPUT_8BIT_MODE, //MIPnlOutputFormatBitMode_e eOutputFormatBitMode;
      0, //MI_U8 MI_U8SwapOdd_RG :1; ///< Swap Odd RG
      0, //MI_U8 MI_U8SwapEven_RG :1; ///< Swap Even RG
      0, //MI_U8 MI_U8SwapOdd_GB :1; ///< Swap Odd GB
      0, //MI_U8 MI_U8SwapEven_GB :1; ///< Swap Even GB
      0, //MI_U8 MI_U8DoubleClk :1; ///< Double CLK On/off
      0x0, //u32 u32MaxSET; ///< Max Lpll Set
      0x0, //u32 u32MinSET; ///< Min Lpll Set
      E_MI_PNL_CHG_VTOTAL, //MIPnlOutputTimingMode_e eOutTimingMode; ///< Define which panel output timing change mode is used to change VFreq for same panel
      0, //MI_U8 MI_U8NoiseDith :1; ///< Noise Dither On/Off
      (MI_PANEL_ChannelSwapType_e)2,
      (MI_PANEL_ChannelSwapType_e)4,
      (MI_PANEL_ChannelSwapType_e)3,
      (MI_PANEL_ChannelSwapType_e)1,
      (MI_PANEL_ChannelSwapType_e)0,
      };
      
    4. 修改stMipiDsiConfig,主要修改//HsTrail HsPrpr HsZero ClkHsPrpr ClkHsExit ClkTrail ClkZero ClkHsPost DaHsExit ,按照规格重新算一遍:

      注意mipi的chanel swap和p/n swap是否和公版的线序一样是否要做调整?

      MI_PANEL_MipiDsiConfig_t stMipiDsiConfig =
      {
      //HsTrail HsPrpr HsZero ClkHsPrpr ClkHsExit ClkTrail ClkZero ClkHsPost DaHsExit ContDet
      0x05, 0x05, 0x06, 0x07, 0x0D, 0x06, 0x0E, 0x0B, 0x07, 0x00,
      //Lpx TaGet TaSure TaGo
      0x10, 0x1A, 0x18, 0x32,
      //Hac, Hpw, Hbp, Hfp, Vac, Vpw, Vbp, Vfp, Bllp, Fps
      960, 20, 20, 20, 1280, 10, 10, 20, 0, 60,
      E_MI_PNL_MIPI_DSI_LANE_4, // MIPnlMipiDsiLaneMode_e enLaneNum;
      E_MI_PNL_MIPI_DSI_RGB888, // MIPnlMipiDsiFormat_e enFormat;
      E_MI_PNL_MIPI_DSI_SYNC_PULSE, // MIPnlMipiDsiCtrlMode_e enCtrl;
      GM8775C_CMD,
      sizeof(GM8775C_CMD),
      1, 0x01AF, 0x01B9, 0x80D2, 7,
      0,0,0,0,0,1,
      };
      
    5. 如何配置HS定时参数

    6. 如何配置LP定时参数

    mipi相关参数计算表格

    1. 屏参合入之后,程序运行之前,检查相关寄存器和GPIO是否设置正确,例如用户这块panel,因为用的是ttl的程序点的, 先要/config/riu_w 101e 0xd 0x1000 pin demux设置正确, 然后因为硬件需要把如下gpio设置为高,先要设置如下GPIO,根据用户硬件不同,是不一样的。

      echo 4 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio4/direction
      echo 1 > /sys/class/gpio/gpio4/value
      echo 19 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio19/direction
      echo 1 > /sys/class/gpio/gpio19/value
      echo 10 > /sys/class/gpio/export
      echo out > /sys/class/gpio/gpio10/direction
      echo 1 > /sys/class/gpio/gpio10/value
      
    2. 运行demo,查看屏幕是否正常。

    3. 屏幕正常之后,关闭GM的测试PATTERN,去掉GM芯片的外围晶振,再来看是否正常。注意mipi时钟要调正确:

      Pixel CLK:像素时钟 

      MIPI CLK:MIPI时钟 

      LVDS CLK:LVDS时钟

      像素时钟的计算方式为:

      Pixel CLK=(H Total * V Total) * FPS

      MIPI时钟的计算方式根据MIPI数据输入时所用的通道LANE的数量决定。

      即Mipiclock = [ (width+hsync+hfp+hbp) x (height+vsync+vfp+vbp) ] x(bus_width) x fps/ (lane_num)/2。

      即mipi 屏的传输时钟频率(CLKN,CLKP)等于(屏幕分辨率宽width+hsync+hfp+hbp)x (屏幕分辨率高height+vsync+vfp+vbp) x(RGB显示数据宽度) x 帧率/ (lane_num)/2。

      在这里除以2是因为MIPI时钟的触发方式为双边沿触发。

      GM8775C,输出端LVDS像素时钟为:Pixel CLK=(H Total * V Total) * FPS

      对于LVDS CLK来说,当输出为单通道的LVDS信号时,LVDS CLK和它的像素时钟相等。当输出为双通道的LVDS信号时,LVDS CLK是它的像素时钟的一半。

    4. 对于用户960X1280这块panel,实际调试的时候发现屏幕闪,把stPanelParam.u16HStart,stPanelParam.u16VStart设置为0,再来看,画面正常。