Android 9 设置双屏显示 平台模块输出mipi信号,通过lt8911exb转接芯片将信号转为edp信号,调试过程如下: 一、添加lt8911exb驱动文件: 1.将驱动文件复制到该路径下:drivers/video/fbdev/msm/ 2.修改该目录下的Makefile和Kconfig; 3.在arch/arm64/configs/msm8953_defconfig(msm8953-perf_defconfig)文件中将驱动文件宏名称设为y并保存; 4.在arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi中添加该驱动: 主屏的转接芯片驱动,挂载i2c_3上:
副屏的转接芯片驱动,挂载在i2c_2上:将副屏的背光控制脚加进去了,本来是在 arch/arm64/boot/dts/qcom/msm8953-nopmi-panel-camera.dtsi
&mdss_dsi1 { //qcom,platform-bklight-en-gpio = <&tlmm 40 0>; }; 修改后报错,就没有在此处更改。
A = hact + hfp + hbp + hs = 1526 B = vact + vfp + vbp + vs = 790 plck = A × B × fp(60) 二、验证该驱动添加内核成功并执行了probe函数 1.编译make bootimage -j4 ; make dtboimage -j4; 2.烧录成功后,查看log: 3.若log中没有执行到probe函数,则需依次排查原因: (1)cd out/target/product/msm8953_64/obj/KERNEL_OBJ/drivers/video/fbdev/msm/ 查看目录下是否有目标驱动的中间文件; (2)i2c:cat /sys/bus/i2c/devices/3-0029/name ls /sys/bus/i2c/drivers/ 查看驱动设备是否正常挂载到i2c总线上; (3)dtsi:属性匹配名称是否完全一致; 三、配置LCD屏参数 配置分为两个阶段:lk阶段和kernel阶段。 准备:根据硬件电路确认lcd的vdd,reset,te,背光的GPIO,lcd屏为博立亚的15.6寸主屏,11.6的副屏;edp接口,1个edp通道;(项目使用了vdd,reset和背光引脚),通道速率分别是1.62G和2.7G。
lk阶段: 1.根据LCD规格书配置该文件的屏参数:bootable/bootloader/lk/dev/gcdb/display/include/panel_ili9881d_720p_video.h
static struct panel_config ili9881d_720p_video_panel_data = { “qcom,mdss_dsi_ili9881d_720p_video”, /* panel_node_id / “dsi:0:”, / panel_controller / “qcom,mdss-dsi-panel”, / panel_compatible / 10, / panel_interface / 0, / panel_type / “DISPLAY_1”, / panel_destination / 0, / panel_orientation / 0, / panel_clockrate / 60, / panel_framerate / 0, / panel_channelid / 0, / dsi_virtualchannel_id / 0, / panel_broadcast_mode / 0, / panel_lp11_init / 0, / panel_init_delay / 0, / dsi_stream / 0, / interleave_mode / 0, / panel_bitclock_freq / 0, / panel_operating_mode / 0, / panel_with_enable_gpio / 0, / mode_gpio_state / “qcom,mdss_dsi_ili9881d_720p_dsi1_video” / 添加副屏名称 */ };
static struct panel_resolution ili9881d_720p_video_panel_res = { 1366, /* panel_width / 768, / panel_height / 70, / hfront_porch / 70, / hback_porch / 10, / vfront_porch / 10, / vback_porch / 2, / vpulse_width */
static struct lane_configuration ili9881d_720p_video_lane_config = { 4, 0, 1, 1, 1, 1, 1(最后一个1代表高速模式)
static const uint32_t ili9881d_720p_video_timings[] = { 0xf3, 0x3a, 0x26, 0x00, 0x6a, 0x6e, 0x2c, 0x3E, 0x2f, 0x03, 0x04, 0x00 //该timing值数组代表lcd的时序,可根据高通的一个表格计算得到;
static struct panel_timing ili9881d_720p_video_timing_info = { 0, /* dsi_mdp_trigger / 4, / dsi_dma_trigger / 0x0a, / tclk_post /data由hs->lp,hs clk需要继续发送byteclk周期个数; 0x1D / tclk_pre */data由lp->hs,hs clock需要hold住的byteclk周期个数; //主要修改post和pre的值,根据高通的表格计算可以得到。
将lt8911exb驱动文件修改为普通的执行文件,将其添加在bootable/bootloader/lk/target/msm8953/目录下,使其在lk阶段生效,可以显示开机logo等kernel启动前的显示内容。这样就不用将主屏转接芯片驱动添加到内核中了。
相关配置如下: /bootable/bootloader/lk/include/target.h @@ -121,4 +121,5 @@ bool target_battery_is_present(); uint32_t target_get_pmic(); int target_update_cmdline(char *cmdline); int target_get_vb_version(); void lt8911exb_config(void);//声明驱动的入口函数
将mipi输出强制改成高速,调试过程中发现,不改会影响副屏显示。
配置背光引脚:
pin_source表示GPIO源,如果是pmic上的引脚则pm8941_gpios,cpu上的引脚是msmgpio。
配置屏的数据,使屏在boot阶段启动: /bootable/bootloader/lk/target/msm8953/oem_panel.c
static int init_panel_data():
int oem_panel_select():
lk阶段配置可参考patch:包含i2c总线的配置,时钟的配置。 Kernel阶段配置: 1.添加屏参数的dtsi,并将屏参数dtsi复制到该路径下: arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi
2.根据屏的规格书修改相关参数; 主屏:arch/arm64/boot/dts/qcom/dsi-panel-ili9881d-720p-video.dtsi: &mdss_mdp { dsi_ili9881d_720p_video: qcom,mdss_dsi_ili9881d_720p_video { qcom,mdss-dsi-panel-name = “ili9881d 720p video mode dsi panel”; qcom,mdss-dsi-panel-controller = <&mdss_dsi0>;//面板控制器,对mdss-dsi0的配置在msm8953-mdss.dtsi qcom,mdss-dsi-panel-type = “dsi_video_mode”;//设置屏为video模式 qcom,mdss-dsi-panel-destination = “display_1”;//指定目标面板 qcom,mdss-dsi-panel-framerate = <60>;//帧率刷新60Hz(VSYNC) qcom,mdss-dsi-virtual-channel-id = <0>;//虚拟通道标识,0为默认值 qcom,mdss-dsi-stream = <0>;//指定使用的数据包流,0:默认值 qcom,mdss-dsi-panel-width = <1366>;//宽度像素 qcom,mdss-dsi-panel-height = <768>;//高度像素 qcom,mdss-dsi-h-front-porch = <70>;//水平前肩:VDEN到HSYNC之间的vclk的个数 qcom,mdss-dsi-h-back-porch = <70>;//水平后肩:HSYNC到VDEN的vclk的个数 qcom,mdss-dsi-h-pulse-width = <20>;//HSYNC的脉冲宽度,单位是行数; qcom,mdss-dsi-h-sync-skew = <0>;//水平同步偏移值 qcom,mdss-dsi-v-back-porch = <10>;//垂直后肩:VYSNC开始后到VDEN使能之间的行数 qcom,mdss-dsi-v-front-porch = <10>;//垂直前肩:VDEN结束后到VYSNC之间的行数 qcom,mdss-dsi-v-pulse-width = <2>;//VYSNC的脉冲宽度,单位是行数 qcom,mdss-dsi-h-left-border = <0>;//水平左边框值,0:默认值 qcom,mdss-dsi-h-right-border = <0>;//水平有边框值 qcom,mdss-dsi-v-top-border = <0>;//垂直上边框值 qcom,mdss-dsi-v-bottom-border = <0>;//垂直下边框值 qcom,mdss-dsi-bpp = <24>;//像素深度,RGB888 qcom,mdss-dsi-color-order = “rgb_swap_rgb”;//msm rgb->panel rgb通道顺序对应 qcom,mdss-dsi-underflow-color = <0xff>; qcom,mdss-dsi-border-color = <0>; qcom,mdss-dsi-on-command = [ //面板的初始化指令 05 01 00 00 78 00 02 11 00 //0x11:sleep out 05 01 00 00 14 00 02 29 00]; //0x29:display on qcom,mdss-dsi-off-command = [ //取消初始化指令 05 01 00 00 32 00 02 28 00 05 01 00 00 78 00 02 10 00]; qcom,mdss-dsi-on-command-state = “dsi_lp_mode”;//发送初始化指令后的状态为LP (low power)模式 qcom,mdss-dsi-off-command-state = “dsi_hs_mode”;//取消command模式后状态设置为HS高速模式 qcom,mdss-dsi-h-sync-pulse = <1>;//水平同步脉冲,决定硬件是否在垂直消隐期间发送水平同步脉冲; qcom,mdss-dsi-traffic-mode = “burst_mode”;// non burst with sync pulses //”non burst with sync start event” qcom,mdss-dsi-lane-map = “lane_map_0123”; qcom,mdss-dsi-bllp-eof-power-mode; qcom,mdss-dsi-bllp-power-mode; qcom,mdss-dsi-lane-0-state; qcom,mdss-dsi-lane-1-state; qcom,mdss-dsi-lane-2-state; qcom,mdss-dsi-lane-3-state; qcom,mdss-dsi-force-clock-lane-hs;//强制将DSI置于高速模式 qcom,mdss-dsi-always-on; qcom,mdss-dsi-panel-timings = [7A 1A 12 00 3E 42 16 1E 14 03 04 00];//LCD的时序值,可以通过高通的表格计算得到。 qcom,mdss-dsi-t-clk-post = <0x0a>;//data由hs->lp,hs clk需要继续发送byteclk周期个数; qcom,mdss-dsi-t-clk-pre = <0x1D>;//data由lp->hs,hs clock需要hold住的byteclk周期个数; qcom,mdss-dsi-bl-min-level = <1>;//最小背光值 qcom,mdss-dsi-bl-max-level = <4095>; qcom,mdss-dsi-dma-trigger = “trigger_sw”;//通过软件触发DMA; qcom,mdss-dsi-mdp-trigger = “none”;// qcom,mdss-dsi-bl-pmic-control-type = “bl_ctrl_wled”;//通过wled控制背光 qcom,mdss-dsi-reset-sequence = <1 5>, <0 10>, <1 120>; qcom,mdss-dsi-post-init-delay = <4>; qcom,mdss-pan-physical-width-dimension = <59>; qcom,mdss-pan-physical-height-dimension = <104>; }; };
//参数含义可参考documentation/devicetree/bindings/drm/msm/mdss-dsi-panel.txt
副屏:arch/arm64/boot/dts/qcom/dsi-panel-ili9881d-720p-dsi1-video.dtsi: (可以直接copy主屏的该文件进行修改),除了修改LCD对应的参数外,还需: 屏蔽掉: //qcom,mdss-dsi-panel-controller = <&mdss_dsi0>; qcom,mdss-dsi-panel-type = “dsi_video_mode”;//设置屏为video模式 //qcom,mdss-dsi-panel-destination = “display_1”;
3.更改主副屏其他参数: arch/arm64/boot/dts/qcom/msm8953-nopmi-panel-camera.dtsi
&mdss_dsi { //修改为双通道dsi hw-config = “dual_dsi”; //“dual_dsi”; //“single_dsi”; };
&mdss_dsi0 { qcom,dsi-pref-prim-pan = <&dsi_ili9881d_720p_video>; pinctrl-names = “mdss_default”, “mdss_sleep”; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; //qcom,platform-te-gpio = <&tlmm 24 0>;//未使用 //qcom,platform-reset-gpio = <&tlmm 61 0>; qcom,platform-bklight-en-gpio = <&tlmm 23 0>;//修改背光脚 };
&mdss_dsi1 { status = “ok”; qcom,dsi-pref-prim-pan = <&dsi_ili9881d_720p_dsi1_video>; pinctrl-names = “mdss_default”, “mdss_sleep”; pinctrl-0 = <&mdss_dsi1_active &mdss_te1_active>; pinctrl-1 = <&mdss_dsi1_suspend &mdss_te1_suspend>;//没有使用TE,所以不用更改*.pinctrl.dtsi的相应配置 qcom,bridge-index = <0>;//dba的配置 qcom,pluggable;//dba的配置 //qcom,platform-te-gpio = <&tlmm 25 0>; //qcom,platform-reset-gpio = <&tlmm 87 0>; //qcom,platform-bklight-en-gpio = <&tlmm 40 0>; }; //mdss_dsi,mdss_dsi0,mdss_dsi1定义在msm8953-mdss.dtsi中。
&dsi_ili9881d_720p_video { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; qcom,mdss-dsi-bl-pmic-control-type = “bl_ctrl_pwm”;//更改背光通过PWM控制 qcom,mdss-dsi-bl-pmic-pwm-frequency = <100>; qcom,mdss-dsi-bl-pmic-bank-select = <0>; qcom,mdss-dsi-pwm-gpio = <&pm8953_mpps 4 0>; };
&dsi_ili9881d_720p_dsi1_video { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; qcom,dba-panel;//dba的配置 qcom,bridge-name = “dsi1-bridge”; }; //dba:(display bridge abstract),显示桥抽象层。作用是检测有其他桥接芯片连接,并将其事件发送HAL层处理。 在kernel中,drivers/video/fbdev/msm/mdss_dsi.c中,probe函数对dba有相应的创建工作队列和初始化操作:
可参考:https://blog.csdn.net/xishuang_gongzi/article/details/78076752
4.将mipi输出强制改为高速模式,不然影响副屏点亮。
5.drivers/video/fbdev/msm/mdss_dba_utils.c内定义宏:
该宏设置的对应timing参数在include/uap/video/msm_hdmi_modes.h中:
将屏相应参数补充到数组中,此处的参数会替代lk中lk/dev/gcdb/display/include里面相应的.h文件里面的参数。因此副屏并不需要在lk中添加.h文件。
四、调试 make bootimage ; make aboot; make dtboimage ;编译烧录后: 1.首先确认iic驱动挂载成功,屏添加成功: cat proc/cmdline
2.先看背光,主副屏背光不亮:使用万用表测模块GPIO口的电压输出,如果没有电压,需要检查软件配置: (1)arch/arm64/boot/dts/qcom/msm8953-nopmi-panel-camera.dtsi; (2)/bootable/bootloader/lk/target/msm8953/target_display.c ; (3)副屏背光配置在副屏的转接芯片驱动中; 软件配置正确,gpio有1.8v输出电压,然后测插口基座处有3.3v电压,此时背光就点亮了,如果还是不亮,就换一块屏幕或者请硬件工程师协助分析;
3.背光点亮后,LCD屏没有显示,分析: (1)模组没有输出mipi信号(检查相关的软件配置)、示波器测mipi信号。 (2)LCD相关的时序timing值,平台mipi的timing等参数配置不正确; (3)转接芯片IC的驱动对LCD的相关配置:屏支持的line数,通道速率;色深;video模式等;以及相应的寄存器配置问题,可以找供应商协助; (4)对比硬件图测量屏接口基座的电压值,各个pin针的电压是否正确; (5)确认硬件没有问题,转接芯片寄存器没有问题之后,还是不亮,就需要多检查软件配置。
其他参考: https://www.lcdfans.com/582.html https://blog.csdn.net/liwei16611/category_6263565.html
Video模式和command模式: Command:需要IC自带GRAM,在mipi四条data line中,只能使用line0,且在LP模式,通过ACK和error与Host通信; Video模式:不需要GRAM,要通过四通道不断给panel刷数据,
|