查看: 3629|回复: 0

uboot屏幕适配源码解析

[复制链接]
  • TA的每日心情
    开心
    2024-11-20 21:23
  • 签到天数: 597 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2018-8-9 13:44:23 | 显示全部楼层 |阅读模式
    分享到:
    uboot屏幕适配源码解析,从源头开始追踪,一直到追踪完为止,本篇有点长,连贯一气呵成也还不错。
    uboot屏幕适配的源码源头从这个函数开始 stdio_add_devices追踪,稍后写一篇 uboot 源码完全追踪,会有 uboot 整个完整代码追踪注释,从执行的第1条指令到最后一条指令,能看到这个函数的。这里看到的严格来说是函数指针数组的 stdio_add_devices 项,他是个函数指针,函数入口,执行他就是执行 stdio_add_devices(void) 函数:

    打开这个函数,前面的代码和lcd屏幕没啥关系看一眼掠过:


    上面这个 drv_video_init() 才开始和 lcd 屏幕有关,打开它看看:

    打开这个board_video_skip() 函数,暂时先看这个函数,先看第一部分:

    首先获取环境变量 panel,有的话直接把这个名字提取出来,没有的话,逐个检测 displays,检测到了把名字提取出来,同时把索引保存到 i 变量中, i 在整个函数内有效,检测不到,i=0,意思就是第一个 displays 实例作为默认屏幕。displays 就是上一篇添加的屏幕实例。
    (上一篇文章中,可以把自己的displays实例放在第一的位置,panel 环境变量直接去掉不要,也行。)
    display_count 是 displays 实例的个数,就是你有几个屏幕实例,他给你遍历

    再看那个函数第二部分:

    打开这个函数mxs_lcd_panel_setup() :

    上一篇文章中的添加的displays实例中的 .bus / .pixfmt / .mode 三个成员变量全部提取走了,保存到 fbmode,depth,panel 中,记住这三个变量,稍后分析。还剩一个.enable 变量,这个后面也会用到。

    这个panel 变量,看看是个啥:
    Panel 变量:

    Panel结构体:第一个成员变量 isaBase 是 lcdc 基地址

    继续看那个函数的第三部分,enable 用上了,检查一下enable存在的话,就执行 enable 这个函数,displays+i 就是刚才找到的displays 实例,存在 i 变量中,现在使用这个 i

    看这个enable 函数具体干了哪些事情:

    • 1,使用 .bus 成员变量,开启总线时钟


    • 2,设置pads,就是配置soc 的管脚


    • 3,(看注释) 复位 LCD,打开背光

    看一下 5.9 / 1.8 这两个pads,看原理图:
    1.8 是这个 pads,LCD_PWM,调亮度背光的,和上面注释一样

    5.9  没找到,1(A),2(B),3(C),4(D),5(E),59=E9,应该是这个:LCD_RESET

    这两个pads直接引出到 LCD 接口:



    接着看另一个函数video_init():

    打开看这个函数的第一部分:

    有个 video_hw_init() 函数,打开看,上面 fbmod,depth,panel 三个变量保存的东西,经过了一堆赋值和计算,保存到了mode,bpp,panel 中,



    看上图最后一个函数 mxs_lcd_init(&panel, &mode, bpp); 同时给他传入三个参数,这三个参数可是涵盖了我们 displays 实例中的几乎所有参数,这个函数很重要,几乎就是所有了,进去看看做了什么:
    1,设置时钟,reset 新时钟生效

    2,根据 bpp 的值,有多种计算方法,算出三个变量的值

    3,写寄存器,各种写寄存器


    这个函数就是读写寄存器,把displays 实例里面的参数,全部写入 soc 生效。
    具体如何写,写的什么,这个问题查查芯片手册,看看nxp是怎么写的,什么样的风格,这个不是本文研究的东西,暂时不阐述。
    接着看上面那个函数第二部分,dma,gis,都是lcdif,video硬件有关的东西,最后一句返回 panel 指针

    再回到上一层看这个,pGD变量,其实是 panel 指针,结构体如下:

    pGD 结构体:

    接着看video_init() 函数:flush_cache,计算两个 fgx bgx 变量





    Video_clean, flush_cache:

    上面连续好几个 flush,貌似 flush 完,就把内容刷到屏幕上了
    Video_init 结束了,接着看 board_cfb_skip

    board_cfb_skip 空,没东西

    接下来是keyboard 标志,console_dev 结构体初始化,stdio_register(&console_dev)注册console_dev:

    这个函数结束了,看上一层函数stdio_add_devices的剩余部分:
    Keyboard init,logbuff init ,和其他一些初始化,这个函数也结束

    再返回上一层函数,是这个函数,后头看看本文第一个图片,是不是一样,又返回原点了,整篇完整的追踪结束。

    其实本文核心的东西,信息量最大的部分是这里:

    我们上一篇增加的 displays 实例内的参数,经过各种计算各种形式各种传递,然后把几乎所有的参数传入这个函数,然后读写soc 寄存器,适配自己的lcd屏幕,然后屏幕就可以工作了,完。
    话说,荔枝派的拆机屏,正面直视漏光面积达到了55%,屏幕素质渣渣的一塌糊涂。但是我还是很喜欢这块渣渣屏,因为确实很好用,就是个裸屏,驱动板都没有,自己加的驱动模块,好处是,一个屏幕手册,就可以对这个屏幕知根知底,并且这个屏幕驱动很简单很容易使用,自己想怎么适配就怎么适配。
    .

    .
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-19 07:03 , Processed in 0.141224 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.