From b521fcc24c96af50ee24d6bf6beac79a6983e5e5 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Tue, 12 Sep 2023 16:44:33 +0800 Subject: [PATCH 01/49] arm64: dts: rockchip: add rk3567 evb2 dual channel lvds devicetree Add support for dual channel lvds with hdmi output Signed-off-by: Chaoyi Chen Change-Id: I782edeaf7ad9bb057d3911453d039fbacc14ee13 --- arch/arm64/boot/dts/rockchip/Makefile | 1 + ...rk3567-evb2-lp4x-v10-dual-channel-lvds.dts | 168 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 9bddc2665805..ce3a7d5eb994 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -128,6 +128,7 @@ 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) += 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 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; +}; From 9a72b813218694443e2665db3bc5285370c2dd0b Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Tue, 12 Sep 2023 16:49:06 +0800 Subject: [PATCH 02/49] arm64: dts: rockchip: add rk3567 evb2 dual lvds devicetree Add support for dual lvds with hdmi output Signed-off-by: Chaoyi Chen Change-Id: I6e3c07be15886ebf1daf9b22b72659c21a21f0dd --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../rk3567-evb2-lp4x-v10-dual-lvds.dts | 172 ++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index ce3a7d5eb994..1bcfcb3de3ca 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -129,6 +129,7 @@ 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 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; +}; From ca9f8fb207c0863ffc82336de12d5eef174597e4 Mon Sep 17 00:00:00 2001 From: Wangqiang Guo Date: Thu, 14 Sep 2023 12:15:33 +0000 Subject: [PATCH 03/49] media: rockchip: hdmirx: enhance compatibility and stability. 1.Add the judgment of signal loss when use g_dv_timing. 2.Wait for the signal to stabilize before get resolution. Change-Id: I4cef1bd8a67f38dd531d24ccbb23d960bb82abae Signed-off-by: Wangqiang Guo --- drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c index 1d745b49da5c..eae19e62edb2 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; From 49d91f5a0fc07eb15b4bb3c68937c3d864044259 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 12:05:26 +0800 Subject: [PATCH 04/49] media: i2c: maxim4c: driver version 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 Signed-off-by: Cai Wenzhong Change-Id: Ife74e6251b09628e8413aa810c995e7a71449f1d --- drivers/media/i2c/maxim4c/Kconfig | 30 +- drivers/media/i2c/maxim4c/maxim4c_api.h | 14 +- drivers/media/i2c/maxim4c/maxim4c_drv.c | 207 +++++++----- drivers/media/i2c/maxim4c/maxim4c_drv.h | 4 +- drivers/media/i2c/maxim4c/maxim4c_i2c.c | 2 +- drivers/media/i2c/maxim4c/maxim4c_link.c | 63 ++-- drivers/media/i2c/maxim4c/maxim4c_link.h | 6 - .../media/i2c/maxim4c/maxim4c_mipi_txphy.c | 16 +- drivers/media/i2c/maxim4c/maxim4c_pattern.c | 91 ++++-- drivers/media/i2c/maxim4c/maxim4c_remote.c | 301 ++++++++++++++---- drivers/media/i2c/maxim4c/maxim4c_v4l2.c | 27 +- .../media/i2c/maxim4c/maxim4c_video_pipe.c | 22 +- drivers/media/i2c/maxim4c/remote_max9295.c | 110 +++---- drivers/media/i2c/maxim4c/remote_max96715.c | 120 ++++--- drivers/media/i2c/maxim4c/remote_max96717.c | 128 +++----- 15 files changed, 698 insertions(+), 443 deletions(-) diff --git a/drivers/media/i2c/maxim4c/Kconfig b/drivers/media/i2c/maxim4c/Kconfig index 40e6a22e8c96..667ce82c11cf 100644 --- a/drivers/media/i2c/maxim4c/Kconfig +++ b/drivers/media/i2c/maxim4c/Kconfig @@ -3,42 +3,44 @@ # 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_V4L2 && VIDEO_V4L2_SUBDEV_API depends on MEDIA_CAMERA_SUPPORT 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..cdad54f34302 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c +++ b/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c @@ -259,7 +259,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 +356,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 +408,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; @@ -497,7 +502,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..09d170e5a85a 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,7 +256,25 @@ 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; @@ -259,8 +284,11 @@ int maxim4c_pattern_init(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); @@ -273,23 +301,10 @@ 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 generator and mode init pattern = &maxim4c->pattern; @@ -297,6 +312,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 +323,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 +337,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 = { From c3e9ad5bbcf6267f6fd7bde652ef3cfc0e74c3fb Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:43:02 +0800 Subject: [PATCH 05/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi 1. rk3588 evb: i2c bus = 6, csi2_dphy1_hw = full mode (csi2_dphy3) 2. dphy1_hw gpios: pwdn = gpio4_a6, lock = gpio3_b4, errb = gpio0_c2 3. dphy1_hw maxim serdes remote camera poc_en gpio: gpio3_b1 4. serializer: max96717, sensor: 1920 * 1440 30fps Signed-off-by: Cai Wenzhong Change-Id: I1702d91783789a5754af9c411149c470b061232b --- ...3588-vehicle-evb-maxim-max96712-dphy3.dtsi | 613 ++++++++++++++++++ 1 file changed, 613 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi 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>; + }; + }; +}; From 619492814532195966228b6302ec42e430314356 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:46:13 +0800 Subject: [PATCH 06/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi 1. rk3588 evb: i2c bus = 7, csi2_dphy0_hw = full mode (csi2_dphy0) 2. dphy0_hw gpios: pwdn = gpio1_b2, lock = gpio3_b7, errb = gpio3_d1 3. dphy0_hw maxim serdes remote camera poc_en gpio: gpio3_b0 4. serializer: max96715, sensor: 1280 * 800 30fps Signed-off-by: Cai Wenzhong Change-Id: Idfe33a58ee812980054304e789496d1b64916059 --- ...3588-vehicle-evb-maxim-max96712-dphy0.dtsi | 708 ++++++++++++++++++ 1 file changed, 708 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dphy0.dtsi 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>; + }; + }; +}; From 8b8c355566d88c2fbf99a7d89726cd5ec2f753d1 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:48:01 +0800 Subject: [PATCH 07/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi 1. rk3588 evb: i2c bus = 7, csi2_dphy0_hw = full mode (csi2_dphy0) 2. dphy0_hw gpios: pwdn = gpio1_b2, lock = gpio3_b7, errb = gpio3_d1 3. dphy0_hw maxim serdes remote camera poc_en gpio: gpio3_b0 4. serializer: max96715, sensor: 1280 * 800 30fps Signed-off-by: Cai Wenzhong Change-Id: Iea14cb3a46192d8d361d8e0b1276e4b0408f041c --- ...3588-vehicle-evb-maxim-max96722-dphy0.dtsi | 708 ++++++++++++++++++ 1 file changed, 708 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy0.dtsi 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>; + }; + }; +}; From 8eb0cbaf508159d40863e7dc78d79f2469817ac4 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:49:19 +0800 Subject: [PATCH 08/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi 1. rk3588 evb: i2c bus = 6, csi2_dphy1_hw = full mode (csi2_dphy3) 2. dphy1_hw gpios: pwdn = gpio4_a6, lock = gpio3_b4, errb = gpio0_c2 3. dphy1_hw maxim serdes remote camera poc_en gpio: gpio3_b1 4. serializer: max9295, sensor: 1600 * 1300 30fps Signed-off-by: Cai Wenzhong Change-Id: I1b37629e20d0a8407e2f0411b01f791fe436b15e --- ...3588-vehicle-evb-maxim-max96722-dphy3.dtsi | 478 ++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96722-dphy3.dtsi 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>; + }; + }; +}; From 8e453803c272602998f18cfcf26af3c20d8e75a4 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Thu, 24 Aug 2023 10:25:06 +0800 Subject: [PATCH 09/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi 1. rk3588 evb: i2c bus = 8, mipi_dcphy0 (csi2_dcphy0) 2. mipi_dcphy0 gpios: pwdn = gpio4_a4, lock = gpio4_a2, errb = gpio4_a5 3. mipi_dcphy0 maxim serdes remote camera poc_en gpio: gpio3_a6 4. serializer: max96715, sensor: 1280 * 800 30fps Signed-off-by: Cai Wenzhong Change-Id: Ib23ebda25a44dc52a9b5954196e3d3b21f2f46f6 --- ...588-vehicle-evb-maxim-max96712-dcphy0.dtsi | 696 ++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy0.dtsi 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>; + }; + }; +}; From 7231af1561872bfc5a3021c7c8c63c06d35d21f9 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Thu, 24 Aug 2023 10:27:03 +0800 Subject: [PATCH 10/49] arm64: dts: rockchip: add rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi 1. rk3588 evb: i2c bus = 2, mipi_dcphy1 (csi2_dcphy1) 2. mipi_dcphy1 gpios: pwdn = gpio4_d1, lock = gpio4_d3, errb = gpio4_d2 3. mipi_dcphy1 maxim serdes remote camera poc_en gpio: gpio3_a7 4. serializer: max9295, sensor: 1600 * 1300 30fps Signed-off-by: Cai Wenzhong Change-Id: Ib268ad9cc83849bad5bae6126079ce543c71b7bc --- ...588-vehicle-evb-maxim-max96712-dcphy1.dtsi | 466 ++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-maxim-max96712-dcphy1.dtsi 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>; + }; + }; +}; From 5001f9dba8c01e732506752efb4ad83ea90d69a1 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:49:52 +0800 Subject: [PATCH 11/49] arm64: dts: rockchip: rk3588-vehicle-evb-v21: Enable maxim4c driver Signed-off-by: Cai Wenzhong Change-Id: I99751f247e6eaec27e6ebe5985a7042dc2121d69 --- arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..073831038d43 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts @@ -7,7 +7,7 @@ /dts-v1/; #include "rk3588-vehicle-evb-v21.dtsi" -#include "rk3588-vehicle-evb-maxim-max96712.dtsi" +#include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi" #include "rk3588-vehicle-serdes-display-v21.dtsi" #include "rk3588-android.dtsi" From 6c5208b3ef463819bd53558fea470ab8a87cac02 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Wed, 23 Aug 2023 15:51:16 +0800 Subject: [PATCH 12/49] arm64: dts: rockchip: rk3588-vehicle-maxim-cameras-s66: Enable maxim4c driver 1. max96712@0x29: AVM Camera x 4 1.1 i2c bus = 2, csi2_dphy0_hw = full mode (csi2_dphy0) 1.2 max96715 GSML1 LVDS Camera, 1280*800, 30fps 1.3 gpios: pwdn = gpio1_c4, lock = gpio1_c6, errb = gpio1_d2 2. max96722@0x6b: DMS Camera x1 + OMS Camera x1 2.1 i2c bus = 2, csi2_dphy1_hw = full mode (csi2_dphy3) 2.2 max9295a GMSL2 DVP Camera, 1600*1300, 30fps 2.3 gpios: pwdn = gpio1_c7, lock = gpio1_d5, errb = gpio1_b1 Signed-off-by: Cai Wenzhong Change-Id: I1cdf9eb53b695be102e63c6fb329525d8e03c242 --- .../rk3588-vehicle-maxim-cameras-s66.dtsi | 920 +++++++++++++++++- 1 file changed, 889 insertions(+), 31 deletions(-) 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>; }; }; From 7a07ac5cd2070f21347fe55cf9632be20253c9b7 Mon Sep 17 00:00:00 2001 From: Liang Chen Date: Mon, 18 Sep 2023 15:16:30 +0800 Subject: [PATCH 13/49] irqchip/gic-v3-its: add GFP_DMA32 flag for memory allocated for ITS in rk3567 Change-Id: I4c7ef759cff823c311615e3aa067fcb900c03353 Signed-off-by: Liang Chen --- drivers/irqchip/irq-gic-v3-its.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 8ccff68c76d7..5b735395a320 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -2168,7 +2168,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) @@ -2306,7 +2308,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) @@ -2357,6 +2361,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) @@ -2947,7 +2952,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)); @@ -3108,6 +3115,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; @@ -3138,6 +3146,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; @@ -3306,7 +3315,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)); @@ -3414,7 +3425,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 { @@ -3436,6 +3449,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 @@ -3480,6 +3494,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 @@ -5085,7 +5100,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)); @@ -5120,6 +5137,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; From c4afd40f7f28cd711772f64724466ab1e6eb3cf3 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 13 Jul 2023 10:51:39 +0800 Subject: [PATCH 14/49] dmaengine: pl330: Add support for mcbufsz parsed from DT This patch introduce property 'arm,pl330-mcbufsz-bytes' to support assign mcbufsz from DT. And we limit the max value to one PAGE_SIZE. though there is no limit for the controller. e.g. arm,pl330-mcbufsz-bytes = <2048>; Signed-off-by: Sugar Zhang Change-Id: Ia13c35e58cd6addcc7a80cb05b484184f6031989 --- drivers/dma/pl330.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 91592809d496..b1d6faede65b 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -3191,6 +3191,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)); @@ -3205,7 +3206,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++) From bca24656b60df6853c55be4fe71dbcbbafa50b39 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 29 Aug 2023 15:41:43 +0800 Subject: [PATCH 15/49] ASoC: rockchip: sai: Allow mclk shift around 1 Hz This patch allow mclk shift around +/- 1 Hz compared to requested freq. we could not always achieve the precise freq as required, e.g. request: 98304000, but got: 98303999 there is no big deal and any side effect on the above case, so, we allow a tiny shift for mclk. Signed-off-by: Sugar Zhang Change-Id: Id181a3aa9017b1994786b71c3b56454a2e78b6aa --- sound/soc/rockchip/rockchip_sai.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 0e0f3b78b366..55760f1ab2e4 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; } From c4d222f150c985fd11415ded79fdfe0ae562669a Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 12 Sep 2023 16:14:45 +0800 Subject: [PATCH 16/49] ASoC: rockchip: sai: Add support for more capabilities * support samplerate up to 384k * support channel range from mono to 512ch Signed-off-by: Sugar Zhang Change-Id: I190990c18166dc5cd316bd0f2c5b0d9e9452c631 --- sound/soc/rockchip/rockchip_sai.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 55760f1ab2e4..cb90ef9a2b94 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -797,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 | @@ -813,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 | From 4cf62acda44cf02906b0f34f26eb2ca0add63e25 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 10:51:08 +0800 Subject: [PATCH 17/49] ASoC: rockchip: sai: Introduce SND_SOC_ROCKCHIP_SAI_VERBOSE This patch add verbose config for sai, and put expert-level or not-commonly-used controls into there. Signed-off-by: Sugar Zhang Change-Id: Ibe637ad00c058e01164c227c8549f0938920dff2 --- sound/soc/rockchip/Kconfig | 6 ++++ sound/soc/rockchip/rockchip_sai.c | 60 +++++++++++++++---------------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index f815c821a2c1..337ead61a397 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -65,6 +65,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 CLKDEV_LOOKUP && SND_SOC_ROCKCHIP diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index cb90ef9a2b94..094b6851dc7c 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -869,8 +869,8 @@ 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" }; @@ -933,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); @@ -944,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); @@ -960,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); @@ -971,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); @@ -1040,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); @@ -1051,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); @@ -1188,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), @@ -1214,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), @@ -1243,11 +1248,6 @@ static const struct snd_kcontrol_new rockchip_sai_controls[] = { 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_SINGLE_BOOL_EXT("Clk Auto Switch", 0, rockchip_sai_clk_auto_get, rockchip_sai_clk_auto_put), From 480426852e4f58b0490bc16472808a4ef86af6e7 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Wed, 13 Sep 2023 19:13:51 +0800 Subject: [PATCH 18/49] ASoC: rockchip: multi_dais_pcm: Fix warning debugfs: Directory 'multi-dais' with parent already present! Signed-off-by: Sugar Zhang Change-Id: I1aeee5332c79f78c5436c4bb7c57d3d692ef9b75 --- sound/soc/rockchip/rockchip_multi_dais_pcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/rockchip/rockchip_multi_dais_pcm.c b/sound/soc/rockchip/rockchip_multi_dais_pcm.c index d69395f70139..c37019139ef7 100644 --- a/sound/soc/rockchip/rockchip_multi_dais_pcm.c +++ b/sound/soc/rockchip/rockchip_multi_dais_pcm.c @@ -685,6 +685,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; From e92cb0063f23404249b9ded866f62f9fb48d8a4b Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 09:18:47 +0800 Subject: [PATCH 19/49] ASoC: rockchip: multi-dais: Add support controls for sub dais This patch add controls for all sub-dai component to allow user set/get each dai's controls. if no name_prefix specified in driver, user should confirm that the dai node of DT has assigned the property 'sound-name-prefix'. e.g. SAI0 + SAI1 combo &sai0 { sound-name-prefix = "SAI0"; }; &sai1 { sound-name-prefix = "SAI1"; }; amixer scontrols ... Simple mixer control 'SAI0 SDI0 Loopback',0 Simple mixer control 'SAI0 SDI0 Loopback Src Select',0 Simple mixer control 'SAI1 SDI0 Loopback',0 Simple mixer control 'SAI1 SDI0 Loopback Src Select',0 Signed-off-by: Sugar Zhang Change-Id: I9c3c56fe21e71afb26ad103f947b3dbfe1ccff11 --- sound/soc/rockchip/rockchip_multi_dais.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_multi_dais.c b/sound/soc/rockchip/rockchip_multi_dais.c index e52be215dab1..e44f061a7f3a 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,16 @@ 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; + comp->card = dai->component->card; ret = child->driver->probe(child); if (ret < 0) { dev_err(child->dev, @@ -234,6 +239,21 @@ static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai) child->name, ret); return ret; } + + if (!comp->name_prefix) { + ret = device_property_read_string(child->dev, + SOUND_NAME_PREFIX, &str); + if (!ret) + comp->name_prefix = str; + } + + 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; } } From 62614fd022fe3fa06cb11b903642cd7b1d6ef9cf Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 09:51:43 +0800 Subject: [PATCH 20/49] ASoC: rockchip: multi-dais: Add support for more capabilities * support samplerate up to 384k * support channel range from mono to 512ch Signed-off-by: Sugar Zhang Change-Id: I4a7d85ea77cabbb1ce6e9f1fc237d83443ab13b1 --- sound/soc/rockchip/rockchip_multi_dais.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/rockchip/rockchip_multi_dais.c b/sound/soc/rockchip/rockchip_multi_dais.c index e44f061a7f3a..b0f5e4a7e92f 100644 --- a/sound/soc/rockchip/rockchip_multi_dais.c +++ b/sound/soc/rockchip/rockchip_multi_dais.c @@ -403,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 | @@ -414,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 | From bac64251b49c9003530464405e198a5376ba0eb8 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 10:01:26 +0800 Subject: [PATCH 21/49] ASoC: rockchip: multi-dais: Introduce module option prealloc_buffer_size_kbytes Currently, The fixed 512KB prealloc buffer size is too larger for tiny memory kernel (such as 16MB memory). This patch adds the module option "prealloc_buffer_size_kbytes" to specify prealloc buffer size. It's suitable for cards which use the multi-dais driver. Signed-off-by: Sugar Zhang Change-Id: I9bee728dfd775c2f5924d4e1416088446918c2e4 --- sound/soc/rockchip/rockchip_multi_dais_pcm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_multi_dais_pcm.c b/sound/soc/rockchip/rockchip_multi_dais_pcm.c index c37019139ef7..88daa5dd9ec6 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]; @@ -563,7 +567,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++) { From 9e5a460a99fb2de8078aa925a3a0222527004c77 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 09:39:24 +0800 Subject: [PATCH 22/49] arm64: dts: rockchip: rk3562: Add property 'sound-name-prefix' for SAIx This patch add name-prefix for SAIx to support prefix kcontrol, widget and route names in an ASoC machine that has multiple dais with conflicting names. such as multi-dais. Signed-off-by: Sugar Zhang Change-Id: I51cd4eeaa9adc36a3606c39c8a4269d085ba2932 --- arch/arm64/boot/dts/rockchip/rk3562.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index ecb54d453df0..6908ef194196 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"; }; From 00226b650e628293b4bb69a62fb02220e84316dd Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 22:24:56 +0800 Subject: [PATCH 23/49] arm64: configs: rockchip_linux: Enable SND_SOC_ROCKCHIP_MULTI_DAIS This patch enable SND_SOC_ROCKCHIP_MULTI_DAIS for combine multiple dais into a union one. Signed-off-by: Sugar Zhang Change-Id: I8cbec8001fe50b48261eb5c75a9191f7e05fa7fa --- arch/arm64/configs/rockchip_linux_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 368eff2b54b1..86af8ea238b8 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -395,6 +395,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 From 5b607cc5239cd6f0560d85de347948d936abe7f7 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 14 Sep 2023 22:30:32 +0800 Subject: [PATCH 24/49] arm64: configs: rockchip: Enable SND_SOC_ROCKCHIP_MULTI_DAIS This patch enable SND_SOC_ROCKCHIP_MULTI_DAIS for combine multiple dais into a union one. Signed-off-by: Sugar Zhang Change-Id: Ib1787a9df01a97185668cededcd41cd1192e0f4e --- arch/arm64/configs/rockchip_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index bfa664697885..c96b1c40c7ba 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 From 83d56e1a331ce5ad9be348c78bdcfb7550cae862 Mon Sep 17 00:00:00 2001 From: Xing Zheng Date: Fri, 8 Sep 2023 16:45:42 +0800 Subject: [PATCH 25/49] ASoC: codecs: rv1106_codec: add support DAC control manually There are three status via control name "DAC Control Manually": - None: By default, mute/unmute via rv1106_mute_stream() automatically - Off: Force DAC control off manually - On: Force DAC control on manually And fixes incorrect DAC mute register, it should be ACODEC_DAC_ANA_CTL1. Signed-off-by: Xing Zheng Change-Id: I9d7059b86654802eb4290897765d94f4b9afd787 --- sound/soc/codecs/rv1106_codec.c | 111 +++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 23 deletions(-) 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; From bad87896471d138570f64f6019d36002bb9ba2d3 Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Mon, 18 Sep 2023 17:54:34 +0800 Subject: [PATCH 26/49] media: i2c: maxim4c: driver version v2.02.00 1. Force all MIPI clocks running Setting in csi out enable. 2. Pattern mode force_clock_out_en default enable. Signed-off-by: Cai Wenzhong Change-Id: I44e89309704cba4ee5d03762b9b42fad4bc92af6 --- drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c | 14 +++++++++++--- drivers/media/i2c/maxim4c/maxim4c_pattern.c | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c b/drivers/media/i2c/maxim4c/maxim4c_mipi_txphy.c index cdad54f34302..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 @@ -484,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, diff --git a/drivers/media/i2c/maxim4c/maxim4c_pattern.c b/drivers/media/i2c/maxim4c/maxim4c_pattern.c index 09d170e5a85a..1a3de8f3d7b4 100644 --- a/drivers/media/i2c/maxim4c/maxim4c_pattern.c +++ b/drivers/media/i2c/maxim4c/maxim4c_pattern.c @@ -280,6 +280,7 @@ int maxim4c_pattern_data_init(maxim4c_t *maxim4c) 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 @@ -306,6 +307,10 @@ int maxim4c_pattern_data_init(maxim4c_t *maxim4c) return ret; } + // 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; pattern->pattern_generator = PATTERN_GENERATOR_0; From b494e6c66862d0a6b81ad05814379bcec3f58626 Mon Sep 17 00:00:00 2001 From: Cody Xie Date: Thu, 14 Sep 2023 21:38:35 +0800 Subject: [PATCH 27/49] gpio: nca9539: Add support Novosense NCA9539 I2C GPIO expander Change-Id: I29b8488f250e019081594b2978acb81b2427a703 Signed-off-by: Cody Xie --- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-nca9539.c | 332 ++++++++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+) create mode 100644 drivers/gpio/gpio-nca9539.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 20bff29c27ff..9c5778b13855 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -984,6 +984,14 @@ config GPIO_MC9S08DZ60 help Select this to enable the MC9S08DZ60 GPIO driver +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 0a905ed33d0e..b42c5d084c97 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -107,6 +107,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"); From 872587f88a21c2cad9771012c62bf1112880495f Mon Sep 17 00:00:00 2001 From: Cody Xie Date: Fri, 15 Sep 2023 20:07:46 +0800 Subject: [PATCH 28/49] dt-bindings: gpio: nca9539: Add nca9539 support Change-Id: Ib51bffad1130036891fd3020a3e1f28d5062e095 Signed-off-by: Cody Xie --- .../bindings/gpio/novo,nca9539-gpio.yaml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/novo,nca9539-gpio.yaml 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>; + }; + + +... From 16c577629b40aa45c89c2b61f74e714b47a10744 Mon Sep 17 00:00:00 2001 From: Cody Xie Date: Fri, 15 Sep 2023 11:25:27 +0800 Subject: [PATCH 29/49] arm64: dts: rockchip: add dtsi for nca9539 io expander on rk3588 vehicle EVBV22 Change-Id: Ia3392162363d2a683eca5d852b7e50d1eb5dba24 Signed-off-by: Cody Xie --- ...8-vehicle-evb-v22-nca9539-io-expander.dtsi | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22-nca9539-io-expander.dtsi 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>; + }; +}; From df29c9cccd984c78e45c2f5f5bc318868abcca3e Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Mon, 18 Sep 2023 16:41:45 +0800 Subject: [PATCH 30/49] arm64: dts: rockchip: rk3588-amp: support ap core for amp Signed-off-by: Steven Liu Change-Id: I895095b1376e5a37a1abd67f5905625b83f45022 --- arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi index 8ee5ed10945b..013ed63cba62 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,6 +25,12 @@ #size-cells = <2>; ranges; + /* remote amp core address */ + amp_shmem_reserved: amp-shmem@7800000 { + reg = <0x0 0x7800000 0x0 0x400000>; + no-map; + }; + /* mcu address */ mcu_reserved: mcu@8200000 { reg = <0x0 0x8200000 0x0 0x100000>; From 5b23d1c00a9fa584c01f4882f170d5d6834ac040 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 19 Sep 2023 16:35:58 +0800 Subject: [PATCH 31/49] arm64: dts: rockchip: add rk3588 evb1 lp4 v10 linux amp dts Signed-off-by: Steven Liu Change-Id: I952a645f19daf84be80e59132d885521494afdc5 --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../rk3588-evb1-lp4-v10-linux-amp.dts | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-evb1-lp4-v10-linux-amp.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 1bcfcb3de3ca..1c574168ec1c 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -196,6 +196,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 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>; + }; +}; + From 2879b9eb0ae0e4c56590c2f374813c2efbb5d539 Mon Sep 17 00:00:00 2001 From: Jiahang Zheng Date: Mon, 28 Aug 2023 15:31:59 +0800 Subject: [PATCH 32/49] mailbox: rockchip: Add Rockchip MBOX Demo Change-Id: I7a14465997ac9738753214d8477411249479ca66 Signed-off-by: Jiahang Zheng --- drivers/mailbox/Kconfig | 6 ++ drivers/mailbox/Makefile | 2 + drivers/mailbox/rockchip-mbox-demo.c | 138 +++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 drivers/mailbox/rockchip-mbox-demo.c diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 4d043f7dc9bb..ab3d6f693969 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -79,6 +79,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 2e06e02b2e03..2a2eecd4ac46 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -19,6 +19,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 "); From 36d935ea8cea8aa04588ada0a518c4c1eb1cfdc4 Mon Sep 17 00:00:00 2001 From: Luo Wei Date: Sat, 12 Aug 2023 12:47:18 +0800 Subject: [PATCH 33/49] arm64: dts: rockchip: rk3588-vehicle-evb: add v22 dts files and use serdes-mfd-display default Signed-off-by: Luo Wei Change-Id: I361617bdd84c8652a21289a68afbb6c3a5d40c2a --- arch/arm64/boot/dts/rockchip/Makefile | 1 + .../dts/rockchip/rk3588-vehicle-evb-v21.dts | 100 +- .../dts/rockchip/rk3588-vehicle-evb-v22.dts | 594 ++++ ...3588-vehicle-serdes-mfd-display-maxim.dtsi | 1092 +++++++ ...k3588-vehicle-serdes-mfd-display-rohm.dtsi | 2680 +++++++++++++++++ 5 files changed, 4466 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v22.dts create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-maxim.dtsi create mode 100644 arch/arm64/boot/dts/rockchip/rk3588-vehicle-serdes-mfd-display-rohm.dtsi diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 1c574168ec1c..7d565641641b 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -234,6 +234,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/rk3588-vehicle-evb-v21.dts b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts index 073831038d43..be6ede05dc5f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vehicle-evb-v21.dts @@ -8,7 +8,7 @@ #include "rk3588-vehicle-evb-v21.dtsi" #include "rk3588-vehicle-evb-maxim-max96712-dphy3.dtsi" -#include "rk3588-vehicle-serdes-display-v21.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.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-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>; +}; From 6c967d40730452a43f51817eabf06b025151326a Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 19 Sep 2023 17:23:30 +0800 Subject: [PATCH 34/49] rpmsg: rockchip: use rockchip,rpmsg for all rockchip platform Signed-off-by: Steven Liu Change-Id: I341ab82acf1b879e66e1fa424e882e965288087f --- drivers/rpmsg/rockchip_rpmsg.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) 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 */ }, }; From 427e603def1e96316e8ec7bf2c066d879523361f Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Tue, 19 Sep 2023 17:29:00 +0800 Subject: [PATCH 35/49] arm64: dts: rockchip: rk3588-amp: support ap rpmsg Signed-off-by: Steven Liu Change-Id: I58bb79e5a35ef6d82b95e96afb0e127fb1b7be18 --- arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi index 013ed63cba62..1d5e50466286 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-amp.dtsi @@ -31,10 +31,38 @@ 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"; }; From c5fb98b26ff464c2c56db41b1501ed67f5ddd726 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 20 Sep 2023 10:04:18 +0800 Subject: [PATCH 36/49] arm64: dts: rockchip: rk3568-amp: Move the rpmsg node backwards. Signed-off-by: Steven Liu Change-Id: I4f613d4bfef823af8fb67ec30b82d687561ab96d --- arch/arm64/boot/dts/rockchip/rk3568-amp.dtsi | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 { From 66f223674f791a2fc91c782e43a3cb0ddade0208 Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Wed, 20 Sep 2023 10:06:51 +0800 Subject: [PATCH 37/49] arm64: dts: rockchip: rk3562-amp: Move the rpmsg node backwards. Signed-off-by: Steven Liu Change-Id: I7c3d7dd69301e506259d65a3d35250bdac8126d3 --- arch/arm64/boot/dts/rockchip/rk3562-amp.dtsi | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 { From da03114d74d1133e2cfbd920f4ea84bee163f772 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sat, 16 Sep 2023 00:33:09 +0800 Subject: [PATCH 38/49] PCI: rockchip: dw: Use handle_level_irq for legacy irq We get a report that a wireless ethernet device which uses legacy interrupt, exposes a buggy behaviour when patching RT support. It can be observed on RK3588 EVB1 with NVMe under RT environment when adding pci=nomsi to cmdline. The backtrace looks like below: echo 3 > /proc/sys/vm/drop_caches && dd if=/dev/nvme0n1 of=/dev/null bs=1M count=50000 [ 10.826850] irq 155: nobody cared (try booting with the "irqpoll" option) [ 10.826862] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.160-rt89 #505 [ 10.826867] Hardware name: Rockchip RK3588 EVB1 LP4 V10 Board (DT) [ 10.826870] Call trace: [ 10.826871] dump_backtrace+0x0/0x1e0 [ 10.826881] show_stack+0x18/0x24 [ 10.826886] dump_stack_lvl+0xcc/0xf8 [ 10.826891] dump_stack+0x18/0x54 [ 10.826895] __report_bad_irq+0x4c/0xdc [ 10.826899] note_interrupt+0x2cc/0x380 [ 10.826905] handle_irq_event+0x10c/0x180 [ 10.826909] handle_simple_irq+0xac/0x120 [ 10.826913] generic_handle_irq+0x30/0x50 [ 10.826917] rk_pcie_legacy_int_handler+0xa8/0x160 [ 10.826923] __handle_domain_irq+0xb8/0x140 [ 10.826927] gic_handle_irq+0xd8/0x2e4 [ 10.826932] el1_irq+0xcc/0x180 [ 10.826935] arch_cpu_idle+0x18/0x3c [ 10.826940] default_idle_call+0x2c/0x9c [ 10.826944] do_idle+0x21c/0x2a0 [ 10.826949] cpu_startup_entry+0x24/0x70 [ 10.826952] rest_init+0xd0/0xe0 [ 10.826956] arch_call_rest_init+0x10/0x1c [ 10.826960] start_kernel+0x50c/0x544 [ 10.826963] handlers: [ 10.826965] [<0000000015317c1f>] irq_default_primary_handler threaded [<00000000edb1561e>] pcie_pme_irq [ 10.826977] [<0000000015317c1f>] irq_default_primary_handler threaded [<000000000065643b>] nvme_irq [ 10.826988] [<0000000015317c1f>] irq_default_primary_handler threaded [<000000000065643b>] nvme_irq [ 10.826996] Disabling IRQ #155 And NVMe can't work anymore due to the irq problem. The actual problem looks like: nvme_irq nvme_irq //process the previous request -> nvme_process_cq(nvmeq) // the previous one is still processing -> if(nvme_process_cq(nvmeq)) -> return IRQ_HANDLED -> return IRQ_NONE so a spurious irq was counted and if the irq ack time is short enough to increase the spurious irq exceeding the limitation, report_bad_irq was triggered. This is why the bug was only observed under RT environment since the irq was distributed more quickly than ever, but the bug was always there. root@linaro-alip:/# cat /proc/irq/155/spurious count 8990 unhandled 24339 last_unhandled 189829 ms This can be fixed by the drivers as we could see many patches regarding "irq xxx: nobody cared", and it's the case if we don't allow nvme_irq to nest itself or postpone the handler. However the legacy interrupt support is also buggy. For legacy interrupt, it's a level irq rather than an edge one. But it happened to work because Rockchip PCIe RC only generates oneshot irq instead of level, preventing the irq storm from happening. So changing to use handle_level_irq is correct and should help mask/unmask the irq when dealing with it in between. That's a decent solution for all. Signed-off-by: Shawn Lin Change-Id: Ie9499b3dbd19ac053500b4c726294296be537ffd --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index ca12580bd5b5..4e5a2251b49b 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -1682,7 +1682,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; From b61b2776d4ea400d677461a0753f5652aa9f6362 Mon Sep 17 00:00:00 2001 From: Weiwen Chen Date: Tue, 19 Sep 2023 17:40:06 +0800 Subject: [PATCH 39/49] ARM: dts: rockchip: add rv1106g-evb1-v11-nofastae-spi-nand Signed-off-by: Weiwen Chen Change-Id: Iacddf213a6415e927f4a70cbf761b706f45f1a05 --- arch/arm/boot/dts/Makefile | 1 + .../rv1106g-evb1-v11-nofastae-spi-nand.dts | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 arch/arm/boot/dts/rv1106g-evb1-v11-nofastae-spi-nand.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4b666fa2b9df..55e6477489bf 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -999,6 +999,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)>; +}; From 44e562e446aef7fad95e56987d4e8ce94bcb57a3 Mon Sep 17 00:00:00 2001 From: Wu Liangqing Date: Thu, 21 Sep 2023 07:44:16 +0000 Subject: [PATCH 40/49] arm64: dts: rockchip: px30: Add reboot_mode label for Android Change-Id: I93d73ed9ee84eaa690b844deaa392241e42f094f Signed-off-by: Wu Liangqing --- arch/arm64/boot/dts/rockchip/px30.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index ecb7884681b3..6a0be2418d81 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -644,7 +644,7 @@ status = "disabled"; }; - reboot-mode { + reboot_mode: reboot-mode { compatible = "syscon-reboot-mode"; offset = <0x200>; mode-bootloader = ; From f421f8a9774dffe97af775e30dc82a953cb7280f Mon Sep 17 00:00:00 2001 From: Yandong Lin Date: Thu, 21 Sep 2023 10:01:14 +0800 Subject: [PATCH 41/49] video: rockchip: mpp: rkvenc2: fix slice mode poll failed the return value 0 of the func wait_event_interruptible() means success. Fixes: eecc48ce7bfe ("video: rockchip: mpp: disable usr poll timeout") Signed-off-by: Yandong Lin Change-Id: I849625aecb6713d0f4f8652f69ae9335d56d8b65 --- drivers/video/rockchip/mpp/mpp_rkvenc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 1843f3de2869..5bd70546150c 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -2122,7 +2122,7 @@ task_done_ret: if (ret < 0) return ret; - } while (ret > 0); + } while (!ret); rkvenc2_task_timeout_process(session, task); From b795e7c67f90029218ac7597b4e907abbb0f598a Mon Sep 17 00:00:00 2001 From: Wangqiang Guo Date: Mon, 18 Sep 2023 13:02:35 +0000 Subject: [PATCH 42/49] media: rockchip: hdmirx: avoid PKTDEC_AVIIF_CHG_IRQ mistrigger. HDMIRX enable PKTDEC_AVIIF_CHG_IRQ to detect whether color_range/color_space/color_fmt change or not, but other aviif changes also cause the interrupt to trigger. Change-Id: I7add2a6b519ad97e74ad3ba64dd8961e46a32584 Signed-off-by: Wangqiang Guo --- .../media/platform/rockchip/hdmirx/rk_hdmirx.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c index eae19e62edb2..dcd49b65ea94 100644 --- a/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c +++ b/drivers/media/platform/rockchip/hdmirx/rk_hdmirx.c @@ -2483,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; From 7cbc3d90571868f1712f750a6bbeb62d25d5c04e Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Tue, 19 Sep 2023 17:48:39 +0800 Subject: [PATCH 43/49] ASoC: rockchip: sai: Reduce FIFO XRUN warning prompt Warning once each time FIFO XRUN occurs, and then disable it, until the next time the stream resume. Before: rockchip_sai_isr: 222 callbacks suppressed rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun rockchip-sai ff800000.sai: TX FIFO Underrun ... cat /proc/interrupts | grep sai 30: 512 0 0 0 0 0 0 0 GICv2 110 Level sai After: rockchip-sai ff800000.sai: TX FIFO Underrun cat /proc/interrupts | grep sai 30: 1 0 0 0 0 0 0 0 GICv2 110 Level sai Signed-off-by: Sugar Zhang Change-Id: I0d3aa37a36ae8e44ccec97053076ef5d74dff9cc --- sound/soc/rockchip/rockchip_sai.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 094b6851dc7c..372a53655969 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -1277,6 +1277,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); @@ -1286,6 +1289,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); From 7664a3c45fdd21e61152ea5079056a365992f811 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 22 Sep 2023 16:40:11 +0800 Subject: [PATCH 44/49] ASoC: rockchip: sai: Fix Transmit SDOx Select To keep the same order with TRM. Signed-off-by: Sugar Zhang Change-Id: Idadd729223381522b347997ffc3ab2d120087cc6 --- sound/soc/rockchip/rockchip_sai.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c index 372a53655969..6609c1fa4788 100644 --- a/sound/soc/rockchip/rockchip_sai.c +++ b/sound/soc/rockchip/rockchip_sai.c @@ -876,7 +876,7 @@ 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); @@ -1243,10 +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_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, From 562725ba7000cf0d72b8a485a38c4774505466eb Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 21 Sep 2023 19:31:58 +0800 Subject: [PATCH 45/49] ASoC: rockchip: multi-dais: Fix component's name_prefix name_prefix should be assigned before dai probe to support add_component_controls in probe routine. Fixes: e92cb0063f23 ("ASoC: rockchip: multi-dais: Add support controls for sub dais") Signed-off-by: Sugar Zhang Change-Id: I056ad90c877be16467f25c7cbd90d682b223b58a --- sound/soc/rockchip/rockchip_multi_dais.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/rockchip/rockchip_multi_dais.c b/sound/soc/rockchip/rockchip_multi_dais.c index b0f5e4a7e92f..d4994f6f4c2e 100644 --- a/sound/soc/rockchip/rockchip_multi_dais.c +++ b/sound/soc/rockchip/rockchip_multi_dais.c @@ -231,6 +231,13 @@ static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai) child = mdais->dais[i].dai; comp = child->component; if (!child->probed && child->driver->probe) { + 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) { @@ -240,13 +247,6 @@ static int rockchip_mdais_dai_probe(struct snd_soc_dai *dai) return ret; } - if (!comp->name_prefix) { - ret = device_property_read_string(child->dev, - SOUND_NAME_PREFIX, &str); - if (!ret) - comp->name_prefix = str; - } - ret = snd_soc_add_component_controls(comp, comp->driver->controls, comp->driver->num_controls); From f7cdb2cfcaa788d7b2efbc478adde0c5346ff93f Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 21 Sep 2023 19:31:59 +0800 Subject: [PATCH 46/49] ASoC: rockchip: i2s-tdm: Use add_component_controls This patch use add_component_controls instead of dai's one to support multiple instance with name_prefix. Signed-off-by: Sugar Zhang Change-Id: I5aed3ba8e071544154f39b92c1180bbda0afe767 --- sound/soc/rockchip/rockchip_i2s_tdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index f9f4c0fc6176..50784bb149dc 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -1959,7 +1959,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; } From 9f997ad95e9150e5500616068f8e5a6e1babcc46 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 1 Sep 2023 19:42:44 +0800 Subject: [PATCH 47/49] ASoC: rockchip: i2s-tdm: Add support for PATHx controls This patch add support PATHx controls which allow user can select PATHx dynamically. Signed-off-by: Sugar Zhang Change-Id: I9c3af821f9080ec2a07ed846ad059f68c82ec74f --- sound/soc/rockchip/rockchip_i2s_tdm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 50784bb149dc..a303d8fa9a4f 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -1939,7 +1939,34 @@ 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 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), From 2e41a8e117b57dd3f360c022f4235a76f73915f3 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Fri, 5 May 2023 09:20:47 +0800 Subject: [PATCH 48/49] ASoC: rockchip: i2s-tdm: Add support for PCM R/W Wait Time ALSA core blocks userspace for 10 seconds for PCM R/W default. Consider the situation BT-slave which acts as SLAVE mode, when BT-master offline sometime, the CLK lost, user have to wait the core timeout(10s), it's quite bad experience. This patch allows userspace to override the WAIT_TIME to recover more quickly from terminal audio stream. especially for stream which have no mechanism to detect the LINK offline. Usage: /# amixer -c 0 contents | grep Wait numid=43,iface=PCM,name='PCM Read Wait Time MS' numid=44,iface=PCM,name='PCM Write Wait Time MS' /# amixer -c 0 cset numid=43 500 numid=43,iface=PCM,name='PCM Read Wait Time MS' ; type=INTEGER,access=rw------,values=1,min=0,max=10000,step=1 : values=500 Signed-off-by: Sugar Zhang Change-Id: I53a35344238557813ea3683dd19474819e987d19 --- sound/soc/rockchip/rockchip_i2s_tdm.c | 83 ++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index a303d8fa9a4f..b0c4ce01e2be 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -71,6 +71,7 @@ #define CLK_PPM_MIN (-1000) #define CLK_PPM_MAX (1000) #define MAXBURST_PER_FIFO 8 +#define WAIT_TIME_MS_MAX 10000 #define QUIRK_ALWAYS_ON BIT(0) #define QUIRK_HDMI_PATH BIT(1) @@ -115,6 +116,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; @@ -1957,6 +1959,73 @@ 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), @@ -1976,6 +2045,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) @@ -2019,11 +2094,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; } From a2d0c7f12f46c81b82f2453a39ea65013d553275 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 21 Sep 2023 19:32:01 +0800 Subject: [PATCH 49/49] ASoC: rockchip: i2s: Use add_component_controls This patch use add_component_controls instead of dai's one to support multiple instance with name_prefix. Signed-off-by: Sugar Zhang Change-Id: Ideb9af565f8b44dffaa32f88fed412c5781bcaed --- sound/soc/rockchip/rockchip_i2s.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 6a02002d020f..9b91f5bc265d 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -589,7 +589,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; }