我有一个自定义硬件设备,它使用 Variscite i.MX6Q(四核)来驱动 320x240 显示器。一旦 linux 内核开始启动,LCD 显示屏就会很好地工作——完全没有问题。然而,在此之前,引导加载程序 (u-boot) 显示白屏(有时带有微弱的垂直线)约 0.25 秒,然后黑屏约 8 秒,直到内核接管(重新初始化显示并正确显示内核自己的闪屏)。
由于 linux 内核可以很好地驱动显示器,我确定我只是在我的 u-boot 设置中错误配置了一些东西......但我正在努力弄清楚什么和在哪里!我尝试过的资源/事情包括:
- 将低分辨率的 LVDS LCD 移植到 i.MX6 - 这似乎高度相关,但指的是调整 linux 内核驱动程序而不是 uboot,我没有足够的经验将知识移植到 uboot。
- U-Boot 闪屏 - LVDS - 这似乎与我遇到的问题非常接近,但没有列出明确的解决方案。论坛中的一个回复链接到了一个反转时钟极性的建议,我尝试过但没有发现任何差异。
- 如何在 u-boot 中的并行 LCD 上显示闪屏- 在与之前的帖子相同的主题中,这再次暗示了为低分辨率显示器指定时钟的问题。
- i.mx6 33.26MHz LVDS 面板无法在 u-boot 中显示- 按照这些说明,我修改了 ...../uboot/drivers/video/ipu_common.c 并将 g_ldb_clk struct .rate 成员设置为 6400000,但这似乎没有效果。
- 将显示器添加到 iMX 开发人员套件 [警告 - PDF!] - 关于如何向 iMX 板添加对新显示器的支持的说明;第 6.1.4 节讨论 iMX6Q。但是,我已将正确的显示时间添加到 display[] var(请参见下面的代码)中,但我仍然遇到问题。
从我的定制板原理图中,我知道我需要在 PWM2 上配置 PWM 背光显示,在 GPIO 5-13 上配置背光启用/禁用,并且我需要提供自定义显示时序。因此,..../uboot/board/variscite/mx6var_som.c 中的相关部分:
struct display_info_t const displays[] = {{
.bus = -1,
.addr = 0,
.pixfmt = IPU_PIX_FMT_RGB24,
.detect = detect_MyCustomBoard,
.enable = lvds_enable_disable,
.mode = {
.name = "VAR-QVGA MX6CB-R",
.refresh = 60, /* optional */
.xres = 320,
.yres = 240,
.pixclock = MHZ2PS(6.4),
.left_margin = 64,
.right_margin = 20,
.upper_margin = 8,
.lower_margin = 4,
.hsync_len = 4,
.vsync_len = 10,
.sync = FB_SYNC_EXT,
.vmode = FB_VMODE_NONINTERLACED
} },
...
};
static void setup_display(void)
{
...
/* Turn off backlight until display is ready */
SETUP_IOMUX_PAD(PAD_DISP0_DAT19__GPIO5_IO13 | MUX_PAD_CTRL(NO_PAD_CTRL));
gpio_direction_output(IMX_GPIO_NR(5, 13), 0);
/* Setup the backlight dimmer (via PWM) */
SETUP_IOMUX_PAD(PAD_DISP0_DAT9__PWM2_OUT | MUX_PAD_CTRL(BACKLIGHT_PWM_CTRL));
pwm_init(VAR_SOM_BACKLIGHT_PWM_ID, VAR_SOM_BACKLIGHT_PERIOD, 0);
pwm_config(VAR_SOM_BACKLIGHT_PWM_ID, 0, VAR_SOM_BACKLIGHT_PERIOD);
...
/* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
reg = readl(&mxc_ccm->CCGR3);
reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
writel(reg, &mxc_ccm->CCGR3);
/* set LDB0, LDB1 clk select to 011/011 */
reg = readl(&mxc_ccm->cs2cdr);
reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
| MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
reg |= (1 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
| (1 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
writel(reg, &mxc_ccm->cs2cdr);
...
}
int splash_screen_prepare(void)
{
...
/* Turn on backlight */
gpio_set_value(IMX_GPIO_NR(5, 13), 1);
pwm_config(VAR_SOM_BACKLIGHT_PWM_ID, VAR_SOM_BACKLIGHT_PERIOD*127/256, VAR_SOM_BACKLIGHT_PERIOD);
...
}
为了比较,这里是我的 linux 设备树的相关部分:
&pwm2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2_1>;
status = "okay";
};
backlight {
compatible = "pwm-backlight";
pwms = <&pwm2 0 50000>;
brightness-levels = <0 4 8 16 32 64 128 248>;
default-brightness-level = <7>;
status = "okay";
};
&ldb {
status = "okay";
lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <24>;
status = "okay";
primary;
display-timings {
native-mode = <&timing0r>;
timing0r: hsd100pxn1 {
clock-frequency = <6400000>;
hactive = <320>;
vactive = <240>;
hback-porch = <64>;
hfront-porch = <20>;
vback-porch = <8>;
vfront-porch = <4>;
hsync-len = <4>;
vsync-len = <10>;
};
};
};
...
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
imx6qdl-var-som-mx6 {
pinctrl_hog: hoggrp {
fsl,pins = <
...
/* LCD Enable on GPIO 5-13 */
MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13 0xc0000000
...
>;
};
在硬件方面,来自 iMX6 的 LVDS 信号通过 TI SN65LVDS822 FlatlinkTM LVDS 接收器转换为并行 RGB,驱动 320x240 QVGA Okaya RH320240T-3x5AP-A 显示器。
我使用的框架是 Yocto(Krogoth 版本),其中包括:
- U-Boot 2015.04-mx6+g535519b:git://github.com/varigit/uboot-imx.git,分支 imx_v2015.04_4.1.15_1.1.0_ga_var03,提交 535519
- Linux 内核 4.1.15:git://github.com/varigit/linux-2.6-imx.git,分支 imx-rel_imx_4.1.15_2.0.0_ga-var01,提交 5a4b34
我确实有一个 Variscite DevKit,当我在 DevKit 中启动 SOM(使用适当的设备树和相关驱动程序)时,一切正常,我看到了 uboot 启动图像和 linux 内核启动图像。这意味着我用于 uboot 启动的图像是有效的,可以被 uboot 读取等。
还有另一个问题:我的生产板组上没有串行控制台访问权限:(。
所以,这里最大的问题是我在我的 uboot 显示驱动程序初始化中做错了什么?在这一点上,我什至欢迎有关如何进行调试的策略(尽管我无法使用示波器)。