From 04dd17822334871b23ea2862f7798fb0e0007777 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 11 May 2024 08:53:19 +0000
Subject: [PATCH] change otg to host mode

---
 kernel/drivers/media/platform/rockchip/cif/hw.c |  719 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 606 insertions(+), 113 deletions(-)

diff --git a/kernel/drivers/media/platform/rockchip/cif/hw.c b/kernel/drivers/media/platform/rockchip/cif/hw.c
index 328fb02..9b4a1c3 100644
--- a/kernel/drivers/media/platform/rockchip/cif/hw.c
+++ b/kernel/drivers/media/platform/rockchip/cif/hw.c
@@ -8,6 +8,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/of_graph.h>
@@ -17,14 +18,16 @@
 #include <linux/pm_runtime.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/regmap.h>
+#include <media/videobuf2-cma-sg.h>
 #include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-dma-sg.h>
 #include <media/v4l2-fwnode.h>
 #include <linux/iommu.h>
-#include <dt-bindings/soc/rockchip-system-status.h>
 #include <soc/rockchip/rockchip-system-status.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
-#include "dev.h"
+#include <soc/rockchip/rockchip_iommu.h>
+#include "common.h"
 
 static const struct cif_reg px30_cif_regs[] = {
 	[CIF_REG_DVP_CTRL] = CIF_REG(CIF_CTRL),
@@ -597,6 +600,377 @@
 	[CIF_REG_GRF_CIFIO_CON1] = CIF_REG(CIF_GRF_VI_CON1),
 };
 
+static const char * const rk3588_cif_clks[] = {
+	"aclk_cif",
+	"hclk_cif",
+	"dclk_cif",
+	"iclk_host0",
+	"iclk_host1",
+};
+
+static const char * const rk3588_cif_rsts[] = {
+	"rst_cif_a",
+	"rst_cif_h",
+	"rst_cif_d",
+	"rst_cif_host0",
+	"rst_cif_host1",
+	"rst_cif_host2",
+	"rst_cif_host3",
+	"rst_cif_host4",
+	"rst_cif_host5",
+};
+
+static const struct cif_reg rk3588_cif_regs[] = {
+	[CIF_REG_DVP_CTRL] = CIF_REG(DVP_CTRL),
+	[CIF_REG_DVP_INTEN] = CIF_REG(DVP_INTEN),
+	[CIF_REG_DVP_INTSTAT] = CIF_REG(DVP_INTSTAT),
+	[CIF_REG_DVP_FOR] = CIF_REG(DVP_FOR),
+	[CIF_REG_DVP_MULTI_ID] = CIF_REG(DVP_MULTI_ID),
+	[CIF_REG_DVP_SAV_EAV] = CIF_REG(DVP_SAV_EAV),
+	[CIF_REG_DVP_FRM0_ADDR_Y] = CIF_REG(DVP_FRM0_ADDR_Y_ID0),
+	[CIF_REG_DVP_FRM0_ADDR_UV] = CIF_REG(DVP_FRM0_ADDR_UV_ID0),
+	[CIF_REG_DVP_FRM1_ADDR_Y] = CIF_REG(DVP_FRM1_ADDR_Y_ID0),
+	[CIF_REG_DVP_FRM1_ADDR_UV] = CIF_REG(DVP_FRM1_ADDR_UV_ID0),
+	[CIF_REG_DVP_FRM0_ADDR_Y_ID1] = CIF_REG(DVP_FRM0_ADDR_Y_ID1),
+	[CIF_REG_DVP_FRM0_ADDR_UV_ID1] = CIF_REG(DVP_FRM0_ADDR_UV_ID1),
+	[CIF_REG_DVP_FRM1_ADDR_Y_ID1] = CIF_REG(DVP_FRM1_ADDR_Y_ID1),
+	[CIF_REG_DVP_FRM1_ADDR_UV_ID1] = CIF_REG(DVP_FRM1_ADDR_UV_ID1),
+	[CIF_REG_DVP_FRM0_ADDR_Y_ID2] = CIF_REG(DVP_FRM0_ADDR_Y_ID2),
+	[CIF_REG_DVP_FRM0_ADDR_UV_ID2] = CIF_REG(DVP_FRM0_ADDR_UV_ID2),
+	[CIF_REG_DVP_FRM1_ADDR_Y_ID2] = CIF_REG(DVP_FRM1_ADDR_Y_ID2),
+	[CIF_REG_DVP_FRM1_ADDR_UV_ID2] = CIF_REG(DVP_FRM1_ADDR_UV_ID2),
+	[CIF_REG_DVP_FRM0_ADDR_Y_ID3] = CIF_REG(DVP_FRM0_ADDR_Y_ID3),
+	[CIF_REG_DVP_FRM0_ADDR_UV_ID3] = CIF_REG(DVP_FRM0_ADDR_UV_ID3),
+	[CIF_REG_DVP_FRM1_ADDR_Y_ID3] = CIF_REG(DVP_FRM1_ADDR_Y_ID3),
+	[CIF_REG_DVP_FRM1_ADDR_UV_ID3] = CIF_REG(DVP_FRM1_ADDR_UV_ID3),
+	[CIF_REG_DVP_VIR_LINE_WIDTH] = CIF_REG(DVP_VIR_LINE_WIDTH),
+	[CIF_REG_DVP_SET_SIZE] = CIF_REG(DVP_CROP_SIZE),
+	[CIF_REG_DVP_CROP] = CIF_REG(DVP_CROP),
+	[CIF_REG_DVP_LINE_INT_NUM] = CIF_REG(DVP_LINE_INT_NUM_01),
+	[CIF_REG_DVP_LINE_INT_NUM1] = CIF_REG(DVP_LINE_INT_NUM_23),
+	[CIF_REG_DVP_LINE_CNT] = CIF_REG(DVP_LINE_INT_NUM_01),
+	[CIF_REG_DVP_LINE_CNT1] = CIF_REG(DVP_LINE_INT_NUM_23),
+
+	[CIF_REG_MIPI_LVDS_ID0_CTRL0] = CIF_REG(CSI_MIPI0_ID0_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID0_CTRL1] = CIF_REG(CSI_MIPI0_ID0_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL0] = CIF_REG(CSI_MIPI0_ID1_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL1] = CIF_REG(CSI_MIPI0_ID1_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL0] = CIF_REG(CSI_MIPI0_ID2_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL1] = CIF_REG(CSI_MIPI0_ID2_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL0] = CIF_REG(CSI_MIPI0_ID3_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL1] = CIF_REG(CSI_MIPI0_ID3_CTRL1),
+	[CIF_REG_MIPI_LVDS_CTRL] = CIF_REG(CSI_MIPI0_CTRL),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0] = CIF_REG(CSI_MIPI0_VLW_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1] = CIF_REG(CSI_MIPI0_VLW_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2] = CIF_REG(CSI_MIPI0_VLW_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3] = CIF_REG(CSI_MIPI0_VLW_ID3),
+	[CIF_REG_MIPI_LVDS_INTEN] = CIF_REG(CSI_MIPI0_INTEN),
+	[CIF_REG_MIPI_LVDS_INTSTAT] = CIF_REG(CSI_MIPI0_INTSTAT),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID2_3),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1] = CIF_REG(CSI_MIPI0_LINE_CNT_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3] = CIF_REG(CSI_MIPI0_LINE_CNT_ID2_3),
+	[CIF_REG_MIPI_LVDS_ID0_CROP_START] = CIF_REG(CSI_MIPI0_ID0_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID1_CROP_START] = CIF_REG(CSI_MIPI0_ID1_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID2_CROP_START] = CIF_REG(CSI_MIPI0_ID2_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID3_CROP_START] = CIF_REG(CSI_MIPI0_ID3_CROP_START),
+	[CIF_REG_MIPI_FRAME_NUM_VC0] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC0),
+	[CIF_REG_MIPI_FRAME_NUM_VC1] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC1),
+	[CIF_REG_MIPI_FRAME_NUM_VC2] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC2),
+	[CIF_REG_MIPI_FRAME_NUM_VC3] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC3),
+	[CIF_REG_MIPI_EFFECT_CODE_ID0] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID0),
+	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
+	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
+	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
+	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
+
+	[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
+	[CIF_REG_GLB_INTEN] = CIF_REG(GLB_INTEN),
+	[CIF_REG_GLB_INTST] = CIF_REG(GLB_INTST),
+
+	[CIF_REG_SCL_CH_CTRL] = CIF_REG(SCL_CH_CTRL),
+	[CIF_REG_SCL_CTRL] = CIF_REG(SCL_CTRL),
+	[CIF_REG_SCL_FRM0_ADDR_CH0] = CIF_REG(SCL_FRM0_ADDR_CH0),
+	[CIF_REG_SCL_FRM1_ADDR_CH0] = CIF_REG(SCL_FRM1_ADDR_CH0),
+	[CIF_REG_SCL_VLW_CH0] = CIF_REG(SCL_VLW_CH0),
+	[CIF_REG_SCL_FRM0_ADDR_CH1] = CIF_REG(SCL_FRM0_ADDR_CH1),
+	[CIF_REG_SCL_FRM1_ADDR_CH1] = CIF_REG(SCL_FRM1_ADDR_CH1),
+	[CIF_REG_SCL_VLW_CH1] = CIF_REG(SCL_VLW_CH1),
+	[CIF_REG_SCL_FRM0_ADDR_CH2] = CIF_REG(SCL_FRM0_ADDR_CH2),
+	[CIF_REG_SCL_FRM1_ADDR_CH2] = CIF_REG(SCL_FRM1_ADDR_CH2),
+	[CIF_REG_SCL_VLW_CH2] = CIF_REG(SCL_VLW_CH2),
+	[CIF_REG_SCL_FRM0_ADDR_CH3] = CIF_REG(SCL_FRM0_ADDR_CH3),
+	[CIF_REG_SCL_FRM1_ADDR_CH3] = CIF_REG(SCL_FRM1_ADDR_CH3),
+	[CIF_REG_SCL_VLW_CH3] = CIF_REG(SCL_VLW_CH3),
+	[CIF_REG_SCL_BLC_CH0] = CIF_REG(SCL_BLC_CH0),
+	[CIF_REG_SCL_BLC_CH1] = CIF_REG(SCL_BLC_CH1),
+	[CIF_REG_SCL_BLC_CH2] = CIF_REG(SCL_BLC_CH2),
+	[CIF_REG_SCL_BLC_CH3] = CIF_REG(SCL_BLC_CH3),
+	[CIF_REG_TOISP0_CTRL] = CIF_REG(TOISP0_CH_CTRL),
+	[CIF_REG_TOISP0_SIZE] = CIF_REG(TOISP0_CROP_SIZE),
+	[CIF_REG_TOISP0_CROP] = CIF_REG(TOISP0_CROP),
+	[CIF_REG_TOISP1_CTRL] = CIF_REG(TOISP1_CH_CTRL),
+	[CIF_REG_TOISP1_SIZE] = CIF_REG(TOISP1_CROP_SIZE),
+	[CIF_REG_TOISP1_CROP] = CIF_REG(TOISP1_CROP),
+	[CIF_REG_GRF_CIFIO_CON] = CIF_REG(CIF_GRF_SOC_CON2),
+};
+
+static const char * const rv1106_cif_clks[] = {
+	"aclk_cif",
+	"hclk_cif",
+	"dclk_cif",
+	"pclk_cif",
+	"i0clk_cif",
+	"i1clk_cif",
+	"rx0clk_cif",
+	"rx1clk_cif",
+	"isp0clk_cif",
+	"sclk_m0_cif",
+	"sclk_m1_cif",
+	"pclk_vepu_cif",
+};
+
+static const char * const rv1106_cif_rsts[] = {
+	"rst_cif_a",
+	"rst_cif_h",
+	"rst_cif_d",
+	"rst_cif_p",
+	"rst_cif_i0",
+	"rst_cif_i1",
+	"rst_cif_rx0",
+	"rst_cif_rx1",
+	"rst_cif_isp0",
+	"rst_cif_pclk_vepu",
+};
+
+static const struct cif_reg rv1106_cif_regs[] = {
+	[CIF_REG_DVP_CTRL] = CIF_REG(DVP_CTRL),
+	[CIF_REG_DVP_INTEN] = CIF_REG(DVP_INTEN),
+	[CIF_REG_DVP_INTSTAT] = CIF_REG(DVP_INTSTAT),
+	[CIF_REG_DVP_FOR] = CIF_REG(DVP_FOR),
+	[CIF_REG_DVP_SAV_EAV] = CIF_REG(DVP_SAV_EAV),
+	[CIF_REG_DVP_FRM0_ADDR_Y] = CIF_REG(DVP_FRM0_ADDR_Y_ID0),
+	[CIF_REG_DVP_FRM0_ADDR_UV] = CIF_REG(DVP_FRM0_ADDR_UV_ID0),
+	[CIF_REG_DVP_FRM1_ADDR_Y] = CIF_REG(DVP_FRM1_ADDR_Y_ID0),
+	[CIF_REG_DVP_FRM1_ADDR_UV] = CIF_REG(DVP_FRM1_ADDR_UV_ID0),
+	[CIF_REG_DVP_VIR_LINE_WIDTH] = CIF_REG(DVP_VIR_LINE_WIDTH),
+	[CIF_REG_DVP_SET_SIZE] = CIF_REG(DVP_CROP_SIZE),
+	[CIF_REG_DVP_CROP] = CIF_REG(DVP_CROP),
+	[CIF_REG_DVP_LINE_INT_NUM] = CIF_REG(DVP_LINE_INT_NUM_01),
+	[CIF_REG_DVP_LINE_CNT] = CIF_REG(DVP_LINE_CNT_01),
+
+	[CIF_REG_MIPI_LVDS_ID0_CTRL0] = CIF_REG(CSI_MIPI0_ID0_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID0_CTRL1] = CIF_REG(CSI_MIPI0_ID0_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL0] = CIF_REG(CSI_MIPI0_ID1_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL1] = CIF_REG(CSI_MIPI0_ID1_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL0] = CIF_REG(CSI_MIPI0_ID2_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL1] = CIF_REG(CSI_MIPI0_ID2_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL0] = CIF_REG(CSI_MIPI0_ID3_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL1] = CIF_REG(CSI_MIPI0_ID3_CTRL1),
+	[CIF_REG_MIPI_LVDS_CTRL] = CIF_REG(CSI_MIPI0_CTRL),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0] = CIF_REG(CSI_MIPI0_VLW_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1] = CIF_REG(CSI_MIPI0_VLW_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2] = CIF_REG(CSI_MIPI0_VLW_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3] = CIF_REG(CSI_MIPI0_VLW_ID3),
+	[CIF_REG_MIPI_LVDS_INTEN] = CIF_REG(CSI_MIPI0_INTEN),
+	[CIF_REG_MIPI_LVDS_INTSTAT] = CIF_REG(CSI_MIPI0_INTSTAT),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID2_3),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1] = CIF_REG(CSI_MIPI0_LINE_CNT_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3] = CIF_REG(CSI_MIPI0_LINE_CNT_ID2_3),
+	[CIF_REG_MIPI_LVDS_ID0_CROP_START] = CIF_REG(CSI_MIPI0_ID0_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID1_CROP_START] = CIF_REG(CSI_MIPI0_ID1_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID2_CROP_START] = CIF_REG(CSI_MIPI0_ID2_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID3_CROP_START] = CIF_REG(CSI_MIPI0_ID3_CROP_START),
+	[CIF_REG_MIPI_FRAME_NUM_VC0] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC0),
+	[CIF_REG_MIPI_FRAME_NUM_VC1] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC1),
+	[CIF_REG_MIPI_FRAME_NUM_VC2] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC2),
+	[CIF_REG_MIPI_FRAME_NUM_VC3] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC3),
+	[CIF_REG_MIPI_EFFECT_CODE_ID0] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID0),
+	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
+	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
+	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
+	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
+	[CIF_REG_LVDS_ID0_CTRL0] = CIF_REG(CIF_LVDS0_ID0_CTRL0),
+	[CIF_REG_LVDS_ID1_CTRL0] = CIF_REG(CIF_LVDS0_ID1_CTRL0),
+	[CIF_REG_LVDS_ID2_CTRL0] = CIF_REG(CIF_LVDS0_ID2_CTRL0),
+	[CIF_REG_LVDS_ID3_CTRL0] = CIF_REG(CIF_LVDS0_ID3_CTRL0),
+	[CIF_REG_LVDS_SAV_EAV_ACT0_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID0_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK0_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID0_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT1_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID0_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK1_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID0_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT0_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID1_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK0_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID1_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT1_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID1_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK1_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID1_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT0_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID2_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK0_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID2_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT1_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID2_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK1_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID2_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT0_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID3_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK0_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID3_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_ACT1_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID3_RV1106),
+	[CIF_REG_LVDS_SAV_EAV_BLK1_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID3_RV1106),
+	[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
+	[CIF_REG_GLB_INTEN] = CIF_REG(GLB_INTEN),
+	[CIF_REG_GLB_INTST] = CIF_REG(GLB_INTST),
+
+	[CIF_REG_SCL_CH_CTRL] = CIF_REG(SCL_CH_CTRL),
+	[CIF_REG_SCL_CTRL] = CIF_REG(SCL_CTRL),
+	[CIF_REG_SCL_FRM0_ADDR_CH0] = CIF_REG(SCL_FRM0_ADDR_CH0),
+	[CIF_REG_SCL_FRM1_ADDR_CH0] = CIF_REG(SCL_FRM1_ADDR_CH0),
+	[CIF_REG_SCL_VLW_CH0] = CIF_REG(SCL_VLW_CH0),
+	[CIF_REG_SCL_FRM0_ADDR_CH1] = CIF_REG(SCL_FRM0_ADDR_CH1),
+	[CIF_REG_SCL_FRM1_ADDR_CH1] = CIF_REG(SCL_FRM1_ADDR_CH1),
+	[CIF_REG_SCL_VLW_CH1] = CIF_REG(SCL_VLW_CH1),
+	[CIF_REG_SCL_FRM0_ADDR_CH2] = CIF_REG(SCL_FRM0_ADDR_CH2),
+	[CIF_REG_SCL_FRM1_ADDR_CH2] = CIF_REG(SCL_FRM1_ADDR_CH2),
+	[CIF_REG_SCL_VLW_CH2] = CIF_REG(SCL_VLW_CH2),
+	[CIF_REG_SCL_FRM0_ADDR_CH3] = CIF_REG(SCL_FRM0_ADDR_CH3),
+	[CIF_REG_SCL_FRM1_ADDR_CH3] = CIF_REG(SCL_FRM1_ADDR_CH3),
+	[CIF_REG_SCL_VLW_CH3] = CIF_REG(SCL_VLW_CH3),
+	[CIF_REG_SCL_BLC_CH0] = CIF_REG(SCL_BLC_CH0),
+	[CIF_REG_SCL_BLC_CH1] = CIF_REG(SCL_BLC_CH1),
+	[CIF_REG_SCL_BLC_CH2] = CIF_REG(SCL_BLC_CH2),
+	[CIF_REG_SCL_BLC_CH3] = CIF_REG(SCL_BLC_CH3),
+
+	[CIF_REG_TOISP0_CTRL] = CIF_REG(TOISP0_CH_CTRL),
+	[CIF_REG_TOISP0_SIZE] = CIF_REG(TOISP0_CROP_SIZE),
+	[CIF_REG_TOISP0_CROP] = CIF_REG(TOISP0_CROP),
+	[CIF_REG_GRF_CIFIO_CON] = CIF_REG(RV1106_CIF_GRF_VI_CON),
+	[CIF_REG_GRF_CIFIO_VENC] = CIF_REG(RV1106_CIF_GRF_VENC_WRAPPER),
+};
+
+static const char * const rk3562_cif_clks[] = {
+	"aclk_cif",
+	"hclk_cif",
+	"dclk_cif",
+	"csirx0_data",
+	"csirx1_data",
+	"csirx2_data",
+	"csirx3_data",
+};
+
+static const char * const rk3562_cif_rsts[] = {
+	"rst_cif_a",
+	"rst_cif_h",
+	"rst_cif_d",
+	"rst_cif_i0",
+	"rst_cif_i1",
+	"rst_cif_i2",
+	"rst_cif_i3",
+};
+
+static const struct cif_reg rk3562_cif_regs[] = {
+	[CIF_REG_MIPI_LVDS_ID0_CTRL0] = CIF_REG(CSI_MIPI0_ID0_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID0_CTRL1] = CIF_REG(CSI_MIPI0_ID0_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL0] = CIF_REG(CSI_MIPI0_ID1_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID1_CTRL1] = CIF_REG(CSI_MIPI0_ID1_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL0] = CIF_REG(CSI_MIPI0_ID2_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID2_CTRL1] = CIF_REG(CSI_MIPI0_ID2_CTRL1),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL0] = CIF_REG(CSI_MIPI0_ID3_CTRL0),
+	[CIF_REG_MIPI_LVDS_ID3_CTRL1] = CIF_REG(CSI_MIPI0_ID3_CTRL1),
+	[CIF_REG_MIPI_LVDS_CTRL] = CIF_REG(CSI_MIPI0_CTRL),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID0] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0] = CIF_REG(CSI_MIPI0_VLW_ID0),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID1] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1] = CIF_REG(CSI_MIPI0_VLW_ID1),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID2] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2] = CIF_REG(CSI_MIPI0_VLW_ID2),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_Y_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM0_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME1_ADDR_UV_ID3] = CIF_REG(CSI_MIPI0_FRM1_ADDR_UV_ID3),
+	[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3] = CIF_REG(CSI_MIPI0_VLW_ID3),
+	[CIF_REG_MIPI_LVDS_INTEN] = CIF_REG(CSI_MIPI0_INTEN),
+	[CIF_REG_MIPI_LVDS_INTSTAT] = CIF_REG(CSI_MIPI0_INTSTAT),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3] = CIF_REG(CSI_MIPI0_LINE_INT_NUM_ID2_3),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1] = CIF_REG(CSI_MIPI0_LINE_CNT_ID0_1),
+	[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3] = CIF_REG(CSI_MIPI0_LINE_CNT_ID2_3),
+	[CIF_REG_MIPI_LVDS_ID0_CROP_START] = CIF_REG(CSI_MIPI0_ID0_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID1_CROP_START] = CIF_REG(CSI_MIPI0_ID1_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID2_CROP_START] = CIF_REG(CSI_MIPI0_ID2_CROP_START),
+	[CIF_REG_MIPI_LVDS_ID3_CROP_START] = CIF_REG(CSI_MIPI0_ID3_CROP_START),
+	[CIF_REG_MIPI_FRAME_NUM_VC0] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC0),
+	[CIF_REG_MIPI_FRAME_NUM_VC1] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC1),
+	[CIF_REG_MIPI_FRAME_NUM_VC2] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC2),
+	[CIF_REG_MIPI_FRAME_NUM_VC3] = CIF_REG(CSI_MIPI0_FRAME_NUM_VC3),
+	[CIF_REG_MIPI_EFFECT_CODE_ID0] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID0),
+	[CIF_REG_MIPI_EFFECT_CODE_ID1] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID1),
+	[CIF_REG_MIPI_EFFECT_CODE_ID2] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID2),
+	[CIF_REG_MIPI_EFFECT_CODE_ID3] = CIF_REG(CSI_MIPI0_EFFECT_CODE_ID3),
+	[CIF_REG_MIPI_FRAME_SIZE_ID0] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID0),
+	[CIF_REG_MIPI_FRAME_SIZE_ID1] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID1),
+	[CIF_REG_MIPI_FRAME_SIZE_ID2] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID2),
+	[CIF_REG_MIPI_FRAME_SIZE_ID3] = CIF_REG(CSI_MIPI0_FRAME_SIZE_ID3),
+	[CIF_REG_MIPI_ON_PAD] = CIF_REG(CSI_MIPI0_ON_PAD),
+
+	[CIF_REG_GLB_CTRL] = CIF_REG(GLB_CTRL),
+	[CIF_REG_GLB_INTEN] = CIF_REG(GLB_INTEN),
+	[CIF_REG_GLB_INTST] = CIF_REG(GLB_INTST),
+
+	[CIF_REG_SCL_CH_CTRL] = CIF_REG(SCL_CH_CTRL),
+	[CIF_REG_SCL_CTRL] = CIF_REG(SCL_CTRL),
+	[CIF_REG_SCL_FRM0_ADDR_CH0] = CIF_REG(SCL_FRM0_ADDR_CH0),
+	[CIF_REG_SCL_FRM1_ADDR_CH0] = CIF_REG(SCL_FRM1_ADDR_CH0),
+	[CIF_REG_SCL_VLW_CH0] = CIF_REG(SCL_VLW_CH0),
+	[CIF_REG_SCL_BLC_CH0] = CIF_REG(SCL_BLC_CH0),
+
+	[CIF_REG_TOISP0_CTRL] = CIF_REG(TOISP0_CH_CTRL),
+	[CIF_REG_TOISP0_SIZE] = CIF_REG(TOISP0_CROP_SIZE),
+	[CIF_REG_TOISP0_CROP] = CIF_REG(TOISP0_CROP),
+};
+
 static const struct rkcif_hw_match_data px30_cif_match_data = {
 	.chip_id = CHIP_PX30_CIF,
 	.clks = px30_cif_clks,
@@ -678,6 +1052,32 @@
 	.cif_regs = rk3568_cif_regs,
 };
 
+static const struct rkcif_hw_match_data rk3588_cif_match_data = {
+	.chip_id = CHIP_RK3588_CIF,
+	.clks = rk3588_cif_clks,
+	.clks_num = ARRAY_SIZE(rk3588_cif_clks),
+	.rsts = rk3588_cif_rsts,
+	.rsts_num = ARRAY_SIZE(rk3588_cif_rsts),
+	.cif_regs = rk3588_cif_regs,
+};
+
+static const struct rkcif_hw_match_data rv1106_cif_match_data = {
+	.chip_id = CHIP_RV1106_CIF,
+	.clks = rv1106_cif_clks,
+	.clks_num = ARRAY_SIZE(rv1106_cif_clks),
+	.rsts = rv1106_cif_rsts,
+	.rsts_num = ARRAY_SIZE(rv1106_cif_rsts),
+	.cif_regs = rv1106_cif_regs,
+};
+
+static const struct rkcif_hw_match_data rk3562_cif_match_data = {
+	.chip_id = CHIP_RK3562_CIF,
+	.clks = rk3562_cif_clks,
+	.clks_num = ARRAY_SIZE(rk3562_cif_clks),
+	.rsts = rk3562_cif_rsts,
+	.rsts_num = ARRAY_SIZE(rk3562_cif_rsts),
+	.cif_regs = rk3562_cif_regs,
+};
 
 static const struct of_device_id rkcif_plat_of_match[] = {
 #ifdef CONFIG_CPU_PX30
@@ -722,6 +1122,12 @@
 		.data = &rk3568_cif_match_data,
 	},
 #endif
+#ifdef CONFIG_CPU_RK3588
+	{
+		.compatible = "rockchip,rk3588-cif",
+		.data = &rk3588_cif_match_data,
+	},
+#endif
 #ifdef CONFIG_CPU_RV1126
 	{
 		.compatible = "rockchip,rv1126-cif",
@@ -732,6 +1138,18 @@
 		.data = &rv1126_cif_lite_match_data,
 	},
 #endif
+#ifdef CONFIG_CPU_RV1106
+	{
+		.compatible = "rockchip,rv1106-cif",
+		.data = &rv1106_cif_match_data,
+	},
+#endif
+#ifdef CONFIG_CPU_RK3562
+	{
+		.compatible = "rockchip,rk3562-cif",
+		.data = &rk3562_cif_match_data,
+	},
+#endif
 	{},
 };
 
@@ -739,16 +1157,32 @@
 {
 	struct device *dev = ctx;
 	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
+	unsigned int intstat_glb = 0;
+	u64 irq_start, irq_stop;
 	int i;
-	struct rkcif_device *tmp_dev = NULL;
 
-	for (i = 0; i < cif_hw->dev_num; i++) {
-		tmp_dev = cif_hw->cif_dev[i];
-		if (tmp_dev->isr_hdl &&
-		    (atomic_read(&tmp_dev->pipe.stream_cnt) != 0))
-			tmp_dev->isr_hdl(irq, tmp_dev);
+	irq_start = ktime_get_ns();
+	if (cif_hw->chip_id >= CHIP_RK3588_CIF) {
+		intstat_glb = rkcif_irq_global(cif_hw->cif_dev[0]);
+		if (intstat_glb)
+			rkcif_write_register(cif_hw->cif_dev[0], CIF_REG_GLB_INTST, intstat_glb);
 	}
 
+	for (i = 0; i < cif_hw->dev_num; i++) {
+		if (cif_hw->cif_dev[i]->isr_hdl) {
+			cif_hw->cif_dev[i]->isr_hdl(irq, cif_hw->cif_dev[i]);
+			if (cif_hw->cif_dev[i]->err_state &&
+			    (!work_busy(&cif_hw->cif_dev[i]->err_state_work.work))) {
+				cif_hw->cif_dev[i]->err_state_work.err_state = cif_hw->cif_dev[i]->err_state;
+				cif_hw->cif_dev[i]->err_state = 0;
+				schedule_work(&cif_hw->cif_dev[i]->err_state_work.work);
+			}
+			if (cif_hw->chip_id >= CHIP_RK3588_CIF && intstat_glb)
+				rkcif_irq_handle_toisp(cif_hw->cif_dev[i], intstat_glb);
+		}
+	}
+	irq_stop = ktime_get_ns();
+	cif_hw->irq_time = irq_stop - irq_start;
 	return IRQ_HANDLED;
 }
 
@@ -783,17 +1217,14 @@
 
 static void rkcif_iommu_cleanup(struct rkcif_hw *cif_hw)
 {
-	if (cif_hw->domain)
-		iommu_detach_device(cif_hw->domain, cif_hw->dev);
+	if (cif_hw->iommu_en)
+		rockchip_iommu_disable(cif_hw->dev);
 }
 
 static void rkcif_iommu_enable(struct rkcif_hw *cif_hw)
 {
-	if (!cif_hw->domain)
-		cif_hw->domain = iommu_get_domain_for_dev(cif_hw->dev);
-
-	if (cif_hw->domain)
-		iommu_attach_device(cif_hw->domain, cif_hw->dev);
+	if (cif_hw->iommu_en)
+		rockchip_iommu_enable(cif_hw->dev);
 }
 
 static inline bool is_iommu_enable(struct device *dev)
@@ -833,81 +1264,49 @@
 		rkcif_iommu_enable(cif_hw);
 }
 
-static char *rkcif_get_monitor_mode(enum rkcif_monitor_mode mode)
+static int rkcif_get_efuse_value(struct device_node *np, char *porp_name,
+				    u8 *value)
 {
-	switch (mode) {
-	case RKCIF_MONITOR_MODE_IDLE:
-		return "idle";
-	case RKCIF_MONITOR_MODE_CONTINUE:
-		return "continue";
-	case RKCIF_MONITOR_MODE_TRIGGER:
-		return "trigger";
-	case RKCIF_MONITOR_MODE_HOTPLUG:
-		return "hotplug";
-	default:
-		return "unknown";
-	}
+	struct nvmem_cell *cell;
+	unsigned char *buf;
+	size_t len;
+
+	cell = of_nvmem_cell_get(np, porp_name);
+	if (IS_ERR(cell))
+		return PTR_ERR(cell);
+
+	buf = (unsigned char *)nvmem_cell_read(cell, &len);
+
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	*value = buf[0];
+
+	kfree(buf);
+
+	return 0;
 }
 
-static void rkcif_init_reset_timer(struct rkcif_hw *hw)
+static int rkcif_get_speciand_package_number(struct device_node *np)
 {
-	struct device_node *node = hw->dev->of_node;
-	struct rkcif_hw_timer *hw_timer = &hw->hw_timer;
-	u32 para[8];
-	int i;
+	u8 spec = 0, package = 0, low = 0, high = 0;
 
-	if (!of_property_read_u32_array(node,
-					OF_CIF_MONITOR_PARA,
-					para,
-					CIF_MONITOR_PARA_NUM)) {
-		for (i = 0; i < CIF_MONITOR_PARA_NUM; i++) {
-			if (i == 0) {
-				hw_timer->monitor_mode = para[0];
-				dev_info(hw->dev,
-					 "%s: timer monitor mode:%s\n",
-					 __func__, rkcif_get_monitor_mode(hw_timer->monitor_mode));
-			}
+	if (rkcif_get_efuse_value(np, "specification", &spec))
+		return -EINVAL;
+	if (rkcif_get_efuse_value(np, "package_low", &low))
+		return -EINVAL;
+	if (rkcif_get_efuse_value(np, "package_high", &high))
+		return -EINVAL;
 
-			if (i == 1) {
-				hw_timer->monitor_cycle = para[1];
-				dev_info(hw->dev,
-					 "timer of monitor cycle:%d\n",
-					 hw_timer->monitor_cycle);
-			}
+	package = ((high & 0x1) << 3) | low;
 
-			if (i == 2) {
-				hw_timer->err_time_interval = para[2];
-				dev_info(hw->dev,
-					 "timer err time for keeping:%d ms\n",
-					 hw_timer->err_time_interval);
-			}
+	/* RK3588S */
+	if (spec == 0x13)
+		return package;
 
-			if (i == 3) {
-				hw_timer->err_ref_cnt = para[3];
-				dev_info(hw->dev,
-					 "timer err ref val for resetting:%d\n",
-					 hw_timer->err_ref_cnt);
-			}
-
-			if (i == 4) {
-				hw_timer->is_reset_by_user = para[4];
-				dev_info(hw->dev,
-					 "reset by user:%d\n",
-					 hw_timer->is_reset_by_user);
-			}
-		}
-	} else {
-		hw_timer->monitor_mode = RKCIF_MONITOR_MODE_IDLE;
-		hw_timer->err_time_interval = 0xffffffff;
-		hw_timer->monitor_cycle = 0xffffffff;
-		hw_timer->err_ref_cnt = 0xffffffff;
-		hw_timer->is_reset_by_user = 0;
-	}
-
-	hw_timer->is_running = false;
-	spin_lock_init(&hw_timer->timer_lock);
-	hw->reset_info.is_need_reset = 0;
-	timer_setup(&hw_timer->timer, rkcif_reset_watchdog_timer_handler, 0);
+	return -EINVAL;
 }
 
 static int rkcif_plat_hw_probe(struct platform_device *pdev)
@@ -921,6 +1320,9 @@
 	const struct rkcif_hw_match_data *data;
 	struct resource *res;
 	int i, ret, irq;
+	bool is_mem_reserved = false;
+	struct notifier_block *notifier;
+	int package = 0;
 
 	match = of_match_node(rkcif_plat_of_match, node);
 	if (IS_ERR(match))
@@ -934,6 +1336,13 @@
 	dev_set_drvdata(dev, cif_hw);
 	cif_hw->dev = dev;
 
+	package = rkcif_get_speciand_package_number(node);
+	if (package == 0x2) {
+		cif_hw->is_rk3588s2 = true;
+		dev_info(dev, "attach rk3588s2\n");
+	} else {
+		cif_hw->is_rk3588s2 = false;
+	}
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
@@ -949,10 +1358,7 @@
 	cif_hw->irq = irq;
 	cif_hw->match_data = data;
 	cif_hw->chip_id = data->chip_id;
-	if (data->chip_id == CHIP_RK1808_CIF ||
-	    data->chip_id == CHIP_RV1126_CIF ||
-	    data->chip_id == CHIP_RV1126_CIF_LITE ||
-	    data->chip_id == CHIP_RK3568_CIF) {
+	if (data->chip_id >= CHIP_RK1808_CIF) {
 		res = platform_get_resource_byname(pdev,
 						   IORESOURCE_MEM,
 						   "cif_regs");
@@ -972,6 +1378,11 @@
 		cif_hw->base_addr = devm_ioremap_resource(dev, res);
 		if (IS_ERR(cif_hw->base_addr))
 			return PTR_ERR(cif_hw->base_addr);
+	}
+
+	if (of_property_read_bool(np, "rockchip,android-usb-camerahal-enable")) {
+		dev_info(dev, "config cif adapt to android usb camera hal!\n");
+		cif_hw->adapt_to_usbcamerahal = true;
 	}
 
 	cif_hw->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
@@ -1003,25 +1414,32 @@
 		if (data->rsts[i])
 			rst = devm_reset_control_get(dev, data->rsts[i]);
 		if (IS_ERR(rst)) {
+			cif_hw->cif_rst[i] = NULL;
 			dev_err(dev, "failed to get %s\n", data->rsts[i]);
-			return PTR_ERR(rst);
+		} else {
+			cif_hw->cif_rst[i] = rst;
 		}
-		cif_hw->cif_rst[i] = rst;
 	}
 
 	cif_hw->cif_regs = data->cif_regs;
 
-	cif_hw->iommu_en = is_iommu_enable(dev);
-	if (!cif_hw->iommu_en) {
-		ret = of_reserved_mem_device_init(dev);
-		if (ret)
-			dev_info(dev, "No reserved memory region assign to CIF\n");
-	}
+	cif_hw->is_dma_sg_ops = true;
+	cif_hw->is_dma_contig = true;
+	mutex_init(&cif_hw->dev_lock);
+	spin_lock_init(&cif_hw->group_lock);
+	atomic_set(&cif_hw->power_cnt, 0);
 
-	if (data->chip_id != CHIP_RK1808_CIF &&
-	    data->chip_id != CHIP_RV1126_CIF &&
-	    data->chip_id != CHIP_RV1126_CIF_LITE &&
-	    data->chip_id != CHIP_RK3568_CIF) {
+	cif_hw->iommu_en = is_iommu_enable(dev);
+	ret = of_reserved_mem_device_init(dev);
+	if (ret) {
+		is_mem_reserved = false;
+		dev_info(dev, "No reserved memory region assign to CIF\n");
+	}
+	if (cif_hw->iommu_en && !is_mem_reserved)
+		cif_hw->is_dma_contig = false;
+	cif_hw->mem_ops = &vb2_cma_sg_memops;
+
+	if (data->chip_id < CHIP_RK1808_CIF) {
 		cif_dev = devm_kzalloc(dev, sizeof(*cif_dev), GFP_KERNEL);
 		if (!cif_dev)
 			return -ENOMEM;
@@ -1036,20 +1454,20 @@
 			return ret;
 	}
 
-	rkcif_hw_soft_reset(cif_hw, true);
-
 	mutex_init(&cif_hw->dev_lock);
-	spin_lock_init(&cif_hw->spin_lock);
 
 	pm_runtime_enable(&pdev->dev);
-	rkcif_init_reset_timer(cif_hw);
 
-	if (data->chip_id == CHIP_RK1808_CIF ||
-	    data->chip_id == CHIP_RV1126_CIF ||
-	    data->chip_id == CHIP_RK3568_CIF) {
+	if (data->chip_id >= CHIP_RK1808_CIF &&
+	    data->chip_id != CHIP_RV1126_CIF_LITE) {
 		platform_driver_register(&rkcif_plat_drv);
 		platform_driver_register(&rkcif_subdev_driver);
 	}
+
+	notifier = &cif_hw->reset_notifier;
+	notifier->priority = 1;
+	notifier->notifier_call = rkcif_reset_notifier;
+	rkcif_csi2_register_notifier(notifier);
 
 	return 0;
 }
@@ -1063,19 +1481,53 @@
 		rkcif_iommu_cleanup(cif_hw);
 
 	mutex_destroy(&cif_hw->dev_lock);
-	if (cif_hw->chip_id != CHIP_RK1808_CIF &&
-	    cif_hw->chip_id != CHIP_RV1126_CIF &&
-	    cif_hw->chip_id != CHIP_RV1126_CIF_LITE &&
-	    cif_hw->chip_id != CHIP_RK3568_CIF)
+	if (cif_hw->chip_id < CHIP_RK1808_CIF)
 		rkcif_plat_uninit(cif_hw->cif_dev[0]);
-	del_timer_sync(&cif_hw->hw_timer.timer);
+
+	rkcif_csi2_unregister_notifier(&cif_hw->reset_notifier);
+
 	return 0;
+}
+
+static void rkcif_hw_shutdown(struct platform_device *pdev)
+{
+	struct rkcif_hw *cif_hw = platform_get_drvdata(pdev);
+	struct rkcif_device *cif_dev = NULL;
+	int i = 0;
+
+	if (pm_runtime_get_if_in_use(&pdev->dev) <= 0)
+		return;
+
+	if (cif_hw->chip_id == CHIP_RK3588_CIF ||
+	    cif_hw->chip_id == CHIP_RV1106_CIF ||
+	    cif_hw->chip_id == CHIP_RK3562_CIF) {
+		write_cif_reg(cif_hw->base_addr, 0, 0);
+	} else {
+		for (i = 0; i < cif_hw->dev_num; i++) {
+			cif_dev = cif_hw->cif_dev[i];
+			if (atomic_read(&cif_dev->pipe.stream_cnt)) {
+				if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
+					rkcif_write_register(cif_dev,
+							     CIF_REG_MIPI_LVDS_CTRL,
+							     0);
+				else
+					rkcif_write_register(cif_dev,
+							     CIF_REG_DVP_CTRL,
+							     0);
+			}
+		}
+	}
+	if (cif_hw->irq > 0)
+		disable_irq(cif_hw->irq);
+	pm_runtime_put(&pdev->dev);
 }
 
 static int __maybe_unused rkcif_runtime_suspend(struct device *dev)
 {
 	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
 
+	if (atomic_dec_return(&cif_hw->power_cnt))
+		return 0;
 	rkcif_disable_sys_clk(cif_hw);
 
 	return pinctrl_pm_select_sleep_state(dev);
@@ -1086,17 +1538,49 @@
 	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
 	int ret;
 
+	if (atomic_inc_return(&cif_hw->power_cnt) > 1)
+		return 0;
 	ret = pinctrl_pm_select_default_state(dev);
 	if (ret < 0)
 		return ret;
 	rkcif_enable_sys_clk(cif_hw);
+	rkcif_hw_soft_reset(cif_hw, true);
+
+	return 0;
+}
+
+static int __maybe_unused rkcif_sleep_suspend(struct device *dev)
+{
+	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
+
+	if (atomic_read(&cif_hw->power_cnt) == 0)
+		return 0;
+
+	rkcif_disable_sys_clk(cif_hw);
+
+	return pinctrl_pm_select_sleep_state(dev);
+}
+
+static int __maybe_unused rkcif_sleep_resume(struct device *dev)
+{
+	struct rkcif_hw *cif_hw = dev_get_drvdata(dev);
+	int ret;
+
+	if (atomic_read(&cif_hw->power_cnt) == 0)
+		return 0;
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret < 0)
+		return ret;
+	rkcif_enable_sys_clk(cif_hw);
+	rkcif_hw_soft_reset(cif_hw, true);
 
 	return 0;
 }
 
 static const struct dev_pm_ops rkcif_plat_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
-				pm_runtime_force_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(rkcif_sleep_suspend,
+				rkcif_sleep_resume)
 	SET_RUNTIME_PM_OPS(rkcif_runtime_suspend, rkcif_runtime_resume, NULL)
 };
 
@@ -1108,15 +1592,17 @@
 	},
 	.probe = rkcif_plat_hw_probe,
 	.remove = rkcif_plat_remove,
+	.shutdown = rkcif_hw_shutdown,
 };
 
-static int __init rk_cif_plat_drv_init(void)
+int rk_cif_plat_drv_init(void)
 {
 	int ret;
 
 	ret = platform_driver_register(&rkcif_hw_plat_drv);
 	if (ret)
 		return ret;
+	rkcif_csi2_hw_plat_drv_init();
 	return rkcif_csi2_plat_drv_init();
 }
 
@@ -1124,9 +1610,16 @@
 {
 	platform_driver_unregister(&rkcif_hw_plat_drv);
 	rkcif_csi2_plat_drv_exit();
+	rkcif_csi2_hw_plat_drv_exit();
 }
 
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
+subsys_initcall(rk_cif_plat_drv_init);
+#else
+#if !defined(CONFIG_VIDEO_REVERSE_IMAGE)
 module_init(rk_cif_plat_drv_init);
+#endif
+#endif
 module_exit(rk_cif_plat_drv_exit);
 
 MODULE_AUTHOR("Rockchip Camera/ISP team");

--
Gitblit v1.6.2