0

我有一个自定义硬件设备,它使用 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 显示驱动程序初始化中做错了什么?在这一点上,我什至欢迎有关如何进行调试的策略(尽管我无法使用示波器)。

4

0 回答 0