RK3399 Android7.1调试LT9211

文章详细介绍了如何使用LT9211芯片在RK3399平台上实现MIPI到LVDS的转换,包括DTS配置、内核驱动代码和uboot驱动的添加。在调试过程中,解决了屏幕唤醒慢、图像抖动和开机不显示等问题,主要通过优化LT9211的寄存器配置和确保驱动在启动流程中的正确加载顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LT9211是龙讯的一款MIPI转LVDS的芯片,因RK3399没有LVDS接口,所以使用这颗芯片用来接LVDS的显示屏。连接关系简化如下:

https://i-blog.csdnimg.cn/blog_migrate/54b04fdf706307e964e26b45fd73affd.png

对RK3399主控来讲,LT9211就相当于是一款MIPI显示屏,所以我们设置屏参的时候就是按照MIPI屏的配置修改DTS的。如下:

&dsi {
    status = "okay";
    rockchip,lane-rate = <500>;
    panel@0 {
        compatible ="simple-panel-dsi";
        reg = <0>;
        backlight = <&backlight>;
    enable-gpios = <&gpio3 2 GPIO_ACTIVE_HIGH>;
        reset-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
                  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;//NG
        dsi,format = <MIPI_DSI_FMT_RGB888>;
        dsi,lanes = <4>;
        status = "okay";
        prepare-delay-ms = <20>;
        reset-delay-ms = <20>;
        init-delay-ms = <20>;
        enable-delay-ms = <20>;
        disable-delay-ms = <20>;
        unprepare-delay-ms = <120>;
        display-timings {
            native-mode = <&timing1>;

            timing1: timing1 {
                clock-frequency = <69000000>;
                hactive = <1280>;
                vactive = <800>;
                hback-porch = <20>;
                hfront-porch = <40>;
                vback-porch = <12>;
                vfront-porch = <24>;
                hsync-len = <8>;
                vsync-len = <10>;
                de-active = <0>;
                hsync-active = <0>;
                vsync-active = <0>;
                pixelclk-active = <0>;
            };
        };
    };
};

​另外,内核中需要添加LT9211的驱动代码,LT9211通过i2c与RK3399主控进行通信,驱动中的主要内容就是对LT9211的寄存器进行配置,对它初始化,让它可以将输入的MIPI信号转为LVDS信号点亮屏幕。驱动中的主要内容如下:

void lt9211_init(struct i2c_client *client)

{

                                 LT9211_ChipID(client);

                                 LT9211_SystemInt(client);

                                 LT9211_MipiRxPhy(client);

                                 LT9211_MipiRxDigital(client);

                                 LT9211_TimingSet(client);

                                 LT9211_MipiRxPll(client);

                                 LT9211_MipiPcr(client);           

                                 LT9211_TxDigital(client);

                                 LT9211_TxPhy(client);

#if LT9211_OUTPUT_PATTERN

                                 LT9211_Pattern(&video_1280x800_60Hz,client);

#endif

                                 mdelay(10);

                                 LT9211_Txpll(client);

                                 LT9211_RXCSC(client);

                                 LT9211_ClockCheckDebug(client);

                                 LT9211_VideoCheckDebug(client);

                                 LT9211_BT_Set(client);

}

在每次点屏的时候都会跑这个初始化函数,具体位置如下:

static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)

{

                                 struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);

                                 unsigned long lane_rate = dw_mipi_dsi_get_lane_rate(dsi);

                                 if (dsi->dphy.phy)

                                   dw_mipi_dsi_set_hs_clk(dsi, lane_rate);

                                 else

                                   dw_mipi_dsi_set_pll(dsi, lane_rate);

                                 dev_info(dsi->dev, "final DSI-Link bandwidth: %u x %d Mbps\n",

                                    dsi->lane_mbps, dsi->slave ? dsi->lanes * 2 : dsi->lanes);

                                 dw_mipi_dsi_vop_routing(dsi);

                                 dw_mipi_dsi_pre_enable(dsi);

                                 if (dsi->panel)

                                   drm_panel_prepare(dsi->panel);

                                 dw_mipi_dsi_enable(dsi);

                                 if (dsi->panel)

                                   drm_panel_enable(dsi->panel);

                                 printk("dw_mipi_dsi lt9211_init\n");      

                                 msleep(100);

                                 lt9211_init(g_client_lt9211);  

}

除内核中添加LT9211驱动代码外,uboot中也需要添加LT9211的代码,驱动代码内容是一样的,只需要按照uboot驱动的编写格式移植到uboot中就行了。uboot中lt9211_init函数的具体位置如下:

static int display_enable(struct display_state *state)

{

                                 const struct rockchip_connector *conn = state->conn_state.connector;

                                 const struct rockchip_crtc *crtc = state->crtc_state.crtc;

                                 const struct rockchip_connector_funcs *conn_funcs = conn->funcs;

                                 const struct rockchip_crtc_funcs *crtc_funcs = crtc->funcs;

                                 int ret = 0;

                                 display_init(state);

                                 if (!state->is_init)

                                   return -EINVAL;

                                 if (state->is_enable)

                                   return 0;

                                 if (crtc_funcs->prepare) {

                                   ret = crtc_funcs->prepare(state);

                                   if (ret)

                                            return ret;

                                 }

                                 if (conn_funcs->prepare) {

                                   ret = conn_funcs->prepare(state);

                                   if (ret)

                                            goto unprepare_crtc;

                                 }

                                 rockchip_panel_prepare(state);

                                 if (crtc_funcs->enable) {

                                   ret = crtc_funcs->enable(state);

                                   if (ret)

                                            goto unprepare_conn;

                                 }

                                 if (conn_funcs->enable) {

                                   ret = conn_funcs->enable(state);

                                   if (ret)

                                            goto disable_crtc;

                                 }

                                

                                 lt9211_init();

                                 rockchip_panel_enable(state);

                                

                                 state->is_enable = true;

                                 return 0;

unprepare_crtc:

                                 if (crtc_funcs->unprepare)

                                   crtc_funcs->unprepare(state);

unprepare_conn:

                                 if (conn_funcs->unprepare)

                                   conn_funcs->unprepare(state);

disable_crtc:

                                 if (crtc_funcs->disable)

                                   crtc_funcs->disable(state);

                                 return ret;

}

调试中遇到的问题:

1,熄屏后按电源键唤醒屏幕显示很慢(约2秒钟),且在唤醒瞬间有时会有条纹状闪现。

解决:修改LT9211_MipiPcr的寄存器配置,改为如下配置:

void LT9211_MipiPcr(struct i2c_client *client)

{                               

                                 u8 loopx;

                                 u8 pcr_m;

                                

  LT9211_mipi_write(client,0xff,0xd0);     

  LT9211_mipi_write(client,0x0c,0x60); 

                                 LT9211_mipi_write(client,0x1c,0x60); 

                                 LT9211_mipi_write(client,0x24,0x70); 

                                           

                                 LT9211_mipi_write(client,0x2d,0x30);

                                 LT9211_mipi_write(client,0x31,0x01);

                                 /*stage1 hs mode*/

                                 LT9211_mipi_write(client,0x25,0xd0); 

                                 LT9211_mipi_write(client,0x2a,0x30);

                                 LT9211_mipi_write(client,0x21,0x4f); 

                                 LT9211_mipi_write(client,0x22,0x00);

                                 /*stage2 hs mode*/

                                 LT9211_mipi_write(client,0x1e,0x01); 

                                 LT9211_mipi_write(client,0x23,0x80); 

    /*stage2 de mode*/

                                 LT9211_mipi_write(client,0x0a,0x02);

                                 LT9211_mipi_write(client,0x38,0x02);

                                 LT9211_mipi_write(client,0x39,0x04);

                                 LT9211_mipi_write(client,0x3a,0x08);

                                 LT9211_mipi_write(client,0x3b,0x10);

                                  

                                 LT9211_mipi_write(client,0x3f,0x04);

                                 LT9211_mipi_write(client,0x40,0x08);

                                 LT9211_mipi_write(client,0x41,0x10);

                                 LT9211_mipi_write(client,0x42,0x20);

                                 LT9211_mipi_write(client,0x2b,0xa0);

    LT9211_mipi_write(client,0xff,0xd0);  

                                 pcr_m = LT9211_read(client,0x26);

                                 pcr_m &= 0x7f;

                                 LT9211_mipi_write(client,0x26,pcr_m);

                                 LT9211_mipi_write(client,0x27,0x0f);

                                 LT9211_mipi_write(client,0xff,0x81);

                                 LT9211_mipi_write(client,0x20,0xbf);

                                 LT9211_mipi_write(client,0x20,0xff);

                                 msleep(5);

                                 LT9211_mipi_write(client,0x0B,0x6F);

                                 LT9211_mipi_write(client,0x0B,0xFF);

                                

                                 msleep(100);//800->120

                                 {

                                   for(loopx = 0; loopx < 20; loopx++)

                                   {

                                            msleep(100);

                                            LT9211_mipi_write(client,0xff,0xd0);

                                            if(LT9211_read(client,0x87)&0x08)

                                            {

                                                     printk("\r\nLT9211 pcr stable\n");

                                                     break;

                                            }

                                            else

                                            {

                                                     printk("\r\nLT9211 pcr unstable!!!!");

                                            }

                                         }

                               }

                                

                                 LT9211_mipi_write(client,0xff,0xd0);

                                 printk("LT9211 pcr_stable_M=%x\n",(LT9211_read(client,0x94)&0x7F));//打印M值

}

2,点亮屏幕后概率性图像剧烈抖动

原因:实际使用的为单LVDS屏,LT9211寄存器配置为双LVDS屏

解决:修改寄存器配置,如下:

LT9211_TxDigital函数中修改如下:

if( LT9211_OutPutModde == OUTPUT_LVDS_2_PORT )

                                   {

                                            LT9211_mipi_write( client,0x5c,0x01);

                                   }

                                   else

                                   {

                                            LT9211_mipi_write( client,0x5c,0x00);

                                   }

和LT9211_TxPhy函数中修改如下:

if(LT9211_OutPutModde == OUTPUT_LVDS_2_PORT)

                                   {

                                   LT9211_mipi_write( client,0x3b,0xb8);

                                   }

                                   else

                                   {

                                   LT9211_mipi_write( client,0x3b,0x38);

                                   }

3,开机概率性不显示,日志打印可看出有如下打印:

[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 1.589547] LT9211 pcr unstable!!!!
[ 2.637270] LT9211 pcr unstable!!!!
[ 2.637270] LT9211 pcr unstable!!!!LT9211 pcr_stable_M=24

原因:MIPI信号时序不对

解决:之前只在内核中加载了LT9211驱动,也就是lt9211_init执行的较晚。解决方法就是在uboot中也添加lt9211驱动。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值