From ce956f7a334fde4c0c7fa5f81bd2e2c4115c25c3 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 5 Jan 2024 18:03:39 +0800 Subject: [PATCH 1/2] media: rockchip: isp: fix resume mi no enable Change-Id: Ic7aa8eb5528e97b4d425971d5189ef85c0c1c6c9 Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/hw.c | 40 ++++++++++++++++++- .../media/platform/rockchip/isp/isp_rockit.c | 2 +- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/isp/hw.c b/drivers/media/platform/rockchip/isp/hw.c index 5b0f291aaac1..6457772f7b89 100644 --- a/drivers/media/platform/rockchip/isp/hw.c +++ b/drivers/media/platform/rockchip/isp/hw.c @@ -441,6 +441,9 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) }, { .base = MI_GAIN_WR_BASE, .shd = MI_GAIN_WR_BASE_SHD, + }, { + .base = MI_WR_CTRL, + .shd = MI_WR_CTRL_SHD, } }; @@ -495,7 +498,34 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) reg = reg_buf + backup[j].base; reg1 = reg_buf + backup[j].shd; backup[j].val = *reg; - writel(*reg1, base + backup[j].base); + if (backup[j].base == MI_WR_CTRL) { + val = *reg1 & 0xf; + val |= (*reg & ~0xf); + } else { + val = *reg1; + } + writel(val, base + backup[j].base); + } + if (dev->isp_ver == ISP_V30) { + reg = reg_buf + ISP32_MI_WR_CTRL2_SHD; + reg1 = reg_buf + ISP3X_MI_BP_WR_CTRL; + if ((*reg & ISP32_BP_EN_IN_SHD) != (*reg1 & ISP3X_BP_ENABLE)) { + val = *reg & ISP32_BP_EN_IN_SHD; + val |= *reg1 & ~ISP3X_BP_ENABLE; + writel(val, base + ISP3X_MI_BP_WR_CTRL); + } + reg1 = reg_buf + ISP32_MI_MPDS_WR_CTRL; + if ((*reg & ISP32_MPDS_EN_IN_SHD) != (*reg1 & ISP32_DS_ENABLE)) { + val = *reg & ISP32_MPDS_EN_IN_SHD; + val |= *reg1 & ~ISP32_DS_ENABLE; + writel(val, base + ISP32_MI_MPDS_WR_CTRL); + } + reg1 = reg_buf + ISP32_MI_BPDS_WR_CTRL; + if ((*reg & ISP32_BPDS_EN_IN_SHD) != (*reg1 & ISP32_DS_ENABLE)) { + val = *reg & ISP32_BPDS_EN_IN_SHD; + val |= *reg1 & ~ISP32_DS_ENABLE; + writel(val, base + ISP32_MI_BPDS_WR_CTRL); + } } /* update module */ @@ -522,6 +552,14 @@ void rkisp_hw_reg_restore(struct rkisp_hw_dev *dev) /* config base_reg */ for (j = 0; j < ARRAY_SIZE(backup); j++) writel(backup[j].val, base + backup[j].base); + if (dev->isp_ver == ISP_V30) { + reg = reg_buf + ISP3X_MI_BP_WR_CTRL; + writel(*reg, base + ISP3X_MI_BP_WR_CTRL); + reg = reg_buf + ISP32_MI_MPDS_WR_CTRL; + writel(*reg, base + ISP32_MI_MPDS_WR_CTRL); + reg = reg_buf + ISP32_MI_BPDS_WR_CTRL; + writel(*reg, base + ISP32_MI_BPDS_WR_CTRL); + } /* base_reg = shd_reg, write is base but read is shd */ val = rkisp_read_reg_cache(isp, ISP_MPFBC_HEAD_PTR); writel(val, base + ISP_MPFBC_HEAD_PTR); diff --git a/drivers/media/platform/rockchip/isp/isp_rockit.c b/drivers/media/platform/rockchip/isp/isp_rockit.c index 6a5fa4084abd..8fb41ec43afe 100644 --- a/drivers/media/platform/rockchip/isp/isp_rockit.c +++ b/drivers/media/platform/rockchip/isp/isp_rockit.c @@ -203,7 +203,7 @@ int rkisp_rockit_buf_queue(struct rockit_cfg *input_rockit_cfg) isprk_buf->isp_buf.buff_addr[0], isprk_buf->isp_buf.buff_addr[1]); /* single sensor with pingpong buf, update next if need */ - if (stream->ispdev->hw_dev->is_single && + if (ispdev->hw_dev->is_single && !ispdev->is_suspend && stream->id != RKISP_STREAM_VIR && stream->id != RKISP_STREAM_LUMA && stream->streaming && !stream->next_buf) { From beb9974b6fb001eb197b613257ef57fd603db652 Mon Sep 17 00:00:00 2001 From: Lan Honglin Date: Tue, 26 Dec 2023 11:19:35 +0800 Subject: [PATCH 2/2] media: i2c: sc850sl: fix gain discontinuity issue sync update from 4.19 Change-Id: I432669771e6a3a5c9e07811f94f5bd77ed5b2e63 Signed-off-by: Lan Honglin --- drivers/media/i2c/sc850sl.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/media/i2c/sc850sl.c b/drivers/media/i2c/sc850sl.c index 9273346a7333..a2c904986423 100644 --- a/drivers/media/i2c/sc850sl.c +++ b/drivers/media/i2c/sc850sl.c @@ -73,7 +73,7 @@ #define SC850SL_REG_DGAIN 0x3e06 #define SC850SL_REG_AGAIN 0x3e08 #define SC850SL_REG_AGAIN_FINE 0x3e09 -//#define SC850SL_REG_DGAIN_FINE 0x3e07 +#define SC850SL_REG_DGAIN_FINE 0x3e07 //short fram gain reg #define SC850SL_SF_REG_AGAIN 0x3e12 @@ -370,7 +370,6 @@ static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] = {0x59fd, 0x3f}, {0x59fe, 0x38}, {0x59ff, 0x30}, - {0x0100, 0x01}, /* * [gain < 2x] {0x363c, 0x05}, * [gain >=2x] {0x363c, 0x07}, @@ -713,7 +712,7 @@ static void sc850sl_get_module_inf(struct sc850sl *sc850sl, } static void sc850sl_get_gain_reg(u32 val, u32 *again_reg, u32 *again_fine_reg, - u32 *dgain_reg) + u32 *dgain_reg, u32 *dgain_fine_reg) { u8 u8Reg0x3e09 = 0x40, u8Reg0x3e08 = 0x03; u32 aCoarseGain = 0; @@ -757,16 +756,19 @@ static void sc850sl_get_gain_reg(u32 val, u32 *again_reg, u32 *again_fine_reg, u8Reg0x3e09 = aFineGain; //dcg = 2.72  -->  2.72*1024=2785.28 u8Reg0x3e08 = (again > 200) ? (u8Reg0x3e08 | 0x20) : (u8Reg0x3e08 & 0x1f); - + *dgain_fine_reg = val * 128 / again / dgain; //dgain - if (dgain <= 1) { /*1x ~ 2x*/ + if (dgain < 2) { /*1x ~ 2x*/ *dgain_reg = 0x00; - } else if (dgain <= 2) { /*2x ~ 4x*/ + } else if (dgain < 4) { /*2x ~ 4x*/ *dgain_reg = 0x01; - } else if (dgain <= 4) { /*4x ~ 8x*/ + *dgain_fine_reg += (dgain - 2) * 64; + } else if (dgain < 8) { /*4x ~ 8x*/ *dgain_reg = 0x03; + *dgain_fine_reg += (dgain - 4) * 32; } else { *dgain_reg = 0x07; + *dgain_fine_reg = 0x80; } *again_reg = u8Reg0x3e08; @@ -1347,7 +1349,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) struct sc850sl, ctrl_handler); struct i2c_client *client = sc850sl->client; s64 max; - u32 again, again_fine, dgain; + u32 again, again_fine, dgain, dgain_fine; int ret = 0; u32 val; @@ -1355,7 +1357,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_VBLANK: /* Update max exposure while meeting expected vblanking */ - max = sc850sl->cur_mode->height + ctrl->val - 8; + max = sc850sl->cur_mode->height + ctrl->val - 4; __v4l2_ctrl_modify_range(sc850sl->exposure, sc850sl->exposure->minimum, max, sc850sl->exposure->step, @@ -1389,9 +1391,10 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_ANALOGUE_GAIN: if (sc850sl->cur_mode->hdr_mode != NO_HDR) goto out_ctrl; - sc850sl_get_gain_reg(ctrl->val, &again, &again_fine, &dgain); - dev_dbg(&client->dev, "recv_gain:%d set again 0x%x, again_fine 0x%x, set dgain 0x%x\n", - ctrl->val, again, again_fine, dgain); + sc850sl_get_gain_reg(ctrl->val, &again, &again_fine, &dgain, &dgain_fine); + dev_dbg(&client->dev, + "recv_gain:%d set again 0x%x, again_fine 0x%x, set dgain 0x%x, dgain_fine 0x%x\n", + ctrl->val, again, again_fine, dgain, dgain_fine); ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_AGAIN, @@ -1405,6 +1408,10 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) SC850SL_REG_DGAIN, SC850SL_REG_VALUE_08BIT, dgain); + ret |= sc850sl_write_reg(sc850sl->client, + SC850SL_REG_DGAIN_FINE, + SC850SL_REG_VALUE_08BIT, + dgain_fine); break; case V4L2_CID_VBLANK: ret = sc850sl_write_reg(sc850sl->client, SC850SL_REG_VTS,