[PATCH v4 1/2] arm64: dts: imx8mq-evk: Add OV5640 camera support via overlays
From: <hidden>
Date: 2026-06-19 10:03:15
Also in:
imx, linux-devicetree, lkml
Subsystem:
arm/freescale imx / mxc arm architecture, the rest · Maintainers:
Frank Li, Sascha Hauer, Linus Torvalds
From: Robby Cai <redacted> Add overlays for single and dual camera setups on CSI1 and CSI2, enabling the following media pipelines: - OV5640 (I2C2) -> MIPI CSI1 -> CSI1 bridge - OV5640 (I2C1) -> MIPI CSI2 -> CSI2 bridge On the i.MX8MQ EVK, both sensors share a common reset GPIO, while each sensor has an independent powerdown (PWDN) GPIO. Both sensors also share the same MCLK source (CLKO2), configured identically as required by the hardware design. Signed-off-by: Robby Cai <redacted> --- arch/arm64/boot/dts/freescale/Makefile | 7 ++ .../dts/freescale/imx8mq-evk-ov5640-csi1.dtso | 69 +++++++++++++++++++ .../dts/freescale/imx8mq-evk-ov5640-csi2.dtso | 65 +++++++++++++++++ arch/arm64/boot/dts/freescale/imx8mq-evk.dts | 50 ++++++++++++++ 4 files changed, 191 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 8ddaab127ab9..8507cbdb5556 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile@@ -501,6 +501,13 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-pcie1-ep-dtbs += imx8mq-evk.dtb imx-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-pcie1-ep.dtb +imx8mq-evk-ov5640-csi1-dtbs := imx8mq-evk.dtb imx8mq-evk-ov5640-csi1.dtbo +dtb-${CONFIG_ARCH_MXC} += imx8mq-evk-ov5640-csi1.dtb +imx8mq-evk-ov5640-csi2-dtbs := imx8mq-evk.dtb imx8mq-evk-ov5640-csi2.dtbo +dtb-${CONFIG_ARCH_MXC} += imx8mq-evk-ov5640-csi2.dtb +imx8mq-evk-ov5640-dual-dtbs := imx8mq-evk.dtb imx8mq-evk-ov5640-csi1.dtbo imx8mq-evk-ov5640-csi2.dtbo +dtb-${CONFIG_ARCH_MXC} += imx8mq-evk-ov5640-dual.dtb + dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-kontron-pitx-imx8m.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso
new file mode 100644
index 000000000000..1e9931802cdc
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi1.dtso@@ -0,0 +1,69 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mq-clock.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/media/video-interfaces.h> + +&csi1 { + status = "okay"; +}; + +&i2c2 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + camera@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_camera1_pwdn>; + clocks = <&clk IMX8MQ_CLK_CLKO2>; + clock-names = "xclk"; + assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>; + assigned-clock-rates = <20000000>; + powerdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + DOVDD-supply = <&sw4_reg>; + AVDD-supply = <®_2v8>; + DVDD-supply = <®_1v5>; + + port { + camera1_ep: endpoint { + remote-endpoint = <&mipi_csi1_in_ep>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + }; +}; + +&mipi_csi1 { + assigned-clock-rates = <266000000>, <200000000>, <66000000>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mipi_csi1_in_ep: endpoint { + remote-endpoint = <&camera1_ep>; + data-lanes = <1 2>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso
new file mode 100644
index 000000000000..fd247b3b5982
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk-ov5640-csi2.dtso@@ -0,0 +1,65 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mq-clock.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/media/video-interfaces.h> + +&csi2 { + status = "okay"; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + camera@3c { + compatible = "ovti,ov5640"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_camera2_pwdn>; + clocks = <&clk IMX8MQ_CLK_CLKO2>; + clock-names = "xclk"; + assigned-clocks = <&clk IMX8MQ_CLK_CLKO2>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_200M>; + assigned-clock-rates = <20000000>; + powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + DOVDD-supply = <&sw4_reg>; + AVDD-supply = <®_2v8>; + DVDD-supply = <®_1v5>; + + port { + camera2_ep: endpoint { + remote-endpoint = <&mipi_csi2_in_ep>; + clock-lanes = <0>; + data-lanes = <1 2>; + }; + }; + }; +}; + +&mipi_csi2 { + assigned-clock-rates = <266000000>, <200000000>, <66000000>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mipi_csi2_in_ep: endpoint { + remote-endpoint = <&camera2_ep>; + data-lanes = <1 2>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
index e7d87ea81b69..d8c139c9128d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts@@ -50,6 +50,20 @@ reg_usdhc2_vmmc: regulator-vsd-3v3 { enable-active-high; }; + reg_1v5: regulator-1v5 { + compatible = "regulator-fixed"; + regulator-name = "DVDD_1V5"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + }; + + reg_2v8: regulator-2v8 { + compatible = "regulator-fixed"; + regulator-name = "AVDD_2V8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + buck2_reg: regulator-buck2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_buck2>;
@@ -542,12 +556,34 @@ &wdog1 { }; &iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mclk>, <&pinctrl_camera_reset>; + pinctrl_buck2: vddarmgrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x19 >; }; + pinctrl_camera1_pwdn: camera1pwdngrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19 + >; + }; + + pinctrl_camera2_pwdn: camera2pwdngrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5 0x19 + >; + }; + + /* Shared reset line for cameras on CSI1 and CSI2. */ + pinctrl_camera_reset: cameraresetgrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19 + >; + }; + pinctrl_fec1: fec1grp { fsl,pins = < MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3
@@ -575,12 +611,26 @@ MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f >; }; + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f + MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f + >; + }; + pinctrl_ir: irgrp { fsl,pins = < MX8MQ_IOMUXC_GPIO1_IO12_GPIO1_IO12 0x4f >; }; + /* Shared MCLK for cameras on CSI1 and CSI2. */ + pinctrl_mclk: mclkgrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2 0x59 + >; + }; + pinctrl_mipi_dsi: mipidsigrp { fsl,pins = < MX8MQ_IOMUXC_ECSPI1_SCLK_GPIO5_IO6 0x16
--
2.50.1