From 102a0743326a03cd1a1202ceda21e175b7d3575c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 20 Feb 2024 01:20:52 +0000
Subject: [PATCH] add new system file
---
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