任务:rk3128 的GM8775模块(mipi->lvds)点亮lvds屏幕
实现方法一:通过配置mipi,使用mipi指令对gm8775初始化,从而点亮lvds屏
实现方法二:通过配置i2c,使用i2c传入指令初始化gm8775,从而点亮lvds屏
第一步:使用公版的sdk,启动rk3128的板子。
启动板子最重要的一步是配置好电源,当电源配置好后板子就能正常跑起来。
(1)配置电源时要注意使用的是pmu还是dcdc,pmu正常是rk8xx这些,需要在dts中添加对应的节点。
方法是,在其它dts中找到相同的节点,然后参考,记得要disabled掉dcdc的节点
&pwm_regulator1 {
status = "disabled";
};
&pwm_regulator2 {
status = "disabled";
};
配置pmu还要注意将gpio口和原理图对应,一个int设为high,一个sleep设为low。
还有一个问题就是要将pmu的驱动对应起来。否则系统会一直卡在rk8xx无法进入,我最开始就是没注意,卡在这个问题上。
要启动系统还有一些基本的东西需要配置,比如emmc,需要okay,并且disabled掉nand,如下
&nandc {
status = "disabled"; // used nand set "okay" ,used emmc set "disabled"
};
&nandc0reg {
status = "okay"; // used nand set "disabled" ,used emmc set "okay"
};
&emmc {
status = "okay";
};
正常情况下,到了这里,将hdmi打开,就会有hdmi的显示了。
(2)先使用方法一配置屏幕
方法一是通过在dts中直接配置mipi,然后使用mipi指令,对8775进行初始化。mipi配置的框架如下
首先注意打开mipi节点
&dsihost0 {
status = "okay";
};
接下来是配置mipi相关的配置
&disp_timings {
status = "okay";
};
&rk_screen {
status = "okay";
display-timings = <&disp_timings>;
};
&fb {
status = "okay";
rockchip,disp-mode = <DUAL>; // DUAL ONE_DUAL NO_DUAL
rockchip,disp-policy = <DISPLAY_POLICY_BOX>;
rockchip,uboot-logo-on = <1>;
};
&lcdc {
status = "okay";
backlight = <&backlight>;
rockchip,fb-win-map = <FB0_WIN0_FB1_WIN1_FB2_WIN2>;
};
/这里截取一手readmine上的解析**/
DTSI解析:
1.
disp_mipi_init: mipi_dsi_init{
compatible = "rockchip,mipi_dsi_init";
rockchip,screen_init = <1>;
//mipi屏是否需要初始化
rockchip,dsi_lane = <4>;
//每个mipi有几个lane
rockchip,dsi_hs_clk = <940>;
//屏ddr clock;计算公式:100+H_total*V_total*fps*3*8/lanes,(H_total,V_total
包括active,bp,fp 和sync-len的和;fps为帧率,开始时,fps为50多帧就
好,然后慢慢抬高;3为一个像素点为rgb 3个字节;8为8-bits;lanes为
(dsi_lane*mipi_dsi_num) )。实际的结果要比理论值大100M左右。
rockchip,mipi_dsi_num = <2>;
//单mipi还是双mipi
};
- 屏电源控制,可以移到lcdc的dtsi里。
disp_mipi_power_ctr: mipi_power_ctr {
compatible = "rockchip,mipi_power_ctr";
mipi_lcd_rst:mipi_lcd_rst{
compatible = "rockchip,lcd_rst";
rockchip,gpios = <&gpio7 GPIO_B2 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
mipi_lcd_en:mipi_lcd_en {
compatible = "rockchip,lcd_en";
rockchip,gpios = <&gpio6 GPIO_A7 GPIO_ACTIVE_HIGH>;
rockchip,delay = <10>;
};
};
- 屏初始化命令
disp_mipi_init_cmds: screen-on-cmds {
rockchip,cmd_debug = <0>;
compatible = "rockchip,screen-on-cmds";
rockchip,on-cmds1 {
//命令名字,只要不重复,可以随便取。
compatible = "rockchip,on-cmds";
rockchip,cmd_type = <LPDT>; //是否打开debug HSDT参数为关闭debug
//命令是在low power还是high speed下发送。
rockchip,dsi_id = <2>;
//命令通过哪个mipi发送,对于单mipi,这个值始终是0;对于双mipi,这个值是2。
rockchip,cmd = <0x39 0x0a 0x01 0x03>;
//命令格式:命令type+命令+参数。
rockchip,cmd_delay = <10>;
//命令发送完延时。
};
- 屏参相关
display timing:
disp_timings: display-timings {
native-mode = <&timing0>;
compatible = "rockchip,display-timings";
timing0: timing0 {
screen-type = <SCREEN_DUAL_MIPI>;
//单mipi:SCREEN_MIPI;双mipi:SCREEN_DUAL_MIPI
lvds-format = <LVDS_8BIT_2>;
//无效属性
out-face = <OUT_P888>;
//pixel format
clock-frequency = <265000000>;
//lcdc送pixel速率,计算公式:H*V(包括同步信号)*fps
hactive = <2560>;
//水平有效像素
vactive = <1600>;
//竖直有效像素
hsync-len = <38>;//19
hback-porch = <40>;//40
hfront-porch = <108>;//123
//水平同步信号
vsync-len = <4>;
vback-porch = <4>;
vfront-porch = <12>;
//竖直同步信号
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
swap-rb = <0>;
swap-rg = <0>;
swap-gb = <0>;
};
};
/************************************************************************************/
需要注意一般有需要修改到的地方:
&fb {
status = "okay";
rockchip,disp-mode = <DUAL>; // DUAL ONE_DUAL NO_DUAL 表示是几通道的
rockchip,disp-policy = <DISPLAY_POLICY_BOX>;
rockchip,uboot-logo-on = <1>; //如果不显示,可以尝试把这个节点改为0 或者改为1测试
};
当然,配置完这些,还有需要注意的就是backlight的配置,需要配置对应的bl_en 的gpio,lcdc_bl的pwm。
这边注意pwm几需要对应的是lcd_bl的pwm。并记得将该pwm使能。由于之前配置edp屏的时候,有记录,所以配置backlight的时候没有碰到什么问题。
接下来就是屏参数的配置,和mipi指令的发送问题了。主要是在disp_mipi_init_cmds节点中配置。节点的配置一般没什么问题,问题主要在与配置的指令不对。(需要注意mipi指令格式 ,本次调试使用的不是DCS指令格式,具体查阅数据手册,每次调屏的时候都需要注意,之前有调试过一个mipi使用的是DCS)
最后注意配置完还不显示,注意将其他显示的设备都拔出,可能会被其他显示占用。本次调试,后面花费了较多时间查的时候,后面发现是hdmi没有拔除。导致屏幕一直没有显示。
(3)使用方法二进行屏幕配置
方法二是通过i2c的指令进行配置。
首先要知道i2c驱动框架的写法,然后需要注意的是,需要将设备注册成i2c设备,并将驱动注册进总线。其它在也和其它驱动类似,总体没有碰到什么问题。
在dts中需要配置的节点,如下:
&i2c3 {
status = "okay";
clock-frequency = <400000>;
gm8775: gm8775@2d {
compatible = "gm8775,mipi";
reg = <0x2d>;
status = "okay";
};
};
在本次调试中,关于调试i2c碰到的一个问题就是i2c频率的问题,正常是没有看到配置的。但是在调试时,发现写入数据一直报错。后发现是频率问题。修改方法如下:
struct i2c_msg msg[2] = {
[0] = {
.addr = i2c_c->addr,
.flags = i2c_c->flags,
.len = sizeof(txbuf),
.buf = txbuf,
.scl_rate = 400000,
},
在配置i2c_msg结构变量时,配置.scl_rate的值,并使它和dts中的对应。
其它要注意的就是指令的值,即配置寄存器的值,比如屏参,时钟频率,对应的是mipi的,还是其他的。
i2c指令的方法调试,在用mipi指令调试(确保mipi的配置没有问题)后,基本没有什么大的问题。
(注意使用i2c方法初始化的时候,需要将rockchip,screen_init = <1>改为<0>,则为不使用mipi初始化)
继本次调试之后,再记录一个之前调过的mipi屏幕的框架
&dsi {
status = "okay";
panel@0 {
compatible ="simple-panel-dsi";
reg = <0>;
power-supply = <&vcc3v3_lcd>;
backlight = <&backlight>;
prepare-delay-ms = <60>;
enable-delay-ms = <200>;
disable-delay-ms = <200>;
unprepare-delay-ms = <80>;
reset-delay-ms = <80>;
init-delay-ms = <80>;
dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
dsi,format = <MIPI_DSI_FMT_RGB888>;
dsi,lanes = <4>;
panel-init-sequence = [
。。。 //时序
];
panel-exit-sequence = [
05 14 01 28
05 78 01 10
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <37000000>;
hactive = <480>;
vactive = <1280>;
hfront-porch = <1>;
hsync-len = <4>;
hback-porch = <1>;
vfront-porch = <2>;
vsync-len = <4>;
vback-porch = <2>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&dsi_in_vopb {
status = "okay";
};
&dsi_in_vopl {
status = "disabled";
};
&i2c1 {
status = "okay";
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_xfer>;
hanvonpen: hanvonpen@18 { //触屏模块
status = "okay";
compatible = "Hanvon0868";
reg = <0x18>;
touch-gpio = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>;
reset-gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
};
};