高通LCD bring up流程

前言

  高通平台LCD的bring up可分为两部分:kernel、lk。在点屏之前要仔细看LCD电路原理图和IC spec,搞清楚LCD亮屏需要满足的上电条件和时序要求。同时找FAE拿到初始化代码。

kernel

  

添加LCD的dtsi

  参考FAE提供的初始化信息,填写分辨率hfp\hbp\hpwvfp\vbp\vpw,一般来讲FAE会提供初始化代码、hfp\hbp\hpw、vfp\vbp\vpw、spec等信息
  arch/arm64/boot/dts/qcom/dsi-panel-XXX-xxxp-video.dtsi

&mdss_mdp {
	dsi_hx8394f_720p_video: qcom,mdss_dsi_hx8394f_720p_video { //保持一致就好
		qcom,mdss-dsi-panel-name = "hx8394f 720p video mode dsi panel";//panel name
		qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;//保持不变;指定此panel将映射到的DSI控制器的模型
		qcom,mdss-dsi-panel-type = "dsi_video_mode";//指定面板操作模式。
							 						//“dsi_video_mode” = 启用视频模式
							 						//“dsi_cmd_mode” = 启用命令模式
		qcom,mdss-dsi-panel-destination = "display_1";//指定面板的目标显示,保持不变
		qcom,mdss-dsi-panel-framerate = <60>;//指每秒显示60帧,一帧就是一个完整的图像(一般都是60)
		qcom,mdss-dsi-virtual-channel-id = <0>; //指定虚拟频道标识符,默认为0;保持不变
		qcom,mdss-dsi-stream = <0>;//指定要使用的数据包流:0 = 流 0(默认值);1 = 流 1。保持不变
		qcom,mdss-dsi-panel-width = <720>;//分辨率-w
		qcom,mdss-dsi-panel-height = <1440>;//分辨率-h
		qcom,mdss-dsi-h-front-porch = <60>;//hfp-表示一行的有效数据结束到下一个水平同步信号开始之间的VCLK的个数,对应驱动中的right_margin;
		qcom,mdss-dsi-h-back-porch = <60>;//hbp-表示从水平同步信号开始到一行的有效数据开始之间的VCLK的个数,对应驱动中的left_margin;
		qcom,mdss-dsi-h-pulse-width = <18>;//hpw-表示水平同步信号的宽度,用VCLK计算,对应驱动中的hsync_len;(设置一行有几个像素)
		qcom,mdss-dsi-h-sync-skew = <0>;//水平同步倾斜值:0 = 默认值。保持不变
		qcom,mdss-dsi-v-back-porch = <12>;//vbp-表示在一帧图像开始时,垂直同步信号以后的无效的行数,对应驱动中的upper_margin;
		qcom,mdss-dsi-v-front-porch = <15>;//vfp-表示在一帧图像结束后,垂直同步信号以前的无效的行数,对应驱动中的lower_margin;
		qcom,mdss-dsi-v-pulse-width = <2>;//vpw-表示垂直同步脉冲的宽度,用行数计算,对应驱动中vsync_len;(有多少显示的行)
		qcom,mdss-dsi-h-left-border = <0>;//水平左边框(单位:像素):0 = 默认值。保持不变
		qcom,mdss-dsi-h-right-border = <0>;//水平右边框(单位:像素):0 = 默认值。保持不变
		qcom,mdss-dsi-v-top-border = <0>;//垂直上边框(单位:像素):0 = 默认值。保持不变
		qcom,mdss-dsi-v-bottom-border = <0>;//垂直下边框(单位:像素):0 = 默认值。保持不变
		qcom,mdss-dsi-bpp = <24>; // 指定面板的每像素位数。
				  				// 3   = 适用于 rgb111
				  				// 8   = 适用于 rgb332
				  				// 12 = 适用于 rgb444
				  				// 16 = 适用于 rgb565
				  				// 18 = 适用于 rgb666
				  				// 24 = 适用于 rgb888
		qcom,mdss-dsi-color-order = "rgb_swap_rgb"; // 指定 R、G 和 B 通道排序"rgb_swap_rgb" =DSI_RGB_SWAP_RGB默认值)
		qcom,mdss-dsi-underflow-color = <0xff>;// 指定面板下溢颜色的控制器设置:0xff = 默认值。保持不变
		qcom,mdss-dsi-border-color = <0>;//如有边框,定义边框颜色值。0 = 默认值。
		qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 B9 FF 83 94//根据FAE提供的初始化代码填写
					39 01 00 00 00 00 03 C0 1F 31
					...
					05 01 00 00 78 00 02 11 00
					05 01 00 00 14 00 02 29 00];

		qcom,mdss-dsi-off-command = [//根据FAE提供的初始化代码填写
			05 01 00 00 14 00 02 28 00
			05 01 00 00 78 00 02 10 00];
		qcom,mdss-dsi-on-command-state = "dsi_lp_mode";//指定用于发送 ON /OFF命令的控制状态的字符串。
											//"dsi_lp_mode" = DSI 低功率模式(默认值)
											//"dsi_hs_mode" = DSI 高速模式
		qcom,mdss-dsi-off-command-state = "dsi_lp_mode";
		qcom,mdss-dsi-h-sync-pulse = <0>; //指定面板的脉冲模式选项。
											//0 = 不在 vs/ve 数据包之后发送hsa/he(默认值)
											//1 = 在 vs/ve 数据包之后发送 hsa/he
		qcom,mdss-dsi-traffic-mode = "non_burst_sync_event";//指定面板流量模式
											//"non_burst_sync_pulse" = 使用同步脉冲的非突发流量(默认值)
											//"non_burst_sync_event" = 使用同步 启动事件的非突发流量
											//"burst_mode" = 突发模式
		qcom,mdss-dsi-lane-map = "lane_map_0123";// 指定数据通道交换配置; 保持不变
											//"lane_map_0123" = <0 1 2 3>(默认值)
		qcom,mdss-dsi-bllp-eof-power-mode;//用于确定低功率空白期(BLLP)EOF 模式期间的 DSI 通道状态
		qcom,mdss-dsi-bllp-power-mode;//用于确定低功率空白期(BLLP)模式 期间的 DSI 通道状态
		qcom,mdss-dsi-tx-eot-append;
		qcom,mdss-dsi-lane-0-state;//指定是否启用数据通道 0
		qcom,mdss-dsi-lane-1-state;
		qcom,mdss-dsi-lane-2-state;
		qcom,mdss-dsi-lane-3-state;
		qcom,mdss-dsi-panel-timings// 高通表格计算出来的
			= [87 1C 12 00 42 42 18 21 17 03 04 00];
		qcom,mdss-dsi-t-clk-post = <0x04>;//指定模式切换后的字节时钟周期
		qcom,mdss-dsi-t-clk-pre = <0x1B>;// 指定模式切换前的字节时钟周期
		qcom,mdss-dsi-dma-trigger = "trigger_sw";//指定用于 DMA 路径的触发机制
										//"none" = 无触发
										//"trigger_te" = 断开用于触发的检查信 号线
										//"trigger_sw" = 由软件触发(默认设置) "trigger_sw_seof" = 软件触发和帧触 发的开始/结束。
										//"trigger_sw_te" = 软件触发和 TE
		qcom,mdss-dsi-mdp-trigger = "none";//指定用于 MDP 路径的触发机制;"none" = 无触发
		qcom,mdss-dsi-lp11-init;//确保在reset前,保证DSI clock和data都要及时被拉高
		qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; //列出重置 GPIO 值和睡眠序列的数组
										//每个命令具有下面定义的格式:
										//--> 重置 GPIO 值:高电平低电平
										//--> 睡眠值:多少毫秒
	};
};

将屏的dtsi放到平台的dtsi中

  指定要用哪个屏幕

#include "dsi-panel-hx8394f-720p-video.dtsi"

&mdss_dsi0 {//对应 .dtsi中“panel-controller”
	qcom,dsi-pref-prim-pan = <&dsi_hx8394f_720p_video>;//与屏的dtsi中保持一致
	pinctrl-names = "mdss_default", "mdss_sleep";
	pinctrl-0 = <&mdss_dsi_active &mdss_te_active>;
	pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>;
	qcom,regulator-ldo-mode;//低压差线性稳压器(一种电压转换芯片)

	qcom,platform-te-gpio = <&tlmm 24 0>;
	qcom,platform-reset-gpio = <&tlmm 60 0>;
	//qcom,platform-bklight-en-gpio = <&tlmm 93 0>;
	//qcom,platform-enable-gpio = <&tlmm 94 0>;
};


&dsi_hx8394f_720p_video {
        qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;//一个节点,列出用于为DSI面板供电的电源元件
        qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_pwm";//用于指定此面板的背光控制的实现
        qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>;//PWM周期(以微秒为单位)
        qcom,mdss-dsi-bl-pmic-bank-select = <0>; //PG背光通道
        qcom,mdss-dsi-pwm-gpio = <&pm8916_mpps 4 0>;// PMIC gpio绑定到背光
        // esd检查
        qcom,esd-check-enabled;//启用ESD恢复功能
        qcom,mdss-dsi-panel-status-check-mode = "reg_read"; //指定用于ESD恢复的面板状态检查方法;“ reg_read” =读取面板状态寄存器以检查面板状态
        qcom,mdss-dsi-panel-status-command = [06 01 00 01 00 00 01 09];//基于qcom dsi控制器协议的多个dcs数据包形成的字节流,以读取面板状态
        qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode";
        qcom,mdss-dsi-panel-status-value = <0x80 0x73 0x06>;//多个整数数组,每个整数数组指定用于检查面板状态的面板状态寄存器的值。 每个数组的大小是qcom,mdss-dsi-panel-status-read-length中指定的长度总和,并且必须相等。
        qcom,mdss-dsi-panel-on-check-value = <0x80 0x73 0x06>;
        qcom,mdss-dsi-panel-status-read-length = <3>;//数组长度
};

电压配置

  除lab、ibb外,还有vdd、vddio自己在平台代码找一下
  drivers/video/fbdev/msm/mdss_dsi.c

&mdss_dsi0 {
	lab-supply = <&lab_regulator>;
	ibb-supply = <&ibb_regulator>;
};
 
&labibb {
	status = "ok";
	qpnp,qpnp-labibb-mode = "lcd";
};

&ibb_regulator {
	qcom,qpnp-ibb-discharge-resistor = <32>;
};

&dsi_panel_pwr_supply {
	qcom,panel-supply-entry@2 {
		reg = <2>;
		qcom,supply-name = "lab";
		qcom,supply-min-voltage = <4600000>;
		qcom,supply-max-voltage = <6000000>;
		qcom,supply-enable-load = <100000>;
		qcom,supply-disable-load = <100>;
	};

	qcom,panel-supply-entry@3 {
		reg = <3>;
		qcom,supply-name = "ibb";
		qcom,supply-min-voltage = <4600000>;
		qcom,supply-max-voltage = <6000000>;
		qcom,supply-enable-load = <100000>;
		qcom,supply-disable-load = <100>;
		qcom,supply-post-on-sleep = <20>;
	};
};

修改设备树显示电压"regulator-l17",“regulator-l6”

lk

/android/bootable/bootloader/lk

添加屏的.h文件

.h中很多参数都是根据dtsi填写的
/dev/gcdb/display/include/panel_xxxx_xxxp_video.h
.h中用到的结构体定义在
/android/bootable/bootloader/lk/dev/gcdb/display/include/panel.h

Panel configuration

static struct panel_config hx8394f_720p_video_panel_data = {
	"qcom,mdss_dsi_hx8394f_720p_video", "dsi:0:", "qcom,mdss-dsi-panel",
	10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, NULL
};

对应结构体定义与解析

struct panel_config{

	char  *panel_node_id;//"qcom,mdss_dsi_st7703p_720p_video" 与dtsi保持一致
	char  *panel_controller; //"dsi:0:"对应dtsi中“panel-controller”
	char  *panel_compatible;// "qcom,mdss-dsi-panel" 保持不变
	uint16_t panel_interface;//看电路图上有几个mipi接口就填几
	uint16_t panel_type; //video是MIPI_VIDEO_PANEL(0), cmd是MIPI_CMD_PANEL(1)
	char   *panel_destination;// "DISPLAY_1" 对应dtsi中panel-destination
	uint32_t panel_orientation;//屏幕旋转方向,默认为0
	/* panel_clockrate is deprecated in favor of panel_bitclock_freq */
	uint32_t panel_clockrate;//默认为0,不建议修改
	uint16_t panel_framerate;// 刷新率,一般为60
	uint16_t panel_channelid;//保持不变
	uint16_t dsi_virtualchannel_id;//对应DTS中虚拟频道ID(保持不变)
	uint16_t panel_broadcast_mode;//保持不变
	uint16_t panel_lp11_init;//确保在reset前,保证DSI clock和data都要及时被拉高
	uint16_t panel_init_delay;// 初始化延迟
	uint16_t dsi_stream;//保持不变
	uint8_t  interleave_mode;//交错模式(保持不变)
	uint32_t panel_bitclock_freq;//保持不变
	uint32_t panel_operating_mode;//操作模式,默认为0
	uint32_t panel_with_enable_gpio;//保持不变
	uint8_t  mode_gpio_state;//保持不变
	char  *slave_panel_node_id;//NULL
};

Panel resolution

根据dtsi写,从左到右依次为分辨率(width*high)、hfp、hbp、hpw、hss、vfp、vbp、vpw…

static struct panel_resolution hx8394f_720p_video_panel_res = {
	720, 1440, 58, 58, 16, 0, 15, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0
//  w,  h,  hfp, hbp, hpw, hss, vfp, vpw ...
};

以下参数在上面dtsi中有详细介绍,这里就不再重复了

struct panel_resolution{

	uint16_t panel_width;
	uint16_t panel_height;
	uint16_t hfront_porch;//hfp
	uint16_t hback_porch;//hbp
	uint16_t hpulse_width;//hpw
	uint16_t hsync_skew;//hss - 水平同步倾斜值
	uint16_t vfront_porch;//vfp
	uint16_t vback_porch;//vbp
	uint16_t vpulse_width;//vpw
	uint16_t hleft_border;//水平左边框
	uint16_t hright_border;//水平右边框
	uint16_t vtop_border;//垂直上边框
	uint16_t vbottom_border;//垂直下边框
	uint16_t hactive_res;//0
	uint16_t vactive_res;//0
	uint16_t invert_data_polarity;//0
	uint16_t invert_vsync_polarity;//垂直脉冲模式
	uint16_t invert_hsync_polarity;//水平脉冲模式
};

Panel color information

static struct color_info hx8394f_720p_video_color = {
	24, 0, 0xff, 0, 0, 0
};
struct color_info{
	uint8_t  color_format;
	uint8_t  color_order;
	uint8_t  underflow_color;
	uint8_t  border_color;
	uint8_t  pixel_packing;
	uint8_t  pixel_alignment;
};

对应dtsi中
在这里插入图片描述
"rgb_swap_rgb"对应0
在这里插入图片描述
在安卓R上,pixel_alignment在代码中并没有去解析

Panel on/off command information

初始化代码
eg:

static char st7703p_720p_video_on_cmd1[] = {
	0x06, 0x00, 0x39, 0xC0,
	0xB1, 0x85, 0x00, 0x24,
	0xDA, 0x01, 0xFF, 0xFF,
};

dtsi 的qcom,mdss-dsi-on-command中,每一行为一个cmd,cmd=0开始
第一行第一个数和第二个数之和是数值的个数(第2个一般是0x00),后面两个是datatype;(23,15,05对应80,29和39对应c0).
第二行开始写数值,结尾一行不足4个的填写0xff.
注意:始化代码最后两行只写一行

static char st7703p_720p_video_on_cmd22[] = {
	0x11, 0x00, 0x05, 0x80,
};

static char st7703p_720p_video_on_cmd23[] = {
	0x29, 0x00, 0x05, 0x80
};

mipi_dsi_cmd结构体中,第一个参数是相应数组的总数,包括第一行和0xff在内

static struct mipi_dsi_cmd st7703p_720p_video_on_command[] = {
	{0x08, st7703p_720p_video_on_cmd0, 0x00},
	{0x0C, st7703p_720p_video_on_cmd1, 0x00},
	{0x08, st7703p_720p_video_on_cmd2, 0x00},
	{0x10, st7703p_720p_video_on_cmd3, 0x00},
	...

ST7703P_720P_VIDEO_ON_COMMAND 是初始化命令的个数,也就是刚刚填的cmd的个数

#define ST7703P_720P_VIDEO_ON_COMMAND 24

Panel timing

根据dtsi的timings来算

oem_panel.c

android/bootable/bootloader/lk/target/msmxxxx/oem_panel.c

#include "include/panel_xxxxxx_xxxp_video.h"

将panel加入枚举

/*---------------------------------------------------------------------------*/
/* static panel selection variable                                           */
/*---------------------------------------------------------------------------*/
enum {
	TRULY_1080P_VIDEO_PANEL,
	TRULY_1080P_CMD_PANEL,
	...
	ST7703P_720P_VIDEO_PANEL,
	ILI9881C_720P_VIDEO_PANEL,
	UNKNOWN_PANEL
};

加入panel_list

/*
 * The list of panels that are supported on this target.
 * Any panel in this list can be selected using fastboot oem command.
 */
static struct panel_list supp_panels[] = {
	{"truly_1080p_video", TRULY_1080P_VIDEO_PANEL},
	{"truly_1080p_cmd", TRULY_1080P_CMD_PANEL},
	...
	{"st7703p_720p_video", ST7703P_720P_VIDEO_PANEL},
	{"ili9881c_720p_video", ILI9881C_720P_VIDEO_PANEL},
};

将 panel_st7703p_720p_video.h中的数据依次赋值

	case ST7703P_720P_VIDEO_PANEL:
		panelstruct->paneldata    = &st7703p_720p_video_panel_data;
		panelstruct->panelres     = &st7703p_720p_video_panel_res;
		panelstruct->color		               = &st7703p_720p_video_color;
		panelstruct->videopanel   = &st7703p_720p_video_video_panel;
		panelstruct->commandpanel = &st7703p_720p_video_command_panel;
		panelstruct->state		               = &st7703p_720p_video_state;
		panelstruct->laneconfig   = &st7703p_720p_video_lane_config;
		panelstruct->paneltiminginfo
						         = &st7703p_720p_video_timing_info;
		panelstruct->panelresetseq
						         = &st7703p_720p_video_panel_reset_seq;
		panelstruct->backlightinfo = &st7703p_720p_video_backlight;
		pinfo->mipi.panel_on_cmds
						         = st7703p_720p_video_on_command;
		pinfo->mipi.num_of_panel_on_cmds
						         = ST7703P_720P_VIDEO_ON_COMMAND;
		pinfo->mipi.panel_off_cmds
						         = st7703p_720p_video_off_command;
		pinfo->mipi.num_of_panel_off_cmds
						         = ST7703P_720P_VIDEO_OFF_COMMAND;
		memcpy(phy_db->timing,
				               st7703p_720p_video_timings, TIMING_SIZE);
		pinfo->mipi.signature  = ST7703P_720P_VIDEO_SIGNATURE;
		phy_db->regulator_mode = DSI_PHY_REGULATOR_LDO_MODE;
		break;

注意:不要忘记配置供电模式

  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值