From d465481ffac2e109060f62bbc6d6afd05c66c724 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Wed, 8 Jan 2025 15:14:04 +0800 Subject: [PATCH] media: rockchip: isp: aiisp for isp35 Change-Id: I52313925f5007b9192402e50a985e8cbd42b1e73 Signed-off-by: Cai YiWei --- .../media/platform/rockchip/isp/capture_v35.c | 8 +- drivers/media/platform/rockchip/isp/dev.c | 8 +- drivers/media/platform/rockchip/isp/dev.h | 2 + drivers/media/platform/rockchip/isp/hw.c | 83 +- drivers/media/platform/rockchip/isp/hw.h | 4 +- .../media/platform/rockchip/isp/isp_params.c | 2 + .../media/platform/rockchip/isp/isp_params.h | 2 + .../platform/rockchip/isp/isp_params_v35.c | 1545 ++++++++++++++--- .../platform/rockchip/isp/isp_params_v35.h | 63 +- .../platform/rockchip/isp/isp_stats_v35.c | 315 +++- drivers/media/platform/rockchip/isp/procfs.c | 12 +- drivers/media/platform/rockchip/isp/regs.h | 1 + drivers/media/platform/rockchip/isp/rkisp.c | 36 +- drivers/media/platform/rockchip/isp/rkisp.h | 2 + .../media/platform/rockchip/isp/vpsl_reg.h | 252 +++ include/uapi/linux/rk-isp2-config.h | 30 +- include/uapi/linux/rk-isp35-config.h | 21 +- 17 files changed, 2019 insertions(+), 367 deletions(-) create mode 100644 drivers/media/platform/rockchip/isp/vpsl_reg.h diff --git a/drivers/media/platform/rockchip/isp/capture_v35.c b/drivers/media/platform/rockchip/isp/capture_v35.c index bb3c759479c0..32e71077b0c4 100644 --- a/drivers/media/platform/rockchip/isp/capture_v35.c +++ b/drivers/media/platform/rockchip/isp/capture_v35.c @@ -961,7 +961,7 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) vb2_set_plane_payload(vb2_buf, i, payload_size); } - rkisp_dmarx_get_frame(dev, &i, NULL, &ns, true); + rkisp_dmarx_get_frame(dev, &i, NULL, &ns, !dev->is_aiisp_en); if (!ns) ns = rkisp_time_get_ns(dev); buf->vb.sequence = i; @@ -1024,7 +1024,9 @@ static void rkisp_stream_stop(struct rkisp_stream *stream) stream->ops->disable_mi(stream); if (IS_HDR_RDBK(dev->rd_mode)) { spin_lock_irqsave(&dev->hw_dev->rdbk_lock, lock_flags); - if (dev->hw_dev->cur_dev_id != dev->dev_id || dev->hw_dev->is_idle) { + if (dev->hw_dev->cur_dev_id != dev->dev_id || + (!dev->is_aiisp_en && dev->hw_dev->is_idle) || + (dev->is_aiisp_en && dev->hw_dev->is_be_idle)) { is_wait = false; if (stream->ops->disable_mi) stream->ops->disable_mi(stream); @@ -1635,7 +1637,7 @@ void rkisp_mi_v35_isr(u32 mis_val, struct rkisp_device *dev) ns = rkisp_time_get_ns(dev); stream->dbg.interval = ns - stream->dbg.timestamp; stream->dbg.timestamp = ns; - rkisp_dmarx_get_frame(dev, &seq, NULL, &ns, true); + rkisp_dmarx_get_frame(dev, &seq, NULL, &ns, !dev->is_aiisp_en); stream->dbg.delay = stream->dbg.timestamp - ns; stream->dbg.id = seq; } else { diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 11d907dc79f1..93e419aa967d 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -351,7 +351,8 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, rkisp_csi_config_patch(dev, false); dev->is_aiisp_sync = false; if (dev->is_aiisp_en && - (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2) || dev->is_rdbk_auto)) + ((dev->isp_ver == ISP_V35 && !hw->is_single) || + (dev->isp_ver == ISP_V39 && (dev->isp_inp & INP_RAWRD2 || dev->is_rdbk_auto)))) dev->is_aiisp_sync = true; return 0; err: @@ -937,6 +938,11 @@ static int rkisp_plat_probe(struct platform_device *pdev) isp_dev->sw_base_addr = devm_kzalloc(dev, RKISP_ISP_SW_MAX_SIZE * mult, GFP_KERNEL); if (!isp_dev->sw_base_addr) return -ENOMEM; + if (isp_dev->hw_dev->isp_ver == ISP_V35) { + isp_dev->sw_vpsl_base_addr = devm_kzalloc(dev, VPSL_SW_MAX_SIZE * mult, GFP_KERNEL); + if (!isp_dev->sw_vpsl_base_addr) + return -ENOMEM; + } ret = rkisp_vs_irq_parse(dev); if (ret) diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index f5eba75d5b55..5ad79c4bd1fd 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -80,6 +80,7 @@ enum rkisp_isp_state { ISP_FRAME_BP = BIT(6), ISP_FRAME_LDC = BIT(7), ISP_FRAME_VPSS = BIT(8), + ISP_FRAME_VPSL = BIT(9), ISP_STOP = BIT(16), ISP_START = BIT(17), @@ -213,6 +214,7 @@ struct rkisp_device { struct device *dev; char name[128]; void *sw_base_addr; + void *sw_vpsl_base_addr; struct rkisp_hw_dev *hw_dev; struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index f8e447b5f86e..e0183a655813 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -24,6 +24,7 @@ #include "dev.h" #include "hw.h" #include "regs.h" +#include "vpsl_reg.h" /* * rkisp_hw share hardware resource with rkisp virtual device @@ -249,6 +250,42 @@ static irqreturn_t isp_irq_hdl(int irq, void *ctx) return IRQ_HANDLED; } +static irqreturn_t vpsl_mi_irq_hdl(int irq, void *ctx) +{ + struct device *dev = ctx; + struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); + struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id]; + void __iomem *base = hw_dev->vpsl_base_addr; + u32 mis_val; + + mis_val = readl(base + VPSL_MI_MIS); + if (mis_val) { + writel(mis_val, base + VPSL_MI_ICR); + v4l2_dbg(3, rkisp_debug, &isp->v4l2_dev, + "%s isr:0x%x\n", __func__, mis_val); + rkisp_vpsl_mi_isr(isp, mis_val); + } + return IRQ_HANDLED; +} + +static irqreturn_t vpsl_irq_hdl(int irq, void *ctx) +{ + struct device *dev = ctx; + struct rkisp_hw_dev *hw_dev = dev_get_drvdata(dev); + struct rkisp_device *isp = hw_dev->isp[hw_dev->cur_dev_id]; + void __iomem *base = hw_dev->vpsl_base_addr; + u32 mis_val; + + mis_val = readl(base + VPSL_MIS); + if (mis_val) { + writel(mis_val, base + VPSL_ICR); + v4l2_dbg(3, rkisp_debug, &isp->v4l2_dev, + "%s isr:0x%x\n", __func__, mis_val); + } + + return IRQ_HANDLED; +} + int rkisp_register_irq(struct rkisp_hw_dev *hw_dev) { const struct isp_match_data *match_data = hw_dev->match_data; @@ -794,6 +831,14 @@ static struct isp_irqs_data isp_irqs[] = { {"mipi_irq", mipi_irq_hdl} }; +static struct isp_irqs_data isp35_irqs[] = { + {"isp_irq", isp_irq_hdl}, + {"isp_mi_irq", mi_irq_hdl}, + {"isp_mipi_irq", mipi_irq_hdl}, + {"vpsl_mi_irq", vpsl_mi_irq_hdl}, + {"vpsl_irq", vpsl_irq_hdl}, +}; + static const struct isp_match_data rv1103b_isp_match_data = { .clks = rv1106_isp_clks, .num_clks = ARRAY_SIZE(rv1106_isp_clks), @@ -833,8 +878,8 @@ static const struct isp_match_data rv1126b_isp_match_data = { .isp_ver = ISP_V35, .clk_rate_tbl = rv1126_isp_clk_rate, .num_clk_rate_tbl = ARRAY_SIZE(rv1126_isp_clk_rate), - .irqs = isp_irqs, - .num_irqs = ARRAY_SIZE(isp_irqs), + .irqs = isp35_irqs, + .num_irqs = ARRAY_SIZE(isp35_irqs), .unite = false, }; @@ -1299,6 +1344,29 @@ static int rkisp_hw_probe(struct platform_device *pdev) hw_dev->unite = ISP_UNITE_NONE; } + hw_dev->vpsl_base_addr = NULL; + if (hw_dev->isp_ver == ISP_V35) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "get vpsl resource failed\n"); + ret = -EINVAL; + goto err; + } + hw_dev->vpsl_base_addr = devm_ioremap_resource(dev, res); + if (PTR_ERR(hw_dev->vpsl_base_addr) == -EBUSY) { + resource_size_t offset = res->start; + resource_size_t size = resource_size(res); + + hw_dev->vpsl_base_addr = devm_ioremap(dev, offset, size); + } + + if (IS_ERR(hw_dev->vpsl_base_addr)) { + dev_err(dev, "ioremap vpsl failed\n"); + ret = PTR_ERR(hw_dev->vpsl_base_addr); + goto err; + } + } + memset(&hw_dev->max_in, 0, sizeof(hw_dev->max_in)); if (!of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3)) { hw_dev->max_in.is_fix = true; @@ -1361,6 +1429,7 @@ static int rkisp_hw_probe(struct platform_device *pdev) mutex_init(&hw_dev->dev_lock); spin_lock_init(&hw_dev->rdbk_lock); atomic_set(&hw_dev->refcnt, 0); + spin_lock_init(&hw_dev->reg_lock); spin_lock_init(&hw_dev->buf_lock); INIT_LIST_HEAD(&hw_dev->list); INIT_LIST_HEAD(&hw_dev->rpt_list); @@ -1518,6 +1587,16 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) base = hw_dev->base_next_addr; memcpy_fromio(buf, base, RKISP_ISP_SW_REG_SIZE); } + if (isp->sw_vpsl_base_addr && hw_dev->vpsl_base_addr) { + u32 *flag; + + buf = isp->sw_vpsl_base_addr; + memset(buf, 0, VPSL_SW_MAX_SIZE * mult); + flag = buf + VPSL_SW_REG_SIZE + VPSL_PYR_CTRL; + *flag = SW_REG_CACHE; + flag = buf + VPSL_PYR_CHN + VPSL_PYR_CTRL; + *flag = SW_REG_CACHE; + } default_sw_reg_flag(hw_dev->isp[i]); } rkisp_hw_enum_isp_size(hw_dev); diff --git a/drivers/media/platform/rockchip/isp/hw.h b/drivers/media/platform/rockchip/isp/hw.h index 20fbc19f0cb8..9314e72870da 100644 --- a/drivers/media/platform/rockchip/isp/hw.h +++ b/drivers/media/platform/rockchip/isp/hw.h @@ -55,6 +55,7 @@ struct rkisp_hw_dev { void *sw_reg; void __iomem *base_addr; void __iomem *base_next_addr; + void __iomem *vpsl_base_addr; struct clk *clks[RKISP_MAX_BUS_CLK]; int num_clks; const struct isp_clk_info *clk_rate_tbl; @@ -77,7 +78,8 @@ struct rkisp_hw_dev { atomic_t refcnt; struct rkisp_sram sram; - + /* lock for reg */ + spinlock_t reg_lock; /* share buf for multi dev */ spinlock_t buf_lock; struct rkisp_bridge_buf bufs[BRIDGE_BUF_MAX]; diff --git a/drivers/media/platform/rockchip/isp/isp_params.c b/drivers/media/platform/rockchip/isp/isp_params.c index cedb6221ee55..5ed7da6e64c5 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.c +++ b/drivers/media/platform/rockchip/isp/isp_params.c @@ -506,7 +506,9 @@ void rkisp_params_first_cfg(struct rkisp_isp_params_vdev *params_vdev, enum v4l2_quantization quantization) { struct rkisp_device *dev = params_vdev->dev; + u32 val = rkisp_read(dev, ISP_HDRMGE_CTRL, false); + params_vdev->is_hdr = !!(val & SW_HDRMGE_EN); if (!params_vdev->is_first_cfg) return; params_vdev->is_first_cfg = false; diff --git a/drivers/media/platform/rockchip/isp/isp_params.h b/drivers/media/platform/rockchip/isp/isp_params.h index 0cc858a3882c..cec291be2d3b 100644 --- a/drivers/media/platform/rockchip/isp/isp_params.h +++ b/drivers/media/platform/rockchip/isp/isp_params.h @@ -58,6 +58,7 @@ struct rkisp_isp_params_ops { void (*aiisp_event)(struct rkisp_isp_params_vdev *params_vdev, u32 irq); int (*aiisp_start)(struct rkisp_isp_params_vdev *params_vdev, struct rkisp_aiisp_st *st); int (*get_aiawb_buffd)(struct rkisp_isp_params_vdev *params_vdev, void *arg); + void (*vpsl_update_regs)(struct rkisp_isp_params_vdev *params_vdev); }; /* @@ -111,6 +112,7 @@ struct rkisp_isp_params_vdev { bool is_subs_evt; bool is_first_cfg; + bool is_hdr; }; static inline void diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.c b/drivers/media/platform/rockchip/isp/isp_params_v35.c index 5653db4538c4..2347785bc33c 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.c @@ -2,6 +2,7 @@ /* Copyright (c) 2025 Rockchip Electronics Co., Ltd. */ #include +#include #include #include #include @@ -295,44 +296,60 @@ isp_dpcc_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) static void isp_bls_config(struct rkisp_isp_params_vdev *params_vdev, - const struct isp35_bls_cfg *arg, u32 id) + const struct isp35_bls_cfg *arg, + enum rkisp_params_type type, u32 id) { + struct rkisp_device *dev = params_vdev->dev; const struct isp2x_bls_fixed_val *pval; + unsigned long lock_flags = 0; u32 new_control, value; + bool is_lock = false; + + if (!dev->is_aiisp_en || + type == RKISP_PARAMS_LAT || type == RKISP_PARAMS_ALL) { + pval = &arg->bls1_val; + switch (params_vdev->raw_type) { + case RAW_BGGR: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_A_FIXED, id); + break; + case RAW_GBRG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_B_FIXED, id); + break; + case RAW_GRBG: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_D_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_C_FIXED, id); + break; + case RAW_RGGB: + default: + isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_A_FIXED, id); + isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_B_FIXED, id); + isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_C_FIXED, id); + isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_D_FIXED, id); + break; + } + if (type == RKISP_PARAMS_LAT) { + spin_lock_irqsave(&dev->hw_dev->reg_lock, lock_flags); + value = isp3_param_read(params_vdev, ISP32_BLS_ISP_OB_OFFSET, id); + value &= 0xffff; + value |= arg->isp_ob_offset1 << 16; + isp3_param_write(params_vdev, value, ISP32_BLS_ISP_OB_OFFSET, id); + spin_unlock_irqrestore(&dev->hw_dev->reg_lock, lock_flags); + return; + } + } new_control = isp3_param_read(params_vdev, ISP3X_BLS_CTRL, id); new_control &= (ISP_BLS_ENA | ISP32_BLS_BLS2_EN); - - pval = &arg->bls1_val; if (arg->bls1_en) new_control |= ISP_BLS_BLS1_EN; - switch (params_vdev->raw_type) { - case RAW_BGGR: - isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_D_FIXED, id); - isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_C_FIXED, id); - isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_B_FIXED, id); - isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_A_FIXED, id); - break; - case RAW_GBRG: - isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_C_FIXED, id); - isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_D_FIXED, id); - isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_A_FIXED, id); - isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_B_FIXED, id); - break; - case RAW_GRBG: - isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_B_FIXED, id); - isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_A_FIXED, id); - isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_D_FIXED, id); - isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_C_FIXED, id); - break; - case RAW_RGGB: - default: - isp3_param_write(params_vdev, pval->r, ISP3X_BLS1_A_FIXED, id); - isp3_param_write(params_vdev, pval->gr, ISP3X_BLS1_B_FIXED, id); - isp3_param_write(params_vdev, pval->gb, ISP3X_BLS1_C_FIXED, id); - isp3_param_write(params_vdev, pval->b, ISP3X_BLS1_D_FIXED, id); - break; - } /* fixed subtraction values */ pval = &arg->fixed_val; @@ -395,10 +412,23 @@ isp_bls_config(struct rkisp_isp_params_vdev *params_vdev, } isp3_param_write(params_vdev, new_control, ISP3X_BLS_CTRL, id); - value = ISP_PACK_2SHORT(arg->isp_ob_offset, arg->isp_ob_offset1); - isp3_param_write(params_vdev, value, ISP32_BLS_ISP_OB_OFFSET, id); isp3_param_write(params_vdev, arg->isp_ob_predgain, ISP32_BLS_ISP_OB_PREDGAIN, id); isp3_param_write(params_vdev, arg->isp_ob_max, ISP32_BLS_ISP_OB_MAX, id); + + if (dev->is_aiisp_en && !dev->is_aiisp_sync && type != RKISP_PARAMS_ALL) + is_lock = true; + if (is_lock) { + spin_lock_irqsave(&dev->hw_dev->reg_lock, lock_flags); + + value = isp3_param_read(params_vdev, ISP32_BLS_ISP_OB_OFFSET, id); + value &= 0xffff0000; + value |= arg->isp_ob_offset; + } else { + value = ISP_PACK_2SHORT(arg->isp_ob_offset, arg->isp_ob_offset1); + } + isp3_param_write(params_vdev, value, ISP32_BLS_ISP_OB_OFFSET, id); + if (is_lock) + spin_unlock_irqrestore(&dev->hw_dev->reg_lock, lock_flags); } static void @@ -629,7 +659,8 @@ isp_debayer_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) static void isp_awbgain_config(struct rkisp_isp_params_vdev *params_vdev, - const struct isp32_awb_gain_cfg *arg, u32 id) + const struct isp32_awb_gain_cfg *arg, + enum rkisp_params_type type, u32 id) { struct rkisp_device *dev = params_vdev->dev; @@ -643,6 +674,18 @@ isp_awbgain_config(struct rkisp_isp_params_vdev *params_vdev, return; } + if (!dev->is_aiisp_en || dev->is_aiisp_sync || + type == RKISP_PARAMS_ALL || type == RKISP_PARAMS_LAT) { + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->awb1_gain_gb, arg->awb1_gain_gr), + ISP32_ISP_AWB1_GAIN_G, id); + isp3_param_write(params_vdev, + ISP_PACK_2SHORT(arg->awb1_gain_b, arg->awb1_gain_r), + ISP32_ISP_AWB1_GAIN_RB, id); + if (type == RKISP_PARAMS_LAT) + return; + } + isp3_param_write(params_vdev, ISP_PACK_2SHORT(arg->gain0_green_b, arg->gain0_green_r), ISP3X_ISP_AWB_GAIN0_G, id); @@ -663,13 +706,6 @@ isp_awbgain_config(struct rkisp_isp_params_vdev *params_vdev, isp3_param_write(params_vdev, ISP_PACK_2SHORT(arg->gain2_blue, arg->gain2_red), ISP3X_ISP_AWB_GAIN2_RB, id); - - isp3_param_write(params_vdev, - ISP_PACK_2SHORT(arg->awb1_gain_gb, arg->awb1_gain_gr), - ISP32_ISP_AWB1_GAIN_G, id); - isp3_param_write(params_vdev, - ISP_PACK_2SHORT(arg->awb1_gain_b, arg->awb1_gain_r), - ISP32_ISP_AWB1_GAIN_RB, id); } static void @@ -1030,6 +1066,7 @@ isp_rawae_config(struct rkisp_isp_params_vdev *params_vdev, const struct isp35_rawae_meas_cfg *arg, u32 addr, u32 id) { + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; struct rkisp_device *ispdev = params_vdev->dev; struct v4l2_rect *out_crop = &ispdev->isp_sdev.out_crop; u32 width = out_crop->width, height = out_crop->height; @@ -1101,11 +1138,18 @@ isp_rawae_config(struct rkisp_isp_params_vdev *params_vdev, value |= ISP3X_RAWAE3_SEL(arg->rawae_sel & 0xf); value |= !!arg->bnr2ae_sel << 29; isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + priv->is_ae3_fe = true; + if ((arg->bnr2ae_sel && arg->bnr_be_sel) || + (!arg->bnr2ae_sel && arg->rawae_sel == 3)) + priv->is_ae3_fe = false; } else { value &= ~(ISP3X_RAWAE012_SEL(3) | BIT(30)); value |= ISP3X_RAWAE012_SEL(arg->rawae_sel & 0xf); value |= !!arg->bnr2ae_sel << 30; isp3_param_write(params_vdev, value, ISP3X_VI_ISP_PATH, id); + priv->is_ae0_fe = true; + if (arg->bnr2ae_sel && arg->bnr_be_sel) + priv->is_ae0_fe = false; } } @@ -3571,7 +3615,13 @@ isp_bay3d_config(struct rkisp_isp_params_vdev *params_vdev, isp3_param_set_bits(params_vdev, ISP3X_ISP_CTRL1, ISP3X_RAW3D_FST_FRAME, id); ctrl &= ISP35_MODULE_EN; - ctrl |= (arg->iir_rw_fmt & 0x3) << 13 | + value = arg->iir_rw_fmt; + if (value != priv->bay3d_iir_rw_fmt) { + dev_err(dev->dev, "%s iir_rw_fmt:%d unequal to init fmt:%d\n", + __func__, value, priv->bay3d_iir_rw_fmt); + value = priv->bay3d_iir_rw_fmt; + } + ctrl |= (value & 0x3) << 13 | !!arg->motion_est_en << 8 | (arg->out_use_pre_mode & 0x7) << 5 | !!arg->iir_wr_src << 3 | @@ -3964,8 +4014,8 @@ isp_bay3d_config(struct rkisp_isp_params_vdev *params_vdev, static void isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) { - struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; - struct rkisp_device *ispdev = params_vdev->dev; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; u32 value, ctrl; ctrl = isp3_param_read_cache(params_vdev, ISP33_BAY3D_CTRL0, id); @@ -3973,30 +4023,66 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) return; if (en) { - if (!priv_val->buf_3dnr_iir.mem_priv) { - dev_err(ispdev->dev, "no bay3d buffer available\n"); + if (!priv->buf_bay3d_iir[0].mem_priv || + !priv->buf_bay3d_ds[0].mem_priv || + !priv->buf_bay3d_wgt[0].mem_priv) { + dev_err(dev->dev, "no bay3d buffer available\n"); return; } - value = priv_val->bay3d_iir_size; + priv->bay3d_iir_idx = 0; + priv->bay3d_iir_cur_idx = 0; + value = priv->bay3d_iir_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_SIZE, id); - value = priv_val->buf_3dnr_iir.dma_addr + value * id; - isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); + value = priv->buf_bay3d_iir[0].dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_BASE, id); + if (priv->bay3d_iir_rw_fmt == 3) { + isp3_param_write(params_vdev, value, ISP35_B3DLDC_WR_ADDR, id); + value += priv->bay3d_iir_offs; + } + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_BASE, id); + if (priv->buf_aiisp[0].mem_priv) { + priv->aiisp_cur_idx = 0; + value = priv->buf_aiisp[0].dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP39_AIISP_RD_BASE, id); + } + value = priv->bay3d_iir_stride; + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_WR_LENGTH, id); + isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_IIR_RD_LENGTH, id); + isp3_param_write(params_vdev, value, ISP3X_MI_DBR_RD_LENGTH, id); + isp3_param_write(params_vdev, value, ISP35_B3DLDC_WR_STRIDE, id); - value = priv_val->bay3d_ds_size; + priv->bay3d_ds_idx = 0; + priv->bay3d_ds_cur_idx = 0; + value = priv->bay3d_ds_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_SIZE, id); - value = priv_val->buf_3dnr_ds.dma_addr + value * id; + value = priv->buf_bay3d_ds[0].dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_DS_RD_BASE, id); - value = priv_val->bay3d_wgt_size; + priv->bay3d_wgt_idx = 0; + priv->bay3d_wgt_cur_idx = 0; + value = priv->bay3d_wgt_size; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_SIZE, id); isp3_param_write(params_vdev, value, ISP32_MI_BAY3D_CUR_RD_SIZE, id); - value = priv_val->buf_3dnr_wgt.dma_addr + value * id; + value = priv->buf_bay3d_wgt[0].dma_addr + value * id; isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_WR_BASE, id); isp3_param_write(params_vdev, value, ISP3X_MI_BAY3D_CUR_RD_BASE, id); + if (priv->buf_gain[0].mem_priv) { + value = priv->gain_size; + isp3_param_write(params_vdev, value, ISP3X_MI_GAIN_WR_SIZE, id); + if (!params_vdev->is_hdr) + isp3_param_write(params_vdev, 0, ISP32_MI_RAW0_RD_SIZE, id); + value = priv->buf_gain[0].dma_addr + value * id; + isp3_param_write(params_vdev, value, ISP3X_MI_GAIN_WR_BASE, id); + if (!params_vdev->is_hdr) + isp3_param_write(params_vdev, value, ISP3X_MI_RAW0_RD_BASE, id); + else + isp3_param_write(params_vdev, value, ISP35_B3DLDCH_RD_BASE, id); + priv->gain_cur_idx = 0; + } + ctrl |= ISP35_MODULE_EN; isp3_param_write(params_vdev, ctrl, ISP33_BAY3D_CTRL0, id); @@ -4004,7 +4090,7 @@ isp_bay3d_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) ISP3X_BAY3D_DS_WR_AUTO_UPD | ISP3X_BAY3D_IIRSELF_UPD | ISP3X_BAY3D_CURSELF_UPD | ISP3X_BAY3D_DSSELF_UPD | ISP3X_BAY3D_RDSELF_UPD; - if (priv_val->buf_gain.mem_priv) + if (priv->buf_gain[0].mem_priv) value |= ISP3X_GAIN_WR_AUTO_UPD | ISP3X_GAINSELF_UPD; isp3_param_set_bits(params_vdev, MI_WR_CTRL2, value, id); @@ -4249,32 +4335,220 @@ isp_rgbir_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) isp3_param_write(params_vdev, value, ISP39_RGBIR_CTRL, id); } +static void vpsl_update_buf(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + u32 i, val, ds_cnt; + + if (!priv->pbuf_vpsl) + return; + priv->vpsl_cur_idx = priv->pbuf_vpsl->index; + ds_cnt = priv->yraw_sel ? VPSL_YRAW_CHN_MAX / 2 : VPSL_YRAW_CHN_MAX; + for (i = 0; i < ds_cnt; i++) { + val = priv->pbuf_vpsl->dma_addr + priv->vpsl_yraw_offs[i]; + vpsl_write(dev, VPSL_MI_CHN0_WR_BASE + i * 0x100, val, false); + val = priv->vpsl_yraw_stride[i]; + vpsl_write(dev, VPSL_MI_CHN0_WR_STRIDE + i * 0x100, val, false); + vpsl_write(dev, VPSL_MI_CHN0_WR_CTRL + i * 0x100, VPSL_CHN_WR_AUTO_UPD, false); + } + ds_cnt = priv->yraw_sel ? VPSL_SIG_CHN_MAX - 1 : VPSL_SIG_CHN_MAX; + for (i = 0; i < ds_cnt; i++) { + val = priv->pbuf_vpsl->dma_addr + priv->vpsl_sig_offs[i]; + vpsl_write(dev, VPSL_MI_CHN6_WR_BASE + i * 0x100, val, false); + val = priv->vpsl_sig_stride[i]; + vpsl_write(dev, VPSL_MI_CHN6_WR_STRIDE + i * 0x100, val, false); + vpsl_write(dev, VPSL_MI_CHN6_WR_CTRL + i * 0x100, VPSL_CHN_WR_AUTO_UPD, false); + } + + vpsl_write(dev, VPSL_MI_IMSC, 0xffffffff, false); + val = VPSL_MI_WR_ID_POLL_DIS | VPSL_MI_WR_INIT_OFFSET_EN | VPSL_MI_WR_INIT_BASE_EN; + vpsl_write(dev, VPSL_MI_CTRL, val, false); + if (dev->hw_dev->is_single) + vpsl_write(dev, VPSL_MI_WR_INIT, 0x7ff0, true); +} + +static void vpsl_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_ai_cfg *arg) +{ + struct rkisp_device *dev = params_vdev->dev; + u32 i, val; + + if (!arg->pyr_sigma_en) + return; + for (i = 0; i < ISP35_VPSL_SIGMA_NUM; i++) { + val = arg->pyr_sigma_y[i]; + vpsl_write(dev, VPSL_PYR_SIGMA_LUT, val, true); + } +} + +static void vpsl_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_ai_cfg *arg, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + u32 val; + + if (!arg->pyr_yraw_mode && !arg->pyr_sigma_en) + return; + if (!priv->buf_vpsl[0].mem_priv) { + dev_err(dev->dev, "no vpsl buffer available\n"); + return; + } + + val = VPSL_CHN0_EN | VPSL_CHN1_EN | VPSL_CHN2_EN | + VPSL_CHN6_EN | VPSL_CHN7_EN | VPSL_CHN8_EN | VPSL_CHN9_EN; + if (!priv->yraw_sel) + val |= VPSL_CHN3_EN | VPSL_CHN4_EN | VPSL_CHN5_EN | VPSL_CHN10_EN; + vpsl_write(dev, VPSL_PYR_CHN, val, false); + + val = (arg->pyr_yraw_mode & 0x3) | + !!arg->pyr_sigma_en << 2 | + !!arg->pyr_yraw_sel << 4 | + (arg->pyr_gain_leftshift & 0x7) << 8 | + arg->pyr_blacklvl_sig << 16; + vpsl_write(dev, VPSL_PYR_CTRL, val, false); + + //vpsl_write(dev, VPSL_IMSC, 0xffffffff, false); + if (dev->hw_dev->is_single) { + vpsl_cfg_sram(params_vdev, arg); + val = VPSL_CFG_GEN_UPD | VPSL_YRAW_CHN_FORCE_UPD | VPSL_SIGMA_CHN_FORCE_UPD; + vpsl_write(dev, VPSL_UPDATE, val, true); + } +} + +static void +isp_ai_config(struct rkisp_isp_params_vdev *params_vdev, + const struct isp35_ai_cfg *arg, u32 id) +{ + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params + id; + struct isp35_ai_cfg *arg_rec = ¶ms_rec->others.ai_cfg; + u32 i, val; + + val = isp3_param_read(params_vdev, ISP35_AI_CTRL, id); + val &= (ISP35_AIISP_EN | ISP35_AIPRE_IIR2DDR_EN | ISP35_AIPRE_GIAN2DDR_EN); + val |= !!arg->aiisp_raw12_msb << 2 | + (arg->aiisp_gain_mode & 0x3) << 4 | + !!arg->aiisp_curve_en << 6 | + !!arg->aipre_iir_en << 8 | + //!!arg->aipre_iir2ddr_en << 9 | + !!arg->aipre_gain_en << 10 | + //!!arg->aipre_gain2ddr_en << 11 | + !!arg->aipre_yraw_sel << 12 | + !!arg->aipre_nl_ddr_mode << 13 | + !!arg->aipre_gain_bypass << 14 | + !!arg->aipre_gain_mode << 15 | + !!arg->aipre_narmap_inv << 16 | + !!arg->aipre_luma2gain_dis << 17; + if (params_vdev->is_hdr) + val |= ISP35_AIISP_HDR_EN; + isp3_param_write(params_vdev, val, ISP35_AI_CTRL, id); + for (i = 0; i < ISP35_AI_SIGMA_NUM / 2; i++) { + val = ISP_PACK_2SHORT(arg->aiisp_sigma_y[i * 2], arg->aiisp_sigma_y[i * 2 + 1]); + isp3_param_write(params_vdev, val, ISP35_AI_SIGMA_Y0 + i * 4, id); + } + val = arg->aiisp_sigma_y[ISP35_AI_SIGMA_NUM - 1]; + isp3_param_write(params_vdev, val, ISP35_AI_SIGMA_Y16, id); + + val = arg->aipre_scale | (arg->aipre_zp & 0xff) << 8 | + (arg->aipre_black_lvl & 0x1ff) << 20; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_NL_PRE, id); + + val = (arg->aipre_gain_alpha & 0xf) | arg->aipre_global_gain << 4 | + arg->aipre_gain_ratio << 12; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_GAIN_PARA, id); + + for (i = 0; i < ISP35_AI_SIGMA_NUM / 3; i++) { + val = (arg->aipre_sigma_y[i * 3] & 0x3ff) | + (arg->aipre_sigma_y[i * 3 + 1] & 0x3ff) << 10 | + (arg->aipre_sigma_y[i * 3 + 2] & 0x3ff) << 20; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_SIGMA_CURVE0 + i * 4, id); + } + + val = arg->aipre_noise_mot_offset | (arg->aipre_noise_mot_gain & 0x7f) << 8 | + (arg->aipre_noise_luma_offset & 0x3ff) << 16; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_NOISE0, id); + + val = (arg->aipre_noise_luma_gain & 0x7ff) | + (arg->aipre_noise_luma_clip & 0x3ff) << 12 | + arg->aipre_noise_luma_static << 24; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_NOISE1, id); + + val = arg->aipre_nar_manual | + (arg->aipre_nar_manual_alpha & 0x3f) << 8; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_NOISE2, id); + + vpsl_config(params_vdev, arg, id); + *arg_rec = *arg; +} + +static void +isp_ai_enable(struct rkisp_isp_params_vdev *params_vdev, bool en, u32 id) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + u32 val, ctrl = isp3_param_read(params_vdev, ISP35_AI_CTRL, id); + + if (en == !!(ctrl & ISP35_MODULE_EN)) + return; + ctrl &= ~(ISP35_AIISP_ST | ISP35_AIPRE_IIR2DDR_EN | ISP35_AIPRE_GIAN2DDR_EN); + if (en) { + if (priv->buf_aipre_gain[0].mem_priv) { + priv->aipre_gain_cur_idx = 0; + val = priv->buf_aipre_gain[0].dma_addr; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_GAIN_WR_BASE, id); + val = priv->aipre_gain_stride; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_GAIN_WR_STRIDE, id); + ctrl |= ISP35_AIPRE_GIAN2DDR_EN; + } + if (priv->buf_vpsl[0].mem_priv) { + vpsl_update_buf(params_vdev); + if (!priv->yraw_sel) + params_vdev->dev->irq_ends_mask |= ISP_FRAME_VPSL; + } + ctrl |= ISP35_AIISP_EN | ISP35_AIPRE_ITS_FORCE_UPD; + } else { + ctrl &= ~ISP35_AIISP_EN; + params_vdev->dev->irq_ends_mask &= ~ISP_FRAME_VPSL; + } + isp3_param_write(params_vdev, ctrl, ISP35_AI_CTRL, id); + if (en) { + ctrl &= ~ISP35_AIPRE_ITS_FORCE_UPD; + isp3_param_write(params_vdev, ctrl, ISP35_AI_CTRL, id); + } +} + static __maybe_unused void __isp_isr_other_config(struct rkisp_isp_params_vdev *params_vdev, const struct isp35_isp_params_cfg *new_params, enum rkisp_params_type type, u32 id) { + struct rkisp_device *dev = params_vdev->dev; u64 module_cfg_update = new_params->module_cfg_update; - v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, - "%s id:%d seq:%d module_cfg_update:0x%llx\n", - __func__, id, new_params->frame_id, module_cfg_update); + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s id:%d seq:%d type:%d module_cfg_update:0x%llx\n", + __func__, id, new_params->frame_id, type, module_cfg_update); - if (module_cfg_update & ISP35_MODULE_RGBIR) + if (module_cfg_update & ISP35_MODULE_RGBIR && type != RKISP_PARAMS_LAT) isp_rgbir_config(params_vdev, &new_params->others.rgbir_cfg, id); if (module_cfg_update & ISP35_MODULE_BLS)//bls0 ob TNR blc1, blc2 for awb - isp_bls_config(params_vdev, &new_params->others.bls_cfg, id); + isp_bls_config(params_vdev, &new_params->others.bls_cfg, type, id); if (module_cfg_update & ISP35_MODULE_AWB_GAIN)//awb0 TNR awb1 - isp_awbgain_config(params_vdev, &new_params->others.awb_gain_cfg, id); - if (module_cfg_update & ISP35_MODULE_DPCC) + isp_awbgain_config(params_vdev, &new_params->others.awb_gain_cfg, type, id); + if (module_cfg_update & ISP35_MODULE_DPCC && type != RKISP_PARAMS_LAT) isp_dpcc_config(params_vdev, &new_params->others.dpcc_cfg, id); - if (module_cfg_update & ISP35_MODULE_HDRMGE) + if (module_cfg_update & ISP35_MODULE_HDRMGE && type != RKISP_PARAMS_LAT) isp_hdrmge_config(params_vdev, &new_params->others.hdrmge_cfg, type, id); - if (module_cfg_update & ISP35_MODULE_GAIN) + if (module_cfg_update & ISP35_MODULE_GAIN && type != RKISP_PARAMS_LAT) isp_gain_config(params_vdev, &new_params->others.gain_cfg, id); - if (module_cfg_update & ISP35_MODULE_BAY3D) + if (module_cfg_update & ISP35_MODULE_AI && type != RKISP_PARAMS_LAT) + isp_ai_config(params_vdev, &new_params->others.ai_cfg, id); + if (module_cfg_update & ISP35_MODULE_BAY3D && type != RKISP_PARAMS_LAT) isp_bay3d_config(params_vdev, &new_params->others.bay3d_cfg, id); + if (type == RKISP_PARAMS_IMD && dev->is_aiisp_en && !dev->is_aiisp_sync) + return; + if (module_cfg_update & ISP35_MODULE_CAC) isp_cac_config(params_vdev, &new_params->others.cac_cfg, id); if (module_cfg_update & ISP35_MODULE_LSC) @@ -4317,7 +4591,8 @@ void __isp_isr_other_en(struct rkisp_isp_params_vdev *params_vdev, const struct isp35_isp_params_cfg *new_params, enum rkisp_params_type type, u32 id) { - struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; u64 module_en_update = new_params->module_en_update; u64 module_ens = new_params->module_ens; u64 mask; @@ -4325,26 +4600,31 @@ void __isp_isr_other_en(struct rkisp_isp_params_vdev *params_vdev, mask = ISP35_MODULE_YNR | ISP35_MODULE_CNR | ISP35_MODULE_SHARP; if ((module_ens & mask) && ((module_ens & mask) != mask)) - dev_err(params_vdev->dev->dev, "ynr cnr sharp no enable together\n"); - v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, - "%s id:%d seq:%d module_en_update:0x%llx module_ens:0x%llx\n", - __func__, id, new_params->frame_id, module_en_update, module_ens); + dev_err(dev->dev, "ynr cnr sharp no enable together\n"); + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s id:%d seq:%d type:%d module_en_update:0x%llx module_ens:0x%llx\n", + __func__, id, new_params->frame_id, type, module_en_update, module_ens); - if (module_en_update & ISP35_MODULE_RGBIR) + if (module_en_update & ISP35_MODULE_RGBIR && type != RKISP_PARAMS_LAT) isp_rgbir_enable(params_vdev, !!(module_ens & ISP35_MODULE_RGBIR), id); if (module_en_update & ISP35_MODULE_BLS) isp_bls_enable(params_vdev, !!(module_ens & ISP35_MODULE_BLS), id); if (module_en_update & ISP35_MODULE_AWB_GAIN) isp_awbgain_enable(params_vdev, !!(module_ens & ISP35_MODULE_AWB_GAIN), id); - if (module_en_update & ISP35_MODULE_DPCC) + if (module_en_update & ISP35_MODULE_DPCC && type != RKISP_PARAMS_LAT) isp_dpcc_enable(params_vdev, !!(module_ens & ISP35_MODULE_DPCC), id); - if (module_en_update & ISP35_MODULE_GAIN || - ((priv_val->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) && + if ((module_en_update & ISP35_MODULE_GAIN && type != RKISP_PARAMS_LAT) || + ((priv->buf_info_owner == RKISP_INFO2DRR_OWNER_GAIN) && !(isp3_param_read(params_vdev, ISP3X_GAIN_CTRL, id) & ISP3X_GAIN_2DDR_EN))) isp_gain_enable(params_vdev, !!(module_ens & ISP35_MODULE_GAIN), id); - if (module_en_update & ISP35_MODULE_BAY3D) + if (module_en_update & ISP35_MODULE_AI && type != RKISP_PARAMS_LAT) + isp_ai_enable(params_vdev, !!(module_ens & ISP35_MODULE_AI), id); + if (module_en_update & ISP35_MODULE_BAY3D && type != RKISP_PARAMS_LAT) isp_bay3d_enable(params_vdev, !!(module_ens & ISP35_MODULE_BAY3D), id); + if (type == RKISP_PARAMS_IMD && dev->is_aiisp_en && !dev->is_aiisp_sync) + return; + if (module_en_update & ISP35_MODULE_CAC) isp_cac_enable(params_vdev, !!(module_ens & ISP35_MODULE_CAC), id); if (module_en_update & ISP35_MODULE_LSC) @@ -4393,19 +4673,27 @@ void __isp_isr_meas_config(struct rkisp_isp_params_vdev *params_vdev, struct isp35_isp_params_cfg *new_params, enum rkisp_params_type type, u32 id) { + struct rkisp_device *dev = params_vdev->dev; u64 module_cfg_update = new_params->module_cfg_update; + v4l2_dbg(4, rkisp_debug, &dev->v4l2_dev, + "%s id:%d seq:%d type:%d module_cfg_update:0x%llx\n", + __func__, id, new_params->frame_id, type, module_cfg_update); + + if (!dev->is_aiisp_en || dev->is_aiisp_sync || type != RKISP_PARAMS_LAT) { + if (module_cfg_update & ISP35_MODULE_RAWAE0) + isp_rawae0_config(params_vdev, &new_params->meas.rawae0, id); + if (module_cfg_update & ISP35_MODULE_RAWHIST0) + isp_rawhist0_config(params_vdev, &new_params->meas.rawhist0, id); + if ((module_cfg_update & ISP35_MODULE_RAWAF)) + isp_rawaf_config(params_vdev, &new_params->meas.rawaf, id); + if (dev->is_aiisp_en && !dev->is_aiisp_sync && type == RKISP_PARAMS_IMD) { + params_vdev->cur_fe_frame_id = new_params->frame_id; + return; + } + } params_vdev->cur_frame_id = new_params->frame_id; - - v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, - "%s id:%d seq:%d module_cfg_update:0x%llx\n", - __func__, id, new_params->frame_id, module_cfg_update); - - if (module_cfg_update & ISP35_MODULE_RAWAE0) - isp_rawae0_config(params_vdev, &new_params->meas.rawae0, id); - - if (module_cfg_update & ISP35_MODULE_RAWHIST0) - isp_rawhist0_config(params_vdev, &new_params->meas.rawhist0, id); + params_vdev->exposure = new_params->exposure; if (module_cfg_update & ISP35_MODULE_RAWAE3) isp_rawae3_config(params_vdev, &new_params->meas.rawae3, id); @@ -4417,8 +4705,6 @@ void __isp_isr_meas_config(struct rkisp_isp_params_vdev *params_vdev, isp_awbsync_config(params_vdev, &new_params->meas.awbsync, id); if (module_cfg_update & ISP35_MODULE_RAWAWB) isp_rawawb_config(params_vdev, &new_params->meas.rawawb, id); - if ((module_cfg_update & ISP35_MODULE_RAWAF)) - isp_rawaf_config(params_vdev, &new_params->meas.rawaf, id); } static __maybe_unused @@ -4430,8 +4716,8 @@ void __isp_isr_meas_en(struct rkisp_isp_params_vdev *params_vdev, u64 module_ens = new_params->module_ens; v4l2_dbg(4, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, - "%s id:%d seq:%d module_en_update:0x%llx module_ens:0x%llx\n", - __func__, id, new_params->frame_id, module_en_update, module_ens); + "%s id:%d seq:%d type:%d module_en_update:0x%llx module_ens:0x%llx\n", + __func__, id, new_params->frame_id, type, module_en_update, module_ens); if (module_en_update & ISP35_MODULE_RAWAE0) isp_rawae0_enable(params_vdev, !!(module_ens & ISP35_MODULE_RAWAE0), id); @@ -4476,131 +4762,6 @@ void rkisp_params_cfgsram_v35(struct rkisp_isp_params_vdev *params_vdev, bool is ISP3X_RAWHIST_BIG1_BASE, true, id); } -static int -rkisp_alloc_internal_buf(struct rkisp_isp_params_vdev *params_vdev, - const struct isp35_isp_params_cfg *new_params) -{ - struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; - struct rkisp_device *dev = params_vdev->dev; - struct rkisp_isp_subdev *isp_sdev = &dev->isp_sdev; - u64 module_en_update, module_ens; - int ret; - - module_en_update = new_params->module_en_update; - module_ens = new_params->module_ens; - - if ((module_en_update & ISP35_MODULE_BAY3D) && (module_ens & ISP35_MODULE_BAY3D)) { - u8 iir_rw_fmt = new_params->others.bay3d_cfg.iir_rw_fmt; - u32 w = isp_sdev->in_crop.width; - u32 h = isp_sdev->in_crop.height; - u32 size, val, w16, w32, w128; - bool is_alloc; - - if (dev->unite_div > ISP_UNITE_DIV1) - w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; - if (dev->unite_div == ISP_UNITE_DIV4) - h = h / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; - w16 = ALIGN(w, 16); - w32 = ALIGN(w, 32); - w128 = ALIGN(w, 128); - priv_val->bay3d_iir_stride = 0; - switch (iir_rw_fmt) { - case 0: - val = w16 * 7 / 4; - size = val * h; - break; - case 1: - size = w16 * h * 2; - break; - case 2: - case 4: - val = ALIGN(w16 * 9 / 4, 16); - size = val * h; - priv_val->bay3d_iir_stride = val; - break; - case 3: - val = ALIGN((w32 + w128 / 8) * 2, 16); - size = val * h; - priv_val->bay3d_iir_stride = val; - break; - default: - dev_err(dev->dev, "bay3d iir_rw_fmt:%d error\n", iir_rw_fmt); - return -EINVAL; - } - - val = ALIGN(size, 16); - priv_val->bay3d_iir_size = val; - if (dev->unite_div > ISP_UNITE_DIV1) - val *= dev->unite_div; - is_alloc = true; - if (priv_val->buf_3dnr_iir.mem_priv) { - if (val > priv_val->buf_3dnr_iir.size) - rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); - else - is_alloc = false; - } - if (is_alloc) { - priv_val->buf_3dnr_iir.size = val; - ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_iir); - if (ret) { - dev_err(dev->dev, "alloc bay3d iir buf fail:%d\n", ret); - goto err_3dnr; - } - } - - val = (w16 * 36 / 8 + 31) / 32 * 4; - size = val * ((h + 7) / 8); - val = ALIGN(size, 16); - priv_val->bay3d_ds_size = val; - if (dev->unite_div > ISP_UNITE_DIV1) - val *= dev->unite_div; - is_alloc = true; - if (priv_val->buf_3dnr_ds.mem_priv) { - if (val > priv_val->buf_3dnr_ds.size) - rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); - else - is_alloc = false; - } - if (is_alloc) { - priv_val->buf_3dnr_ds.size = val; - ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_ds); - if (ret) { - rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); - dev_err(dev->dev, "alloc bay3d ds buf fail:%d\n", ret); - goto err_3dnr; - } - } - - val = (((w + 31) / 32 + 1) / 2 * 2 + 3) / 4 * 4; - size = val * ((h + 31) / 32); - val = ALIGN(size, 16); - priv_val->bay3d_wgt_size = val; - if (dev->unite_div > ISP_UNITE_DIV1) - val *= dev->unite_div; - is_alloc = true; - if (priv_val->buf_3dnr_wgt.mem_priv) { - if (val > priv_val->buf_3dnr_wgt.size) - rkisp_free_buffer(dev, &priv_val->buf_3dnr_wgt); - else - is_alloc = false; - } - if (is_alloc) { - priv_val->buf_3dnr_wgt.size = val; - ret = rkisp_alloc_buffer(dev, &priv_val->buf_3dnr_wgt); - if (ret) { - rkisp_free_buffer(dev, &priv_val->buf_3dnr_iir); - rkisp_free_buffer(dev, &priv_val->buf_3dnr_ds); - dev_err(dev->dev, "alloc bay3d wgt buf fail:%d\n", ret); - goto err_3dnr; - } - } - } - - return 0; -err_3dnr: - return ret; -} - static bool rkisp_params_check_bigmode_v35(struct rkisp_isp_params_vdev *params_vdev) { @@ -4663,7 +4824,6 @@ static void rkisp_save_first_param_v35(struct rkisp_isp_params_vdev *params_vdev if (params_vdev->dev->unite_div == ISP_UNITE_DIV2) memcpy(params_vdev->isp35_params + 1, param, size); } - rkisp_alloc_internal_buf(params_vdev, params_vdev->isp35_params); } static void rkisp_clear_first_param_v35(struct rkisp_isp_params_vdev *params_vdev) @@ -4964,10 +5124,371 @@ err: return -ENOMEM; } -static void -rkisp_params_get_bay3d_buffd_v35(struct rkisp_isp_params_vdev *params_vdev, - struct rkisp_bay3dbuf_info *bay3dbuf) +static int +rkisp_alloc_vpsl_buf(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bnr_buf_info *bnrbuf) { + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_dummy_buffer *buf; + u32 w = dev->isp_sdev.out_crop.width; + u32 h = dev->isp_sdev.out_crop.height; + u32 size, vpsl_size, stride, ds_w, ds_h, ds_ch; + int i, ret, cnt; + + /* yraw down sample */ + if (priv->yraw_sel) { + ds_ch = VPSL_YRAW_CHN_MAX / 2; + ds_w = ALIGN((w + 1) / 2, 2); + } else { + ds_ch = VPSL_YRAW_CHN_MAX; + ds_w = (w + 1) / 2; + } + ds_h = (h + 1) / 2; + vpsl_size = 0; + for (i = 0; i < ds_ch; i++) { + if (priv->yraw_sel) + stride = ALIGN(((ds_w * 11) + 7) / 8, 16); + else + stride = ALIGN(ds_w, 16); + priv->vpsl_yraw_stride[i] = stride; + priv->vpsl_yraw_offs[i] = vpsl_size; + bnrbuf->u.v35.vpsl_yraw_stride[i] = stride; + bnrbuf->u.v35.vpsl_yraw_offs[i] = vpsl_size; + size = stride * ds_h; + vpsl_size += size; + + ds_w = priv->yraw_sel ? ALIGN((ds_w + 1) / 2, 2) : (ds_w + 1) / 2; + ds_h = (ds_h + 1) / 2; + } + /* Sigma down sample */ + ds_ch = priv->yraw_sel ? VPSL_SIG_CHN_MAX - 1 : VPSL_SIG_CHN_MAX; + ds_w = (w + 1) / 2; + ds_h = (h + 1) / 2; + for (i = 0; i < ds_ch; i++) { + stride = ALIGN(ds_w, 16); + priv->vpsl_sig_stride[i] = stride; + priv->vpsl_sig_offs[i] = vpsl_size; + bnrbuf->u.v35.vpsl_sig_stride[i] = stride; + bnrbuf->u.v35.vpsl_sig_offs[i] = vpsl_size; + size = stride * ds_h; + vpsl_size += size; + + ds_w = (ds_w + 1) / 2; + ds_h = (ds_h + 1) / 2; + } + + cnt = bnrbuf->u.v35.vpsl.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_vpsl[i]; + buf->size = vpsl_size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc vpsl buf%d fail:%d\n", i, ret); + goto err_vpsl; + } + if (!i) + priv->pbuf_vpsl = buf; + else + list_add_tail(&buf->queue, &priv->vpsl_list); + buf->index = i; + bnrbuf->u.v35.vpsl.buf_fd[i] = buf->dma_fd; + } + priv->vpsl_cnt = cnt; + bnrbuf->u.v35.vpsl.buf_cnt = cnt; + bnrbuf->u.v35.vpsl.buf_size = vpsl_size; + return 0; +err_vpsl: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_vpsl[i]; + rkisp_free_buffer(dev, buf); + } + priv->vpsl_cnt = 0; + bnrbuf->u.v35.vpsl.buf_cnt = 0; + bnrbuf->u.v35.vpsl.buf_size = 0; + return ret; +} + +static int +rkisp_params_init_bnr_buf_v35(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_bnr_buf_info *bnrbuf) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_isp_subdev *isp_sdev = &dev->isp_sdev; + struct rkisp_dummy_buffer *buf; + u32 w = isp_sdev->out_crop.width; + u32 h = isp_sdev->out_crop.height; + u32 iir_rw_fmt, size, val, w16, w32, w128, iir_size = 0; + int ret, i, cnt; + + INIT_LIST_HEAD(&priv->iir_list); + INIT_LIST_HEAD(&priv->gain_list); + INIT_LIST_HEAD(&priv->vpsl_list); + INIT_LIST_HEAD(&priv->aipre_gain_list); + + iir_rw_fmt = bnrbuf->u.v35.iir_rw_fmt; + if (dev->unite_div > ISP_UNITE_DIV1) + w = w / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + if (dev->unite_div == ISP_UNITE_DIV4) + h = h / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; + w16 = ALIGN(w, 16); + w32 = ALIGN(w, 32); + w128 = ALIGN(w, 128); + priv->bay3d_iir_stride = 0; + priv->bay3d_iir_offs = 0; + switch (iir_rw_fmt) { + case 0: + val = w16 * 7 / 4; + size = val * h; + break; + case 1: + size = w16 * h * 2; + break; + case 2: + case 4: + val = ALIGN(w16 * 9 / 4, 16); + size = val * h; + priv->bay3d_iir_stride = val; + break; + case 3: + val = ALIGN((w32 + w128 / 8) * 2, 16); + size = val * h; + priv->bay3d_iir_stride = val; + priv->bay3d_iir_offs = w32 * 2; + break; + default: + dev_err(dev->dev, "bay3d iir_rw_fmt:%d error\n", iir_rw_fmt); + return -EINVAL; + } + size = ALIGN(size, 16); + priv->bay3d_iir_size = size; + if (dev->unite_div > ISP_UNITE_DIV1) + size *= dev->unite_div; + cnt = bnrbuf->iir.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + if (iir_rw_fmt == 3 && cnt < 2) + cnt = 2; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_bay3d_iir[i]; + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc bay3d iir buf%d fail:%d\n", i, ret); + goto err_iir; + } + if (!i) + priv->pbuf_bay3d_iir = buf; + else + list_add_tail(&buf->queue, &priv->iir_list); + buf->index = i; + bnrbuf->iir.buf_fd[i] = buf->dma_fd; + } + priv->bay3d_iir_cnt = cnt; + bnrbuf->iir.buf_cnt = cnt; + bnrbuf->iir.buf_size = size; + iir_size = size; + + val = (w16 * 36 / 8 + 31) / 32 * 4; + size = ALIGN(val * ((h + 7) / 8), 16); + priv->bay3d_ds_size = size; + if (dev->unite_div > ISP_UNITE_DIV1) + size *= dev->unite_div; + cnt = bnrbuf->u.v35.ds.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_bay3d_ds[i]; + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc bay3d ds buf:%d fail:%d\n", i, ret); + goto err_ds; + } + buf->index = i; + bnrbuf->u.v35.ds.buf_fd[i] = buf->dma_fd; + } + priv->bay3d_ds_cnt = cnt; + bnrbuf->u.v35.ds.buf_cnt = cnt; + bnrbuf->u.v35.ds.buf_size = size; + + val = (((w + 31) / 32 + 1) / 2 * 2 + 3) / 4 * 4; + size = ALIGN(val * ((h + 31) / 32), 16); + priv->bay3d_wgt_size = size; + if (dev->unite_div > ISP_UNITE_DIV1) + size *= dev->unite_div; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_bay3d_wgt[i]; + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc bay3d wgt buf:%d fail:%d\n", i, ret); + goto err_wgt; + } + buf->index = i; + bnrbuf->u.v35.wgt.buf_fd[i] = buf->dma_fd; + } + priv->bay3d_wgt_cnt = cnt; + bnrbuf->u.v35.wgt.buf_cnt = cnt; + bnrbuf->u.v35.wgt.buf_size = size; + + cnt = bnrbuf->u.v35.aiisp.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt && iir_size; i++) { + buf = &priv->buf_aiisp[i]; + buf->size = iir_size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc aiisp buf%d fail:%d\n", i, ret); + goto err_aiisp; + } + buf->index = i; + bnrbuf->u.v35.aiisp.buf_fd[i] = buf->dma_fd; + } + priv->aiisp_cnt = cnt; + bnrbuf->u.v35.aiisp.buf_cnt = cnt; + bnrbuf->u.v35.aiisp.buf_size = iir_size; + + size = ALIGN(w * h / 4, 16); + priv->gain_size = size; + if (dev->unite_div > ISP_UNITE_DIV1) + size *= dev->unite_div; + cnt = bnrbuf->u.v35.gain.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_gain[i]; + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc gain buf%d fail:%d\n", i, ret); + goto err_gain; + } + if (!i) + priv->pbuf_gain_wr = buf; + else + list_add_tail(&buf->queue, &priv->gain_list); + buf->index = i; + bnrbuf->u.v35.gain.buf_fd[i] = buf->dma_fd; + } + priv->gain_cnt = cnt; + bnrbuf->u.v35.gain.buf_cnt = cnt; + bnrbuf->u.v35.gain.buf_size = size; + + val = ALIGN(w / 4, 16); + priv->aipre_gain_stride = val; + size = ALIGN(val * (h / 2), 16); + if (dev->unite_div > ISP_UNITE_DIV1) + size *= dev->unite_div; + cnt = bnrbuf->u.v35.aipre_gain.buf_cnt; + if (cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; + for (i = 0; i < cnt; i++) { + buf = &priv->buf_aipre_gain[i]; + buf->size = size; + buf->is_need_dbuf = true; + buf->is_need_dmafd = true; + ret = rkisp_alloc_buffer(dev, buf); + if (ret) { + dev_err(dev->dev, "alloc aipre gain buf%d fail:%d\n", i, ret); + goto err_aipre_gain; + } + if (!i) + priv->pbuf_aipre_gain = buf; + else + list_add_tail(&buf->queue, &priv->aipre_gain_list); + buf->index = i; + bnrbuf->u.v35.aipre_gain.buf_fd[i] = buf->dma_fd; + } + priv->aipre_gain_cnt = cnt; + bnrbuf->u.v35.aipre_gain.buf_cnt = cnt; + bnrbuf->u.v35.aipre_gain.buf_size = size; + + priv->bay3d_iir_rw_fmt = iir_rw_fmt; + priv->yraw_sel = !!bnrbuf->u.v35.yraw_sel; + ret = rkisp_alloc_vpsl_buf(params_vdev, bnrbuf); + if (ret) + goto err_vpsl; + return 0; +err_vpsl: + i = priv->aipre_gain_cnt; +err_aipre_gain: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_aipre_gain[i]; + rkisp_free_buffer(dev, buf); + } + priv->aipre_gain_cnt = 0; + bnrbuf->u.v35.aipre_gain.buf_cnt = 0; + bnrbuf->u.v35.aipre_gain.buf_size = 0; + + i = priv->gain_cnt; +err_gain: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_gain[i]; + rkisp_free_buffer(dev, buf); + } + priv->gain_cnt = 0; + bnrbuf->u.v35.gain.buf_cnt = 0; + bnrbuf->u.v35.gain.buf_size = 0; + + i = priv->aiisp_cnt; +err_aiisp: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_aiisp[i]; + rkisp_free_buffer(dev, buf); + } + priv->aiisp_cnt = 0; + bnrbuf->u.v35.aiisp.buf_cnt = 0; + bnrbuf->u.v35.aiisp.buf_size = 0; + + i = priv->bay3d_wgt_cnt; +err_wgt: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_bay3d_wgt[i]; + rkisp_free_buffer(dev, buf); + } + priv->bay3d_wgt_cnt = 0; + bnrbuf->u.v35.wgt.buf_cnt = 0; + bnrbuf->u.v35.wgt.buf_size = 0; + + i = priv->bay3d_ds_cnt; +err_ds: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_bay3d_ds[i]; + rkisp_free_buffer(dev, buf); + } + priv->bay3d_ds_cnt = 0; + bnrbuf->u.v35.ds.buf_cnt = 0; + bnrbuf->u.v35.ds.buf_size = 0; + + i = priv->bay3d_iir_cnt; +err_iir: + for (i -= 1; i >= 0; i--) { + buf = &priv->buf_bay3d_iir[i]; + rkisp_free_buffer(dev, buf); + } + priv->bay3d_iir_cnt = 0; + bnrbuf->iir.buf_cnt = 0; + bnrbuf->iir.buf_size = 0; + return ret; } static int @@ -4981,8 +5502,8 @@ rkisp_params_get_aiawb_buffd_v35(struct rkisp_isp_params_vdev *params_vdev, void u32 width = out_crop->width, height = out_crop->height; int i, size, ret, cnt = cfg->info.buf_cnt; - if (cnt <= 0 || cnt > RKISP_BUFFER_MAX) - cnt = RKISP_BUFFER_MAX; + if (cnt <= 0 || cnt >= RKISP_BUFFER_MAX) + cnt = RKISP_BUFFER_MAX - 1; switch (cfg->ds) { case RKISP_AIAWB_DS_4X4: size = (width / 4) * (height / 4) * 8; @@ -5035,25 +5556,42 @@ err: static void rkisp_params_stream_stop_v35(struct rkisp_isp_params_vdev *params_vdev) { - struct rkisp_isp_params_val_v35 *priv_val = params_vdev->priv_val; - struct rkisp_device *ispdev = params_vdev->dev; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; int i; - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_iir); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_wgt); - rkisp_free_buffer(ispdev, &priv_val->buf_3dnr_ds); - rkisp_free_buffer(ispdev, &priv_val->buf_gain); + for (i = 0; i < priv->vpsl_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_vpsl[i]); + priv->vpsl_cnt = 0; + for (i = 0; i < priv->aipre_gain_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_aipre_gain[i]); + priv->aipre_gain_cnt = 0; + for (i = 0; i < priv->gain_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_gain[i]); + priv->gain_cnt = 0; + for (i = 0; i < priv->aiisp_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_aiisp[i]); + priv->aiisp_cnt = 0; + for (i = 0; i < priv->bay3d_wgt_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_bay3d_wgt[i]); + priv->bay3d_wgt_cnt = 0; + for (i = 0; i < priv->bay3d_ds_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_bay3d_ds[i]); + priv->bay3d_ds_cnt = 0; + for (i = 0; i < priv->bay3d_iir_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_bay3d_iir[i]); + priv->bay3d_iir_cnt = 0; for (i = 0; i < RKISP_STATS_DDR_BUF_NUM; i++) - rkisp_free_buffer(ispdev, &ispdev->stats_vdev.stats_buf[i]); - for (i = 0; i < priv_val->buf_aiawb_cnt; i++) - rkisp_free_buffer(ispdev, &priv_val->buf_aiawb[i]); - priv_val->buf_aiawb_cnt = 0; - priv_val->buf_aiawb_idx = 0; - priv_val->buf_info_owner = 0; - priv_val->buf_info_cnt = 0; - priv_val->buf_info_idx = -1; + rkisp_free_buffer(dev, &dev->stats_vdev.stats_buf[i]); + for (i = 0; i < priv->buf_aiawb_cnt; i++) + rkisp_free_buffer(dev, &priv->buf_aiawb[i]); for (i = 0; i < RKISP_INFO2DDR_BUF_MAX; i++) - rkisp_free_buffer(ispdev, &priv_val->buf_info[i]); + rkisp_free_buffer(dev, &priv->buf_info[i]); + priv->buf_aiawb_cnt = 0; + priv->buf_aiawb_idx = -1; + priv->buf_info_owner = 0; + priv->buf_info_cnt = 0; + priv->buf_info_idx = -1; } static void @@ -5113,6 +5651,71 @@ module_data_abandon(struct rkisp_isp_params_vdev *params_vdev, } } +static void +rkisp_params_cfg_latter_v35(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id) +{ + struct rkisp_device *dev = params_vdev->dev; + struct isp35_isp_params_cfg *new_params = NULL; + struct rkisp_buffer *cur_buf = NULL; + unsigned long flags = 0; + int i; + + spin_lock_irqsave(¶ms_vdev->config_lock, flags); + if (!params_vdev->streamon) + goto unlock; + + /* get buffer by frame_id */ + while (!list_empty(¶ms_vdev->params_be)) { + cur_buf = list_first_entry(¶ms_vdev->params_be, struct rkisp_buffer, queue); + new_params = cur_buf->vaddr[0]; + if (new_params->frame_id < frame_id) { + list_del(&cur_buf->queue); + for (i = 0; i < dev->unite_div; i++) { + /* update en immediately */ + if (new_params->module_en_update || + (new_params->module_cfg_update & ISP35_MODULE_FORCE)) { + __isp_isr_meas_config(params_vdev, + new_params, RKISP_PARAMS_LAT, i); + __isp_isr_other_config(params_vdev, + new_params, RKISP_PARAMS_LAT, i); + __isp_isr_other_en(params_vdev, + new_params, RKISP_PARAMS_LAT, i); + __isp_isr_meas_en(params_vdev, + new_params, RKISP_PARAMS_LAT, i); + new_params->module_cfg_update = 0; + } + if (new_params->module_cfg_update & (ISP35_MODULE_LDCH | ISP35_MODULE_BAY3D)) + module_data_abandon(params_vdev, new_params, i); + new_params++; + } + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + cur_buf = NULL; + continue; + } else if (new_params->frame_id == frame_id) { + list_del(&cur_buf->queue); + } else { + cur_buf = NULL; + } + break; + } + + if (!cur_buf) + goto unlock; + + new_params = cur_buf->vaddr[0]; + for (i = 0; i < dev->unite_div; i++) { + __isp_isr_meas_config(params_vdev, new_params, RKISP_PARAMS_LAT, i); + __isp_isr_other_config(params_vdev, new_params, RKISP_PARAMS_LAT, i); + __isp_isr_other_en(params_vdev, new_params, RKISP_PARAMS_LAT, i); + __isp_isr_meas_en(params_vdev, new_params, RKISP_PARAMS_LAT, i); + new_params->module_cfg_update = 0; + new_params++; + } + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); +unlock: + spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); +} + static void rkisp_params_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, u32 frame_id, enum rkisp_params_type type) @@ -5123,6 +5726,11 @@ rkisp_params_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, unsigned long flags = 0; int i; + if (type == RKISP_PARAMS_LAT) { + rkisp_params_cfg_latter_v35(params_vdev, frame_id); + return; + } + spin_lock_irqsave(¶ms_vdev->config_lock, flags); if (!params_vdev->streamon) goto unlock; @@ -5133,27 +5741,29 @@ rkisp_params_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, new_params = (struct isp35_isp_params_cfg *)(cur_buf->vaddr[0]); if (new_params->frame_id < frame_id) { list_del(&cur_buf->queue); - if (list_empty(¶ms_vdev->params)) - break; for (i = 0; i < dev->unite_div; i++) { /* update en immediately */ if (new_params->module_en_update || (new_params->module_cfg_update & ISP35_MODULE_FORCE)) { - __isp_isr_meas_config(params_vdev, - new_params, RKISP_PARAMS_ALL, i); - __isp_isr_other_config(params_vdev, - new_params, RKISP_PARAMS_ALL, i); - __isp_isr_other_en(params_vdev, - new_params, RKISP_PARAMS_ALL, i); - __isp_isr_meas_en(params_vdev, - new_params, RKISP_PARAMS_ALL, i); - new_params->module_cfg_update = 0; + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + type = RKISP_PARAMS_ALL; + __isp_isr_meas_config(params_vdev, new_params, type, i); + __isp_isr_other_config(params_vdev, new_params, type, i); + __isp_isr_other_en(params_vdev, new_params, type, i); + __isp_isr_meas_en(params_vdev, new_params, type, i); + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + new_params->module_cfg_update = 0; } - if (new_params->module_cfg_update & ISP35_MODULE_LDCH) + if ((!dev->is_aiisp_en || dev->is_aiisp_sync) && + (new_params->module_cfg_update & + (ISP35_MODULE_LDCH | ISP35_MODULE_BAY3D))) module_data_abandon(params_vdev, new_params, i); new_params++; } - vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + else + list_add_tail(&cur_buf->queue, ¶ms_vdev->params_be); cur_buf = NULL; continue; } else if (new_params->frame_id == frame_id) { @@ -5174,17 +5784,24 @@ rkisp_params_cfg_v35(struct rkisp_isp_params_vdev *params_vdev, __isp_isr_other_config(params_vdev, new_params, type, i); __isp_isr_other_en(params_vdev, new_params, type, i); __isp_isr_meas_en(params_vdev, new_params, type, i); - if (IS_HDR_RDBK(dev->rd_mode)) { + if (new_params->module_cfg_update & ISP35_MODULE_HDRMGE) { params_rec->others.hdrmge_cfg = new_params->others.hdrmge_cfg; - params_rec->others.drc_cfg = new_params->others.drc_cfg; - params_rec->module_cfg_update = new_params->module_cfg_update; - params_rec++; + params_rec->module_cfg_update |= ISP35_MODULE_HDRMGE; } - new_params->module_cfg_update = 0; + if (new_params->module_cfg_update & ISP35_MODULE_DRC && + (!dev->is_aiisp_en || dev->is_aiisp_sync)) { + params_rec->others.drc_cfg = new_params->others.drc_cfg; + params_rec->module_cfg_update |= ISP35_MODULE_DRC; + } + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + new_params->module_cfg_update = 0; new_params++; + params_rec++; } - vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); - + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + else + list_add_tail(&cur_buf->queue, ¶ms_vdev->params_be); unlock: spin_unlock_irqrestore(¶ms_vdev->config_lock, flags); } @@ -5205,38 +5822,424 @@ rkisp_params_clear_fstflg(struct rkisp_isp_params_vdev *params_vdev) isp3_param_clear_bits(params_vdev, ISP3X_ISP_CTRL1, value, i); } +static void +rkisp_params_aiisp_update_buf(struct rkisp_isp_params_vdev *params_vdev) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + unsigned long lock_flags = 0; + u32 val; + + if (params_vdev->dev->is_aiisp_sync) + return; + + spin_lock_irqsave(&priv->buf_lock, lock_flags); + val = isp3_param_read_direct(params_vdev, ISP3X_MI_BAY3D_IIR_WR_BASE_SHD); + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_RD_BASE, 0); + priv->pbuf_bay3d_iir = NULL; + if (!list_empty(&priv->iir_list)) { + priv->pbuf_bay3d_iir = list_first_entry(&priv->iir_list, + struct rkisp_dummy_buffer, queue); + list_del(&priv->pbuf_bay3d_iir->queue); + + val = priv->pbuf_bay3d_iir->dma_addr; + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_WR_BASE, 0); + priv->bay3d_iir_cur_idx = priv->pbuf_bay3d_iir->index; + } + + priv->pbuf_gain_wr = NULL; + if (!list_empty(&priv->gain_list)) { + priv->pbuf_gain_wr = list_first_entry(&priv->gain_list, + struct rkisp_dummy_buffer, queue); + list_del(&priv->pbuf_gain_wr->queue); + + val = priv->pbuf_gain_wr->dma_addr; + isp3_param_write(params_vdev, val, ISP3X_MI_GAIN_WR_BASE, 0); + priv->gain_cur_idx = priv->pbuf_gain_wr->index; + } + val = ISP3X_BAY3D_IIRSELF_UPD | ISP3X_BAY3D_RDSELF_UPD | ISP3X_GAINSELF_UPD; + isp3_param_set_bits(params_vdev, MI_WR_CTRL2, val, 0); + + priv->pbuf_aipre_gain = NULL; + if (!list_empty(&priv->aipre_gain_list)) { + priv->pbuf_aipre_gain = list_first_entry(&priv->aipre_gain_list, + struct rkisp_dummy_buffer, queue); + list_del(&priv->pbuf_aipre_gain->queue); + + val = priv->pbuf_aipre_gain->dma_addr; + isp3_param_write(params_vdev, val, ISP35_AI_PRE_GAIN_WR_BASE, 0); + + val = isp3_param_read(params_vdev, ISP35_AI_CTRL, 0); + val &= ~ISP35_AIISP_ST; + val |= ISP35_AIPRE_ITS_FORCE_UPD; + isp3_param_write(params_vdev, val, ISP35_AI_CTRL, 0); + val &= ~ISP35_AIPRE_ITS_FORCE_UPD; + isp3_param_write(params_vdev, val, ISP35_AI_CTRL, 0); + } + + v4l2_dbg(3, rkisp_debug, ¶ms_vdev->dev->v4l2_dev, + "aiisp_update %x:%x %x:%x %x:%x %x:%x, iir:%x gain:%x aipre:%x\n", + ISP3X_MI_BAY3D_IIR_WR_BASE_SHD, + isp3_param_read_direct(params_vdev, ISP3X_MI_BAY3D_IIR_WR_BASE_SHD), + ISP3X_MI_BAY3D_IIR_RD_BASE_SHD, + isp3_param_read_direct(params_vdev, ISP3X_MI_BAY3D_IIR_RD_BASE_SHD), + ISP3X_MI_GAIN_WR_BASE_SHD, + isp3_param_read_direct(params_vdev, ISP3X_MI_GAIN_WR_BASE_SHD), + ISP35_AI_PRE_GAIN_WR_BASE, + isp3_param_read_direct(params_vdev, ISP35_AI_PRE_GAIN_WR_BASE), + priv->pbuf_bay3d_iir ? (u32)priv->pbuf_bay3d_iir->dma_addr : 0, + priv->pbuf_gain_wr ? (u32)priv->pbuf_gain_wr->dma_addr : 0, + priv->pbuf_aipre_gain ? (u32)priv->pbuf_aipre_gain->dma_addr : 0); + if (!priv->pbuf_gain_wr || !priv->pbuf_aipre_gain || !priv->pbuf_bay3d_iir) { + if (priv->pbuf_bay3d_iir) { + list_add_tail(&priv->pbuf_bay3d_iir->queue, &priv->iir_list); + priv->pbuf_bay3d_iir = NULL; + } + if (priv->pbuf_gain_wr) { + list_add_tail(&priv->pbuf_gain_wr->queue, &priv->gain_list); + priv->pbuf_gain_wr = NULL; + } + if (priv->pbuf_aipre_gain) { + list_add_tail(&priv->pbuf_aipre_gain->queue, &priv->aipre_gain_list); + priv->pbuf_aipre_gain = NULL; + } + } + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); +} + +static void +rkisp_params_aiisp_event_v35(struct rkisp_isp_params_vdev *params_vdev, u32 irq) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_dummy_buffer *buf = NULL; + struct v4l2_event ev = { 0 }; + struct rkisp_aiisp_ev_info *ev_info; + unsigned long lock_flags = 0; + u32 h = dev->isp_sdev.out_crop.height; + u32 val, wr_line, rd_line; + + if (sizeof(*ev_info) > sizeof(ev.u)) { + v4l2_err(&dev->v4l2_dev, "aiisp_ev_info too large\n"); + return; + } + ev.type = RKISP_V4L2_EVENT_AIISP_LINECNT; + ev_info = (struct rkisp_aiisp_ev_info *)ev.u.data; + ev_info->iir_index = -1; + ev_info->gain_index = -1; + ev_info->aiisp_index = -1; + ev_info->vpsl_index = -1; + ev_info->aipre_gain_index = -1; + val = rkisp_read(dev, ISP39_AIISP_LINE_CNT, false); + if (irq & ISP3X_OUT_FRM_QUARTER) { + rd_line = ISP39_AIISP_RD_LINECNT(val); + ev.id = RKISP_AIISP_RD_LINECNT_ID; + ev_info->height = !rd_line ? h : rd_line; + rkisp_dmarx_get_frame(dev, &ev_info->sequence, NULL, &ev_info->timestamp, false); + spin_lock_irqsave(&priv->buf_lock, lock_flags); + if (priv->pbuf_aiisp) { + ev_info->aiisp_index = priv->pbuf_aiisp->index; + priv->pbuf_aiisp = NULL; + } + if (priv->pbuf_gain_rd && !dev->is_aiisp_sync) { + list_add_tail(&priv->pbuf_gain_rd->queue, &priv->gain_list); + priv->pbuf_gain_rd = NULL; + } + if (!priv->yraw_sel) { + buf = priv->pbuf_vpsl; + if (buf) + ev_info->vpsl_index = buf->index; + buf = priv->pbuf_aipre_gain; + if (buf) + ev_info->aipre_gain_index = buf->index; + } + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + v4l2_event_queue(dev->isp_sdev.sd.devnode, &ev); + } else { + wr_line = ISP39_AIISP_WR_LINECNT(val); + ev.id = RKISP_AIISP_WR_LINECNT_ID; + ev_info->height = !wr_line ? h : wr_line; + rkisp_dmarx_get_frame(dev, &ev_info->sequence, NULL, &ev_info->timestamp, true); + + spin_lock_irqsave(&priv->buf_lock, lock_flags); + if (!priv->pbuf_bay3d_iir || !priv->pbuf_vpsl || + !priv->pbuf_gain_wr || !priv->pbuf_aipre_gain) { + if (priv->pbuf_bay3d_iir) { + list_add_tail(&priv->pbuf_bay3d_iir->queue, &priv->iir_list); + priv->pbuf_bay3d_iir = NULL; + } + if (priv->pbuf_gain_wr) { + list_add_tail(&priv->pbuf_gain_wr->queue, &priv->gain_list); + priv->pbuf_gain_wr = NULL; + } + if (priv->pbuf_aipre_gain && priv->yraw_sel) { + list_add_tail(&priv->pbuf_aipre_gain->queue, &priv->aipre_gain_list); + priv->pbuf_aipre_gain = NULL; + } + if (priv->pbuf_vpsl && priv->yraw_sel) { + list_add_tail(&priv->pbuf_vpsl->queue, &priv->vpsl_list); + priv->pbuf_vpsl = NULL; + } + } + + if (priv->yraw_sel) { + buf = priv->pbuf_vpsl; + if (buf) + ev_info->vpsl_index = buf->index; + buf = priv->pbuf_aipre_gain; + if (buf) + ev_info->aipre_gain_index = buf->index; + } + + buf = priv->pbuf_bay3d_iir; + if (buf) + ev_info->iir_index = buf->index; + buf = priv->pbuf_gain_wr; + if (buf) + ev_info->gain_index = buf->index; + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + if (buf) + v4l2_event_queue(dev->isp_sdev.sd.devnode, &ev); + } + v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, + "%s seq:%d height:%d idx(iir:%d gain:%d vpsl:%d aipre:%d aiisp:%d)\n", + ev.id ? "isp_be" : "isp_fe", ev_info->sequence, ev_info->height, + ev_info->iir_index, ev_info->gain_index, + ev_info->vpsl_index, ev_info->aipre_gain_index, ev_info->aiisp_index); +} + +static int +rkisp_params_aiisp_start_v35(struct rkisp_isp_params_vdev *params_vdev, + struct rkisp_aiisp_st *st) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = params_vdev->dev; + struct rkisp_dummy_buffer *buf, *buf_tmp; + unsigned long lock_flags = 0; + u32 val, seq = st->sequence; + + if (!dev->is_aiisp_en) + return -EINVAL; + if (st->gain_index < 0 || st->gain_index >= priv->gain_cnt || + st->aiisp_index < 0 || st->aiisp_index >= priv->aiisp_cnt || + st->iir_index < 0 || st->iir_index >= priv->bay3d_iir_cnt || + st->vpsl_index >= priv->vpsl_cnt || + st->aipre_gain_index >= priv->aipre_gain_cnt) { + dev_err(dev->dev, "%s seq:%d error, aiisp(%d cnt:%d)\n" + "iir(%d cnt:%d) gain(%d cnt:%d) aipre(%d cnt:%d) vpsl(%d cnt:%d)\n", + __func__, seq, st->aiisp_index, priv->aiisp_cnt, + st->iir_index, priv->bay3d_iir_cnt, st->gain_index, priv->gain_cnt, + st->aipre_gain_index, priv->aipre_gain_cnt, st->vpsl_index, priv->vpsl_cnt); + return -EINVAL; + } + + if (!dev->is_aiisp_sync) + rkisp_params_cfg(params_vdev, seq, RKISP_PARAMS_LAT); + + spin_lock_irqsave(&priv->buf_lock, lock_flags); + if (!dev->is_aiisp_sync) { + buf = &priv->buf_bay3d_iir[st->iir_index]; + list_for_each_entry(buf_tmp, &priv->iir_list, queue) { + if (buf_tmp == buf) { + dev_err(dev->dev, "iir idx:%d error\n", st->iir_index); + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + return 0; + } + } + list_add_tail(&buf->queue, &priv->iir_list); + + if (st->aipre_gain_index >= 0) { + buf = &priv->buf_aipre_gain[st->aipre_gain_index]; + list_for_each_entry(buf_tmp, &priv->aipre_gain_list, queue) { + if (buf_tmp == buf) { + dev_err(dev->dev, "aipre idx:%d error\n", st->aipre_gain_index); + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + return 0; + } + } + list_add_tail(&buf->queue, &priv->aipre_gain_list); + } + + if (st->vpsl_index >= 0) { + buf = &priv->buf_vpsl[st->vpsl_index]; + list_for_each_entry(buf_tmp, &priv->vpsl_list, queue) { + if (buf_tmp == buf) { + dev_err(dev->dev, "vpsl idx:%d error\n", st->vpsl_index); + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + return 0; + } + } + list_add_tail(&buf->queue, &priv->vpsl_list); + } + } + priv->pbuf_gain_rd = &priv->buf_gain[st->gain_index]; + priv->pbuf_aiisp = &priv->buf_aiisp[st->aiisp_index]; + priv->aiisp_cur_idx = st->aiisp_index; + + val = priv->pbuf_aiisp->dma_addr; + rkisp_write(dev, ISP39_AIISP_RD_BASE, val, true); + val = priv->pbuf_gain_rd->dma_addr; + if (!params_vdev->is_hdr) { + rkisp_write(dev, ISP3X_MI_RAW0_RD_BASE, val, true); + rkisp_set_bits(dev, ISP3X_CSI2RX_RAW_RD_CTRL, 0, ISP35_RX0_FORCE_UPD, true); + + val = ISP3X_DBR_RDSELF_UPD; + } else { + rkisp_write(dev, ISP35_B3DLDCH_RD_BASE, val, true); + + val = ISP3X_DBR_RDSELF_UPD | ISP3X_BAY3D_RDSELF_UPD; + } + rkisp_set_bits(dev, ISP3X_MI_WR_CTRL2, 0, val, true); + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); + + val = params_vdev->is_hdr ? ISP35_B3DLDCH_RD_BASE_SHD : ISP3X_MI_RAW0_RD_BASE_SHD; + v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, + "isp_be start seq:%d idx(%d %d) %x %x, %x:%x %x:%x\n", + seq, st->aiisp_index, st->gain_index, + (u32)priv->pbuf_aiisp->dma_addr, + (u32)priv->pbuf_gain_rd->dma_addr, + ISP3X_MI_DBR_RD_BASE_SHD, rkisp_read(dev, ISP3X_MI_DBR_RD_BASE_SHD, true), + val, rkisp_read(dev, val, true)); + return 0; +} + +static void +rkisp_vpsl_update_regs_v35(struct rkisp_isp_params_vdev *params_vdev) +{ + struct isp35_isp_params_cfg *params = params_vdev->isp35_params; + struct rkisp_device *isp, *dev = params_vdev->dev; + struct rkisp_hw_dev *hw = dev->hw_dev; + void __iomem *base = hw->vpsl_base_addr; + u32 i, *val, *flag; + + for (i = 0; i < hw->dev_link_num; i++) { + isp = hw->isp[i]; + if (isp && isp->is_aiisp_en) + break; + } + if (i == hw->dev_link_num) + return; + + for (i = VPSL_CTRL; i < VPSL_SW_REG_SIZE; i += 4) { + val = dev->sw_vpsl_base_addr + i; + flag = dev->sw_vpsl_base_addr + i + VPSL_SW_REG_SIZE; + + if (*flag == SW_REG_CACHE) + writel(*val, base + i); + } + vpsl_cfg_sram(params_vdev, ¶ms->others.ai_cfg); + writel(VPSL_CFG_GEN_UPD | VPSL_CFG_FORCE_UPD, base + VPSL_UPDATE); + writel(VPSL_MI_FORCE_UPD, base + VPSL_MI_WR_INIT); +} + static void rkisp_params_isr_v35(struct rkisp_isp_params_vdev *params_vdev, u32 isp_mis) { + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct isp35_isp_params_cfg *params_rec = params_vdev->isp35_params; struct rkisp_device *dev = params_vdev->dev; - u32 cur_frame_id, i; + u32 i, val, reg; - rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); if (isp_mis & CIF_ISP_V_START) { if (params_vdev->rdbk_times) params_vdev->rdbk_times--; - if (IS_HDR_RDBK(dev->rd_mode) && !params_vdev->rdbk_times) { - struct isp35_isp_params_cfg *params = params_vdev->isp35_params; + if (!params_vdev->rdbk_times) { + if (!dev->is_aiisp_en && priv->bay3d_iir_cnt > 1) { + priv->bay3d_iir_cur_idx = priv->bay3d_iir_idx; + i = (priv->bay3d_iir_idx + 1) % priv->bay3d_iir_cnt; + priv->bay3d_iir_idx = i; + for (i = 0; i < dev->unite_div; i++) { + if (priv->bay3d_iir_rw_fmt == 3) + reg = ISP35_B3DLDC_WR_ADDR; + else + reg = ISP3X_MI_BAY3D_IIR_WR_BASE; + val = isp3_param_read_cache(params_vdev, reg, i); + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_RD_BASE, i); - for (i = 0; i < dev->unite_div; i++) { - if (params->module_cfg_update & ISP35_MODULE_HDRMGE) - isp_hdrmge_config(params_vdev, ¶ms->others.hdrmge_cfg, RKISP_PARAMS_SHD, i); - if (params->module_cfg_update & ISP35_MODULE_DRC) - isp_hdrdrc_config(params_vdev, ¶ms->others.drc_cfg, RKISP_PARAMS_SHD, i); - params->module_cfg_update = 0; - params++; + val = priv->buf_bay3d_iir[priv->bay3d_iir_idx].dma_addr; + val += i * priv->bay3d_iir_size; + if (priv->bay3d_iir_rw_fmt == 3) { + isp3_param_write(params_vdev, val, ISP35_B3DLDC_WR_ADDR, i); + val += priv->bay3d_iir_offs; + } + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_IIR_WR_BASE, i); + } + } + if (priv->bay3d_ds_cnt > 1) { + priv->bay3d_ds_cur_idx = priv->bay3d_ds_idx; + i = (priv->bay3d_ds_idx + 1) % priv->bay3d_ds_cnt; + priv->bay3d_ds_idx = i; + for (i = 0; i < dev->unite_div; i++) { + val = isp3_param_read_cache(params_vdev, ISP3X_MI_BAY3D_DS_WR_BASE, i); + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_DS_RD_BASE, i); + + val = priv->buf_bay3d_ds[priv->bay3d_ds_idx].dma_addr; + val += i * priv->bay3d_ds_size; + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_DS_WR_BASE, i); + } + } + if (priv->bay3d_wgt_cnt > 1) { + priv->bay3d_wgt_cur_idx = priv->bay3d_wgt_idx; + i = (priv->bay3d_wgt_idx + 1) % priv->bay3d_wgt_cnt; + priv->bay3d_wgt_idx = i; + for (i = 0; i < dev->unite_div; i++) { + val = isp3_param_read_cache(params_vdev, ISP3X_MI_BAY3D_CUR_WR_BASE, i); + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_CUR_RD_BASE, i); + + val = priv->buf_bay3d_wgt[priv->bay3d_wgt_idx].dma_addr; + val += i * priv->bay3d_wgt_size; + isp3_param_write(params_vdev, val, ISP3X_MI_BAY3D_CUR_WR_BASE, i); + } + } + for (i = 0; i < dev->unite_div && !dev->is_aiisp_en; i++) { + if (params_rec->module_cfg_update & ISP35_MODULE_HDRMGE && + (dev->is_aiisp_en || IS_HDR_RDBK(dev->rd_mode))) { + isp_hdrmge_config(params_vdev, ¶ms_rec->others.hdrmge_cfg, RKISP_PARAMS_SHD, i); + params_rec->module_cfg_update &= ~ISP35_MODULE_HDRMGE; + } + if (params_rec->module_cfg_update & ISP35_MODULE_DRC && + ((!dev->is_aiisp_en && IS_HDR_RDBK(dev->rd_mode)) || dev->is_aiisp_sync)) { + isp_hdrdrc_config(params_vdev, ¶ms_rec->others.drc_cfg, RKISP_PARAMS_SHD, i); + params_rec->module_cfg_update &= ~ISP35_MODULE_DRC; + } + params_rec++; } - return; } } if ((isp_mis & CIF_ISP_FRAME) && !params_vdev->rdbk_times) rkisp_params_clear_fstflg(params_vdev); - if ((isp_mis & CIF_ISP_FRAME) && - !IS_HDR_RDBK(dev->rd_mode) && !params_vdev->rdbk_times) - rkisp_params_cfg_v35(params_vdev, cur_frame_id + 1, RKISP_PARAMS_ALL); + rkisp_dmarx_get_frame(dev, &i, NULL, NULL, true); + if (isp_mis & ISP3X_BAY3D_FRM_END && dev->is_aiisp_en) { + rkisp_params_aiisp_update_buf(params_vdev); + if (!IS_HDR_RDBK(dev->rd_mode)) + rkisp_params_cfg_v35(params_vdev, i + 1, RKISP_PARAMS_IMD); + } else if (isp_mis & CIF_ISP_FRAME && !IS_HDR_RDBK(dev->rd_mode) && + !params_vdev->rdbk_times && !dev->is_aiisp_en) { + rkisp_params_cfg_v35(params_vdev, i + 1, RKISP_PARAMS_ALL); + } + +} + +void rkisp_params_vpsl_mi_isr_v35(struct rkisp_isp_params_vdev *params_vdev, u32 mis_val) +{ + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + unsigned long lock_flags = 0; + + if (params_vdev->dev->is_aiisp_sync) + return; + spin_lock_irqsave(&priv->buf_lock, lock_flags); + if (mis_val & VPSL_MI_YRAW_ALL_END) { + priv->pbuf_vpsl = NULL; + if (!list_empty(&priv->vpsl_list)) { + priv->pbuf_vpsl = list_first_entry(&priv->vpsl_list, + struct rkisp_dummy_buffer, queue); + list_del(&priv->pbuf_vpsl->queue); + vpsl_update_buf(params_vdev); + } + } + spin_unlock_irqrestore(&priv->buf_lock, lock_flags); } static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { @@ -5255,8 +6258,11 @@ static struct rkisp_isp_params_ops rkisp_isp_params_ops_tbl = { .fop_release = rkisp_params_fop_release_v35, .check_bigmode = rkisp_params_check_bigmode_v35, .info2ddr_cfg = rkisp_params_info2ddr_cfg_v35, - .get_bay3d_buffd = rkisp_params_get_bay3d_buffd_v35, .get_aiawb_buffd = rkisp_params_get_aiawb_buffd_v35, + .init_bnr_buf = rkisp_params_init_bnr_buf_v35, + .aiisp_event = rkisp_params_aiisp_event_v35, + .aiisp_start = rkisp_params_aiisp_start_v35, + .vpsl_update_regs = rkisp_vpsl_update_regs_v35, }; int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) @@ -5277,6 +6283,7 @@ int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) return -ENOMEM; } + spin_lock_init(&priv->buf_lock); params_vdev->priv_val = priv; params_vdev->ops = &rkisp_isp_params_ops_tbl; rkisp_clear_first_param_v35(params_vdev); diff --git a/drivers/media/platform/rockchip/isp/isp_params_v35.h b/drivers/media/platform/rockchip/isp/isp_params_v35.h index 3ee884225c94..1863b6f67f9e 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v35.h +++ b/drivers/media/platform/rockchip/isp/isp_params_v35.h @@ -29,27 +29,80 @@ struct rkisp_isp_params_val_v35 { u32 buf_aiawb_cnt; int buf_aiawb_idx; - struct rkisp_dummy_buffer buf_3dnr_wgt; - struct rkisp_dummy_buffer buf_3dnr_iir; - struct rkisp_dummy_buffer buf_3dnr_ds; - struct rkisp_dummy_buffer buf_gain; + struct rkisp_dummy_buffer buf_bay3d_wgt[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_bay3d_iir[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_bay3d_ds[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_gain[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_aipre_gain[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_aiisp[RKISP_BUFFER_MAX]; + struct rkisp_dummy_buffer buf_vpsl[RKISP_BUFFER_MAX]; + + spinlock_t buf_lock; + struct list_head iir_list; + struct list_head gain_list; + struct list_head aipre_gain_list; + struct list_head vpsl_list; + struct rkisp_dummy_buffer *pbuf_bay3d_iir; + struct rkisp_dummy_buffer *pbuf_gain_wr; + struct rkisp_dummy_buffer *pbuf_gain_rd; + struct rkisp_dummy_buffer *pbuf_aipre_gain; + struct rkisp_dummy_buffer *pbuf_vpsl; + struct rkisp_dummy_buffer *pbuf_aiisp; + + u32 bay3d_iir_rw_fmt; + u32 bay3d_iir_offs; u32 bay3d_iir_stride; - u32 bay3d_ds_size; u32 bay3d_iir_size; + int bay3d_iir_cnt; + int bay3d_iir_idx; + int bay3d_iir_cur_idx; + + u32 bay3d_ds_size; + int bay3d_ds_cnt; + int bay3d_ds_idx; + int bay3d_ds_cur_idx; + u32 bay3d_wgt_size; + int bay3d_wgt_cnt; + int bay3d_wgt_idx; + int bay3d_wgt_cur_idx; + + int aiisp_cnt; + int aiisp_cur_idx; + u32 gain_size; + int gain_cnt; + int gain_cur_idx; + + u32 aipre_gain_stride; + int aipre_gain_cnt; + int aipre_gain_cur_idx; + + int vpsl_cnt; + int vpsl_cur_idx; + + u32 vpsl_yraw_offs[VPSL_YRAW_CHN_MAX]; + u32 vpsl_yraw_stride[VPSL_YRAW_CHN_MAX]; + u32 vpsl_sig_offs[VPSL_SIG_CHN_MAX]; + u32 vpsl_sig_stride[VPSL_SIG_CHN_MAX]; u32 hist_blk_num; u32 enh_row; u32 enh_col; + + bool yraw_sel; + bool is_ae0_fe; + bool is_ae3_fe; }; #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35) int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev); void rkisp_uninit_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev); +void rkisp_params_vpsl_mi_isr_v35(struct rkisp_isp_params_vdev *params_vdev, u32 mis_val); #else static inline int rkisp_init_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) { return -EINVAL; } static inline void rkisp_uninit_params_vdev_v35(struct rkisp_isp_params_vdev *params_vdev) {} +static inline void rkisp_params_vpsl_mi_isr_v35(struct rkisp_isp_params_vdev *params_vdev, u32 mis_val) {} #endif #if IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISP_VERSION_V35_DBG) int rkisp_get_params_v35(struct rkisp_isp_params_vdev *params_vdev, void *arg); diff --git a/drivers/media/platform/rockchip/isp/isp_stats_v35.c b/drivers/media/platform/rockchip/isp/isp_stats_v35.c index a3937c9b98c8..70999758dd6a 100644 --- a/drivers/media/platform/rockchip/isp/isp_stats_v35.c +++ b/drivers/media/platform/rockchip/isp/isp_stats_v35.c @@ -63,6 +63,7 @@ static int rkisp_stats_get_bay3d_stats(struct rkisp_isp_stats_vdev *stats_vdev, struct rkisp35_stat_buffer *pbuf) { + struct rkisp_isp_params_val_v35 *priv = stats_vdev->dev->params_vdev.priv_val; struct isp33_bay3d_stat *bay3d; u32 i, val; @@ -79,6 +80,12 @@ rkisp_stats_get_bay3d_stats(struct rkisp_isp_stats_vdev *stats_vdev, bay3d->sigma_y[i * 2 + 1] = (val >> 16) & 0xfff; } pbuf->meas_type |= ISP35_STAT_BAY3D; + pbuf->stat.buf_bay3d_iir_index = priv->bay3d_iir_cur_idx; + pbuf->stat.buf_bay3d_ds_index = priv->bay3d_ds_cur_idx; + pbuf->stat.buf_bay3d_wgt_index = priv->bay3d_wgt_cur_idx; + pbuf->stat.buf_gain_index = priv->gain_cur_idx; + pbuf->stat.buf_aipre_gain_index = priv->aipre_gain_cur_idx; + pbuf->stat.buf_vpsl_index = priv->vpsl_cur_idx; } return 0; } @@ -191,14 +198,16 @@ rkisp_stats_update_buf(struct rkisp_isp_stats_vdev *stats_vdev) u32 val, addr = 0, offset = 0; int i, ret = 0; - spin_lock_irqsave(&stats_vdev->rd_lock, flags); - if (!stats_vdev->nxt_buf && !list_empty(&stats_vdev->stat)) { - buf = list_first_entry(&stats_vdev->stat, - struct rkisp_buffer, queue); - list_del(&buf->queue); - stats_vdev->nxt_buf = buf; + if (!dev->is_aiisp_en || dev->is_aiisp_sync) { + spin_lock_irqsave(&stats_vdev->rd_lock, flags); + if (!stats_vdev->nxt_buf && !list_empty(&stats_vdev->stat)) { + buf = list_first_entry(&stats_vdev->stat, + struct rkisp_buffer, queue); + list_del(&buf->queue); + stats_vdev->nxt_buf = buf; + } + spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); } - spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); if (stats_vdev->nxt_buf) { addr = stats_vdev->nxt_buf->buff_addr[0]; @@ -376,29 +385,191 @@ rkisp_stats_info2ddr(struct rkisp_isp_stats_vdev *stats_vdev, } static void -rkisp_stats_send_meas_v35(struct rkisp_isp_stats_vdev *stats_vdev, - struct rkisp_isp_readout_work *meas_work) +rkisp_stats_send_meas_fe(struct rkisp_isp_stats_vdev *stats_vdev) { struct rkisp_isp_params_vdev *params_vdev = &stats_vdev->dev->params_vdev; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; + struct rkisp_device *dev = stats_vdev->dev; + struct rkisp35_stat_buffer *stat_tmp_buf, *stat_buf = NULL; + struct rkisp_buffer *cur_buf = NULL; + unsigned long flags = 0; + u32 cur_frame_id, size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + u32 val, ris = isp3_stats_read(stats_vdev, ISP3X_ISP_3A_RIS); + u32 mask = ISP3X_3A_RAWAF; + u64 ns; + + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + return; + if (priv->is_ae0_fe) + mask |= ISP3X_3A_RAWAE_CH0 | ISP3X_3A_RAWHIST_CH0; + if (priv->is_ae3_fe) + mask |= ISP3X_3A_RAWAE_BIG | ISP3X_3A_RAWHIST_BIG; + if (ris & mask) { + isp3_stats_write(stats_vdev, ISP3X_ISP_3A_ICR, ris & mask); + val = isp3_stats_read(stats_vdev, ISP3X_RAWAF_CTRL); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAF_CTRL, val); + if (ris & ISP3X_3A_RAWAE_CH0) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_LITE_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_LITE_BASE, val); + } + if (ris & ISP3X_3A_RAWHIST_CH0) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_LITE_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_LITE_BASE, val); + } + if (ris & ISP3X_3A_RAWAE_BIG) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_BIG1_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_BIG1_BASE, val); + } + if (ris & ISP3X_3A_RAWHIST_BIG) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_BIG1_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_BIG1_BASE, val); + } + } + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, &ns, true); + if (!ns) + ns = ktime_get_ns(); + spin_lock_irqsave(&stats_vdev->rd_lock, flags); + if (!list_empty(&stats_vdev->stat)) { + cur_buf = list_first_entry(&stats_vdev->stat, + struct rkisp_buffer, queue); + list_del(&cur_buf->queue); + } + spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); + + if (cur_buf) { + stat_buf = cur_buf->vaddr[0]; + stat_tmp_buf = stats_vdev->stats_buf[0].vaddr; + rkisp_finish_buffer(dev, &stats_vdev->stats_buf[0]); + + stat_buf->frame_id = cur_frame_id; + stat_buf->params_id = params_vdev->cur_fe_frame_id; + stat_buf->stat.info2ddr.buf_fd = -1; + stat_buf->stat.info2ddr.owner = 0; + stat_buf->stat.buf_aiawb_index = -1; + stat_buf->stat.buf_bay3d_iir_index = -1; + stat_buf->stat.buf_bay3d_ds_index = -1; + stat_buf->stat.buf_bay3d_wgt_index = -1; + stat_buf->stat.buf_aipre_gain_index = -1; + stat_buf->stat.buf_gain_index = -1; + stat_buf->stat.buf_vpsl_index = -1; + } + if (ris & ISP3X_3A_RAWAE_CH0 && stat_buf && stat_tmp_buf) { + memcpy(&stat_buf->stat.rawae0, + &stat_tmp_buf->stat.rawae0, sizeof(struct isp33_rawae_stat)); + stat_buf->meas_type |= ISP35_STAT_RAWAE0; + } + if (ris & ISP3X_3A_RAWHIST_CH0 && stat_buf && stat_tmp_buf) { + memcpy(&stat_buf->stat.rawhist0, + &stat_tmp_buf->stat.rawhist0, sizeof(struct isp33_rawhist_stat)); + stat_buf->meas_type |= ISP35_STAT_RAWHST0; + } + if (ris & ISP3X_3A_RAWAE_BIG && stat_buf && stat_tmp_buf) { + memcpy(&stat_buf->stat.rawae3, + &stat_tmp_buf->stat.rawae3, sizeof(struct isp33_rawae_stat)); + stat_buf->meas_type |= ISP35_STAT_RAWAE3; + } + if (ris & ISP3X_3A_RAWHIST_BIG && stat_buf && stat_tmp_buf) { + memcpy(&stat_buf->stat.rawhist3, + &stat_tmp_buf->stat.rawhist3, sizeof(struct isp33_rawhist_stat)); + stat_buf->meas_type |= ISP35_STAT_RAWHST3; + } + if (ris & ISP3X_3A_RAWAF && stat_buf && stat_tmp_buf) { + memcpy(&stat_buf->stat.rawaf, + &stat_tmp_buf->stat.rawaf, sizeof(struct isp39_rawaf_stat)); + stat_buf->meas_type |= ISP35_STAT_RAWAF; + } + if (stat_buf) + rkisp_stats_get_bay3d_stats(stats_vdev, stat_buf); + if (cur_buf) { + cur_buf->vb.sequence = cur_frame_id; + cur_buf->vb.vb2_buf.timestamp = ns; + vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0, size); + vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + } + v4l2_dbg(4, rkisp_debug, &stats_vdev->dev->v4l2_dev, + "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x\n", + __func__, + cur_frame_id, params_vdev->cur_fe_frame_id, ris, + cur_buf, !stat_buf ? 0 : stat_buf->meas_type); +} + +static void +rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev) +{ + struct rkisp_isp_params_vdev *params_vdev = &stats_vdev->dev->params_vdev; + struct rkisp_isp_params_val_v35 *priv = params_vdev->priv_val; struct rkisp_device *dev = stats_vdev->dev; struct rkisp_buffer *cur_buf = stats_vdev->cur_buf; - struct rkisp35_stat_buffer *cur_stat_buf = NULL; - u32 size = stats_vdev->vdev_fmt.fmt.meta.buffersize; - u32 cur_frame_id = meas_work->frame_id; + struct rkisp35_stat_buffer *stat_tmp_buf = NULL, *cur_stat_buf = NULL; + u32 cur_frame_id, size = stats_vdev->vdev_fmt.fmt.meta.buffersize; + u32 val, mask, ris = isp3_stats_read(stats_vdev, ISP3X_ISP_3A_RIS); + u64 ns; bool is_dummy = false; unsigned long flags = 0; + mask = ISP3X_3A_RAWAWB | ISP35_AIAWB_DONE | ISP3X_3A_DDR_DONE; + if (!dev->is_aiisp_en || dev->is_aiisp_sync) { + mask |= ISP3X_3A_RAWAF | ISP3X_3A_RAWAE_CH0 | ISP3X_3A_RAWHIST_CH0 | + ISP3X_3A_RAWAE_BIG | ISP3X_3A_RAWHIST_BIG; + } + if (dev->is_aiisp_en && !priv->is_ae0_fe) + mask |= ISP3X_3A_RAWHIST_CH0 | ISP3X_3A_RAWAE_CH0; + if (dev->is_aiisp_en && !priv->is_ae3_fe) + mask |= ISP3X_3A_RAWAE_BIG | ISP3X_3A_RAWHIST_BIG; + if (ris & mask) { + isp3_stats_write(stats_vdev, ISP3X_ISP_3A_ICR, ris & mask); + if (dev->is_aiisp_en && !dev->is_aiisp_sync) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAWB_CTRL); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAWB_CTRL, val); + if (ris & ISP3X_3A_RAWAE_CH0) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_LITE_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_LITE_BASE, val); + } + if (ris & ISP3X_3A_RAWHIST_CH0) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_LITE_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_LITE_BASE, val); + } + if (ris & ISP3X_3A_RAWAE_BIG) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWAE_BIG1_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWAE_BIG1_BASE, val); + } + if (ris & ISP3X_3A_RAWHIST_BIG) { + val = isp3_stats_read(stats_vdev, ISP3X_RAWHIST_BIG1_BASE); + if (val & ISP35_3A_MEAS_DONE) + isp3_module_done(stats_vdev, ISP3X_RAWHIST_BIG1_BASE, val); + } + } + } + rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, &ns, !dev->is_aiisp_en); + if (!ns) + ns = ktime_get_ns(); + if (dev->is_aiisp_en && !dev->is_aiisp_sync) { + spin_lock_irqsave(&stats_vdev->rd_lock, flags); + if (!list_empty(&stats_vdev->stat)) { + cur_buf = list_first_entry(&stats_vdev->stat, + struct rkisp_buffer, queue); + list_del(&cur_buf->queue); + } + spin_unlock_irqrestore(&stats_vdev->rd_lock, flags); + stat_tmp_buf = stats_vdev->stats_buf[0].vaddr; + rkisp_finish_buffer(dev, &stats_vdev->stats_buf[0]); + } if (!stats_vdev->rdbk_drop) { if (!cur_buf && stats_vdev->stats_buf[0].mem_priv) { rkisp_finish_buffer(stats_vdev->dev, &stats_vdev->stats_buf[0]); cur_stat_buf = stats_vdev->stats_buf[0].vaddr; - cur_stat_buf->frame_id = cur_frame_id; - cur_stat_buf->params_id = params_vdev->cur_frame_id; is_dummy = true; } else if (cur_buf) { cur_stat_buf = cur_buf->vaddr[0]; - cur_stat_buf->frame_id = cur_frame_id; - cur_stat_buf->params_id = params_vdev->cur_frame_id; } /* buffer done when frame of right handle */ @@ -408,8 +579,6 @@ rkisp_stats_send_meas_v35(struct rkisp_isp_stats_vdev *stats_vdev, is_dummy = false; } else if (cur_stat_buf) { cur_stat_buf = (void *)cur_stat_buf + size / 2; - cur_stat_buf->frame_id = cur_frame_id; - cur_stat_buf->params_id = params_vdev->cur_frame_id; } } @@ -420,47 +589,69 @@ rkisp_stats_send_meas_v35(struct rkisp_isp_stats_vdev *stats_vdev, stats_vdev->cur_buf = stats_vdev->nxt_buf; stats_vdev->nxt_buf = NULL; } - rkisp_stats_update_buf(stats_vdev); + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + rkisp_stats_update_buf(stats_vdev); } } else { cur_buf = NULL; } if (cur_stat_buf) { - cur_stat_buf->stat.buf_aiawb_index = -1; + cur_stat_buf->frame_id = cur_frame_id; + cur_stat_buf->params_id = params_vdev->cur_frame_id; cur_stat_buf->stat.info2ddr.buf_fd = -1; cur_stat_buf->stat.info2ddr.owner = 0; + cur_stat_buf->stat.buf_aiawb_index = -1; + cur_stat_buf->stat.buf_bay3d_iir_index = -1; + cur_stat_buf->stat.buf_bay3d_ds_index = -1; + cur_stat_buf->stat.buf_bay3d_wgt_index = -1; + cur_stat_buf->stat.buf_aipre_gain_index = -1; + cur_stat_buf->stat.buf_gain_index = -1; + cur_stat_buf->stat.buf_vpsl_index = -1; } - if (meas_work->isp3a_ris & ISP3X_3A_RAWAWB && cur_stat_buf) - cur_stat_buf->meas_type |= ISP35_STAT_RAWAWB; - - if (meas_work->isp3a_ris & ISP3X_3A_RAWAF && cur_stat_buf) + if (ris & (mask & ISP3X_3A_RAWAF) && cur_stat_buf) cur_stat_buf->meas_type |= ISP35_STAT_RAWAF; - - if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_BIG && cur_stat_buf) - cur_stat_buf->meas_type |= ISP35_STAT_RAWAE3; - - if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_BIG && cur_stat_buf) - cur_stat_buf->meas_type |= ISP35_STAT_RAWHST3; - - if (meas_work->isp3a_ris & ISP3X_3A_RAWAE_CH0 && cur_stat_buf) + if (ris & (mask & ISP3X_3A_RAWAE_CH0) && cur_stat_buf) { cur_stat_buf->meas_type |= ISP35_STAT_RAWAE0; - - if (meas_work->isp3a_ris & ISP3X_3A_RAWHIST_CH0 && cur_stat_buf) + if (dev->is_aiisp_en && !dev->is_aiisp_sync && stat_tmp_buf) + memcpy(&cur_stat_buf->stat.rawae0, + &stat_tmp_buf->stat.rawae0, sizeof(struct isp33_rawae_stat)); + } + if (ris & (mask & ISP3X_3A_RAWHIST_CH0) && cur_stat_buf) { cur_stat_buf->meas_type |= ISP35_STAT_RAWHST0; - - if (meas_work->isp3a_ris & ISP35_AIAWB_DONE && cur_stat_buf) + if (dev->is_aiisp_en && !dev->is_aiisp_sync && stat_tmp_buf) + memcpy(&cur_stat_buf->stat.rawhist0, + &stat_tmp_buf->stat.rawhist0, sizeof(struct isp33_rawhist_stat)); + } + if (ris & (mask & ISP3X_3A_RAWAE_BIG) && cur_stat_buf) { + cur_stat_buf->meas_type |= ISP35_STAT_RAWAE3; + if (dev->is_aiisp_en && !dev->is_aiisp_sync && stat_tmp_buf) + memcpy(&cur_stat_buf->stat.rawae3, + &stat_tmp_buf->stat.rawae3, sizeof(struct isp33_rawae_stat)); + } + if (ris & (mask & ISP3X_3A_RAWHIST_BIG) && cur_stat_buf) { + cur_stat_buf->meas_type |= ISP35_STAT_RAWHST3; + if (dev->is_aiisp_en && !dev->is_aiisp_sync && stat_tmp_buf) + memcpy(&cur_stat_buf->stat.rawhist3, + &stat_tmp_buf->stat.rawhist3, sizeof(struct isp33_rawhist_stat)); + } + if (ris & (mask & ISP3X_3A_RAWAWB) && cur_stat_buf) { + cur_stat_buf->meas_type |= ISP35_STAT_RAWAWB; + if (dev->is_aiisp_en && !dev->is_aiisp_sync && stat_tmp_buf) + memcpy(&cur_stat_buf->stat.rawawb, + &stat_tmp_buf->stat.rawawb, sizeof(struct isp33_rawawb_stat)); + } + if (ris & ISP35_AIAWB_DONE && cur_stat_buf) rkisp_stats_get_aiawb_stats(stats_vdev, cur_stat_buf); - if (meas_work->isp3a_ris & ISP35_AWBSYNC_DONE && cur_stat_buf) + if (ris & ISP35_AWBSYNC_DONE && cur_stat_buf) rkisp_stats_get_awbsync_stats(stats_vdev, cur_stat_buf); - if (meas_work->isp_ris & ISP3X_FRAME) { + if (!dev->is_aiisp_en || dev->is_aiisp_sync) rkisp_stats_get_bay3d_stats(stats_vdev, cur_stat_buf); - rkisp_stats_get_sharp_stats(stats_vdev, cur_stat_buf); - rkisp_stats_get_enh_stats(stats_vdev, cur_stat_buf); - rkisp_stats_get_hist_stats(stats_vdev, cur_stat_buf); - } + rkisp_stats_get_sharp_stats(stats_vdev, cur_stat_buf); + rkisp_stats_get_enh_stats(stats_vdev, cur_stat_buf); + rkisp_stats_get_hist_stats(stats_vdev, cur_stat_buf); if (cur_stat_buf && (dev->is_first_double || dev->is_wait_aiq)) { cur_stat_buf->meas_type |= ISP35_STAT_RTT_FST; @@ -481,20 +672,16 @@ rkisp_stats_send_meas_v35(struct rkisp_isp_stats_vdev *stats_vdev, } } if (cur_buf && cur_stat_buf) { - cur_stat_buf->frame_id = cur_frame_id; - cur_stat_buf->params_id = params_vdev->cur_frame_id; - cur_stat_buf->stat.info2ddr.buf_fd = -1; - cur_stat_buf->stat.info2ddr.owner = 0; rkisp_stats_info2ddr(stats_vdev, cur_stat_buf); vb2_set_plane_payload(&cur_buf->vb.vb2_buf, 0, size); cur_buf->vb.sequence = cur_frame_id; - cur_buf->vb.vb2_buf.timestamp = meas_work->timestamp; + cur_buf->vb.vb2_buf.timestamp = ns; vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } v4l2_dbg(4, rkisp_debug, &stats_vdev->dev->v4l2_dev, - "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x aiawb(fd:%d 0x%x)\n", - __func__, cur_frame_id, params_vdev->cur_frame_id, meas_work->isp3a_ris, + "%s seq:%d params_id:%d ris:0x%x buf:%p meas_type:0x%x aiawb(idx:%d 0x%x)\n", + __func__, cur_frame_id, params_vdev->cur_frame_id, ris, cur_buf, !cur_stat_buf ? 0 : cur_stat_buf->meas_type, !cur_stat_buf ? -1 : cur_stat_buf->stat.buf_aiawb_index, isp3_stats_read(stats_vdev, ISP35_AIAWB_WR_BASE_SHD)); @@ -504,27 +691,12 @@ static void rkisp_stats_isr_v35(struct rkisp_isp_stats_vdev *stats_vdev, u32 isp_ris, u32 isp3a_ris) { - struct rkisp_isp_readout_work work; - u32 cur_frame_id, isp_mis_tmp = 0; - u32 temp_isp3a_ris; - - rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, NULL, true); - - temp_isp3a_ris = isp3_stats_read(stats_vdev, ISP3X_ISP_3A_RIS); - isp_mis_tmp = temp_isp3a_ris; - if (isp_mis_tmp) - isp3_stats_write(stats_vdev, ISP3X_ISP_3A_ICR, isp_mis_tmp); - rkisp_pdaf_isr(stats_vdev->dev); - if (isp_ris & ISP3X_FRAME) { - work.readout = RKISP_ISP_READOUT_MEAS; - work.frame_id = cur_frame_id; - work.isp_ris = isp_ris; - work.isp3a_ris = temp_isp3a_ris; - work.timestamp = ktime_get_ns(); - rkisp_stats_send_meas_v35(stats_vdev, &work); - } + if (isp_ris & ISP3X_BAY3D_FRM_END) + rkisp_stats_send_meas_fe(stats_vdev); + if (isp_ris & ISP3X_FRAME) + rkisp_stats_send_meas(stats_vdev); } static void @@ -583,7 +755,9 @@ rkisp_stats_first_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev) if (dev->hw_dev->is_single) rkisp_unite_set_bits(dev, ISP3X_SWS_CFG, 0, ISP3X_3A_DDR_WRITE_EN, false); val = rkisp_read(dev, ISP39_W3A_CTRL0, false); - val |= ISP39_W3A_EN | ISP39_W3A_AUTO_CLR_EN | ISP39_W3A_FORCE_UPD; + val |= ISP39_W3A_EN | ISP39_W3A_FORCE_UPD; + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + val |= ISP39_W3A_AUTO_CLR_EN; if (pdaf_vdev && pdaf_vdev->streaming) { val |= ISP39_W3A_PDAF_EN; rkisp_pdaf_update_buf(dev); @@ -611,7 +785,8 @@ rkisp_stats_next_ddr_config_v35(struct rkisp_isp_stats_vdev *stats_vdev) return; /* pingpong buf */ if (hw->is_single) { - rkisp_stats_update_buf(stats_vdev); + if (!dev->is_aiisp_en || dev->is_aiisp_sync) + rkisp_stats_update_buf(stats_vdev); if (pdaf_vdev && pdaf_vdev->streaming) rkisp_pdaf_update_buf(dev); } diff --git a/drivers/media/platform/rockchip/isp/procfs.c b/drivers/media/platform/rockchip/isp/procfs.c index b633a2cc39c7..712159cfe95a 100644 --- a/drivers/media/platform/rockchip/isp/procfs.c +++ b/drivers/media/platform/rockchip/isp/procfs.c @@ -1195,7 +1195,17 @@ static void isp35_show(struct rkisp_device *dev, struct seq_file *p) rkisp_read(dev, ISP35_B3DLDC_ADR_STS, false), rkisp_read(dev, ISP35_B3DLDC_CTRL, false), !(val & BIT(8)), !!(tmp & BIT(20)), !!(tmp & BIT(21)), !!(tmp & BIT(22)), - priv->buf_3dnr_iir.size, priv->buf_3dnr_ds.size, priv->buf_3dnr_wgt.size); + priv->buf_bay3d_iir[0].size, priv->buf_bay3d_ds[0].size, priv->buf_bay3d_wgt[0].size); + val = rkisp_read(dev, ISP35_AI_CTRL, false); + seq_printf(p, "%-10s %s(0x%x) vpsl(ctrl:0x%x chn:0x%x), aiisp(idx:%d cnt:%d)\n" + "\t iir(idx:%d cnt:%d) gain(idx:%d cnt:%d) aipre(idx:%d cnt:%d) vpsl(idx:%d cnt:%d)\n", + "AINR", (val & 1) ? "ON" : "OFF", val, + vpsl_read(dev, VPSL_PYR_CTRL, false), vpsl_read(dev, VPSL_PYR_CHN, false), + priv->aiisp_cur_idx, priv->aiisp_cnt, + priv->bay3d_iir_cur_idx, priv->bay3d_iir_cnt, + priv->gain_cur_idx, priv->gain_cnt, + priv->aipre_gain_cur_idx, priv->aipre_gain_cnt, + priv->vpsl_cur_idx, priv->vpsl_cnt); val = rkisp_read(dev, ISP3X_YNR_GLOBAL_CTRL, false); seq_printf(p, "%-10s %s(0x%x) bypass(hi:%d mi:%d lo:%d) lp_en:%d\n", "YNR", (val & 1) ? "ON" : "OFF", val, diff --git a/drivers/media/platform/rockchip/isp/regs.h b/drivers/media/platform/rockchip/isp/regs.h index 4338c8f3c1ec..79b6e89b9b23 100644 --- a/drivers/media/platform/rockchip/isp/regs.h +++ b/drivers/media/platform/rockchip/isp/regs.h @@ -37,6 +37,7 @@ #include "dev.h" #include "regs_v2x.h" #include "regs_v3x.h" +#include "vpsl_reg.h" #define CIF_ISP_PACK_4BYTE(a, b, c, d) \ (((a) & 0xFF) << 0 | ((b) & 0xFF) << 8 | \ diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 253bfdfebb31..678fac13a543 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -50,6 +50,7 @@ #include "isp_external.h" #include "regs.h" #include "rkisp_tb_helper.h" +#include "isp_params_v35.h" #define ISP_V4L2_EVENT_ELEMS 4 @@ -683,6 +684,7 @@ static void rkisp_update_list_reg(struct rkisp_device *dev) val |= ISP3X_3A_DDR_WRITE_EN; writel(val, hw->base_addr + ISP3X_SWS_CFG); } + dev->params_vdev.ops->vpsl_update_regs(&dev->params_vdev); } if (dev->isp_ver >= ISP_V33) { val = rkisp_read(dev, ISP39_W3A_CTRL0, false); @@ -2430,8 +2432,8 @@ static int rkisp_isp_start(struct rkisp_device *dev) u32 val; v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, - "%s refcnt:%d link_num:%d\n", __func__, - atomic_read(&hw->refcnt), hw->dev_link_num); + "%s refcnt:%d link_num:%d unite_div:%d\n", __func__, + atomic_read(&hw->refcnt), hw->dev_link_num, dev->unite_div); dev->cap_dev.is_done_early = false; if (dev->cap_dev.wait_line >= dev->isp_sdev.out_crop.height) @@ -3862,7 +3864,7 @@ static void rkisp_config_aiisp(struct rkisp_device *dev) goto unlock; dev->is_aiisp_upd = false; if (dev->is_aiisp_en) { - en = ISP39_AIISP_EN; + en = (dev->isp_ver == ISP_V39) ? ISP39_AIISP_EN : ISP35_AIISP_EN; irq = ISP39_AIISP_LINECNT_DONE; if (dev->aiisp_cfg.rd_linecnt) irq |= ISP3X_OUT_FRM_QUARTER; @@ -3871,14 +3873,14 @@ static void rkisp_config_aiisp(struct rkisp_device *dev) en = 0; } irq_mask = ISP39_AIISP_LINECNT_DONE | ISP3X_OUT_FRM_QUARTER; - en_mask = ISP39_AIISP_EN; + en_mask = (dev->isp_ver == ISP_V39) ? ISP39_AIISP_EN : ISP35_AIISP_EN; if (dev->aiisp_cfg.rd_linecnt >= h) rd_line = h - 1; else rd_line = dev->aiisp_cfg.rd_linecnt; - if (dev->aiisp_cfg.wr_linecnt >= h) - wr_line = (h - 1) << 16; + if (dev->aiisp_cfg.wr_linecnt >= (h - 10)) + wr_line = (h - 10) << 16; else wr_line = dev->aiisp_cfg.wr_linecnt << 16; @@ -3886,7 +3888,10 @@ static void rkisp_config_aiisp(struct rkisp_device *dev) rkisp_write(dev, ISP32_ISP_IRQ_CFG1, wr_line, false); rkisp_write(dev, ISP39_SLICE_ST_CTRL, 0, false); rkisp_set_bits(dev, CIF_ISP_IMSC, irq_mask, irq, false); - rkisp_set_bits(dev, ISP3X_MI_RD_CTRL2, en_mask, en, false); + if (dev->isp_ver == ISP_V39) + rkisp_set_bits(dev, ISP3X_MI_RD_CTRL2, en_mask, en, false); + else + rkisp_set_bits(dev, ISP35_AI_CTRL, en_mask, en, false); unlock: spin_unlock_irqrestore(&dev->aiisp_lock, lock_flags); } @@ -3896,7 +3901,7 @@ static int rkisp_set_aiisp_linecnt(struct rkisp_device *dev, { unsigned long lock_flags = 0; - if (dev->isp_ver != ISP_V39) + if (dev->isp_ver != ISP_V39 && dev->isp_ver != ISP_V35) return -EINVAL; spin_lock_irqsave(&dev->aiisp_lock, lock_flags); dev->is_aiisp_en = !!cfg->mode; @@ -3911,7 +3916,7 @@ static int rkisp_get_aiisp_linecnt(struct rkisp_device *dev, { unsigned long lock_flags = 0; - if (dev->isp_ver != ISP_V39) + if (dev->isp_ver != ISP_V39 && dev->isp_ver != ISP_V35) return -EINVAL; spin_lock_irqsave(&dev->aiisp_lock, lock_flags); @@ -3982,7 +3987,10 @@ end: rkisp_sditf_sof(dev, 0); rkisp_check_mi_ends_mask(dev); - rkisp_set_bits(dev, ISP3X_MI_RD_CTRL2, 0, ISP39_AIISP_ST, true); + if (dev->isp_ver == ISP_V39) + rkisp_set_bits(dev, ISP3X_MI_RD_CTRL2, 0, ISP39_AIISP_ST, true); + else + rkisp_set_bits(dev, ISP35_AI_CTRL, 0, ISP35_AIISP_ST, true); } } return ret; @@ -5022,7 +5030,7 @@ vs_skip: isp_mis_tmp); } - if (isp_mis & ISP39_AIISP_LINECNT_DONE && dev->isp_ver == ISP_V39) { + if (isp_mis & ISP39_AIISP_LINECNT_DONE) { writel(ISP39_AIISP_LINECNT_DONE, base + CIF_ISP_ICR); rkisp_aiisp_irq_event(dev, ISP39_AIISP_LINECNT_DONE); } @@ -5210,6 +5218,12 @@ vs_skip: } } +void rkisp_vpsl_mi_isr(struct rkisp_device *dev, u32 mis_val) +{ + if (dev->isp_ver == ISP_V35) + rkisp_params_vpsl_mi_isr_v35(&dev->params_vdev, mis_val); +} + irqreturn_t rkisp_vs_isr_handler(int irq, void *ctx) { struct device *dev = ctx; diff --git a/drivers/media/platform/rockchip/isp/rkisp.h b/drivers/media/platform/rockchip/isp/rkisp.h index 10628ac096dc..5b635b53c44d 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.h +++ b/drivers/media/platform/rockchip/isp/rkisp.h @@ -198,6 +198,8 @@ void rkisp_rx_buf_pool_free(struct rkisp_device *dev); int rkisp_expander_config(struct rkisp_device *dev, struct rkmodule_hdr_cfg *cfg, bool on); +void rkisp_vpsl_mi_isr(struct rkisp_device *dev, u32 mis_val); + static inline struct ispsd_out_fmt *rkisp_get_ispsd_out_fmt(struct rkisp_isp_subdev *isp_sdev) { diff --git a/drivers/media/platform/rockchip/isp/vpsl_reg.h b/drivers/media/platform/rockchip/isp/vpsl_reg.h new file mode 100644 index 000000000000..ada2da1ba532 --- /dev/null +++ b/drivers/media/platform/rockchip/isp/vpsl_reg.h @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) + * + * Copyright (C) 2025 Rockchip Electronics Co., Ltd. + */ + +#ifndef _VPSL_REG_H +#define _VPSL_REG_H +#include "dev.h" + +#define VPSL_BASE 0x00000000 +#define VPSL_CTRL (VPSL_BASE + 0x00000) +#define VPSL_PYR_CTRL (VPSL_BASE + 0x00004) +#define VPSL_PYR_CHN (VPSL_BASE + 0x00008) +#define VPSL_VERSION (VPSL_BASE + 0x0000C) +#define VPSL_UPDATE (VPSL_BASE + 0x00010) +#define VPSL_CLK_EN (VPSL_BASE + 0x00014) +#define VPSL_CLK_GATE (VPSL_BASE + 0x00018) +#define VPSL_RESET (VPSL_BASE + 0x0001C) +#define VPSL_PYR_SIGMA_LUT (VPSL_BASE + 0x00020) +#define VPSL_IRQ_CFG (VPSL_BASE + 0x00050) +#define VPSL_IMSC (VPSL_BASE + 0x00070) +#define VPSL_RIS (VPSL_BASE + 0x00074) +#define VPSL_MIS (VPSL_BASE + 0x00078) +#define VPSL_ICR (VPSL_BASE + 0x0007C) +#define VPSL_ISR (VPSL_BASE + 0x00080) +#define VPSL_PYR_CTRL_SHD (VPSL_BASE + 0x00094) +#define VPSL_PYR_CHN_SHD (VPSL_BASE + 0x00098) +#define VPSL_WORKING (VPSL_BASE + 0x000A0) +#define VPSL_PIPE_ACK0 (VPSL_BASE + 0x000B0) +#define VPSL_PIPE_ACK1 (VPSL_BASE + 0x000B4) +#define VPSL_LINE_CNT0 (VPSL_BASE + 0x000C0) +#define VPSL_LINE_CNT1 (VPSL_BASE + 0x000C4) +#define VPSL_FRAME_CNT (VPSL_BASE + 0x000C8) +#define VPSL_PYR_FIFO_DBG (VPSL_BASE + 0x000d0) + +#define VPSL_MI_BASE 0x00001000 +#define VPSL_MI_CTRL (VPSL_MI_BASE + 0x00000) +#define VPSL_MI_WR_INIT (VPSL_MI_BASE + 0x00004) +#define VPSL_MI_HURRY_CTRL (VPSL_MI_BASE + 0x00040) +#define VPSL_MI_ARQOS_CTRL (VPSL_MI_BASE + 0x00044) +#define VPSL_MI_IMSC (VPSL_MI_BASE + 0x00050) +#define VPSL_MI_RIS (VPSL_MI_BASE + 0x00054) +#define VPSL_MI_MIS (VPSL_MI_BASE + 0x00058) +#define VPSL_MI_ICR (VPSL_MI_BASE + 0x0005C) +#define VPSL_MI_ISR (VPSL_MI_BASE + 0x00060) +#define VPSL_MI_RD_CTRL (VPSL_MI_BASE + 0x00100) +#define VPSL_MI_RD_INIT (VPSL_MI_BASE + 0x00104) +#define VPSL_MI_RD_START (VPSL_MI_BASE + 0x00108) +#define VPSL_MI_RD_Y_BASE (VPSL_MI_BASE + 0x00110) +#define VPSL_MI_RD_Y_WIDTH (VPSL_MI_BASE + 0x00114) +#define VPSL_MI_RD_Y_HEIGHT (VPSL_MI_BASE + 0x00118) +#define VPSL_MI_RD_Y_STRIDE (VPSL_MI_BASE + 0x0011C) +#define VPSL_MI_RD_Y_BASE_SHD (VPSL_MI_BASE + 0x00130) +#define VPSL_MI_RD_Y_WIDTH_SHD (VPSL_MI_BASE + 0x00138) +#define VPSL_MI_RD_Y_HEIGHT_SHD (VPSL_MI_BASE + 0x0013C) +#define VPSL_MI_CHN0_WR_CTRL (VPSL_MI_BASE + 0x00200) +#define VPSL_MI_CHN0_WR_BASE (VPSL_MI_BASE + 0x00210) +#define VPSL_MI_CHN0_WR_SIZE (VPSL_MI_BASE + 0x00224) +#define VPSL_MI_CHN0_WR_STRIDE (VPSL_MI_BASE + 0x00228) +#define VPSL_MI_CHN0_WR_BASE_SHD (VPSL_MI_BASE + 0x00230) +#define VPSL_MI_CHN0_WR_END_ADDR (VPSL_MI_BASE + 0x00234) +#define VPSL_MI_CHN1_WR_CTRL (VPSL_MI_BASE + 0x00300) +#define VPSL_MI_CHN1_WR_BASE (VPSL_MI_BASE + 0x00310) +#define VPSL_MI_CHN1_WR_SIZE (VPSL_MI_BASE + 0x00324) +#define VPSL_MI_CHN1_WR_STRIDE (VPSL_MI_BASE + 0x00328) +#define VPSL_MI_CHN1_WR_BASE_SHD (VPSL_MI_BASE + 0x00330) +#define VPSL_MI_CHN1_WR_END_ADDR (VPSL_MI_BASE + 0x00334) +#define VPSL_MI_CHN2_WR_CTRL (VPSL_MI_BASE + 0x00400) +#define VPSL_MI_CHN2_WR_BASE (VPSL_MI_BASE + 0x00410) +#define VPSL_MI_CHN2_WR_SIZE (VPSL_MI_BASE + 0x00424) +#define VPSL_MI_CHN2_WR_STRIDE (VPSL_MI_BASE + 0x00428) +#define VPSL_MI_CHN2_WR_BASE_SHD (VPSL_MI_BASE + 0x00430) +#define VPSL_MI_CHN2_WR_END_ADDR (VPSL_MI_BASE + 0x00434) +#define VPSL_MI_CHN3_WR_CTRL (VPSL_MI_BASE + 0x00500) +#define VPSL_MI_CHN3_WR_BASE (VPSL_MI_BASE + 0x00510) +#define VPSL_MI_CHN3_WR_SIZE (VPSL_MI_BASE + 0x00524) +#define VPSL_MI_CHN3_WR_STRIDE (VPSL_MI_BASE + 0x00528) +#define VPSL_MI_CHN3_WR_BASE_SHD (VPSL_MI_BASE + 0x00530) +#define VPSL_MI_CHN3_WR_END_ADDR (VPSL_MI_BASE + 0x00534) +#define VPSL_MI_CHN4_WR_CTRL (VPSL_MI_BASE + 0x00600) +#define VPSL_MI_CHN4_WR_BASE (VPSL_MI_BASE + 0x00610) +#define VPSL_MI_CHN4_WR_SIZE (VPSL_MI_BASE + 0x00624) +#define VPSL_MI_CHN4_WR_STRIDE (VPSL_MI_BASE + 0x00628) +#define VPSL_MI_CHN4_WR_BASE_SHD (VPSL_MI_BASE + 0x00630) +#define VPSL_MI_CHN4_WR_END_ADDR (VPSL_MI_BASE + 0x00634) +#define VPSL_MI_CHN5_WR_CTRL (VPSL_MI_BASE + 0x00700) +#define VPSL_MI_CHN5_WR_BASE (VPSL_MI_BASE + 0x00710) +#define VPSL_MI_CHN5_WR_SIZE (VPSL_MI_BASE + 0x00724) +#define VPSL_MI_CHN5_WR_STRIDE (VPSL_MI_BASE + 0x00728) +#define VPSL_MI_CHN5_WR_BASE_SHD (VPSL_MI_BASE + 0x00730) +#define VPSL_MI_CHN5_WR_END_ADDR (VPSL_MI_BASE + 0x00734) +#define VPSL_MI_CHN6_WR_CTRL (VPSL_MI_BASE + 0x00800) +#define VPSL_MI_CHN6_WR_BASE (VPSL_MI_BASE + 0x00810) +#define VPSL_MI_CHN6_WR_SIZE (VPSL_MI_BASE + 0x00824) +#define VPSL_MI_CHN6_WR_STRIDE (VPSL_MI_BASE + 0x00828) +#define VPSL_MI_CHN6_WR_BASE_SHD (VPSL_MI_BASE + 0x00830) +#define VPSL_MI_CHN6_WR_END_ADDR (VPSL_MI_BASE + 0x00834) +#define VPSL_MI_CHN7_WR_CTRL (VPSL_MI_BASE + 0x00900) +#define VPSL_MI_CHN7_WR_BASE (VPSL_MI_BASE + 0x00910) +#define VPSL_MI_CHN7_WR_SIZE (VPSL_MI_BASE + 0x00924) +#define VPSL_MI_CHN7_WR_STRIDE (VPSL_MI_BASE + 0x00928) +#define VPSL_MI_CHN7_WR_BASE_SHD (VPSL_MI_BASE + 0x00930) +#define VPSL_MI_CHN7_WR_END_ADDR (VPSL_MI_BASE + 0x00934) +#define VPSL_MI_CHN8_WR_CTRL (VPSL_MI_BASE + 0x00a00) +#define VPSL_MI_CHN8_WR_BASE (VPSL_MI_BASE + 0x00a10) +#define VPSL_MI_CHN8_WR_SIZE (VPSL_MI_BASE + 0x00a24) +#define VPSL_MI_CHN8_WR_STRIDE (VPSL_MI_BASE + 0x00a28) +#define VPSL_MI_CHN8_WR_BASE_SHD (VPSL_MI_BASE + 0x00a30) +#define VPSL_MI_CHN8_WR_END_ADDR (VPSL_MI_BASE + 0x00a34) +#define VPSL_MI_CHN9_WR_CTRL (VPSL_MI_BASE + 0x00b00) +#define VPSL_MI_CHN9_WR_BASE (VPSL_MI_BASE + 0x00b10) +#define VPSL_MI_CHN9_WR_SIZE (VPSL_MI_BASE + 0x00b24) +#define VPSL_MI_CHN9_WR_STRIDE (VPSL_MI_BASE + 0x00b28) +#define VPSL_MI_CHN9_WR_BASE_SHD (VPSL_MI_BASE + 0x00b30) +#define VPSL_MI_CHN9_WR_END_ADDR (VPSL_MI_BASE + 0x00b34) +#define VPSL_MI_CHN10_WR_CTRL (VPSL_MI_BASE + 0x00c00) +#define VPSL_MI_CHN10_WR_BASE (VPSL_MI_BASE + 0x00c10) +#define VPSL_MI_CHN10_WR_SIZE (VPSL_MI_BASE + 0x00c24) +#define VPSL_MI_CHN10_WR_STRIDE (VPSL_MI_BASE + 0x00c28) +#define VPSL_MI_CHN10_WR_BASE_SHD (VPSL_MI_BASE + 0x00c30) +#define VPSL_MI_CHN10_WR_END_ADDR (VPSL_MI_BASE + 0x00c34) + +#define VPSL_PYR_YRAW_MODE(x) ((x) & 0x3) +#define VPSL_PYR_SIGMA_EN BIT(2) +#define VPSL_PYR_RAW_MODE BIT(4) +#define VPSL_PYR_GAIN_LEFTSHIFT(x) (((x) & 0x7) << 8) +#define VPSL_PYR_BLK_SIG(x) (((x) & 0xff) << 16) +#define VPSL_PYR_TBL_RD_ONLY BIT(28) +#define VPSL_PYR_CHN_ADAPT_DIS BIT(29) +#define VPSL_PYR_ERR_CLR_P BIT(30) +#define VPSL_PYR_TBL_CLR_P BIT(31) + +#define VPSL_CHN0_EN BIT(0) +#define VPSL_CHN1_EN BIT(1) +#define VPSL_CHN2_EN BIT(2) +#define VPSL_CHN3_EN BIT(3) +#define VPSL_CHN4_EN BIT(4) +#define VPSL_CHN5_EN BIT(5) +#define VPSL_CHN6_EN BIT(6) +#define VPSL_CHN7_EN BIT(7) +#define VPSL_CHN8_EN BIT(8) +#define VPSL_CHN9_EN BIT(9) +#define VPSL_CHN10_EN BIT(10) + +#define VPSL_CFG_FORCE_UPD BIT(0) +#define VPSL_CFG_GEN_UPD BIT(1) +#define VPSL_YRAW_CHN_FORCE_UPD BIT(4) +#define VPSL_SIGMA_CHN_FORCE_UPD BIT(5) + +#define VPSL_YRAW_CLK_EN BIT(0) +#define VPSL_SIGMA_CLK_EN BIT(1) +#define VPSL_MI_CLK_EN BIT(31) + +#define VPSL_YRAW_CKG_DIS BIT(0) +#define VPSL_SIGMA_CKG_DIS BIT(1) +#define VPSL_MI_CHN0_CKG_DIS BIT(16) +#define VPSL_MI_CHN1_CKG_DIS BIT(17) +#define VPSL_MI_CHN2_CKG_DIS BIT(18) +#define VPSL_MI_CHN3_CKG_DIS BIT(19) +#define VPSL_MI_CHN4_CKG_DIS BIT(20) +#define VPSL_MI_CHN5_CKG_DIS BIT(21) +#define VPSL_MI_CHN6_CKG_DIS BIT(22) +#define VPSL_MI_CHN7_CKG_DIS BIT(23) +#define VPSL_MI_CHN8_CKG_DIS BIT(24) +#define VPSL_MI_CHN9_CKG_DIS BIT(25) +#define VPSL_MI_CHN10_CKG_DIS BIT(26) +#define VPSL_MI_RD_CKG_DIS BIT(31) + +#define VPSL_GLB_SOFT_RST BIT(0) +#define VPSL_RST_PROTECT_DIS BIT(30) +#define VPSL_SAFETY_DONE_CLR BIT(31) + +#define VPSL_ISP2VPSL_FRM_ST BIT(0) +#define VPSL_YRAW_IN_FRM_END BIT(4) +#define VPSL_YRAW_IN_CFG_IRQ BIT(5) +#define VPSL_YRAW_FRM_END BIT(6) +#define VPSL_SIGMA_IN_FRM_END BIT(8) +#define VPSL_SIGMA_IN_CFG_IRQ BIT(9) +#define VPSL_SIGMA_FRM_END BIT(10) +#define VPSL_SIGMA_GAIN_FULL_ERR BIT(31) + +#define VPSL_MI_WR_INIT_BASE_EN BIT(4) +#define VPSL_MI_WR_INIT_OFFSET_EN BIT(5) +#define VPSL_MI_WR_FIFO_DIS BIT(24) +#define VPSL_MI_WR_GLB_EN_DIS BIT(25) +#define VPSL_MI_WR_ID_POLL_CLR BIT(26) +#define VPSL_MI_WR_ID_POLL_DIS BIT(27) + +#define VPSL_MI_FORCE_UPD BIT(0) +#define VPSL_MI_CHN0_SELF_UPD BIT(4) +#define VPSL_MI_CHN1_SELF_UPD BIT(5) +#define VPSL_MI_CHN2_SELF_UPD BIT(6) +#define VPSL_MI_CHN3_SELF_UPD BIT(7) +#define VPSL_MI_CHN4_SELF_UPD BIT(8) +#define VPSL_MI_CHN5_SELF_UPD BIT(9) +#define VPSL_MI_CHN6_SELF_UPD BIT(10) +#define VPSL_MI_CHN7_SELF_UPD BIT(11) +#define VPSL_MI_CHN8_SELF_UPD BIT(12) +#define VPSL_MI_CHN9_SELF_UPD BIT(13) +#define VPSL_MI_CHN10_SELF_UPD BIT(14) +#define VPSL_ITSELF_FORCE_PRO_DIS BIT(31) + +#define VPSL_CHN_WR_AUTO_UPD BIT(1) +#define VPSL_CHN_BURST_LEN(x) (((x) & 0x3) << 8) +#define VPSL_CHN_WR_EN_SHD BIT(30) +#define VPSL_CHN_WORKING BIT(31) + +#define VPSL_MI_CHN0_END BIT(0) +#define VPSL_MI_CHN1_END BIT(1) +#define VPSL_MI_CHN2_END BIT(2) +#define VPSL_MI_CHN3_END BIT(3) +#define VPSL_MI_CHN4_END BIT(4) +#define VPSL_MI_CHN5_END BIT(5) +#define VPSL_MI_CHN6_END BIT(6) +#define VPSL_MI_CHN7_END BIT(7) +#define VPSL_MI_CHN8_END BIT(8) +#define VPSL_MI_CHN9_END BIT(9) +#define VPSL_MI_CHN10_END BIT(10) +#define VPSL_MI_READ_END BIT(16) +#define VPSL_BUS_ERR BIT(28) +#define VPSL_MI_SIGMA_ALL_END BIT(30) +#define VPSL_MI_YRAW_ALL_END BIT(31) + +#define VPSL_SW_REG_SIZE 0x2000 +#define VPSL_SW_MAX_SIZE (VPSL_SW_REG_SIZE * 2) + +static inline void vpsl_write(struct rkisp_device *dev, u32 reg, u32 val, bool is_direct) +{ + void __iomem *base = dev->hw_dev->vpsl_base_addr; + u32 *mem = dev->sw_vpsl_base_addr + reg; + u32 *flag = dev->sw_vpsl_base_addr + reg + VPSL_SW_REG_SIZE; + + *mem = val; + *flag = SW_REG_CACHE; + if (dev->hw_dev->is_single || is_direct) { + *flag = SW_REG_CACHE_SYNC; + writel(val, base + reg); + } +} + +static inline u32 vpsl_read(struct rkisp_device *dev, u32 reg, bool is_direct) +{ + void __iomem *base = dev->hw_dev->vpsl_base_addr; + u32 val; + + if (dev->hw_dev->is_single || is_direct) + val = readl(base + reg); + else + val = *(u32 *)(dev->sw_vpsl_base_addr + reg); + return val; +} +#endif diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index 9dce8dc2ed35..d19386cf76d3 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -430,10 +430,11 @@ struct rkisp_aiisp_ev_info { int sequence; int height; - /* bnr front end */ int iir_index; int gain_index; - /* bnr back end */ + int aipre_gain_index; + int vpsl_index; + int aiisp_index; } __attribute__ ((packed)); @@ -443,7 +444,11 @@ struct rkisp_aiisp_st { int iir_index; int gain_index; + int aiisp_index; + + int aipre_gain_index; + int vpsl_index; } __attribute__ ((packed)); /* struct rkisp_aiisp_cfg @@ -457,6 +462,9 @@ struct rkisp_aiisp_cfg { int rd_linecnt; } __attribute__ ((packed)); +#define VPSL_YRAW_CHN_MAX 6 +#define VPSL_SIG_CHN_MAX 5 + struct rkisp_bnr_buf_info { struct rkisp_buf_info iir; union { @@ -465,6 +473,24 @@ struct rkisp_bnr_buf_info { struct rkisp_buf_info gain; __u8 iirsparse_en; } v39; + struct { + struct rkisp_buf_info ds; + struct rkisp_buf_info wgt; + + struct rkisp_buf_info aiisp; + struct rkisp_buf_info gain; + struct rkisp_buf_info aipre_gain; + struct rkisp_buf_info vpsl; + __u8 iir_rw_fmt; + __u8 gain_mode; + __u8 yraw_sel; + /* yraw ds_2x2 to ds_64x64 buf offset and stride */ + __u32 vpsl_yraw_offs[VPSL_YRAW_CHN_MAX]; + __u32 vpsl_yraw_stride[VPSL_YRAW_CHN_MAX]; + /* sigma ds_2x2 to ds_32x32 buf offset and stride */ + __u32 vpsl_sig_offs[VPSL_SIG_CHN_MAX]; + __u32 vpsl_sig_stride[VPSL_SIG_CHN_MAX]; + } v35; } u; } __attribute__ ((packed)); diff --git a/include/uapi/linux/rk-isp35-config.h b/include/uapi/linux/rk-isp35-config.h index 3e63aa605c5c..e8d706617c7d 100644 --- a/include/uapi/linux/rk-isp35-config.h +++ b/include/uapi/linux/rk-isp35-config.h @@ -157,6 +157,7 @@ #define ISP35_BAY3D_FILT_COEFF_NUM 6 #define ISP35_AI_SIGMA_NUM 33 +#define ISP35_VPSL_SIGMA_NUM 81 #define ISP35_SHARP_X_NUM ISP33_SHARP_X_NUM #define ISP35_SHARP_Y_NUM ISP33_SHARP_Y_NUM @@ -625,7 +626,7 @@ struct isp35_ai_cfg { __u16 aiisp_sigma_y[ISP35_AI_SIGMA_NUM]; /* AIPRE_NL_PRE */ __u8 aipre_scale; - __u8 aipre_zp; + __s8 aipre_zp; __u16 aipre_black_lvl; /* AIPRE_GAIN_PARA */ __u8 aipre_gain_alpha; @@ -635,7 +636,7 @@ struct isp35_ai_cfg { __u16 aipre_sigma_y[ISP35_AI_SIGMA_NUM]; /* AIPRE_NOISE0 */ __u8 aipre_noise_mot_offset; - __u8 aipre_noise_mot_gain; + __s8 aipre_noise_mot_gain; __u16 aipre_noise_luma_offset; /* AIPRE_NOISE1 */ __u16 aipre_noise_luma_gain; @@ -644,6 +645,15 @@ struct isp35_ai_cfg { /* AIPRE_NOISE2 */ __u8 aipre_nar_manual; __u8 aipre_nar_manual_alpha; + + /* VPSL_PYR_CTRL */ + __u8 pyr_yraw_mode; + __u8 pyr_sigma_en; + __u8 pyr_yraw_sel; + __u8 pyr_gain_leftshift; + __u8 pyr_blacklvl_sig; + /* VPSL_PYR_SIGMA_LUT */ + __u8 pyr_sigma_y[ISP35_VPSL_SIGMA_NUM]; } __attribute__ ((packed)); struct isp35_ynr_cfg { @@ -1739,7 +1749,14 @@ struct isp35_stat { struct isp33_hist_stat hist; struct isp35_awbsync_stat awbsync; struct isp32_info2ddr_stat info2ddr; + int buf_aiawb_index; + int buf_bay3d_iir_index; + int buf_bay3d_ds_index; + int buf_bay3d_wgt_index; + int buf_gain_index; + int buf_aipre_gain_index; + int buf_vpsl_index; } __attribute__ ((packed)); struct rkisp35_stat_buffer {