[rk3288][Android5.1/7.1 LCD 兼容]

参见改进方案:https://intgyl.com/post/84b102bf.html#more

## 兼容方案 ### 定做LCD fpc
1
2
3
4
5
6
该方案是硬件设计时预留几个gpio,不同厂家的屏对不同的gpio进行上拉或者下拉,将上下拉电阻直接贴到fpc上,
系统启动时读取gpio电平进行判断。
优点:
硬件更改版号时不需要考虑屏的区别,软件无需单独出版本,生产时也没有烧录错误的风险,该方案对我们来说是最简单的。
缺点:
需要模组厂配合。
### 软件读取IC的 ID
1
2
3
4
5
该方案是在系统启动时读取 LCD IC的寄存器,不同的IC其内容不同,以此达到区分的目的。
优点:
该方案不需要模组厂配合,硬件也无需考虑屏的区别,在明确LCD IC的情况下,可以考虑使用。
缺点:
如果不同模组厂使用的是相同的IC该方案便不可行。

使用gpio

1
2
3
4
5
该方案对软件来说与方案1相同,不同点在于该方案是将上下拉电阻贴到PCB板上。
优点:
不依赖模组厂。
缺点:
针对不同的屏在贴片时需要做区分,如果后期改换其他屏,需要修改电阻,该方案只能做到软件兼容,硬件无法兼容。

增加特定分区

1
2
3
4
5
6
该方案是在原有的emmc或ufs分区的基础上增加一个oem分区,在生产时针对不同的屏烧录对应的oem.img文件即可。
优点:
该方案可以做到软硬件同时兼容,如果后期需要更换,只需要重新烧录对应的oem.img文件即可,同时一些特有的信息也可以添加到该分区,
软件升级时无需对该分区进行操作。
缺点:
生产时需要区分不同的屏,不能出现烧录错误的情况,否则会出现显示异常。

Parameter.txt(rk平台特有)

1
2
该方案效果与方案4相同,都是修改commandline,区别在于方案4是读取oem分区的内容后再修改,该方案时直接修改原始commandline。
优缺点与方案4相同。

根据项目实际情况采用方案5, 以下介绍兼容过程中涉及的修改。

Android5.1

Device tree修改

公共部分

由于该平台在LCD兼容方面做的不完善,无法直接将不同dtsi文件包含到平台中,所有LCD devicetree文件中包含的内容是完整的(LCD的上下电、reset、command、timging等),因此需要将不同的devicetree之间相同的部分抽离出来。中对应的是下图部分(lcd-power-common-gpio.dtsi),该部分是对LCD的上下电和reset操作。

不同部分

不同的LCD其command和timing会有所区别,需要将这部分独立出来, 如下图:

由于代码在解析dtb文件时是通过名称来匹配,因此在抽离不同部分后需要修改对应的节点名称:

uboot 代码修改

在进行LCD初始化前,读取parameter.txt中commandline的LCD信息,保存在global date结构中。使用方案5时commandline中已经包含了LCD信息,因此uboot中无需修改。


由于在devicetree中修改了dts节点名称,此处需要根据不同的屏加载对应的内容。


整体的修改思路是:在进行LCD初始化前完成识别操作,原有代码初始化LCD时读取的节点是写死的,修改后根据判断动态获取。

kernel 修改

LCD驱动

Kernel中对LCD驱动的修改思路与修改内容与uboot一样,此处不在详细描述,以下是kernel修改的相关patch

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
diff --git a/kernel/drivers/video/of_display_timing.c b/kernel/drivers/video/of_display_timing.c
index 9905a39..cb0139b 100644
--- a/kernel/drivers/video/of_display_timing.c
+++ b/kernel/drivers/video/of_display_timing.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <video/display_timing.h>
#include <video/of_display_timing.h>
+#include <linux/lcd_compatible.h>

@@ -164,13 +165,18 @@ struct display_timings *of_get_display_timings(struct device_node *np)
struct device_node *entry;
struct device_node *native_mode;
struct display_timings *disp;
+ char node_name[STRING_LEN];

if (!np) {
pr_err("%s: no devicenode given\n", of_node_full_name(np));
return NULL;
}

- timings_np = of_find_node_by_name(np, "display-timings");
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "display-timings", strlen("display-timings"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+
+ timings_np = of_find_node_by_name(np, node_name);
if (!timings_np) {
pr_err("%s: could not find display-timings node\n",
of_node_full_name(np));
@@ -270,11 +276,16 @@ EXPORT_SYMBOL_GPL(of_get_display_timings);
int of_display_timings_exist(struct device_node *np)
{
struct device_node *timings_np;
+ char node_name[STRING_LEN];

if (!np)
return -EINVAL;

- timings_np = of_parse_phandle(np, "display-timings", 0);
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "display-timings", strlen("display-timings"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+
+ timings_np = of_parse_phandle(np, node_name, 0);
if (!timings_np)
return -EINVAL;

diff --git a/kernel/drivers/video/rockchip/screen/lcd_mipi.c b/kernel/drivers/video/rockchip/screen/lcd_mipi.c
index fbb95c7..ffdc543 100755
--- a/kernel/drivers/video/rockchip/screen/lcd_mipi.c
+++ b/kernel/drivers/video/rockchip/screen/lcd_mipi.c
@@ -32,6 +32,7 @@
#include <lcd.h>
#include "../transmitter/mipi_dsi.h"
#endif
+#include <linux/lcd_compatible.h>

#ifdef CONFIG_RK_3288_DSI_UBOOT
#define MIPI_SCREEN_DBG(x...) /* printf(x) */
@@ -46,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define printk(x...) /* printf(x) */
#endif
static struct mipi_screen *gmipi_screen;
+char lcd_module[STRING_LEN];

static void rk_mipi_screen_pwr_disable(struct mipi_screen *screen)
{
@@ -283,6 +285,31 @@ int rk_mipi_screen_standby(u8 enable)
}
return 0;
}
+
+int lcd_detect()
+{
+ char *panel_name = NULL;
+
+ panel_name = strstr(saved_command_line, RK_MIPI);
+ if (NULL != panel_name) {
+ if (0 == strncmp(panel_name, CMDLINE_HANVON, strlen(CMDLINE_HANVON))) {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] hanvon\n");
+ } else if (0 == strncmp(panel_name, CMDLINE_WACOM, strlen(CMDLINE_WACOM))) {
+ strncpy(lcd_module, WACOM, strlen(WACOM));
+ pr_info("[lcd_detect] wacom");
+ } else {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] default hanvon(no matched lcd)\n");
+ }
+ } else {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] default hanvon(no cmdline)\n");
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_LCD_MIPI
static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
{
@@ -294,12 +321,17 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
//u32 value, i, debug, gpio, ret, length;
//u32 cmds[sizeof(dcs_cmd->dcs_cmd.cmds) / sizeof(u32)];
u32 value, i, debug, gpio, ret, cmds[64], length;//david
+ char node_name[STRING_LEN];

memset(screen, 0, sizeof(*screen));

INIT_LIST_HEAD(&screen->cmdlist_head);

- childnode = of_find_node_by_name(NULL, "mipi_dsi_init");
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "mipi_dsi_init", strlen("mipi_dsi_init"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+
+ childnode = of_find_node_by_name(NULL, node_name);
if (!childnode) {
MIPI_SCREEN_DBG("%s: Can not get child => mipi_init.\n", __func__);
} else {
@@ -422,7 +454,11 @@ static int rk_mipi_screen_init_dt(struct mipi_screen *screen)
}
}

- root = of_find_node_by_name(NULL, "screen-on-cmds");
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "screen-on-cmds", strlen("screen-on-cmds"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+
+ root = of_find_node_by_name(NULL, node_name);
if (!root) {
MIPI_SCREEN_DBG("can't find screen-on-cmds node\n");
} else {
@@ -722,6 +758,9 @@ int rk_mipi_screen_probe(void)
return -ENOMEM;
}
#ifdef CONFIG_OF_LIBFDT
+
+ lcd_detect();
+
ret = rk_mipi_screen_init_dt(gmipi_screen);
if (ret < 0) {
printf(" rk_mipi_screen_init_dt fail!\n");
@@ -745,6 +784,8 @@ static int __init rk_mipi_screen_probe(struct platform_device *pdev)
return -ENOMEM;
}

+ lcd_detect();
+
ret = rk_mipi_screen_init_dt(gmipi_screen);
if (ret < 0) {
dev_err(&pdev->dev, " rk_mipi_screen_init_dt fail!\n");
diff --git a/kernel/include/linux/lcd_compatible.h b/kernel/include/linux/lcd_compatible.h
new file mode 100644
index 0000000..778ac86
--- /dev/null
+++ b/kernel/include/linux/lcd_compatible.h
@@ -0,0 +1,13 @@
+#ifndef _LCD_COMPATIBLE_H
+#define _LCD_COMPATIBLE_H
+
+#define STRING_LEN 32
+#define HANVON "_hanvon"
+#define WACOM "_wacom"
+
+#define RK_MIPI "rk_mipi_dsi"
+#define CMDLINE_HANVON "rk_mipi_dsi_ili9881c_hanvon"
+#define CMDLINE_WACOM "rk_mipi_dsi_ili9881c_wacom"
+
+extern char lcd_module[STRING_LEN];
+#endif /* _LCD_COMPATIBLE_H */

Touch panel驱动

更换LCD后触摸屏也可能会改变,此时需要在不同的TP驱动中增加判断。


parameter.txt 修改

使用方案 5时,需要针对每一款屏增加一个parameter.txt文件,如下图:

与原始文件的区别仅在于commandline中增加了对应的lcd信息:

编译脚本修改

编译脚本中只需将所有的parameter 文件拷贝到release目录下即可,烧录时选择对应文件即可。

新加一款屏

uboot修改

在现有代码基础上增加一款屏,在uboot增加对应的定义,增加parameter文件即可。

fdt_compat_id 中增加相应的枚举类型。

compat_names中增加类型对应的dts节点名称。

parameter

device/rockchip/rk3288 目录下增加一个对应的文件parameter_xxx.txt, 其中的CMDLINE最后修改为对应的名称即可,名称要以1rk_mipi_dsi开头, 该名称根据代码解析自定义。

其他修改

将新LCD对应的dtsi加到 g3288.dts中,对应的TP驱动做相关判断即可

Android 7.1

Android7.1中LCD 兼容修改要简单一些,rockchip在lcd驱动方面有所修改,兼容思路与Android5.1中的修改相同,其中parameter中的修改相同,此处不再赘述。

uboot 修改

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
39
40
41
42
43
44
45
46
47
48
49
diff --git a/u-boot/board/rockchip/common/rkloader/parameter.c b/u-boot/board/rockchip/common/rkloader/parameter.c
index bc8a0d4..47db825 100755
--- a/u-boot/board/rockchip/common/rkloader/parameter.c
+++ b/u-boot/board/rockchip/common/rkloader/parameter.c
@@ -10,10 +10,36 @@

#include "../config.h"
#include "parameter.h"
+#include <lcd.h>


BootInfo gBootInfo;

+static int lcd_detect()
+{
+ char *panel_name = NULL;
+ panel_name = strstr(gBootInfo.cmd_line, RK_MIPI);
+ if (NULL != panel_name) {
+
+ if (0 == strncmp(panel_name, CMDLINE_WACOM, strlen(CMDLINE_WACOM))) {
+ strncpy(gd->lcd_module, WACOM, strlen(WACOM));
+ printf("[lcd_detect_oem] lcd_module = %s\n", gd->lcd_module);
+ } else if (0 == strncmp(panel_name, CMDLINE_HANVON, strlen(CMDLINE_HANVON))) {
+ strncpy(gd->lcd_module, HANVON, strlen(HANVON));
+ printf("[lcd_detect_oem] lcd_module = %s\n", gd->lcd_module);
+ } else {
+ strncpy(gd->lcd_module, HANVON, strlen(HANVON));
+ printf("[lcd_detect_oem] default lcd_module = %s\n", gd->lcd_module);
+ }
+
+ } else {
+ strncpy(gd->lcd_module, HANVON, strlen(HANVON));
+ printf("[lcd_detect_oem] panel_name is null, lcd_module = %s\n", gd->lcd_module);
+ }
+
+ return 0;
+}
+
static int find_mtd_part(cmdline_mtd_partition *this_mtd, const char *part_name)
{
int i = 0;
@@ -411,5 +437,7 @@ end:
if (param)
free(param);

+ lcd_detect();
+
return ret;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
diff --git a/u-boot/drivers/video/rockchip_display.c b/u-boot/drivers/video/rockchip_display.c
index f477b20..bfbef19 100644
--- a/u-boot/drivers/video/rockchip_display.c
+++ b/u-boot/drivers/video/rockchip_display.c
@@ -363,8 +363,14 @@ static int display_get_timing_from_dts(int panel, const void *blob,
int hfront_porch, hback_porch, hsync_len;
int vfront_porch, vback_porch, vsync_len;
int val, flags = 0;
+ char node_name[128];

- timing = fdt_subnode_offset(blob, panel, "display-timings");
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "display-timings", strlen("display-timings"));
+ strncat(node_name, gd->lcd_module, strlen(gd->lcd_module));
+ printf("[lcd_detect_timings] node_name = %s, %s: %d\n",node_name, __func__, __LINE__);
+
+ timing = fdt_subnode_offset(blob, panel, node_name);
if (timing < 0)
return -ENODEV;
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
diff --git a/u-boot/drivers/video/rockchip_dsi_panel.c b/u-boot/drivers/video/rockchip_dsi_panel.c
index 10200f4..5e1d601 100644
--- a/u-boot/drivers/video/rockchip_dsi_panel.c
+++ b/u-boot/drivers/video/rockchip_dsi_panel.c
@@ -22,6 +22,7 @@
#include "rockchip_panel.h"
#include "rockchip_mipi_dsi.h"

+DECLARE_GLOBAL_DATA_PTR;
#define msleep(a) udelay(a * 1000)

#ifdef CONFIG_RK_PWM_BL
@@ -252,6 +253,7 @@ static int rockchip_dsi_panel_parse_dt(const void *blob, int node, struct rockch
const void *data;
int len = 0;
int ret = 0;
+ char node_name[128];

fdtdec_decode_gpio(blob, node, "enable-gpios", enable_gpio);
fdtdec_decode_gpio(blob, node, "reset-gpios", reset_gpio);
@@ -264,7 +266,12 @@ static int rockchip_dsi_panel_parse_dt(const void *blob, int node, struct rockch
panel->delay_reset = fdtdec_get_int(blob, node, "reset-delay-ms", 0);
panel->bus_format = fdtdec_get_int(blob, node, "bus-format", MEDIA_BUS_FMT_RBG888_1X24);

- data = fdt_getprop(blob, node, "panel-init-sequence", &len);
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "panel-init-sequence", strlen("panel-init-sequence"));
+ strncat(node_name, gd->lcd_module, strlen(gd->lcd_module));
+ printf("[lcd_detect_panel-init-sequence] node_name = %s, %s: %d\n",node_name, __func__, __LINE__);
+
+ data = fdt_getprop(blob, node, node_name, &len);
if (data) {
panel->on_cmds = malloc(sizeof(*panel->on_cmds));
if (!panel->on_cmds)
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
diff --git a/u-boot/include/asm-generic/global_data.h b/u-boot/include/asm-generic/global_data.h
index 8c91ab9..fcc6e03 100644
--- a/u-boot/include/asm-generic/global_data.h
+++ b/u-boot/include/asm-generic/global_data.h
@@ -46,6 +46,7 @@ typedef struct global_data {
unsigned long mem_clk;
#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) || defined(CONFIG_ROCKCHIP_DISPLAY)
unsigned long fb_base; /* Base address of framebuffer mem */
+ char lcd_module[32];
#endif
#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
unsigned long post_log_word; /* Record POST activities */
diff --git a/u-boot/include/lcd.h b/u-boot/include/lcd.h
index 818589e..8063b1e 100755
--- a/u-boot/include/lcd.h
+++ b/u-boot/include/lcd.h
@@ -13,6 +13,12 @@
#ifndef _LCD_H_
#define _LCD_H_

+#define HANVON "_hanvon"
+#define WACOM "_wacom"
+#define RK_MIPI "rk_mipi_dsi"
+#define CMDLINE_HANVON "rk_mipi_dsi_ili9881c_hanvon"
+#define CMDLINE_WACOM "rk_mipi_dsi_ili9881c_wacom"
+
extern char lcd_is_enabled;

extern int lcd_line_length;

device tree 修改

Android7.1的代码中将lcd command timing等配置放到了 kernel/include/dt-bindings/display/screen-timing/ 目录下。
将dts中panel timing 相关的配置从rk3288-xxx.dts中删除,添加到kernel/include/dt-bindings/display/screen-timing/ 下每个lcd的配置中。

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
-/*
- * &disp_timings {
- * native-mode = <&timing0>;
- * };
- *
- * &rk_screen {
- * };
- *
- */
-/*
- *
- * &lvds_panel {
- * power-supply = <&vcc_lcd>;
- * };
- *
- * &dsi0 {
- * status = "okay";
- * rockchip,lane-rate = <1000>;
- *
- * panel: panel {
- * compatible = "simple-panel-dsi";
- * reg = <0>;
- * backlight = <&backlight>;
- * enable-gpios = <&gpio7 4 GPIO_ACTIVE_HIGH>;
- * power-supply = <&vcc_lcd>;
- * dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST)>;
- * dsi,format = <MIPI_DSI_FMT_RGB888>;
- * dsi,lanes = <4>;
- * reset-delay-ms = <20>;
- * init-delay-ms = <20>;
- * enable-delay-ms = <120>;
- * prepare-delay-ms = <120>;
- * status = "okay";
- *
- * disp_timings: display-timings {
- * native-mode = <&timing0>;
- *
- * timing0: timing0 {
- * clock-frequency = <150000000>;
- * hactive = <1200>;
- * vactive = <1920>;
- * hback-porch = <80>;
- * hfront-porch = <81>;
- * vback-porch = <21>;
- * vfront-porch = <21>;
- * hsync-len = <10>;
- * vsync-len = <3>;
- * hsync-active = <0>;
- * vsync-active = <0>;
- * de-active = <0>;
- * pixelclk-active = <0>;
- * };
- * };
- * };
- * };
- *
- */
+
+&dsi0 {
+ status = "okay";
+ rockchip,lane-rate = <1000>;
+
+ panel: panel {
+ compatible = "simple-panel-dsi";
+ reg = <0>;
+ backlight = <&backlight>;
+ enable = <&gpio3 29 GPIO_ACTIVE_HIGH>;
+ reset = <&gpio7 4 GPIO_ACTIVE_HIGH>;
+ power-supply = <&vcc_lcd>;
+ dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST)>;
+ dsi,format = <MIPI_DSI_FMT_RGB888>;
+ dsi,lanes = <4>;
+ reset-delay-ms = <20>;
+ init-delay-ms = <20>;
+ enable-delay-ms = <120>;
+ prepare-delay-ms = <120>;
+ status = "okay";
+ };
+};
+
&route_dsi0 {
status = "okay";
logo,kernel = "logo.bmp";
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
39
40
41
42
--- a/kernel/include/dt-bindings/display/screen-timing/lcd-ili9881c-mipi-wacom.dtsi
+++ b/kernel/include/dt-bindings/display/screen-timing/lcd-ili9881c-mipi-wacom.dtsi
@@ -1,24 +1,8 @@
&dsi0 {
- status = "okay";
- rockchip,lane-rate = <1000>;

panel: panel {
- compatible = "simple-panel-dsi";
- reg = <0>;
- backlight = <&backlight>;
- enable = <&gpio3 29 GPIO_ACTIVE_HIGH>;
- reset = <&gpio7 4 GPIO_ACTIVE_HIGH>;
- power-supply = <&vcc_lcd>;
- dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST)>;
- dsi,format = <MIPI_DSI_FMT_RGB888>;
- dsi,lanes = <4>;
- reset-delay-ms = <20>;
- init-delay-ms = <20>;
- enable-delay-ms = <120>;
- prepare-delay-ms = <120>;
- status = "okay";

- panel-init-sequence = [
+ panel-init-sequence_wacom = [
39 00 04 ff 98 81 03
15 00 02 01 00
15 00 02 02 00
@@ -214,10 +198,10 @@
05 96 01 10
];

- disp_timings: display-timings {
- native-mode = <&timing0>;
+ disp_timings_wacom: display-timings_wacom {
+ native-mode = <&timing0_wacom>;

- timing0: timing0 {
+ timing0_wacom: timing0_wacom {
clock-frequency = <75000000>;
hactive = <720>;
vactive = <1280>;

panel-init-sequence_xxx 中添加对于添加对应LCD的初始化命令。

kernel 驱动修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
diff --git a/kernel/include/linux/lcd_compatible.h b/kernel/include/linux/lcd_compatible.h
new file mode 100644
index 0000000..778ac86
--- /dev/null
+++ b/kernel/include/linux/lcd_compatible.h
@@ -0,0 +1,13 @@
+#ifndef _LCD_COMPATIBLE_H
+#define _LCD_COMPATIBLE_H
+
+#define STRING_LEN 32
+#define HANVON "_hanvon"
+#define WACOM "_wacom"
+
+#define RK_MIPI "rk_mipi_dsi"
+#define CMDLINE_HANVON "rk_mipi_dsi_ili9881c_hanvon"
+#define CMDLINE_WACOM "rk_mipi_dsi_ili9881c_wacom"
+
+extern char lcd_module[STRING_LEN];
+#endif /* _LCD_COMPATIBLE_H */
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
diff --git a/kernel/drivers/gpu/drm/panel/panel-simple.c b/kernel/drivers/gpu/drm/panel/panel-simple.c
index 727c456..63923fa 100644
--- a/kernel/drivers/gpu/drm/panel/panel-simple.c
+++ b/kernel/drivers/gpu/drm/panel/panel-simple.c
@@ -39,6 +39,9 @@
#include <video/of_display_timing.h>
#include <linux/of_graph.h>
#include <video/videomode.h>
+#include <linux/lcd_compatible.h>
+
+char lcd_module[STRING_LEN];

struct cmd_ctrl_hdr {
u8 dtype; /* data type */
@@ -137,6 +140,30 @@ enum MCU_IOCTL {
MCU_SETBYPASS,
};

+int lcd_detect(void)
+{
+ char *panel_name = NULL;
+
+ panel_name = strstr(saved_command_line, RK_MIPI);
+ if (NULL != panel_name) {
+ if (0 == strncmp(panel_name, CMDLINE_HANVON, strlen(CMDLINE_HANVON))) {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] hanvon\n");
+ } else if (0 == strncmp(panel_name, CMDLINE_WACOM, strlen(CMDLINE_WACOM))) {
+ strncpy(lcd_module, WACOM, strlen(WACOM));
+ pr_info("[lcd_detect] wacom");
+ } else {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] default hanvon(no matched lcd)\n");
+ }
+ } else {
+ strncpy(lcd_module, HANVON, strlen(HANVON));
+ pr_info("[lcd_detect] default hanvon(no cmdline)\n");
+ }
+
+ return 0;
+}
+
static inline int get_panel_cmd_type(const char *s)
{
if (!s)
@@ -369,8 +396,14 @@ static int panel_simple_get_cmds(struct panel_simple *panel)
const void *data;
int len;
int err;
+ char node_name[STRING_LEN];

- data = of_get_property(panel->dev->of_node, "panel-init-sequence",
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "panel-init-sequence", strlen("panel-init-sequence"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+ printk("[lcd_detect_panel-init-sequence] node_name = %s, %s: %d\n",node_name, __func__, __LINE__);
+
+ data = of_get_property(panel->dev->of_node, node_name,
&len);
if (data) {
panel->on_cmds = devm_kzalloc(panel->dev,
@@ -468,9 +501,15 @@ static int panel_simple_of_get_native_mode(struct panel_simple *panel)
struct drm_display_mode *mode;
struct device_node *timings_np;
int ret;
+ char node_name[STRING_LEN];
+
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "display-timings", strlen("display-timings"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+ printk("[lcd_detect_display-timings] node_name = %s, %s: %d\n",node_name, __func__, __LINE__);

timings_np = of_get_child_by_name(panel->dev->of_node,
- "display-timings");
+ node_name);
if (!timings_np) {
dev_dbg(panel->dev, "failed to find display-timings node\n");
return 0;
@@ -753,6 +792,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
if (!panel)
return -ENOMEM;

+ lcd_detect();
+
if (!desc)
of_desc = devm_kzalloc(dev, sizeof(*of_desc), GFP_KERNEL);
else
diff --git a/kernel/drivers/video/of_display_timing.c b/kernel/drivers/video/of_display_timing.c
index b253875..e924276 100644
--- a/kernel/drivers/video/of_display_timing.c
+++ b/kernel/drivers/video/of_display_timing.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <video/display_timing.h>
#include <video/of_display_timing.h>
+#include <linux/lcd_compatible.h>

@@ -193,11 +194,17 @@ struct display_timings *of_get_display_timings(struct device_node *np)
struct device_node *entry;
struct device_node *native_mode;
struct display_timings *disp;
+ char node_name[STRING_LEN];

if (!np)
return NULL;

- timings_np = of_get_child_by_name(np, "display-timings");
+ memset(node_name, 0, sizeof(node_name));
+ strncpy(node_name, "display-timings", strlen("display-timings"));
+ strncat(node_name, lcd_module, strlen(lcd_module));
+ printk("[lcd_detect_display-timings] node_name = %s, %s: %d\n",node_name, __func__, __LINE__);
+
+ timings_np = of_get_child_by_name(np, node_name);
if (!timings_np) {
pr_err("%s: could not find display-timings node\n",
of_node_full_name(np));

mkimgge.sh脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/mkimage.sh b/mkimage.sh
index 635d34c..131f964 100755
--- a/mkimage.sh
+++ b/mkimage.sh
@@ -242,7 +242,7 @@ then
fi
else
echo -n "create parameter..."
- cp -a $PARAMETER $IMAGE_PATH/parameter.txt
+ cp -a ${TARGET_DEVICE_DIR}/parameter_*.txt $IMAGE_PATH/
echo "done."
fi
else
您的支持将鼓励我继续创作!