Display Controller 显示处理单元
模块功能介绍
• 图层特性:
显示处理单元支持4层DMA通道;
输入格式支持RGB88,ARGB8888,RGB565,RGB555,ARGB1555,NV12/NV21, YUV422;
支持2级TLB;
支持图像裁剪;
支持4层透明混合处理;
支持2层缩放;
支持写回DMA;
• 显示特性:
支持TFT(MIPI-DPI),SLCD(MIPI-DBI type A,B and C),MIPI-DSI;
驱动源码位置
驱动源码所在位置:
module_drivers/drivers/video/fbdev/ingenic/fb_stage
添加屏
1. 在***module_drivers/drivers/video/fbdev/ingenic/fb_stage/displays/***下新建相关屏的文件
以FW050为例
2. 在Kconfig中添加屏的标志和依赖,路径如下:
module_drivers/drivers/video/fbdev/ingenic/fb_stage/displays/Kconfig
以FW050为例
config STAGE_FW050
tristate "lcd panel FW050"
depends on FB_INGENIC_DISPLAYS_STAGE
help
lcd panel FW050, for ingenicfb drivers.
3. 在Makefile中添加新的编译文件,文件路径如下:
module_drivers/drivers/video/fbdev/ingenic/fb_stage/displays/Makefile
以FW050为例
obj-$(CONFIG_STAGE_FW050) += panel-fw050.o
4. 根据屏幕手册配置完成屏文件后,在内核编译配置中选择新添加的屏。
5. 注意事项
• 保证MIPI lcd 的各路电压都正常
• 保证复位引脚时序正常
• 保证lcd 的clk设置正常,差距不易过大,否则可能导致屏幕不亮
• 保证lcd 的hbp,fbp,vfb,vbp等各项参数正常
• 如果有初始化参数,需保证初始化参数是对的
• MIPI屏需保证MIPI 屏幕各项设置参数以及MIPI接口参数设置函数是对的
设备树配置
设备树所在位置:
kernel内核(version <= 5.10)dts文件路径:
module_driver/dts-stage/x2000/x2000.dtsi
kernel内核(version > 5.10)dts文件路径:
module_driver/dts/x2000/x2000.dtsi
DPU控制器描述:
dpu: dpu@0x13050000 {
compatible = "ingenic,x2000-dpu";
reg = <0x13050000 0x10000>;
interrupt-parent = <&core_intc>;
interrupts = <IRQ_LCD>;
status = "disabled";
};
设备树默认配置
设备树默认编译会产生DPU控制器设备。
DPU控制器配置
根据屏幕大小以及型号配置相应的设置
|
ingenic,disable-rdma-fb |
选择是否关闭RDMA:0不关闭; 1关闭 |
|
ingenic,layer-exported |
图层导出;0不导出; 1导出 |
|
ingenic,layer-frames |
每层支持framebuffer的个数:最大为3 |
|
ingenic,layer-framesize |
framebuffer的大小 |
|
layer,color_mode |
输入图像的格式: |
|
0:RGB888 |
1:ARGB8888 |
|
2:RGB555 |
3:ARGB1555 |
|
4:RGB565 |
5:YUV422 |
|
6:NV12 |
7:NV21 |
|
layer,src-size |
源图像大小 |
|
layer,target-size |
目标图像大小 |
|
layer,target-pos |
图像起始位置 |
|
layer,enable |
使能层:1:使能 0:未使能 |
|
remote-endpoint |
远程端点:显示屏配置与控制器配置对应 |
在halley5_v30.dts中配置如下:
&dpu {
status = "okay";
ingenic,disable-rdma-fb = <1>;
/*Defines the init state of composer fb export infomations.*/
ingenic,layer-exported = <1 1 0 0>;
ingenic,layer-frames = <2 2 2 2>;
ingenic,layer-framesize
= <720 1280>, <720 1280>, <320 240>, <320 240>;
/*Max framesize for each layer.*/
layer,color_mode = <0 0 0 0>; /*src fmt,*/
layer,src-size
= <720 1280>, <720 1280>, <320 240>, <240 200>;
/*Layer src size should smaller than framesize*/
layer,target-size
= <720 1280>, <720 640>, <160 240>, <240 200>;
/*Target Size should smaller than src_size.*/
layer,target-pos
= <0 0>, <0 640>, <340 480>, <100 980>;
/*target pos , the start point of the target panel.*/
layer,enable = <1 1 1 1>; /*layer enabled or disabled.*/
ingenic,logo-pan-layer = <0>; /*on which layer should init logo pan on.*/
port {
dpu_out_ep: endpoint {
remote-endpoint = <&panel_fw050_ep>;
};
};
};
显示屏配置
|
compatible |
兼容的屏幕,与屏幕文件设置的对应 |
|
status |
okay:使用设备 disable:不使用设备 |
|
pinctrl-0 |
根据具体的屏选择不同的引脚配置 |
|
ingenic,vdd-en-gpio |
供电引脚:PC03 |
|
ingenic,rst-gpio |
复位引脚:PC04 |
|
ingenic,lcd-pwm-gpio |
背光引脚:PC01 |
display-dbi {
compatible = "simple-bus";
#interrupt-cells = <1>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <>;
panel_fw050 {
compatible = "ingenic,fw050";
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&smart_lcd_pb_te>;
ingenic,vdd-en-gpio = <&gpc 3 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
ingenic,rst-gpio = <&gpc 4 GPIO_ACTIVE_LOW INGENIC_GPIO_NOBIAS>;
/* ingenic,lcd-pwm-gpio = <&gpc 1 GPIO_ACTIVE_HIGH INGENIC_GPIO_NOBIAS>;*/
port {
panel_fw050_ep: endpoint {
remote-endpoint = <&dpu_out_ep>;
};
};
};
};
设备树自定义配置
用户可根据实际需求关闭dpu设备,将以上节点配置为disabled。
x2000 DPU 支持的屏幕种类
• smart lcd: dbi硬件接口,液晶屏有自己的ram,防裂屏需要有te功能
• tft lcd: dpi硬件接口,没有ram,需要按照一定的帧率刷新屏幕
• mipi smart lcd: dsi硬件接口,液晶屏有自己的ram
• mipi tft lcd: dsi硬件接口,没有ram,需要按照一定的帧率刷新屏幕
匹配其他型号显示屏
• 设置是否使用rdma,层数,帧大小,输入图像格式,源图像大小,目标图像大小,图像显示的起始位置等
• DPU控制器端点(port)与显示屏配置端点对应
• 配置兼容的屏(compatible)
• 根据不同型号的屏选择控制引脚(pinctrl-0),不同的引脚设置在module_drivers/dts-stage/x2000/x2000-pinctrl.dtsi或module_drivers/dts/x2000/x2000-pinctrl.dtsi
• 根据不同的屏配置其他与屏相关的引脚,例如供电引脚,复位引脚等
内核模块差异
屏幕配置
屏幕配置
struct lcd_panel {
unsigned int num_modes; /*显示模式支持的数量,固定值1*/
struct fb_videomode *modes; /*显示模式*/
struct jzdsi_data *dsi_pdata; /*如果屏幕是mipi dsi接口需要实现*/
enum ingenic_lcd_type lcd_type; /*屏幕种类,如果是mipi tft lcd需要配置LCD_TYPE_TFT,其它的按功能配置*/
unsigned int bpp; /*不需要填充*/
unsigned int width; /*屏幕实际物理宽度,单位mm*/
unsigned int height; /*屏幕实际物理高度,单位mm*/
struct smart_config *smart_config; /*如果屏幕是smart lcd需要实现*/
struct tft_config *tft_config; /*如果屏幕是tft lcd需要实现*/
unsigned dither_enable:1; /*打开dither功能*/
struct {
unsigned dither_red;
unsigned dither_green;
unsigned dither_blue;
} dither;
};
struct fb_videomode {
const char *name; /* optional */
u32 refresh; /*配置帧率,驱动会根据配置参数和帧率计算pixclock*/
u32 xres; /*显示有效宽度,按照屏手册填写*/
u32 yres; /*显示有效高度,按照屏手册填写*/
u32 left_margin; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 right_margin; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 upper_margin; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 lower_margin; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 hsync_len; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 vsync_len; /*tft屏时按照手册填写,当smart lcd时赋值0*/
u32 sync; /*当mipi dsi tft lcd时需要赋值(FB_SYNC_HOR_HIGH_ACT & FB_SYNC_VERT_HIGH_ACT),其他的屏幕不关注*/
u32 vmode; /*默认值:FB_VMODE_NONINTERLACED*/
u32 flag;
};
smart lcd 配置
struct smart_config {
unsigned int te_switch; /*smart lcd te功能控制*/
unsigned int te_mipi_switch; /*设置 mipi dsi smart lcd te功能控制*/
unsigned int te_md; /*0:te前沿有效,1:后沿有效*/
unsigned int te_dp; /*0:te低电平有效,1:高电平有效*/
unsigned int te_anti_jit; /*0:te信号保持1个pixclk有效,1:te信号保持3个pixclk有效*/
unsigned int dc_md; /*0:DC高电平数据,低电平命令, 1:DC高电平命令,低电平数据*/
unsigned int wr_md; /*0:下降沿采样,1:上升沿采样 */
enum smart_lcd_type smart_type; /*smart slcd种类,支持6800/8080/spi-3/spi-4*/
enum smart_lcd_format pix_fmt; /*总线数据格式,支持565,666等*/
enum smart_lcd_dwidth dwidth; /*数据总线宽度*/
enum smart_lcd_cwidth cwidth; /*命令总线宽度*/
unsigned int bus_width;
unsigned long write_gram_cmd; /*发送数据前需要发送的命令,默认0x2c*/
unsigned int length_cmd; /*不需要实现*/
struct smart_lcd_data_table *data_table; /*配置屏幕命令表*/
unsigned int length_data_table; /*配置屏幕命令数量*/
int (*init) (void); /*不需要实现*/
int (*gpio_for_slcd) (void); /*不需要实现*/
};
tft lcd配置
struct tft_config {
unsigned int pix_clk_inv; /*0:pixclk默认输出, 1:反转pixclk*/
unsigned int de_dl; /*0:DE引脚高电平输出有效数据, 1:低电平输出有效数据*/
unsigned int sync_dl; /*0:vsync和hsync引脚高电平输出有效数据, 1:低电平输出有效数据*/
enum tft_lcd_color_even color_even; /*偶数行时总线RGB顺序*/
enum tft_lcd_color_odd color_odd; /*奇数行时总线RGB顺序*/
enum tft_lcd_mode mode; /*总线数据格式,支持888/666/565*/
};
mipi dsi lcd配置
1. mipi dsi lcd 配置
struct jzdsi_data jzdsi_pdata = {
.modes = &panel_modes, /*显示模式*/
.video_config.no_of_lanes = 2, /*按照硬件连接填写,支持1、2lane*/
.video_config.virtual_channel = 0, /*默认值:0*/
.video_config.color_coding
= COLOR_CODE_24BIT, /*RGB888:COLOR_CODE_24BIT,
RGB565:COLOR_CODE_16BIT_CONFIG1,注:当smart lcd时需要配置COLOR_CODE_24BIT*/
.video_config.video_mode = VIDEO_BURST_WITH_SYNC_PULSES, /*默认值:VIDEO_BURST_WITH_SYNC_PULSES*/
.video_config.receive_ack_packets = 0, /*默认值:0*/
.video_config.is_18_loosely = 0, /*默认值:0*/
.video_config.data_en_polarity = 1, /*默认值:1*/
.video_config.byte_clock = 0, /*默认值:0,驱动根据配置参数自动计算*/
.video_config.byte_clock_coef
= MIPI_PHY_BYTE_CLK_COEF_MUL6_DIV5,
/*byte_clock系数,需要根据实际情况变动系数,保证正常显示情况下系数越小越好,例:MUL6_DIV5=1.2(乘6除5)*/
.dsi_config.max_lanes = 2, /*固定值:2*/
.dsi_config.max_hs_to_lp_cycles = 100, /*默认值:100*/
.dsi_config.max_lp_to_hs_cycles = 40, /*默认值:40*/
.dsi_config.max_bta_cycles = 4095, /*默认值:4095*/
.dsi_config.color_mode_polarity = 1, /*默认值:1*/
.dsi_config.shut_down_polarity = 1, /*默认值:1*/
.dsi_config.max_bps = 2750, /*默认值:2.75Gbps*/
.bpp_info = 24, /*RGB888:24 RGB565:16,注:当smart lcd时需要配置24*/
};
1. mipi dsi屏幕寄存器通用配置方式
发送大于等于2个参数:
struct dsi_cmd_packet cmd = {0x39, 0x05, 0x00, {0x2A, 0x00, 0x00, 0x02, 0xCF}}
0x39: 命令种类,发送大于等于2个参数
0x05: 参数个数,5个参数
0x00: 无意义,默认填充0x00
{0x2A, 0x00, 0x00, 0x02, 0xCF}: 5个参数值
发送2个参数:
struct dsi_cmd_packet cmd = {0x15, 0xC2, 0x08}
0x15: 命令种类,发送2个参数
0xC2: 第一个参数
0x08: 第二个参数
发送1个参数
struct dsi_cmd_packet cmd = {0x05, 0x10, 0x00}
0x05: 命令种类,发送1个参数
0x10: 第一个参数
0x00: 无意义,默认填充0x00
pwm背光配置
需要使用pwm背光时可进行如下配置:
&pwm {
pinctrl-names="default";
pinctrl-0=<*** ***&pwm1_pc>; /*按照实际情况配置pwm的gpio*/
status="okay";
};
backlight {
compatible="pwm-backlight";
pwms=<&pwm 1 1000000>; /*选择pwm1控制背光,设置period1000000ns*/
brightness-levels=<0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15>;/*背光等级,可根据需求调整*/
default-brightness-level=<4>;
}
内核编译配置
控制器驱动配置(FB_INGENIC_STATE):
Symbol: FB_INGENIC_STAGE [=y]
Type : tristate
Prompt: Ingenic Framebuffer Driver for stage
Location:
-> Ingenic device-drivers Configurations
-> [LCD] Panel/Touchscreen Drivers
-> Ingenic Framebuffer Driver (FB_INGENIC [=y])
Defined at module_drivers/drivers/video/fbdev/ingenic/fb_stage/Kconfig
### pwm背光驱动配置(PWM_INGENIC_V2):
Symbol: PWM_INGENIC_V2 [=y]
Type : tristate
Prompt: Ingenic PWM V2 support
Location:
-> Ingenic device-drivers Configurations
-> [PWM] drivers
Defined at module_drivers/drivers/pwm/Kconfig
显示屏配置(STAGE_FW050)
mipi dsi接口的屏幕支持自动探测,自动探测会挨个判断选中的屏幕是否可用,当有一款屏幕可用或者所有的屏幕都不可用时停止探测。如下为选择屏FW050。
CONFIG_STAGE_FW050:
lcd panel FW050, for ingenicfb drivers.
Symbol: STAGE_FW050 [=y]
Type : tristate
Prompt: lcd panel FW050
Location:
-> Ingenic device-drivers Configurations
-> [LCD] Panel/Touchscreen Drivers
-> Ingenic Framebuffer Driver (FB_INGENIC [=y])
-> Ingenic Framebuffer Driver for stage (FB_INGENIC_STAGE [=y])
-> Supported lcd panels (FB_INGENIC_DISPLAYS_STAGE [=y])
Defined at module_drivers/drivers/video/fbdev/ingenic/fb_stage/displays/Kconfig
tlb功能使用方法
1. 申请的数据buffer地址需要按4096对齐.
2. 数据buffer虚拟内存到物理内存的映射和tlb表的制作函数.
unsigned int gtlb_base = ioctl(int fd, JZFB_DMMU_MAP, struct dpu_dmmu_map_info *di)
如果使用的数据buffer是多次申请获得的,需要多次调用函返回tlb表地址,也可以一次完成buffer的申请并调用一次函数。
int fd /*fb设备文件描述符*/
unsigned int gtlb_base /*tlb一级页表地址,地址值唯一,所以多次调用后返回值相同*/
struct dpu_dmmu_map_info {
unsigned int addr; /*buffer 地址*/
unsigned int len; /*buffer地址的长度*/
};
1. 配置tlb一级页表地址函数
ioctl(int fd, JZFB_USE_TLB, unsigned int gtlb_base);
int fd /*fb设备文件描述符 */
unsigned int gtlb_base
2. 给驱动传递每层的buffer地址
struct jzfb_lay_cfg {
.addr[0] = 0x7xxxxxxx; /*0帧的地址*/
.addr[1] = 0x7xxxxxxx; /*1帧的地址*/
.addr[2] = 0x7xxxxxxx; /*2帧的地址*/
}
3. 更新图像数据后刷新cache函数
ioctl(int fd, JZFB_DMMU_FLUSH_CACHE, struct dpu_dmmu_map_info *di)
设备节点生成
驱动加载成功后生成以下节点:
/dev/fb0
/dev/fb1
注意事项
(1)最多支持2层缩放,缩放可以是任意2层
(2)只有1,2层支持yuv422、nv12、nv21
(3)TFT屏出现裂屏时,可以修改framebuffer的数量(默认为1),可以将其修改为2或3,在内核编译配置中修改完framebuffer数量后在设备树中修改,两者取小值。
内核编译配置如下:
Symbol: FB_INGENIC_NR_FRAMES [=1]
Type : integer
Prompt: how many frames support
Location:
-> Ingenic device-drivers Configurations
-> [LCD] Panel/Touchscreen Drivers
-> Ingenic Framebuffer Driver (FB_INGENIC [=y])
Defined at drivers/video/fbdev/ingenic/Kconfig
(4)slcd屏出现裂屏时,可以通过te引脚改变