您尚未登录。

楼主 #1 2021-01-18 11:35:36

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

大概一个月前尝试用一块A20板子点LCD的时候,遇到了屏幕在u-boot和启动开始阶段能正常显示,但之后屏幕开始变白的问题。症状类似下图:
white screen
同时可以在log上看到这样的输出:

sun4i-drm display-engine: NO panel or bridge found... RGB output disabled

后来一番Google后找到armbian论坛上的一个贴子给出了有效的解决方法:如log所提示的信息,这是设备树中缺少panel节点造成的,需要修改设备树解决。
前些天貌似也有坛友遇到了相同问题发贴提问,回贴中坛友jimmy提到可能是linux 4.14后显示架构改了。我索性写一贴来讲述一下在主线的u-boot、Linux kernel上如何进行并行RGB液晶屏的配置。

最近编辑记录 SdtElectronics (2021-01-18 12:53:36)

离线

楼主 #2 2021-01-18 11:51:21

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

Re: 新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

首先是u-boot下的配置,修改u-boot代码树的configs/目录下你的板子对应的defconfig文件,添加如下配置:
1,CONFIG_VIDEO_LCD_MODE字段,这是存储液晶屏的分辨率,扫描模式等配置的字段,具体每个键值对的含义和计算方法在Linux-sunxi wiki上的LCD页面上有。下面是一个给480x272的LCD使用的配置样例:

CONFIG_VIDEO_LCD_MODE="x:480,y:272,depth:24,pclk_khz:10000,hs:1,vs:1,le:42,ri:8,up:11,lo:4,sync:3,vmode:0"

2,CONFIG_VIDEO_LCD_BL_EN字段,这是标记驱动液晶屏的使能信号的GPIO的字段,根据你板子的实际情况填写,例如:

CONFIG_VIDEO_LCD_BL_EN="PH7"

3,CONFIG_VIDEO_LCD_BL_PWM字段,这是标记控制背光亮度pwm信号的GPIO的字段,根据你板子的实际情况填写,例如:

CONFIG_VIDEO_LCD_BL_PWM="PB2"

4,CONFIG_VIDEO_LCD_POWER字段,这是标记液晶电源使能信号的GPIO的字段,根据你板子的实际情况填写,例如:

CONFIG_VIDEO_LCD_POWER="PH8"

如果你的设备没有液晶电源使能功能,即液晶电源是常开的,此段可以略去。
5,CONFIG_VIDEO_LCD_DCLK_PHASE字段,指明LCD时钟极性,一般值为0:

CONFIG_VIDEO_LCD_DCLK_PHASE=0

所以为了驱动一块480x272的LCD,我的板子最终需要在defconfig中添加如下配置:

CONFIG_VIDEO_LCD_MODE="x:480,y:272,depth:24,pclk_khz:10000,hs:1,vs:1,le:42,ri:8,up:11,lo:4,sync:3,vmode:0"
CONFIG_VIDEO_LCD_DCLK_PHASE=0
CONFIG_VIDEO_LCD_POWER="PH8"
CONFIG_VIDEO_LCD_BL_EN="PH7"
CONFIG_VIDEO_LCD_BL_PWM="PB2"

离线

楼主 #3 2021-01-18 12:50:55

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

Re: 新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

然后是修改设备树。首先检查你的SoC对应的dtsi文件,比如我的是A20的SoC的话对应的就是sun7i-a20.dtsi,其中的tcon(一个SoC可能有多个tcon,比如A20有两个,那么设备树里会有tcon0和tcon1两个节点)节点的ports的tcon0_out: port@1属性下有没有tcon0_out_lcd属性,没有的话,添加如下内容:

/ {
	...
	soc {
		...
		tcon0: lcd-controller@1c0c000 {
			...
			ports {
				...
				tcon0_out: port@1 {
					...
					//这是要添加的内容
					tcon0_out_lcd: endpoint@0 {
                        			reg = <0>;
                        			remote-endpoint = <&lcd_in_tcon0>;
                   			};
					//结束
				}
			}
		}
	}
}

打省略号的部分只是为了方便大家定位到要添加代码的位置,两段注释中间的代码才是要添加的。之后贴出的代码同理。
添加一个panel节点:

/ {
	...
	soc {
		...
		//这是要添加的内容
		panel: panel {
            		#address-cells = <1>;
            		#size-cells = <0>;
            		port {
                		#address-cells = <1>;
                		#size-cells = <0>;
                		lcd_in_tcon0: endpoint {
					//这里要和上面加的那部分一致
					remote-endpoint = <&tcon0_out_lcd>;
				};
			};
		};
		//结束
	}
}

添加lcd的pins:

/ {
	...
	soc {
		...
		pio: pinctrl@1c20800 {
            		...
            		//这是要添加的内容
            		lcd0_rgb888_pins: lcd0-rgb888 {
				pins = "PD0", "PD1", "PD2", "PD3",
				       "PD4", "PD5", "PD6", "PD7",
				       "PD8", "PD9", "PD10", "PD11",
				       "PD12", "PD13", "PD14", "PD15",
				       "PD16", "PD17", "PD18", "PD19",
				       "PD20", "PD21", "PD22", "PD23",
				       "PD24", "PD25", "PD26", "PD27";
				function = "lcd0";
			};
			//结束
		};
	}
}

注意这个要根据你实际使用的SoC的lcd输出使用的GPIO修改,这个例子使用的是A20的lcd0输出。

离线

楼主 #4 2021-01-18 12:52:27

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

Re: 新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

以上的修改都是对SoC对应的dtsi文件的修改,下面是需要对板子对应的dts做出的修改:
确保在dts文件开头引入了pwm.h:

#include <dt-bindings/pwm/pwm.h>

添加背光控制设备节点:

/ {
	...
	//这是要添加的内容
	backlight: backlight {
		compatible = "pwm-backlight";
		pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
		brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
		default-brightness-level = <6>;
		enable-gpios = <&pio 7 7 GPIO_ACTIVE_HIGH>; /* PH7 */
	};
	//结束
}

这样你就能在/sys/class/backlight下对背光进行调节。为了方便阅读,这个例子只配置了11个背光级别,你可以根据需要细分更多的背光级别。
如果你的设备支持屏幕电源使能,添加电源使能节点:

/ {
	...
	//这是要添加的内容
	panel_power: panel_power {
		compatible = "regulator-fixed";
		regulator-name = "panel-power";
		regulator-min-microvolt = <10400000>;
		regulator-max-microvolt = <10400000>;
		//这里要和uboot配置里的CONFIG_VIDEO_LCD_POWER相一致
		gpio = <&pio 7 8 GPIO_ACTIVE_LOW>; /* PH08 */
		enable-active-low;
		regulator-boot-on;
	};
	//结束
}

配置tcon,display engine,panel设备节点:

//这是要添加的内容
&de {
	status = "okay";
};

&tcon0 {
	pinctrl-names = "default";
	pinctrl-0 = <&lcd0_rgb888_pins>;
	status = "okay";
};

&panel {
	compatible = "nec,nl4827hc19-05b";
	power-supply = <&panel_power>;
	backlight = <&backlight>;
};
//结束

重点讲一下panel节点的compatible属性,它标记了该屏幕是Linux kernel源码树下的/drivers/gpu/drm/panel/panel-simple.c中描述的哪个panel。比方说我这里选择了nec_nl4827hc19_05b这个panel,他在panel-simple.c里的描述是这样的:

static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
	.clock = 10870,
	.hdisplay = 480,
	.hsync_start = 480 + 2,
	.hsync_end = 480 + 2 + 41,
	.htotal = 480 + 2 + 41 + 2,
	.vdisplay = 272,
	.vsync_start = 272 + 2,
	.vsync_end = 272 + 2 + 4,
	.vtotal = 272 + 2 + 4 + 2,
	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};

我们能看出来这是一个480x272的屏幕。我们就根据他的名字,给panel节点设置compatible = "nec,nl4827hc19-05b";。至于选择哪个panel是否重要,还尚待验证,因为有人指出设备树的液晶屏配置在启动时会被u-boot修改成defconfig文件描述的配置。我这里选了panel-simple.c里的一块分辨率和实际使用的屏幕相一致的panel,可以正常驱动。
你可以在我的GitHub仓库里找到我为我的A20板子和480x272的LCD修改好的设备树作为参考。

离线

楼主 #5 2021-01-18 13:06:41

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

Re: 新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

完成以上修改后,重新编译u-boot然后替换原来的SPL和dtb的二进制。如果一切正常的话,屏幕应该可以正常显示了:
demo

离线

楼主 #8 2021-02-23 20:56:09

SdtElectronics
会员
注册时间: 2020-07-27
已发帖子: 101
积分: 379.5
个人网站

Re: 新版本主线内核上的并行RGB LCD适配(解决启动过程中屏幕变白问题)

我在4楼曾提到

至于选择哪个panel是否重要,还尚待验证,因为有人指出设备树的液晶屏配置在启动时会被u-boot修改成defconfig文件描述的配置。

今天在一块800x480上的屏幕上实测后,发现在设备树里选择配置和实际屏幕相符的panel型号是必须的,也就是说,新版本内核上u-boot的defconfig和设备树对于配置屏幕而言是各司其职的,二者都要被正确配置才能使boot和系统正常显示。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn