概要:
xilinx平台zynqmp 7ev芯片,是arm+fpga的异构,一块soc内部集成了cpu、ccu、rpu、vcu以及gpu单元,由于应用在医疗内窥镜领域,需要满足复杂的显示接口,SDI、HDMI、DVI、LVDS、CVBS等显示端口,为了解决这需求,接口功能只能够由fpga构成底层硬件电路,上层通过软件控制实现
在1080p底分辨率时能通过arm端控制mix ip融合之后输出1080p的rgb数据,fpga在通过verilog或硬件驱动芯片完成视频数据的搬运,但当显示数据分辨率到达3840x2160之后,上述方法无法实现SDI和HDMI同显的功能需求,需要使用12G SDI和HDMI 2.0的IP实现,由于在xilinx驱动中只能实现单路接口显示,无法实现同显功能,需要从HDMI和SDI中剥离drm接口驱动,完成显示
下面是HDMI驱动代码研究笔记
1、先看文件入口
下面代码通过of_match_table从设备树中根据compatible匹配对应的节点
在compatible中写入要匹配的字符串
2、进入probe函数
3、probe函数中定义了xlnx_drm_hdmi结构体,先了解其成员变量,下面是裁剪过的,我认为显示中重要的几个,drm相关的,时钟,中断,寄存器地址,phy,像hdcp audio项目中暂时不需要
struct xlnx_drm_hdmi {
/*drm框架encoder节点*/
struct drm_encoder encoder;
/*drm框架connector*/
struct drm_connector connector;
//设备结构体
struct device *dev;
/*hdmi ip核寄存器地址*/
void __iomem *iomem;
//时钟
/* video streaming bus clock */
struct clk *clk;
struct clk *axi_lite_clk;
/* tmds clock for output res */
struct clk *tmds_clk;
/* retimer that we configure by setting a clock rate */
struct clk *retimer_clk;
/* HDMI TXSS interrupt */
int irq;
bool teardown;
struct phy *phy[HDMI_MAX_LANES];
/* mutex to prevent concurrent access to this structure */
struct mutex hdmi_mutex;
/* protects concurrent access from interrupt context */
spinlock_t irq_lock;
bool cable_connected;
bool hdmi_stream_up;
bool have_edid;
bool is_hdmi_20_sink;
int dpms;
XVidC_ColorFormat xvidc_colorfmt;
XVidC_ColorDepth xvidc_colordepth;
/* 基线子系统驱动程序实例的配置 */
XV_HdmiTxSs_Config config;
/* 基线子系统驱动程序实例的簿记 */
XV_HdmiTxSs xv_hdmitxss;
/* 子核中断状态寄存器 */
u32 IntrStatus;
/* 指向xvphy的指针 */
XVphy *xvphy;
/* 指向xgphy的指针 */
XHdmiphy1 *xgtphy;
/* 标志来确定哪个Phy */
u32 isvphy;
};
4、分配空间
5、获取平台设备dev结构体
6、hdmi ip核寄存器地址映射
7、获取设备树信息
8、配置phy相关内容
9、写入hdmi ip核基地址和最大偏移量
10、获取时钟
s_axis_video_aclk
s_axi_cpu_aclk
txref-clk
retimer-clk
①、s_axis_video_aclk
②、s_axi_cpu_aclk
③、txref-clk
④、retimer-clk
11、获取中断
12、创建sysfs组
13、设置平台数据
14、硬件初始化,配置hdmi ip核
①、设置默认颜色格式为RGB
②、ip核复位
③、设置事件上升边缘掩码
④、设置HPD的时间网格
⑤、设置DDC
⑥、使能中断
15、drm握手