高通调试 SPI 屏的 bug

1. spi调试问题:

问题描述: spi屏幕lk启动的时候正常出现小企鹅,到kernel启动的过程黑屏并且花屏才到开机动画;

2. 黑屏的三个阶段:

参照:黑屏分析 分析开机过程黑屏,首先需要定位黑屏问题发生的时间段,开机过程中涉及到显示logo 或者是播放动画的主要有如下三个阶段:

  • 显示 lk logo ;
  • 显示kernel logo;
  • 开机动画 Bootanimation 如下这张ENG 版本开机过程显示图,说明了主要的三个过程:

如下解释: (阶段1)、带有”normal boot“的lk logo,会在lk阶段显示。显示时间一般1s左右。 (阶段2)、启动到kernel的前7s左右,显示的是带”normal boot“字样的lk logo。(这里L/M版本和KK/JB版本很不同,不在此处细说) (阶段3)、之后显示kernel logo的时间段很短,一般只有2s左右. (阶段4)、显示bootanimation动画。

3. 调试过程:

如上所示,我们是在(阶段一)(阶段二)之间黑屏,这时候要看一下lk中DEFINES += DISPLAY_SPLASH_SCREEN = 1 的宏有没有打开;(target/xxx/rules.mk),再将qcom,cont-splash-enabled增加到你对应厂商的屏代码的设备树中;

重新烧录软件,开机;

依然出现问题: 我们这时候发现lk到kernel的第二阶段已经完全正常了,但是又出现问题。。。这时候kernel的开机动画出现抖动,并且无法正常显示(第三阶段);关键来了,灭屏后,一切屏幕正常; 这时候,我已经开始怀疑lk和kernel的spi屏初始化代码有区别:

将lk代码修改为kernel中的初始化代码,结果lk也有问题,出现不断的抖动和闪烁;于是,我只能接受spi 屏kernel和lk初始化代码不一样的结论了;但问题是为什么我们第三阶段已经属于我们kernel启动的时候了,但是为什么没有初始化呢?(灭屏后再次开启已经启用了resume了);

读源码吧: 找到我们kernel源码中的qcom,mdss-spi-on-command节点,在解析设备树用到的,最后我们定位在mdss_spi_panel_on函数中初始化:

int mdss_spi_panel_on(struct mdss_panel_data *pdata)
{
    struct spi_panel_data *ctrl = NULL;
    struct mdss_panel_info *pinfo;
    int i;

    if (pdata == NULL) {
        pr_err("%s: Invalid input data\n", __func__);
        return -EINVAL;
    }
    pinfo = &pdata->panel_info;
    ctrl = container_of(pdata, struct spi_panel_data,
                panel_data);

    for (i = 0; i < ctrl->on_cmds.cmd_cnt; i++) {
        mdss_spi_tx_command(ctrl->on_cmds.cmds[i].command);

        if (ctrl->on_cmds.cmds[i].dchdr.dlen > 1) {
            mdss_spi_tx_parameter(ctrl->on_cmds.cmds[i].parameter,
                    ctrl->on_cmds.cmds[i].dchdr.dlen-1);
        }
        if (ctrl->on_cmds.cmds[i].dchdr.wait != 0)
            msleep(ctrl->on_cmds.cmds[i].dchdr.wait);
    }

    pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
    pr_debug("%s:-\n", __func__);

    return 0;
}

增加log打印,最后判断在第三阶段中上述函数中并没有被调用到,而是由lk的初始化代码一直维持屏的状态; 在mdss_spi_panel_init函数中,注册了相应的回调函数:

int mdss_spi_panel_init(struct device_node *node,
    struct spi_panel_data   *ctrl_pdata,
    bool cmd_cfg_cont_splash)
{
    int rc = 0;
    static const char *panel_name;
    struct mdss_panel_info *pinfo;
    
    if (!node || !ctrl_pdata) {
        pr_err("%s: Invalid arguments\n", __func__);
        return -ENODEV;
    }

    pinfo = &ctrl_pdata->panel_data.panel_info;

    .......
    ctrl_pdata->on = mdss_spi_panel_on;
    ctrl_pdata->off = mdss_spi_panel_off;
    ctrl_pdata->panel_data.set_backlight = mdss_spi_panel_bl_ctrl;

    return 0;
}

而这个回调函数是在什么时候作用到的呢?

mdss_spi_panel_unblank函数中:

static int mdss_spi_panel_unblank(struct mdss_panel_data *pdata)
{
    int ret = 0;
    struct spi_panel_data *ctrl_pdata = NULL;

    if (pdata == NULL) {
        pr_err("%s: Invalid input data\n", __func__);
        return -EINVAL;
    }

    ctrl_pdata = container_of(pdata, struct spi_panel_data,
                panel_data);

//  if (!(ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT)) {

    ret = ctrl_pdata->on(pdata);
    if (ret) {
        pr_err("%s: unable to initialize the panel\n",
                    __func__);
        return ret;
    }
    ctrl_pdata->ctrl_state |= CTRL_STATE_PANEL_INIT;
//  }

    return ret;
}

修改后,patch地址: patch地址 开机正常,spi正常,一切正常;

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏DOTNET

.Net多线程编程—使用Visual Studio 2012进行调试

1 相关概念 1)栈帧 C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。 栈帧也叫过程活动记录,是编译器用来实现过程/函数调...

33613
来自专栏向治洪

使用LRU算法缓存图片,android 3.0

在您的UI中显示单个图片是非常简单的,如果您需要一次显示很多图片就有点复杂了。在很多情况下 (例如使用 ListView, GridView 或者 View...

1758
来自专栏小筱月

script 标签的属性、事件的探究

有 async 没有 defer 时,会与渲染后续文档元素并行加载(加载过程不会阻塞 dom 解析),加载完自动执行(执行会阻塞 dom 解析)

582
来自专栏bboysoul

解决esxi主机vmware 无法清除磁盘的报错

今天新安装了esxi主机,这台服务器中有四块硬盘,当然我是把系统安装在u盘上的,在此之前这台服务器安装的是zstack,zstack是安装在四块硬盘中的其中一块...

784
来自专栏GuZhenYin

Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下Si...

3469
来自专栏向治洪

Android逆向工程

在Root前提下,我们可以使用Hooker方式绑定so库,通过逆向方式篡改数值,从而达到所谓破解目的。然而,目前无论是软件加固方式,或是数据处理能力后台化,还是...

23410
来自专栏Linux驱动

21.Linux-写USB键盘驱动(详解)

本节目的:     根据上节写的USB鼠标驱动,来依葫芦画瓢写出键盘驱动 1.首先我们通过上节的代码中修改,来打印下键盘驱动的数据到底是怎样的 先来回忆下,我们...

1949
来自专栏非著名程序员

常见面试第四题之requestLayout, invalidate和postInvalidate的异同

requestLayout, invalidate和postInvalidate的异同 ? 今天我们来讲讲在面试当中最常见的,最常常被问到的第四题,近期由于小...

2205
来自专栏编程微刊

验证码倒计时的注册页面

1032
来自专栏跟着阿笨一起玩NET

C# TreeView使用技巧

代码中对事件参数e.Action的判断,可以避免在改变节点的Checked的状态时,再次进入AfterCheck(),这样当在AfterCheck()中有其他逻...

542

扫码关注云+社区