1. 程式人生 > >Rockchip之RK3288HDMI介面插拔檢測

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屏正常顯示,哈哈,就這樣舒服完工。

寫這篇那麼囉嗦的筆記是因為想給那些沒有遇到過此類問題的開發人員,當在網上查詢資料無處可查時,能在看到我的這篇筆記之後有些思路,同時也很歡迎各位看過我的筆記的人在發現問題之後能慷慨指出