LCM:高通 LK kernel 流程分析_lk和kernel-程序员宅基地

技术标签: Linux  linux  android  Android  

以下几幅图是最近的一段时间对自己模块LCM的一些总结,目前只是完成了一部分,而且描述的不是特别到位,后期会不断更新和修改的。

第一幅是LCM的总体移植框架和组件图。介绍了LCM驱动的分部和调试屏的步骤和要点。

分lk和kernel两个部分,具体哪些.c,如何添加一块新屏,大体的步骤和方法。

第二幅图是屏的初始化流程图,分为lk和kernel两部分。Lk部分如下所示:

系统起来的时候会调用 bootable/bootloader/lk/app/aboot/aboot.c, 在这个函数里面的 aboot_init()函数里调用显示屏初始化函数target_display_init(),在这个函数里面调用gcdb_display_init()。

在这个函数中有个相当重要的函数就是oem_panel_select(),定义在oem_panel.c中,它根据高通私有代码传进来的hw_id 来决定你到底使用哪一款LCD,并把panel相关数据信息填充到数据结构中–init_panel_data(),gcdb_display_init()中执行完 oem_panel_select()确定使用的panel和panel相关信息后,通过函数指针赋值了一系列与此panel相关的功能函数,包括pll,背光,clk,供电相关的初始化和使能函数,以便在下面进行调用。

同时, 开始执行  一系列屏初始化流程。第一步,上电,执行pdata->power_func,打开一些ldo,使能一些系统电源,拉高一些gpio, 使得屏得到供电,并且在里面对屏做reset,调用的函数是target_panel_reset(),在里面对reset引脚做高低高操作。然后使能时钟,调用pdata->clk_func,接着做一些使能pll,分配framebuffer,通过fbcon_setup(&(panel->fb))函数设置记录显示的分辨率和显示地址等全局指针。接下来进入msm_display_config()函数针对LVDS_PANEL,MIPI_VIDEO_PANEL,MIPI_CMD_PANEL等类型进行dsi和mipi配置。

经过一些列dsi参数置最后调用 mdss_dsi_panel_initialize(),使用mdss_dsi_cmds_tx()向lcm的driver ic发送了初始化代码。并判断,如果 target_panel_auto_detect_enabled()打开了话,就使用高通平台的lcm read_id函数mdss_dsi_read_panel_signature()进行id读取。

完成这一系列操作以后执行msm_display_on(),点亮屏,最后一个阶段调用pdata->bl_func(1)打开背光。这样整个LK的lcm初始化就完成了。LK的初始化流程图如下所示。

接下来是kernel阶段LCM的初始化过程。

kernel阶段,首先会在驱动中注册三个平台设备,msm_fb,mdp,mipi_dsi。mdp模块是高通内部的显示控制芯片,mipi_dsi是传输协议层设备,msm_fb是高通显卡的驱动设备。

首先执行的是mdp驱动的probe,进行硬件资源包括时钟,中断,iommu,总线,DMA的初始化,注册一些接口以供fb设备使用。mdp初始化以后初始化dsi控制器,在mdss_dsi_ctrl_probe函数中,调用了一个函数mdss_ds_config_panel,这个函数中,通过名字匹配去获取panel设备节点,如果没有匹配成功就去调用msm-mtp.dtsi设定的预制panel device node。

接下来执行函数dsi_panel_device_register()注册panel_device设备节点。在这个注册函数中,确定了是DSI_VIDEO_MODE还是MIPI_CMD_MODE,获取了一些资源如gpio,regulatot,dsi-lane相关的信息,重要的是它注册了一个event_handler:mdss_dsi_event_handler,这个事件处理函数会接受其他层传进来的各种event事件包括点亮,熄灭屏等等。也是通过这个event_handler,dsi驱动层与fb层,mdp层进行通信。

然后执行mdss_dsi_panel_init函数进行panel的初始化。这个函数通过解析dtsi文件获取了屏的名字,分辨率,物理尺寸,dsi类型,porch参数,色彩格式,初始化指令,背光模式等一些列参数,并且把它们一一填充到pinfo这个结构体中,并且注册了一些on off ,设置背光,选择模式等操作函数。接下来是mdss_fb设备的初始化,在mdss_fb_probe函数中,通过调用mfd->mdp.init_fnc去初始化mdp,通过lcd_backlight_registered()去注册背光驱动。

在系统开机动画起来的时候,会调用函数mdss_fb_open打开fb控制器,在里面会执行mdss_fb_blank_sub()并传入FB_BLANK_UNBLANK event参数,执行mdss_fb_blank_unblank()函数。这个函数中,通过调用mfd->mdp.on_fnc()执行了mdp驱动中的on_fnc函数,就是mdp3_ctrl_on()函数,该函数向之前dsi驱动中的event handler发送三个事件MDSS_EVENT_LINK_READY,MDSS_EVENT_UNBLANK,MDSS_EVENT_PANEL_ON调用mdss_dsi_panel驱动中mdss_dsi_on()。

在里面执行了配置dsi,上电,reset,发送指令一些列操作从而将屏点亮。这样kernel部分的屏初始化就完成了。

下图就是KERNEL阶段的初始化流程图。

第四幅图,是点亮屏熄灭屏从上层到底层的数据传输图。

如果要灭屏,上层会调用PowerManagerService提供的方法。整个过程的调用关系是goToSleep->goToSleepInternal-> updatePowerStateLocked->updateDisplayPowerStateLocked->

requestPowerState->sendUpdatePowerStateLocked->mHandler.sendMessage(msg)-> updatePowerState->animateScreenStateChange->setScreenState->scheduleScreenUpdate->

postScreenUpdateThreadSafe->mPhotonicModulator.setState->mLock.notifyAll-> mBlanker.requestDisplayState->initPowerManagement->callbacks.onDisplayStateChange->

setHalAutoSuspendModeLocked->nativeSetAutoSuspend

最后到nativeSetAutoSuspend()这个本地方法,是在

frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp

调用的,调用里面的autosuspend_enable(),这个函数会往/sys/power/state节点中写入

mem。

这个节点,是在kernel/kernel/power/main.c当中创建的sysfs文件节点,一旦往里面写入值就会调用相应的store函数。灭屏,上层写入mem,调用了store当中的suspend函数,于是系统就会走suspend流程。传递到屏这边,在msm_fb系统中调用suspend函数,

经过一些列调用,走到mdss_fb_blank_blank(),调用mfd->mdp.off_fnc,调用mdp_ctrl.c

的mdp_ctrl_off函数,于是panel->set_backlight(panel, 0)关闭背光,通过发送

MDSS_EVENT_BLANK 给dsi驱动中的event_handler,调用mdss_dsi_blank()执行一系列下电灭屏的操作。这样整个灭屏流程就执行完了。

亮屏的话,同样是从PowerManagerService提供方法wake up,最后就调用jni的autosuspend_disable(),往/sys/power/state节点中写入on,最后调用suspend流程点亮屏。

流程图如下所示。

第五幅图,总结了背光调节从上层到底层是如何传输的。

当用户在手机的setting-display-backlights调节背光时,系统将会调用

packages\apps\Settings\src\com\android\settings\BrightnessPreference.java去实现。在这里面设置亮度调节范围0-255,通过powermanagerservice.java的接口setBrightness实现服务。这个方法定义在LightService.java中,调用setBrightness()—>setLightLocked()—>setLight_native()。

这个本地方法在frameworks\base\services\jni\com_android_server_LightsService.cpp下实现。在这个文件下,init_native函数中,调用hw_get_module(LIGHTS_HARDWARE_MODULE_ID, (hw_module_t const**)&module)获取 lights硬件抽象层模块lights.default.so并加载,调用hall层函数devices->lights[light]->set_light(devices->lights[light],&state)设置亮度。hall层的代码是hardware/qcom/display/liblight/lights.c。

在这里面实现了open_lights,close_lights,rgb_to_brightness等函数。最关键是,调节亮度时候,会调用其中的set_light_backlight(),通过write_int往/sys/class/leds/lcd-backlight/brightness写值。这个文件节点在kernel层创建。kernel层,在Mdss_dsi_panel.c文件里,有一个背光控制函数static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata,u32 bl_level), 参数背光值就是通过这个bl_level进行调节的。

经过一层层调用,实际上在kernel/drivers/leds/Led-class.c中创建的sysfs文件节点/sys/class/leds/lcd-backlight/brightness,并且在store函数中,把当前亮度值存到led_cdev->brightness变量中, 一层层传到驱动的bl_level。这样,就形成了上层到底层的背光调节值的传递。

以上几幅图,总体上概括了LCM驱动部分以及一些上层的关系,流程。这样的整理对自己的模块理解和熟悉是相当有帮助的。随着工作的深入,我会不断补充和完善这个文档,希望能够在实际工作中取得良好的效果。

————————————————
版权声明:本文为CSDN博主「无敌幸运_Jason」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yctcgogo/article/details/82655903

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_38715577/article/details/105835938

智能推荐

进程间通信---无名管道-程序员宅基地

文章浏览阅读337次,点赞8次,收藏8次。【代码】进程间通信---无名管道。

Android屏幕适配-重点盘点(2)-程序员宅基地

文章浏览阅读705次,点赞17次,收藏17次。当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。无论你现在水平怎么样一定要。

从微信扔骰子看iOS应用安全与逆向分析_frida lldb函数偏移-程序员宅基地

文章浏览阅读1.1k次。以微信扔骰子小游戏为例,记录一次完整 iOS 逆向分析的过程。_frida lldb函数偏移

LaTeX:overleaf latex 中文生僻字处理_latex 生僻字-程序员宅基地

文章浏览阅读8.4k次,点赞7次,收藏12次。问题描述:生僻字只有特定字体才能打出来解决方案:分为xelatex和pdflatexxelatex在usepackage区:\usepackage{ctex}\setCJKfamilyfont{myfont}{SimSun.ttf}\newcommand{\MyFont}{\CJKfamily{myfont}}然后在正文中:\MyFont{奂奒奓奘奙奚奛奜奝奞奟奡奣奤奦奨奁奫妸奯奰奱奲}效果:其中SimSun.ttf是自己上传在overleaf的字体文件的文件名。overleaf_latex 生僻字

java多线程notify()无法唤醒wait()问题_sc notify()无法唤醒wait-程序员宅基地

文章浏览阅读3.9k次,点赞2次,收藏5次。创建两个Runnable,其中一个的run()方法启动并调用wait(),第二个Runnable中run()方法在一定的几秒之后,为第一个任务调用notify(),从而使得第一个Runnable能显示一条信息,用Executor来测试。public class RunnableWait implements Runnable{ public static Object obj=new Obje_sc notify()无法唤醒wait

ssm计算机毕业设计基于Android的智能迎新(源码+程序+app+论文)-程序员宅基地

文章浏览阅读231次,点赞3次,收藏10次。从管理层面来看,该应用集成了个人信息管理,简化了繁琐的手工操作,提高了学校管理的效率和准确性。后端SSM框架结合了Spring的依赖注入和事务管理、SpringMVC的模型-视图-控制器架构以及MyBatis的数据持久化功能,为后端开发提供全面的支持。随着高等教育的大众化,每年有数以百万计的新生步入校园,他们面临的不仅仅是新知识的学习挑战,还有生活环境的适应问题。智能迎新appld92t的开发,不仅体现了科技对教育辅助作用的拓展,也反映了现代高校对于提升学生服务体验的追求。

随便推点

Windows Server 2012 R2安装SqlServer 2016-程序员宅基地

文章浏览阅读2.7k次。1.系统安装微软操作系统 Windows Server 2012 R2 官方原版镜像Windows Server 2012 R2 是由微软公司(Microsoft)设计开发的新一代的服务器专属操作系统,其核心版本号为 Windows NT 6.3 。提供企业级数据中心与混合云解决方案,直观且易于部署、具有成本效益、以应用程序为重点、以用户体验为中心,深受广大 IDC 运营商青睐。在 M..._window server 2012 r2 datacenter 装哪个版本的sqlserver

mac ssh,mac xshell,xshell替代,ssh客户端,ssh工具,远程桌面加速_mac 版 xshell远程连接工具-程序员宅基地

文章浏览阅读772次。HostBufFinalShell 发表 首页 liwei_perfect 消息 设置 我的推广 积分 0 最新回复 FinalShell SSH工具,服务器管理,远程桌面加速软件,支持Windows,Mac OS X,Linux,版本2.9.4,时间2018.7.19 ..._mac 版 xshell远程连接工具

第九次作业_现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点。 输入是一-程序员宅基地

文章浏览阅读1.6k次,点赞2次,收藏17次。现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点输入是一组学生的姓名、学号和绩点,以链表形式存储。删除绩点小于平均绩点的学生结点,成为一个新链表。后按照输入的顺序,依序输出新链表的学生信息。平均绩点是输入的所有学生绩点取算术平均值。输入描述输入包括若干行。 每行是一个学生的姓名、学号和绩点,以空格隔开。最后一行是*.输出描述输出包括学生姓名。 每个学生姓名一行。样例输入sddv 005 3.6jjjbjb 1465 1.5jdsf 015_现在想将学生绩点组成一个链表。链表结点内容包括学生姓名,学号,绩点。 输入是一

Android 8.0 蓝牙唤醒 Ble 锁屏 保活 后台 持续扫描 进程拉活 自动唤醒_<action android:name="com.hungrytree.receiver.bles-程序员宅基地

文章浏览阅读1.1w次,点赞4次,收藏26次。主要是api的说明,嫌啰嗦的可以直接看demo,demo中有个检测锁屏时间重复开启扫描的代码,主要是如果APP没有获得电量或者后台运行的权限,只能持续后台运行几小时。这个demo的作用是实现8.0以后的后台监测到特定蓝牙信号自动唤醒APP的功能,首先需要另外一个装了可以发射蓝牙信号软件的手机,我这边是选取的ios平台上的lightblue,然后在这个软件里面新建一个虚拟设备名称是要demo搜索..._

element中table表格和已选数据联动_element 表格 选中一个连带另一个-程序员宅基地

文章浏览阅读1.3k次。element中table表格和已选数据联动需求:1.根据条件查询表格,多选框选中项移到已选择表格,取消选择,已选项表格也取消该调数据数据2.已选项增加删除按钮,删除之后,查询数据的表格也取消勾选3.重新查询新数据,已选择数据不会改变,新选中的数据添加到已选择表格效果如下直接上代码 // 查询列表 <div slot="content" class="content" v-if="scheme"> <div _element 表格 选中一个连带另一个

dhcp服务器 无线桥接,老款TP-Link TL-WR841N路由器无线桥接设置方法-程序员宅基地

文章浏览阅读6k次。老款TP-Link TL-WR841N路由器的无线桥接设置方法。之所以说是老款TP-Link TL-WR841N路由器的桥接设置,是因为目前TP-Link TL-WR841N路由器又多个硬件版本,最新的版本是V12。而V12版本的TL-WR841N路由器,与前面所有版本的TL-WR841N路由器,在设置上有很大的不同。因此,本文把V1-V11版本的TL-WR841N路由器叫做老款TL-WR841N..._桥接dhcp怎么设置

推荐文章

热门文章

相关标签