Background:
Currently according to the patch <8MP_LVDS_patch > configure uboot's lvds display, using 1280x800 single-channel screen display is normal; based on this basis need to realize 1920x1080 dual-channel display, has been configured as follows:
1. Configure the screen reference of 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. Write the register configuration of 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); media_blk_write(priv, LDB_CTRL, LDB_CH0_MODE_EN_TO_DI0 | CH1_DATA_ WIDTH_24BIT | CH1_BIT_MAPPING_JEIDA).
3. According to the formula, calculate the PLL value:
There is a logo screen displayed, but the screen shows the presence of colored vertical lines, what could this be, please help troubleshoot, thanks; looking forward to your reply!
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
Good morning, sorry for the late reply due to a lot on my hands!
I tried gateworks.bmp, the display is not very good; as shown in the following logo.png; check the uboot driver does not have the VIDEO_FONT_16X32 configuration option; I did a verification, with a 1920x1080 logo image, made into a 1280x800 logo, respectively, placed in uboot and kernel I did a verification with a 1920x1080 logo image, made into a 1280x800 logo, and put it on uboot and kernel respectively, uboot has a jagged situation of cutting diagonal angle; while kernel display is completely normal; thank you for following up the problem!
Hi @dadaxin
The problem is still related to the resolution of the material, if you increase the resolution of the material, the jaggedness will be much less. The logo in the attachment is 296x72, but in reality it is not 296x72 pixels on the screen, so it will be stretched. You can try tools/logos/gateworks.bmp (600x93) in the same directory and see if the horizontal jaggedness is much less. For fonts, try turning on the option VIDEO_FONT_16X32, which is more suitable for high resolution screens.
Best Regards,
Zhiming
Hi @DADAXIN
Can you upload a copy of the logo image you're currently using (the one in the right image above)? Is the default NXP logo also displayed in dual channel 1080p?
Best Regards,
Zhiming
Hi, thanks for the reply! The situation is as follows:
1, the default NXP logo display also has a jagged effect, as shown in the attachment
2, there is a replacement of 1920x1080 logo image, in uboot tilted part of the presence of jagged, the rest of the display is normal; in the kernel under the file is too large, can not be displayed
3, converted to 1280x800 logo image, the effect is still the same in uboot, kernel display Normal
4, switch to 1280x800 single channel screen, uboot and kernel display are normal
Single-channel display is normal, but dual-channel replacement of the logo image, uboot display will be abnormal
Hi @DADAXIN
Did you have a problem with the default logo display as well as the fonts before you replaced the logo? I took a closer look at the image above and it looks like the resolution of the clip itself doesn't match the screen, I wonder if you have a higher resolution image displayed there to test and see what's going on with the higher resolution?
Also, is it the same if the kernel stage shows the same logo material?
Best Regards,
Zhiming
早上好,zhiming
按照内核的lvds寄存器写入;我在uboot中也进行了配置;但效果没有改善:logo倾斜部分还是存在锯齿;请问还有其余操作可以优化吗;期待你的回复!
Hi @dadaxin
Corresponds to this section of the kernel's configuration, which is not in the uboot patch because only a single channel was tested at that time. You need to write the value to the lvds_ctrl register in the uboot patch.
https://github.com/nxp-imx/linux-imx/blob/lf-6.12.y/drivers/phy/freescale/phy-fsl-imx8mp-lvds.c#L113
Best Regards,
Zhiming
Thanks for the follow up, the logo graphic phenomenon is shown below: there are jaggies involving the slanted part of the fonts and the pattern.
Hi @dadaxin
You can refer to the settings in the linux lvds phy driver, set these three bits of LVDS_CTRL and the drive capability should be much better.
phy_write(phy, priv->devdata->lvds_ctrl,
CC_ADJ(0x2) | PRE_EMPH_EN | PRE_EMPH_ADJ(0x3));
Best Regards,
Zhiming
Hi,
Is there any exception in the LOGO section? If it's a word, it should have nothing to do with the lvds controller and everything to do with display font optimization in uboot.
Best Regards,
Zhiming
Thanks for the guidance, it's the point of the question
Hi,
There is this line in the code, val |= CH_EN, here only channel0 is enabled, BIT0, while BIT2 needs to be set.
Best Regards,
Zhiming
Hi @DADAXIN
You try changing LDB_CH1_MODE_EN_TO_DI0 to LDB_CH1_MODE_EN_TO_DI1
Best Regards,
Zhiming
Hi,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、进一步编译,报这一部分的错,不清楚怎么解决;希望能得到你的进一步回复,感谢!!
Hello, I have the same phenomenon as you ( jaggedness ), may I ask, after modifying this function (video_bmp_display), the display is messed up, may I ask where else did you modify it?