Rockchip之RK3288HDMI接口插拔检测

Rockchip之RK3288HDMI接口插拔检测

任务背景:
最近机器的一块屏出现不显示或者白屏现象,这块屏是一块MIPI屏,但它是由3288上的HDMI接口通过一块LPC转接板转成MIPI接口的,所以根源还是HDMI接口,猜想可能是HDMI转MIPI的HDMI插拔检测脚导致的,因此,试着把这个插入检测去掉让HDMI信号直接输出看看结果,首先查看原理图
在这里插入图片描述
检测脚为HDMI_HPD这个脚,首先介绍一下HDMI的知识

1.HDMI接口知识
HDMI,高清晰多媒体接口(英文:High Definition Multimedia Interface),是一种数字化视频/音频接口技术,是是和影像传输的专用数字化接口,其可同时传送音频和影像信号,最高数据传输速度为18Gbps(2.0版)。

2.HDMI状态检测的硬件原理
如Fig.2(来自参考文献[1])所示,当插上HDMI接口时,主机会对显示器的DDC(display data channel)提供5V电压;这个电压经18脚、显示器,再从19脚返回主机;三极管Q1导通,使得HPD脚检测到高电平(大于2V),此时,则认为显 示器已连接。若HPD脚检测到低电平(小于0.8V)则认为显示未连接。
在这里插入图片描述
摘自:http://blog.csdn.net/wurifeng0531_201702/article/details/59212811

由于我的rk3288板子是将HDMI信号通过一个LPC转接板转化成了mipi信号,LPC板子上有一个转门控制HPD脚电压的电路,稍微修改电路之后将HDMI的HPD脚变成0v低电平让rk3288板视为没有HDMI插入,因此原固件当然不输出HDMI信号,屏自然也不显示,现在的目的就是为了让屏亮显示起来。

起初没有一点头绪,网上搜索各种帖子论坛都无果,偶然间看到rk的论坛里有一个帖子的回复说“插入HDMI 时,不上报其插入状态.
drivers/video/rockchip/hdmi/rk_hdmi_task.c 里面

 switch_set_state(&(hdmi->switch_hdmi), 1);

改为:

 switch_set_state(&(hdmi->switch_hdmi), 0);”

于是我立马就在我的source Insight 里搜索定位,果然有这个函数,并且很幸运他所在的函数名为hdmi_wq_insert,利用我蹩脚的英语翻译过来就是hdmi插入,真是太棒了,然后眼睛定位到switch_set_state(&(hdmi->switch_hdmi), 1);函数
在这里插入图片描述
当时我很天真的以为去掉上面hdmi->enable的判断就完事了,于是就高高兴兴的编译烧录重启等待,GG,竟然还是不显示,但是我没有灰心于是继续跟读代码.

在HDP修改回高电平然后屏蔽switch_set_state函数mipi屏不显示了,好了,找到了关键地方,只要能执行到这里问题就解决了,由于我不确认内核运行时是否进入这个函数,于是就在跟读函数时加入了大量的printk,然后在内核起来的时候打印内核的调试信息来看,显然效果是很明显的
在这里插入图片描述
从跟读代码和printk我很清晰的知道了内核起来的时候HDMI的drive会去匹配HDMI的devices,匹配成功就调用probe函数
在这里插入图片描述
在这个函数里会去进行一系列的获取资源,申请资源等操作,最终会进入到一个中断检测的函数
在这里插入图片描述
rockchip_hdmiv2_dev_irq这个函数是HDMI中断检测服务函数最终我们要将这个函数屏蔽,才能取消中断检测,当检测到HPD脚为高电平时会进入到这个中断服务函数里,这个函数里有一个尤为关键的函数hdmi_submit_work ,根据函数名我们也可以知道是上报工作函数
在这里插入图片描述
具体这个函数里面是什么东西呢,让我们去看看
在这里插入图片描述
进去之后你会发现别有洞天,里面又是不认识的一番景象,不要急慢慢来,在这个函数里你会发现一个特别重要的函数INIT_DELAYED_WORK,这个函数叫work工作队列作用就是把工作推后,交由一个内核线程去执行,更直接的就是说如果你写了一个函数,而不想马上执行它,你想在将来某个时刻去执行它,那就用工作队列,这个工作队列做的工作就是去执行hdmi_work_queue这个函数
在这里插入图片描述
进入这个函数你又会发现噼里啪啦的一大堆,你会感叹这都是什么鬼,老子不干了
在这里插入图片描述
当然不行,工作还要做,赚钱重要.看代码重要.

看代码你会发现然不知到进入switch的那个case,这种情况下只能通过printk来尝试看到进入了哪里,在内核调试的阶段,printk可以说是一个很强大的工具,经过一番折腾之后发现先进入
HDMI_ENABLE_CTL----->
HDMI_HPD_CHANGE------>
HDMI_ENABLE_HDCP

具体就不详细说了,然后重要的还是进入 HDMI_HPD_CHANGE时,里面有个hdmi_wq_insert函数,这样一来就回到了开始说的,执行了关键函数switch_set_state屏就能正常显示,所以从源头到结尾全部打通.

注意,注意,注意,重要的事情说三遍,上面说的要把rockchip_hdmiv2_dev_irq这个HDMI中断服务函数,那么屏蔽了之后就检测不了插入和拔出状态,然后之前的代码就必须要改,屏蔽了rockchip_hdmiv2_dev_irq会直接导致进不去hdmi_wq_insert,原因如下:
在这里插入图片描述
原来是当检测到插入时会return HDMI_HPD_ACTIVED这个标志位,检测到拔出时会return HDMI_HPD_REMOVED,这个很重要,这个会直接导致能不能进入hdmi_wq_insert函数
在这里插入图片描述
所以不管有没有插入都要直接让他返回HDMI_HPD_ACTIVED,如下:
在这里插入图片描述
最后还有一步不能少,就是将device设备初始化的函数给屏蔽rk_display_device_enable
在这里插入图片描述
然后编译烧录重启搞定,HDMI信号成功输出,HDMI转mipi屏正常显示,哈哈,就这样舒服完工。

写这篇那么啰嗦的笔记是因为想给那些没有遇到过此类问题的开发人员,当在网上查询资料无处可查时,能在看到我的这篇笔记之后有些思路,同时也很欢迎各位看过我的笔记的人在发现问题之后能慷慨指出

猜你喜欢

转载自blog.csdn.net/Shushan1/article/details/85763270