图像显示
本章节主要介绍 U-Boot 阶段 LOGO 显示的相关内容。
U-Boot 驱动模型支持 Graphics,ArtInChip 平台中的显示驱动基于该框架进行实现。 但驱动内部逻辑参考了 Kernel 中的显示驱动,对新屏适配可参考 SDK 指南中的显示模块使用指南。
相关术语
术语 | 定义 | 注释说明 |
---|---|---|
DE | Display Engine | 显示引擎 |
DI | Display Interface | 显示接口,包括 RGB/LVDS/DSI 等 |
PANEL | panel | 外接屏幕驱动 |
RGB | Red Green Blue | 按红绿蓝三原色编码的显示接口标准 |
LVDS | Low Voltage Differential Signaling | 低压差分信号的显示接口标准 |
MIPI-DSI | Mipi Display Serial Interface | Mipi 组织定义的一个显示接口标准 |
驱动框架
相关配置为:
-
CONFIG_DM_VIDEO
-
CONFIG_DISPLAY
-
CONFIG_VIDEO_ARTINCHIP
相关源码有:
-
drivers/video/artinchip/
-
board/artinchip/d211/d211.c
预留内存
video buffer
,用于保存 LOGO
信息。board_init_f(); // common/board_f.c
|-> reserve_video() // reserve video buffer
reserve_video() 会遍历 uclass_video
链表,解析
struct video_uc_platdata 中的 size
属性是否被设置,如果不为零,即在 DRAM 顶部预留一块大小为 size 的 buffer,并将这块 buffer
的起始地址和结束地址存入 gd->video_bottom 和 gd->video_top
。随后 Boot 重置 DRAM 中可用内存的起始地址,减去这块 buffer。
board_init_f(); // common/board_f.c
|-> initf_dm();
| |-> device_bind_common()
| |-> drv->bind(dev)
| aicfb_bind() // drivers/video/artinchip/aic_fb.c
| // 为 platdata 中的 size 赋值
| ...
|-> reserve_video() // reserve video buffer
初始化流程
|-> board_init_r(); // common/board_r.c
| |-> board_late_init()
| | |-> board_show_logo //board/artinchip/d211/d211.c
| |-> uclass_first_device
| |-> device_probe()
| |-> aicfb_probe() // drivers/video/artinchip/aic_fb.c
| |
| +---------------+
| |
| |-> aicfb_find_de()
| | | -> uclass_get_device_by_ofnode()
| | |-> uclass_get_device_tail()
| | |-> device_probe()
| | aic_de_probe() // drivers/video/artinchip/aic_de.c
| |-> aicfb_find_di()
| | | -> uclass_get_device_by_ofnode()
| | |-> uclass_get_device_tail()
| | |-> device_probe()
| | aic_rgb_probe() / lvds_probe() / aic_dsi_probe()
| | // 这三个函数的关系为三选一,分别位于
| | // drivers/video/artinchip/aic_rgb.c
| | // drivers/video/artinchip/aic_lvds.c
| | // drivers/video/artinchip/aic_dsi.c
| |-> aicfb_find_panel()
| | | -> uclass_get_device_by_ofnode()
| | |-> uclass_get_device_tail()
| | |-> device_probe()
| | |-> panel_probe() // drivers/video/artinchip/panel_xxx.c
| ...
|-> board_prepare_logo // 加载 logo
|-> aicfb_enable_panel
在 probe 过程中并没有开启显示模块,只是设置了相关参数。在 LOGO 加载进 video buffer 后,U-Boot 才会调用 aicfb_enable_panel 执行显示模块的 enable 操作。
LOGO 加载
ArtInChip 平台支持从 MMC、SPI NAND 和 SPI NOR 等启动介质中加载 png/jpg 图片进行硬解码并居中显示。
|-> board_late_init // common/board_r.c
|-> board_show_logo // board/artinchip/d211/d211.c
|-> board_prepare_logo()
| |-> mmc_load_logo() // mmc 启动
| |-> spinand_load_logo() // spinand 启动
| |-> spinor_load_logo() // spinor 启动
| |-> aic_logo_decode() // 对 boot logo image 进行解码
| |-> aicfb_enable_panel() // 开启显示模块
硬件时序要求
DE、DI、panel 三个硬件模块在初始化时有一些时序上的要求,包含先后顺序、延迟大小,主要约束来自于 panel 侧。所以,当接入新的 panel 型号,必须要严格按照手册来完成硬件的初始化。 为了应对这样的硬件特性,驱动设计中使用 callback 方式来实现多个模块间的互相调用。
在显示模块的 enable 操作中,会调用这些回调来完成初始化,如下图(其中关系比较绕的是 panel 初始化逻辑)
该部分逻辑与 kernel 中的显示驱动保持一致,不同点在与 enable 的调用时间不同。详情可参考 SDK 指南中的显示模块使用指南
LOGO 保持
U-Boot 在显示 LOGO 后,会把 video buffer 的信息,包括 buffer 起始地址,大小等添加到 kernel 解析的 dtb 文件中。 具体的方式为:在 dtb 文件的 reserved momory 结点中插入一个子节点,子节点中保存有 address 和 size 信息。 过程如下所示:
|-> image_setup_libfdt()
|-> ft_board_setup()
|-> fdtdec_add_reserved_memory()
Kernel 在启动时不会修改这块内存,kernel 中的显示驱动在初始化时,会将 video buffer 中的内容 memcopy 到 fb0 中,从而保证 LOGO 可以从 U-Boot 保持到 kernel 启动,直到应用程序修改 fb0 文件。kernel 在 memcopy 操作之后,会将 video buffer 释放。
更换 LOGO
ArtInChip 平台支持开机 logo,还支持在 usb 烧录,SD 卡升级和 U 盘升级时显示 logo,并且允许在不同的场景显示不同的 logo 图片。
-
PNG LOGO
-
ArtInChip 平台默认使用 png 格式 logo,图片保存路径为 target/IC/Board/logo/boot_logo.png。注: 图片必须命名为 boot_logo.png。
-
Luban SDK 编译时,编译脚本会在 logo 目录下检索 boot_logo.png 文件,如果文件存在,就把它打包进 logo.itb 文件。
-
Logo 分区 size 默认 768K,打包后的 logo.itb 文件 size 需小于 logo 分区。
以 spi-nand 启动为例:// target/<IC>/<Board>/image_cfg.json "spi-nand": { "size": "128m", // Size of SPI NAND "partitions": { "spl": { "size": "1m" }, "uboot": { "size": "1m" }, "userid": { "size": "256k" }, "bbt": { "size": "256k" }, "env": { "size": "256k" }, "env_r": { "size": "256k" }, "falcon": { "size": "256k" }, "logo": { "size": "768K" }, // 默认配置 768K,需要大于 logo.itb 文件 "kernel": { "size": "12m" }, "recovery": { "size": "10m" }, "ubiroot": { "size": "32m", "ubi": { // Volume in UBI device "rootfs": { "size": "-" }, }, }, "ubisystem": { "size": "-", "ubi": { // Volume in UBI device "user": { "size": "-" }, }, }, } },
-
ArtInChip 平台基于 ffmpeg 进行精简,提供一个专门的 png 转换工具,确保用作 logo 的 png 图片只包含一个 IDAT 数据块。
注:当前暂不支持 32 位带 alpha 信息的 png 图片。
-
png 硬解码输出的格式默认为 ARGB8888, 如果想更换输出格式,需要修改 uboot 源码。源码以及支持的格式如下所示:
// drivers/video/artinchip/decoder/aic_ve_png.c /* output type */ #define ARGB8888 0 #define ABGR8888 1 #define RGBA8888 2 #define BGRA8888 3 #define RGB888 4 #define BGR888 5 #define OUTPUT_FORMAT ARGB8888
-
更换 logo 图片,需要注意以下几点:
- 用作 logo 的 png 图片必须只包含一个 IDAT 数据块
- Png 图片的宽高不能大于当前 LCD panel 的宽高
- image_cfg.json 文件中 logo 分区 size(默认 768K)需要大于 logo.itb 文件
-
-
JPG LOGO
-
更换 jpg 格式的 logo 图片,將图片存放于 target/IC/Board/logo/boot_logo.jpg。注: 图片必须命名为 boot_logo.jpg。
-
更换 jpg logo 图片,需要注意以下几点:
- jpg 图片的宽高不能大于当前 LCD panel 的宽高。
- 修改 logo.its 文件, 将 boot_logo.jpg 打包进 logo.its 文件。
- image_cfg.json 文件中 logo 分区 size (默认 768K)需要大于 logo.its 文件。
logo.its 文件修改,以 spi-nand 启动为例:// target/<IC>/<Board>/logo.its 板级配置,如果存在,优先修改 // target/<IC>/common/logo.its 默认配置 /dts-v1/; / { description = "ArtInChip LOGO"; #address-cells = <1>; images { boot { description = "ArtInChip boot logo"; type = "multi"; compression = "none"; data = /incbin/("logo/boot_logo.jpg"); // 修改为 jpg 图片 }; usbburn { description = "USB burn logo"; type = "multi"; compression = "none"; data = /incbin/("logo/usb_burn.png"); }; udiskburn { description = "udisk burn logo"; type = "multi"; compression = "none"; data = /incbin/("logo/udisk_burn.png"); }; sdburn { description = "SDCard burn logo"; type = "multi"; compression = "none"; data = /incbin/("logo/sd_burn.png"); }; burn_done { description = "burn done logo"; type = "multi"; compression = "none"; data = /incbin/("logo/burn_done.png"); }; }; configurations { default = "conf-1"; conf-1 { description = "ArtInChip logo image"; }; }; };
-
jpeg 硬解码输出的是 YUV 数据, 需要 GE 进行一次数据格式转换,GE 默认转换的格式为 ARGB8888。 如果想修改转换格式,需要修改 uboot 源码。
// drivers/video/artinchip/decoder/aic_ve_jpeg.c /* GE output format */ #define CONVER_FORMAT MPP_FMT_ARGB_8888 // include/artinchip/mpp_types.h 3.14.9. falcon 模式 logo¶
-
Falcon 模式 logo
ArtInChip 平台支持在 falcon 启动时显示 logo。
目前仅支持 SPI NAND Falcon 启动显示 logo,且只能显示 png 格式的 logo。
FAQ
-
新屏支持
参考 SDK 指南中的显示模块使用指南,两者思路相同。