屏适配指南
本章节介绍 LCD 外设在 Luban-Lite 上的适配方法。
屏配置方式
方式一:通过 menuconfig 修改屏参数
在 Luban-Lite 根目录下执行 scons --menuconfig,进入 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 --->
2
3
4
5
6
7
8
9
小技巧:
方式一仅支持修改 simple panel 的时序参数和 RGB/LVDS 的部分参数。
方式二:将屏参数写入 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,
};
2
3
4
5
6
7
8
9
10
11
屏接口参数
struct panel_dsi dsi = {
.mode = DSI_MOD_VID_PULSE,
.format = DSI_FMT_RGB888,
.lane_num = 4,
};
2
3
4
5
注解:
如果方式一和方式二都配置了屏幕参数,最终生效的是方式二的参数。
屏配置说明
如果适配一款 RGB/LVDS屏幕,通过 menuconfig 选择 ArtInChip simple panel,修改显示参数即可。这类屏幕往往不需要初始化,使用通用的屏驱动即可。详情可参考 menuconfig 配置指南章节。
如果 LCD 屏幕需要初始化动作,则需要为其编写一个 panel 驱动,详情可参考后续的屏驱动说明章节。
屏驱动说明
屏源码位置
bsp/artinchip/drv/display/panel/
新屏驱动适配
LCD 屏驱动,即 panel,本质上是一个回调函数和屏参的集合。新屏适配实际上是重新实现一个 struct aic_panel 结构体。
新增一款屏驱动,可以在 panel 源码目录下,根据屏接口选择一个模板,在模版的基础上进行修改。
MIPI-DSI 接口可参考 panel_dsi_xm91080.c
MIPI-DBI 接口可参考 panel_dbi_ili9486l.c
以 MIPI-DSI 接口为例:
1、拷贝一份模板文件,命名为 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')
2
3
4
5
6
7
8
2、修改 struct aic_panel
的命名,并将其注册。
将 struct aic_panel
添加到 panel_com.c
文件的 panels[]
指针数组中
在 panel_com.h
文件中 extern
struct aic_panel。
//panel_com.c
static struct aic_panel *panels[] = {
...
#ifdef AIC_PANEL_DSI_XXX
&dsi_xxx,
#endif
};
//panel_com.h
extern struct aic_panel dsi_xxx;
2
3
4
5
6
7
8
9
10
3、修改 struct display_timing
结构体,根据 LCD 屏幕规格书修改时序参数。
4、重新实现 aic_panel_funcs 结构体中的 prepare
或者 enable
接口,添加初始化操作。
对于 MIPI-DSI 接口屏幕
1、在发送 init_sequence 前需要调用 panel_mipi_send_perpare() 进入 LP 模式发送命令,确保命令准确发送。
2、在发送完 init_sequence 后需要调用 panel_mipi_setup_realmode() 配置正确的 MIPI 模式。
3、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 接口屏幕
1、panel_dbi.c 为 MIPI-DBI 的 init_sequence 封装了 enable 接口 panel_dbi_default_enable()
数据结构
struct aic_panel
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;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
struct aic_panel_funcs
panel 提供,供驱动框架调用的回调。新屏驱动只需要实现 prepare, enable, disable, unprepare 四个接口。
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);
};
2
3
4
5
6
7
struct aic_panel_callbacks
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);
};
2
3
4
5
6
7
8
struct panel_rgb
rgb 接口屏幕参数
struct panel_rgb {
unsigned int mode;
unsigned int format;
unsigned int clock_phase;
unsigned int data_order;
unsigned int data_mirror;
};
2
3
4
5
6
7
struct panel_lvds
lvds 接口屏幕参数
struct panel_lvds {
enum lvds_mode mode;
enum lvds_link_mode link_mode;
};
2
3
4
struct panel_dsi
mipi-dsi 接口屏幕参数
struct panel_dsi {
enum dsi_mode mode;
enum dsi_format format;
unsigned int lane_num;
};
2
3
4
5
struct panel_dbi
mipi-dbi 接口屏幕参数
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;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
函数接口
panel_default_prepare
接口定义 | int panel_default_prepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 prepare 接口函数, 使能 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 负数:失败 |
panel_default_enable
接口定义 | int panel_default_enable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 enable 接口函数,设置 de 模块的 timing 参数,使能相应的 DI 接口,开启背光 |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 |
panel_default_unprepare
接口定义 | int panel_default_unprepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 unprepare 接口函数,禁用 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 |
panel_default_disable
接口定义 | int panel_default_disable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 disable 接口函数,禁用背光,禁用 DI 接口,禁用 DE |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 |
panel_register_callback
接口定义 | int panel_register_callback(struct aic_panel *panel, struct aic_panel_callbacks *pcallback) |
---|---|
功能说明 | DE,DI 提供的回调函数,供 panel 调用 |
参数定义 | 结构体 aic_panel, 结构体 aic_panel_callbacks |
返回值 | 0: 成功 |