diff --git a/Documentation/devicetree/bindings/gpio/novo,nca9539-gpio.yaml b/Documentation/devicetree/bindings/gpio/novo,nca9539-gpio.yaml new file mode 100644 index 000000000000..316c5df543f0 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/novo,nca9539-gpio.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/novo,nca9539-gpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novosense I2C GPIO controller + +maintainers: + - Cody Xie + +description: | + This controller is A GPIO expander with I2C interface and one interrupt pin. + +properties: + compatible: + const: novo,nca9539-gpio + + reg: + items: + - description: the I2C address containing the GPIO controller registers. + + gpio-controller: true + + '#gpio-cells': + const: 2 + + ngpios: + minimum: 0 + maximum: 32 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + interrupts: + maxItems: 1 + + vdd-supply: + - description: the regulator for the VDD supplier. + +required: + - compatible + - reg + - "#gpio-cells" + - gpio-controller + - vdd-supply + +additionalProperties: false + +dependencies: + interrupt-controller: [ interrupts ] + +examples: + - | + #include + #include + / { + nca9539_vdd: nca9539-vdd { + compatible = "regulator-fixed"; + regulator-name = "nca9539_vdd"; + enable-active-high; + regulator-boot-on; + regulator-always-on; + }; + }; + + nca9539_gpio: gpio@74 { + compatible = "novo,nca9539-gpio"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + vdd-supply = <&nca9539_vdd>; + }; + + +... diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4bb89856aaab..754e39bc0996 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1145,6 +1145,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rv1106g-evb1-v11-facial-gate.dtb \ rv1106g-evb1-v10-spi-nand.dtb \ rv1106g-evb1-v10-spi-nor.dtb \ + rv1106g-evb1-v11-nofastae-spi-nand.dtb \ rv1106g-evb2-v10.dtb \ rv1106g-evb2-v10-dual-camera.dtb \ rv1106g-evb2-v11-emmc.dtb \ diff --git a/arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts b/arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts new file mode 100644 index 000000000000..f653f8e78521 --- /dev/null +++ b/arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rv1106g-evb1-v11.dts" +#include "rv1106-tb-nofastae.dtsi" + +/ { + model = "Rockchip RV1106G EVB1 V11 Board"; + compatible = "rockchip,rv1106g-evb1-v11", "rockchip,rv1106"; + chosen { + bootargs = "loglevel=0 rootfstype=erofs rootflags=dax console=ttyFIQ0 root=/dev/rd0 snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=0 driver_async_probe=dwmmc_rockchip"; + }; +}; + +&fiq_debugger { + rockchip,baudrate = <1500000>; +}; + +&ramdisk_r { + reg = <0x800000 (15 * 0x00100000)>; +}; + +&ramdisk_c { + reg = <0x1700000 (10 * 0x00100000)>; +}; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index e94a5bb3e7fc..42172b5db49a 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -145,6 +145,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-k108.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-rkg11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-channel-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-camera.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux.dtb @@ -211,6 +213,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-dsi-dsc-MV2100UZ1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-ipc-6x-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-amp.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-linux-ipc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-lt6911uxe.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb2-lp4-v10.dtb @@ -248,6 +251,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v20.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v21.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-evb-v22.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-vehicle-s66-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb1-lp4x-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-evb1-lp4x-v10-linux.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index add361c0557f..43b2a6ffd942 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -652,7 +652,7 @@ status = "disabled"; }; - reboot-mode { + reboot_mode: reboot-mode { compatible = "syscon-reboot-mode"; offset = <0x200>; mode-bootloader = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi index 36c7febdf571..25f820c68c77 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi @@ -22,18 +22,6 @@ status = "okay"; }; - rpmsg: rpmsg@7c00000 { - compatible = "rockchip,rk3562-rpmsg"; - mbox-names = "rpmsg-rx", "rpmsg-tx"; - mboxes = <&mailbox 0 &mailbox 3>; - rockchip,vdev-nums = <1>; - rockchip,link-id = <0x04>; - reg = <0x0 0x7c00000 0x0 0x20000>; - memory-region = <&rpmsg_dma_reserved>; - - status = "okay"; - }; - reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -63,6 +51,18 @@ }; }; + + rpmsg: rpmsg@7c00000 { + compatible = "rockchip,rpmsg"; + mbox-names = "rpmsg-rx", "rpmsg-tx"; + mboxes = <&mailbox 0 &mailbox 3>; + rockchip,vdev-nums = <1>; + rockchip,link-id = <0x04>; + reg = <0x0 0x7c00000 0x0 0x20000>; + memory-region = <&rpmsg_dma_reserved>; + + status = "okay"; + }; }; &mailbox { diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index 4d9b95f2357c..0f2c36377e52 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562.dtsi @@ -2266,6 +2266,7 @@ &i2s0m0_sdo2 &i2s0m0_sdo3>; #sound-dai-cells = <0>; + sound-name-prefix = "SAI0"; status = "disabled"; }; @@ -2293,6 +2294,7 @@ &i2s1m0_sdo2 &i2s1m0_sdo3>; #sound-dai-cells = <0>; + sound-name-prefix = "SAI1"; status = "disabled"; }; @@ -2314,6 +2316,7 @@ &i2s2m0_sdi &i2s2m0_sdo>; #sound-dai-cells = <0>; + sound-name-prefix = "SAI2"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts new file mode 100644 index 000000000000..04043c5d582a --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include +#include +#include + +#include "rk3567-evb2-lp4x-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3567 EVB2 LP4X V10 Board"; + compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567"; + + panel { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hback-porch = <96>; + hfront-porch = <120>; + vback-porch = <16>; + vfront-porch = <64>; + hsync-len = <64>; + vsync-len = <16>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dual-lvds-odd-pixels; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + port@1 { + reg = <1>; + dual-lvds-even-pixels; + panel_in_lvds1: endpoint { + remote-endpoint = <&lvds1_out_panel>; + }; + }; + }; + }; +}; + +&backlight1 { + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lvds { + status = "okay"; + dual-channel; + + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds1 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + lvds1_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds1>; + }; + }; + }; +}; + +&lvds_in_vp1 { + status = "okay"; +}; + +&lvds1_in_vp1 { + status = "disabled"; +}; + +&lvds1_in_vp2 { + status = "okay"; +}; + +/* enable hdmi */ +&hdmi_in_vp1 { + status = "okay"; +}; + +/* enable video phy */ +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; + +/* disable other encoder output */ +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts new file mode 100644 index 000000000000..d50ccd30a08c --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include +#include +#include + +#include "rk3567-evb2-lp4x-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3567 EVB2 LP4X V10 Board"; + compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567"; + + panel { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <134000000>; + hactive = <1600>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <2>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + /** + * Panel <----> LVDS0 + * Panel <----> LVDS1 + */ + port@0 { + reg = <0>; + dual-lvds-left-pixels; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + port@1 { + reg = <1>; + dual-lvds-right-pixels; + panel_in_lvds1: endpoint { + remote-endpoint = <&lvds1_out_panel>; + }; + }; + }; + }; +}; + +&backlight1 { + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lvds { + status = "okay"; + dual-channel; + + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds1 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + lvds1_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds1>; + }; + }; + }; +}; + +&lvds_in_vp1 { + status = "okay"; +}; + +&lvds1_in_vp1 { + status = "disabled"; +}; + +&lvds1_in_vp2 { + status = "okay"; +}; + +/* enable hdmi */ +&hdmi_in_vp1 { + status = "okay"; +}; + +/* enable video phy */ +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; + +/* disable other encoder output */ +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi index 2e9b96d7f9b1..8de181dd05cf 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi @@ -24,18 +24,6 @@ }; }; - rpmsg: rpmsg@7c00000 { - compatible = "rockchip,rk3568-rpmsg"; - mbox-names = "rpmsg-rx", "rpmsg-tx"; - mboxes = <&mailbox 0 &mailbox 3>; - rockchip,vdev-nums = <1>; - rockchip,link-id = <0x03>; - reg = <0x0 0x7c00000 0x0 0x20000>; - memory-region = <&rpmsg_dma_reserved>; - - status = "okay"; - }; - reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -64,6 +52,18 @@ no-map; }; }; + + rpmsg: rpmsg@7c00000 { + compatible = "rockchip,rpmsg"; + mbox-names = "rpmsg-rx", "rpmsg-tx"; + mboxes = <&mailbox 0 &mailbox 3>; + rockchip,vdev-nums = <1>; + rockchip,link-id = <0x03>; + reg = <0x0 0x7c00000 0x0 0x20000>; + memory-region = <&rpmsg_dma_reserved>; + + status = "okay"; + }; }; &mailbox { diff --git a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi index 8ee5ed10945b..1d5e50466286 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi @@ -3,12 +3,15 @@ * Copyright (c) 2023 Rockchip Electronics Co., Ltd. */ +#include + / { rockchip_amp: rockchip-amp { - compatible = "rockchip,mcu-amp"; + compatible = "rockchip,amp"; clocks = <&cru HCLK_PMU_CM0_ROOT>, <&cru FCLK_PMU_CM0_CORE>, <&cru CLK_PMU_CM0_RTC>, <&cru PCLK_PMUCM0_INTMUX>, <&cru SCLK_UART5>, <&cru PCLK_UART5>, + <&cru PCLK_BUSTIMER0>, <&cru CLK_BUSTIMER4>, <&cru CLK_BUSTIMER5>, <&cru PCLK_BUSTIMER1>, <&cru CLK_BUSTIMER10>, <&cru CLK_BUSTIMER11>; pinctrl-names = "default"; @@ -22,10 +25,44 @@ #size-cells = <2>; ranges; + /* remote amp core address */ + amp_shmem_reserved: amp-shmem@7800000 { + reg = <0x0 0x7800000 0x0 0x400000>; + no-map; + }; + + rpmsg_reserved: rpmsg@7c00000 { + reg = <0x0 0x07c00000 0x0 0x400000>; + no-map; + }; + + rpmsg_dma_reserved: rpmsg-dma@8000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x08000000 0x0 0x100000>; + no-map; + }; + /* mcu address */ mcu_reserved: mcu@8200000 { reg = <0x0 0x8200000 0x0 0x100000>; no-map; }; }; + + rpmsg: rpmsg@7c00000 { + compatible = "rockchip,rpmsg"; + mbox-names = "rpmsg-rx", "rpmsg-tx"; + mboxes = <&mailbox0 0 &mailbox0 3>; + rockchip,vdev-nums = <1>; + rockchip,link-id = <0x03>; + reg = <0x0 0x7c00000 0x0 0x20000>; + memory-region = <&rpmsg_dma_reserved>; + + status = "okay"; + }; +}; + +&mailbox0 { + rockchip,txpoll-period-ms = <1>; + status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-linux-amp.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-linux-amp.dts new file mode 100644 index 000000000000..23ec15727ec0 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-linux-amp.dts @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; + +#include "rk3588-evb1-lp4.dtsi" +#include "rk3588-evb1-imx415.dtsi" +#include "rk3588-linux.dtsi" +#include "rk3588-amp.dtsi" + +/ { + model = "Rockchip RK3588 EVB1 LP4 V10 Board"; + compatible = "rockchip,rk3588-evb1-lp4-v10", "rockchip,rk3588"; + + cpus { + cpu-map { + cluster0 { + /delete-node/ core3; + }; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x02000000 0x0 0x06400000>, + <0x0 0x09400000 0x0 0xe6c00000>, + <0x1 0x00000000 0x1 0x00000000>, + <0x2 0xf0000000 0x0 0x10000000>; + }; +}; + +&arm_pmu { + interrupt-affinity = <&cpu_l0>, <&cpu_l1>, <&cpu_l2>, + <&cpu_b0>, <&cpu_b1>, <&cpu_b2>, <&cpu_b3>; +}; + +/delete-node/ &cpu_l3; + +&route_hdmi0 { + status = "okay"; + connect = <&vp0_out_hdmi0>; + /delete-property/ force-output; + /delete-node/ force_timing; +}; + +&route_hdmi1 { + status = "okay"; + connect = <&vp1_out_hdmi1>; + /delete-property/ force-output; + /delete-node/ force_timing; +}; + +&vcc_1v8_s0 { + /delete-property/ regulator-state-mem; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; +}; + +&vcc_3v3_s0 { + /delete-property/ regulator-state-mem; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; +}; + diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi new file mode 100644 index 000000000000..6821fa84829d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi @@ -0,0 +1,696 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96712_dcphy0_osc: max96712-dcphy0-oscillator { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96712-dcphy0-osc"; + }; +}; + +&mipi_dcphy0 { + status = "okay"; +}; + +&csi2_dcphy0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_dcphy0_in_max96712: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96712_dcphy0_out>; + data-lanes = <1 2>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidcphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi0_csi2_input>; + }; + }; + }; +}; + +&i2c8 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8m2_xfer>; + + max96712_dcphy0: max96712@29 { + compatible = "maxim4c,max96712"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96712_dcphy0_osc 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96712_dcphy0_pwdn>, <&max96712_dcphy0_errb>, <&max96712_dcphy0_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96712"; + rockchip,camera-module-lens-name = "max96712"; + + port { + max96712_dcphy0_out: endpoint { + remote-endpoint = <&mipi_dcphy0_in_max96712>; + data-lanes = <1 2>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1280>; + sensor-height = <800>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <12>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy0_link0_in: endpoint { + remote-endpoint = <&max96712_dcphy0_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + 0B 06 ef 00 00 // HIM on + 0B 07 84 00 00 // Enable HVEN and DBL + 0B 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy0_link1_in: endpoint { + remote-endpoint = <&max96712_dcphy0_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + 0C 06 ef 00 00 // HIM on + 0C 07 84 00 00 // Enable HVEN and DBL + 0C 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link C: link-id = 2 + gmsl-link-config-2 { + status = "okay"; + link-id = <2>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy0_link2_in: endpoint { + remote-endpoint = <&max96712_dcphy0_remote2_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 16 D1 03 00 00 // VGAHiGain + 16 45 00 00 00 // Disable SSC + 0D 06 ef 00 00 // HIM on + 0D 07 84 00 00 // Enable HVEN and DBL + 0D 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link D: link-id = 3 + gmsl-link-config-3 { + status = "okay"; + link-id = <3>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy0_link3_in: endpoint { + remote-endpoint = <&max96712_dcphy0_remote3_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 17 D1 03 00 00 // VGAHiGain + 17 45 00 00 00 // Disable SSC + 0E 06 ef 00 00 // HIM on + 0E 07 84 00 00 // Enable HVEN and DBL + 0E 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 0 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 0 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + ]; + }; + }; + + // Video Pipe 2 + video-pipe-config-2 { + status = "okay"; + pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <2>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 2 to Controller 0 + 09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 AD 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit + 09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 90 80 00 00 // DST1 VC = 2, DT = Frame Start + 09 91 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 92 81 00 00 // DST2 VC = 2, DT = Frame End + ]; + }; + }; + + // Video Pipe 3 + video-pipe-config-3 { + status = "okay"; + pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <3>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 3 to Controller 0 + 09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 ED 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit + 09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start + 09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <1>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <0>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x00>; + data-lane-num = <2>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max96715"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96712_dcphy0_remote0_out: endpoint { + remote-endpoint = <&max96712_dcphy0_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max96715"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96712_dcphy0_remote1_out: endpoint { + remote-endpoint = <&max96712_dcphy0_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-2 { + compatible = "maxim4c,link2,max96715"; + status = "okay"; + + remote-id = <2>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x43>; // 0: disable remap + + port { + max96712_dcphy0_remote2_out: endpoint { + remote-endpoint = <&max96712_dcphy0_link2_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-3 { + compatible = "maxim4c,link3,max96715"; + status = "okay"; + + remote-id = <3>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x44>; // 0: disable remap + + port { + max96712_dcphy0_remote3_out: endpoint { + remote-endpoint = <&max96712_dcphy0_link3_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi0_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi0_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidcphy0_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi0_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi0_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi0_in: endpoint { + remote-endpoint = <&mipi0_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96712-dcphy0 { + max96712_dcphy0_pwdn: max96712-dcphy0-pwdn { + rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dcphy0_errb: max96712-dcphy0-errb { + rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dcphy0_lock: max96712-dcphy0-lock { + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi new file mode 100644 index 000000000000..2b0a04eff63f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi @@ -0,0 +1,466 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96712_dcphy1_osc: max96712-dcphy1-oscillator { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96712-dcphy1-osc"; + }; +}; + +&mipi_dcphy1 { + status = "okay"; +}; + +&csi2_dcphy1 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_dcphy1_in_max96712: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96712_dcphy1_out>; + data-lanes = <1 2>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidcphy1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi1_csi2_input>; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m4_xfer>; + + max96712_dcphy1: max96712@29 { + compatible = "maxim4c,max96712"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96712_dcphy1_osc 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96712_dcphy1_pwdn>, <&max96712_dcphy1_errb>, <&max96712_dcphy1_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96712"; + rockchip,camera-module-lens-name = "max96712"; + + port { + max96712_dcphy1_out: endpoint { + remote-endpoint = <&mipi_dcphy1_in_max96712>; + data-lanes = <1 2>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1600>; + sensor-height = <1300>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy1_link0_in: endpoint { + remote-endpoint = <&max96712_dcphy1_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dcphy1_link1_in: endpoint { + remote-endpoint = <&max96712_dcphy1_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 0 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + // pipe Cross + 01 D9 59 00 00 // pipe 0: Inverts Cross VS + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 0 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 00 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 0; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + // pipe Cross + 01 F9 59 00 00 // pipe 1: Inverts Cross VS + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <1>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <0>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x00>; + data-lane-num = <2>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max9295"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96712_dcphy1_remote0_out: endpoint { + remote-endpoint = <&max96712_dcphy1_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max9295"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96712_dcphy1_remote1_out: endpoint { + remote-endpoint = <&max96712_dcphy1_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi1_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi1_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidcphy1_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi1_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi1_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds1 { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi1_in: endpoint { + remote-endpoint = <&mipi1_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96712-dcphy1 { + max96712_dcphy1_pwdn: max96712-dcphy1-pwdn { + rockchip,pins = <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dcphy1_errb: max96712-dcphy1-errb { + rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dcphy1_lock: max96712-dcphy1-lock { + rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi new file mode 100644 index 000000000000..b68f8f73607a --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi @@ -0,0 +1,708 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96712_dphy0_osc0: max96712-dphy0-oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96712-dphy0-osc0"; + }; +}; + +&csi2_dphy0_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_dphy0_in_max96712: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96712_dphy0_out>; + data-lanes = <1 2 3 4>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi2_csi2_input>; + }; + }; + }; +}; + +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7m3_xfer>; + + max96712_dphy0: max96712@29 { + compatible = "maxim4c,max96712"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96712_dphy0_osc0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96712_dphy0_pwdn>, <&max96712_dphy0_errb>, <&max96712_dphy0_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96712"; + rockchip,camera-module-lens-name = "max96712"; + + port { + max96712_dphy0_out: endpoint { + remote-endpoint = <&mipi_dphy0_in_max96712>; + data-lanes = <1 2 3 4>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1280>; + sensor-height = <800>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link0_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + 0B 06 ef 00 00 // HIM on + 0B 07 84 00 00 // Enable HVEN and DBL + 0B 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link1_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + 0C 06 ef 00 00 // HIM on + 0C 07 84 00 00 // Enable HVEN and DBL + 0C 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link C: link-id = 2 + gmsl-link-config-2 { + status = "okay"; + link-id = <2>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link2_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote2_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 16 D1 03 00 00 // VGAHiGain + 16 45 00 00 00 // Disable SSC + 0D 06 ef 00 00 // HIM on + 0D 07 84 00 00 // Enable HVEN and DBL + 0D 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link D: link-id = 3 + gmsl-link-config-3 { + status = "okay"; + link-id = <3>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link3_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote3_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 17 D1 03 00 00 // VGAHiGain + 17 45 00 00 00 // Disable SSC + 0E 06 ef 00 00 // HIM on + 0E 07 84 00 00 // Enable HVEN and DBL + 0E 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + ]; + }; + }; + + // Video Pipe 2 + video-pipe-config-2 { + status = "okay"; + pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <2>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 2 to Controller 1 + 09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit + 09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 90 80 00 00 // DST1 VC = 2, DT = Frame Start + 09 91 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 92 81 00 00 // DST2 VC = 2, DT = Frame End + ]; + }; + }; + + // Video Pipe 3 + video-pipe-config-3 { + status = "okay"; + pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <3>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 3 to Controller 1 + 09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit + 09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start + 09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <1>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max96715"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96712_dphy0_remote0_out: endpoint { + remote-endpoint = <&max96712_dphy0_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max96715"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96712_dphy0_remote1_out: endpoint { + remote-endpoint = <&max96712_dphy0_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-2 { + compatible = "maxim4c,link2,max96715"; + status = "okay"; + + remote-id = <2>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x43>; // 0: disable remap + + port { + max96712_dphy0_remote2_out: endpoint { + remote-endpoint = <&max96712_dphy0_link2_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-3 { + compatible = "maxim4c,link3,max96715"; + status = "okay"; + + remote-id = <3>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x44>; // 0: disable remap + + port { + max96712_dphy0_remote3_out: endpoint { + remote-endpoint = <&max96712_dphy0_link3_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi2_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi2_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidphy0_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi2_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi2_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds2 { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi2_in: endpoint { + remote-endpoint = <&mipi2_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96712-dphy0 { + max96712_dphy0_pwdn: max96712-dphy0-pwdn { + rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy0_errb: max96712-dphy0-errb { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy0_lock: max96712-dphy0-lock { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi new file mode 100644 index 000000000000..27ab0492cdfc --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96712_dphy3_osc0: max96712-dphy3-oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96712-dphy3-osc0"; + }; +}; + +&csi2_dphy1_hw { + status = "okay"; +}; + +&csi2_dphy3 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_dphy3_in_max96712: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96712_dphy3_out>; + data-lanes = <1 2 3 4>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidphy3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi4_csi2_input>; + }; + }; + }; +}; + +&i2c6 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m3_xfer>; + + max96712_dphy3: max96712@29 { + compatible = "maxim4c,max96712"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96712_dphy3_osc0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96712_dphy3_pwdn>, <&max96712_dphy3_errb>, <&max96712_dphy3_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96712"; + rockchip,camera-module-lens-name = "max96712"; + + port { + max96712_dphy3_out: endpoint { + remote-endpoint = <&mipi_dphy3_in_max96712>; + data-lanes = <1 2 3 4>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1920>; + sensor-height = <1440>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <1>; + link-tx-rate = <0>; + + port { + max96712_dphy3_link0_in: endpoint { + remote-endpoint = <&max96712_dphy3_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <1>; + link-tx-rate = <0>; + + port { + max96712_dphy3_link1_in: endpoint { + remote-endpoint = <&max96712_dphy3_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link C: link-id = 2 + gmsl-link-config-2 { + status = "okay"; + link-id = <2>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <1>; + link-tx-rate = <0>; + + port { + max96712_dphy3_link2_in: endpoint { + remote-endpoint = <&max96712_dphy3_remote2_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 16 D1 03 00 00 // VGAHiGain + 16 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link D: link-id = 3 + gmsl-link-config-3 { + status = "okay"; + link-id = <3>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <1>; + link-tx-rate = <0>; + + port { + max96712_dphy3_link3_in: endpoint { + remote-endpoint = <&max96712_dphy3_remote3_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 17 D1 03 00 00 // VGAHiGain + 17 45 00 00 00 // Disable SSC + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + ]; + }; + }; + + // Video Pipe 2 + video-pipe-config-2 { + status = "okay"; + pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <2>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 2 to Controller 1 + 09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit + 09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 90 80 00 00 // DST1 VC = 2, DT = Frame Start + 09 91 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 92 81 00 00 // DST2 VC = 2, DT = Frame End + ]; + }; + }; + + // Video Pipe 3 + video-pipe-config-3 { + status = "okay"; + pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <2>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <3>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 3 to Controller 1 + 09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit + 09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start + 09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <1>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max96717"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + // Camera i2c 7bit address remap + cam-i2c-addr-def = <0x30>; + cam-i2c-addr-map = <0x31>; // 0: disable remap + + port { + max96712_dphy3_remote0_out: endpoint { + remote-endpoint = <&max96712_dphy3_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 03 02 10 00 00 + 14 17 00 00 00 + 14 32 7f 00 00 + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max96717"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + // Camera i2c 7bit address remap + cam-i2c-addr-def = <0x30>; + cam-i2c-addr-map = <0x32>; // 0: disable remap + + port { + max96712_dphy3_remote1_out: endpoint { + remote-endpoint = <&max96712_dphy3_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 03 02 10 00 00 + 14 17 00 00 00 + 14 32 7f 00 00 + ]; + }; + }; + + serdes-remote-device-2 { + compatible = "maxim4c,link2,max96717"; + status = "okay"; + + remote-id = <2>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x43>; // 0: disable remap + + // Camera i2c 7bit address remap + cam-i2c-addr-def = <0x30>; + cam-i2c-addr-map = <0x33>; // 0: disable remap + + port { + max96712_dphy3_remote2_out: endpoint { + remote-endpoint = <&max96712_dphy3_link2_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 03 02 10 00 00 + 14 17 00 00 00 + 14 32 7f 00 00 + ]; + }; + }; + + serdes-remote-device-3 { + compatible = "maxim4c,link3,max96717"; + status = "okay"; + + remote-id = <3>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x44>; // 0: disable remap + + // Camera i2c 7bit address remap + cam-i2c-addr-def = <0x30>; + cam-i2c-addr-map = <0x34>; // 0: disable remap + + port { + max96712_dphy3_remote3_out: endpoint { + remote-endpoint = <&max96712_dphy3_link3_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 03 02 10 00 00 + 14 17 00 00 00 + 14 32 7f 00 00 + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi4_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi4_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidphy3_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi4_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi4_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds4 { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi4_in: endpoint { + remote-endpoint = <&mipi4_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96712-dphy3 { + max96712_dphy3_pwdn: max96712-dphy3-pwdn { + rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy3_errb: max96712-dphy3-errb { + rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy3_lock: max96712-dphy3-lock { + rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi new file mode 100644 index 000000000000..45447510b7c1 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi @@ -0,0 +1,708 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96722_dphy0_osc0: max96722-dphy0-oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96722-dphy0-osc0"; + }; +}; + +&csi2_dphy0_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_dphy0_in_max96722: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96722_dphy0_out>; + data-lanes = <1 2 3 4>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi2_csi2_input>; + }; + }; + }; +}; + +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7m3_xfer>; + + max96722_dphy0: max96722@29 { + compatible = "maxim4c,max96722"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96722_dphy0_osc0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96722_dphy0_pwdn>, <&max96722_dphy0_errb>, <&max96722_dphy0_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96722"; + rockchip,camera-module-lens-name = "max96722"; + + port { + max96722_dphy0_out: endpoint { + remote-endpoint = <&mipi_dphy0_in_max96722>; + data-lanes = <1 2 3 4>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1280>; + sensor-height = <800>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy0_link0_in: endpoint { + remote-endpoint = <&max96722_dphy0_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + 0B 06 ef 00 00 // HIM on + 0B 07 84 00 00 // Enable HVEN and DBL + 0B 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy0_link1_in: endpoint { + remote-endpoint = <&max96722_dphy0_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + 0C 06 ef 00 00 // HIM on + 0C 07 84 00 00 // Enable HVEN and DBL + 0C 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link C: link-id = 2 + gmsl-link-config-2 { + status = "okay"; + link-id = <2>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy0_link2_in: endpoint { + remote-endpoint = <&max96722_dphy0_remote2_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 16 D1 03 00 00 // VGAHiGain + 16 45 00 00 00 // Disable SSC + 0D 06 ef 00 00 // HIM on + 0D 07 84 00 00 // Enable HVEN and DBL + 0D 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link D: link-id = 3 + gmsl-link-config-3 { + status = "okay"; + link-id = <3>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy0_link3_in: endpoint { + remote-endpoint = <&max96722_dphy0_remote3_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 17 D1 03 00 00 // VGAHiGain + 17 45 00 00 00 // Disable SSC + 0E 06 ef 00 00 // HIM on + 0E 07 84 00 00 // Enable HVEN and DBL + 0E 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + ]; + }; + }; + + // Video Pipe 2 + video-pipe-config-2 { + status = "okay"; + pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <2>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 2 to Controller 1 + 09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit + 09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 90 80 00 00 // DST1 VC = 2, DT = Frame Start + 09 91 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 92 81 00 00 // DST2 VC = 2, DT = Frame End + ]; + }; + }; + + // Video Pipe 3 + video-pipe-config-3 { + status = "okay"; + pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <3>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 3 to Controller 1 + 09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit + 09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start + 09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <1>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max96715"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96722_dphy0_remote0_out: endpoint { + remote-endpoint = <&max96722_dphy0_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max96715"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96722_dphy0_remote1_out: endpoint { + remote-endpoint = <&max96722_dphy0_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-2 { + compatible = "maxim4c,link2,max96715"; + status = "okay"; + + remote-id = <2>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x43>; // 0: disable remap + + port { + max96722_dphy0_remote2_out: endpoint { + remote-endpoint = <&max96722_dphy0_link2_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-3 { + compatible = "maxim4c,link3,max96715"; + status = "okay"; + + remote-id = <3>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x44>; // 0: disable remap + + port { + max96722_dphy0_remote3_out: endpoint { + remote-endpoint = <&max96722_dphy0_link3_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi2_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi2_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidphy0_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi2_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi2_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds2 { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi2_in: endpoint { + remote-endpoint = <&mipi2_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96722-dphy0 { + max96722_dphy0_pwdn: max96722-dphy0-pwdn { + rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96722_dphy0_errb: max96722-dphy0-errb { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96722_dphy0_lock: max96722-dphy0-lock { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi new file mode 100644 index 000000000000..ad176da3978d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi @@ -0,0 +1,478 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ +#include + +/ { + max96722_dphy3_osc0: max96722-dphy3-oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <1>; + clock-frequency = <25000000>; + clock-output-names = "max96722-dphy3-osc0"; + }; +}; + +&csi2_dphy1_hw { + status = "okay"; +}; + +&csi2_dphy3 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_dphy3_in_max96722: endpoint@1 { + reg = <1>; + remote-endpoint = <&max96722_dphy3_out>; + data-lanes = <1 2 3 4>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + csidphy3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi4_csi2_input>; + }; + }; + }; +}; + +&i2c6 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m3_xfer>; + + max96722_dphy3: max96722@29 { + compatible = "maxim4c,max96722"; + status = "okay"; + reg = <0x29>; + clock-names = "xvclk"; + clocks = <&max96722_dphy3_osc0 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max96722_dphy3_pwdn>, <&max96722_dphy3_errb>, <&max96722_dphy3_lock>; + power-domains = <&power RK3588_PD_VI>; + rockchip,grf = <&sys_grf>; + pwdn-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + pocen-gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_HIGH>; + lock-gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_HIGH>; + + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "max96722"; + rockchip,camera-module-lens-name = "max96722"; + + port { + max96722_dphy3_out: endpoint { + remote-endpoint = <&mipi_dphy3_in_max96722>; + data-lanes = <1 2 3 4>; + }; + }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1600>; + sensor-height = <1300>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy3_link0_in: endpoint { + remote-endpoint = <&max96722_dphy3_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy3_link1_in: endpoint { + remote-endpoint = <&max96722_dphy3_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + // pipe Cross + 01 D9 59 00 00 // pipe 0: Inverts Cross VS + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + // pipe Cross + 01 F9 59 00 00 // pipe 1: Inverts Cross VS + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <1>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max9295"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96722_dphy3_remote0_out: endpoint { + remote-endpoint = <&max96722_dphy3_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max9295"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96722_dphy3_remote1_out: endpoint { + remote-endpoint = <&max96722_dphy3_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + /* serdes remote device end */ + }; +}; + +&mipi4_csi2 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi4_csi2_input: endpoint@1 { + reg = <1>; + remote-endpoint = <&csidphy3_out>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + mipi4_csi2_output: endpoint@0 { + reg = <0>; + remote-endpoint = <&cif_mipi4_in>; + }; + }; + }; +}; + +&rkcif_mipi_lvds4 { + status = "okay"; + /* parameters for do cif reset detecting: + * index0: monitor mode, + 0 for idle, + 1 for continue, + 2 for trigger, + 3 for hotplug (for nextchip) + * index1: the frame id to start timer, + min is 2 + * index2: frame num of monitoring cycle + * index3: err time for keep monitoring + after finding out err (ms) + * index4: csi2 err reference val for resetting + */ + rockchip,cif-monitor = <3 2 1 1000 5>; + + port { + cif_mipi4_in: endpoint { + remote-endpoint = <&mipi4_csi2_output>; + }; + }; +}; + +&rkcif { + status = "okay"; + rockchip,android-usb-camerahal-enable; +}; + +&rkcif_mmu { + status = "okay"; +}; + +&pinctrl { + max96722-dphy3 { + max96722_dphy3_pwdn: max96722-dphy3-pwdn { + rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96722_dphy3_errb: max96722-dphy3-errb { + rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96722_dphy3_lock: max96722-dphy3-lock { + rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts index b80c003e7c64..be6ede05dc5f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts @@ -7,8 +7,8 @@ /dts-v1/; #include "rk3588-vehicle-evb-v21.dtsi" -#include "rk3588-vehicle-evb-maxim-max96712.dtsi" -#include "rk3588-vehicle-serdes-display-v21.dtsi" +#include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi" +#include "rk3588-vehicle-serdes-mfd-display-rohm.dtsi" #include "rk3588-android.dtsi" / { @@ -55,6 +55,32 @@ }; }; +&i2c2 { + himax@48 { + himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&i2c4 { + himax@48 { + himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&i2c5 { + ilitek@41 { + interrupt-parent = <&gpio0>; + interrupts = ; + reset-gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_LOW>; + }; +}; + +&i2c6 { + himax@48 { + himax,irq-gpio = <&gpio1 RK_PB7 IRQ_TYPE_EDGE_FALLING>; //use rst as int + }; +}; + &i2s2_2ch { pinctrl-0 = <&i2s2m1_lrck &i2s2m1_sclk @@ -63,6 +89,78 @@ status = "okay"; }; + +&pinctrl { + + bl { + bl0_enable_pin: bl0-enable-pin { + rockchip,pins = + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>, + <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>, + <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + + }; + + bl1_enable_pin: bl1-enable-pin { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl2_enable_pin: bl2-enable-pin { + rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl3_enable_pin: bl3-enable-pin { + rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl4_enable_pin: bl4-enable-pin { + rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl5_enable_pin: bl5-enable-pin { + rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + serdes { + //dsi0 + ser0_rst_pin: ser0-rst-pin { + rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + //dsi1 + ser1_rst_pin: ser1-rst-pin { + rockchip,pins = <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + touch { + //dsi0-i2c2 + touch_gpio_dsi0: touch-gpio-dsi0 { + rockchip,pins = + <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; //rst + }; + //dsi1-i2c6 + touch_gpio_dsi1: touch-gpio-dsi1 { + rockchip,pins = + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>, //rst + <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; //int + }; + //dp0-i2c4 + touch_gpio_dp0: touch-gpio-dp0 { + rockchip,pins = + <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>, //rst + <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>; //int + }; + //edp0-i2c5 + touch_gpio_edp0: touch-gpio-edp0 { + rockchip,pins = + <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>, //rst + <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>; //int + }; + }; +}; + &rockchip_suspend { rockchip,sleep-mode-config = < (0 diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22-nca9539-io-expander.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22-nca9539-io-expander.dtsi new file mode 100644 index 000000000000..bfb50d3ea982 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22-nca9539-io-expander.dtsi @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ + +/ { + nca9539_vdd: nca9539-vdd3v3 { + compatible = "regulator-fixed"; + regulator-name = "nca9539_vdd"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <20>; // NCA9539 POR + vin-supply = <&vcc_3v3_s0>; + }; + +}; + +&i2c5 { + clock-frequency = <400000>; + status = "okay"; + + nca9539_gpio: gpio@74 { + status = "okay"; + compatible = "novo,nca9539-gpio"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <16>; + interrupt-controller; + #interrupt-cells = <2>; + vdd-supply = <&nca9539_vdd>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts new file mode 100644 index 000000000000..c2986168a6c3 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts @@ -0,0 +1,594 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ + +/dts-v1/; + +#include "rk3588-vehicle-evb-v21.dtsi" +#include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi" +#include "rk3588-vehicle-serdes-mfd-display-rohm.dtsi" +#include "rk3588-android.dtsi" + +/ { + model = "Rockchip RK3588 VEHICLE EVB V22 Board"; + compatible = "rockchip,rk3588-vehicle-evb-v22", "rockchip,rk3588"; + + vcc5v0_buck: vcc5v0-buck { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&gpio4 RK_PC3 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_buck_en>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <5000000>; + }; + }; + + vcc4v0_sys_mode: vcc4v0-sys-mode { + compatible = "regulator-fixed"; + regulator-name = "vcc4v0_sys_mode"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <4000000>; + enable-active-high; + gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>; + vin-supply = <&vcc12v_dcin>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc4v0_sys_mode_en>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <4000000>; + }; + }; + + lcd1_vcc12v_buck: lcd1_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd1_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 0 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + lcd2_vcc12v_buck: lcd2_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd2_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 1 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + lcd3_vcc12v_buck: lcd3_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd3_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 2 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + lcd4_vcc12v_buck: lcd4_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd4_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 3 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + lcd5_vcc12v_buck: lcd5_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd5_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 4 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + lcd6_vcc12v_buck: lcd6_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "lcd6_vcc12v_buck"; + regulator-boot-on; + //regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 5 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + camera1_vcc12v_buck: camera1_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "camera1_vcc12v_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 6 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + camera2_vcc12v_buck: camera2_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "camera2_vcc12v_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 7 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + camera3_vcc12v_buck: camera3_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "camera3_vcc12v_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 8 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + camera4_vcc12v_buck: camera4_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "camera4_vcc12v_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 9 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + vcc5v0_host_usb20: vcc5v0-host-usb20 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host_usb20"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 10 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_usb>; + }; + + vcc5v0_host_usb30: vcc5v0-host-usb30 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_host_usb30"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 11 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_usb>; + }; + + adsp_vcc12v_buck: adsp_vcc12v-buck { + compatible = "regulator-fixed"; + regulator-name = "adsp_vcc12v_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 12 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc12v_dcin>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + minipcie_power_buck: minipcie_power-buck { + compatible = "regulator-fixed"; + regulator-name = "minipcie_power_buck"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + enable-active-high; + gpio = <&i2c5_nca9539_gpio 13 GPIO_ACTIVE_HIGH>; + vin-supply = <&vcc5v0_usb>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <12000000>; + }; + }; + + bt-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "dsp_a"; + simple-audio-card,bitclock-inversion = <1>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rockchip,bt"; + simple-audio-card,cpu { + sound-dai = <&i2s2_2ch>; + }; + + simple-audio-card,codec { + sound-dai = <&bt_sco 1>; + }; + }; + + bt_sco: bt-sco { + compatible = "delta,dfbmcs320"; + #sound-dai-cells = <1>; + status = "okay"; + }; + gpio-keys { + compatible = "gpio-keys"; + autorepeat; + + reverse { + label = "GPIO Key Reverse"; + linux,code = ; + gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + debounce-interval = <100>; + }; + + park { + label = "GPIO Key Park"; + linux,code = ; + gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + debounce-interval = <100>; + }; + }; + + vcc3v3_pcie_wifi: vcc3v3-pcie-wifi { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie_wifi"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + enable-active-high; + gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + startup-delay-us = <5000>; + vin-supply = <&vcc_3v3_s3>; + }; + + wireless_bluetooth: wireless-bluetooth { + BT,reset_gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless_wlan: wireless-wlan { + WIFI,poweren_gpio = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&avdd1v8_ddr_pll_s0 { + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; +}; + +&i2s2_2ch { + pinctrl-0 = <&i2s2m1_lrck + &i2s2m1_sclk + &i2s2m1_sdi + &i2s2m1_sdo>; + status = "okay"; +}; + +&i2c2 { + himax@48 { + himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&i2c2_bu18tl82 { + //route-enable; + use-delay-work; +}; + +&i2c2_bu18rl82 { + use-delay-work; + vpower-supply = <&lcd1_vcc12v_buck>; +}; + +&i2c4 { + himax@48 { + himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&i2c4_bu18tl82 { + use-delay-work; +}; + +&i2c4_bu18rl82 { + use-delay-work; + vpower-supply = <&lcd5_vcc12v_buck>; +}; + +&i2c5 { + ilitek@41 { + interrupt-parent = <&gpio1>; + interrupts = ; + }; + + i2c5_nca9539: i2c5-nca9539@74 { + compatible = "novo,nca9539"; + reg = <0x74>; + status = "okay"; + + /* P00-P07 P10-P17 output HIGH level default*/ + serdes-init-sequence = [ + 0002 00ff + 0003 00ff + 0004 0000 + 0005 0000 + 0006 0000 + 0007 0000 + ]; + + i2c5_nca9539_pinctrl: i2c5-nca9539-pinctrl { + compatible = "novo,nca9539-pinctrl"; + status = "okay"; + + i2c5_nca9539_gpio: i2c5-nca9539-gpio { + compatible = "novo,nca9539-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c5_nca9539_pinctrl 0 256 16>; + }; + }; + }; +}; + +&i2c5_bu18tl82 { + use-delay-work; +}; + +&i2c5_bu18rl82 { + use-delay-work; + vpower-supply = <&lcd3_vcc12v_buck>; +}; + +&i2c6 { + himax@48 { + himax,irq-gpio = <&gpio1 RK_PB7 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&i2c6_bu18tl82 { + //route-enable; + use-delay-work; +}; + +&i2c6_bu18rl82 { + use-delay-work; + vpower-supply = <&lcd2_vcc12v_buck>; +}; + +&pinctrl { + + bl { + bl0_enable_pin: bl0-enable-pin { + rockchip,pins = + <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>, + <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>, + <4 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + + }; + + bl1_enable_pin: bl1-enable-pin { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl2_enable_pin: bl2-enable-pin { + rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl3_enable_pin: bl3-enable-pin { + rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl4_enable_pin: bl4-enable-pin { + rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bl5_enable_pin: bl5-enable-pin { + rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + max96712-dphy3 { + max96712_dphy3_pwdn: max96712-dphy3-pwdn { + rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy3_errb: max96712-dphy3-errb { + rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + max96712_dphy3_lock: max96712-dphy3-lock { + rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + touch { + //dsi0-i2c2 + touch_gpio_dsi0: touch-gpio-dsi0 { + rockchip,pins = + <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT + }; + //dsi1-i2c6 + touch_gpio_dsi1: touch-gpio-dsi1 { + rockchip,pins = + <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT + }; + //dp0-i2c4 + touch_gpio_dp0: touch-gpio-dp0 { + rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + //edp0-i2c5 + touch_gpio_edp0: touch-gpio-edp0 { + rockchip,pins = + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; //RST->V22 INT + }; + }; + + vcc5v0-buck { + vcc5v0_buck_en: vcc5v0-buck-en { + rockchip,pins = <4 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + vcc4v0-mode { + vcc4v0_sys_mode_en: vcc4v0-sys-mode-en { + rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-bluetooth { + bt_reset_gpio: bt-reset-gpio { + rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&rockchip_suspend { + rockchip,sleep-mode-config = < + (0 + | RKPM_SLP_ARMOFF_DDRPD + | RKPM_SLP_PMU_PMUALIVE_32K + | RKPM_SLP_PMU_DIS_OSC + | RKPM_SLP_32K_EXT + ) + >; + rockchip,wakeup-config = < + (0 + | RKPM_CPU0_WKUP_EN + | RKPM_GPIO_WKUP_EN + ) + >; + status = "okay"; +}; + +&route_dsi0 { + status = "disabled"; +}; + +&route_dsi1 { + status = "disabled"; +}; + +&u2phy1_otg { + phy-supply = <&vcc5v0_host_usb20>; +}; + +&u2phy2_host { + phy-supply = <&vcc5v0_host_usb20>; +}; + +&u2phy3_host { + phy-supply = <&vcc5v0_host_usb30>; +}; + +&vdd_log_s0 { + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <800000>; + }; +}; + +&vcc_3v3_s0 { + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; +}; + +&vcc_1v8_s0 { + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; +}; + +&vdd_1v8_pll_s0 { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; +}; + +&vcc5v0_host { + status = "disabled"; +}; + diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi index 566c9d00095b..c4fe0cbcf165 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-maxim-cameras-s66.dtsi @@ -3,20 +3,21 @@ * Copyright (c) 2023 Rockchip Electronics Co., Ltd. * */ +#include / { - max96712_osc: max96712-oscillator { + max96712_dphy0_osc0: max96712-dphy0-oscillator@0 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <25000000>; - clock-output-names = "max96712-osc"; + clock-output-names = "max96712-dphy0-osc0"; }; - max96722_osc: max96722-oscillator { + max96722_dphy3_osc0: max96722-dphy3-oscillator@0 { compatible = "fixed-clock"; #clock-cells = <1>; clock-frequency = <25000000>; - clock-output-names = "max96722-osc"; + clock-output-names = "max96722-dphy3-osc0"; }; }; @@ -43,7 +44,7 @@ mipi_dphy0_in_max96712: endpoint@1 { reg = <1>; - remote-endpoint = <&max96712_out>; + remote-endpoint = <&max96712_dphy0_out>; data-lanes = <1 2 3 4>; }; }; @@ -138,7 +139,7 @@ mipi_dphy3_in_max96722: endpoint@1 { reg = <1>; - remote-endpoint = <&max96722_out>; + remote-endpoint = <&max96722_dphy3_out>; data-lanes = <1 2 3 4>; }; }; @@ -231,88 +232,945 @@ clock-frequency = <400000>; // AVM Camera x4 - max96712: max96712@29 { - compatible = "maxim,max96712"; + max96712_dphy0: max96712@29 { + compatible = "maxim4c,max96712"; status = "okay"; reg = <0x29>; clock-names = "xvclk"; - clocks = <&max96712_osc 0>; + clocks = <&max96712_dphy0_osc0 0>; pinctrl-names = "default"; - pinctrl-0 = <&max96712_power>, <&max96712_errb>, <&max96712_lock>; + pinctrl-0 = <&max96712_dphy0_pwdn>, <&max96712_dphy0_errb>, <&max96712_dphy0_lock>; power-domains = <&power RK3588_PD_VI>; rockchip,grf = <&sys_grf>; - power-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_HIGH>; lock-gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; - link-mask = <0x0F>; - auto-init-deskew-mask = <0x3>; - frame-sync-period = <0>; - link-rx-rate = <0>; + rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; rockchip,camera-module-name = "max96712"; rockchip,camera-module-lens-name = "max96712"; port { - max96712_out: endpoint { + max96712_dphy0_out: endpoint { remote-endpoint = <&mipi_dphy0_in_max96712>; data-lanes = <1 2 3 4>; }; }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1280>; + sensor-height = <800>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link0_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + 0B 06 ef 00 00 // HIM on + 0B 07 84 00 00 // Enable HVEN and DBL + 0B 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link1_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + 0C 06 ef 00 00 // HIM on + 0C 07 84 00 00 // Enable HVEN and DBL + 0C 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link C: link-id = 2 + gmsl-link-config-2 { + status = "okay"; + link-id = <2>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link2_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote2_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 16 D1 03 00 00 // VGAHiGain + 16 45 00 00 00 // Disable SSC + 0D 06 ef 00 00 // HIM on + 0D 07 84 00 00 // Enable HVEN and DBL + 0D 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + + // Link D: link-id = 3 + gmsl-link-config-3 { + status = "okay"; + link-id = <3>; // Link ID: 0/1/2/3 + + link-type = <0>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96712_dphy0_link3_in: endpoint { + remote-endpoint = <&max96712_dphy0_remote3_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 17 D1 03 00 00 // VGAHiGain + 17 45 00 00 00 // Disable SSC + 0E 06 ef 00 00 // HIM on + 0E 07 84 00 00 // Enable HVEN and DBL + 0E 0F 01 00 00 // Disable processing DE signals + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + ]; + }; + }; + + // Video Pipe 2 + video-pipe-config-2 { + status = "okay"; + pipe-id = <2>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <2>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 2 to Controller 1 + 09 8B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 AD 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 8D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 8E 9e 00 00 // DST0 VC = 2, DT = YUV422 8bit + 09 8F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 90 80 00 00 // DST1 VC = 2, DT = Frame Start + 09 91 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 92 81 00 00 // DST2 VC = 2, DT = Frame End + ]; + }; + }; + + // Video Pipe 3 + video-pipe-config-3 { + status = "okay"; + pipe-id = <3>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <3>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 3 to Controller 1 + 09 CB 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 ED 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 CD 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 CE de 00 00 // DST0 VC = 3, DT = YUV422 8bit + 09 CF 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 D0 c0 00 00 // DST1 VC = 3, DT = Frame Start + 09 D1 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 D2 c1 00 00 // DST2 VC = 3, DT = Frame End + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <0>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max96715"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x41>; // 0: disable remap + + port { + max96712_dphy0_remote0_out: endpoint { + remote-endpoint = <&max96712_dphy0_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max96715"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x42>; // 0: disable remap + + port { + max96712_dphy0_remote1_out: endpoint { + remote-endpoint = <&max96712_dphy0_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-2 { + compatible = "maxim4c,link2,max96715"; + status = "okay"; + + remote-id = <2>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x43>; // 0: disable remap + + port { + max96712_dphy0_remote2_out: endpoint { + remote-endpoint = <&max96712_dphy0_link2_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + + serdes-remote-device-3 { + compatible = "maxim4c,link3,max96715"; + status = "okay"; + + remote-id = <3>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x44>; // 0: disable remap + + port { + max96712_dphy0_remote3_out: endpoint { + remote-endpoint = <&max96712_dphy0_link3_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <4>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <1>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 07 84 00 00 + 67 c4 00 00 + 0F bf 00 00 + 3F 08 00 00 + 40 2d 00 00 + 20 10 00 00 + 21 11 00 00 + 22 12 00 00 + 23 13 00 00 + 24 14 00 00 + 25 15 00 00 + 26 16 00 00 + 27 17 00 00 + 30 00 00 00 + 31 01 00 00 + 32 02 00 00 + 33 03 00 00 + 34 04 00 00 + 35 05 00 00 + 36 06 00 00 + 37 07 00 00 + ]; + }; + }; + /* serdes remote device end */ }; // DMS Camera x1 + OMS Camera x3 - max96722: max96722@6b { - compatible = "maxim,max96722"; + max96722_dphy3: max96722@6b { + compatible = "maxim4c,max96722"; status = "okay"; reg = <0x6b>; clock-names = "xvclk"; - clocks = <&max96722_osc 0>; + clocks = <&max96722_dphy3_osc0 0>; pinctrl-names = "default"; - pinctrl-0 = <&max96722_power>, <&max96722_errb>, <&max96722_lock>; + pinctrl-0 = <&max96722_dphy3_pwdn>, <&max96722_dphy3_errb>, <&max96722_dphy3_lock>; power-domains = <&power RK3588_PD_VI>; rockchip,grf = <&sys_grf>; - power-gpios = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio1 RK_PC7 GPIO_ACTIVE_HIGH>; lock-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>; - link-mask = <0x33>; - auto-init-deskew-mask = <0x3>; - frame-sync-period = <0>; + rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; rockchip,camera-module-name = "max96722"; rockchip,camera-module-lens-name = "max96722"; port { - max96722_out: endpoint { + max96722_dphy3_out: endpoint { remote-endpoint = <&mipi_dphy3_in_max96722>; data-lanes = <1 2 3 4>; }; }; + + /* support mode config start */ + support-mode-config { + status = "okay"; + + bus-format = ; + sensor-width = <1600>; + sensor-height = <1300>; + max-fps-numerator = <10000>; + max-fps-denominator = <300000>; + bpp = <16>; + link-freq-idx = <20>; + vc-array = <0x10 0x20 0x40 0x80>; // VC0~3: bit4~7 + }; + /* support mode config end */ + + /* serdes local device start */ + serdes-local-device { + status = "okay"; + + /* GMSL LINK config start */ + gmsl-links { + status = "okay"; + + link-vdd-ldo1-en = <1>; + link-vdd-ldo2-en = <1>; + + // Link A: link-id = 0 + gmsl-link-config-0 { + status = "okay"; + link-id = <0>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy3_link0_in: endpoint { + remote-endpoint = <&max96722_dphy3_remote0_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 14 D1 03 00 00 // VGAHiGain + 14 45 00 00 00 // Disable SSC + ]; + }; + }; + + // Link B: link-id = 1 + gmsl-link-config-1 { + status = "okay"; + link-id = <1>; // Link ID: 0/1/2/3 + + link-type = <1>; + link-rx-rate = <0>; + link-tx-rate = <0>; + + port { + max96722_dphy3_link1_in: endpoint { + remote-endpoint = <&max96722_dphy3_remote1_out>; + }; + }; + + link-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 15 D1 03 00 00 // VGAHiGain + 15 45 00 00 00 // Disable SSC + ]; + }; + }; + }; + /* GMSL LINK config end */ + + /* VIDEO PIPE config start */ + video-pipes { + status = "okay"; + + // Video Pipe 0 + video-pipe-config-0 { + status = "okay"; + pipe-id = <0>; // Video Pipe ID: 0/1/2/3/4/5/6/7 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <0>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 0 to Controller 1 + 09 0B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 2D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 0D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 0E 1e 00 00 // DST0 VC = 0, DT = YUV422 8bit + 09 0F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 10 00 00 00 // DST1 VC = 0, DT = Frame Start + 09 11 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 12 01 00 00 // DST2 VC = 0, DT = Frame End + // pipe Cross + 01 D9 59 00 00 // pipe 0: Inverts Cross VS + ]; + }; + }; + + // Video Pipe 1 + video-pipe-config-1 { + status = "okay"; + pipe-id = <1>; // Video Pipe 1: pipe-id = 1 + + pipe-idx = <0>; // Video Pipe X/Y/Z/U: 0/1/2/3 + link-idx = <1>; // Link A/B/C/D: 0/1/2/3 + + pipe-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Send YUV422, FS, and FE from Video Pipe 1 to Controller 1 + 09 4B 07 00 00 // Enable 0/1/2 SRC/DST Mappings + 09 6D 15 00 00 // SRC/DST 0/1/2 -> CSI2 Controller 1; + // For the following MSB 2 bits = VC, LSB 6 bits = DT + 09 4D 1e 00 00 // SRC0 VC = 0, DT = YUV422 8bit + 09 4E 5e 00 00 // DST0 VC = 1, DT = YUV422 8bit + 09 4F 00 00 00 // SRC1 VC = 0, DT = Frame Start + 09 50 40 00 00 // DST1 VC = 1, DT = Frame Start + 09 51 01 00 00 // SRC2 VC = 0, DT = Frame End + 09 52 41 00 00 // DST2 VC = 1, DT = Frame End + // pipe Cross + 01 F9 59 00 00 // pipe 1: Inverts Cross VS + ]; + }; + }; + + // Software override for parallel mode + parallel-mode-config { + status = "okay"; + + parallel-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // Enable software override for all pipes since GMSL1 data is parallel mode, bpp=8, dt=0x1e(yuv-8) + 04 1A f0 00 00 // pipe 0/1/2/3: Enable YUV8-/10-bit mux mode + 04 0B 40 00 00 // pipe 0 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 0C 00 00 00 // pipe 0 and 1 VC software override: 0x00 + 04 0D 00 00 00 // pipe 2 and 3 VC software override: 0x00 + 04 0E 5e 00 00 // pipe 0 DT=0x1E: YUV422 8-bit + 04 0F 7e 00 00 // pipe 1 DT=0x1E: YUV422 8-bit + 04 10 7a 00 00 // pipe 2 DT=0x1E, pipe 3 DT=0x1E: YUV422 8-bit + 04 11 48 00 00 // pipe 1 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 12 20 00 00 // pipe 2 bpp=0x08, pipe 3 bpp=0x08: Datatypes = 0x2A, 0x10-12, 0x31-37 + 04 15 c0 c0 00 // pipe 0/1 enable software overide + 04 18 c0 c0 00 // pipe 2/3 enable software overide + ]; + }; + }; + }; + /* VIDEO PIPE config end */ + + /* MIPI TXPHY config start */ + mipi-txphys { + status = "okay"; + + phy-mode = <0>; + phy-force-clock-out = <1>; + phy-force-clk0-en = <0>; + phy-force-clk3-en = <0>; + + // MIPI TXPHY A: phy-id = 0 + mipi-txphy-config-0 { + status = "okay"; + phy-id = <0>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0x4>; + vc-ext-en = <0>; + }; + + // MIPI TXPHY B: phy-id = 1 + mipi-txphy-config-1 { + status = "okay"; + phy-id = <1>; // MIPI TXPHY ID: 0/1/2/3 + + phy-type = <0>; + auto-deskew = <0x80>; + data-lane-num = <4>; + data-lane-map = <0xe>; + vc-ext-en = <0>; + }; + }; + /* MIPI TXPHY config end */ + + /* local device extra init sequence */ + extra-init-sequence { + status = "disabled"; + + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + // common init sequence such as fsync / gpio and so on + ]; + }; + }; + /* serdes local device end */ + + /* serdes remote device start */ + serdes-remote-device-0 { + compatible = "maxim4c,link0,max9295"; + status = "okay"; + + remote-id = <0>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x45>; // 0: disable remap + + port { + max96722_dphy3_remote0_out: endpoint { + remote-endpoint = <&max96722_dphy3_link0_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + + serdes-remote-device-1 { + compatible = "maxim4c,link1,max9295"; + status = "okay"; + + remote-id = <1>; // Same as Link ID: 0/1/2/3 + + // Serializer i2c 7bit address remap + ser-i2c-addr-def = <0x40>; + ser-i2c-addr-map = <0x46>; // 0: disable remap + + port { + max96722_dphy3_remote1_out: endpoint { + remote-endpoint = <&max96722_dphy3_link1_in>; + }; + }; + + remote-init-sequence { + seq-item-size = <5>; // reg-addr-len + reg-val-len * 2 + 1 + reg-addr-len = <2>; // 1: 8bits, 2: 16bits + reg-val-len = <1>; // 1: 8bits, 2: 16bits, 3: 24bits + + // reg_addr reg_val val_mask delay + init-sequence = [ + 00 01 04 00 00 // RX_RATE: 187.5Mbps, TX_RATE: 3Gbps + 00 11 03 00 00 // Coax Drive + 02 D6 03 00 00 // MFP8: GPIO_OUT_DIS = 1, GPIO_TX_EN = 1 + 03 F0 51 00 00 // RCLK: 27MHz/24MHz (ALT),Enable reference-generation PLL, Enable pre-defined clock setting for reference-generation PLL + 00 03 07 00 00 // RCLK: Enable RCLK output from altermative MFP pin, RCLKOUT clock select reference PLL + 00 06 b1 00 00 // RCLK: GMSL2, Enable RCLK output, i2c selected + 02 C1 10 00 00 // MFP1: GPIO_OUT pin output is driven to 1 when GPIO_RX_EN = 0 + 02 C2 60 00 00 // MFP1: OUT_TYPE = 1: Push-pull, PULL_UPDN_SEL[1:0] = 0b01: Pullup + 00 07 07 00 00 // Enable Parallel video input, Parallel HS and VS Enable + 00 10 05 00 00 // AUTO_LINK = 0, LINK_CFG = 1: LinkA is selected, REG_ENABLE = 1: Regulator enabled + 00 12 14 00 00 // REG_MNL = 1: Enable LDO on/off state controlled by REG_ENABLE + 01 00 62 00 00 // Video X, Line CRC enabled, ENC_MODE = 2: HS, VS, DE encoding on, color bits sent only when DE is high + 01 01 50 00 00 // Video X, BPP = 0x10 + 00 53 10 00 00 // Video X, TX_STR_SEL = 0: Stream ID = 0 for packets from this channel + 00 02 13 00 00 // Video transmit enable for Port X + ]; + }; + }; + /* serdes remote device end */ }; }; &pinctrl { maxim-cameras { - max96712_power: max96712-power { + max96712_dphy0_pwdn: max96712-dphy0-pwdn { rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>; }; - max96712_errb: max96712-errb { + max96712_dphy0_errb: max96712-dphy0-errb { rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; }; - max96712_lock: max96712-lock { + max96712_dphy0_lock: max96712-dphy0-lock { rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; }; - max96722_power: max96722-power { + max96722_dphy3_pwdn: max96722-dphy3-pwdn { rockchip,pins = <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; }; - max96722_errb: max96722-errb { + max96722_dphy3_errb: max96722-dphy3-errb { rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>; }; - max96722_lock: max96722-lock { + max96722_dphy3_lock: max96722-dphy3-lock { rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim.dtsi new file mode 100644 index 000000000000..cc8129a406a8 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim.dtsi @@ -0,0 +1,1092 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +#include + +/ { + aliases { + pinctrl0 = &pinctrl; + }; + + backlight { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + i2c2_max96755f_backlight: backlight@0 { + compatible = "pwm-backlight"; + reg = <0>; + pwms = <&pwm0 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + i2c4_max96745_backlight: backlight@1 { + compatible = "pwm-backlight"; + reg = <1>; + pwms = <&pwm10 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + i2c5_max96745_backlight: backlight@2 { + compatible = "pwm-backlight"; + reg = <2>; + pwms = <&pwm7 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + i2c6_max96755f_backlight: backlight@3 { + compatible = "pwm-backlight"; + reg = <3>; + pwms = <&pwm13 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + i2c7_max96745_backlight: backlight@4 { + compatible = "pwm-backlight"; + reg = <4>; + pwms = <&pwm11 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + i2c8_max96745_backlight: backlight@5 { + compatible = "pwm-backlight"; + reg = <5>; + pwms = <&pwm14 0 1000000 0>; + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + }; +}; + +&dp0 { + //split-mode; + force-hpd; + status = "okay"; +}; + +&dp0_in_vp0 { + status = "okay"; +}; + +&dp0_out { + link-frequencies = /bits/ 64 <2700000000>; + remote-endpoint = <&i2c4_max96745_in>; +}; + +&usbdp_phy0 { + rockchip,dp-lane-mux = <0 1 2 3>; + status = "okay"; +}; + +&usbdp_phy0_dp { + status = "okay"; +}; + +&route_dp0 { + connect = <&vp0_out_dp0>; + status = "okay"; +}; + +&dp1 { + force-hpd; + status = "disabled"; +}; + +&dp1_out { + link-frequencies = /bits/ 64 <2700000000>; + remote-endpoint = <&i2c8_max96745_in>; +}; + +&usbdp_phy1 { + rockchip,dp-lane-mux = <0 1 2 3>; + status = "okay"; +}; + +&usbdp_phy1_dp { + status = "okay"; +}; + +&dsi0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dsi0_out: endpoint { + remote-endpoint = <&i2c2_max96755f_in>; + }; + }; + }; +}; + +&mipi_dcphy0 { + status = "okay"; +}; + +&dsi0_in_vp2 { + status = "okay"; +}; + +&route_dsi0 { + connect = <&vp2_out_dsi0>; + status = "disabled"; +}; + +&dsi1 { + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dsi1_out: endpoint { + remote-endpoint = <&i2c6_max96755f_in>; + }; + }; + }; +}; + +&mipi_dcphy1 { + status = "okay"; +}; + +&dsi1_in_vp3 { + status = "okay"; +}; + +&route_dsi1 { + connect = <&vp3_out_dsi1>; + status = "disabled"; +}; + +&edp0 { + //split-mode; + force-hpd; + status = "okay"; +}; + +&edp0_out { + link-frequencies = /bits/ 64 <2700000000>; + remote-endpoint = <&i2c5_max96745_in>; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&edp0_in_vp1 { + status = "okay"; +}; + +&route_edp0 { + connect = <&vp1_out_edp0>; + status = "okay"; +}; + +&edp1 { + force-hpd; + status = "disabled"; +}; + +&edp1_out { + link-frequencies = /bits/ 64 <2700000000>; + remote-endpoint = <&i2c7_max96745_in>; +}; + +&hdptxphy1 { + status = "okay"; +}; + +&hdmi0 { + status = "disabled"; +}; + +&hdmi1 { + status = "disabled"; +}; + +&hdptxphy_hdmi0 { + status = "disabled"; +}; + +&hdptxphy_hdmi1 { + status = "disabled"; +}; + +&i2c2 { + pinctrl-0 = <&i2c2m4_xfer>; + clock-frequency = <400000>; + status = "okay"; + + max96755@40 { + compatible = "maxim,max96755"; + reg = <0x40>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_serdes_pins>; + lock-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + sel-mipi; + status = "okay"; + + serdes-init-sequence = [ + 0001 0008 + 0002 0053 + 0003 0040 + 0010 0031 + 0013 00ca + 0010 0000 + 02be 001c + 02bf 0040 + 02c0 0020 + 0311 0057 + 0331 0033 + 0332 004e + 03a4 0000 + 0385 0000 + 0386 0000 + 0387 0000 + 005b 0012 + 0053 0010 + ]; + + i2c2_max96755f_pinctrl: i2c2-max96755f-pinctrl { + compatible = "maxim,max96755-pinctrl"; + status = "okay"; + + i2c2_max96755f_pinctrl_hog: hog { + i2c { + groups = "MAX96755_I2C"; + function = "MAX96755_I2C"; + }; + }; + + i2c2_max96755f_panel_pins: panel-pins { + bl-pwm { + pins = "MAX96755_MFP0"; + function = "DES_GPIO0_OUTPUT"; + }; + }; + + i2c2_max96755f_gpio: i2c2-max96755f-gpio { + compatible = "maxim,max96755-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c2_max96755f_pinctrl 0 160 24>; + }; + }; + + i2c2_max96755f_bridge: i2c2-max96755f-bridge { + compatible = "maxim,max96755-bridge"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_max96755f_pinctrl_hog>; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c2_max96755f_in: endpoint { + remote-endpoint = <&dsi0_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c2_max96755f_out: endpoint { + remote-endpoint = <&i2c2_max96755f_panel_in>; + }; + }; + }; + }; + + + max96772@48 { + compatible = "maxim,max96772"; + reg = <0x48>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + serdes-init-sequence = [ + 0001 0002 + 0010 0011 + 0050 0000 + 07f0 0001 + e791 0000 + e793 0000 + e794 0000 + e795 000a + e796 007a + e797 0000 + e798 003c + e799 0000 + e79a 003c + e79b 0000 + e79c 00a0 + e79d 0005 + e79e 0054 + e79f 0001 + e7a0 0002 + e7a1 0000 + e7a2 0014 + e7a3 0000 + e7a4 00fc + e7a5 000e + e7a6 0055 + e7a7 0055 + e7a8 0000 + e7a9 0080 + e7aa 0040 + e7ab 0000 + e7ac 0003 + e7ad 0000 + e7b0 0000 + e7b1 0000 + e7b2 0050 + e7b3 0000 + e7b4 0000 + e7b5 0040 + e7b6 006c + e7b7 0020 + e7b8 0007 + e7b9 0000 + e7ba 0001 + e7bb 0000 + e7bc 0000 + e7bd 0000 + e7be 0052 + e7bf 0000 + ]; + + i2c2_max96772_pinctrl: i2c2-max96772-pinctrl { + compatible = "maxim,max96772-pinctrl"; + status = "okay"; + + i2c2_max96772_gpio: i2c2-max96772-gpio { + compatible = "maxim,max96772-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c2_max96772_pinctrl 0 185 24>; + }; + }; + + i2c2_max96772_panel: i2c2-max96772-panel { + compatible = "maxim,max96772-panel"; + backlight = <&i2c2_max96755f_backlight>; + + panel-timing { + clock-frequency = <180000000>; + hactive = <2560>; + vactive = <1440>; + hfront-porch = <122>; + hsync-len = <60>; + hback-porch = <60>; + vfront-porch = <340>; + vsync-len = <2>; + vback-porch = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c2_max96755f_panel_in: endpoint { + remote-endpoint = <&i2c2_max96755f_out>; + }; + }; + + }; + + }; + + ts@30 { + compatible = "gac,gac_ts"; + reg = <0x30>; + gac,max_x = <2560>; + gac,max_y = <1440>; + }; +}; + +&i2c4 { + pinctrl-0 = <&i2c4m2_xfer>; + clock-frequency = <400000>; + status = "okay"; + + max96745@42 { + compatible = "maxim,max96745"; + reg = <0x42>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_serdes_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + serdes-init-sequence = [ + 0070 0016 + 0005 00c0 + 0107 0042 + 0027 0022 + 0026 0022 + 002a 0007 + 641a 00f0 + ]; + + + i2c4_max96745_pinctrl: i2c4-max96745-pinctrl { + compatible = "maxim,max96745-pinctrl"; + status = "okay"; + + i2c4_max96745_gpio: i2c4-max96745-gpio { + compatible = "maxim,max96745-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c4_max96745_pinctrl 0 210 25>; + }; + }; + + i2c4_max96745_bridge: i2c4-max96745-bridge { + compatible = "maxim,max96745-bridge"; + lock-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c4_max96745_in: endpoint { + remote-endpoint = <&dp0_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c4_max96745_out: endpoint { + remote-endpoint = <&i2c4_max96745_panel_in>; + }; + }; + }; + + }; + + + max96752@48 { + compatible = "maxim,max96752"; + reg = <0x48>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + serdes-init-sequence = [ + 0001 0002 + 0002 0043 + 0140 0020 + 01ce 005e + 0200 0084 + 020e 0040 + 020c 0084 + 0207 00a1 + 0206 0083 + 0215 0090 + 0227 0090 + 020f 0090 + 0221 0090 + 0212 0090 + 0209 0090 + ]; + + i2c4_max96752_pinctrl: i2c4-max96752-pinctrl { + compatible = "maxim,max96752-pinctrl"; + status = "okay"; + + i2c4_max96752_gpio: i2c4-max96752-gpio { + compatible = "maxim,max96752-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c4_max96752_pinctrl 0 236 25>; + }; + }; + + i2c4_max96752_panel: i2c4-max96752-panel { + compatible = "maxim,max96752-panel"; + reg = <0x48>; + backlight = <&i2c4_max96745_backlight>; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <20>; + hsync-len = <20>; + hback-porch = <20>; + vfront-porch = <250>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c4_max96745_panel_in: endpoint { + remote-endpoint = <&i2c4_max96745_out>; + }; + }; + }; + + }; +}; + +&i2c5 { + clock-frequency = <400000>; + status = "okay"; + + max96745@42 { + compatible = "maxim,max96745"; + reg = <0x42>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_serdes_pins>; + lock-gpios = <&gpio0 RK_PD2 GPIO_ACTIVE_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + serdes-init-sequence = [ + 0070 0016 + 0005 00c0 + 0107 0042 + 0027 0022 + 0026 0022 + 002a 0007 + 641a 00f0 + ]; + + + i2c5_max96745_pinctrl: i2c5-max96745-pinctrl { + compatible = "maxim,max96745-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_max96745_pinctrl_hog>, <&i2c5_max96745_panel_pins>; + status = "okay"; + + i2c5_max96745_pinctrl_hog: hog { + i2c { + groups = "MAX96745_I2C"; + function = "MAX96745_I2C"; + }; + }; + + i2c5_max96745_panel_pins: panel-pins { + bl-pwm { + pins = "MAX96745_MFP0"; + function = "DES_GPIO0_OUTPUT_A"; + }; + }; + + i2c5_max96745_gpio: i2c5-max96745-gpio { + compatible = "maxim,max96745-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c5_max96745_pinctrl 0 262 25>; + }; + }; + + i2c5_max96745_bridge: i2c5-max96745-bridge { + compatible = "maxim,max96745-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c5_max96745_in: endpoint { + remote-endpoint = <&edp0_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c5_max96745_out: endpoint { + remote-endpoint = <&i2c5_max96745_panel_in>; + }; + }; + }; + + }; + + + max96752@48 { + compatible = "maxim,max96752"; + reg = <0x48>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + serdes-init-sequence = [ + 0001 0002 + 0002 0043 + 0140 0020 + 01ce 005e + 0200 0084 + 020e 0040 + 020c 0084 + 0207 00a1 + 0206 0083 + 0215 0090 + 0227 0090 + 020f 0090 + 0221 0090 + 0212 0090 + 0209 0090 + ]; + + i2c5_max96752_pinctrl: i2c5-max96752-pinctrl { + compatible = "maxim,max96752-pinctrl"; + status = "okay"; + + i2c5_max96752_gpio: i2c5-max96752-gpio { + compatible = "maxim,max96752-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c5_max96752_pinctrl 0 288 25>; + }; + }; + + i2c5_max96752_panel: i2c5-max96752-panel { + compatible = "maxim,max96752-panel"; + reg = <0x48>; + backlight = <&i2c5_max96745_backlight>; + panel-size= <346 194>; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <20>; + hsync-len = <20>; + hback-porch = <20>; + vfront-porch = <250>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c5_max96745_panel_in: endpoint { + remote-endpoint = <&i2c5_max96745_out>; + }; + }; + + }; + }; +}; + +&i2c6 { + pinctrl-0 = <&i2c6m3_xfer>; + clock-frequency = <400000>; + status = "okay"; + + max96755f@40 { + compatible = "maxim,max96755f"; + reg = <0x40>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_serdes_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + + pinctrl { + compatible = "maxim,max96755f-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_max96755f_pinctrl_hog>; + + i2c6_max96755f_pinctrl_hog: hog { + i2c { + groups = "I2C"; + function = "I2C"; + }; + }; + + + i2c6_max96755f_panel_pins: panel-pins { + bl-pwm { + pins = "MFP18"; + function = "GPIO_TX_0"; + }; + }; + }; + + bridge { + compatible = "maxim,max96755f-bridge"; + lock-gpios = <&gpio1 RK_PA5 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c6_max96755f_in: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c6_max96755f_out: endpoint { + remote-endpoint = <&i2c6_max96755f_panel_in>; + }; + }; + }; + }; + + gmsl@0 { + reg = <0>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + panel@48 { + compatible = "boe,av156fht-l83"; + reg = <0x48>; + backlight = <&i2c6_max96755f_backlight>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_max96755f_panel_pins>; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <20>; + hsync-len = <20>; + hback-porch = <20>; + vfront-porch = <250>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c6_max96755f_panel_in: endpoint { + remote-endpoint = <&i2c6_max96755f_out>; + }; + }; + }; + }; + }; +}; + +&i2c7 { + pinctrl-0 = <&i2c7m3_xfer>; + clock-frequency = <400000>; + status = "disabled"; + + max96745@42 { + compatible = "maxim,max96745"; + reg = <0x42>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_serdes_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + + pinctrl { + compatible = "maxim,max96745-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_max96745_pinctrl_hog>; + + i2c7_max96745_pinctrl_hog: hog { + i2c { + groups = "I2C"; + function = "I2C"; + }; + }; + + i2c7_max96745_panel_pins: panel-pins { + bl-pwm { + pins = "MFP0"; + function = "GPIO_TX_A_0"; + }; + }; + }; + + bridge { + compatible = "maxim,max96745-bridge"; + lock-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c7_max96745_in: endpoint { + remote-endpoint = <&edp1_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c7_max96745_out: endpoint { + remote-endpoint = <&i2c7_max96745_panel_in>; + }; + }; + }; + }; + + gmsl@0 { + reg = <0>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + panel@48 { + compatible = "boe,av156fht-l83"; + reg = <0x48>; + backlight = <&i2c7_max96745_backlight>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_max96745_panel_pins>; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <20>; + hsync-len = <20>; + hback-porch = <20>; + vfront-porch = <250>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c7_max96745_panel_in: endpoint { + remote-endpoint = <&i2c7_max96745_out>; + }; + }; + }; + }; + }; +}; + +&i2c8 { + pinctrl-0 = <&i2c8m2_xfer>; + clock-frequency = <400000>; + status = "disabled"; + + max96745@42 { + compatible = "maxim,max96745"; + reg = <0x42>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_serdes_pins>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + + pinctrl { + compatible = "maxim,max96745-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_max96745_pinctrl_hog>; + + i2c8_max96745_pinctrl_hog: hog { + i2c { + groups = "I2C"; + function = "I2C"; + }; + }; + + i2c8_max96745_panel_pins: panel-pins { + bl-pwm { + pins = "MFP0"; + function = "GPIO_TX_A_0"; + }; + }; + }; + + bridge { + compatible = "maxim,max96745-bridge"; + lock-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c8_max96745_in: endpoint { + remote-endpoint = <&dp1_out>; + }; + }; + + port@1 { + reg = <1>; + + i2c8_max96745_out: endpoint { + remote-endpoint = <&i2c8_max96745_panel_in>; + }; + }; + }; + }; + + gmsl@0 { + reg = <0>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + + panel@48 { + compatible = "boe,av156fht-l83"; + reg = <0x48>; + backlight = <&i2c8_max96745_backlight>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_max96745_panel_pins>; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <20>; + hsync-len = <20>; + hback-porch = <20>; + vfront-porch = <250>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + i2c8_max96745_panel_in: endpoint { + remote-endpoint = <&i2c8_max96745_out>; + }; + }; + }; + }; + }; +}; + +&pinctrl { + serdes { + i2c2_serdes_pins: i2c2-serdes-pins { + rockchip,pins = + <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + i2c4_serdes_pins: i2c4-serdes-pins { + rockchip,pins = + <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + i2c5_serdes_pins: i2c5-serdes-pins { + rockchip,pins = + <0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + i2c6_serdes_pins: i2c6-serdes-pins { + rockchip,pins = + <1 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + i2c7_serdes_pins: i2c7-serdes-pins { + rockchip,pins = + <4 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + i2c8_serdes_pins: i2c8-serdes-pins { + rockchip,pins = + <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm0 { + pinctrl-0 = <&pwm0m2_pins>; + status = "okay"; +}; + +&pwm10 { + pinctrl-0 = <&pwm10m2_pins>; + status = "okay"; +}; + +&pwm11 { + pinctrl-0 = <&pwm11m3_pins>; + status = "okay"; +}; + +&pwm7 { + pinctrl-0 = <&pwm7m0_pins>; + status = "okay"; +}; + +&pwm13 { + pinctrl-0 = <&pwm13m1_pins>; + status = "okay"; +}; + +&pwm14 { + pinctrl-0 = <&pwm14m0_pins>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi new file mode 100644 index 000000000000..1bc6c5e09b83 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi @@ -0,0 +1,2680 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + */ + +/ { + dsi2lvds_backlight1: dsi2lvds_backlight1 { + compatible = "pwm-backlight"; + brightness-levels = < + 0 20 20 21 21 22 22 23 + 23 24 24 25 25 26 26 27 + 27 28 28 29 29 30 30 31 + 31 32 32 33 33 34 34 35 + 35 36 36 37 37 38 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <200>; + }; + + dp2lvds_backlight0: dp2lvds_backlight0 { + compatible = "pwm-backlight"; + brightness-levels = < + 0 20 20 21 21 22 22 23 + 23 24 24 25 25 26 26 27 + 27 28 28 29 29 30 30 31 + 31 32 32 33 33 34 34 35 + 35 36 36 37 37 38 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <200>; + }; + + dp2lvds_backlight1: dp2lvds_backlight1 { + compatible = "pwm-backlight"; + brightness-levels = < + 0 20 20 21 21 22 22 23 + 23 24 24 25 25 26 26 27 + 27 28 28 29 29 30 30 31 + 31 32 32 33 33 34 34 35 + 35 36 36 37 37 38 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <200>; + }; + + edp2lvds_backlight0: edp2lvds_backlight0 { + compatible = "pwm-backlight"; + brightness-levels = < + 0 20 20 21 21 22 22 23 + 23 24 24 25 25 26 26 27 + 27 28 28 29 29 30 30 31 + 31 32 32 33 33 34 34 35 + 35 36 36 37 37 38 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <200>; + }; + + edp2lvds_backlight1: edp2lvds_backlight1 { + compatible = "pwm-backlight"; + brightness-levels = < + 0 20 20 21 21 22 22 23 + 23 24 24 25 25 26 26 27 + 27 28 28 29 29 30 30 31 + 31 32 32 33 33 34 34 35 + 35 36 36 37 37 38 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255 + >; + default-brightness-level = <200>; + }; + + dsi2lvds_panel0 { + compatible = "simple-panel"; + backlight = <&backlight>; + + display-timings { + native-mode = <&dsi2lvds0>; + dsi2lvds0: timing0 { + clock-frequency = <115200000>;//115200000/105573600 + hactive = <1920>; + vactive = <720>; + hfront-porch = <56>; + hsync-len = <32>; + hback-porch = <56>; + vfront-porch = <200>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + panel0_in_i2c2_bu18rl82: endpoint { + remote-endpoint = <&i2c2_bu18rl82_out_panel0>; + }; + }; + }; + }; + + dsi2lvds_panel1 { + compatible = "simple-panel"; + backlight = <&dsi2lvds_backlight1>; + + display-timings { + native-mode = <&dsi2lvds1>; + dsi2lvds1: timing0 { + clock-frequency = <115200000>; + hactive = <1920>; + vactive = <720>; + hfront-porch = <56>; + hsync-len = <32>; + hback-porch = <56>; + vfront-porch = <200>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + panel1_in_i2c6_bu18rl82: endpoint { + remote-endpoint = <&i2c6_bu18rl82_out_panel1>; + }; + }; + }; + }; + + dp2lvds_panel0 { + compatible = "simple-panel"; + backlight = <&dp2lvds_backlight0>; + status = "okay"; + + panel-timing { + clock-frequency = <115200000>; + hactive = <1920>; + vactive = <720>; + hfront-porch = <56>; + hsync-len = <32>; + hback-porch = <56>; + vfront-porch = <200>; + vsync-len = <2>; + vback-porch = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + panel0_in_i2c4_bu18rl82: endpoint { + remote-endpoint = <&i2c4_bu18rl82_out_panel0>; + }; + }; + }; + + dp2lvds_panel1 { + compatible = "simple-panel"; + backlight = <&dp2lvds_backlight1>; + status = "disabled"; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <140>; + hsync-len = <40>; + hback-porch = <100>; + vfront-porch = <15>; + vsync-len = <20>; + vback-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + panel1_in_i2c8_bu18rl82: endpoint { + remote-endpoint = <&i2c8_bu18rl82_out_panel1>; + }; + }; + }; + + edp2lvds_panel0 { + compatible = "simple-panel"; + backlight = <&edp2lvds_backlight0>; + status = "okay"; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <140>; + hsync-len = <40>; + hback-porch = <100>; + vfront-porch = <15>; + vsync-len = <20>; + vback-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + panel0_in_i2c5_bu18rl82: endpoint { + remote-endpoint = <&i2c5_bu18rl82_out_panel0>; + }; + }; + }; + + edp2lvds_panel1 { + compatible = "simple-panel"; + backlight = <&edp2lvds_backlight1>; + status = "disabled"; + + panel-timing { + clock-frequency = <148500000>; + hactive = <1920>; + vactive = <1080>; + hfront-porch = <140>; + hsync-len = <40>; + hback-porch = <100>; + vfront-porch = <15>; + vsync-len = <20>; + vback-porch = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + + port { + panel1_in_i2c7_bu18rl82: endpoint { + remote-endpoint = <&i2c7_bu18rl82_out_panel1>; + }; + }; + }; +}; + +&backlight { + pwms = <&pwm0 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl0_enable_pin>; + enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&dsi2lvds_backlight1 { + pwms = <&pwm13 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl1_enable_pin>; + enable-gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&dp0 { + //split-mode; + force-hpd; + status = "okay"; + + ports { + port@1 { + reg = <1>; + + dp0_out_i2c4_bu18tl82: endpoint { + remote-endpoint = <&i2c4_bu18tl82_in_dp0>; + }; + }; + }; +}; + +&dp0_in_vp0 { + status = "okay"; +}; + +&dp0_in_vp1 { + status = "disabled"; +}; + +&dp0_in_vp2 { + status = "disabled"; +}; + +&dp1 { + force-hpd; + status = "disabled"; + + ports { + port@1 { + reg = <1>; + + dp1_out_i2c8_bu18tl82: endpoint { + remote-endpoint = <&i2c8_bu18tl82_in_dp1>; + }; + }; + }; +}; + +&dp1_in_vp0 { + status = "okay"; +}; + +&dp1_in_vp1 { + status = "disabled"; +}; + +&dp1_in_vp2 { + status = "disabled"; +}; + +&dp2lvds_backlight0 { + pwms = <&pwm10 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl2_enable_pin>; + enable-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&dp2lvds_backlight1 { + pwms = <&pwm14 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl3_enable_pin>; + enable-gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +/* + * mipi_dcphy0 needs to be enabled + * when dsi0 is enabled + */ +&dsi0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dsi0_out_i2c2_bu18tl82: endpoint { + remote-endpoint = <&i2c2_bu18tl82_in_dsi0>; + }; + }; + }; +}; + +&dsi0_in_vp2 { + status = "okay"; +}; + +&dsi0_in_vp3 { + status = "disabled"; +}; + +/* + * mipi_dcphy1 needs to be enabled + * when dsi1 is enabled + */ +&dsi1 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dsi1_out_i2c6_bu18tl82: endpoint { + remote-endpoint = <&i2c6_bu18tl82_in_dsi1>; + }; + }; + }; +}; + +&dsi1_in_vp2 { + status = "disabled"; +}; + +&dsi1_in_vp3 { + status = "okay"; +}; + +&edp0 { + //split-mode; + force-hpd; + status = "okay"; + + ports { + port@1 { + reg = <1>; + + edp0_out_i2c5_bu18tl82: endpoint { + remote-endpoint = <&i2c5_bu18tl82_in_edp0>; + }; + }; + }; +}; + +&edp0_in_vp0 { + status = "disabled"; +}; + +&edp0_in_vp1 { + status = "okay"; +}; + +&edp0_in_vp2 { + status = "disabled"; +}; + +&edp1 { + force-hpd; + status = "disabled"; + + ports { + port@1 { + reg = <1>; + + edp1_out_i2c7_bu18tl82: endpoint { + remote-endpoint = <&i2c7_bu18tl82_in_edp1>; + }; + }; + }; +}; + +&edp1_in_vp0 { + status = "disabled"; +}; + +&edp1_in_vp1 { + status = "okay"; +}; + +&edp1_in_vp2 { + status = "disabled"; +}; + +&edp2lvds_backlight0 { + pwms = <&pwm7 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl4_enable_pin>; + enable-gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&edp2lvds_backlight1 { + pwms = <&pwm11 0 25000 0>; + pinctrl-names = "default"; + pinctrl-0 = <&bl5_enable_pin>; + enable-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&hdmi0 { + status = "disabled"; +}; + +&hdmi1 { + status = "disabled"; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&hdptxphy1 { + status = "okay"; +}; + +&hdptxphy_hdmi0 { + status = "disabled"; +}; + +&hdptxphy_hdmi1 { + status = "disabled"; +}; + +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m4_xfer>; + clock-frequency = <400000>; + + i2c2_bu18tl82: i2c2-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + sel-mipi; + status = "okay"; + + serdes-init-sequence = [ + 0013 0019 + 0014 0008 //014h[3]-lane1 enable + 0021 0008 + 0023 0009 + 0024 0009 + 022b 0038 + 022c 0072 + 022d 0023 //VPLL=75MHZS + //022b 00d8 + //022c 0089 + //022d 003d //VPLL=99MHz (ref26MHz) 4032984*26/1024x1024=99M + 022e 0080 + 027c 0048 + 027d 0048 //i2c addr 0x48 + 0296 0004 + 0297 0009 //CLLTX0_PLL_GAIN 297h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0297 000d //CLLTX0_PLL_GAIN 297h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0018 00a5 + 0019 0069 + 0267 003d + 0268 002c + 0269 002c + 026a 002c + 026b 002c + 0367 003d + 0368 002c + 0369 002c + 036a 002c + 036b 002c + 0018 0000 + 0019 0000 + //002a 0018 //gpio0 input lcd_bl_pwm + //002d 0018 //gpio1 input lcd_pwr_en + + //0030 0018 //gpio2 input lcd_rst + //0033 0018 //gpio3 input tp_rst + //0034 0005 //bypass des gpio3 + //0036 0000 //gpio4 output tp_int + //0037 0006 //bypass des gpio4 + + 02a7 0002 + 02a8 0003 + 02a9 0004 + 02aa 0005 + 0045 0080 + 0046 0007 //1920 + 004b 00d0 + 004c 0002 //720 + 004d 00d0 + 004e 0002 //720 + 0051 0080 + 0052 0007 //1920 + 0053 0024 //CLLCH2_EN 53h[5] 0:1 Clock Tx lane/1:2 Clock Tx lanes + 0054 0080 + 024d 0061 + 0252 0005 + 0274 0030 //I2C slave address of BU18RL82 for accessing via BU18TL82 + 0275 0020 + 0396 0004 + 0397 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.31 Gbps/lane + //0397 000d //CLLTX0_PLL_GAIN 397h[3:2] 1101 2'b11: 2.2~3.60 Gbps/lane + 0061 0003 //CLLTX0 enable CLLTX1 enable + 0060 0003 //CLLTX0/1 RGB data output Enable + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0090 + 0446 00d2 + ]; + + i2c2_bu18tl82_pinctrl: i2c2-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c2_bu18tl82_panel_pins>; + pinctrl-1 = <&i2c2_bu18tl82_panel_pins>; + status = "okay"; + + i2c2_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO4_TO_SER"; + }; + }; + + i2c2_bu18tl82_gpio: i2c2-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c2_bu18tl82_pinctrl 0 160 8>; + }; + }; + + i2c2_bu18tl82_bridge: i2c2-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c2_bu18tl82_in_dsi0: endpoint { + remote-endpoint = <&dsi0_out_i2c2_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c2_bu18tl82_out_i2c2_bu18rl82: endpoint { + remote-endpoint = <&i2c2_bu18rl82_in_i2c2_bu18tl82>; + }; + }; + }; + }; + + i2c2_bu18rl82: i2c2-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + + serdes-init-sequence = [ + 0011 0003 //Clockless Link Receiver Lane-0+ LVDS portA + 0012 0003 //Clockless Link Receiver Lane-1+ LVDS portB + 0013 0000 + 001d 0008 + 001f 0002 //LVDSTX0_REFSEL + 0020 0002 //LVDSTX1_REFSEL + 0031 0048 + 0032 0048 //i2c addr 0x48 + 0423 0000 + 0424 0000 + 0425 0020 + 0426 0080 + //0057 0000 + //0058 0002 + //0057 0000 //rl gpio0 output lcd_bl_pwm + //0058 0002 //bypass ser gpio0 + //005a 0000 //rl gpio1 output lcd_pwr_en + //005b 0003 //bypass ser gpio1 + //005d 0000 //rl gpio2 output lcd_rst + //005e 0004 //bypass ser gpio2 + //0060 0000 //rl gpio3 output tp-rst + //0061 0005 //bypass ser gpio3 + //0063 0018 //rl gpio4 input tp-int + //0064 0006 //bypass ser gpio4 + //0066 0000 //rl gpio5 output + //0067 0001 //set gpio5 high + + 0073 0080 + 0074 0007 //0x0780 = 1920 + 0075 0080 + 0076 0007 //0x0780 = 1920 + 0079 000a //h[3]: dual lvds mode h[1] single lane / dual lane + 007b 00d0 + 007c 0002 //0x02d0 = 720 + 007d 00d0 + 007e 0002 //0x02d0 = 720 + 0081 0003 //01---> Sync OFF + 0082 0010 //Hsync=16clk + 0084 001c //HBP=28clk + 0086 0002 //Vsync=2lines + 0087 0008 //VBP=8lines + 0088 0000 //VSYNC_CHG=0CLK + 0089 0010 //Hsync = 16? + 008b 001c //HFP=28clk? + 008d 0002 //Vsync=2lines? + 008e 0008 //VFP=8line? + 008f 0000 //VSYNC_CHG=0CLK? + 00d0 0040 //[3]FixHtotalEN + 00d8 00c0 + 00d9 0003 //DE=960 + 0429 000a //LVDSTX0_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 045d 0001 + 0529 000a //LVDSTX1_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 055d 0001 + 0091 0003 + 0090 0001 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0090 + 0646 00d2 + ]; + + i2c2_bu18rl82_pinctrl: i2c2-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c2_bu18rl82_panel_pins>; + pinctrl-1 = <&i2c2_bu18rl82_panel_sleep_pins>; + status = "okay"; + + i2c2_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-rst { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO4"; + function = "DES_TO_SER_GPIO3"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c2_bu18rl82_panel_sleep_pins: panel-sleep-pins { + lcd-rst-sleep { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + tp-rst-sleep { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + lcd-otp-pin-sleep { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + }; + + i2c2_bu18rl82_gpio: i2c2-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c2_bu18rl82_pinctrl 0 169 8>; + }; + }; + + i2c2_bu18rl82_bridge: i2c2-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c2_bu18rl82_in_i2c2_bu18tl82: endpoint { + remote-endpoint = <&i2c2_bu18tl82_out_i2c2_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c2_bu18rl82_out_panel0: endpoint { + remote-endpoint = <&panel0_in_i2c2_bu18rl82>; + }; + }; + }; + }; + + himax@48 { + compatible = "himax,hxcommon"; + reg = <0x48>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&touch_gpio_dsi0>; + pinctrl-1 = <&touch_gpio_dsi0>; + himax,location = "himax-touch-dsi0"; + //himax,irq-gpio = <&gpio1 RK_PB0 IRQ_TYPE_EDGE_FALLING>; + himax,rst-gpio = <&i2c2_bu18rl82_gpio 3 GPIO_ACTIVE_LOW>; + himax,panel-coords = <0 1920 0 720>; + himax,display-coords = <0 1920 0 720>; + status = "okay"; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4m2_xfer>; + clock-frequency = <400000>; + status = "okay"; + + i2c4_bu18tl82: i2c4-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + status = "okay"; + + serdes-init-sequence = [ + 0013 001a //013h[3]1-lane1 enable 013h[3] 1-LVDS Receiver Port-A + 0014 000a //014h[3]1-lane1 enable 014h[3] 1-LVDS Receiver Port-B + 0021 0008 + 0023 0009 + 0024 0009 + 022b 0038 + 022c 0072 + 022d 0023 //VPLL=75MHZS + //022b 00d8 + //022c 0089 + //022d 003d //VPLL=99MHz (ref26MHz) 4032984*26/1024x1024=99M + 022e 0080 + ffff 1000 //delay 0x1000us + 027c 0048 + 027d 0048 //i2c addr 0x48 + 0296 0004 + 0297 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.31 Gbps/lane + //0297 000d //CLLTX0_PLL_GAIN 297h[3:2] 1101 2'b11: 2.2~3.60 Gbps/lane + 0018 00a5 + 0019 0069 + 0267 003d + 0268 002c + 0269 002c + 026a 002c + 026b 002c + 0367 003d + 0368 002c + 0369 002c + 036a 002c + 036b 002c + 0018 0000 + 0019 0000 + //002a 0018 //gpio0 input lcd_bl_pwm + //002d 0018 //gpio1 input lcd_pwr_en + + //0030 0018 //gpio2 input lcd_rst + //0033 0018 //gpio3 input tp_rst + //0034 0005 //bypass des gpio3 + //0036 0000 //gpio4 output tp_int + //0037 0006 //bypass des gpio4 + + 02a7 0002 + 02a8 0003 + 02a9 0004 + 02aa 0005 + 0045 0080 + 0046 0007 //1920 + 004b 00d0 + 004c 0002 //720 + 004d 00d0 + 004e 0002 //720 + 0051 0080 + 0052 0007 //1920 + 0053 0064 //0053h[6]1:2 Rx ports CLLCH2_EN 53h[5] 1:2 Clock Tx lanes + 024d 0061 + 0252 0005 + 0274 0030 + 0275 0020 + 0396 0004 + 0397 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0397 000d //CLLTX0_PLL_GAIN 397h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0061 0003 //CLLTX0 enable CLLTX1 enable + 0060 0003 //CLLTX0/1 RGB data output Enable + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0090 //h_blank=144 + 0446 00d2 //v_blank=210 + ]; + + i2c4_bu18tl82_pinctrl: i2c4-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c4_bu18tl82_panel_pins>; + pinctrl-1 = <&i2c4_bu18tl82_panel_pins>; + status = "okay"; + + i2c4_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO4_TO_SER"; + }; + + }; + + i2c4_bu18tl82_gpio: i2c4-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c4_bu18tl82_pinctrl 0 178 8>; + }; + }; + + i2c4_bu18tl82_bridge: i2c4-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c4_bu18tl82_in_dp0: endpoint { + remote-endpoint = <&dp0_out_i2c4_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c4_bu18tl82_out_i2c4_bu18rl82: endpoint { + remote-endpoint = <&i2c4_bu18rl82_in_i2c4_bu18tl82>; + }; + }; + }; + }; + + i2c4_bu18rl82: i2c4-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + + serdes-init-sequence = [ + 0011 0003 //Clockless Link Receiver Lane-0+ LVDS portA + 0012 0003 //Clockless Link Receiver Lane-1+ LVDS portB + 0013 0000 + 001d 0008 + 001f 0002 //LVDSTX0_REFSEL + 0020 0002 //LVDSTX1_REFSEL + 0031 0048 + 0032 0048 //i2c addr 0x48 + 0423 0000 + 0424 0000 + 0425 0020 + 0426 0080 + //0057 0000 + //0058 0002 + //0057 0000 //rl gpio0 output lcd_bl_pwm + //0058 0002 //bypass ser gpio0 + //005a 0000 //rl gpio1 output lcd_pwr_en + //005b 0003 //bypass ser gpio1 + //005d 0000 //rl gpio2 output lcd_rst + //005e 0004 //bypass ser gpio2 + //0060 0000 //rl gpio3 output tp-rst + //0061 0005 //bypass ser gpio3 + //0063 0018 //rl gpio4 input tp-int + //0064 0006 //bypass ser gpio4 + //0066 0000 //rl gpio5 output + //0067 0001 //set gpio5 high + + 0073 0080 + 0074 0007 //0x0780 = 1920 + 0075 0080 + 0076 0007 //0x0780 = 1920 + 0079 000a //h[3]: dual lvds mode h[1] single lane / dual lane + 007b 00d0 + 007c 0002 //0x02d0 = 720 + 007d 00d0 + 007e 0002 //0x02d0 = 720 + 0081 0003 //01---> Sync OFF + 0082 0010 //Hsync=16clk + 0084 001c //HBP=28clk + 0086 0002 //Vsync=2lines + 0087 0008 //VBP=8lines + 0088 0000 //VSYNC_CHG=0CLK + 0089 0010 //Hsync = 16? + 008b 001c //HFP=28clk? + 008d 0002 //Vsync=2lines? + 008e 0008 //VFP=8line? + 008f 0000 //VSYNC_CHG=0CLK? + 00d0 0040 //[3]FixHtotalEN + 00d8 00c0 + 00d9 0003 //DE=960 + 0429 000a //LVDSTX0_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 045d 0001 + 0529 000a //LVDSTX1_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 055d 0001 + 0091 0003 + 0090 0001 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0090 + 0646 00d2 + ]; + + i2c4_bu18rl82_pinctrl: i2c4-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c4_bu18rl82_panel_pins>; + pinctrl-1 = <&i2c4_bu18rl82_panel_sleep_pins>; + status = "okay"; + + i2c4_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-rst { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO4"; + function = "DES_TO_SER_GPIO3"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c4_bu18rl82_panel_sleep_pins: panel-sleep-pins { + lcd-rst-sleep { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + tp-rst-sleep { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + lcd-otp-pin-sleep { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + }; + + i2c4_bu18rl82_gpio: i2c4-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c4_bu18rl82_pinctrl 0 187 8>; + }; + }; + + i2c4_bu18rl82_bridge: i2c4-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c4_bu18rl82_in_i2c4_bu18tl82: endpoint { + remote-endpoint = <&i2c4_bu18tl82_out_i2c4_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c4_bu18rl82_out_panel0: endpoint { + remote-endpoint = <&panel0_in_i2c4_bu18rl82>; + }; + }; + }; + }; + + himax@48 { + compatible = "himax,hxcommon"; + reg = <0x48>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&touch_gpio_dp0>; + pinctrl-1 = <&touch_gpio_dp0>; + himax,location = "himax-touch-dp0"; + himax,irq-gpio = <&gpio3 RK_PC5 IRQ_TYPE_EDGE_FALLING>; + himax,rst-gpio = <&i2c4_bu18rl82_gpio 3 GPIO_ACTIVE_LOW>; + himax,panel-coords = <0 1920 0 720>; + himax,display-coords = <0 1920 0 720>; + status = "okay"; + }; + + lt7911d@2b { + compatible = "lontium,lt7911d-fb-notifier"; + reg = <0x2b>; + reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + status = "okay"; + + i2c5_bu18tl82: i2c5-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + status = "okay"; + + serdes-init-sequence = [ + 0013 001a + 0014 000a + 0021 0008 + 0023 0009 + 0024 0009 + //002a 0018 //gpio0 input lcd_bl_pwm + //002d 0018 //gpio1 input lcd_pwr_en + + //0030 0018 //gpio2 input lcd_rst + //0033 0000 //gpio3 output tp_int + //0034 0005 //bypass des gpio3 + //0036 0018 //gpio4 input tp_rst + //0037 0006 //bypass des gpio4 + 027c 0041 + 027d 0041 + 0045 0080 + 0046 0007 + 004b 0038 + 004c 0004 + 0053 0064 + 022b 0062 + 022c 0027 + 022d 002e + 0274 0030 + 0275 0020 + 0296 0004 + 0297 000d + 02b2 00c8 + 02b4 0001 + 02b8 00ff + 02b9 000f + 02ba 00ff + 02bb 000f + 02be 00ff + 02bf 001f + 02c2 00ff + 02c3 001f + 0396 0004 + 0397 000d + 03b2 00c8 + 03b4 0001 + 03b8 00ff + 03b9 000f + 03ba 00ff + 03bb 000f + 03be 00ff + 03bf 001f + 03c2 00ff + 03c3 001f + 0060 0001 + 0061 0003 + 022e 0080 + 032e 0080 + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0019 + 0445 0020 + 0446 001f + ]; + + i2c5_bu18tl82_pinctrl: i2c5-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c5_bu18tl82_panel_pins>; + pinctrl-1 = <&i2c5_bu18tl82_panel_pins>; + status = "okay"; + + i2c5_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO3_TO_SER"; + }; + }; + + + i2c5_bu18tl82_gpio: i2c5-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c5_bu18tl82_pinctrl 0 196 8>; + }; + }; + + i2c5_bu18tl82_bridge: i2c5-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c5_bu18tl82_in_edp0: endpoint { + remote-endpoint = <&edp0_out_i2c5_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c5_bu18tl82_out_i2c5_bu18rl82: endpoint { + remote-endpoint = <&i2c5_bu18rl82_in_i2c5_bu18tl82>; + }; + }; + }; + }; + + i2c5_bu18rl82: i2c5-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + + serdes-init-sequence = [ + 0011 000b + 0012 0003 + 0013 0001 + 001d 0008 + 001f 0002 + 0020 0002 + 0031 0041 //i2c addr 0x41 + 0032 0041 //i2c addr 0x41 + //0057 0000 //rl gpio0 output lcd_bl_pwm + //0058 0002 //bypass ser gpio0 + //005a 0000 //rl gpio1 output lcd_pwr_en + //005b 0001 //bypass ser gpio1 + //005d 0000 //rl gpio2 output lcd_rst + //005e 0004 //bypass ser gpio2 + //0060 0018 //rl gpio3 input tp-int + //042e 0005 //bypass ser gpio3 + //0061 0005 //bypass ser gpio3 + //0063 0000 //rl gpio4 output tp-rst + //042f 0006 //bypass ser gpio4 + //0064 0006 //bypass ser gpio4 + //0066 0000 //rl gpio5 output + //0067 0007 //bypass ser gpio5 + 0073 0080 + 0074 0007 + 0079 000a + 007b 0038 + 007c 0004 + 0081 0003 + 0082 0010 + 0084 0020 + 0086 0002 + 0087 0002 + 0088 0010 + 0089 0010 + 008b 0020 + 008d 0002 + 008e 0002 + 008f 0010 + 00d0 0040 + 00d8 0042 + 00d9 0004 + 0423 0002 + 0424 00ec + 0425 0027 + 0429 000a + 045d 0001 + 0529 000a + 055d 0003 + 0090 0001 + 0091 0003 + 0426 0080 + 042d 0004 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0019 + 0645 0020 + 0646 001f + ]; + + i2c5_bu18rl82_pinctrl: i2c5-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c5_bu18rl82_panel_pins>; + pinctrl-1 = <&i2c5_bu18rl82_panel_sleep_pins>; + status = "okay"; + + i2c5_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO3"; + function = "DES_TO_SER_GPIO3"; + }; + + tp-rst { + pins = "BU18RL82_GPIO4"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c5_bu18rl82_panel_sleep_pins: panel-sleep-pins { + lcd-rst-sleep { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + tp-rst-sleep { + pins = "BU18RL82_GPIO4"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + lcd-otp-pin-sleep { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + }; + + i2c5_bu18rl82_gpio: i2c5-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c5_bu18rl82_pinctrl 0 205 8>; + }; + }; + + i2c5_bu18rl82_bridge: i2c5-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c5_bu18rl82_in_i2c5_bu18tl82: endpoint { + remote-endpoint = <&i2c5_bu18tl82_out_i2c5_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c5_bu18rl82_out_panel0: endpoint { + remote-endpoint = <&panel0_in_i2c5_bu18rl82>; + }; + }; + }; + }; + + ilitek@41 { + compatible = "ilitek,ili251x"; + reg = <0x41>; + interrupt-parent = <&gpio1>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&touch_gpio_edp0>; + //reset-gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_LOW>; + ilitek,name = "ilitek_i2c"; + status = "okay"; + }; + + lt7911d@2b { + compatible = "lontium,lt7911d-fb-notifier"; + reg = <0x2b>; + reset-gpios = <&gpio0 RK_PD2 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&i2c6 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m3_xfer>; + clock-frequency = <400000>; + + i2c6_bu18tl82: i2c6-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + sel-mipi; + status = "okay"; + + serdes-init-sequence = [ + 0013 0019 + 0014 0008 //014h[3]-lane1 enable + 0021 0008 + 0023 0009 + 0024 0009 + 022b 0038 + 022c 0072 + 022d 0023 //VPLL=75MHZS + //022b 00d8 + //022c 0089 + //022d 003d //VPLL=99MHz (ref26MHz) 4032984*26/1024x1024=99M + 022e 0080 + 027c 0048 + 027d 0048 //i2c addr 0x48 + 0296 0004 + 0297 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0297 000d //CLLTX0_PLL_GAIN 297h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0018 00a5 + 0019 0069 + 0267 003d + 0268 002c + 0269 002c + 026a 002c + 026b 002c + 0367 003d + 0368 002c + 0369 002c + 036a 002c + 036b 002c + 0018 0000 + 0019 0000 + //002a 0018 //gpio0 input lcd_bl_pwm + //002d 0018 //gpio1 input lcd_pwr_en + + //0030 0018 //gpio2 input lcd_rst + //0033 0018 //gpio3 input tp_rst + //0034 0005 //bypass des gpio3 + //0036 0000 //gpio4 output tp_int + //0037 0006 //bypass des gpio4 + + 02a7 0002 + 02a8 0003 + 02a9 0004 + 02aa 0005 + 0045 0080 + 0046 0007 //1920 + 004b 00d0 + 004c 0002 //720 + 004d 00d0 + 004e 0002 //720 + 0051 0080 + 0052 0007 //1920 + 0053 0024 //CLLCH2_EN 53h[5] 0:1 Clock Tx lane/1:2 Clock Tx lanes + 0054 0080 + 024d 0061 + 0252 0005 + 0274 0030 + 0275 0020 + 0396 0004 + 0397 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0397 000d //CLLTX0_PLL_GAIN 397h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0061 0003 //CLLTX0 enable CLLTX1 enable + 0060 0003 //CLLTX0/1 RGB data output Enable + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0090 //h_blank=144 + 0446 00d2 //v_blank=210 + + + ]; + + i2c6_bu18tl82_pinctrl: i2c6-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c6_bu18tl82_panel_pins>; + pinctrl-1 = <&i2c6_bu18tl82_panel_pins>; + status = "okay"; + + i2c6_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO4_TO_SER"; + }; + }; + + + i2c6_bu18tl82_gpio: i2c6-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c6_bu18tl82_pinctrl 0 214 8>; + }; + }; + + i2c6_bu18tl82_bridge: i2c6-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c6_bu18tl82_in_dsi1: endpoint { + remote-endpoint = <&dsi1_out_i2c6_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c6_bu18tl82_out_i2c6_bu18rl82: endpoint { + remote-endpoint = <&i2c6_bu18rl82_in_i2c6_bu18tl82>; + }; + }; + }; + }; + + i2c6_bu18rl82: i2c6-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + + serdes-init-sequence = [ + 0011 0003 //Clockless Link Receiver Lane-0+ LVDS portA + 0012 0003 //Clockless Link Receiver Lane-1+ LVDS portB + 0013 0000 + 001d 0008 + 001f 0002 //LVDSTX0_REFSEL + 0020 0002 //LVDSTX1_REFSEL + 0031 0048 + 0032 0048 //i2c addr 0x48 + 0423 0000 + 0424 0000 + 0425 0020 + 0426 0080 + //0057 0000 + //0058 0002 + //0057 0000 //rl gpio0 output lcd_bl_pwm + //0058 0002 //bypass ser gpio0 + //005a 0000 //rl gpio1 output lcd_pwr_en + //005b 0003 //bypass ser gpio1 + //005d 0000 //rl gpio2 output lcd_rst + //005e 0004 //bypass ser gpio2 + //0060 0000 //rl gpio3 output tp-rst + //0061 0005 //bypass ser gpio3 + //0063 0018 //rl gpio4 input tp-int + //0064 0006 //bypass ser gpio4 + //0066 0000 //rl gpio5 output + //0067 0001 //set gpio5 high + + 0073 0080 + 0074 0007 //0x0780 = 1920 + 0075 0080 + 0076 0007 //0x0780 = 1920 + 0079 000a //h[3]: dual lvds mode h[1] single lane / dual lane + 007b 00d0 + 007c 0002 //0x02d0 = 720 + 007d 00d0 + 007e 0002 //0x02d0 = 720 + 0081 0003 //01---> Sync OFF + 0082 0010 //Hsync=16clk + 0084 001c //HBP=28clk + 0086 0002 //Vsync=2lines + 0087 0008 //VBP=8lines + 0088 0000 //VSYNC_CHG=0CLK + 0089 0010 //Hsync = 16? + 008b 001c //HFP=28clk? + 008d 0002 //Vsync=2lines? + 008e 0008 //VFP=8line? + 008f 0000 //VSYNC_CHG=0CLK? + 00d0 0040 //[3]FixHtotalEN + 00d8 00c0 + 00d9 0003 //DE=960 + 0429 000a //LVDSTX0_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 045d 0001 + 0529 000a //LVDSTX1_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 055d 0001 + 0091 0003 + 0090 0001 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0090 + 0646 00d2 + ]; + + i2c6_bu18rl82_pinctrl: i2c6-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default","sleep"; + pinctrl-0 = <&i2c6_bu18rl82_panel_pins>; + pinctrl-1 = <&i2c6_bu18rl82_panel_sleep_pins>; + status = "okay"; + + i2c6_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-rst { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO4"; + function = "DES_TO_SER_GPIO3"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c6_bu18rl82_panel_sleep_pins: panel-sleep-pins { + lcd-rst-sleep { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + tp-rst-sleep { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + + lcd-otp-pin-sleep { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_LOW"; + }; + }; + + i2c6_bu18rl82_gpio: i2c6-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c6_bu18rl82_pinctrl 0 223 8>; + }; + }; + + i2c6_bu18rl82_bridge: i2c6-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c6_bu18rl82_in_i2c6_bu18tl82: endpoint { + remote-endpoint = <&i2c6_bu18tl82_out_i2c6_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c6_bu18rl82_out_panel1: endpoint { + remote-endpoint = <&panel1_in_i2c6_bu18rl82>; + }; + }; + }; + }; + + himax@48 { + compatible = "himax,hxcommon"; + reg = <0x48>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&touch_gpio_dsi1>; + pinctrl-1 = <&touch_gpio_dsi1>; + himax,location = "himax-touch-dsi1"; + himax,irq-gpio = <&gpio1 RK_PB7 IRQ_TYPE_EDGE_FALLING>; + himax,rst-gpio = <&i2c6_bu18rl82_gpio 3 GPIO_ACTIVE_LOW>; + himax,panel-coords = <0 1920 0 720>; + himax,display-coords = <0 1920 0 720>; + status = "okay"; + }; +}; + +&i2c7 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c7m3_xfer>; + clock-frequency = <400000>; + status = "disabled"; + + i2c7_bu18tl82: i2c7-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + status = "okay"; + + serdes-init-sequence = [ + 0013 001a + 0014 000a + 0021 0008 + 0023 0009 + 0024 0009 + 002a 0018 //gpio0 input lcd_bl_pwm + 002d 0018 //gpio1 input lcd_pwr_en + + 0030 0018 //gpio2 input lcd_rst + 0033 0000 //gpio3 output tp_int + 0034 0005 //bypass des gpio3 + 0036 0018 //gpio4 input tp_rst + 0037 0006 //bypass des gpio4 + 027c 0041 + 027d 0041 + 0045 0080 + 0046 0007 + 004b 0038 + 004c 0004 + 0053 0064 + 022b 0062 + 022c 0027 + 022d 002e + 0274 0030 + 0275 0020 + 0296 0004 + 0297 000d + 02b2 00c8 + 02b4 0001 + 02b8 00ff + 02b9 000f + 02ba 00ff + 02bb 000f + 02be 00ff + 02bf 001f + 02c2 00ff + 02c3 001f + 0396 0004 + 0397 000d + 03b2 00c8 + 03b4 0001 + 03b8 00ff + 03b9 000f + 03ba 00ff + 03bb 000f + 03be 00ff + 03bf 001f + 03c2 00ff + 03c3 001f + 0060 0001 + 0061 0003 + 022e 0080 + 032e 0080 + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0019 + 0445 0020 + 0446 001f + ]; + + i2c7_bu18tl82_pinctrl: i2c7-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_bu18tl82_panel_pins>; + status = "okay"; + + i2c7_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO4_TO_SER"; + }; + }; + + + i2c7_bu18tl82_gpio: i2c7-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c7_bu18tl82_pinctrl 0 232 8>; + }; + }; + + i2c7_bu18tl82_bridge: i2c7-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c7_bu18tl82_in_edp1: endpoint { + remote-endpoint = <&edp1_out_i2c7_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c7_bu18tl82_out_i2c7_bu18rl82: endpoint { + remote-endpoint = <&i2c7_bu18rl82_in_i2c7_bu18tl82>; + }; + }; + }; + }; + + i2c7_bu18rl82: i2c7-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + serdes-init-sequence = [ + 0011 000b + 0012 0003 + 0013 0001 + 001d 0008 + 001f 0002 + 0020 0002 + 0031 0041 //i2c addr 0x41 + 0032 0041 //i2c addr 0x41 + 0057 0000 //rl gpio0 output lcd_bl_pwm + 0058 0002 //bypass ser gpio0 + 005a 0000 //rl gpio1 output lcd_pwr_en + 005b 0001 //bypass ser gpio1 + 005d 0000 //rl gpio2 output lcd_rst + 005e 0004 //bypass ser gpio2 + 0060 0018 //rl gpio3 input tp-int + 042e 0005 //bypass ser gpio3 + 0061 0005 //bypass ser gpio3 + 0063 0000 //rl gpio4 output tp-rst + 0064 0006 //bypass ser gpio4 + 0066 0000 //rl gpio5 output + 0067 0007 //bypass ser gpio5 + 0073 0080 + 0074 0007 + 0079 000a + 007b 0038 + 007c 0004 + 0081 0003 + 0082 0010 + 0084 0020 + 0086 0002 + 0087 0002 + 0088 0010 + 0089 0010 + 008b 0020 + 008d 0002 + 008e 0002 + 008f 0010 + 00d0 0040 + 00d8 0042 + 00d9 0004 + 0423 0002 + 0424 00ec + 0425 0027 + 0429 000a + 045d 0001 + 0529 000a + 055d 0003 + 0090 0001 + 0091 0003 + 0426 0080 + 042d 0004 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0019 + 0645 0020 + 0646 001f + ]; + i2c7_bu18rl82_pinctrl: i2c7-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_bu18rl82_panel_pins>; + status = "okay"; + + i2c7_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-rst { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO4"; + function = "DES_TO_SER_GPIO3"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c7_bu18rl82_gpio: i2c7-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c7_bu18rl82_pinctrl 0 241 8>; + }; + }; + + i2c7_bu18rl82_bridge: i2c7-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c7_bu18rl82_in_i2c7_bu18tl82: endpoint { + remote-endpoint = <&i2c7_bu18tl82_out_i2c7_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c7_bu18rl82_out_panel1: endpoint { + remote-endpoint = <&panel1_in_i2c7_bu18rl82>; + }; + }; + }; + }; + + lt7911d@2b { + compatible = "lontium,lt7911d-fb-notifier"; + reg = <0x2b>; + reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&i2c8 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c8m2_xfer>; + clock-frequency = <400000>; + status = "disabled"; + + i2c8_bu18tl82: i2c8-bu18tl82@10 { + compatible = "rohm,bu18tl82"; + reg = <0x10>; + status = "okay"; + + serdes-init-sequence = [ + 0013 001a //013h[3]1-lane1 enable 013h[3] 1-LVDS Receiver Port-A + 0014 000a //014h[3]1-lane1 enable 014h[3] 1-LVDS Receiver Port-B + 0021 0008 + 0023 0009 + 0024 0009 + 022b 0038 + 022c 0072 + 022d 0023 //VPLL=75MHZS + //022b 00d8 + //022c 0089 + //022d 003d //VPLL=99MHz (ref26MHz) 4032984*26/1024x1024=99M + 022e 0080 + 027c 0048 + 027d 0048 //i2c addr 0x48 + 0296 0004 + 0297 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0297 000d //CLLTX0_PLL_GAIN 297h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0018 00a5 + 0019 0069 + 0267 003d + 0268 002c + 0269 002c + 026a 002c + 026b 002c + 0367 003d + 0368 002c + 0369 002c + 036a 002c + 036b 002c + 0018 0000 + 0019 0000 + 002a 0018 //gpio0 input lcd_bl_pwm + 002d 0018 //gpio1 input lcd_pwr_en + + 0030 0018 //gpio2 input lcd_rst + 0033 0018 //gpio3 input tp_rst + 0034 0005 //bypass des gpio3 + 0036 0000 //gpio4 output tp_int + 0037 0006 //bypass des gpio4 + + 02a7 0002 + 02a8 0003 + 02a9 0004 + 02aa 0005 + 0045 0080 + 0046 0007 //1920 + 004b 00d0 + 004c 0002 //720 + 004d 00d0 + 004e 0002 //720 + 0051 0080 + 0052 0007 //1920 + 0053 0064 //0053h[6]1:2 Rx ports CLLCH2_EN 53h[5] 1:2 Clock Tx lanes + 024d 0061 + 0252 0005 + 0274 0030 + 0275 0020 + 0396 0004 + 0397 0009 //CLLTX0_PLL_GAIN 397h[3:2] 1001 2'b10: 1.2~2.3 Gbps/lane + //0397 000d //CLLTX0_PLL_GAIN 397h[3:2] 1101 2'b11: 2.2~3.6 Gbps/lane + 0061 0003 //CLLTX0 enable CLLTX1 enable + 0060 0003 //CLLTX0/1 RGB data output Enable + /* TL82 Pattern Gen Set 1 + * Horizontal Gray Scale 256 steps + */ + 040A 0010 + 040B 0080 + 040C 0080 + 040D 0080 + 0444 0090 //h_blank=144 + 0446 00d2 //v_blank=210 + ]; + i2c8_bu18tl82_pinctrl: i2c8-bu18tl82-pinctrl { + compatible = "rohm,bu18tl82-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_bu18tl82_panel_pins>; + status = "okay"; + + i2c8_bu18tl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18TL82_GPIO0"; + function = "SER_TO_DES_GPIO0"; + }; + + lcd-pwr-en { + pins = "BU18TL82_GPIO1"; + function = "SER_TO_DES_GPIO1"; + }; + + ser-irq { + pins = "BU18TL82_GPIO2"; + function = "DES_GPIO2_TO_SER"; + }; + + tp-int { + pins = "BU18TL82_GPIO3"; + function = "DES_GPIO4_TO_SER"; + }; + }; + + + i2c8_bu18tl82_gpio: i2c8-bu18tl82-gpio { + compatible = "rohm,bu18tl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c8_bu18tl82_pinctrl 0 250 8>; + }; + }; + + i2c8_bu18tl82_bridge: i2c8-bu18tl82-bridge { + compatible = "rohm,bu18tl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c8_bu18tl82_in_dp1: endpoint { + remote-endpoint = <&dp1_out_i2c8_bu18tl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c8_bu18tl82_out_i2c8_bu18rl82: endpoint { + remote-endpoint = <&i2c8_bu18rl82_in_i2c8_bu18tl82>; + }; + }; + }; + }; + + i2c8_bu18rl82: i2c8-bu18rl82@30 { + compatible = "rohm,bu18rl82"; + reg = <0x30>; + status = "okay"; + serdes-init-sequence = [ + 0011 0003 //Clockless Link Receiver Lane-0+ LVDS portA + 0012 0003 //Clockless Link Receiver Lane-1+ LVDS portB + 0013 0000 + 001d 0008 + 001f 0002 //LVDSTX0_REFSEL + 0020 0002 //LVDSTX1_REFSEL + 0031 0048 + 0032 0048 //i2c addr 0x48 + 0423 0000 + 0424 0000 + 0425 0020 + 0426 0080 + 0057 0000 + 0058 0002 + 0057 0000 //rl gpio0 output lcd_bl_pwm + 0058 0002 //bypass ser gpio0 + 005a 0000 //rl gpio1 output lcd_pwr_en + 005b 0003 //bypass ser gpio1 + 005d 0000 //rl gpio2 output lcd_rst + 005e 0004 //bypass ser gpio2 + 0060 0000 //rl gpio3 output tp-rst + 0061 0005 //bypass ser gpio3 + 0063 0018 //rl gpio4 input tp-int + 0064 0006 //bypass ser gpio4 + 0066 0000 //rl gpio5 output + 0067 0001 //set gpio5 high + + 0073 0080 + 0074 0007 //0x0780 = 1920 + 0075 0080 + 0076 0007 //0x0780 = 1920 + 0079 000a //h[3]: dual lvds mode h[1] single lane / dual lane + 007b 00d0 + 007c 0002 //0x02d0 = 720 + 007d 00d0 + 007e 0002 //0x02d0 = 720 + 0081 0003 //01---> Sync OFF + 0082 0010 //Hsync=16clk + 0084 001c //HBP=28clk + 0086 0002 //Vsync=2lines + 0087 0008 //VBP=8lines + 0088 0000 //VSYNC_CHG=0CLK + 0089 0010 //Hsync = 16? + 008b 001c //HFP=28clk? + 008d 0002 //Vsync=2lines? + 008e 0008 //VFP=8line? + 008f 0000 //VSYNC_CHG=0CLK? + 00d0 0040 //[3]FixHtotalEN + 00d8 00c0 + 00d9 0003 //DE=960 + 0429 000a //LVDSTX0_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 045d 0001 + 0529 000a //LVDSTX1_PLLGAIN 2'b10: 30 MHz ~ 80 MHz + 055d 0001 + 0091 0003 + 0090 0001 + /* RL82 Pattern Gen Set + * Vertical Gray Scale Color Bar + */ + 060A 00B0 + 060B 00FF + 060C 00FF + 060D 00FF + 0644 0090 + 0646 00d2 + ]; + i2c8_bu18rl82_pinctrl: i2c8-bu18rl82-pinctrl { + compatible = "rohm,bu18rl82-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c8_bu18rl82_panel_pins>; + status = "okay"; + + i2c8_bu18rl82_panel_pins: panel-pins { + lcd-bl-pwm { + pins = "BU18RL82_GPIO0"; + function = "SER_GPIO0_TO_DES"; + }; + + lcd-pwr-en { + pins = "BU18RL82_GPIO1"; + function = "SER_GPIO1_TO_DES"; + }; + + lcd-rst { + pins = "BU18RL82_GPIO2"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-rst { + pins = "BU18RL82_GPIO3"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + + tp-int { + pins = "BU18RL82_GPIO4"; + function = "DES_TO_SER_GPIO3"; + }; + + lcd-otp-pin { + pins = "BU18RL82_GPIO5"; + function = "DES_GPIO_OUTPUT_HIGH"; + }; + }; + + i2c8_bu18rl82_gpio: i2c8-bu18rl82-gpio { + compatible = "rohm,bu18rl82-gpio"; + status = "okay"; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&i2c8_bu18rl82_pinctrl 0 259 8>; + }; + }; + + i2c8_bu18rl82_bridge: i2c8-bu18rl82-bridge { + compatible = "rohm,bu18rl82-bridge"; + status = "okay"; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2c8_bu18rl82_in_i2c8_bu18tl82: endpoint { + remote-endpoint = <&i2c8_bu18tl82_out_i2c8_bu18rl82>; + }; + }; + + port@1 { + reg = <1>; + + i2c8_bu18rl82_out_panel1: endpoint { + remote-endpoint = <&panel1_in_i2c8_bu18rl82>; + }; + }; + }; + }; + + lt7911d@2b { + compatible = "lontium,lt7911d-fb-notifier"; + reg = <0x2b>; + reset-gpios = <&gpio3 RK_PD2 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&mipi_dcphy0 { + status = "okay"; +}; + +&mipi_dcphy1 { + status = "okay"; +}; + +/* dsi0->serdes->lvds_panel */ +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0m2_pins>; +}; + +/* dp0->serdes->lvds_panel */ +&pwm10 { + pinctrl-0 = <&pwm10m2_pins>; + status = "okay"; +}; + +/* edp1->serdes->lvds_panel */ +&pwm11 { + pinctrl-0 = <&pwm11m3_pins>; + status = "okay"; +}; + +/* edp0->serdes->lvds_panel */ +&pwm7 { + pinctrl-0 = <&pwm7m0_pins>; + status = "okay"; +}; + +/* dsi1->serdes->lvds_panel */ +&pwm13 { + status = "okay"; + pinctrl-0 = <&pwm13m1_pins>; +}; + +/* dp1->serdes->lvds_panel */ +&pwm14 { + pinctrl-0 = <&pwm14m0_pins>; + status = "okay"; +}; + +&route_dp0 { + status = "disabled"; + connect = <&vp0_out_dp0>; + logo,uboot = "logo34.bmp"; + logo,kernel = "logo34.bmp"; +}; + +&route_dp1 { + status = "disabled"; + connect = <&vp0_out_dp1>; + logo,uboot = "logo34.bmp"; + logo,kernel = "logo34.bmp"; +}; + +&route_dsi0 { + status = "disabled"; + connect = <&vp2_out_dsi0>; + logo,uboot = "logo1.bmp"; + logo,kernel = "logo1.bmp"; +}; + +&route_dsi1 { + status = "disabled"; + connect = <&vp3_out_dsi1>; + logo,uboot = "logo2.bmp"; + logo,kernel = "logo2.bmp"; +}; + +&route_edp0 { + status = "disabled"; + connect = <&vp1_out_edp0>; + logo,uboot = "logo56.bmp"; + logo,kernel = "logo56.bmp"; +}; + +&route_edp1 { + status = "disabled"; + connect = <&vp1_out_edp1>; + logo,uboot = "logo56.bmp"; + logo,kernel = "logo56.bmp"; +}; + +&usbdp_phy0 { + rockchip,dp-lane-mux = <0 1 2 3>; + status = "okay"; +}; + +&usbdp_phy1 { + rockchip,dp-lane-mux = <0 1 2 3>; + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru PLL_V0PLL>; + assigned-clock-rates = <1152000000>; +}; + +&vp0 { + assigned-clocks = <&cru DCLK_VOP0_SRC>; + assigned-clock-parents = <&cru PLL_V0PLL>; +}; + +&vp1 { + assigned-clocks = <&cru DCLK_VOP1_SRC>; + assigned-clock-parents = <&cru PLL_GPLL>; +}; + +&vp2 { + assigned-clocks = <&cru DCLK_VOP2_SRC>; + assigned-clock-parents = <&cru PLL_V0PLL>; +}; + +&vp3 { + assigned-clocks = <&cru DCLK_VOP3>; + assigned-clock-parents = <&cru PLL_V0PLL>; +}; diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index b23d2006bb64..7fb766e2bbd1 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -693,6 +693,7 @@ CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_I2S=y CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES=y +CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y CONFIG_SND_SOC_ROCKCHIP_PDM=y CONFIG_SND_SOC_ROCKCHIP_SAI=y CONFIG_SND_SOC_ROCKCHIP_SPDIF=y diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index ca903a37e024..9e94d63ee4b5 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -389,6 +389,7 @@ CONFIG_SND_USB_AUDIO=y CONFIG_SND_SOC=y CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y +CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y CONFIG_SND_SOC_ROCKCHIP_PDM=y CONFIG_SND_SOC_ROCKCHIP_SAI=y CONFIG_SND_SOC_ROCKCHIP_SPDIF=y diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 0bc38150066c..0ff9bd2fa5e7 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -3186,6 +3186,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) struct resource *res; int i, ret, irq; int num_chan; + int val; struct device_node *np = adev->dev.of_node; ret = dma_set_mask_and_coherent(&adev->dev, DMA_BIT_MASK(32)); @@ -3200,7 +3201,12 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pd = &pl330->ddma; pd->dev = &adev->dev; - pl330->mcbufsz = 0; + if (!device_property_read_u32(&adev->dev, "arm,pl330-mcbufsz-bytes", &val)) { + if ((val > 0) && (val <= PAGE_SIZE)) + pl330->mcbufsz = val; + + dev_info(&adev->dev, "mcbufsz: %d bytes\n", pl330->mcbufsz); + } /* get quirk */ for (i = 0; i < ARRAY_SIZE(of_quirks); i++) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 6b40725bec92..c1c0af33e51b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1056,6 +1056,14 @@ config GPIO_MAX732X_IRQ Say yes here to enable the max732x to be used as an interrupt controller. It requires the driver to be built in the kernel. +config GPIO_NCA9539 + tristate "NCA9539 I2C GPIO expander" + depends on I2C || COMPILE_TEST + select REGMAP_I2C + help + Say yes here to support the NCA9539 series of I2C Expanders. + GPIO expanders used for additional digital outputs or inputs. + config GPIO_PCA953X tristate "PCA95[357]x, PCA9698, TCA64xx, and MAX7310 I/O ports" select REGMAP_I2C diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index f99f02442d36..76445d0fb22a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_GPIO_MT7621) += gpio-mt7621.o obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o +obj-$(CONFIG_GPIO_NCA9539) += gpio-nca9539.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o diff --git a/drivers/gpio/gpio-nca9539.c b/drivers/gpio/gpio-nca9539.c new file mode 100644 index 000000000000..50fff6d90ddd --- /dev/null +++ b/drivers/gpio/gpio-nca9539.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * NCA9539 I2C Port Expander I/O + * + * Copyright (C) 2023 Cody Xie + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NCA9539_REG_INPUT_PORT_BASE 0x00 +#define NCA9539_REG_INPUT_PORT0 (NCA9539_REG_INPUT_PORT_BASE + 0x0) +#define NCA9539_REG_INPUT_PORT1 (NCA9539_REG_INPUT_PORT_BASE + 0x1) +#define NCA9539_REG_OUTPUT_PORT_BASE 0x02 +#define NCA9539_REG_OUTPUT_PORT0 (NCA9539_REG_OUTPUT_PORT_BASE + 0x0) +#define NCA9539_REG_OUTPUT_PORT1 (NCA9539_REG_OUTPUT_PORT_BASE + 0x1) +#define NCA9539_REG_POLARITY_BASE 0x04 +#define NCA9539_REG_POLARITY_PORT0 (NCA9539_REG_POLARITY_BASE + 0x0) +#define NCA9539_REG_POLARITY_PORT1 (NCA9539_REG_POLARITY_BASE + 0x1) +#define NCA9539_REG_CONFIG_BASE 0x06 +#define NCA9539_REG_CONFIG_PORT0 (NCA9539_REG_CONFIG_BASE + 0x0) +#define NCA9539_REG_CONFIG_PORT1 (NCA9539_REG_CONFIG_BASE + 0x1) + +struct nca9539_chip { + struct gpio_chip gpio_chip; + struct regmap *regmap; + struct regulator *regulator; + unsigned int ngpio; +}; + +static int nca9539_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + struct nca9539_chip *priv = gpiochip_get_data(gc); + unsigned int port = offset / 8; + unsigned int pin = offset % 8; + unsigned int value; + int ret; + + dev_dbg(gc->parent, "%s offset(%d)", __func__, offset); + ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value); + if (ret < 0) { + dev_err(gc->parent, "%s offset(%d) read config failed", + __func__, offset); + return ret; + } + + if (value & BIT(pin)) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + +static int nca9539_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) +{ + struct nca9539_chip *priv = gpiochip_get_data(gc); + unsigned int port = offset / 8; + unsigned int pin = offset % 8; + int ret; + + dev_dbg(gc->parent, "%s offset(%d)", __func__, offset); + ret = regmap_update_bits(priv->regmap, NCA9539_REG_CONFIG_BASE + port, + BIT(pin), BIT(pin)); + if (ret < 0) { + dev_err(gc->parent, "%s offset(%d) read config failed", + __func__, offset); + } + + return ret; +} + +static int nca9539_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, + int val) +{ + struct nca9539_chip *priv = gpiochip_get_data(gc); + unsigned int port = offset / 8; + unsigned int pin = offset % 8; + int ret; + + dev_dbg(gc->parent, "%s offset(%d) val(%d)", __func__, offset, val); + ret = regmap_update_bits(priv->regmap, NCA9539_REG_CONFIG_BASE + port, + BIT(pin), 0); + if (ret < 0) { + dev_err(gc->parent, + "%s offset(%d) val(%d) update config failed", __func__, + offset, val); + return ret; + } + + ret = regmap_update_bits(priv->regmap, + NCA9539_REG_OUTPUT_PORT_BASE + port, BIT(pin), + val ? BIT(pin) : 0); + if (ret < 0) { + dev_err(gc->parent, + "%s offset(%d) val(%d) update output failed", __func__, + offset, val); + return ret; + } + + return ret; +} + +static int nca9539_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct nca9539_chip *priv = gpiochip_get_data(gc); + unsigned int port = offset / 8; + unsigned int pin = offset % 8; + unsigned int reg; + unsigned int value; + int ret; + + dev_dbg(gc->parent, "%s offset(%d)", __func__, offset); + ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value); + if (ret < 0) { + dev_err(gc->parent, "%s offset(%d) check config failed", + __func__, offset); + return ret; + } + if (!(BIT(pin) & value)) + reg = NCA9539_REG_OUTPUT_PORT_BASE + port; + else + reg = NCA9539_REG_INPUT_PORT_BASE + port; + ret = regmap_read(priv->regmap, reg, &value); + if (ret < 0) { + dev_err(gc->parent, "%s offset(%d) read value failed", __func__, + offset); + return -EIO; + } + + return !!(BIT(pin) & value); +} + +static void nca9539_gpio_set(struct gpio_chip *gc, unsigned int offset, int val) +{ + struct nca9539_chip *priv = gpiochip_get_data(gc); + unsigned int port = offset / 8; + unsigned int pin = offset % 8; + unsigned int value; + int ret; + + dev_dbg(gc->parent, "%s offset(%d) val(%d)", __func__, offset, val); + ret = regmap_read(priv->regmap, NCA9539_REG_CONFIG_BASE + port, &value); + if (ret < 0 || !!(BIT(pin) & value)) { + dev_err(gc->parent, "%s offset(%d) val(%d) check config failed", + __func__, offset, val); + } + + ret = regmap_update_bits(priv->regmap, + NCA9539_REG_OUTPUT_PORT_BASE + port, BIT(pin), + val ? BIT(pin) : 0); + if (ret < 0) { + dev_err(gc->parent, "%s offset(%d) val(%d) read input failed", + __func__, offset, val); + } +} + +static bool nca9539_is_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case NCA9539_REG_OUTPUT_PORT0: + case NCA9539_REG_OUTPUT_PORT1: + case NCA9539_REG_POLARITY_PORT0: + case NCA9539_REG_POLARITY_PORT1: + case NCA9539_REG_CONFIG_PORT0: + case NCA9539_REG_CONFIG_PORT1: + return true; + } + return false; +} + +static bool nca9539_is_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case NCA9539_REG_INPUT_PORT0: + case NCA9539_REG_INPUT_PORT1: + case NCA9539_REG_OUTPUT_PORT0: + case NCA9539_REG_OUTPUT_PORT1: + case NCA9539_REG_POLARITY_PORT0: + case NCA9539_REG_POLARITY_PORT1: + case NCA9539_REG_CONFIG_PORT0: + case NCA9539_REG_CONFIG_PORT1: + return true; + } + return false; +} + +static bool nca9539_is_volatile_reg(struct device *dev, unsigned int reg) +{ + return true; +} + +static const struct reg_default nca9539_regmap_default[] = { + { NCA9539_REG_INPUT_PORT0, 0xFF }, + { NCA9539_REG_INPUT_PORT1, 0xFF }, + { NCA9539_REG_OUTPUT_PORT0, 0xFF }, + { NCA9539_REG_OUTPUT_PORT1, 0xFF }, + { NCA9539_REG_POLARITY_PORT0, 0x00 }, + { NCA9539_REG_POLARITY_PORT1, 0x00 }, + { NCA9539_REG_CONFIG_PORT0, 0xFF }, + { NCA9539_REG_CONFIG_PORT1, 0xFF }, +}; + +static const struct regmap_config nca9539_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 7, + .writeable_reg = nca9539_is_writeable_reg, + .readable_reg = nca9539_is_readable_reg, + .volatile_reg = nca9539_is_volatile_reg, + .reg_defaults = nca9539_regmap_default, + .num_reg_defaults = ARRAY_SIZE(nca9539_regmap_default), + .cache_type = REGCACHE_FLAT, +}; + +static const struct gpio_chip template_chip = { + .label = "nca9539-gpio", + .owner = THIS_MODULE, + .get_direction = nca9539_gpio_get_direction, + .direction_input = nca9539_gpio_direction_input, + .direction_output = nca9539_gpio_direction_output, + .get = nca9539_gpio_get, + .set = nca9539_gpio_set, + .base = -1, + .can_sleep = true, +}; + +static int nca9539_probe(struct i2c_client *client) +{ + struct nca9539_chip *chip; + struct regulator *reg; + int ret; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->gpio_chip = template_chip; + chip->gpio_chip.label = "nca9539-gpio"; + chip->gpio_chip.parent = &client->dev; + chip->ngpio = (uintptr_t)of_device_get_match_data(&client->dev); + chip->gpio_chip.ngpio = chip->ngpio; + + reg = devm_regulator_get(&client->dev, "vdd"); + if (IS_ERR(reg)) + return dev_err_probe(&client->dev, PTR_ERR(reg), + "reg get err\n"); + + ret = regulator_enable(reg); + if (ret) { + dev_err(&client->dev, "reg en err: %d\n", ret); + return ret; + } + chip->regulator = reg; + + chip->regmap = devm_regmap_init_i2c(client, &nca9539_regmap_config); + if (IS_ERR(chip->regmap)) { + ret = PTR_ERR(chip->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + goto err_exit; + } + regcache_mark_dirty(chip->regmap); + ret = regcache_sync(chip->regmap); + if (ret) { + dev_err(&client->dev, "Failed to sync register map: %d\n", ret); + goto err_exit; + } + + // TODO(Cody): irq_chip setup + + ret = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip); + if (ret < 0) { + dev_err(&client->dev, "Unable to register gpiochip\n"); + goto err_exit; + } + + i2c_set_clientdata(client, chip); + + return 0; + +err_exit: + regulator_disable(chip->regulator); + return ret; +} + +static int nca9539_remove(struct i2c_client *client) +{ + struct nca9539_chip *chip = i2c_get_clientdata(client); + + regulator_disable(chip->regulator); + + return 0; +} + +static const struct of_device_id nca9539_gpio_of_match_table[] = { + { + .compatible = "novo,nca9539-gpio", + .data = (void *)16, + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, nca9539_gpio_of_match_table); + +static const struct i2c_device_id nca9539_gpio_id_table[] = { + { "nca9539-gpio" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(i2c, nca9539_gpio_id_table); + +static struct i2c_driver nca9539_driver = { + .driver = { + .name = "nca9539-gpio", + .of_match_table = nca9539_gpio_of_match_table, + }, + .probe_new = nca9539_probe, + .remove = nca9539_remove, + .id_table = nca9539_gpio_id_table, +}; +module_i2c_driver(nca9539_driver); + +MODULE_AUTHOR("Cody Xie "); +MODULE_DESCRIPTION("GPIO expander driver for Novosense nca9539"); +MODULE_LICENSE("GPL"); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index bbc98dd17e92..0fda42db4f18 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -2179,7 +2179,9 @@ static struct page *its_allocate_prop_table(gfp_t gfp_flags) { struct page *prop_page; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ)); if (!prop_page) @@ -2317,7 +2319,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, } gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, order); if (!page) @@ -2368,6 +2372,7 @@ retry_baser: if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) { if (tmp & GITS_BASER_SHAREABILITY_MASK) @@ -2958,7 +2963,9 @@ static struct page *its_allocate_pending_table(gfp_t gfp_flags) { struct page *pend_page; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; pend_page = alloc_pages(gfp_flags | __GFP_ZERO, get_order(LPI_PENDBASE_SZ)); @@ -3117,6 +3124,7 @@ static void its_cpu_init_lpis(void) if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK; @@ -3147,6 +3155,7 @@ static void its_cpu_init_lpis(void) if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK; @@ -3316,7 +3325,9 @@ static bool its_alloc_table_entry(struct its_node *its, if (!table[idx]) { gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, get_order(baser->psz)); @@ -3424,7 +3435,9 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; gfp_flags = GFP_KERNEL; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) { + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) { gfp_flags |= GFP_DMA32; itt = (void *)__get_free_pages(gfp_flags, get_order(sz)); } else { @@ -3446,6 +3459,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, kfree(dev); if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566")) free_pages((unsigned long)itt, get_order(sz)); else @@ -3490,6 +3504,7 @@ static void its_free_device(struct its_device *its_dev) kfree(its_dev->event_map.col_map); if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566")) free_pages((unsigned long)its_dev->itt, get_order(its_dev->itt_sz)); else @@ -5122,7 +5137,9 @@ static int __init its_probe_one(struct resource *res, its->numa_node = numa_node; gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, get_order(ITS_CMD_QUEUE_SZ)); @@ -5157,6 +5174,7 @@ static int __init its_probe_one(struct resource *res, if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GITS_CBASER_SHAREABILITY_MASK; diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 72549d9a88f5..eaa874092b7f 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -98,6 +98,12 @@ config ROCKCHIP_MBOX Please check it that the Soc you use have Mailbox hardware. Say Y here if you want to use the Rockchip Mailbox support. +config ROCKCHIP_MBOX_DEMO + tristate "Rockchip MBOX Demo" + depends on ROCKCHIP_MBOX + help + Say y here to enable Rockchip MBOX Demo. + config PCC bool "Platform Communication Channel Driver" depends on ACPI diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index fc9376117111..5bbdb5478d97 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -21,6 +21,8 @@ obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o obj-$(CONFIG_ROCKCHIP_MBOX) += rockchip-mailbox.o +obj-$(CONFIG_ROCKCHIP_MBOX_DEMO) += rockchip-mbox-demo.o + obj-$(CONFIG_PCC) += pcc.o obj-$(CONFIG_ALTERA_MBOX) += mailbox-altera.o diff --git a/drivers/mailbox/rockchip-mbox-demo.c b/drivers/mailbox/rockchip-mbox-demo.c new file mode 100644 index 000000000000..17a313b7e0ab --- /dev/null +++ b/drivers/mailbox/rockchip-mbox-demo.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Rockchip MBOX Demo. + * + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. + * Author: Jiahang Zheng + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The Linux kernel uses the mailbox framework TXDONE_BY_POLL mechanism. + * The minimum unit of the txpoll period interface is ms. + * Configure rockchip,txpoll-period-ms = <1> in dts. + * If data that is longer than MBOX_TX_QUEUE_LEN may be lost, + * each send should be at least interval txpoll-period-ms + */ +#define MSG_LIMIT (100) +#define LINUX_TEST_COMPENSATION (1) + +struct rk_mbox_dev { + struct platform_device *pdev; + struct mbox_client mbox_cl; + struct mbox_chan *mbox_rx_chan; + struct mbox_chan *mbox_tx_chan; + struct rockchip_mbox_msg tx_msg; + int rx_count; +}; + +static void rk_mbox_rx_callback(struct mbox_client *client, void *message) +{ + struct rk_mbox_dev *test_dev = container_of(client, struct rk_mbox_dev, mbox_cl); + struct platform_device *pdev = test_dev->pdev; + struct device *dev = &pdev->dev; + struct rockchip_mbox_msg *tx_msg; + struct rockchip_mbox_msg *rx_msg; + + rx_msg = message; + dev_info(dev, "mbox master: rx_count:%d cmd=0x%x data=0x%x\n", + ++test_dev->rx_count, rx_msg->cmd, rx_msg->data); + + /* test should not live forever */ + if (test_dev->rx_count >= MSG_LIMIT) { + dev_info(dev, "Rockchip mbox test exit!\n"); + return; + } + + mdelay(LINUX_TEST_COMPENSATION); + tx_msg = &test_dev->tx_msg; + mbox_send_message(test_dev->mbox_tx_chan, tx_msg); +} + +static int mbox_demo_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rk_mbox_dev *test_dev = NULL; + struct mbox_client *cl; + struct rockchip_mbox_msg *tx_msg; + int ret = 0; + + test_dev = devm_kzalloc(dev, sizeof(*test_dev), GFP_KERNEL); + if (!test_dev) + return -ENOMEM; + + /* link_id: master core 0 and remote core 3 */ + tx_msg = &test_dev->tx_msg; + tx_msg->cmd = 0x03U; + tx_msg->data = 0x524D5347U; + + dev_info(dev, "rockchip mbox demo probe.\n"); + test_dev->pdev = pdev; + test_dev->rx_count = 0; + + cl = &test_dev->mbox_cl; + cl->dev = dev; + cl->rx_callback = rk_mbox_rx_callback; + + platform_set_drvdata(pdev, test_dev); + test_dev->mbox_rx_chan = mbox_request_channel_byname(cl, "test-rx"); + if (IS_ERR(test_dev->mbox_rx_chan)) { + ret = PTR_ERR(test_dev->mbox_rx_chan); + dev_err(dev, "failed to request mbox rx chan, ret %d\n", ret); + return ret; + } + test_dev->mbox_tx_chan = mbox_request_channel_byname(cl, "test-tx"); + if (IS_ERR(test_dev->mbox_tx_chan)) { + ret = PTR_ERR(test_dev->mbox_tx_chan); + dev_err(dev, "failed to request mbox tx chan, ret %d\n", ret); + return ret; + } + + dev_info(dev, "mbox master: send cmd=0x%x data=0x%x\n", tx_msg->cmd, tx_msg->data); + mbox_send_message(test_dev->mbox_tx_chan, tx_msg); + + return ret; +} + +static int mbox_demo_remove(struct platform_device *pdev) +{ + struct rk_mbox_dev *test_dev = platform_get_drvdata(pdev); + + mbox_free_channel(test_dev->mbox_rx_chan); + mbox_free_channel(test_dev->mbox_tx_chan); + + return 0; +} + +static const struct of_device_id mbox_demo_match[] = { + { .compatible = "rockchip,mbox-demo", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mbox_demo_match); + +static struct platform_driver mbox_demo_driver = { + .probe = mbox_demo_probe, + .remove = mbox_demo_remove, + .driver = { + .name = "mbox-demo", + .of_match_table = mbox_demo_match, + }, +}; +module_platform_driver(mbox_demo_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Rockchip MBOX Demo"); +MODULE_AUTHOR("Jiahang Zheng "); diff --git a/drivers/media/i2c/maxim4c/Kconfig b/drivers/media/i2c/maxim4c/Kconfig index 540cd2695920..04dddb27131f 100644 --- a/drivers/media/i2c/maxim4c/Kconfig +++ b/drivers/media/i2c/maxim4c/Kconfig @@ -3,44 +3,46 @@ # Maxim Quad GMSL deserializer and serializer devices # config VIDEO_DES_MAXIM4C - tristate "Maxim Qual GMSL deserializer support" + tristate "Maxim Quad GMSL deserializer support" depends on I2C && VIDEO_DEV depends on MEDIA_CAMERA_SUPPORT select MEDIA_CONTROLLER select VIDEO_V4L2_SUBDEV_API select V4L2_FWNODE help - This driver supports the Maxim Qual GMSL2/GMSL1 deserializer. + This driver supports the Maxim Quad GMSL2/GMSL1 deserializer. To compile this driver as a module, choose M here: the module will be called maxim4c. +menu "Maxim Quad GMSL serializer devices support" + visible if VIDEO_DES_MAXIM4C + config MAXIM4C_SER_MAX9295 - tristate "Maxim GMSL serializer support" - depends on I2C - select VIDEO_DES_MAXIM4C + tristate "Maxim GMSL2 serializer max9295 support" + depends on VIDEO_DES_MAXIM4C help - This driver supports the Maxim GMSL2 serializer. + This driver supports the Maxim GMSL2 max9295 serializer. To compile this driver as a module, choose M here: the module will be called remote_max9295. config MAXIM4C_SER_MAX96715 - tristate "Maxim GMSL serializer support" - depends on I2C - select VIDEO_DES_MAXIM4C + tristate "Maxim GMSL1 Serializer max96715 support" + depends on VIDEO_DES_MAXIM4C help - This driver supports the Maxim GMSL1 serializer. + This driver supports the Maxim GMSL1 max96715 serializer. To compile this driver as a module, choose M here: the module will be called remote_max96715. config MAXIM4C_SER_MAX96717 - tristate "Maxim GMSL serializer support" - depends on I2C - select VIDEO_DES_MAXIM4C + tristate "Maxim GMSL2 Serializer max96717 support" + depends on VIDEO_DES_MAXIM4C help - This driver supports the Maxim GMSL2 serializer. + This driver supports the Maxim GMSL2 max96717 serializer. To compile this driver as a module, choose M here: the module will be called remote_max96717. + +endmenu diff --git a/drivers/media/i2c/maxim4c/maxim4c_api.h b/drivers/media/i2c/maxim4c/maxim4c_api.h index 45cba9a0f6a1..6dd3bbca17d7 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_api.h +++ b/drivers/media/i2c/maxim4c/maxim4c_api.h @@ -23,6 +23,9 @@ /* Maxim Deserializer Test Pattern */ #define MAXIM4C_TEST_PATTERN 0 +/* Maxim Deserializer pwdn on/off enable */ +#define MAXIM4C_LOCAL_DES_ON_OFF_EN 0 + /* maxim4c i2c api */ int maxim4c_i2c_write_reg(struct i2c_client *client, u16 reg_addr, u16 reg_len, u16 val_len, u32 reg_val); @@ -77,15 +80,22 @@ int maxim4c_remote_mfd_add_devices(maxim4c_t *maxim4c); int maxim4c_remote_devices_init(maxim4c_t *maxim4c, u8 link_init_mask); int maxim4c_remote_devices_deinit(maxim4c_t *maxim4c, u8 link_init_mask); int maxim4c_remote_load_init_seq(maxim4c_remote_t *remote_device); +int maxim4c_remote_i2c_addr_select(maxim4c_remote_t *remote_device, u32 i2c_id); +int maxim4c_remote_i2c_client_init(maxim4c_remote_t *remote_device, + struct i2c_client *des_client); int maxim4c_remote_device_register(maxim4c_t *maxim4c, - maxim4c_remote_t *remote_device); + maxim4c_remote_t *remote_device); /* maxim4c v4l2 subdev api */ int maxim4c_v4l2_subdev_init(maxim4c_t *maxim4c); void maxim4c_v4l2_subdev_deinit(maxim4c_t *maxim4c); +int maxim4c_module_hw_init(maxim4c_t *maxim4c); + /* maxim4c pattern api */ -int maxim4c_pattern_init(maxim4c_t *maxim4c); +int maxim4c_pattern_hw_init(maxim4c_t *maxim4c); +int maxim4c_pattern_support_mode_init(maxim4c_t *maxim4c); +int maxim4c_pattern_data_init(maxim4c_t *maxim4c); int maxim4c_pattern_enable(maxim4c_t *maxim4c, bool enable); #endif /* __MAXIM4C_API_H__ */ diff --git a/drivers/media/i2c/maxim4c/maxim4c_drv.c b/drivers/media/i2c/maxim4c/maxim4c_drv.c index 68d721f6cd99..88924dce5926 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_drv.c +++ b/drivers/media/i2c/maxim4c/maxim4c_drv.c @@ -6,7 +6,7 @@ * * Author: Cai Wenzhong * - * V2.0.00 maxim serdes qual GMSL2/GMSL1 driver framework. + * V2.00.00 maxim serdes quad GMSL2/GMSL1 driver framework. * 1. local deserializer support: max96712/max96722 * 2. remote serializer support: max9295/max96715/max96717 * 3. support deserializer and serializer auto adaptive @@ -14,6 +14,14 @@ * 5. support remote serializer I2c address mapping * 6. support remote serializer hot plug detection and recovery * + * V2.01.00 + * 1. remote device and local link are bound through link id + * 2. support local and remote port chain check + * 3. drivers/media/i2c/maxim4c/Kconfig support menu select + * 4. optimize delay time and error messages + * 5. power control: local by pwdn gpio, remote by pocen gpio + * 6. local pwdn on/off enable depend on MAXIM4C_LOCAL_DES_ON_OFF_EN + * */ #include #include @@ -43,14 +51,10 @@ #include "maxim4c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(2, 0x00, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(2, 0x01, 0x00) #define MAXIM4C_XVCLK_FREQ 25000000 -/* device compatible */ -#define MAXIM4C_MAX96712_COMPAT "maxim4c,max96712" -#define MAXIM4C_MAX96722_COMPAT "maxim4c,max96722" - static int maxim4c_check_local_chipid(maxim4c_t *maxim4c) { struct i2c_client *client = maxim4c->client; @@ -59,6 +63,11 @@ static int maxim4c_check_local_chipid(maxim4c_t *maxim4c) u8 chipid = 0; for (loop = 0; loop < 5; loop++) { + if (loop != 0) { + dev_info(dev, "check local chipid retry (%d)", loop); + msleep(10); + } + ret = maxim4c_i2c_read_byte(client, MAXIM4C_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS, &chipid); @@ -74,13 +83,10 @@ static int maxim4c_check_local_chipid(maxim4c_t *maxim4c) return 0; } } else { - dev_err(dev, "Unexpected maxim chipid(%02x)\n", chipid); + dev_err(dev, "Unexpected maxim chipid = %02x\n", chipid); return -ENODEV; } } - - dev_info(dev, "retry (%d) to check local chipid", loop + 1); - msleep(10); } dev_err(dev, "maxim check chipid error, ret(%d)\n", ret); @@ -181,13 +187,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work) link_id = MAXIM4C_LINK_ID_A; if (curr_lock_state & MAXIM4C_LINK_MASK_A) { - dev_info(dev, "link A plug in\n"); + dev_info(dev, "Link A plug in\n"); maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_A); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true); } else { - dev_info(dev, "link A plug out\n"); + dev_info(dev, "Link A plug out\n"); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false); } @@ -197,13 +203,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work) link_id = MAXIM4C_LINK_ID_B; if (curr_lock_state & MAXIM4C_LINK_MASK_B) { - dev_info(dev, "link B plug in\n"); + dev_info(dev, "Link B plug in\n"); maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_B); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true); } else { - dev_info(dev, "link B plug out\n"); + dev_info(dev, "Link B plug out\n"); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false); } @@ -213,13 +219,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work) link_id = MAXIM4C_LINK_ID_C; if (curr_lock_state & MAXIM4C_LINK_MASK_C) { - dev_info(dev, "link C plug in\n"); + dev_info(dev, "Link C plug in\n"); maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_C); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true); } else { - dev_info(dev, "link C plug out\n"); + dev_info(dev, "Link C plug out\n"); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false); } @@ -229,13 +235,13 @@ static void maxim4c_hot_plug_state_check_work(struct work_struct *work) link_id = MAXIM4C_LINK_ID_D; if (curr_lock_state & MAXIM4C_LINK_MASK_D) { - dev_info(dev, "link D plug in\n"); + dev_info(dev, "Link D plug in\n"); maxim4c_remote_devices_init(maxim4c, MAXIM4C_LINK_MASK_D); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, true); } else { - dev_info(dev, "link D plug out\n"); + dev_info(dev, "Link D plug out\n"); maxim4c_video_pipe_linkid_enable(maxim4c, link_id, false); } @@ -290,10 +296,10 @@ static int maxim4c_local_device_power_on(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; - if (!IS_ERR(maxim4c->power_gpio)) { - dev_info(dev, "local device power gpio on\n"); + if (!IS_ERR(maxim4c->pwdn_gpio)) { + dev_info(dev, "local device pwdn gpio on\n"); - gpiod_set_value_cansleep(maxim4c->power_gpio, 1); + gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 1); usleep_range(5000, 10000); } @@ -305,10 +311,10 @@ static void maxim4c_local_device_power_off(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; - if (!IS_ERR(maxim4c->power_gpio)) { - dev_info(dev, "local device power gpio off\n"); + if (!IS_ERR(maxim4c->pwdn_gpio)) { + dev_info(dev, "local device pwdn gpio off\n"); - gpiod_set_value_cansleep(maxim4c->power_gpio, 0); + gpiod_set_value_cansleep(maxim4c->pwdn_gpio, 0); } } @@ -318,7 +324,7 @@ static int maxim4c_remote_device_power_on(maxim4c_t *maxim4c) // remote PoC enable if (!IS_ERR(maxim4c->pocen_gpio)) { - dev_info(dev, "remote device poc gpio on\n"); + dev_info(dev, "remote device pocen gpio on\n"); gpiod_set_value_cansleep(maxim4c->pocen_gpio, 1); usleep_range(5000, 10000); @@ -333,7 +339,7 @@ static int maxim4c_remote_device_power_off(maxim4c_t *maxim4c) // remote PoC enable if (!IS_ERR(maxim4c->pocen_gpio)) { - dev_info(dev, "remote device poc gpio off\n"); + dev_info(dev, "remote device pocen gpio off\n"); gpiod_set_value_cansleep(maxim4c->pocen_gpio, 0); } @@ -346,8 +352,15 @@ static int maxim4c_runtime_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct maxim4c *maxim4c = v4l2_get_subdevdata(sd); + int ret = 0; - return maxim4c_remote_device_power_on(maxim4c); +#if MAXIM4C_LOCAL_DES_ON_OFF_EN + ret |= maxim4c_local_device_power_on(maxim4c); +#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */ + + ret |= maxim4c_remote_device_power_on(maxim4c); + + return ret; } static int maxim4c_runtime_suspend(struct device *dev) @@ -355,8 +368,15 @@ static int maxim4c_runtime_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct maxim4c *maxim4c = v4l2_get_subdevdata(sd); + int ret = 0; - return maxim4c_remote_device_power_off(maxim4c); + ret |= maxim4c_remote_device_power_off(maxim4c); + +#if MAXIM4C_LOCAL_DES_ON_OFF_EN + maxim4c_local_device_power_off(maxim4c); +#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */ + + return ret; } static const struct dev_pm_ops maxim4c_pm_ops = { @@ -378,22 +398,26 @@ static int maxim4c_extra_init_seq_parse(maxim4c_t *maxim4c, struct device_node * struct maxim4c_i2c_init_seq *init_seq = NULL; init_seq_node = of_get_child_by_name(node, "extra-init-sequence"); - if (!IS_ERR_OR_NULL(init_seq_node)) { - if (!of_device_is_available(init_seq_node)) { - dev_info(dev, "%pOF is disabled\n", init_seq_node); + if (IS_ERR_OR_NULL(init_seq_node)) { + dev_dbg(dev, "%pOF no child node extra-init-sequence\n", node); + return 0; + } - return 0; - } - - dev_info(dev, "load extra-init-sequence\n"); - - init_seq = &maxim4c->extra_init_seq; - maxim4c_i2c_load_init_seq(dev, - init_seq_node, init_seq); + if (!of_device_is_available(init_seq_node)) { + dev_dbg(dev, "%pOF is disabled\n", init_seq_node); of_node_put(init_seq_node); + return 0; } + dev_info(dev, "load extra-init-sequence\n"); + + init_seq = &maxim4c->extra_init_seq; + maxim4c_i2c_load_init_seq(dev, + init_seq_node, init_seq); + + of_node_put(init_seq_node); + return 0; } @@ -404,8 +428,12 @@ static int maxim4c_module_parse_dt(maxim4c_t *maxim4c) // maxim serdes local node = of_get_child_by_name(dev->of_node, "serdes-local-device"); - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node)) { + dev_err(dev, "%pOF has no child node: serdes-local-device\n", + dev->of_node); + return -ENODEV; + } if (!of_device_is_available(node)) { dev_info(dev, "%pOF is disabled\n", node); @@ -492,36 +520,51 @@ static int maxim4c_module_hw_postinit(maxim4c_t *maxim4c) return ret; } -static int maxim4c_module_hw_init(maxim4c_t *maxim4c) +int maxim4c_module_hw_init(maxim4c_t *maxim4c) { + struct device *dev = &maxim4c->client->dev; int ret = 0; ret = maxim4c_module_hw_previnit(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: hw prev init error\n", __func__); + return ret; + } ret = maxim4c_link_hw_init(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: hw link init error\n", __func__); return ret; + } ret = maxim4c_video_pipe_hw_init(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: hw pipe init error\n", __func__); return ret; + } ret = maxim4c_mipi_txphy_hw_init(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: hw txphy init error\n", __func__); return ret; + } ret = maxim4c_run_extra_init_seq(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: run extra init seq error\n", __func__); return ret; + } ret = maxim4c_module_hw_postinit(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: hw post init error\n", __func__); return ret; + } return 0; } +EXPORT_SYMBOL(maxim4c_module_hw_init); static int maxim4c_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -529,32 +572,30 @@ static int maxim4c_probe(struct i2c_client *client, struct device *dev = &client->dev; struct device_node *node = dev->of_node; maxim4c_t *maxim4c = NULL; - const u32 *chip_id = NULL; + u32 chip_id; int ret = 0; dev_info(dev, "driver version: %02x.%02x.%02x", DRIVER_VERSION >> 16, (DRIVER_VERSION & 0xff00) >> 8, DRIVER_VERSION & 0x00ff); - chip_id = of_device_get_match_data(dev); - if (chip_id == NULL) { - dev_err(dev, "maxim4c driver get match data error\n"); - return -EINVAL; - } - - if (*chip_id == MAX96712_CHIP_ID) { - dev_info(dev, "maxim4c driver for max96712"); - } else if (*chip_id == MAX96722_CHIP_ID) { - dev_info(dev, "maxim4c driver for max96722"); + chip_id = (uintptr_t)of_device_get_match_data(dev); + if (chip_id == MAX96712_CHIP_ID) { + dev_info(dev, "maxim4c driver for max96712\n"); + } else if (chip_id == MAX96722_CHIP_ID) { + dev_info(dev, "maxim4c driver for max96722\n"); } else { - dev_err(dev, "maxim4c driver unknown chip"); + dev_err(dev, "maxim4c driver unknown chip\n"); return -EINVAL; } maxim4c = devm_kzalloc(dev, sizeof(*maxim4c), GFP_KERNEL); - if (!maxim4c) + if (!maxim4c) { + dev_err(dev, "maxim4c probe no memory error\n"); return -ENOMEM; + } + maxim4c->client = client; - maxim4c->chipid = *chip_id; + maxim4c->chipid = chip_id; ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX, &maxim4c->module_index); @@ -569,9 +610,9 @@ static int maxim4c_probe(struct i2c_client *client, return -EINVAL; } - maxim4c->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW); - if (IS_ERR(maxim4c->power_gpio)) - dev_warn(dev, "Failed to get power-gpios, maybe no use\n"); + maxim4c->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); + if (IS_ERR(maxim4c->pwdn_gpio)) + dev_warn(dev, "Failed to get pwdn-gpios, maybe no use\n"); maxim4c->pocen_gpio = devm_gpiod_get(dev, "pocen", GPIOD_OUT_LOW); if (IS_ERR(maxim4c->pocen_gpio)) @@ -594,13 +635,21 @@ static int maxim4c_probe(struct i2c_client *client, // client->dev->driver_data = subdev // subdev->dev->driver_data = maxim4c ret = maxim4c_v4l2_subdev_init(maxim4c); + if (ret) { + dev_err(dev, "maxim4c probe v4l2 subdev init error\n"); + goto err_power_off; + } + +#if MAXIM4C_TEST_PATTERN + ret = maxim4c_pattern_data_init(maxim4c); if (ret) goto err_power_off; -#if MAXIM4C_TEST_PATTERN - ret = maxim4c_pattern_init(maxim4c); +#if (MAXIM4C_LOCAL_DES_ON_OFF_EN == 0) + ret = maxim4c_pattern_hw_init(maxim4c); if (ret) goto err_power_off; +#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */ pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -612,9 +661,11 @@ static int maxim4c_probe(struct i2c_client *client, maxim4c_module_data_init(maxim4c); maxim4c_module_parse_dt(maxim4c); +#if (MAXIM4C_LOCAL_DES_ON_OFF_EN == 0) ret = maxim4c_module_hw_init(maxim4c); if (ret) goto err_subdev_deinit; +#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */ ret = maxim4c_remote_mfd_add_devices(maxim4c); if (ret) @@ -657,28 +708,17 @@ static int maxim4c_remove(struct i2c_client *client) return 0; } -#if IS_ENABLED(CONFIG_OF) -static const u32 max96712_chip_id = MAX96712_CHIP_ID; -static const u32 max96722_chip_id = MAX96722_CHIP_ID; - static const struct of_device_id maxim4c_of_match[] = { { - .compatible = MAXIM4C_MAX96712_COMPAT, - .data = &max96712_chip_id, + .compatible = "maxim4c,max96712", + .data = (const void *)MAX96712_CHIP_ID }, { - .compatible = MAXIM4C_MAX96722_COMPAT, - .data = &max96722_chip_id, + .compatible = "maxim4c,max96722", + .data = (const void *)MAX96722_CHIP_ID }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, maxim4c_of_match); -#endif - -static const struct i2c_device_id maxim4c_match_id[] = { - { MAXIM4C_MAX96712_COMPAT, 0 }, - { MAXIM4C_MAX96722_COMPAT, 0 }, - {}, -}; static struct i2c_driver maxim4c_i2c_driver = { .driver = { @@ -688,11 +728,10 @@ static struct i2c_driver maxim4c_i2c_driver = { }, .probe = &maxim4c_probe, .remove = &maxim4c_remove, - .id_table = maxim4c_match_id, }; module_i2c_driver(maxim4c_i2c_driver); -MODULE_AUTHOR("Cai wenzhong "); -MODULE_DESCRIPTION("Maxim qual gmsl deserializer driver"); +MODULE_AUTHOR("Cai Wenzhong "); +MODULE_DESCRIPTION("Maxim quad gmsl deserializer driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/maxim4c/maxim4c_drv.h b/drivers/media/i2c/maxim4c/maxim4c_drv.h index d5cd4a79e7e4..444f20f5d3e8 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_drv.h +++ b/drivers/media/i2c/maxim4c/maxim4c_drv.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -55,7 +56,7 @@ struct maxim4c_mode { typedef struct maxim4c { struct i2c_client *client; struct clk *xvclk; - struct gpio_desc *power_gpio; + struct gpio_desc *pwdn_gpio; struct gpio_desc *pocen_gpio; struct gpio_desc *lock_gpio; @@ -101,6 +102,7 @@ typedef struct maxim4c { struct maxim4c_i2c_init_seq extra_init_seq; + struct mfd_cell remote_mfd_devs[MAXIM4C_LINK_ID_MAX]; maxim4c_remote_t *remote_device[MAXIM4C_LINK_ID_MAX]; } maxim4c_t; diff --git a/drivers/media/i2c/maxim4c/maxim4c_i2c.c b/drivers/media/i2c/maxim4c/maxim4c_i2c.c index 1a88ef2cece8..77aba745428e 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_i2c.c +++ b/drivers/media/i2c/maxim4c/maxim4c_i2c.c @@ -88,7 +88,7 @@ int maxim4c_i2c_read_reg(struct i2c_client *client, ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) { dev_err(&client->dev, - "%s: reading register 0x%x from 0x%x failed\n", + "%s: reading register 0x%04x from 0x%02x failed\n", __func__, reg_addr, client->addr); return -EIO; } diff --git a/drivers/media/i2c/maxim4c/maxim4c_link.c b/drivers/media/i2c/maxim4c/maxim4c_link.c index 5dd31d60653d..688dfe85abee 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_link.c +++ b/drivers/media/i2c/maxim4c/maxim4c_link.c @@ -107,16 +107,16 @@ static int maxim4c_link_run_init_seq(maxim4c_t *maxim4c) maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link; struct maxim4c_link_cfg *link_cfg = NULL; struct maxim4c_i2c_init_seq *init_seq = NULL; - int i = 0; + int link_idx = 0; int ret = 0; // link init sequence - for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) { - link_cfg = &gmsl_link->link_cfg[i]; + for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) { + link_cfg = &gmsl_link->link_cfg[link_idx]; init_seq = &link_cfg->link_init_seq; ret = maxim4c_i2c_run_init_seq(client, init_seq); if (ret) { - dev_err(dev, "link id = %d init sequence error\n", i); + dev_err(dev, "link id = %d init sequence error\n", link_idx); return ret; } } @@ -386,6 +386,11 @@ int maxim4c_link_wait_linklock(struct maxim4c *maxim4c, u8 link_mask) msleep(time_ms); for (loop_idx = 0; loop_idx < 20; loop_idx++) { + if (loop_idx != 0) { + msleep(10); + time_ms += 10; + } + for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) { link_bit_mask = BIT(link_idx); @@ -405,9 +410,6 @@ int maxim4c_link_wait_linklock(struct maxim4c *maxim4c, u8 link_mask) maxim4c->link_lock_state = lock_state; return 0; } - - msleep(10); - time_ms += 10; } if ((lock_state & link_mask) != 0) { @@ -554,9 +556,7 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev, struct device_node *init_seq_node = NULL; struct maxim4c_i2c_init_seq *init_seq = NULL; struct maxim4c_link_cfg *link_cfg = NULL; - struct maxim4c_remote_info *remote_info; const char *link_cfg_name = "gmsl-link-config"; - const char *prop_str = NULL; u32 value = 0; u32 sub_idx = 0, link_id = 0; int ret = 0; @@ -568,7 +568,8 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev, link_cfg_name, strlen(link_cfg_name))) { if (sub_idx >= MAXIM4C_LINK_ID_MAX) { - dev_err(dev, "Too many matching %s node\n", link_cfg_name); + dev_err(dev, "%pOF: Too many matching %s node\n", + parent_node, link_cfg_name); of_node_put(node); break; @@ -622,20 +623,6 @@ static int maxim4c_gmsl_link_config_parse_dt(struct device *dev, link_cfg->link_rx_rate = value; } - /* remote info */ - remote_info = &link_cfg->remote_info; - ret = of_property_read_string(node, "remote-name", &prop_str); - if (ret == 0) { - dev_info(dev, "remote-name property: %s", prop_str); - remote_info->remote_name = prop_str; - } - - ret = of_property_read_string(node, "remote-compatible", &prop_str); - if (ret == 0) { - dev_info(dev, "remote-compatible property: %s", prop_str); - remote_info->remote_compatible = prop_str; - } - /* link init sequence */ init_seq_node = of_get_child_by_name(node, "link-init-sequence"); if (!IS_ERR_OR_NULL(init_seq_node)) { @@ -666,8 +653,11 @@ int maxim4c_link_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node) dev_info(dev, "=== maxim4c link parse dt ===\n"); node = of_get_child_by_name(of_node, "gmsl-links"); - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node)) { + dev_err(dev, "%pOF has no child node: gmsl-links\n", + of_node); return -ENODEV; + } if (!of_device_is_available(node)) { dev_info(dev, "%pOF is disabled\n", node); @@ -699,29 +689,42 @@ EXPORT_SYMBOL(maxim4c_link_parse_dt); int maxim4c_link_hw_init(maxim4c_t *maxim4c) { + struct device *dev = &maxim4c->client->dev; maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link; int ret = 0; // All links disable at beginning. ret = maxim4c_link_status_init(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: link status error\n", __func__); return ret; + } if (gmsl_link->link_vdd_ldo1_en) ret |= maxim4c_link_enable_vdd_ldo1(maxim4c); if (gmsl_link->link_vdd_ldo2_en) ret |= maxim4c_link_enable_vdd_ldo2(maxim4c); + if (ret) { + dev_err(dev, "%s: link vdd ldo enable error\n", __func__); + return ret; + } // Link Rate Setting - ret |= maxim4c_link_set_rate(maxim4c); - if (ret) + ret = maxim4c_link_set_rate(maxim4c); + if (ret) { + dev_err(dev, "%s: link set rate error\n", __func__); return ret; + } // link init sequence ret = maxim4c_link_run_init_seq(maxim4c); + if (ret) { + dev_err(dev, "%s: link run init seq error\n", __func__); + return ret; + } - return ret; + return 0; } EXPORT_SYMBOL(maxim4c_link_hw_init); @@ -745,8 +748,6 @@ void maxim4c_link_data_init(maxim4c_t *maxim4c) else link_cfg->link_rx_rate = MAXIM4C_LINK_RX_RATE_6GBPS; link_cfg->link_tx_rate = MAXIM4C_LINK_TX_RATE_187_5MPS; - link_cfg->remote_info.remote_name = NULL; - link_cfg->remote_info.remote_compatible = NULL; link_cfg->link_init_seq.reg_init_seq = NULL; } } diff --git a/drivers/media/i2c/maxim4c/maxim4c_link.h b/drivers/media/i2c/maxim4c/maxim4c_link.h index 575cb6e55fb9..f25d4cb9fd04 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_link.h +++ b/drivers/media/i2c/maxim4c/maxim4c_link.h @@ -63,18 +63,12 @@ enum maxim4c_link_tx_rate { MAXIM4C_LINK_TX_RATE_187_5MPS = 0, }; -struct maxim4c_remote_info { - const char *remote_name; - const char *remote_compatible; -}; - struct maxim4c_link_cfg { u8 link_enable; u8 link_type; u8 link_rx_rate; u8 link_tx_rate; - struct maxim4c_remote_info remote_info; struct maxim4c_i2c_init_seq link_init_seq; }; diff --git a/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c b/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c index f56ded63c186..5734902e59f8 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c +++ b/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c @@ -220,11 +220,22 @@ int maxim4c_mipi_csi_output(maxim4c_t *maxim4c, bool enable) { struct i2c_client *client = maxim4c->client; struct device *dev = &client->dev; + maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy; u8 reg_mask = 0, reg_value = 0; int ret = 0; dev_dbg(dev, "%s: enable = %d\n", __func__, enable); + if (mipi_txphy->force_clock_out_en != 0) { + reg_mask = BIT(7); + reg_value = enable ? BIT(7) : 0; + + // Force all MIPI clocks running Config + ret |= maxim4c_i2c_update_byte(client, + 0x08A0, MAXIM4C_I2C_REG_ADDR_16BITS, + reg_mask, reg_value); + } + /* Bit1 of the register 0x040B: CSI_OUT_EN * 1 = CSI output enabled * 0 = CSI output disabled @@ -259,7 +270,8 @@ static int maxim4c_mipi_txphy_config_parse_dt(struct device *dev, txphy_cfg_name, strlen(txphy_cfg_name))) { if (sub_idx >= MAXIM4C_TXPHY_ID_MAX) { - dev_err(dev, "Too many matching %s node\n", txphy_cfg_name); + dev_err(dev, "%pOF: Too many matching %s node\n", + parent_node, txphy_cfg_name); of_node_put(node); break; @@ -355,8 +367,11 @@ int maxim4c_mipi_txphy_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node) dev_info(dev, "=== maxim4c mipi txphy parse dt ===\n"); node = of_get_child_by_name(of_node, "mipi-txphys"); - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node)) { + dev_err(dev, "%pOF has no child node: mipi-txphys\n", + of_node); return -ENODEV; + } if (!of_device_is_available(node)) { dev_info(dev, "%pOF is disabled\n", node); @@ -404,6 +419,7 @@ EXPORT_SYMBOL(maxim4c_mipi_txphy_parse_dt); int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c) { struct i2c_client *client = maxim4c->client; + struct device *dev = &client->dev; maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy; struct maxim4c_txphy_cfg *phy_cfg = NULL; u8 mode = 0; @@ -479,9 +495,6 @@ int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c) phy_cfg->clock_master = 1; break; } - // MIPI clocks running mode - if (mipi_txphy->force_clock_out_en != 0) - mode |= BIT(7); // MIPI TXPHY Mode setting ret |= maxim4c_i2c_write_byte(client, @@ -497,7 +510,12 @@ int maxim4c_mipi_txphy_hw_init(maxim4c_t *maxim4c) // mipi txphy auto init deskew ret |= maxim4c_txphy_auto_init_deskew(maxim4c); - return ret; + if (ret) { + dev_err(dev, "%s: txphy hw init error\n", __func__); + return ret; + } + + return 0; } EXPORT_SYMBOL(maxim4c_mipi_txphy_hw_init); diff --git a/drivers/media/i2c/maxim4c/maxim4c_pattern.c b/drivers/media/i2c/maxim4c/maxim4c_pattern.c index 816f2c6e0fad..1a3de8f3d7b4 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_pattern.c +++ b/drivers/media/i2c/maxim4c/maxim4c_pattern.c @@ -91,6 +91,13 @@ static int maxim4c_pattern_previnit(maxim4c_t *maxim4c) if (ret) return ret; + // video pipe disable. + ret = maxim4c_i2c_write_byte(client, + 0x00F4, MAXIM4C_I2C_REG_ADDR_16BITS, + 0x00); + if (ret) + return ret; + // MIPI CSI output disable. ret = maxim4c_i2c_write_byte(client, 0x040B, MAXIM4C_I2C_REG_ADDR_16BITS, @@ -108,7 +115,7 @@ static int maxim4c_pattern_previnit(maxim4c_t *maxim4c) return 0; } -static int maxim4c_pattern_hw_init(maxim4c_t *maxim4c) +static int maxim4c_pattern_config(maxim4c_t *maxim4c) { const u32 h_active = PATTERN_WIDTH; const u32 h_fp = 88; @@ -249,18 +256,40 @@ static int maxim4c_pattern_hw_init(maxim4c_t *maxim4c) return ret; } -int maxim4c_pattern_init(maxim4c_t *maxim4c) +int maxim4c_pattern_support_mode_init(maxim4c_t *maxim4c) +{ + struct device *dev = &maxim4c->client->dev; + struct maxim4c_mode *supported_mode = NULL; + + dev_info(dev, "=== maxim4c pattern support mode init ===\n"); + + maxim4c->cfg_modes_num = 1; + maxim4c->cur_mode = &maxim4c->supported_mode; + supported_mode = &maxim4c->supported_mode; + + // init using def mode + memcpy(supported_mode, &maxim4c_pattern_mode, sizeof(struct maxim4c_mode)); + + return 0; +} +EXPORT_SYMBOL(maxim4c_pattern_support_mode_init); + +int maxim4c_pattern_data_init(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; struct device_node *node = NULL; struct maxim4c_mode *supported_mode = NULL; struct maxim4c_pattern *pattern = NULL; + maxim4c_mipi_txphy_t *mipi_txphy = &maxim4c->mipi_txphy; int ret = 0; // maxim serdes local node = of_get_child_by_name(dev->of_node, "serdes-local-device"); - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node)) { + dev_err(dev, "%pOF has no child node: serdes-local-device\n", + dev->of_node); return -ENODEV; + } if (!of_device_is_available(node)) { dev_info(dev, "%pOF is disabled\n", node); @@ -273,23 +302,14 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c) /* mipi txphy parse dt */ ret = maxim4c_mipi_txphy_parse_dt(maxim4c, node); - if (ret) + if (ret) { + dev_err(dev, "%s: txphy parse dt error\n", __func__); return ret; + } - ret = maxim4c_pattern_previnit(maxim4c); - if (ret) - return ret; - - ret = maxim4c_mipi_txphy_hw_init(maxim4c); - if (ret) - return ret; - - maxim4c->cfg_modes_num = 1; - maxim4c->cur_mode = &maxim4c->supported_mode; - supported_mode = &maxim4c->supported_mode; - - // init using def mode - memcpy(supported_mode, &maxim4c_pattern_mode, sizeof(struct maxim4c_mode)); + // pattern need enable force_clock_out_en + dev_info(dev, "Pattern mode force_clock_out_en default enable\n"); + mipi_txphy->force_clock_out_en = 1; // pattern generator and mode init pattern = &maxim4c->pattern; @@ -297,6 +317,7 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c) pattern->pattern_mode = PATTERN_CHECKERBOARD; pattern->pattern_pclk = PATTERN_PCLK_75M; + supported_mode = &maxim4c->supported_mode; switch (pattern->pattern_pclk) { case PATTERN_PCLK_25M: supported_mode->max_fps.denominator = 100000; @@ -307,13 +328,13 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c) case PATTERN_PCLK_150M: supported_mode->max_fps.denominator = 600000; if (supported_mode->link_freq_idx < 12) - dev_info(dev, "link_freq_idx = %d is too low\n", + dev_warn(dev, "link_freq_idx = %d is too low\n", supported_mode->link_freq_idx); break; case PATTERN_PCLK_375M: supported_mode->max_fps.denominator = 1500000; if (supported_mode->link_freq_idx < 22) - dev_info(dev, "link_freq_idx = %d is too low\n", + dev_warn(dev, "link_freq_idx = %d is too low\n", supported_mode->link_freq_idx); break; } @@ -321,8 +342,33 @@ int maxim4c_pattern_init(maxim4c_t *maxim4c) dev_info(dev, "video pattern: generator = %d, mode = %d, pclk = %d\n", pattern->pattern_generator, pattern->pattern_mode, pattern->pattern_pclk); - ret = maxim4c_pattern_hw_init(maxim4c); - - return ret; + return 0; } -EXPORT_SYMBOL(maxim4c_pattern_init); +EXPORT_SYMBOL(maxim4c_pattern_data_init); + +int maxim4c_pattern_hw_init(maxim4c_t *maxim4c) +{ + struct device *dev = &maxim4c->client->dev; + int ret = 0; + + ret = maxim4c_pattern_previnit(maxim4c); + if (ret) { + dev_err(dev, "%s: pattern previnit error\n", __func__); + return ret; + } + + ret = maxim4c_mipi_txphy_hw_init(maxim4c); + if (ret) { + dev_err(dev, "%s: txphy hw init error\n", __func__); + return ret; + } + + ret = maxim4c_pattern_config(maxim4c); + if (ret) { + dev_err(dev, "%s: pattern config error\n", __func__); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(maxim4c_pattern_hw_init); diff --git a/drivers/media/i2c/maxim4c/maxim4c_remote.c b/drivers/media/i2c/maxim4c/maxim4c_remote.c index 3f09cdd72898..5835e0b9f4a5 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_remote.c +++ b/drivers/media/i2c/maxim4c/maxim4c_remote.c @@ -8,48 +8,129 @@ * */ #include +#include #include #include "maxim4c_api.h" -static struct mfd_cell maxim4c_remote_devs[MAXIM4C_LINK_ID_MAX]; +static const char *maxim4c_remote_devs_name[MAXIM4C_LINK_ID_MAX] = { + "remote0", "remote1", "remote2", "remote3" +}; + +static const char *maxim4c_remote_link_compat[MAXIM4C_LINK_ID_MAX] = { + "maxim4c,link0", "maxim4c,link1", "maxim4c,link2", "maxim4c,link3" +}; + +static int maxim4c_remote_dev_info_parse(struct device *dev, + struct mfd_cell *remote_mfd_dev, u8 link_id) +{ + struct device_node *node = NULL; + const char *remote_device_name = "serdes-remote-device"; + const char *prop_str = NULL, *link_compat = NULL; + u32 sub_idx = 0, remote_id = 0; + int ret = 0; + + node = NULL; + sub_idx = 0; + while ((node = of_get_next_child(dev->of_node, node))) { + if (!strncasecmp(node->name, + remote_device_name, + strlen(remote_device_name))) { + if (sub_idx >= MAXIM4C_LINK_ID_MAX) { + dev_err(dev, "%pOF: Too many matching %s node\n", + dev->of_node, remote_device_name); + + of_node_put(node); + break; + } + + if (!of_device_is_available(node)) { + dev_info(dev, "%pOF is disabled\n", node); + + sub_idx++; + + continue; + } + + /* remote id */ + ret = of_property_read_u32(node, "remote-id", &remote_id); + if (ret) { + sub_idx++; + + continue; + } + if (remote_id >= MAXIM4C_LINK_ID_MAX) { + sub_idx++; + + continue; + } + + if (remote_id != link_id) { + sub_idx++; + + continue; + } + + dev_info(dev, "remote device id = %d\n", remote_id); + + ret = of_property_read_string(node, "compatible", &prop_str); + if (ret) { + dev_err(dev, "%pOF no compatible error\n", node); + + of_node_put(node); + return -EINVAL; + } + + link_compat = maxim4c_remote_link_compat[remote_id]; + if (!strncasecmp(prop_str, + link_compat, strlen(link_compat))) { + dev_info(dev, "compatible property: %s\n", prop_str); + + remote_mfd_dev->name = maxim4c_remote_devs_name[remote_id]; + remote_mfd_dev->of_compatible = prop_str; + + of_node_put(node); + return 0; + } + + dev_err(dev, "%pOF compatible and remote_id mismatch\n", node); + + of_node_put(node); + return -EINVAL; + } + } + + return -EINVAL; +} static int maxim4c_remote_mfd_devs_init(maxim4c_t *maxim4c) { struct device *dev = &maxim4c->client->dev; maxim4c_gmsl_link_t *gmsl_link = &maxim4c->gmsl_link; - struct maxim4c_link_cfg *link_cfg = NULL; struct mfd_cell *remote_mfd_dev = NULL; - const char *remote_name = NULL, *remote_compatible = NULL; int link_idx = 0, nr_mfd_cell = 0; + int ret = 0; - remote_mfd_dev = maxim4c_remote_devs; + remote_mfd_dev = maxim4c->remote_mfd_devs; nr_mfd_cell = 0; for (link_idx = 0; link_idx < MAXIM4C_LINK_ID_MAX; link_idx++) { - link_cfg = &gmsl_link->link_cfg[link_idx]; - if (link_cfg->link_enable == 0) - continue; + remote_mfd_dev->name = NULL; + remote_mfd_dev->of_compatible = NULL; - remote_name = link_cfg->remote_info.remote_name; - remote_compatible = link_cfg->remote_info.remote_compatible; - if (remote_compatible == NULL) { - dev_err(dev, "%s: link id = %d, remote compatible = NULL", - __func__, link_idx); + if (gmsl_link->link_cfg[link_idx].link_enable == 0) { + dev_dbg(dev, "%s: link id = %d is disabled\n", + __func__, link_idx); continue; } - if (remote_name == NULL) { - dev_err(dev, "%s: link id = %d, remote name = NULL", - __func__, link_idx); - continue; + ret = maxim4c_remote_dev_info_parse(dev, remote_mfd_dev, link_idx); + if (ret == 0) { + remote_mfd_dev++; + nr_mfd_cell++; } - - remote_mfd_dev->name = remote_name; - remote_mfd_dev->of_compatible = remote_compatible; - - remote_mfd_dev++; - nr_mfd_cell++; } + dev_info(dev, "Total number of remote devices is %d", nr_mfd_cell); + return nr_mfd_cell; } @@ -58,19 +139,21 @@ int maxim4c_remote_mfd_add_devices(maxim4c_t *maxim4c) struct device *dev = &maxim4c->client->dev; int nr_mfd_cell = 0, ret = 0; + dev_info(dev, "=== maxim4c add remote devices ==="); + nr_mfd_cell = maxim4c_remote_mfd_devs_init(maxim4c); if (nr_mfd_cell == 0) { dev_err(dev, "%s: remote mfd devices init error\n", - __func__); + __func__); return -EINVAL; } ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, - maxim4c_remote_devs, nr_mfd_cell, + maxim4c->remote_mfd_devs, nr_mfd_cell, NULL, 0, NULL); if (ret) dev_err(dev, "%s: add remote mfd devices error: %d\n", - __func__, ret); + __func__, ret); return ret; } @@ -87,14 +170,14 @@ int maxim4c_remote_devices_init(maxim4c_t *maxim4c, u8 link_init_mask) dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask); for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) { - link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable; - if (link_enable == 0) { - dev_info(dev, "link id = %d is disabled\n", i); + if ((link_init_mask & BIT(i)) == 0) { + dev_dbg(dev, "link id = %d init mask is disabled\n", i); continue; } - if ((link_init_mask & BIT(i)) == 0) { - dev_info(dev, "link id = %d init mask is disabled\n", i); + link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable; + if (link_enable == 0) { + dev_info(dev, "link id = %d is disabled\n", i); continue; } @@ -143,14 +226,14 @@ int maxim4c_remote_devices_deinit(maxim4c_t *maxim4c, u8 link_init_mask) dev_dbg(dev, "%s: link init mask = 0x%02x\n", __func__, link_init_mask); for (i = 0; i < MAXIM4C_LINK_ID_MAX; i++) { - link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable; - if (link_enable == 0) { - dev_info(dev, "link id = %d is disabled\n", i); + if ((link_init_mask & BIT(i)) == 0) { + dev_dbg(dev, "link id = %d init mask is disabled\n", i); continue; } - if ((link_init_mask & BIT(i)) == 0) { - dev_info(dev, "link id = %d init mask is disabled\n", i); + link_enable = maxim4c->gmsl_link.link_cfg[i].link_enable; + if (link_enable == 0) { + dev_info(dev, "link id = %d is disabled\n", i); continue; } @@ -196,54 +279,156 @@ int maxim4c_remote_load_init_seq(maxim4c_remote_t *remote_device) node = of_get_child_by_name(dev->of_node, "remote-init-sequence"); if (!IS_ERR_OR_NULL(node)) { + dev_info(dev, "load remote-init-sequence\n"); + ret = maxim4c_i2c_load_init_seq(dev, node, &remote_device->remote_init_seq); of_node_put(node); - - } else { - ret = 0; - dev_info(dev, "no node remote-init-sequence\n"); + return ret; } - return ret; + return 0; } EXPORT_SYMBOL(maxim4c_remote_load_init_seq); +int maxim4c_remote_i2c_addr_select(maxim4c_remote_t *remote_device, u32 i2c_id) +{ + struct device *dev = remote_device->dev; + struct i2c_client *client = remote_device->client; + + if (i2c_id == MAXIM4C_I2C_SER_DEF) { + client->addr = remote_device->ser_i2c_addr_def; + dev_info(dev, "ser select default i2c addr = 0x%02x\n", client->addr); + } else if (i2c_id == MAXIM4C_I2C_SER_MAP) { + client->addr = remote_device->ser_i2c_addr_map; + dev_info(dev, "ser select mapping i2c addr = 0x%02x\n", client->addr); + } else { + dev_err(dev, "i2c select id = %d error\n", i2c_id); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL(maxim4c_remote_i2c_addr_select); + +int maxim4c_remote_i2c_client_init(maxim4c_remote_t *remote_device, + struct i2c_client *des_client) +{ + struct device *dev = remote_device->dev; + struct i2c_client *ser_client = NULL; + u16 ser_client_addr = 0; + + if (remote_device->ser_i2c_addr_map) + ser_client_addr = remote_device->ser_i2c_addr_map; + else + ser_client_addr = remote_device->ser_i2c_addr_def; + ser_client = devm_i2c_new_dummy_device(&des_client->dev, + des_client->adapter, ser_client_addr); + if (IS_ERR(ser_client)) { + dev_err(dev, "failed to alloc i2c client.\n"); + return -PTR_ERR(ser_client); + } + ser_client->addr = remote_device->ser_i2c_addr_def; + + remote_device->client = ser_client; + i2c_set_clientdata(ser_client, remote_device); + + dev_info(dev, "remote i2c client init, i2c_addr = 0x%02x\n", + ser_client_addr); + + return 0; +} +EXPORT_SYMBOL(maxim4c_remote_i2c_client_init); + +static int maxim4c_remote_device_chain_check(maxim4c_remote_t *remote_device) +{ + struct device *dev = NULL; + struct device_node *endpoint = NULL; + struct device_node *link_node = NULL; + u8 remote_id, link_id; + u32 value; + int ret = 0; + + if (remote_device == NULL) { + dev_err(dev, "%s: input parameter is error\n", __func__); + return -EINVAL; + } + + dev = remote_device->dev; + remote_id = remote_device->remote_id; + + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) { + dev_err(dev, "%s: no endpoint error\n", __func__); + return -EINVAL; + } + + link_node = of_graph_get_remote_port_parent(endpoint); + if (!link_node) { + dev_err(dev, "%pOF: endpoint has no remote port parent error\n", + endpoint); + return -EINVAL; + } + + ret = of_property_read_u32(link_node, "link-id", &value); + if (ret) { + dev_err(dev, "%pOF: no property link_id error\n", link_node); + + of_node_put(link_node); + return -EINVAL; + } + of_node_put(link_node); + link_id = value; + + if (remote_id != link_id) { + dev_err(dev, "remote_id (%d) != link_id (%d) of %pOF\n", + remote_id, link_id, link_node); + return -EINVAL; + } + + return 0; +} + int maxim4c_remote_device_register(maxim4c_t *maxim4c, maxim4c_remote_t *remote_device) { struct device *dev = NULL; u8 remote_id; + int ret = 0; if ((maxim4c == NULL) || (remote_device == NULL)) { - dev_err(dev, "%s: input parameter is error!\n", - __func__); + dev_err(dev, "%s: input parameter is error!\n", __func__); return -EINVAL; } dev = remote_device->dev; remote_id = remote_device->remote_id; - if (remote_id < MAXIM4C_LINK_ID_MAX) { - if (maxim4c->remote_device[remote_id] == NULL) { - remote_device->remote_enable = 1; - maxim4c->remote_device[remote_id] = remote_device; - dev_dbg(dev, "%s: remote_id = %d is success\n", - __func__, remote_id); - - return 0; - } else { - dev_err(dev, "%s: remote_id = %d is conflict\n", - __func__, remote_id); - - return -EINVAL; - } - } else { + if (remote_id >= MAXIM4C_LINK_ID_MAX) { dev_err(dev, "%s: remote_id = %d is error\n", - __func__, remote_id); + __func__, remote_id); return -EINVAL; } + + if (maxim4c->remote_device[remote_id] != NULL) { + dev_err(dev, "%s: remote_id = %d is conflict\n", + __func__, remote_id); + + return -EINVAL; + } + + ret = maxim4c_remote_device_chain_check(remote_device); + if (ret) { + dev_err(dev, "%s: remote device id = %d chain error\n", + __func__, remote_id); + return -EINVAL; + } + + remote_device->remote_enable = 1; + maxim4c->remote_device[remote_id] = remote_device; + + return 0; } EXPORT_SYMBOL(maxim4c_remote_device_register); diff --git a/drivers/media/i2c/maxim4c/maxim4c_v4l2.c b/drivers/media/i2c/maxim4c/maxim4c_v4l2.c index f8838d6615c2..37df9a622f59 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_v4l2.c +++ b/drivers/media/i2c/maxim4c/maxim4c_v4l2.c @@ -95,6 +95,11 @@ static int maxim4c_support_mode_init(maxim4c_t *maxim4c) dev_info(dev, "=== maxim4c support mode init ===\n"); +#if MAXIM4C_TEST_PATTERN + ret = maxim4c_pattern_support_mode_init(maxim4c); + return ret; +#endif + maxim4c->cfg_modes_num = 1; maxim4c->cur_mode = &maxim4c->supported_mode; mode = &maxim4c->supported_mode; @@ -311,14 +316,12 @@ static long maxim4c_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) break; case RKMODULE_SET_CSI_DPHY_PARAM: dphy_param = (struct rkmodule_csi_dphy_param *)arg; - if (dphy_param->vendor == rk3588_dcphy_param.vendor) - rk3588_dcphy_param = *dphy_param; + rk3588_dcphy_param = *dphy_param; dev_dbg(&maxim4c->client->dev, "set dcphy param\n"); break; case RKMODULE_GET_CSI_DPHY_PARAM: dphy_param = (struct rkmodule_csi_dphy_param *)arg; - if (dphy_param->vendor == rk3588_dcphy_param.vendor) - *dphy_param = rk3588_dcphy_param; + *dphy_param = rk3588_dcphy_param; dev_dbg(&maxim4c->client->dev, "get dcphy param\n"); break; default: @@ -430,6 +433,22 @@ static int __maxim4c_start_stream(struct maxim4c *maxim4c) u8 link_mask = 0, link_freq_idx = 0; u8 video_pipe_mask = 0; +#if MAXIM4C_LOCAL_DES_ON_OFF_EN +#if MAXIM4C_TEST_PATTERN + ret = maxim4c_pattern_hw_init(maxim4c); + if (ret) { + dev_err(dev, "test pattern hw init error\n"); + return ret; + } +#else + ret = maxim4c_module_hw_init(maxim4c); + if (ret) { + dev_err(dev, "maxim4c module hw init error\n"); + return ret; + } +#endif /* MAXIM4C_TEST_PATTERN */ +#endif /* MAXIM4C_LOCAL_DES_ON_OFF_EN */ + link_mask = maxim4c->gmsl_link.link_enable_mask; video_pipe_mask = maxim4c->video_pipe.pipe_enable_mask; diff --git a/drivers/media/i2c/maxim4c/maxim4c_video_pipe.c b/drivers/media/i2c/maxim4c/maxim4c_video_pipe.c index 71adca30b13a..e47e778a289a 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_video_pipe.c +++ b/drivers/media/i2c/maxim4c/maxim4c_video_pipe.c @@ -100,8 +100,8 @@ static int maxim4c_video_pipe_config_parse_dt(struct device *dev, pipe_cfg_name, strlen(pipe_cfg_name))) { if (sub_idx >= MAXIM4C_PIPE_O_ID_MAX) { - dev_err(dev, "Too many matching %s node\n", - pipe_cfg_name); + dev_err(dev, "%pOF: Too many matching %s node\n", + parent_node, pipe_cfg_name); of_node_put(node); break; @@ -205,8 +205,11 @@ int maxim4c_video_pipe_parse_dt(maxim4c_t *maxim4c, struct device_node *of_node) dev_info(dev, "=== maxim4c video pipe parse dt ===\n"); node = of_get_child_by_name(of_node, "video-pipes"); - if (IS_ERR_OR_NULL(node)) + if (IS_ERR_OR_NULL(node)) { + dev_err(dev, "%pOF has no child node: video-pipes\n", + of_node); return -ENODEV; + } if (!of_device_is_available(node)) { dev_info(dev, "%pOF is disabled\n", node); @@ -325,21 +328,28 @@ EXPORT_SYMBOL(maxim4c_video_pipe_data_init); int maxim4c_video_pipe_hw_init(maxim4c_t *maxim4c) { + struct device *dev = &maxim4c->client->dev; u8 pipe_enable_mask = 0; int ret = 0; ret = maxim4c_video_pipe_select(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: video pipe select error\n", __func__); return ret; + } pipe_enable_mask = maxim4c->video_pipe.pipe_enable_mask; ret = maxim4c_video_pipe_mask_enable(maxim4c, pipe_enable_mask, true); - if (ret) + if (ret) { + dev_err(dev, "%s: video pipe mask enable error\n", __func__); return ret; + } ret = maxim4c_video_pipe_run_init_seq(maxim4c); - if (ret) + if (ret) { + dev_err(dev, "%s: video pipe run init seq error\n", __func__); return ret; + } return 0; } diff --git a/drivers/media/i2c/maxim4c/remote_max9295.c b/drivers/media/i2c/maxim4c/remote_max9295.c index 78cd2b3555bd..b0505164e26e 100644 --- a/drivers/media/i2c/maxim4c/remote_max9295.c +++ b/drivers/media/i2c/maxim4c/remote_max9295.c @@ -20,25 +20,6 @@ #define MAX9295_CHIP_ID 0x91 #define MAX9295_REG_CHIP_ID 0x0D -static int max9295_i2c_addr_select(maxim4c_remote_t *max9295, u32 i2c_id) -{ - struct device *dev = max9295->dev; - struct i2c_client *client = max9295->client; - - if (i2c_id == MAXIM4C_I2C_SER_DEF) { - client->addr = max9295->ser_i2c_addr_def; - dev_info(dev, "select default i2c addr = 0x%x\n", client->addr); - } else if (i2c_id == MAXIM4C_I2C_SER_MAP) { - client->addr = max9295->ser_i2c_addr_map; - dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr); - } else { - dev_err(dev, "i2c select id = %d error\n", i2c_id); - return -EINVAL; - } - - return 0; -} - static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295) { struct device *dev = max9295->dev; @@ -49,7 +30,7 @@ static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295) if (max9295->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address remap\n"); - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); i2c_8bit_addr = (max9295->ser_i2c_addr_map << 1); ret = maxim4c_i2c_write_byte(client, @@ -60,7 +41,7 @@ static int max9295_i2c_addr_remap(maxim4c_remote_t *max9295) return ret; } - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); } if (max9295->cam_i2c_addr_map) { @@ -98,7 +79,7 @@ static int max9295_i2c_addr_def(maxim4c_remote_t *max9295) if (max9295->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address def\n"); - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); i2c_8bit_addr = (max9295->ser_i2c_addr_def << 1); ret = maxim4c_i2c_write_byte(client, @@ -109,7 +90,7 @@ static int max9295_i2c_addr_def(maxim4c_remote_t *max9295) return ret; } - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); } return 0; @@ -128,13 +109,13 @@ static int max9295_check_chipid(maxim4c_remote_t *max9295) &chip_id); if (ret != 0) { dev_info(dev, "Retry check chipid using map address\n"); - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_MAP); ret = maxim4c_i2c_read_byte(client, MAX9295_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS, &chip_id); if (ret != 0) { dev_err(dev, "MAX9295 detect error, ret(%d)\n", ret); - max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); return -ENODEV; } @@ -143,13 +124,13 @@ static int max9295_check_chipid(maxim4c_remote_t *max9295) } if (chip_id != MAX9295_CHIP_ID) { - dev_err(dev, "Unexpected MAX9295 chip id(%02x)\n", chip_id); + dev_err(dev, "Unexpected chip id = %02x\n", chip_id); return -ENODEV; } - dev_info(dev, "Detected MAX9295 chipid: 0x%02x\n", chip_id); + dev_info(dev, "Detected MAX9295 chip id: 0x%02x\n", chip_id); - return ret; + return 0; } static int max9295_soft_power_down(maxim4c_remote_t *max9295) @@ -175,7 +156,7 @@ static int max9295_module_init(maxim4c_remote_t *max9295) struct i2c_client *client = max9295->client; int ret = 0; - ret = max9295_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); + ret = maxim4c_remote_i2c_addr_select(max9295, MAXIM4C_I2C_SER_DEF); if (ret) return ret; @@ -263,47 +244,30 @@ static int max9295_parse_dt(maxim4c_remote_t *max9295) return 0; } -static int max9295_i2c_client_init(maxim4c_remote_t *max9295, - struct i2c_client *local_client) -{ - struct device *dev = max9295->dev; - struct i2c_client *remote_client = NULL; - u16 remote_client_addr = 0; - - if (max9295->ser_i2c_addr_map) - remote_client_addr = max9295->ser_i2c_addr_map; - else - remote_client_addr = max9295->ser_i2c_addr_def; - remote_client = devm_i2c_new_dummy_device(&local_client->dev, - local_client->adapter, remote_client_addr); - if (IS_ERR(remote_client)) { - dev_err(dev, "failed to alloc i2c client.\n"); - return -PTR_ERR(remote_client); - } - remote_client->addr = max9295->ser_i2c_addr_def; - - max9295->client = remote_client; - i2c_set_clientdata(remote_client, max9295); - - dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n", - remote_client_addr); - - return 0; -} - static int max9295_probe(struct platform_device *pdev) { struct i2c_client *client = to_i2c_client(pdev->dev.parent); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct maxim4c *maxim4c = v4l2_get_subdevdata(sd); struct maxim4c_remote *max9295 = NULL; + u32 link_id = MAXIM4C_LINK_ID_MAX; int ret = 0; dev_info(&pdev->dev, "max9295 serializer probe\n"); + link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); + link_id = link_id - MAXIM4C_LINK_ID_MAX; + if (link_id >= MAXIM4C_LINK_ID_MAX) { + dev_err(&pdev->dev, "max9295 probe match data error\n"); + return -EINVAL; + } + dev_info(&pdev->dev, "max9295 probe link id = %d\n", link_id); + max9295 = devm_kzalloc(&pdev->dev, sizeof(*max9295), GFP_KERNEL); - if (!max9295) + if (!max9295) { + dev_err(&pdev->dev, "max9295 probe no memory error\n"); return -ENOMEM; + } max9295->dev = &pdev->dev; max9295->remote_ops = &max9295_ops; @@ -312,11 +276,22 @@ static int max9295_probe(struct platform_device *pdev) max9295_parse_dt(max9295); - max9295_i2c_client_init(max9295, client); + if (max9295->remote_id != link_id) { + dev_err(&pdev->dev, "max9295 probe remote_id error\n"); + return -EINVAL; + } + + ret = maxim4c_remote_i2c_client_init(max9295, client); + if (ret) { + dev_err(&pdev->dev, "remote i2c client init error\n"); + return ret; + } ret = maxim4c_remote_device_register(maxim4c, max9295); - if (ret) + if (ret) { + dev_err(&pdev->dev, "remote serializer register error\n"); return ret; + } maxim4c_remote_load_init_seq(max9295); @@ -329,10 +304,21 @@ static int max9295_remove(struct platform_device *pdev) } static const struct of_device_id max9295_of_table[] = { - { .compatible = "maxim4c,max9295", }, + { + .compatible = "maxim4c,link0,max9295", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A) + }, { + .compatible = "maxim4c,link1,max9295", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B) + }, { + .compatible = "maxim4c,link2,max9295", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C) + }, { + .compatible = "maxim4c,link3,max9295", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D) + }, { /* Sentinel */ }, }; - MODULE_DEVICE_TABLE(of, max9295_of_table); static struct platform_driver max9295_driver = { diff --git a/drivers/media/i2c/maxim4c/remote_max96715.c b/drivers/media/i2c/maxim4c/remote_max96715.c index 63ebfb798f03..3f2689a1b8df 100644 --- a/drivers/media/i2c/maxim4c/remote_max96715.c +++ b/drivers/media/i2c/maxim4c/remote_max96715.c @@ -34,43 +34,28 @@ static int __maybe_unused max96715_link_mode_select(maxim4c_remote_t *max96715, struct device *dev = max96715->dev; struct i2c_client *client = max96715->client; u8 reg_mask = 0, reg_value = 0; + u32 delay_ms = 0; int ret = 0; dev_dbg(dev, "%s: mode = %d\n", __func__, mode); reg_mask = BIT(7) | BIT(6); - if (mode == LINK_MODE_CONFIG) + if (mode == LINK_MODE_CONFIG) { reg_value = BIT(6); - else + delay_ms = 5; + } else { reg_value = BIT(7); + delay_ms = 50; + } ret |= maxim4c_i2c_update_byte(client, 0x04, MAXIM4C_I2C_REG_ADDR_08BITS, reg_mask, reg_value); - mdelay(5); + msleep(delay_ms); return ret; } -static int max96715_i2c_addr_select(maxim4c_remote_t *max96715, u32 i2c_id) -{ - struct device *dev = max96715->dev; - struct i2c_client *client = max96715->client; - - if (i2c_id == MAXIM4C_I2C_SER_DEF) { - client->addr = max96715->ser_i2c_addr_def; - dev_info(dev, "select default i2c addr = 0x%x\n", client->addr); - } else if (i2c_id == MAXIM4C_I2C_SER_MAP) { - client->addr = max96715->ser_i2c_addr_map; - dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr); - } else { - dev_err(dev, "i2c select id = %d error\n", i2c_id); - return -EINVAL; - } - - return 0; -} - static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715) { struct device *dev = max96715->dev; @@ -81,7 +66,7 @@ static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715) if (max96715->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address remap\n"); - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); i2c_8bit_addr = (max96715->ser_i2c_addr_map << 1); ret = maxim4c_i2c_write_byte(client, @@ -92,7 +77,7 @@ static int max96715_i2c_addr_remap(maxim4c_remote_t *max96715) return ret; } - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); } if (max96715->cam_i2c_addr_map) { @@ -130,7 +115,7 @@ static int max96715_i2c_addr_def(maxim4c_remote_t *max96715) if (max96715->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address def\n"); - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); i2c_8bit_addr = (max96715->ser_i2c_addr_def << 1); ret = maxim4c_i2c_write_byte(client, @@ -141,7 +126,7 @@ static int max96715_i2c_addr_def(maxim4c_remote_t *max96715) return ret; } - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); } return 0; @@ -160,13 +145,13 @@ static int max96715_check_chipid(maxim4c_remote_t *max96715) &chip_id); if (ret != 0) { dev_info(dev, "Retry check chipid using map address\n"); - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_MAP); ret = maxim4c_i2c_read_byte(client, MAX96715_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_08BITS, &chip_id); if (ret != 0) { dev_err(dev, "MAX96715 detect error, ret(%d)\n", ret); - max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); return -ENODEV; } @@ -175,13 +160,13 @@ static int max96715_check_chipid(maxim4c_remote_t *max96715) } if (chip_id != MAX96715_CHIP_ID) { - dev_err(dev, "Unexpected MAX96715 chip id(%02x)\n", chip_id); + dev_err(dev, "Unexpected chip id = %02x\n", chip_id); return -ENODEV; } - dev_info(dev, "Detected MAX96715 chipid: 0x%02x\n", chip_id); + dev_info(dev, "Detected MAX96715 chip id: 0x%02x\n", chip_id); - return ret; + return 0; } static int max96715_soft_power_down(maxim4c_remote_t *max96715) @@ -208,7 +193,7 @@ static int max96715_module_init(maxim4c_remote_t *max96715) struct maxim4c *maxim4c = max96715->local; int ret = 0; - ret = max96715_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); + ret = maxim4c_remote_i2c_addr_select(max96715, MAXIM4C_I2C_SER_DEF); if (ret) return ret; @@ -322,47 +307,30 @@ static int max96715_parse_dt(maxim4c_remote_t *max96715) return 0; } -static int max96715_i2c_client_init(maxim4c_remote_t *max96715, - struct i2c_client *local_client) -{ - struct device *dev = max96715->dev; - struct i2c_client *remote_client = NULL; - u16 remote_client_addr = 0; - - if (max96715->ser_i2c_addr_map) - remote_client_addr = max96715->ser_i2c_addr_map; - else - remote_client_addr = max96715->ser_i2c_addr_def; - remote_client = devm_i2c_new_dummy_device(&local_client->dev, - local_client->adapter, remote_client_addr); - if (IS_ERR(remote_client)) { - dev_err(dev, "failed to alloc i2c client.\n"); - return -PTR_ERR(remote_client); - } - remote_client->addr = max96715->ser_i2c_addr_def; - - max96715->client = remote_client; - i2c_set_clientdata(remote_client, max96715); - - dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n", - remote_client_addr); - - return 0; -} - static int max96715_probe(struct platform_device *pdev) { struct i2c_client *client = to_i2c_client(pdev->dev.parent); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct maxim4c *maxim4c = v4l2_get_subdevdata(sd); struct maxim4c_remote *max96715 = NULL; + u32 link_id = MAXIM4C_LINK_ID_MAX; int ret = 0; dev_info(&pdev->dev, "max96715 serializer probe\n"); + link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); + link_id = link_id - MAXIM4C_LINK_ID_MAX; + if (link_id >= MAXIM4C_LINK_ID_MAX) { + dev_err(&pdev->dev, "max96715 probe match data error\n"); + return -EINVAL; + } + dev_info(&pdev->dev, "max96715 probe link id = %d\n", link_id); + max96715 = devm_kzalloc(&pdev->dev, sizeof(*max96715), GFP_KERNEL); - if (!max96715) + if (!max96715) { + dev_err(&pdev->dev, "max96715 probe no memory error\n"); return -ENOMEM; + } max96715->dev = &pdev->dev; max96715->remote_ops = &max96715_ops; @@ -371,11 +339,22 @@ static int max96715_probe(struct platform_device *pdev) max96715_parse_dt(max96715); - max96715_i2c_client_init(max96715, client); + if (max96715->remote_id != link_id) { + dev_err(&pdev->dev, "max96715 probe remote_id error\n"); + return -EINVAL; + } + + ret = maxim4c_remote_i2c_client_init(max96715, client); + if (ret) { + dev_err(&pdev->dev, "remote i2c client init error\n"); + return ret; + } ret = maxim4c_remote_device_register(maxim4c, max96715); - if (ret) + if (ret) { + dev_err(&pdev->dev, "remote serializer register error\n"); return ret; + } maxim4c_remote_load_init_seq(max96715); @@ -388,10 +367,21 @@ static int max96715_remove(struct platform_device *pdev) } static const struct of_device_id max96715_of_table[] = { - { .compatible = "maxim4c,max96715", }, + { + .compatible = "maxim4c,link0,max96715", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A) + }, { + .compatible = "maxim4c,link1,max96715", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B) + }, { + .compatible = "maxim4c,link2,max96715", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C) + }, { + .compatible = "maxim4c,link3,max96715", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D) + }, { /* Sentinel */ }, }; - MODULE_DEVICE_TABLE(of, max96715_of_table); static struct platform_driver max96715_driver = { diff --git a/drivers/media/i2c/maxim4c/remote_max96717.c b/drivers/media/i2c/maxim4c/remote_max96717.c index f8740e35d446..d0a3b7d55d64 100644 --- a/drivers/media/i2c/maxim4c/remote_max96717.c +++ b/drivers/media/i2c/maxim4c/remote_max96717.c @@ -20,25 +20,6 @@ #define MAX96717_CHIP_ID 0xBF #define MAX96717_REG_CHIP_ID 0x0D -static int max96717_i2c_addr_select(maxim4c_remote_t *max96717, u32 i2c_id) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - - if (i2c_id == MAXIM4C_I2C_SER_DEF) { - client->addr = max96717->ser_i2c_addr_def; - dev_info(dev, "select default i2c addr = 0x%x\n", client->addr); - } else if (i2c_id == MAXIM4C_I2C_SER_MAP) { - client->addr = max96717->ser_i2c_addr_map; - dev_info(dev, "select mapping i2c addr = 0x%x\n", client->addr); - } else { - dev_err(dev, "i2c select id = %d error\n", i2c_id); - return -EINVAL; - } - - return 0; -} - static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717) { struct device *dev = max96717->dev; @@ -49,7 +30,7 @@ static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717) if (max96717->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address remap\n"); - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); i2c_8bit_addr = (max96717->ser_i2c_addr_map << 1); ret = maxim4c_i2c_write_byte(client, @@ -60,7 +41,7 @@ static int max96717_i2c_addr_remap(maxim4c_remote_t *max96717) return ret; } - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); } if (max96717->cam_i2c_addr_map) { @@ -98,7 +79,7 @@ static int max96717_i2c_addr_def(maxim4c_remote_t *max96717) if (max96717->ser_i2c_addr_map) { dev_info(dev, "Serializer i2c address def\n"); - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); i2c_8bit_addr = (max96717->ser_i2c_addr_def << 1); ret = maxim4c_i2c_write_byte(client, @@ -109,7 +90,7 @@ static int max96717_i2c_addr_def(maxim4c_remote_t *max96717) return ret; } - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); } return 0; @@ -128,13 +109,13 @@ static int max96717_check_chipid(maxim4c_remote_t *max96717) &chip_id); if (ret != 0) { dev_info(dev, "Retry check chipid using map address\n"); - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_MAP); ret = maxim4c_i2c_read_byte(client, MAX96717_REG_CHIP_ID, MAXIM4C_I2C_REG_ADDR_16BITS, &chip_id); if (ret != 0) { dev_err(dev, "MAX96717 detect error, ret(%d)\n", ret); - max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); + maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); return -ENODEV; } @@ -143,27 +124,10 @@ static int max96717_check_chipid(maxim4c_remote_t *max96717) } if (chip_id != MAX96717_CHIP_ID) { - dev_err(dev, "Unexpected MAX96717 chip id(%02x)\n", chip_id); + dev_err(dev, "Unexpected chip id = %02x\n", chip_id); return -ENODEV; } - dev_info(dev, "Detected MAX96717 chipid: 0x%02x\n", chip_id); - - return ret; -} - -static int max96717_soft_power_down(maxim4c_remote_t *max96717) -{ - struct device *dev = max96717->dev; - struct i2c_client *client = max96717->client; - int ret = 0; - - ret = maxim4c_i2c_write_byte(client, - 0x10, MAXIM4C_I2C_REG_ADDR_16BITS, - BIT(7)); - if (ret) { - dev_err(dev, "soft power down setting error!\n"); - return ret; - } + dev_info(dev, "Detected MAX96717 chip id: 0x%02x\n", chip_id); return 0; } @@ -174,7 +138,7 @@ static int max96717_module_init(maxim4c_remote_t *max96717) struct i2c_client *client = max96717->client; int ret = 0; - ret = max96717_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); + ret = maxim4c_remote_i2c_addr_select(max96717, MAXIM4C_I2C_SER_DEF); if (ret) return ret; @@ -201,10 +165,7 @@ static int max96717_module_deinit(maxim4c_remote_t *max96717) { int ret = 0; -#if 0 ret |= max96717_i2c_addr_def(max96717); -#endif - ret |= max96717_soft_power_down(max96717); return ret; } @@ -262,47 +223,30 @@ static int max96717_parse_dt(maxim4c_remote_t *max96717) return 0; } -static int max96717_i2c_client_init(maxim4c_remote_t *max96717, - struct i2c_client *local_client) -{ - struct device *dev = max96717->dev; - struct i2c_client *remote_client = NULL; - u16 remote_client_addr = 0; - - if (max96717->ser_i2c_addr_map) - remote_client_addr = max96717->ser_i2c_addr_map; - else - remote_client_addr = max96717->ser_i2c_addr_def; - remote_client = devm_i2c_new_dummy_device(&local_client->dev, - local_client->adapter, remote_client_addr); - if (IS_ERR(remote_client)) { - dev_err(dev, "failed to alloc i2c client.\n"); - return -PTR_ERR(remote_client); - } - remote_client->addr = max96717->ser_i2c_addr_def; - - max96717->client = remote_client; - i2c_set_clientdata(remote_client, max96717); - - dev_info(dev, "remote i2c client init, i2c_addr = 0x%x\n", - remote_client_addr); - - return 0; -} - static int max96717_probe(struct platform_device *pdev) { struct i2c_client *client = to_i2c_client(pdev->dev.parent); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct maxim4c *maxim4c = v4l2_get_subdevdata(sd); struct maxim4c_remote *max96717 = NULL; + u32 link_id = MAXIM4C_LINK_ID_MAX; int ret = 0; dev_info(&pdev->dev, "max96717 serializer probe\n"); + link_id = (uintptr_t)of_device_get_match_data(&pdev->dev); + link_id = link_id - MAXIM4C_LINK_ID_MAX; + if (link_id >= MAXIM4C_LINK_ID_MAX) { + dev_err(&pdev->dev, "max96717 probe match data error\n"); + return -EINVAL; + } + dev_info(&pdev->dev, "max96717 probe link id = %d\n", link_id); + max96717 = devm_kzalloc(&pdev->dev, sizeof(*max96717), GFP_KERNEL); - if (!max96717) + if (!max96717) { + dev_err(&pdev->dev, "max96717 probe no memory error\n"); return -ENOMEM; + } max96717->dev = &pdev->dev; max96717->remote_ops = &max96717_ops; @@ -311,11 +255,22 @@ static int max96717_probe(struct platform_device *pdev) max96717_parse_dt(max96717); - max96717_i2c_client_init(max96717, client); + if (max96717->remote_id != link_id) { + dev_err(&pdev->dev, "max96717 probe remote_id error\n"); + return -EINVAL; + } + + ret = maxim4c_remote_i2c_client_init(max96717, client); + if (ret) { + dev_err(&pdev->dev, "remote i2c client init error\n"); + return ret; + } ret = maxim4c_remote_device_register(maxim4c, max96717); - if (ret) + if (ret) { + dev_err(&pdev->dev, "remote serializer register error\n"); return ret; + } maxim4c_remote_load_init_seq(max96717); @@ -328,10 +283,21 @@ static int max96717_remove(struct platform_device *pdev) } static const struct of_device_id max96717_of_table[] = { - { .compatible = "maxim4c,max96717", }, + { + .compatible = "maxim4c,link0,max96717", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_A) + }, { + .compatible = "maxim4c,link1,max96717", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_B) + }, { + .compatible = "maxim4c,link2,max96717", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_C) + }, { + .compatible = "maxim4c,link3,max96717", + .data = (const void *)(MAXIM4C_LINK_ID_MAX + MAXIM4C_LINK_ID_D) + }, { /* Sentinel */ }, }; - MODULE_DEVICE_TABLE(of, max96717_of_table); static struct platform_driver max96717_driver = { diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c index 1d745b49da5c..dcd49b65ea94 100644 --- a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c +++ b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c @@ -530,6 +530,16 @@ static int hdmirx_g_dv_timings(struct file *file, void *_fh, struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; u32 dma_cfg1; + if (port_no_link(hdmirx_dev)) { + v4l2_err(v4l2_dev, "%s port has no link!\n", __func__); + return -ENOLINK; + } + + if (signal_not_lock(hdmirx_dev)) { + v4l2_err(v4l2_dev, "%s signal is not locked!\n", __func__); + return -ENOLCK; + } + *timings = hdmirx_dev->timings; dma_cfg1 = hdmirx_readl(hdmirx_dev, DMA_CONFIG1); v4l2_dbg(1, debug, v4l2_dev, "%s: pix_fmt: %s, DMA_CONFIG1:%#x\n", @@ -1558,7 +1568,7 @@ static int hdmirx_wait_lock_and_get_timing(struct rk_hdmirx_dev *hdmirx_dev) } hdmirx_reset_dma(hdmirx_dev); - usleep_range(200*1000, 200*1010); + usleep_range(500*1000, 500*1010); hdmirx_format_change(hdmirx_dev); return 0; @@ -2473,13 +2483,28 @@ static void mainunit_2_int_handler(struct rk_hdmirx_dev *hdmirx_dev, hdmirx_writel(hdmirx_dev, MAINUNIT_2_INT_FORCE, 0x0); } +/* + * In the normal preview, some scenarios will trigger the change interrupt + * by mistake, and the trigger source of the interrupt needs to be detected + * to avoid the problem. + */ static void pkt_0_int_handler(struct rk_hdmirx_dev *hdmirx_dev, int status, bool *handled) { struct v4l2_device *v4l2_dev = &hdmirx_dev->v4l2_dev; + u32 pre_fmt_fourcc = hdmirx_dev->cur_fmt_fourcc; + u32 pre_color_range = hdmirx_dev->cur_color_range; + u32 pre_color_space = hdmirx_dev->cur_color_space; if ((status & PKTDEC_AVIIF_CHG_IRQ)) { - process_signal_change(hdmirx_dev); + hdmirx_get_color_range(hdmirx_dev); + hdmirx_get_color_space(hdmirx_dev); + hdmirx_get_pix_fmt(hdmirx_dev); + if (hdmirx_dev->cur_fmt_fourcc != pre_fmt_fourcc || + hdmirx_dev->cur_color_range != pre_color_range || + hdmirx_dev->cur_color_space != pre_color_space) { + process_signal_change(hdmirx_dev); + } v4l2_dbg(2, debug, v4l2_dev, "%s: ptk0_st:%#x\n", __func__, status); *handled = true; diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index 6d6d459d869d..66422973a7e0 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -1537,7 +1537,7 @@ static struct irq_chip rk_pcie_legacy_irq_chip = { static int rk_pcie_intx_map(struct irq_domain *domain, unsigned int irq, irq_hw_number_t hwirq) { - irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_simple_irq); + irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_level_irq); irq_set_chip_data(irq, domain->host_data); return 0; diff --git a/drivers/rpmsg/rockchip_rpmsg.c b/drivers/rpmsg/rockchip_rpmsg.c index 6912eae4b7e4..897712542ef7 100644 --- a/drivers/rpmsg/rockchip_rpmsg.c +++ b/drivers/rpmsg/rockchip_rpmsg.c @@ -26,11 +26,6 @@ #include "rpmsg_internal.h" -enum rk_rpmsg_chip { - RK3562, - RK3568, -}; - struct rk_virtio_dev { struct virtio_device vdev; unsigned int vring[2]; @@ -44,7 +39,6 @@ struct rk_virtio_dev { struct rk_rpmsg_dev { struct platform_device *pdev; - enum rk_rpmsg_chip chip; int vdev_nums; unsigned int link_id; int first_notify; @@ -307,7 +301,6 @@ static int rockchip_rpmsg_probe(struct platform_device *pdev) dev_info(dev, "rockchip rpmsg platform probe.\n"); rpdev->pdev = pdev; - rpdev->chip = (enum rk_rpmsg_chip)device_get_match_data(dev); rpdev->first_notify = 0; cl = &rpdev->mbox_cl; @@ -399,8 +392,7 @@ static int rockchip_rpmsg_remove(struct platform_device *pdev) } static const struct of_device_id rockchip_rpmsg_match[] = { - { .compatible = "rockchip,rk3562-rpmsg", .data = (void *)RK3562, }, - { .compatible = "rockchip,rk3568-rpmsg", .data = (void *)RK3568, }, + { .compatible = "rockchip,rpmsg", }, { /* sentinel */ }, }; diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index c5783a454b73..dd1e74183ecd 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -2104,7 +2104,7 @@ task_done_ret: if (ret < 0) return ret; - } while (ret > 0); + } while (!ret); rkvenc2_task_timeout_process(session, task); diff --git a/sound/soc/codecs/rv1106_codec.c b/sound/soc/codecs/rv1106_codec.c index f239b3319ac1..a835d8c1592a 100644 --- a/sound/soc/codecs/rv1106_codec.c +++ b/sound/soc/codecs/rv1106_codec.c @@ -97,6 +97,9 @@ struct rv1106_codec_priv { unsigned int mic_mute_l; unsigned int mic_mute_r; + /* DAC Control Manually */ + unsigned int dac_ctrl_manual; + /* For the high pass filter */ unsigned int hpf_cutoff; @@ -182,12 +185,22 @@ static int rv1106_codec_main_micbias_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); static int rv1106_codec_main_micbias_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); +static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); static const char *offon_text[2] = { [0] = "Off", [1] = "On", }; +static const char *noneoffon_text[3] = { + [0] = "None", + [1] = "Off", + [2] = "On", +}; + static const char *mute_text[2] = { [0] = "Work", [1] = "Mute", @@ -254,6 +267,11 @@ static const struct soc_enum rv1106_mic_mute_enum_array[] = { SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(mute_text), mute_text), }; +/* DAC Control Manually */ +static const struct soc_enum rv1106_dac_pa_ctrl_maunal_enum_array[] = { + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(noneoffon_text), noneoffon_text), +}; + /* ALC AGC Approximate Sample Rate */ #define AGC_ASR_NUM 8 @@ -422,6 +440,10 @@ static const struct snd_kcontrol_new rv1106_codec_dapm_controls[] = { rv1106_codec_hpmix_gain_get, rv1106_codec_hpmix_gain_put, rv1106_codec_dac_hpmix_gain_tlv), + + /* DAC Control Manually */ + SOC_ENUM_EXT("DAC Control Manually", rv1106_dac_pa_ctrl_maunal_enum_array[0], + rv1106_codec_dac_ctrl_manual_get, rv1106_codec_dac_ctrl_manual_put), }; static unsigned int using_adc_lr(enum adc_mode_e adc_mode) @@ -1015,35 +1037,47 @@ static int rv1106_codec_adc_dig_config(struct rv1106_codec_priv *rv1106, return 0; } +static int rv1106_codec_dac_mute(struct rv1106_codec_priv *rv1106, int mute) +{ + if (mute) { + /* Mute DAC HPMIX/LINEOUT */ + regmap_update_bits(rv1106->regmap, + ACODEC_DAC_ANA_CTL1, + ACODEC_DAC_L_LINEOUT_MUTE_MSK, + ACODEC_DAC_L_LINEOUT_MUTE); + regmap_update_bits(rv1106->regmap, + ACODEC_DAC_HPMIX_CTL, + ACODEC_DAC_HPMIX_MUTE_MSK, + ACODEC_DAC_HPMIX_MUTE); + rv1106_codec_pa_ctrl(rv1106, false); + } else { + /* Unmute DAC HPMIX/LINEOUT */ + regmap_update_bits(rv1106->regmap, + ACODEC_DAC_HPMIX_CTL, + ACODEC_DAC_HPMIX_MUTE_MSK, + ACODEC_DAC_HPMIX_WORK); + regmap_update_bits(rv1106->regmap, + ACODEC_DAC_ANA_CTL1, + ACODEC_DAC_L_LINEOUT_MUTE_MSK, + ACODEC_DAC_L_LINEOUT_WORK); + rv1106_codec_pa_ctrl(rv1106, true); + } + + return 0; +} + static int rv1106_mute_stream(struct snd_soc_dai *dai, int mute, int stream) { struct snd_soc_component *component = dai->component; struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (mute) { - /* Mute DAC HPMIX/LINEOUT */ - regmap_update_bits(rv1106->regmap, - ACODEC_DAC_ANA_CTL1, - ACODEC_DAC_L_LINEOUT_MUTE_MSK, - ACODEC_DAC_L_LINEOUT_MUTE); - regmap_update_bits(rv1106->regmap, - ACODEC_DAC_HPMIX_CTL, - ACODEC_DAC_HPMIX_MUTE_MSK, - ACODEC_DAC_HPMIX_MUTE); - rv1106_codec_pa_ctrl(rv1106, false); - } else { - /* Unmute DAC HPMIX/LINEOUT */ - regmap_update_bits(rv1106->regmap, - ACODEC_DAC_HPMIX_CTL, - ACODEC_DAC_HPMIX_MUTE_MSK, - ACODEC_DAC_HPMIX_WORK); - regmap_update_bits(rv1106->regmap, - ACODEC_DAC_L_LINEOUT_MUTE_MSK, - ACODEC_DAC_MUTE_MSK, - ACODEC_DAC_L_LINEOUT_WORK); - rv1106_codec_pa_ctrl(rv1106, true); - } + if (rv1106->dac_ctrl_manual == 1) + mute = 1; /* Force DAC control off manually */ + else if (rv1106->dac_ctrl_manual == 2) + mute = 0; /* Force DAC control on manually */ + + rv1106_codec_dac_mute(rv1106, mute); } return 0; @@ -1343,6 +1377,36 @@ static int rv1106_codec_hpmix_gain_put(struct snd_kcontrol *kcontrol, return snd_soc_put_volsw_range(kcontrol, ucontrol); } +static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = rv1106->dac_ctrl_manual; + + return 0; +} + +static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); + + rv1106->dac_ctrl_manual = ucontrol->value.integer.value[0]; + + if (rv1106->dac_ctrl_manual == 0) + return 0; + + if (rv1106->dac_ctrl_manual == 1) + rv1106_codec_dac_mute(rv1106, 1); /* Force DAC control off manually */ + else if (rv1106->dac_ctrl_manual == 2) + rv1106_codec_dac_mute(rv1106, 0); /* Force DAC control on manually */ + + return 0; +} + static int rv1106_codec_adc_enable(struct rv1106_codec_priv *rv1106) { unsigned int lr = using_adc_lr(rv1106->adc_mode); @@ -1774,6 +1838,7 @@ static int rv1106_codec_check_micbias(struct rv1106_codec_priv *rv1106, static int rv1106_codec_dapm_controls_prepare(struct rv1106_codec_priv *rv1106) { rv1106->adc_mode = DIFF_ADCL; + rv1106->dac_ctrl_manual = 0; rv1106->hpf_cutoff = 0; rv1106->agc_l = 0; rv1106->agc_r = 0; diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index 389aabe45a8c..206155acd8b0 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -66,6 +66,12 @@ config SND_SOC_ROCKCHIP_SAI Rockchip SAI Controller. The Controller supports up to maximum of 128 channels each for play and record. +config SND_SOC_ROCKCHIP_SAI_VERBOSE + bool "Rockchip SAI Verbose Controls" + depends on SND_SOC_ROCKCHIP_SAI + help + Say Y if you want to export much more controls and info for SAI. + config SND_SOC_ROCKCHIP_SPDIF tristate "Rockchip SPDIF Device Driver" depends on HAVE_CLK && SND_SOC_ROCKCHIP diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 04c8096aeef9..7d7265e3f9ae 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -653,7 +653,9 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai) i2s->has_capture ? &i2s->capture_dma_data : NULL); if (i2s->mclk_calibrate) - snd_soc_add_dai_controls(dai, &rockchip_i2s_compensation_control, 1); + snd_soc_add_component_controls(dai->component, + &rockchip_i2s_compensation_control, + 1); return 0; } diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 68b30e4f39a1..b2a2f13618ef 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -66,6 +66,7 @@ #define CLK_PPM_MIN (-1000) #define CLK_PPM_MAX (1000) #define MAXBURST_PER_FIFO 8 +#define WAIT_TIME_MS_MAX 10000 #define TRCM_TXRX 0 #define TRCM_TX 1 @@ -114,6 +115,7 @@ struct rk_i2s_tdm_dev { struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_pcm_substream *substreams[SNDRV_PCM_STREAM_LAST + 1]; + unsigned int wait_time[SNDRV_PCM_STREAM_LAST + 1]; struct reset_control *tx_reset; struct reset_control *rx_reset; struct pinctrl *pinctrl; @@ -2030,7 +2032,101 @@ static int rockchip_i2s_tdm_loopback_put(struct snd_kcontrol *kcontrol, return 0; } +static const char * const rpaths_text[] = { + "From SDI0", "From SDI1", "From SDI2", "From SDI3" }; + +static const char * const tpaths_text[] = { + "From PATH0", "From PATH1", "From PATH2", "From PATH3" }; + +/* TXCR */ +static SOC_ENUM_SINGLE_DECL(tpath3_enum, I2S_TXCR, 29, tpaths_text); +static SOC_ENUM_SINGLE_DECL(tpath2_enum, I2S_TXCR, 27, tpaths_text); +static SOC_ENUM_SINGLE_DECL(tpath1_enum, I2S_TXCR, 25, tpaths_text); +static SOC_ENUM_SINGLE_DECL(tpath0_enum, I2S_TXCR, 23, tpaths_text); + +/* RXCR */ +static SOC_ENUM_SINGLE_DECL(rpath3_enum, I2S_RXCR, 23, rpaths_text); +static SOC_ENUM_SINGLE_DECL(rpath2_enum, I2S_RXCR, 21, rpaths_text); +static SOC_ENUM_SINGLE_DECL(rpath1_enum, I2S_RXCR, 19, rpaths_text); +static SOC_ENUM_SINGLE_DECL(rpath0_enum, I2S_RXCR, 17, rpaths_text); + +static int rockchip_i2s_tdm_wait_time_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = WAIT_TIME_MS_MAX; + uinfo->value.integer.step = 1; + + return 0; +} + +static int rockchip_i2s_tdm_rd_wait_time_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE]; + + return 0; +} + +static int rockchip_i2s_tdm_rd_wait_time_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX) + return -EINVAL; + + i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE] = ucontrol->value.integer.value[0]; + + return 1; +} + +static int rockchip_i2s_tdm_wr_wait_time_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component); + + ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK]; + + return 0; +} + +static int rockchip_i2s_tdm_wr_wait_time_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); + struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component); + + if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX) + return -EINVAL; + + i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK] = ucontrol->value.integer.value[0]; + + return 1; +} + +#define SAI_PCM_WAIT_TIME(xname, xhandler_get, xhandler_put) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, \ + .info = rockchip_i2s_tdm_wait_time_info, \ + .get = xhandler_get, .put = xhandler_put } + static const struct snd_kcontrol_new rockchip_i2s_tdm_snd_controls[] = { + SOC_ENUM("Receive PATH3 Source Select", rpath3_enum), + SOC_ENUM("Receive PATH2 Source Select", rpath2_enum), + SOC_ENUM("Receive PATH1 Source Select", rpath1_enum), + SOC_ENUM("Receive PATH0 Source Select", rpath0_enum), + SOC_ENUM("Transmit SDO3 Source Select", tpath3_enum), + SOC_ENUM("Transmit SDO2 Source Select", tpath2_enum), + SOC_ENUM("Transmit SDO1 Source Select", tpath1_enum), + SOC_ENUM("Transmit SDO0 Source Select", tpath0_enum), + SOC_ENUM_EXT("I2STDM Digital Loopback Mode", loopback_mode, rockchip_i2s_tdm_loopback_get, rockchip_i2s_tdm_loopback_put), @@ -2040,6 +2136,12 @@ static const struct snd_kcontrol_new rockchip_i2s_tdm_snd_controls[] = { SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum, rockchip_i2s_tdm_rx_lanes_get, rockchip_i2s_tdm_rx_lanes_put), #endif + SAI_PCM_WAIT_TIME("PCM Read Wait Time MS", + rockchip_i2s_tdm_rd_wait_time_get, + rockchip_i2s_tdm_rd_wait_time_put), + SAI_PCM_WAIT_TIME("PCM Write Wait Time MS", + rockchip_i2s_tdm_wr_wait_time_get, + rockchip_i2s_tdm_wr_wait_time_put), }; static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai) @@ -2052,7 +2154,9 @@ static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai) dai->playback_dma_data = &i2s_tdm->playback_dma_data; if (i2s_tdm->mclk_calibrate) - snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1); + snd_soc_add_component_controls(dai->component, + &rockchip_i2s_tdm_compensation_control, + 1); return 0; } @@ -2101,11 +2205,15 @@ static int rockchip_i2s_tdm_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai); + int stream = substream->stream; - if (i2s_tdm->substreams[substream->stream]) + if (i2s_tdm->substreams[stream]) return -EBUSY; - i2s_tdm->substreams[substream->stream] = substream; + if (i2s_tdm->wait_time[stream]) + substream->wait_time = msecs_to_jiffies(i2s_tdm->wait_time[stream]); + + i2s_tdm->substreams[stream] = substream; return 0; } diff --git a/sound/soc/rockchip/rockchip_multi_dais.c b/sound/soc/rockchip/rockchip_multi_dais.c index e52be215dab1..d4994f6f4c2e 100644 --- a/sound/soc/rockchip/rockchip_multi_dais.c +++ b/sound/soc/rockchip/rockchip_multi_dais.c @@ -23,6 +23,8 @@ #define DAIS_DRV_NAME "rockchip-mdais" #define RK3308_GRF_SOC_CON2 0x308 +#define SOUND_NAME_PREFIX "sound-name-prefix" + static inline struct rk_mdais_dev *to_info(struct snd_soc_dai *dai) { return snd_soc_dai_get_drvdata(dai); @@ -220,13 +222,23 @@ static int rockchip_mdais_tdm_slot(struct snd_soc_dai *dai, static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai) { struct rk_mdais_dev *mdais = to_info(dai); + struct snd_soc_component *comp; struct snd_soc_dai *child; + const char *str; int ret, i = 0; for (i = 0; i < mdais->num_dais; i++) { child = mdais->dais[i].dai; + comp = child->component; if (!child->probed && child->driver->probe) { - child->component->card = dai->component->card; + if (!comp->name_prefix) { + ret = device_property_read_string(child->dev, + SOUND_NAME_PREFIX, &str); + if (!ret) + comp->name_prefix = str; + } + + comp->card = dai->component->card; ret = child->driver->probe(child); if (ret < 0) { dev_err(child->dev, @@ -234,6 +246,14 @@ static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai) child->name, ret); return ret; } + + ret = snd_soc_add_component_controls(comp, + comp->driver->controls, + comp->driver->num_controls); + if (ret) + dev_err(dai->dev, "%s: Failed to add controls, should add '%s' in DT\n", + dev_name(child->dev), SOUND_NAME_PREFIX); + dai->probed = 1; } } @@ -383,9 +403,9 @@ static int rockchip_mdais_dai_prepare(struct platform_device *pdev, .probe = rockchip_mdais_dai_probe, .playback = { .stream_name = "Playback", - .channels_min = 2, - .channels_max = 32, - .rates = SNDRV_PCM_RATE_8000_192000, + .channels_min = 1, + .channels_max = 512, + .rates = SNDRV_PCM_RATE_8000_384000, .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | @@ -394,9 +414,9 @@ static int rockchip_mdais_dai_prepare(struct platform_device *pdev, }, .capture = { .stream_name = "Capture", - .channels_min = 2, - .channels_max = 32, - .rates = SNDRV_PCM_RATE_8000_192000, + .channels_min = 1, + .channels_max = 512, + .rates = SNDRV_PCM_RATE_8000_384000, .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | diff --git a/sound/soc/rockchip/rockchip_multi_dais_pcm.c b/sound/soc/rockchip/rockchip_multi_dais_pcm.c index 8063bbbbd24f..d52bd1e91395 100644 --- a/sound/soc/rockchip/rockchip_multi_dais_pcm.c +++ b/sound/soc/rockchip/rockchip_multi_dais_pcm.c @@ -20,6 +20,10 @@ #define MAX_FIFO_SIZE 32 /* max fifo size in frames */ #define SND_DMAENGINE_MPCM_DRV_NAME "snd_dmaengine_mpcm" +static unsigned int prealloc_buffer_size_kbytes = 512; +module_param(prealloc_buffer_size_kbytes, uint, 0444); +MODULE_PARM_DESC(prealloc_buffer_size_kbytes, "Preallocate DMA buffer size (KB)."); + struct dmaengine_mpcm { struct rk_mdais_dev *mdais; struct dma_chan *tx_chans[MAX_DAIS]; @@ -561,7 +565,7 @@ static int dmaengine_mpcm_new(struct snd_soc_component *component, struct snd_so size_t max_buffer_size; unsigned int i; - prealloc_buffer_size = 512 * 1024; + prealloc_buffer_size = prealloc_buffer_size_kbytes * 1024; max_buffer_size = SIZE_MAX; for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) { @@ -683,6 +687,9 @@ int snd_dmaengine_mpcm_register(struct rk_mdais_dev *mdais) if (!pcm) return -ENOMEM; +#ifdef CONFIG_DEBUG_FS + pcm->component.debugfs_prefix = "dma"; +#endif pcm->mdais = mdais; for (i = 0; i < num; i++) { child = mdais->dais[i].dev; diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 97faa2e2df22..0d2136a6a808 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -22,6 +22,7 @@ #define DRV_NAME "rockchip-sai" +#define CLK_SHIFT_RATE_HZ_MAX 1 /* 1 Hz */ #define FW_RATIO_MAX 8 #define FW_RATIO_MIN 1 #define MAXBURST_PER_FIFO 8 @@ -496,9 +497,10 @@ static int rockchip_sai_hw_params(struct snd_pcm_substream *substream, if (sai->is_clk_auto) clk_set_rate(sai->mclk, bclk_rate); mclk_rate = clk_get_rate(sai->mclk); - if (mclk_rate < bclk_rate) { - dev_err(sai->dev, "Mismatch mclk: %u, expected %u at least\n", - mclk_rate, bclk_rate); + if (mclk_rate < bclk_rate - CLK_SHIFT_RATE_HZ_MAX || + mclk_rate > bclk_rate + CLK_SHIFT_RATE_HZ_MAX) { + dev_err(sai->dev, "Mismatch mclk: %u, expected %u (+/- %dHz)\n", + mclk_rate, bclk_rate, CLK_SHIFT_RATE_HZ_MAX); return -EINVAL; } @@ -795,8 +797,8 @@ static int rockchip_sai_init_dai(struct rk_sai_dev *sai, struct resource *res, if (sai->has_playback) { dai->playback.stream_name = "Playback"; dai->playback.channels_min = 1; - dai->playback.channels_max = 128; - dai->playback.rates = SNDRV_PCM_RATE_8000_192000; + dai->playback.channels_max = 512; + dai->playback.rates = SNDRV_PCM_RATE_8000_384000; dai->playback.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | @@ -811,8 +813,8 @@ static int rockchip_sai_init_dai(struct rk_sai_dev *sai, struct resource *res, if (sai->has_capture) { dai->capture.stream_name = "Capture"; dai->capture.channels_min = 1; - dai->capture.channels_max = 128; - dai->capture.rates = SNDRV_PCM_RATE_8000_192000; + dai->capture.channels_max = 512; + dai->capture.rates = SNDRV_PCM_RATE_8000_384000; dai->capture.formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | @@ -867,14 +869,14 @@ static const char * const lpx_text[] = { "From SDO0", "From SDO1", "From SDO2", "From SDO3" }; static const char * const lps_text[] = { "Disable", "Enable" }; -static const char * const sync_out_text[] = { "External", "Internal" }; -static const char * const sync_in_text[] = { "External", "Internal" }; +static const char * const sync_out_text[] = { "From CRU", "From IO" }; +static const char * const sync_in_text[] = { "From IO", "From Sync Port" }; static const char * const rpaths_text[] = { "From SDI0", "From SDI1", "From SDI2", "From SDI3" }; static const char * const tpaths_text[] = { - "To SDO0", "To SDO1", "To SDO2", "To SDO3" }; + "From PATH0", "From PATH1", "From PATH2", "From PATH3" }; /* TXCR */ static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text); @@ -931,8 +933,8 @@ static SOC_ENUM_SINGLE_DECL(tpath2_enum, SAI_PATH_SEL, 4, tpaths_text); static SOC_ENUM_SINGLE_DECL(tpath1_enum, SAI_PATH_SEL, 2, tpaths_text); static SOC_ENUM_SINGLE_DECL(tpath0_enum, SAI_PATH_SEL, 0, tpaths_text); -static int rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -942,8 +944,8 @@ static int rockchip_sai_fpw_get(struct snd_kcontrol *kcontrol, return 0; } -static int rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -958,8 +960,8 @@ static int rockchip_sai_fpw_put(struct snd_kcontrol *kcontrol, return 1; } -static int rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -969,8 +971,8 @@ static int rockchip_sai_fw_ratio_get(struct snd_kcontrol *kcontrol, return 0; } -static int rockchip_sai_fw_ratio_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_fw_ratio_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -1038,8 +1040,8 @@ static int rockchip_sai_rx_lanes_put(struct snd_kcontrol *kcontrol, return 1; } -static int rockchip_sai_mss_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_mss_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -1049,8 +1051,8 @@ static int rockchip_sai_mss_get(struct snd_kcontrol *kcontrol, return 0; } -static int rockchip_sai_mss_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int __maybe_unused rockchip_sai_mss_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component); @@ -1186,21 +1188,17 @@ static int rockchip_sai_wr_wait_time_put(struct snd_kcontrol *kcontrol, .info = rockchip_sai_wait_time_info, \ .get = xhandler_get, .put = xhandler_put } -static DECLARE_TLV_DB_SCALE(fs_shift_tlv, 0, 8192, 0); +static __maybe_unused DECLARE_TLV_DB_SCALE(fs_shift_tlv, 0, 8192, 0); static const struct snd_kcontrol_new rockchip_sai_controls[] = { - +#ifdef CONFIG_SND_SOC_ROCKCHIP_SAI_VERBOSE SOC_ENUM("Transmit Edge Shift", tsft_enum), - SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum, - rockchip_sai_tx_lanes_get, rockchip_sai_tx_lanes_put), SOC_ENUM("Transmit Store Justified Mode", tsjm_enum), SOC_ENUM("Transmit First Bit Mode", tfbm_enum), SOC_ENUM("Transmit Valid Data Justified", tvdj_enum), SOC_ENUM("Transmit Slot Bit Width", tsbw_enum), SOC_ENUM("Receive Edge Shift", rsft_enum), - SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum, - rockchip_sai_rx_lanes_get, rockchip_sai_rx_lanes_put), SOC_ENUM("Receive Store Justified Mode", rsjm_enum), SOC_ENUM("Receive First Bit Mode", rfbm_enum), SOC_ENUM("Receive Valid Data Justified", rvdj_enum), @@ -1212,16 +1210,25 @@ static const struct snd_kcontrol_new rockchip_sai_controls[] = { SOC_ENUM_EXT("Frame Width Ratio", fw_ratio_enum, rockchip_sai_fw_ratio_get, rockchip_sai_fw_ratio_put), + SOC_ENUM_EXT("Master Slave Mode Select", mss_switch, + rockchip_sai_mss_get, rockchip_sai_mss_put), + SOC_ENUM("Sclk Polarity", sp_switch), + SOC_ENUM("Frame Sync Polarity", fp_switch), + + SOC_SINGLE_TLV("Transmit Frame Shift Select", SAI_TX_SHIFT, + 0, 8192, 0, fs_shift_tlv), + SOC_SINGLE_TLV("Receive Frame Shift Select", SAI_RX_SHIFT, + 0, 8192, 0, fs_shift_tlv), +#endif + SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum, + rockchip_sai_tx_lanes_get, rockchip_sai_tx_lanes_put), + SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum, + rockchip_sai_rx_lanes_get, rockchip_sai_rx_lanes_put), SOC_SINGLE_TLV("Receive Mono Slot Select", SAI_MONO_CR, 2, 128, 0, rmss_tlv), SOC_ENUM("Receive Mono Switch", rmono_switch), SOC_ENUM("Transmit Mono Switch", tmono_switch), - SOC_ENUM_EXT("Master / Slave Mode Select", mss_switch, - rockchip_sai_mss_get, rockchip_sai_mss_put), - SOC_ENUM("Sclk Polarity", sp_switch), - SOC_ENUM("Frame Sync Polarity", fp_switch), - SOC_ENUM("SDI3 Loopback Src Select", lp3_enum), SOC_ENUM("SDI2 Loopback Src Select", lp2_enum), SOC_ENUM("SDI1 Loopback Src Select", lp1_enum), @@ -1236,15 +1243,10 @@ static const struct snd_kcontrol_new rockchip_sai_controls[] = { SOC_ENUM("Receive PATH2 Source Select", rpath2_enum), SOC_ENUM("Receive PATH1 Source Select", rpath1_enum), SOC_ENUM("Receive PATH0 Source Select", rpath0_enum), - SOC_ENUM("Transmit PATH3 Sink Select", tpath3_enum), - SOC_ENUM("Transmit PATH2 Sink Select", tpath2_enum), - SOC_ENUM("Transmit PATH1 Sink Select", tpath1_enum), - SOC_ENUM("Transmit PATH0 Sink Select", tpath0_enum), - - SOC_SINGLE_TLV("Transmit Frame Shift Select", SAI_TX_SHIFT, - 0, 8192, 0, fs_shift_tlv), - SOC_SINGLE_TLV("Receive Frame Shift Select", SAI_RX_SHIFT, - 0, 8192, 0, fs_shift_tlv), + SOC_ENUM("Transmit SDO3 Source Select", tpath3_enum), + SOC_ENUM("Transmit SDO2 Source Select", tpath2_enum), + SOC_ENUM("Transmit SDO1 Source Select", tpath1_enum), + SOC_ENUM("Transmit SDO0 Source Select", tpath0_enum), SOC_SINGLE_BOOL_EXT("Clk Auto Switch", 0, rockchip_sai_clk_auto_get, @@ -1276,6 +1278,9 @@ static irqreturn_t rockchip_sai_isr(int irq, void *devid) dev_warn_ratelimited(sai->dev, "TX FIFO Underrun\n"); regmap_update_bits(sai->regmap, SAI_INTCR, SAI_INTCR_TXUIC, SAI_INTCR_TXUIC); + regmap_update_bits(sai->regmap, SAI_INTCR, + SAI_INTCR_TXUIE_MASK, + SAI_INTCR_TXUIE(0)); substream = sai->substreams[SNDRV_PCM_STREAM_PLAYBACK]; if (substream) snd_pcm_stop_xrun(substream); @@ -1285,6 +1290,9 @@ static irqreturn_t rockchip_sai_isr(int irq, void *devid) dev_warn_ratelimited(sai->dev, "RX FIFO Overrun\n"); regmap_update_bits(sai->regmap, SAI_INTCR, SAI_INTCR_RXOIC, SAI_INTCR_RXOIC); + regmap_update_bits(sai->regmap, SAI_INTCR, + SAI_INTCR_RXOIE_MASK, + SAI_INTCR_RXOIE(0)); substream = sai->substreams[SNDRV_PCM_STREAM_CAPTURE]; if (substream) snd_pcm_stop_xrun(substream);