RK 安卓10/11平台 HDMI-IN 调试
这篇文章我们介绍一下在安卓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框架,后续我们在做介绍。