内容和参考
内容
参考
- Linux源码: linux源码国内源下载 和 Linux源码GitHub
硬件信息

软件代码
设备树配置
参考文档:Documentation/devicetree/bindings/display/arm,malidp.txt
编译选项
mali-dp-y := malidp_drv.o malidp_hw.o malidp_planes.o malidp_crtc.omali-dp-y += malidp_mw.o
代码流程
malidp初始化流程
硬件描述信息
mali-dp得硬件描述不仅仅来源于设备树,驱动中患有一个表位于 struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] 中,描述了寄存器及硬件得详细信息。
static const struct of_device_id malidp_drm_of_match[] = {
{ .compatible = "arm,mali-dp550", .data = &malidp_device[MALIDP_550]},
}
[MALIDP_550] = {
.map = {
.coeffs_base = MALIDP550_COEFFS_BASE,
.se_base = MALIDP550_SE_BASE,
.dc_base = MALIDP550_DC_BASE,
.out_depth_base = MALIDP550_DE_OUTPUT_DEPTH,
.features = MALIDP_REGMAP_HAS_CLEARIRQ |
MALIDP_DEVICE_AFBC_SUPPORT_SPLIT |
MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT |
MALIDP_DEVICE_AFBC_YUYV_USE_422_P2,
.n_layers = ARRAY_SIZE(malidp550_layers),
.layers = malidp550_layers,
.de_irq_map = {
......
.pixel_formats = malidp550_de_formats,
.n_pixel_formats = ARRAY_SIZE(malidp550_de_formats),
.bus_align_bytes = 8,
},
.query_hw = malidp550_query_hw,
.enter_config_mode = malidp550_enter_config_mode,
.leave_config_mode = malidp550_leave_config_mode,
.in_config_mode = malidp550_in_config_mode,
.set_config_valid = malidp550_set_config_valid,
.modeset = malidp550_modeset,
.rotmem_required = malidp550_rotmem_required,
.se_set_scaling_coeffs = malidp550_se_set_scaling_coeffs,
.se_calc_mclk = malidp550_se_calc_mclk,
.enable_memwrite = malidp550_enable_memwrite,
.disable_memwrite = malidp550_disable_memwrite,
.features = 0,
},
// 支持得图像格式
static const struct malidp_format_id malidp550_de_formats[] = {
MALIDP_COMMON_FORMATS,
};
// 支持得图层:4层图层,LV1, LG1, LV2, LS
static const struct malidp_layer malidp550_layers[] = {
/* id, base address, fb pointer address base, stride offset,
* yuv2rgb matrix offset, mmu control register offset, rotation_features
*/
{ DE_VIDEO1, MALIDP550_DE_LV1_BASE, MALIDP550_DE_LV1_PTR_BASE,
MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY,
MALIDP550_DE_LV1_AD_CTRL },
{ DE_GRAPHICS1, MALIDP550_DE_LG_BASE, MALIDP550_DE_LG_PTR_BASE,
MALIDP_DE_LG_STRIDE, 0, 0, ROTATE_ANY,
MALIDP550_DE_LG_AD_CTRL },
{ DE_VIDEO2, MALIDP550_DE_LV2_BASE, MALIDP550_DE_LV2_PTR_BASE,
MALIDP_DE_LV_STRIDE0, MALIDP550_LV_YUV2RGB, 0, ROTATE_ANY,
MALIDP550_DE_LV2_AD_CTRL },
{ DE_SMART, MALIDP550_DE_LS_BASE, MALIDP550_DE_LS_PTR_BASE,
MALIDP550_DE_LS_R1_STRIDE, 0, 0, ROTATE_NONE, 0 },
};
malidp_de_planes_init
malidp550_layers 中可以看到 mali-dp550支持4个plane,对每层plane 从 malidp550_de_formats 中 获取到当前层所支持得formats,然后依次调用以下进行初始化:
中断相关
初始化 和 卸载
在手册 2.4.1 章节中 描述了:
Mali-DP550 每路支持两个中断: IRQDE, IRQSE
- IRQDE0. Interrupt request signal from the primary display core and primary display engine.
- IRQSE0. Interrupt request signal from the primary scaling engine.
这里配置有几个概念:
- mali-dp550 包含IRQDE 和 IRQSE 两个中断, 其中DC得状态也在DE中断中处理。
mali-dp550 得 DE, DC, SE前边几个寄存器地址一致,所以 malidp_hw_disable_irq, malidp_hw_clear_irq,malidp_hw_enable_irq 等操作中断得接口封装成统一接口。
#define MALIDP_REG_STATUS 0x00000 #define MALIDP_REG_SETIRQ 0x00004 #define MALIDP_REG_MASKIRQ 0x00008 #define MALIDP_REG_CLEARIRQ 0x0000cmali-dp550得 disable irq 是给 MALIDP_REG_MASKIRQ 写0,而不是写1(这点和其他不一致)。
- mali-dp550得 clear irq 是给 MALIDP_REG_CLEARIRQ 写1。
- mali-dp550得中断使能 策略 是 根据 malidp_device 这个全局结构体中配置得策略进行使能和屏蔽得。
在中断初始化时,根据 .irq_mask进行配置 使能,在中断处理函数里 判断 .vsync_irq 和 .err_mask 状态。
struct malidp_irq_map {
u32 irq_mask; /* mask of IRQs that can be enabled in the block */
u32 vsync_irq; /* IRQ bit used for signaling during VSYNC */
u32 err_mask; /* mask of bits that represent errors */
};
const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES] = {
.de_irq_map = {
.irq_mask = MALIDP_DE_IRQ_UNDERRUN |
MALIDP500_DE_IRQ_AXI_ERR |
MALIDP500_DE_IRQ_VSYNC |
MALIDP500_DE_IRQ_GLOBAL,
.vsync_irq = MALIDP500_DE_IRQ_VSYNC,
.err_mask = MALIDP_DE_IRQ_UNDERRUN |
MALIDP500_DE_IRQ_AXI_ERR |
MALIDP500_DE_IRQ_SATURATION,
},
.se_irq_map = {
.irq_mask = MALIDP500_SE_IRQ_CONF_MODE |
MALIDP500_SE_IRQ_CONF_VALID |
MALIDP500_SE_IRQ_GLOBAL,
.vsync_irq = MALIDP500_SE_IRQ_CONF_VALID,
.err_mask = MALIDP500_SE_IRQ_INIT_BUSY |
MALIDP500_SE_IRQ_AXI_ERROR |
MALIDP500_SE_IRQ_OVERRUN,
},
.dc_irq_map = {
.irq_mask = MALIDP500_DE_IRQ_CONF_VALID,
.vsync_irq = MALIDP500_DE_IRQ_CONF_VALID,
},
}
软件流程:
malidp_irq_init
malidp_de_irq_init(drm, irq_de);
// 屏蔽中断+清中断
malidp_hw_disable_irq(hwdev, MALIDP_DE_BLOCK, 0xffffffff);
malidp_hw_clear_irq(hwdev, MALIDP_DE_BLOCK, 0xffffffff);
malidp_hw_disable_irq(hwdev, MALIDP_DC_BLOCK, 0xffffffff);
malidp_hw_clear_irq(hwdev, MALIDP_DC_BLOCK, 0xffffffff);
// 注册中断
devm_request_threaded_irq(malidp_de_irq)
// 根据 malidp_device 中对应irq_mask 打开相应中断
malidp_hw_enable_irq(hwdev, MALIDP_DC_BLOCK,
hwdev->hw->map.dc_irq_map.irq_mask);
malidp_hw_enable_irq(hwdev, MALIDP_DE_BLOCK,
hwdev->hw->map.de_irq_map.irq_mask);
malidp_se_irq_init(drm, irq_se);
// 同上
malidp_se_irq_fini
malidp_hw_disable_irq(hwdev, MALIDP_SE_BLOCK,
hwdev->hw->map.se_irq_map.irq_mask);
malidp_de_irq_fini
// 同上
