需求:RK3288Android7.1上10寸mipi屏兼容
思路:
1、修改屏幕厂商提供的屏幕初始化指令为rk可以识别的格式存放在panel-init-sequence
2、修改屏参display-timings
3、确定reset-gpio
实现:
首先根据屏幕厂商提供的初始化指令将panel-init-sequence填好
//28H & 10H should be sent before host video off
//Resolution:800x1280
//External system porch setting: VS=4 ,VBP=12 ,VFP=20 ,HS=20 ,HBP=80 ,HFP=80
//Frame rate:60HZ
//Power:VCI=3.3, IOVCC=1.8
//SET_HS_BURST
//序数 reg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
SSD_SEND(,地址,寄存器1的值,寄存器2的值,寄存器3值...)
SSD_SEND(0x01,0xE0,0xAB,0xBA);
SSD_SEND(0x01,0xE1,0xBA,0xAB);
SSD_SEND(0x01,0xB1,0x10,0x01,0x47,0xFF);
SSD_SEND(0x01,0xB2,0x0C,0x14,0x04,0x50,0x50,0x14);
SSD_SEND(0x01,0xB3,0x56,0xD3,0x00);
SSD_SEND(0x01,0xB4,0x33,0x20,0x04);//30 正扫 20反扫
SSD_SEND(0x01,0xB6,0xB0,0x00,0x00,0x10,0x00,0x10,0x00);
SSD_SEND(0x01,0xB8,0x56,0x12,0x29,0x29,0x48);//06 正扫 56 反扫
SSD_SEND(0x01,0xB9,0x7C,0x66,0x57,0x4C,0x49,0x3C,0x42,0x2E,0x48,0x47,0x48,0x66,0x54,0x5B,0x4D,0x4A,0x3D,0x27,0x06,0x7C,0x66,0x57,0x4C,0x49,0x3C,0x42,0x2E,0x48,0x47,0x48,0x66,0x54,0x5B,0x4D,0x4A,0x3D,0x27,0x06);
SSD_SEND(0x01,0xC0,0x32,0x23,0x67,0x67,0x33,0x33,0x33,0x33,0x10,0x04,0x88,0x04,0x3F,0x00,0x00,0xC0);
SSD_SEND(0x01,0xC1,0x13,0x14,0x02,0x08,0x10,0x04,0x7D,0x04,0x54,0x00);
SSD_SEND(0x01,0xC2,0x37,0x09,0x08,0x89,0x88,0x21,0x22,0x21,0x44,0xBB,0x18,0x00);
//SSD_SEND(0x01,0xC3,0x89,0x64,0x24,0x07,0x1F,0x1E,0x02,0x16,0x14,0x02,0x12,0x10,0x02,0x0E,0x0C,0x04,0x02,0x02,0x02,0x02,0x02,0x02);//正扫
//SSD_SEND(0x01,0xC4,0x09,0x24,0x24,0x07,0x1F,0x1E,0x02,0x17,0x15,0x02,0x13,0x11,0x02,0x0F,0x0D,0x05,0x02,0x02,0x02,0x02,0x02,0x02);//正扫
SSD_SEND(0x01,0xC3,0x89,0x64,0x24,0x05,0x1F,0x1E,0x02,0x15,0x17,0x02,0x0D,0x0F,0x02,0x11,0x13,0x07,0x02,0x02,0x02,0x02,0x02,0x02);//反扫
SSD_SEND(0x01,0xC4,0x08,0x24,0x24,0x04,0x1F,0x1E,0x02,0x14,0x16,0x02,0x0C,0x0E,0x02,0x10,0x12,0x06,0x02,0x02,0x02,0x02,0x02,0x02);//反扫
SSD_SEND(0x01,0xC6,0x22,0x22);
SSD_SEND(0x01,0xC8,0x21,0x00,0x32,0x40,0x54,0x16);
SSD_SEND(0x01,0xCA,0xCB,0x43);
SSD_SEND(0x01,0xCD,0x0E,0x4F,0x4F,0x25,0x1E,0x6B,0x06,0xB3);
SSD_SEND(0x01,0xD2,0xE3,0x2B,0x38,0x00);
SSD_SEND(0x01,0xD4,0x00,0x01,0x00,0x0E,0x04,0x44,0x08,0x10,0x00,0x07,0x00);
SSD_SEND(0x01,0xE6,0x80,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
SSD_SEND(0x01,0xF0,0x12,0x03,0x20,0x00,0xFF);
DCS_Short_Write_NP(0x11);
Delay(750);//delay 150ms
DCS_Short_Write_NP(0x29);
Delay(100);//delay 20ms
可以看到除了初始化序列,厂商提供了屏参
//Resolution:800x1280
//External system porch setting: VS=4 ,VBP=12 ,VFP=20 ,HS=20 ,HBP=80 ,HFP=80
//Frame rate:60HZ
这样我们可以先将屏参填好
display-timings {
native-mode = <&timing_mipi_7_inch>;
timing_mipi_7_inch: timing_mipi_7_inch {
lane-rante=<600>;
clock-frequency = <77000000>;
hactive = <800>;
vactive = <1280>;
hsync-len = <20>;
hback-porch = <80>;
hfront-porch = <80>;
vsync-len = <4>;
vback-porch = <12>;
vfront-porch = <20>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
V S = v s y n c − l e n VS=vsync-len VS=vsync−len
V B P = v b a c k − p o r c h VBP=vback-porch VBP=vback−porch
V F P = v f r o n t − p o r c h VFP=vfront-porch VFP=vfront−porch
H S = h s y n c − l e n HS=hsync-len HS=hsync−len
H B P = h b a c k − p o r c h HBP=hback-porch HBP=hback−porch
H F P = h f r o n t − p o r c h HFP=hfront-porch HFP=hfront−porch
c l o c k − f r e q u e n c y = ( v s y n c − l e n + v b a c k − p o r c h + v f r o n t − p o r c h + v f r o n t − p o r c h ) ∗ ( h s y n c − l e n + h b a c k − p o r c h + h f r o n t − p o r c h ) ∗ f p s clock-frequency=(vsync-len + vback-porch + vfront-porch+vfront-porch)*(hsync-len +hback-porch+hfront-porch)*fps clock−frequency=(vsync−len+vback−porch+vfront−porch+vfront−porch)∗(hsync−len+hback−porch+hfront−porch)∗fps
然后将初始化指令转化为rk可以识别的格式
转化规则rk说明书上面有:
用得比较多的就是DCS Write,0x15,0x39是用的最频繁的。
SSD_SEND(0x01,0xE0,0xAB,0xBA);
转化为
39 00 03 E0 AB BA
初始化指令转化后为:
panel-init-sequence = [
39 00 03 E0 AB BA
39 00 03 E1 BA AB
39 00 05 B1 10 01 47 FF
39 00 07 B2 0C 14 04 50 50 14
39 00 04 B3 56 D3 00
39 00 04 B4 33 20 04
39 00 08 B6 B0 00 00 10 00 10 00
39 00 06 B8 56 12 29 29 48
39 00 27 B9 7C 66 57 4C 49 3C 42 2E 48 47 48 66 54 5B 4D 4A 3D 27 06 7C 66 57 4C 49 3C 42 2E 48 47 48 66 54 5B 4D 4A 3D 27 06
39 00 11 C0 32 23 67 67 33 33 33 33 10 04 88 04 3F 00 00 C0
39 00 0B C1 13 14 02 08 10 04 7D 04 54 00
39 00 0D C2 37 09 08 89 88 21 22 21 44 BB 18 00
39 00 17 C3 89 64 24 05 1F 1E 02 15 17 02 0D 0F 02 11 13 07 02 02 02 02 02 02
39 00 17 C4 08 24 24 04 1F 1E 02 14 16 02 0C 0E 02 10 12 06 02 02 02 02 02 02
39 00 03 C6 22 22
39 00 07 C8 21 00 32 40 54 16
39 00 03 CA CB 43
39 00 09 CD 0E 4F 4F 25 1E 6B 06 B3
39 00 05 D2 E3 2B 38 00
39 00 0C D4 00 01 00 0E 04 44 08 10 00 07 00
39 00 09 E6 80 01 FF FF FF FF FF FF
39 00 06 F0 12 03 20 00 FF
05 FF 01 11
05 64 01 29
];
如果还是看不懂指令格式怎么转化的可以看一下这个链接,写得很详细
https://blog.csdn.net/qq_38312843/article/details/107534743
reset-gpios = <&gpio7 3 GPIO_ACTIVE_HIGH>;
基本上就没什么问题了。
不出意外的话要出意外了,配置好设备树编译烧录后发现,屏幕黑屏,系统起不来,根据串口日志可以发现以下报错信息:
[ 0.951745] panel-simple-dsi ff960000.dsi.0: panel_simple_parse_cmds: error, len=79
[ 0.951762] panel-simple-dsi ff960000.dsi.0: failed to parse panel init sequence
[ 0.951780] panel-simple-dsi ff960000.dsi.0: failed to get init cmd: -22
[ 0.951797] panel-simple-dsi: probe of ff960000.dsi.0 failed with error -22
定位代码:
可以发现是因为单条指令太长了,rk存不下,然后kernel就挂了。
我们需要将存放命令的数组开大一点就行。
--- a/u-boot/drivers/video/screen/lcd_mipi.c
+++ b/u-boot/drivers/video/screen/lcd_mipi.c
@@ -307,7 +307,7 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
struct list_head *pos;
struct property *prop;
enum of_gpio_flags flags;
- u32 value, i, debug, gpio, ret, cmds[25], length;
+ u32 value, i, debug, gpio, ret, cmds[128], length;
然后屏幕就可以正常点亮了
完整补丁:
diff --git a/kernel/arch/arm/boot/dts/mc-screen.dtsi b/kernel/arch/arm/boot/dts/mc-screen.dtsi
index c3f6a59c7c..d8c3ffa36f 100644
--- a/kernel/arch/arm/boot/dts/mc-screen.dtsi
+++ b/kernel/arch/arm/boot/dts/mc-screen.dtsi
@@ -1362,7 +1362,7 @@
dsi,format = <MIPI_DSI_FMT_RGB888>;
dsi,lanes = <4>;
reset-delay-ms = <20>;
- //init-delay-ms = <20>;
+ init-delay-ms = <200>;
enable-delay-ms = <120>;
prepare-delay-ms = <120>;
status = "disabled";
@@ -1370,38 +1370,57 @@
panel-read-sequence = [];
panel-init-sequence = [
- 15 00 02 80 48
- 15 00 02 81 B8
- 15 00 02 82 88
- 15 00 02 83 88
- 15 00 02 84 58
- 15 00 02 85 D2
- 15 00 02 86 88
- 15 78 02 11 00
- 15 32 02 29 00
+ 39 00 03 E0 AB BA
+ 39 00 03 E1 BA AB
+ 39 00 05 B1 10 01 47 FF
+ 39 00 07 B2 0C 14 04 50 50 14
+ 39 00 04 B3 56 D3 00
+ 39 00 04 B4 33 20 04
+ 39 00 08 B6 B0 00 00 10 00 10 00
+ 39 00 06 B8 56 12 29 29 48
+ 39 00 27 B9 7C 66 57 4C 49 3C 42 2E 48 47 48 66 54 5B 4D 4A 3D 27 06 7C 66 57 4C 49 3C 42 2E 48 47 48 66 54 5B 4D 4A 3D 27 06
+ 39 00 11 C0 32 23 67 67 33 33 33 33 10 04 88 04 3F 00 00 C0
+ 39 00 0B C1 13 14 02 08 10 04 7D 04 54 00
+ 39 00 0D C2 37 09 08 89 88 21 22 21 44 BB 18 00
+ 39 00 17 C3 89 64 24 05 1F 1E 02 15 17 02 0D 0F 02 11 13 07 02 02 02 02 02 02
+ 39 00 17 C4 08 24 24 04 1F 1E 02 14 16 02 0C 0E 02 10 12 06 02 02 02 02 02 02
+ 39 00 03 C6 22 22
+ 39 00 07 C8 21 00 32 40 54 16
+ 39 00 03 CA CB 43
+ 39 00 09 CD 0E 4F 4F 25 1E 6B 06 B3
+ 39 00 05 D2 E3 2B 38 00
+ 39 00 0C D4 00 01 00 0E 04 44 08 10 00 07 00
+ 39 00 09 E6 80 01 FF FF FF FF FF FF
+ 39 00 06 F0 12 03 20 00 FF
+ 05 FF 01 11
+ 05 64 01 29
];
panel-exit-sequence = [
- 05 00 01 28
- 05 78 01 10
+ 05 00 01 28
+ 05 78 01 10
];
display-timings {
native-mode = <&timing_mipi_7_inch>;
timing_mipi_7_inch: timing_mipi_7_inch {
- clock-frequency = <56500000>;
- hactive = <1024>;
- vactive = <600>;
- hsync-len = <10>;
- hback-porch = <160>;
- hfront-porch = <160>;
- vsync-len = <1>;
- vback-porch = <24>;
- vfront-porch = <12>;
+ clock-frequency = <77000000>;
+
+ hactive = <800>;
+ vactive = <1280>;
+
+ hsync-len = <20>;
+ hback-porch = <80>;
+ hfront-porch = <80>;
+
+ vsync-len = <4>;
+ vback-porch = <12>;
+ vfront-porch = <20>;
+
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
- pixelclk-active = <0>;
+ pixelclk-active = <0>;
};
};
};
diff --git a/u-boot/drivers/mc/screen/screen_adapter.c b/u-boot/drivers/mc/screen/screen_adapter.c
index b742fafb84..d6404f1a8f 100644
--- a/u-boot/drivers/mc/screen/screen_adapter.c
+++ b/u-boot/drivers/mc/screen/screen_adapter.c
@@ -77,7 +77,7 @@ static screen screen_list[] = {
* MIPI-DSI Panel
*/
{AUTO_MIPI_10_1_INCH, NULL, 0x00, NULL, NULL, NONE, 0x00, NULL, screen_set_panel_mipi_dsi},
- {AUTO_MIPI_7_INCH, PANEL7_PATH, 400, NULL, NULL, NONE, 0x00, NULL, screen_set_panel_mipi_dsi},
+ {AUTO_MIPI_7_INCH, PANEL7_PATH, 580, NULL, NULL, NONE, 0x00, NULL, screen_set_panel_mipi_dsi},
/**
* eDP Panel
diff --git a/u-boot/drivers/video/rockchip_dsi_panel.c b/u-boot/drivers/video/rockchip_dsi_panel.c
index 5081d3dc5c..a1461a8b8d 100644
--- a/u-boot/drivers/video/rockchip_dsi_panel.c
+++ b/u-boot/drivers/video/rockchip_dsi_panel.c
@@ -176,8 +176,10 @@ static int rockchip_dsi_panel_send_cmds(struct display_state *state,
if (ret)
printf("failed to write cmd%d: %d\n", i, ret);
- if (cmds->cmds[i].dchdr.wait)
- msleep(cmds->cmds[i].dchdr.wait);
+ if (cmds->cmds[i].dchdr.wait){
+ msleep(cmds->cmds[i].dchdr.wait);
+ }
+
}
return 0;
diff --git a/u-boot/drivers/video/screen/lcd_mipi.c b/u-boot/drivers/video/screen/lcd_mipi.c
index cc0d215bdd..a4073e332a 100755
--- a/u-boot/drivers/video/screen/lcd_mipi.c
+++ b/u-boot/drivers/video/screen/lcd_mipi.c
@@ -307,7 +307,7 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
struct list_head *pos;
struct property *prop;
enum of_gpio_flags flags;
- u32 value, i, debug, gpio, ret, cmds[25], length;
+ u32 value, i, debug, gpio, ret, cmds[128], length;
memset(screen, 0, sizeof(*screen));