這篇文章我們介紹一下在安卓9、10、11的版本上,rk平臺的hdmi-in功能是如何實現的,下篇文章我們再介紹安卓12之后的版本有了什么變化。希望對在rk平臺調試hdmi-in功能的朋友有一些幫助。
目錄
(1)概述
(2)基本功能流程實現原理
1.系統功能框圖
2.系統功能流程
2.1 APK工作流程
2.2?熱拔插
2.3 切換分辨率
(3)功能配置說明
1.驅動代碼與配置
1.1 驅動代碼
1.2 config配置
2.DTS配置
2.1 設備配置
2.2 圖像鏈路配置
2.2.1 RK3399
2.2.2 RK3568
3.camera xml注冊設備
3.1 設備名稱與ID
3.2 分辨率配置
3.3 SOC模式
3.4 旋轉角配置
4.APK適配
4.1 獲取APK
4.2 APK 源碼適配
5.EDID配置
(4)調試方法
1.查看設備是否注冊camera
2.查看拓撲結構
3.v4l2抓取數據流
4.v4l2抓圖
5.不同芯片平臺接收能力
6.配置使用ISP CMA內存
7.配置RK3399 ISP超頻
(5)總結
(1)概述
安卓9/10/11等版本一般對應的都是rk比較舊的主控芯片,例如rk3399、rk3568/6等等,這里呢,我們又可以分為兩類,一類是rk3399等較久的主控,一類是RK3566/8兩個平臺。rk3399之類的主控芯片沒有VICAP的圖像模塊,都是通過ISP接收HDMI-IN的圖像數據,RK3566/68的平臺有VICAP(RKCIF)模塊,也有RKISP模塊,可以兩種方式實現。
在RK的主控芯片中只有RK3588擁有獨立的HDMIRX模塊,其他主控芯片都沒有HDMI-RX模塊,想要實現HDMI-IN 的功能只能通過外掛轉接芯片的方式實現。比較常用的轉接芯片有RK628、LT6911系列等等,這篇文章我們就介紹一下這種方式的實現以及調試指南
(2)基本功能流程實現原理
1.系統功能框圖
系統框圖如下圖所示,RK628D作為類camera設備使用,基于V4L2框架實現相關驅動,HDMI信號源通過RK628的HDMIRX接口輸入,經過RK628的內部模塊處理將接收的圖像數據處理為MIPI-CSI信號作為數據輸出,同時圖像格式也統一轉換為YUV422格式輸出,經MIPI lane接入到主控的MIPI接口,由主控接收圖像并對圖像進行處理顯示,從而實現HDMI-IN的功能。
2.系統功能流程
2.1 APK工作流程
APK預覽工作流程如下圖所示:
2.2?熱拔插
熱拔插中斷處理流程如下圖所示
2.3 切換分辨率
切換分辨率流程如下圖所示:
(3)功能配置說明
1.驅動代碼與配置
1.1 驅動代碼
轉接芯片驅動代碼如下:
drivers/media/i2c/rk628/
drivers/media/i2c/lt6911uxe.c
drivers/media/i2c/lt6911uxc.c
drivers/media/i2c/tc35874x.c
1.2 config配置
kernel的config配置如下:
CONFIG_VIDEO_LT6911UXC=y
CONFIG_VIDEO_LT6911UXE=y
CONFIG_VIDEO_RK628_CSI=y
CONFIG_VIDEO_TC35874X=y
2.DTS配置
以下介紹調試的時候的dts配置。主要有設備配置,鏈路配置,鏈路配置中,由于rk3566/68平臺有兩種場景,因此,我們分別介紹兩種場景的配置。
2.1 設備配置
轉接芯片一般都是i2c設備,需要配置到i2c總線下,參考如下配置:
&i2c5 {status = "okay";rk628_csi: rk628_csi@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";status = "okay";power-domains = <&power RK3588_PD_VI>;pinctrl-names = "default";pinctrl-0 = <&rk628_pin>;interrupt-parent = <&gpio2>;interrupts = <RK_PC4 IRQ_TYPE_EDGE_RISING>;enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;continues-clk = <1>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "HDMI-MIPI";rockchip,camera-module-lens-name = "RK628-CSI";port {hdmiin_out0: endpoint {remote-endpoint = <&hdmi_mipi0_in>;data-lanes = <1 2 3 4>;};};};
};
-
interrupt-parent/ interrupts:連接RK628中斷的GPIO引腳;
-
enable-gpios:RK628供電控制GPIO引腳(若為常供電可不配置);
-
reset-gpios:RK628復位控制GPIO引腳
-
rockchip,camera-module相關的都是適配RK的camera框架平臺私有配置,與camera類似。
2.2 圖像鏈路配置
這里具體RK3399以及RK3568為例,RK3399代表的是RK舊的平臺,RK3568代表的是引入VICAP之后的平臺,在RK3568之后的芯片平臺也沒有基于安卓11的版本,都是基于安卓12以后得版本,我們后續在做詳細的介紹。
2.2.1 RK3399
RK339平臺只能使用ISP接收圖像,鏈路我們可以描述為:轉接芯片-->dphy_rx0 -->isp
其中dts配置可以參考如下配置。需要注意的是rk3399有兩個isp,配置對應的是哪一路即可。
&i2c4 {clock-frequency = <400000>;status = "okay";rk628_csi_v4l2: rk628_csi_v4l2@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";interrupt-parent = <&gpio2>;interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;//enable-gpios = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;//power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "RK628-CSI";rockchip,camera-module-lens-name = "NC";port {hdmiin_out0: endpoint {remote-endpoint = <&mipi_in>;data-lanes = <1 2 3 4>;};};};
};&mipi_dphy_rx0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <&hdmiin_out0>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;dphy_rx_out: endpoint@0 {reg = <0>;remote-endpoint = <&isp_mipi_in>;};};};
};&isp0 {status = "okay";port {#address-cells = <1>;#size-cells = <0>;isp_mipi_in: endpoint@0 {reg = <0>;remote-endpoint = <&dphy_rx_out>;};};
};&isp0_mmu {status = "okay";
};
2.2.2 RK3568
RK3568則有兩種情況,一是使用isp接收,二是使用vicap模塊接收圖像,我們分別進行介紹。
rk3568使用isp的場景,對應的圖像鏈路為:
對應的dts配置為:
&csi2_dphy_hw {status = "okay";
};&csi2_dphy0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <&hdmiin_out0>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;csidphy_out: endpoint@0 {reg = <0>;remote-endpoint = <&isp0_in>;};};};
};&i2c4 {clock-frequency = <400000>;status = "okay";rk628_csi_v4l2: rk628_csi_v4l2@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";interrupt-parent = <&gpio2>;interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;//enable-gpios = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;//power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "RK628-CSI";rockchip,camera-module-lens-name = "NC";port {hdmiin_out0: endpoint {remote-endpoint = <&mipi_in>;data-lanes = <1 2 3 4>;};};};
};&rkisp {status = "okay";
};&rkisp_mmu {status = "okay";
};&rkisp_vir0 {status = "okay";port {#address-cells = <1>;#size-cells = <0>;isp0_in: endpoint@0 {reg = <0>;remote-endpoint = <&csidphy_out>;};};
};
RK3568使用VICap的場景,圖像鏈路為:
對應的dts配置參考為:
&csi2_dphy_hw {status = "okay";
};&csi2_dphy0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;hdmi_to_mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <<6911uxc_out>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;csidphy_out: endpoint@1 {reg = <1>;remote-endpoint = <&mipi_csi2_input>;data-lanes = <1 2 3 4>;};};};
};&i2c3 {status = "okay";lt6911uxc: lt6911uxc@2b {status = "okay";reg = <0x2b>;compatible = "lontium,lt6911uxc";clocks = <&ext_cam_clk>;clock-names = "xvclk";interrupt-parent = <&gpio4>;interrupts = <16 IRQ_TYPE_LEVEL_LOW>;power-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;hpd-ctl-gpios = <&gpio3 27 GPIO_ACTIVE_LOW>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "LT6911UXC";rockchip,camera-module-lens-name = "NC";port {lt6911uxc_out: endpoint {remote-endpoint = <&hdmi_to_mipi_in>;data-lanes = <1 2 3 4>;};};};
};&mipi_csi2 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_csi2_input: endpoint@1 {reg = <1>;remote-endpoint = <&csidphy_out>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;mipi_csi2_output: endpoint@0 {reg = <0>;remote-endpoint = <&cif_mipi_in>;data-lanes = <1 2 3 4>;};};};
};&rkcif_mipi_lvds {status = "okay";port {cif_mipi_in: endpoint {remote-endpoint = <&mipi_csi2_output>;data-lanes = <1 2 3 4>;};};
};&rkcif_mmu {status = "okay";
};&rkcif {status = "okay";
};
3.camera xml注冊設備
camera3_profiles.xml文件對應SDK目錄下具體芯片平臺的文件:
hardware/rockchip/camera/etc/camera/camera3_profiles_rk3xxx.xml
在設備上的路徑為:
/vendor/etc/camera/camera3_profiles.xml
若是臨時調試,可以采用adb替換文件的形式,但需要注意文件路徑與文件名的正確性。
xml增加配置的時候可以參考其他已有的sensor,后續僅介紹關鍵的幾個修改點。
3.1 設備名稱與ID
xml中name參數與moduleid參數取決定著能否成功注冊安卓camera設備,若該兩項屬性配置異常,則會導致
-
name:需要與驅動名稱一致,有大小寫區別;
-
moduleId:需要與驅動dts中配置的index一致;
3.2 分辨率配置
scaler.availableStreamConfigurations/scaler.availableMinFrameDurations/ scaler.availableStallDurations:需要正確配置預預覽支持的分辨率以及幀率,此處的分辨率不能大于驅動實際輸出的分辨率大小,如下所示:
<scaler.availableStreamConfigurations value="BLOB,1920x1080,OUTPUT,BLOB,176x144,OUTPUT,YCbCr_420_888,1920x1080,OUTPUT,YCbCr_420_888,176x144,OUTPUT,IMPLEMENTATION_DEFINED,1920x1080,OUTPUT,IMPLEMENTATION_DEFINED,176x144,OUTPUT"/><scaler.availableMinFrameDurations value="BLOB,1920x1080,33333333,BLOB,176x144,33333333,YCbCr_420_888,1920x1080,33333333,YCbCr_420_888,176x144,33333333,IMPLEMENTATION_DEFINED,1920x1080,33333333,IMPLEMENTATION_DEFINED,176x144,33333333" /><scaler.availableStallDurations value="BLOB,1920x1080,33333333,
3.3 SOC模式
在<Sensor_info_RKISP1>中需要配置sensorType,一般SOC為YUVsensor,即不啟動3A,RAW為RAW sensor,啟動3A,HDMI-IN都是YUV的圖像,因此需要設置為SOC模式。
<sensorType value="SENSOR_TYPE_SOC"/> <!-- SENSOR_TYPE_SOC or SENSOR_TYPE_RAW -->
3.4 旋轉角配置
<sensor. Orientation value="0"/>
4.APK適配
4.1 獲取APK
APK源碼地址:
RKDocs/common/hdmi-in/apk/rkCamera2_based_on_CameraHal3_V1.3.tar.gz
4.2 APK 源碼適配
rkCamera2/jni/native.cpp
獲取連接狀態和分辨率的位置:
5.EDID配置
(4)調試方法
1.查看設備是否注冊camera
使用如下命令查看是否成功注冊cameraID
dumpsys media.camera
2.查看拓撲結構
HDMI2MIPI驅動框架類似camera,需要保證pipeline的完整才可以正常工作,使用media-ctl查看pipeline,同時也可以查看轉接芯片對應的subdev節點,以便于apk那邊適配修改。
media-ctl -d /dev/mediaX -p //X=0123...
3.v4l2抓取數據流
v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=3840,height=2160,pixelformat='NV12' --stream-mmap=4
4.v4l2抓圖
v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=3840,height=2160,pixelformat='NV12' --stream-mmap=3 --stream-skip=4 --stream-to=/data/3840x2160_nv12.yuv --stream-count=5 --stream-poll
5.不同芯片平臺接收能力
由于各個芯片平臺isp/vicap的性能不同,對圖像的最大接收能力也不同。可參考下表
芯片平臺 | 控制器 | 支持分辨率 |
RK3288/RK3326 | ISP | 1080P60 |
RK3399 | ISP | 4K30 超頻 |
RK3568/6 | ISP/VICAP | ISP:1080P60 VICAP:4K30 |
6.配置使用ISP CMA內存
部分平臺HDMI IN接收圖像數據時,根據實際系統負載,可能會存在帶寬不足導致丟幀或MIPI接收異常等問題。此時需要提高DDR頻率,若仍無改善,可給ISP預留使用CMA內存,以改善解決此問題。
- rockchip_defconfig 配置預留 CMA 內存 128MB
CONFIG_CMA=y
CONFIG_CMA_SIZE_MBYTES=128
- 在dts配置ISP關閉IOMMU,使用CMA內存
&rkisp_mmu {status = "disabled";
};
7.配置RK3399 ISP超頻
配置RK3399超頻625M,實現接收4K30圖像。
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
index 5ed8dac..e8f259d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
@@ -148,7 +148,7 @@<50000000>, <100000000>,<75000000>, <75000000>,<816000000>, <816000000>,
- <600000000>, <200000000>,
+ <625000000>, <200000000>,<800000000>, <150000000>,<75000000>, <37500000>,<300000000>, <100000000>,
diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c
index 4e548f0..5aa9e13 100644
--- a/drivers/media/platform/rockchip/isp1/dev.c
+++ b/drivers/media/platform/rockchip/isp1/dev.c
@@ -757,7 +757,7 @@ static const unsigned int rk3368_isp_clk_rate[] = {/* isp clock adjustment table (MHz) */static const unsigned int rk3399_isp_clk_rate[] = {
- 300, 400, 600
+ 300, 400, 625};static struct isp_irqs_data rk1808_isp_irqs[] = {
(5)總結
本文較長基本詳細介紹了安卓9/10/11等平臺hdmi-in功能的開發,可以看到hdmi-in與camera最大的不同在于增加了切換分辨率與熱拔插的功能,而目前在安卓11的版本上面,都是使用apk輪詢的方式實現的,而在安卓12之后的版本中,對這一方式有所優化,并且也增加了低延時送顯示的應用框架,不再完全依賴于camera框架,后續我們在做介紹。