From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 03 Jan 2024 09:43:39 +0000
Subject: [PATCH] update kernel to 5.10.198

---
 kernel/drivers/media/platform/rockchip/isp/csi.c |  281 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 230 insertions(+), 51 deletions(-)

diff --git a/kernel/drivers/media/platform/rockchip/isp/csi.c b/kernel/drivers/media/platform/rockchip/isp/csi.c
index 0d90605..efa3714 100644
--- a/kernel/drivers/media/platform/rockchip/isp/csi.c
+++ b/kernel/drivers/media/platform/rockchip/isp/csi.c
@@ -12,9 +12,10 @@
 #include <media/v4l2-subdev.h>
 #include <media/videobuf2-dma-contig.h>
 #include "dev.h"
+#include "isp_external.h"
 #include "regs.h"
 
-static void get_remote_mipi_sensor(struct rkisp_device *dev,
+void rkisp_get_remote_mipi_sensor(struct rkisp_device *dev,
 				  struct v4l2_subdev **sensor_sd, u32 function)
 {
 	struct media_graph graph;
@@ -81,6 +82,8 @@
 		id = local->index - 1;
 		if (id && id < RKISP_STREAM_DMATX3)
 			stream = &csi->ispdev->cap_dev.stream[id + 1];
+		if (id >= ARRAY_SIZE(csi->sink))
+			return -EINVAL;
 		if (flags & MEDIA_LNK_FL_ENABLED) {
 			if (csi->sink[id].linked) {
 				ret = -EBUSY;
@@ -103,14 +106,15 @@
 }
 
 static int rkisp_csi_g_mbus_config(struct v4l2_subdev *sd,
-				  struct v4l2_mbus_config *config)
+				   unsigned int pad_id,
+				   struct v4l2_mbus_config *config)
 {
 	struct v4l2_subdev *remote_sd;
 
 	if (!sd)
 		return -ENODEV;
 	remote_sd = get_remote_subdev(sd);
-	return v4l2_subdev_call(remote_sd, video, g_mbus_config, config);
+	return v4l2_subdev_call(remote_sd, pad, get_mbus_config, pad_id, config);
 }
 
 static int rkisp_csi_get_set_fmt(struct v4l2_subdev *sd,
@@ -159,10 +163,10 @@
 static const struct v4l2_subdev_pad_ops rkisp_csi_pad_ops = {
 	.set_fmt = rkisp_csi_get_set_fmt,
 	.get_fmt = rkisp_csi_get_set_fmt,
+	.get_mbus_config = rkisp_csi_g_mbus_config,
 };
 
 static const struct v4l2_subdev_video_ops rkisp_csi_video_ops = {
-	.g_mbus_config = rkisp_csi_g_mbus_config,
 	.s_stream = rkisp_csi_s_stream,
 };
 
@@ -208,7 +212,7 @@
 	emd_vc = 0xFF;
 	emd_dt = 0;
 	dev->hdr.sensor = NULL;
-	get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
+	rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_CAM_SENSOR);
 	if (mipi_sensor) {
 		ctrl = v4l2_ctrl_find(mipi_sensor->ctrl_handler,
 				      CIFISP_CID_EMB_VC);
@@ -279,15 +283,10 @@
 
 		dev->hdr.op_mode = HDR_NORMAL;
 		dev->hdr.esp_mode = HDR_NORMAL_VC;
-		if (mipi_sensor) {
-			ret = v4l2_subdev_call(mipi_sensor,
-					       core, ioctl,
-					       RKMODULE_GET_HDR_CFG,
-					       &hdr_cfg);
-			if (!ret) {
-				dev->hdr.op_mode = hdr_cfg.hdr_mode;
-				dev->hdr.esp_mode = hdr_cfg.esp.mode;
-			}
+		memset(&hdr_cfg, 0, sizeof(hdr_cfg));
+		if (rkisp_csi_get_hdr_cfg(dev, &hdr_cfg) == 0) {
+			dev->hdr.op_mode = hdr_cfg.hdr_mode;
+			dev->hdr.esp_mode = hdr_cfg.esp.mode;
 		}
 
 		/* normal read back mode */
@@ -316,9 +315,13 @@
 			rkisp_write(dev, CSI2RX_DATA_IDS_1, val, true);
 		} else {
 			rkisp_set_bits(dev, CSI2RX_DATA_IDS_1, mask, val, true);
-			for (i = 0; i < dev->hw_dev->dev_num; i++)
+			for (i = 0; i < dev->hw_dev->dev_num; i++) {
+				if (dev->hw_dev->isp[i] &&
+				    !dev->hw_dev->isp[i]->is_hw_link)
+					continue;
 				rkisp_set_bits(dev->hw_dev->isp[i],
 					CSI2RX_DATA_IDS_1, mask, val, false);
+			}
 		}
 		val = SW_CSI_ID4(csi->mipi_di[4]);
 		rkisp_write(dev, CSI2RX_DATA_IDS_2, val, true);
@@ -338,9 +341,13 @@
 			Y_STAT_AFIFOX3_OVERFLOW;
 		rkisp_write(dev, CSI2RX_MASK_OVERFLOW, val, true);
 		val = RAW0_WR_FRAME | RAW1_WR_FRAME | RAW2_WR_FRAME |
-			MIPI_DROP_FRM | RAW_WR_SIZE_ERR | MIPI_LINECNT |
+			RAW_WR_SIZE_ERR | MIPI_LINECNT |
 			RAW_RD_SIZE_ERR | RAW0_Y_STATE |
 			RAW1_Y_STATE | RAW2_Y_STATE;
+		if (dev->isp_ver == ISP_V20)
+			val |= MIPI_DROP_FRM;
+		else
+			val |= ISP21_MIPI_DROP_FRM;
 		rkisp_write(dev, CSI2RX_MASK_STAT, val, true);
 
 		/* hdr merge */
@@ -423,6 +430,133 @@
 	return 0;
 }
 
+int rkisp_expander_config(struct rkisp_device *dev,
+			  struct rkmodule_hdr_cfg *cfg, bool on)
+{
+	struct rkmodule_hdr_cfg hdr_cfg;
+	u32 i, val, num, d0, d1, drop_bit = 0;
+
+	if (dev->isp_ver != ISP_V32)
+		return 0;
+
+	if (!on) {
+		rkisp_write(dev, ISP32_EXPD_CTRL, 0, false);
+		return 0;
+	}
+
+	if (!cfg) {
+		if (rkisp_csi_get_hdr_cfg(dev, &hdr_cfg) != 0)
+			goto err;
+		cfg = &hdr_cfg;
+	}
+
+	if (cfg->hdr_mode != HDR_COMPR)
+		return 0;
+
+	/* compressed data max 12bit and src data max 20bit */
+	if (cfg->compr.bit > 20)
+		drop_bit = cfg->compr.bit - 20;
+	dev->hdr.compr_bit = cfg->compr.bit - drop_bit;
+
+	num = cfg->compr.segment;
+	for (i = 0; i < num; i++) {
+		val = cfg->compr.slope_k[i];
+		rkisp_write(dev, ISP32_EXPD_K0 + i * 4, val, false);
+	}
+
+	d0 = 0;
+	d1 = cfg->compr.data_compr[0];
+	val = ISP32_EXPD_DATA(d0, d1 > 0xfff ? 0xfff : d1);
+	rkisp_write(dev, ISP32_EXPD_X00_01, val, false);
+
+	d1 = cfg->compr.data_src_shitf[0];
+	val = ISP32_EXPD_DATA(d0, drop_bit ? d1 >> drop_bit : d1);
+	rkisp_write(dev, ISP32_EXPD_Y00_01, val, false);
+
+	for (i = 1; i < num - 1; i += 2) {
+		d0 = cfg->compr.data_compr[i];
+		d1 = cfg->compr.data_compr[i + 1];
+		val = ISP32_EXPD_DATA(d0 > 0xfff ? 0xfff : d0,
+				      d1 > 0xfff ? 0xfff : d1);
+		rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, val, false);
+
+		d0 = cfg->compr.data_src_shitf[i];
+		d1 = cfg->compr.data_src_shitf[i + 1];
+		if (drop_bit) {
+			d0 = d0 >> drop_bit;
+			d1 = d1 >> drop_bit;
+		}
+		val = ISP32_EXPD_DATA(d0, d1);
+		rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, val, false);
+	}
+
+	/* the last valid point */
+	val = cfg->compr.data_compr[i];
+	val = val > 0xfff ? 0xfff : val;
+	d0 = ISP32_EXPD_DATA(val, val);
+
+	val = cfg->compr.data_src_shitf[i];
+	val = drop_bit ? val >> drop_bit : val;
+	d1 = ISP32_EXPD_DATA(val, val);
+
+	num = HDR_COMPR_SEGMENT_16;
+	for (; i < num - 1; i += 2) {
+		rkisp_write(dev, ISP32_EXPD_X00_01 + (i + 1) * 2, d0, false);
+		rkisp_write(dev, ISP32_EXPD_Y00_01 + (i + 1) * 2, d1, false);
+	}
+	rkisp_write(dev, ISP32_EXPD_Y16, val, false);
+
+	switch (cfg->compr.segment) {
+	case HDR_COMPR_SEGMENT_12:
+		num = 1;
+		break;
+	case HDR_COMPR_SEGMENT_16:
+		num = 2;
+		break;
+	default:
+		num = 0;
+	}
+	val = ISP32_EXPD_EN |
+	      ISP32_EXPD_MODE(num) |
+	      ISP32_EXPD_K_SHIFT(cfg->compr.k_shift);
+	rkisp_write(dev, ISP32_EXPD_CTRL, val, false);
+	return 0;
+err:
+	return -EINVAL;
+}
+
+int rkisp_csi_get_hdr_cfg(struct rkisp_device *dev, void *arg)
+{
+	struct rkmodule_hdr_cfg *cfg = arg;
+	struct v4l2_subdev *sd = NULL;
+	u32 type;
+
+	if (dev->isp_inp & INP_CSI) {
+		type = MEDIA_ENT_F_CAM_SENSOR;
+	} else if (dev->isp_inp & INP_CIF) {
+		type = MEDIA_ENT_F_PROC_VIDEO_COMPOSER;
+	} else {
+		switch (dev->isp_inp & 0x7) {
+		case INP_RAWRD2 | INP_RAWRD0:
+			cfg->hdr_mode = HDR_RDBK_FRAME2;
+			break;
+		case INP_RAWRD2 | INP_RAWRD1 | INP_RAWRD0:
+			cfg->hdr_mode = HDR_RDBK_FRAME3;
+			break;
+		default: //INP_RAWRD2
+			cfg->hdr_mode = HDR_RDBK_FRAME1;
+		}
+		return 0;
+	}
+	rkisp_get_remote_mipi_sensor(dev, &sd, type);
+	if (!sd) {
+		v4l2_err(&dev->v4l2_dev, "%s don't find subdev\n", __func__);
+		return -EINVAL;
+	}
+
+	return v4l2_subdev_call(sd, core, ioctl, RKMODULE_GET_HDR_CFG, cfg);
+}
+
 int rkisp_csi_config_patch(struct rkisp_device *dev)
 {
 	int val = 0, ret = 0;
@@ -434,63 +568,106 @@
 		dev->hw_dev->mipi_dev_id = dev->dev_id;
 		ret = csi_config(&dev->csi_dev);
 	} else {
-		if (dev->isp_inp & INP_CIF) {
-			struct rkmodule_hdr_cfg hdr_cfg;
+		struct rkmodule_hdr_cfg hdr_cfg;
 
-			get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
+		memset(&hdr_cfg, 0, sizeof(hdr_cfg));
+		ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg);
+		if (dev->isp_inp & INP_CIF) {
+			struct rkisp_vicap_mode mode;
+			int buf_cnt;
+
+			memset(&mode, 0, sizeof(mode));
+			mode.name = dev->name;
+
+			rkisp_get_remote_mipi_sensor(dev, &mipi_sensor, MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
+			if (!mipi_sensor)
+				return -EINVAL;
 			dev->hdr.op_mode = HDR_NORMAL;
 			dev->hdr.esp_mode = HDR_NORMAL_VC;
-			if (mipi_sensor) {
-				ret = v4l2_subdev_call(mipi_sensor,
-						       core, ioctl,
-						       RKMODULE_GET_HDR_CFG,
-						       &hdr_cfg);
-				if (!ret) {
-					dev->hdr.op_mode = hdr_cfg.hdr_mode;
-					dev->hdr.esp_mode = hdr_cfg.esp.mode;
-				}
+			if (!ret) {
+				dev->hdr.op_mode = hdr_cfg.hdr_mode;
+				dev->hdr.esp_mode = hdr_cfg.esp.mode;
+				rkisp_expander_config(dev, &hdr_cfg, true);
 			}
 
-			/* normal read back mode */
-			if (dev->hdr.op_mode == HDR_NORMAL)
+			/* normal read back mode default */
+			if (dev->hdr.op_mode == HDR_NORMAL || dev->hdr.op_mode == HDR_COMPR)
 				dev->hdr.op_mode = HDR_RDBK_FRAME1;
-		} else {
-			switch (dev->isp_inp & 0x7) {
-			case INP_RAWRD2 | INP_RAWRD0:
-				dev->hdr.op_mode = HDR_RDBK_FRAME2;
-				break;
-			case INP_RAWRD2 | INP_RAWRD1 | INP_RAWRD0:
-				dev->hdr.op_mode = HDR_RDBK_FRAME3;
-				break;
-			default: //INP_RAWRD2
-				dev->hdr.op_mode = HDR_RDBK_FRAME1;
+
+			if (dev->isp_inp == INP_CIF && dev->isp_ver > ISP_V21)
+				mode.rdbk_mode = dev->is_rdbk_auto ? RKISP_VICAP_RDBK_AUTO : RKISP_VICAP_ONLINE;
+			else
+				mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
+			v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_MODE, &mode);
+			dev->vicap_in = mode.input;
+			/* vicap direct to isp */
+			if (dev->isp_ver >= ISP_V30 && !mode.rdbk_mode) {
+				switch (dev->hdr.op_mode) {
+				case HDR_RDBK_FRAME3:
+					dev->hdr.op_mode = HDR_LINEX3_DDR;
+					break;
+				case HDR_RDBK_FRAME2:
+					dev->hdr.op_mode = HDR_LINEX2_DDR;
+					break;
+				default:
+					dev->hdr.op_mode = HDR_NORMAL;
+				}
+				if (dev->hdr.op_mode != HDR_NORMAL) {
+					buf_cnt = 1;
+					v4l2_subdev_call(mipi_sensor, core, ioctl,
+							 RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
+				}
+			} else if (mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
+				buf_cnt = RKISP_VICAP_BUF_CNT;
+				v4l2_subdev_call(mipi_sensor, core, ioctl,
+						 RKISP_VICAP_CMD_INIT_BUF, &buf_cnt);
 			}
+		} else {
+			dev->hdr.op_mode = hdr_cfg.hdr_mode;
 		}
 
-		if (dev->hdr.op_mode == HDR_RDBK_FRAME2)
-			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX2;
-		else if (dev->hdr.op_mode == HDR_RDBK_FRAME3)
-			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX3;
-
 		if (!dev->hw_dev->is_mi_update)
-			rkisp_write(dev, CSI2RX_CTRL0,
-				    SW_IBUF_OP_MODE(dev->hdr.op_mode), true);
+			rkisp_unite_write(dev, CSI2RX_CTRL0,
+					  SW_IBUF_OP_MODE(dev->hdr.op_mode), true);
 
+		/* hdr merge */
+		switch (dev->hdr.op_mode) {
+		case HDR_RDBK_FRAME2:
+		case HDR_FRAMEX2_DDR:
+		case HDR_LINEX2_DDR:
+		case HDR_LINEX2_NO_DDR:
+			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX2;
+			break;
+		case HDR_RDBK_FRAME3:
+		case HDR_FRAMEX3_DDR:
+		case HDR_LINEX3_DDR:
+			val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX3;
+			break;
+		default:
+			val = 0;
+		}
 		if (is_feature_on) {
 			if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) {
 				v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n");
 				return -EINVAL;
 			}
 		}
-		rkisp_write(dev, ISP_HDRMGE_BASE, val, false);
+		rkisp_unite_write(dev, ISP_HDRMGE_BASE, val, false);
 
-		rkisp_set_bits(dev, CSI2RX_MASK_STAT, 0, RAW_RD_SIZE_ERR, true);
+		val = RAW_RD_SIZE_ERR;
+		if (!IS_HDR_RDBK(dev->hdr.op_mode))
+			val |= ISP21_MIPI_DROP_FRM;
+		rkisp_unite_set_bits(dev, CSI2RX_MASK_STAT, 0, val, true);
 	}
 
 	if (IS_HDR_RDBK(dev->hdr.op_mode))
-		rkisp_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS, true);
+		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, SW_MPIP_DROP_FRM_DIS, true);
 
-	memset(dev->filt_state, 0, sizeof(dev->filt_state));
+	if (dev->isp_ver >= ISP_V30)
+		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP3X_SW_ACK_FRM_PRO_DIS, true);
+	/* line counter from isp out, default from mp out */
+	if (dev->isp_ver == ISP_V32_L)
+		rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, ISP32L_ISP2ENC_CNT_MUX, true);
 	dev->rdbk_cnt = -1;
 	dev->rdbk_cnt_x1 = -1;
 	dev->rdbk_cnt_x2 = -1;
@@ -556,6 +733,8 @@
 		csi_dev->pads[CSI_SRC_CH2].flags = MEDIA_PAD_FL_SOURCE;
 		csi_dev->pads[CSI_SRC_CH3].flags = MEDIA_PAD_FL_SOURCE;
 		csi_dev->pads[CSI_SRC_CH4].flags = MEDIA_PAD_FL_SOURCE;
+	} else if (dev->isp_ver >= ISP_V30) {
+		return 0;
 	}
 
 	ret = media_entity_pads_init(&sd->entity, csi_dev->max_pad,

--
Gitblit v1.6.2