背景:
当前根据补丁<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值:
显示有logo画面,但屏幕显示存在彩色竖线,这会是什么情况,请帮忙排查下,谢谢;期待您的回复!
Hi @DADAXIN
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
Hi,@Zhiming
早上好,由于手上事情较多,回复的比较晚,很抱歉!
我试了gateworks.bmp,显示效果不太好;如下列logo.png所示;查阅uboot驱动没有VIDEO_FONT_16X32这个配置选项;我做了一个验证,用1920x1080的logo图,做成1280x800的logo,分别放在uboot和kernel上面,uboot存在切斜角度的锯齿情况;而kernel显示是完全正常的;感谢您对问题的跟进!
Hi @DADAXIN
这个问题还是和素材分辨率有关,拉高素材分辨率,锯齿感会少很多。附件里得logo分辨是296x72,但是实际上在屏幕得显示范围,肯定不是296x72个像素点,所以会被拉伸。你可以试试同级目录下的tools/logos/gateworks.bmp(600x93)文件,看看横向锯齿感会不会少很多。字体的话,可以试试打开VIDEO_FONT_16X32这个选项,更适用于高分辨率屏幕。
Best Regards,
Zhiming
Hi @DADAXIN
你目前使用的logo图(上面右边图片里的)能传一份上来吗?默认的NXP logo也是双通道1080p的情况下显示的吗?
Best Regards,
Zhiming
你好,感谢回复!情况如下:
1、默认的NXP logo显示也有锯齿效果,如附件显示
2、有更换1920x1080的logo图,在uboot下倾斜部分存在锯齿,其余部分正常显示;在kernel下文件过大,不能显示
3、转换为1280x800的logo图,在uboot下效果依旧,kernel下显示正常
4、换成1280x800的单通道屏,uboot和kernel显示都正常
单通道显示是正常的,但双通道更换logo图,uboot显示会有异常
Hi @DADAXIN
你在替换logo之前,默认的logo显示以及字体有问题吗?我仔细看了上面的图,看上去像是素材本身分辨率和屏幕不匹配,不知道你那里有没有分辨率更高的图片显示,测试看看高分辨率是什么情况?
另外,内核阶段如果显示相同的logo素材也是这样吗?
Best Regards,
Zhiming
早上好,zhiming
按照内核的 lvds寄存器写入;我在uboot中也进行了配置;但效果没有改善:logo倾斜部分还是存在锯齿;请问还有其余操作可以优化吗;期待你的回复!?
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
Best Regards,
Zhiming
感谢跟进,logo图现象如下所示:涉及到字体和图案的倾斜部分,会存在锯齿现象
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
Hi,
LOGO部分有异常吗?如果是字的话,应该是和lvds控制器无关,和uboot里的显示字体优化有关。
Best Regards,
Zhiming
感谢指导,是这个问题点
Hi,
代码里有这一行,val |= CH_EN,这里只enable了channel0,BIT0,同时需要设置BIT2。
Best Regards,
Zhiming
Hi @DADAXIN
你试试把LDB_CH1_MODE_EN_TO_DI0 改成LDB_CH1_MODE_EN_TO_DI1
Best Regards,
Zhiming
嗨,志明
感谢您的回复以及对问题的跟进,最近工作比较繁忙,回复比较晚请见谅;我进行了替换操作
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、进一步编译,报这一部分的错,不清楚怎么解决;希望能得到你的进一步回复,感谢!!...
您好,我与你的现象一致(锯齿),请问下,修改了这个函数(video_bmp_display)以后,显示乱码了,请问您还修改了哪里吗