屏适配指南
- 方式一:通过 menuconfig
修改屏参数。
RGB/LVDS 屏幕不需要初始化,使用通用的屏驱动即可。如果适配一款 RGB/LVDS 屏幕,通过 menuconfig 选择 ArtInChip simple panel , 修改显示参数即可。详情可参考 menuconfig 配置。
- 方式二:将屏参数写入 panel
驱动源码中。
如果适配一款 LCD 屏幕且需要初始化操作,则需要按照屏驱动适配编写一个 panel 驱动。
屏配置方式
方式一:通过 menuconfig 修改屏参数
Board options --->
Graphics Support --->
Graphics support
[*] Display Support
select Display interface (Display LVDS interface) --->
LVDS interface options --->
Display Panels --->
ArtInChip Panel Drivers (ArtInChip simple panel) --->
display timing of simple panel --->
方式一仅支持修改 simple panel 的时序参数和 RGB/LVDS 的部分参数。
配置完成后,保存并退出 menuconfig,系统将根据配置重新编译内核和相关驱动。
方式二:将屏参数写入 panel 驱动源码中。
-
时序参数
static struct display_timing xm91080_timing = { .pixelclock = 130000000, .hactive = 1080, .hfront_porch = 160, .hback_porch = 160, .hsync_len = 40, .vactive = 1920, .vfront_porch = 10, .vback_porch = 20, .vsync_len = 8, };
-
屏接口参数
struct panel_dsi dsi = { .mode = DSI_MOD_VID_PULSE, .format = DSI_FMT_RGB888, .lane_num = 4, };
屏驱动适配
本节介绍如何适配一款 LCD 屏幕。LCD 屏驱动,即 panel,本质上是一个回调函数和屏参的集合。新屏适配实际上是重新实现一个
structaic_panel
结构体。
在 bsp/artinchip/drv/display/panel/ 源码目录下,根据屏接口选择一个模板,并在模版的基础上进行修改。
-
MIPI-DSI 接口可参考 panel_dsi_xm91080.c
-
MIPI-DBI 接口可参考 panel_dbi_ili9486l.c
新屏驱动适配 的详细流程如下所示,以 MIPI-DSI 接口为例:
- 拷贝一份模板文件,命名为 panel_dsi_xxx.c,将新文件添加进
Kconifg 和 SConscript
文件中。
// bsp/artinchip/drv/display/panel/Kconfig config AIC_PANEL_DSI_XXX bool "ArtInChip MIPI DSI xxx panel" depends on AIC_DISP_MIPI_DSI // bsp/artinchip/SConscript if GetDepend('AIC_PANEL_DSI_XXX'): src += Glob('drv/display/panel/panel_dsi_xxx.c')
- 修改
struct aic_panel
的命名,并将其注册到系统中。-
将
struct aic_panel
添加到 panel_com.c 文件的 panels[] 指针数组中//panel_com.c static struct aic_panel *panels[] = { ... #ifdef AIC_PANEL_DSI_XXX &dsi_xxx, #endif };
-
在 panel_com.h 文件中
extern struct aic_panel
。//panel_com.h extern struct aic_panel dsi_xxx;
-
- 修改
struct display_timing
结构体,并修改时序参数。注: 关于 LCD 时序参数,可查看用户手册 > 多媒体 > LCD 章节。 - 重新实现 aic_panel_funcs 结构体中的 prepare 或者 enable
接口,添加初始化操作。
-
对于 MIPI-DSI 接口屏幕
-
在发送 init_sequence 前需要调用 panel_mipi_send_perpare() 进入 LP 模式发送命令,确保命令准确发送。
-
在发送完 init_sequence 后需要调用 panel_mipi_setup_realmode() 配置正确的 MIPI 模式。
-
panel_dsi.c 为 MIPI-DSI 的 init_sequence 封装了两个接口:
-
panel_dsi_dcs_send_seq():发送 DCS 命令
-
panel_dsi_generic_send_seq():发送 Generic 命令
提示:MIPI-DSI Command 有两种 Data Type: DCS 和 Generic
-
DCS (Display Command Set),MIPI 协议定义的一个专门用于显示的命令集,使用广泛
-
Generic,屏厂根据 MIPI 协议进行定制
-
-
-
对于 MIPI-DBI 接口屏幕
-
panel_dbi.c 为 MIPI-DBI 的 init_sequence 封装了 enable 接口 panel_dbi_default_enable()
-
-
数据结构
struct aic_panel {
const char *name;
struct aic_panel_funcs *funcs;
struct aic_panel_callbacks callbacks;
const struct display_timing *timings;
union {
struct panel_rgb *rgb;
struct panel_lvds *lvds;
struct panel_dsi *dsi;
};
int connector_type;
};
/* Each panel driver should define the follow functions. */
struct aic_panel_funcs {
int (*prepare)(void);
int (*enable)(struct aic_panel *panel);
int (*disable)(struct aic_panel *panel);
int (*unprepare)(void);
int (*register_callback)(struct aic_panel *panel,
struct aic_panel_callbacks *pcallback);
};
panel 无需实现,由 DE、DI 提供,供 panel 调用的回调。
struct aic_panel_callbacks {
int (*di_enable)(void);
int (*di_disable)(void);
int (*di_send_cmd)(u32 dt, u32 vc, const u8 *data, u32 len);
int (*di_set_videomode)(const struct display_timing *timings, int enable);
int (*timing_enable)(void);
int (*timing_disable)(void);
};
struct panel_rgb {
unsigned int mode;
unsigned int format;
unsigned int clock_phase;
unsigned int data_order;
unsigned int data_mirror;
};
struct panel_lvds {
enum lvds_mode mode;
enum lvds_link_mode link_mode;
};
struct panel_dsi {
enum dsi_mode mode;
enum dsi_format format;
unsigned int lane_num;
};
struct panel_dbi_commands {
const u8 *buf;
size_t len;
};
struct spi_cfg {
unsigned int qspi_mode;
unsigned int vbp_num;
unsigned int code1_cfg;
unsigned int code[3];
};
struct panel_dbi {
unsigned int type;
unsigned int format;
unsigned int first_line;
unsigned int other_line;
struct panel_dbi_commands commands;
struct spi_cfg *spi;
};
函数接口
接口定义 | int panel_default_prepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 prepare 接口函数,使能 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 负数:失败 |
注意事项 | - |
接口定义 | int panel_default_enable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 enable 接口函数,设置 de 模块的 timing 参数,使能相应的 DI 接口,开启背光 |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_default_unprepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 unprepare 接口函数,禁用 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_default_disable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 disable 接口函数,禁用背光,禁用 DI 接口,禁用 DE |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_register_callback(struct aic_panel *panel, struct aic_panel_callbacks *pcallback) |
---|---|
功能说明 | DE,DI 提供的回调函数,供 panel 调用 |
参数定义 | 结构体 aic_panel 结构体 aic_panel_callbacks |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | void panel_di_enable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 使能相应的 DI 接口 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_di_disable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 禁用相应的 DI 接口 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_de_timing_enable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 启用 DE, 设置 de 模块的 timing 参数 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_de_timing_disable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 禁用 DE, 设置 de 模块的 timing 参数 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_mipi_send_perpare(struct aic_panel *panel) |
---|---|
功能说明 | 将 mipi-dsi 通道切换到 command mode, 准备好给 mipi 屏幕发送初始化命令 |
参数定义 | 结构体 aic_panel |
返回值 | void |
注意事项 | 在 mipi 屏幕发送初始化命令前要先调用这个函数,以确保 mipi 屏幕收到正确的初始化命令 |
接口定义 | void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel) |
---|---|
功能说明 | 给 mipi 屏幕发送初始化命令 |
参数定义 | 结构体 aic_panel , 初始化序列大小 size, 初始化序列 para_cmd |
返回值 | void |
注意事项 | - |
接口定义 | void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel) |
---|---|
功能说明 | 将 mipi-dsi 通道切换回正确的模式 |
参数定义 | 结构体 aic_panel |
返回值 | void |
注意事项 | 在 mipi 屏幕发送完初始化命令后调用这个函数,以确保 mipi 通道正常工作 |
接口定义 | #define panel_dsi_generic_send_seq(panel, seq…) |
---|---|
功能说明 | 发送屏厂根据 mipi 协议扩展的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | #define panel_dsi_dcs_send_seq(panel, seq…) |
---|---|
功能说明 | 发送 mipi 协议标准的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | int panel_dbi_default_enable(struct aic_panel *panel) |
---|---|
功能说明 | mipi-dbi 接口的默认使能函数, 发送 mipi-dbi 的 init_sequence |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |