视频数据流通常由外部设备组成 例如相机传感器、iic、spi、uart总线上的控制器、芯片内部IP模块 包括DMA视频缓冲和视频数据处理器。
芯片内部板是通过DT节点描述, 和其他的SOC类似,外部设备是以它们各自总线控制器节点下的子节点存在。例如iic
所有视频设备的数据接口是通过子节点 ”port“来描述,一个port的配置取决于参与到数据传输的其他设备通过‘endpoint字节点’描述。
device {
...
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
...
endpoint@0 { ... };
endpoint@1 { ... };
};
port@1 { ... };
};
};
如果一个port 配置到和同一总线的的多个远程设备工作,则必须为它们每一个提供一个”endpoint”子节点,如果在一个设备节点上存在多个port 或者在一个port 上有多个endpoint 或者port节点需要与一个选定的硬件接口联系,通常的方案是使用#address-cells #size-cells 和reg 属性 。
所有的port 可以分组到ports节点下,允许#address-cells、#size-cells 属性标识 port、endpoint 节点和一个设备可能含有的所有子节点。
两个endpoint 节点通过“remote-endpoint”句柄彼此联系。 设备的endpoint 子节点包含对于这个设备和其他设备交换数据所有需要的属性。
允许一个port下的多个endpoint处于激活状态。
示例
下面这个例子描述两个数据流 ov772x 和imx074 是分别具有并行和串行的相机传感器,两个传感器是在iic总线对应的iic控制器的节点下。ov772x传感器直接连接到ceu0视频主机接口 imx074是通过mipi csi-2 连接到ceu0,ceu0有一个DMA缓冲将捕捉数据写入到内存中,ceu0节点有一个’port’节点,可以指示在任何时候只有以下数据之一 ov772x -> ceu0 or imx074 -> csi2 -> ceu0
ceu0: ceu@0xfe910000 {
compatible = "renesas,sh-mobile-ceu";
reg = <0xfe910000 0xa0>;
interrupts = <0x880>;
mclk: master_clock {
compatible = "renesas,ceu-clock";
#clock-cells = <1>;
clock-frequency = <50000000>; /* Max clock frequency */
clock-output-names = "mclk";
};
port {
#address-cells = <1>;
#size-cells = <0>;
/* Parallel bus endpoint */
ceu0_1: endpoint@1 {
reg = <1>; /* Local endpoint # */
remote = <&ov772x_1_1>; /* Remote phandle */
bus-width = <8>; /* Used data lines */
data-shift = <2>; /* Lines 9:2 are used */
/* If hsync-active/vsync-active are missing,
embedded BT.656 sync is used */
hsync-active = <0>; /* Active low */
vsync-active = <0>; /* Active low */
data-active = <1>; /* Active high */
pclk-sample = <1>; /* Rising */
};
/* MIPI CSI-2 bus endpoint */
ceu0_0: endpoint@0 {
reg = <0>;
remote = <&csi2_2>;
};
};
};
i2c0: i2c@0xfff20000 {
...
ov772x_1: camera@0x21 {
compatible = "ovti,ov772x";
reg = <0x21>;
vddio-supply = <®ulator1>;
vddcore-supply = <®ulator2>;
clock-frequency = <20000000>;
clocks = <&mclk 0>;
clock-names = "xclk";
port {
/* With 1 endpoint per port no need for addresses. */
ov772x_1_1: endpoint {
bus-width = <8>;
remote-endpoint = <&ceu0_1>;
hsync-active = <1>;
vsync-active = <0>; /* Who came up with an
inverter here ?... */
data-active = <1>;
pclk-sample = <1>;
};
};
};
imx074: camera@0x1a {
compatible = "sony,imx074";
reg = <0x1a>;
vddio-supply = <®ulator1>;
vddcore-supply = <®ulator2>;
clock-frequency = <30000000>; /* Shared clock with ov772x_1 */
clocks = <&mclk 0>;
clock-names = "sysclk"; /* Assuming this is the
name in the datasheet */
port {
imx074_1: endpoint {
clock-lanes = <0>;
data-lanes = <1 2>;
remote-endpoint = <&csi2_1>;
};
};
};
};
csi2: csi2@0xffc90000 {
compatible = "renesas,sh-mobile-csi2";
reg = <0xffc90000 0x1000>;
interrupts = <0x17a0>;
#address-cells = <1>;
#size-cells = <0>;
port@1 {
compatible = "renesas,csi2c"; /* One of CSI2I and CSI2C. */
reg = <1>; /* CSI-2 PHY #1 of 2: PHY_S,
PHY_M has port address 0,
is unused. */
csi2_1: endpoint {
clock-lanes = <0>;
data-lanes = <2 1>;
remote-endpoint = <&imx074_1>;
};
};
port@2 {
reg = <2>; /* port 2: link to the CEU */
csi2_2: endpoint {
remote-endpoint = <&ceu0_0>;
};
};
};
分析 :
ceu0 的port 下有两个endpoint 节点 ceu0_1的remote ov772x_1_1 ceu0_0的remote csi2_2
i2c0总线下有两个设备 ov772x_1 和imx074 每个设备下都只有一个port 每个port下有一个endpoint ov772x_1 的endpoint 连接到 ceu0_1 imx074的endpoint 连接到 csi2_1
csi2因为是双向连接 所以有两个port 每个port下有一个endpoint 一路endpoint 连接到074_1 一路endpoint 连接到ceu0_0