高通lk屏幕向kernel传参
LK把相关参数报存到cmdline上:
在Bootable\bootloader\lk\dev\gcdb\display\gcdb_display_param.c
上gcdb_display_cmdline_arg
函数里:
调用过程如图所示:
aboot_init()-->
target_display_panel_node()-->
gcdb_display_cmdline_arg(panel_name, pbuf, buf_size)
aboot_init()函数里面:
#define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
..........
if (cmdline) {
if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
target_display_panel_node(device.display_panel,
display_panel_buf, MAX_PANEL_BUF_SIZE) &&
strlen(display_panel_buf)) {
cmdline_len += strlen(display_panel_buf);
}
}
target_display_panel_node()函数里面:
bool gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size)
{
char *dsi_id = NULL;
char *panel_node = NULL;
char *slave_panel_node = NULL;
uint16_t dsi_id_len = 0, panel_node_len = 0, slave_panel_node_len = 0;
uint32_t arg_size = 0;
bool ret = true;
bool rc;
char *default_str;
int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG | DST_SPLIT_FLAG;
int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
panel_name += strspn(panel_name, " ");
rc = mdss_dsi_set_panel_node(panel_name, &dsi_id, &panel_node,
&slave_panel_node, &panel_mode);
if (!rc) {
if (panelstruct.paneldata && target_cont_splash_screen()) {
dsi_id = panelstruct.paneldata->panel_controller;
panel_node = panelstruct.paneldata->panel_node_id;
panel_mode =
panelstruct.paneldata->panel_operating_mode &
panel_mode;
slave_panel_node =
panelstruct.paneldata->slave_panel_node_id;
} else {
if (target_is_edp())
default_str = "0:edp:";
else
default_str = "0:dsi:0:";
arg_size = prefix_string_len + strlen(default_str);
if (buf_size < arg_size) {
dprintf(CRITICAL, "display command line buffer is small\n");
return false;
}
strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
pbuf += prefix_string_len;
buf_size -= prefix_string_len;
strlcpy(pbuf, default_str, buf_size);
return true;
}
}
if (dsi_id == NULL || panel_node == NULL) {
dprintf(CRITICAL, "panel node or dsi ctrl not present\n");
return false;
}
if (panel_mode && slave_panel_node == NULL) {
dprintf(CRITICAL, "slave node not present in dual dsi case\n");
return false;
}
dsi_id_len = strlen(dsi_id);
panel_node_len = strlen(panel_node);
if (!slave_panel_node)
slave_panel_node = NO_PANEL_CONFIG;
slave_panel_node_len = strlen(slave_panel_node);
arg_size = prefix_string_len + dsi_id_len + panel_node_len +
LK_OVERRIDE_PANEL_LEN + 1;
arg_size += DSI_1_STRING_LEN + slave_panel_node_len;
if (buf_size < arg_size) {
dprintf(CRITICAL, "display command line buffer is small\n");
ret = false;
} else {
strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
pbuf += prefix_string_len;
buf_size -= prefix_string_len;
strlcpy(pbuf, LK_OVERRIDE_PANEL, buf_size);
pbuf += LK_OVERRIDE_PANEL_LEN;
buf_size -= LK_OVERRIDE_PANEL_LEN;
strlcpy(pbuf, dsi_id, buf_size);
pbuf += dsi_id_len;
buf_size -= dsi_id_len;
strlcpy(pbuf, panel_node, buf_size);
pbuf += panel_node_len;
buf_size -= panel_node_len;
strlcpy(pbuf, DSI_1_STRING, buf_size);
pbuf += DSI_1_STRING_LEN;
buf_size -= DSI_1_STRING_LEN;
strlcpy(pbuf, slave_panel_node, buf_size);
}
end:
return ret;
}
最终传给赋值给cmdline的就是从mdss_mdp3.panel=1:dsi:0:qcom,mdss_dsi_tianshan_qhd_video:1:none
kernel获取LK保存的pbuf
调用顺序:
start_kernel()-->
setup_arch()-->
set_command_line()-->
这是将command_line保存下来:
/**
* mdss_dsi_find_panel_of_node(): find device node of dsi panel
* @pdev: platform_device of the dsi ctrl node
* @panel_cfg: string containing intf specific config data
*
* Function finds the panel device node using the interface
* specific configuration data. This configuration data is
* could be derived from the result of bootloader's GCDB
* panel detection mechanism. If such config data doesn't
* exist then this panel returns the default panel configured
* in the device tree.
*
* returns pointer to panel node on success, NULL on error.
*/
static struct device_node *mdss_dsi_find_panel_of_node(
struct platform_device *pdev, char *panel_cfg)
{
int len, i;
int ctrl_id = pdev->id - 1;
char panel_name[MDSS_MAX_PANEL_LEN];
char ctrl_id_stream[3] = "0:";
char *stream = NULL, *pan = NULL;
struct device_node *dsi_pan_node = NULL, *mdss_node = NULL;
len = strlen(panel_cfg);
if (!len) {
/* no panel cfg chg, parse dt */
pr_debug("%s:%d: no cmd line cfg present\n",
__func__, __LINE__);
goto end;
} else {
if (ctrl_id == 1)
strlcpy(ctrl_id_stream, "1:", 3);
stream = strnstr(panel_cfg, ctrl_id_stream, len);
if (!stream) {
pr_err("controller config is not present\n");
goto end;
}
stream += 2;
pan = strnchr(stream, strlen(stream), ':');
if (!pan) {
strlcpy(panel_name, stream, MDSS_MAX_PANEL_LEN);
} else {
for (i = 0; (stream + i) < pan; i++)
panel_name[i] = *(stream + i);
panel_name[i] = 0;
}
pr_debug("%s:%d:%s:%s\n", __func__, __LINE__,
panel_cfg, panel_name);
mdss_node = of_parse_phandle(pdev->dev.of_node,
"qcom,mdss-mdp", 0);
if (!mdss_node) {
pr_err("%s: %d: mdss_node null\n",
__func__, __LINE__);
return NULL;
}
dsi_pan_node = of_find_node_by_name(mdss_node,
panel_name);
if (!dsi_pan_node) {
pr_err("%s: invalid pan node, selecting prim panel\n",
__func__);
goto end;
}
return dsi_pan_node;
}
end:
//最后如果都没有匹配到的话,就使用这个qcom,dsi-pref-prim-pan节点上的
if (strcmp(panel_name, NONE_PANEL))
dsi_pan_node = mdss_dsi_pref_prim_panel(pdev);
return dsi_pan_node;
}
高通lk屏幕向kernel传参的更多相关文章
- 高通spi 屏幕 -lk代码分析
lk SPI驱动 1. 初始化时钟 在lk中,我们是从kmain开始执行下来的,而执行顺序则是先初始化时钟,也就是在platform_early_init函数中开始执行的: 在这里我们需要修改这个函数 ...
- 高通平台framework,hal,kernel打开log【转】
本文转载自:https://blog.csdn.net/u010164190/article/details/78625636 .Add framework log #define LOG_NDEBU ...
- 高通平台msm8909 LK 实现LCD 兼容
前段时间小米出现红米note2 换屏门,现在我们公司也要上演了:有两个供应商提供不同IC 的LCD panel. 软件区分的办法是读取LCD IC 的ID 寄存器,下面解析高通平台LK中LCD兼容的过 ...
- Web API中的传参方式
在Restful风格的WebApi的里面,API服务的增删改查,分别对应着Http Method的Get / Post / Delete /Put,下面简单总结了Get / Post /Delete ...
- 高通移植mipi LCD的过程LK代码
lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...
- C++ 传参时传内置类型时用传值(pass by value)方式效率较高
来源:唐磊的个人博客<C++ 传参时传内置类型时用传值(pass by value)方式效率较高> 在<Effective C++>里提到对内置(C-like)类型在函数传参时 ...
- 1.函数的结构,调用,传参,形参,实参,args,kwargs,名称空间,高阶函数
1.函数的初识 初始函数 获取任意一个字符串的元素的个数 s1='dsjdkjkfefenga' count=0 for i in s1: count+=1 print(count) 获取列表的元素的 ...
- uboot向kernel的传参机制——bootm与tags
http://blog.csdn.net/skyflying2012/article/details/35787971 最近阅读代码学习了uboot boot kernel的过程以及uboot如何传参 ...
- 【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
随机推荐
- 【30天自制操作系统】day01:内存分布图
- Cocos Creator 资源加载流程剖析【五】——从编辑器到运行时
我们在编辑器中看到的资源,在构建之后会进行一些转化,本章将揭开Creator对资源进行的处理. 资源处理的整体规则 首先我们将Creator的开发和运行划分为以下几个场景: 编辑器 当我们将资源放到编 ...
- 【戾气满满】Ubuntu 18.04使用QT通过FreeTDS+unixODBC连接MSSQL填坑记(含泪亲测可用)
前言 照例废话几句,想玩下QT,但是学习吧总得想点事情做啊,单纯学习语法用法这些?反正我是学不下去的,脑袋一拍,就先学下怎么连接数据库吧!然而万万没想到,我这是给自己挖了一个深深的坑啊! 学习自然去官 ...
- Java方法之重载
Java方法之重载 本篇探究Java中的方法重载.那么,什么是重载呢?先上一串代码: package com.my.pac06; /** * @author Summerday * @date 201 ...
- 【原创】WinForm中实现单独Time控件的方式
WinForm默认只提供了DateTimePicker,今天的项目只用时间,不能出现日期,百撕不得骑姐(^^),也没花多少时间,随便试了一下,就成功了,分享一下. 在DateTimePicker属性中 ...
- 使用EasyPOI导入导出图片出现数组越界异常
在我使用easypoi做导出功能的时候,突然抛了一个数组越界异常,找了很久也没找到,最后猜想有可能是路径出了问题,然后打印了一下图片存放的路径,结果发现在其保存路径上存在“.”,也就是easypoi底 ...
- Servlet是什么?JSP和Servlet的区别。Servlet的生命周期。
Servlet(Server Applet),全称Java Servlet, 是用Java编写的服务器端程序.而这些Sevlet都要实现Servlet这个借口.其主要功能在于交互式地浏览和修改数据,生 ...
- DotNet Core中使用RabbitMQ
上一篇随笔记录到RabbitMQ的安装,安装完成,我们就开始使用吧. RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协 ...
- phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)
漏洞详情 范围 phpMyAdmin 4.8.0和4.8.1 原理 首先在index.php 50-63行代码 $target_blacklist = array ( 'import.php', 'e ...
- Linux学习入门-------------------------VMvare与镜像的安装与配置
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_39038465/article/d ...