2197169_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2197169_zh-CN

2197169_zh-CN

IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

背景:

当前根据补丁<8MP_LVDS_patch>配置uboot的lvds显示,使用1280x800的单通道屏显示是正常的;基于这个基础需要实现1920x1080的双通道显示,已进行如下配置:

1、配置lvds的屏参:

timing_lvds: timing_lvds {
clock-frequency = <141140000>;
hactive = <1920>;
vactive = <1080>;
hfront-porch = <94>;
hback-porch = <92>;
hsync-len = <2>;
vback-porch = <18>;
vfront-porch = <16>;
vsync-len = <2>;
hsync-active = <1>;
vsync-active = <1>;
de-active = <1>;
};


2、写入ldb的寄存器配置:

//CH1
#define CH1_DATA_WIDTH_24BIT (1 << 7)
#define CH1_BIT_MAPPING_JEIDA (1 <<
#define CH1_BIT_MAPPING_SPWG (0 <<

media_blk_write(priv, LDB_CTRL,
LDB_CH0_MODE_EN_TO_DI0 | CH0_DATA_WIDTH_24BIT | CH0_BIT_MAPPING_JEIDA |
LDB_CH1_MODE_EN_TO_DI0 | CH1_DATA_WIDTH_24BIT | CH1_BIT_MAPPING_JEIDA);

3、根据公式,计算出PLL值:

PLL_1443X_RATE(987980000U, 823, 5, 2, 20971),
uboot_lvds_1920x1080.jpg

显示有logo画面,但屏幕显示存在彩色竖线,这会是什么情况,请帮忙排查下,谢谢;期待您的回复!



i.MX 8M | i.MX 8M Mini | i.MX 8M Nanoi.MX8ULPRe: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

由于内核和uboot里的bmp显示不是相同的功能,所以目前我怀疑是bmp显示相关的函数有问题,请尝试替换一下video_bmp_display函数。
int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y,
              bool align)
{
    struct video_priv *priv = dev_get_uclass_priv(dev);
    int i, j;
    uchar *start, *fb;
    struct bmp_image *bmp = map_sysmem(bmp_image, 0);
    uchar *bmap;
    unsigned long width, height;
    unsigned long pwidth = priv->xsize;
    unsigned colours, bpix, bmp_bpix;
    enum video_format eformat;
    struct bmp_color_table_entry *palette;
    int hdr_size;
    int ret;

    if (!bmp || !(bmp->header.signature[0] == 'B' &&
        bmp->header.signature[1] == 'M')) {
        printf("Error: no valid bmp image at %lx\n", bmp_image);
        return -EINVAL;
    }

    video_bmp_get_info(bmp, &width, &height, &bmp_bpix);
    hdr_size = get_unaligned_le16(&bmp->header.size);
    debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix);
    palette = (void *)bmp + 14 + hdr_size;

    colours = 1 << bmp_bpix;

    bpix = VNBITS(priv->bpix);
    eformat = priv->format;

    if (bpix != 1 && bpix != 8 && bpix != 16 && bpix != 32) {
        printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
               bpix, bmp_bpix);
        return -EINVAL;
    }

    /*
     * We support displaying 8bpp and 24bpp BMPs on 16bpp LCDs
     * and displaying 24bpp BMPs on 32bpp LCDs
     */
    if (bpix != bmp_bpix &&
        !(bmp_bpix == 8  && (bpix == 16 || bpix == 24 || bpix == 32)) &&
        !(bmp_bpix == 24 && (bpix == 16 || bpix == 32))) {
        printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
               bpix, colours);
        return -EPERM;
    }

    debug("Display-bmp: %d x %d  with %d colours, display %d\n",
          (int)width, (int)height, (int)colours, 1 << bpix);

    unsigned long bmp_stride_bytes =
        ((width * bmp_bpix + 31) / 32) * 4;

    unsigned long dst_bytes_per_pixel = bpix / 8;
    if (!dst_bytes_per_pixel)           
        dst_bytes_per_pixel = 1;

    if (align) {
        video_splash_align_axis(&x, priv->xsize, width);
        video_splash_align_axis(&y, priv->ysize, height);
    }

    if ((x + width) > pwidth)
        width = pwidth - x;
    if ((y + height) > priv->ysize)
        height = priv->ysize - y;

    bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
    start = (uchar *)(priv->fb +
        (y + height) * priv->line_length + x * (bpix / 8));

    /* Move back to the final line to be drawn (BMP 自下而上存储) */
    fb = start - priv->line_length;

    switch (bmp_bpix) {
    case 1:
    case 8: {
        unsigned long src_bpp_bytes = 1;
        unsigned long dst_line_bytes = width * (bpix / 8);
        if (!dst_line_bytes)
            dst_line_bytes = width;

        for (i = 0; i < height; ++i) {
            schedule();
            for (j = 0; j < width; j++) {
                write_pix8(fb, bpix, eformat, palette, bmap);
                bmap++;
                fb += (bpix / 8) ? (bpix / 8) : 1;
            }
           
            bmap += bmp_stride_bytes - width * src_bpp_bytes;
            
            fb -= dst_line_bytes + priv->line_length;
        }
        break;
    }
    case 16:
        if (CONFIG_IS_ENABLED(BMP_16BPP)) {
            unsigned long src_bpp_bytes = 2;
            for (i = 0; i < height; ++i) {
                schedule();
                for (j = 0; j < width; j++) {
                    *fb++ = *bmap++;
                    *fb++ = *bmap++;
                }
                
                bmap += bmp_stride_bytes - width * src_bpp_bytes;
                fb   -= width * 2 + priv->line_length;
            }
        }
        break;
    case 24:
        if (CONFIG_IS_ENABLED(BMP_24BPP)) {
            unsigned long src_bpp_bytes = 3;
            for (i = 0; i < height; ++i) {
                for (j = 0; j < width; j++) {
                    if (bpix == 16) {
                        /* 16bit 565RGB format */
                        *(u16 *)fb = ((bmap[2] >> 3) << 11) |
                                 ((bmap[1] >> 2) << 5)  |
                                 (bmap[0] >> 3);
                        bmap += 3;
                        fb   += 2;
                    } else if (eformat == VIDEO_X2R10G10B10) {
                        u32 pix;
                        pix  = (u32)(*bmap++) << 2U;
                        pix |= (u32)(*bmap++) << 12U;
                        pix |= (u32)(*bmap++) << 22U;
                        *fb++ = pix & 0xff;
                        *fb++ = (pix >> 8) & 0xff;
                        *fb++ = (pix >> 16) & 0xff;
                        *fb++ = pix >> 24;
                    } else if (eformat == VIDEO_RGBA8888) {
                        u32 pix;
                        pix  = (u32)(*bmap++) << 8U;  /* blue */
                        pix |= (u32)(*bmap++) << 16U; /* green */
                        pix |= (u32)(*bmap++) << 24U; /* red */
                        *fb++ = (pix >> 24) & 0xff;
                        *fb++ = (pix >> 16) & 0xff;
                        *fb++ = (pix >> 8)  & 0xff;
                        *fb++ = 0xff;
                    } else {
                        
                        *fb++ = *bmap++;
                        *fb++ = *bmap++;
                        *fb++ = *bmap++;
                        *fb++ = 0;
                    }
                }
                
                bmap += bmp_stride_bytes - width * src_bpp_bytes;
                fb   -= priv->line_length + width * (bpix / 8);
            }
        }
        break;
    case 32:
        if (CONFIG_IS_ENABLED(BMP_32BPP)) {
            unsigned long src_bpp_bytes = 4;
            for (i = 0; i < height; ++i) {
                for (j = 0; j < width; j++) {
                    if (eformat == VIDEO_X2R10G10B10) {
                        u32 pix;
                        pix  = (u32)(*bmap++) << 2U;
                        pix |= (u32)(*bmap++) << 12U;
                        pix |= (u32)(*bmap++) << 22U;
                        pix |= ((u32)(*bmap++) >> 6) << 30U;
                        *fb++ = pix & 0xff;
                        *fb++ = (pix >> 8) & 0xff;
                        *fb++ = (pix >> 16) & 0xff;
                        *fb++ = pix >> 24;
                    } else if (eformat == VIDEO_RGBA8888) {
                        u32 pix;
                        pix  = (u32)(*bmap++) << 8U;  /* blue */
                        pix |= (u32)(*bmap++) << 16U; /* green */
                        pix |= (u32)(*bmap++) << 24U; /* red */
                        bmap++;                      /* alpha (忽略) */
                        *fb++ = (pix >> 24) & 0xff;
                        *fb++ = (pix >> 16) & 0xff;
                        *fb++ = (pix >> 8)  & 0xff;
                        *fb++ = 0xff;               /* opacity */
                    } else {
                        *fb++ = *bmap++;
                        *fb++ = *bmap++;
                        *fb++ = *bmap++;
                        *fb++ = *bmap++;
                    }
                }
               
                bmap += bmp_stride_bytes - width * src_bpp_bytes;
                fb   -= priv->line_length + width * (bpix / 8);
            }
        }
        break;
    default:
        break;
    };

    /* Find the position of the top left of the image in the framebuffer */
    fb = (uchar *)(priv->fb + y * priv->line_length + x * (bpix / 8));
    ret = video_sync_copy(dev, start, fb);
    if (ret)
        return log_ret(ret);

    return video_sync(dev, false);
}





Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi,@Zhiming

       早上好,由于手上事情较多,回复的比较晚,很抱歉!

       我试了gateworks.bmp,显示效果不太好;如下列logo.png所示;查阅uboot驱动没有VIDEO_FONT_16X32这个配置选项;我做了一个验证,用1920x1080的logo图,做成1280x800的logo,分别放在uboot和kernel上面,uboot存在切斜角度的锯齿情况;而kernel显示是完全正常的;感谢您对问题的跟进!

uboot_logo_H.jpg

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

这个问题还是和素材分辨率有关,拉高素材分辨率,锯齿感会少很多。附件里得logo分辨是296x72,但是实际上在屏幕得显示范围,肯定不是296x72个像素点,所以会被拉伸。你可以试试同级目录下的tools/logos/gateworks.bmp(600x93)文件,看看横向锯齿感会不会少很多。字体的话,可以试试打开VIDEO_FONT_16X32这个选项,更适用于高分辨率屏幕。

Zhiming_Liu_0-1762826615066.png

Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

你目前使用的logo图(上面右边图片里的)能传一份上来吗?默认的NXP logo也是双通道1080p的情况下显示的吗?

Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

你好,感谢回复!情况如下:

1、默认的NXP logo显示也有锯齿效果,如附件显示
2、有更换1920x1080的logo图,在uboot下倾斜部分存在锯齿,其余部分正常显示;在kernel下文件过大,不能显示
3、转换为1280x800的logo图,在uboot下效果依旧,kernel下显示正常
4、换成1280x800的单通道屏,uboot和kernel显示都正常

单通道显示是正常的,但双通道更换logo图,uboot显示会有异常


3.jpg4.jpg

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

你在替换logo之前,默认的logo显示以及字体有问题吗?我仔细看了上面的图,看上去像是素材本身分辨率和屏幕不匹配,不知道你那里有没有分辨率更高的图片显示,测试看看高分辨率是什么情况?

另外,内核阶段如果显示相同的logo素材也是这样吗?

Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

早上好,zhiming

按照内核的 lvds寄存器写入;我在uboot中也进行了配置;但效果没有改善:logo倾斜部分还是存在锯齿;请问还有其余操作可以优化吗;期待你的回复!?

uboot_lvds.png


lvds_define.png






Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

对应内核的这一段配置,uboot补丁里没有这段配置,因为当时只测试了单通道。你需要把值写入uboot补丁里的lvds_ctrl寄存器。

https://github.com/nxp-imx/linux-imx/blob/lf-6.12.y/drivers/phy/freescale/phy-fsl-imx8mp-lvds.c#L113

Zhiming_Liu_0-1762475137940.png

Zhiming_Liu_1-1762475147603.png





Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

感谢跟进,logo图现象如下所示:涉及到字体和图案的倾斜部分,会存在锯齿现象

2.jpg
1.jpg

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线你好,uboot没有找到对应phy文件:"fsl,imx8mp-lvds-phy",应该在哪个地方写入寄存器呢呢;<8MP_LVDS_patch>补丁也没有这个驱动文件Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

你可以参考linux lvds phy驱动里的设置,设置LVDS_CTRL的这三位,驱动能力应该会好很多。

	phy_write(phy, priv->devdata->lvds_ctrl,
			CC_ADJ(0x2) | PRE_EMPH_EN | PRE_EMPH_ADJ(0x3));



Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线感谢回复!logo图像也有部分锯齿现象,换成1280x800单通道屏,logo显示是正常的;我调整各种panel时钟和PLL值,都不能改善;请问有什么建议吗Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi,

LOGO部分有异常吗?如果是字的话,应该是和lvds控制器无关,和uboot里的显示字体优化有关。

Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线你好,lvds屏显示logo还有个现象:logo部分字母存在锯齿现象,应该怎么优化呢;期待您的回复Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

感谢指导,是这个问题点

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi,

代码里有这一行,val |= CH_EN,这里只enable了channel0,BIT0,同时需要设置BIT2。

Zhiming_Liu_0-1762150737457.png



Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线你好,感谢回复;将LDB_CH1_MODE_EN_TO_DI0改动为LDB_CH1_MODE_EN_TO_DI1,显示效果依旧Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

Hi @DADAXIN 

你试试把LDB_CH1_MODE_EN_TO_DI0 改成LDB_CH1_MODE_EN_TO_DI1

Best Regards,
Zhiming

Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

嗨,志明

感谢您的回复以及对问题的跟进,最近工作比较繁忙,回复比较晚请见谅;我进行了替换操作

1、当前5.10.72对应的uboot2021版本,替换后会报没有video_format定义;而在6.6.52对应的uboot2024版本是有的,我同步了这部分配置:
+++ b/include/video.h
@@ -56,6 +56,15 @@ enum video_log2_bpp {
VIDEO_BPP32,
};

+
+enum video_format {
+ VIDEO_UNKNOWN,
+ VIDEO_RGBA8888,
+ VIDEO_X8B8G8R8,
+ VIDEO_X8R8G8B8,
+ VIDEO_X2R10G10B10,
+};
+

2、进一步编译,报这一部分的错,不清楚怎么解决;希望能得到你的进一步回复,感谢!!...

DADAXIN_0-1765003767987.png


Re: IMX8MP uboot下配置双通道lvds,显示存在彩色竖线

HI @DADAXIN @Zhiming_Liu 

     您好,我与你的现象一致(锯齿),请问下,修改了这个函数(video_bmp_display)以后,显示乱码了,请问您还修改了哪里吗

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎03-25-2026 03:29 AM
更新者: