高通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 搭建高通平台环境开发环境 在高通 ...
随机推荐
- .NET 收徒,带你走向架构师。
最近感悟天命,偶有所得,故而打算收徒若干,以继吾之传承. 有缘者,可破瓶颈,走向架构师之峰,指日可待. 入门基本要求: 1.工作经验:1年或以上. 2.入门费用:10000元(RMB). 联系方式(联 ...
- 删除列表中重复元素以及求list中元素个数
Python 去除列表中重复的元素 来自比较容易记忆的是用内置的set l1 = ['b','c','d','b','c','a','a'] l2 = list(set(l1)) print l2 还 ...
- JS完美拖拽
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- 利用PyInstaller打包exe文件
前言 平常我们通过Python写完一些小脚本之后,如果使用不频繁的话,一般会选择在DOS界面直接跑脚本,或者在IDE中运行.但当我们需要频繁使用某些脚本,或者在没有Python环境的机器上也能顺利运行 ...
- Dev 日志 | 如何将 jar 包发布到 Maven 中央仓库
摘要 Maven 中央仓库并不支持直接上传 jar 包,因此需要将 jar 包发布到一些指定的第三方 Maven 仓库,比如:Sonatype OSSRH 仓库,然后该仓库再将 jar 包同步到 Ma ...
- Spring基础——AOP通知
spring(AOP通知) 切面 切面是封装通用业务逻辑的组件,可以作用到其他组件上.是spring组件中的某个方法.无返回类型.参数类型与通知类型有关.一个切面 开启数据库 关闭数据库 开启事务 检 ...
- 入职小白随笔之Android四大组件——服务(Service)
Service Android多线程编程 当我们在程序中执行一些耗时操作时,比如发起一条网络请求,考虑到网速等原因,服务器未必会立刻响应我们的请求,此时我们就需要将这些操作放在子线程中去运行,以防止主 ...
- 2、netty第一个例子,简单的http服务器
用netty来启动一个简单的可处理http请求的服务器. 依照前面写的使用netty的过程.贴上代码 server import io.netty.bootstrap.ServerBootstrap; ...
- 2019 DevOps 必备面试题——容器化和虚拟化
原文地址:https://medium.com/edureka/devops-interview-questions-e91a4e6ecbf3 原文作者:Saurabh Kulshrestha 翻译君 ...
- 如何使用python远程操作linux
在云服务测试中,往往需要我们进入云服务内容进行相关内容的测试.这测试可以使用平台自身的noVNC.外部辅助xshell等工具连接到云服务内部进行测试.但是在如此反复的测试操作中,就需要用到自动化测试方 ...