From 62ed11eb369fbdbd10b865ddf8538c2979239efc Mon Sep 17 00:00:00 2001 From: Mingwei Yan Date: Mon, 17 Mar 2025 10:01:44 +0800 Subject: [PATCH] media: rockchip: vpss: offline wrap add reset and read hw seq Signed-off-by: Mingwei Yan Change-Id: I5d8a80492896e0e57c3efac3c5bf55c4e83c78ec --- drivers/media/platform/rockchip/vpss/hw.c | 2 ++ drivers/media/platform/rockchip/vpss/hw.h | 1 + .../media/platform/rockchip/vpss/regs_v20.h | 7 +++++ .../rockchip/vpss/vpss_offline_rockit.c | 1 + .../platform/rockchip/vpss/vpss_offline_v20.c | 27 +++++++++++++++++++ include/uapi/linux/rk-vpss-config.h | 3 +++ 6 files changed, 41 insertions(+) diff --git a/drivers/media/platform/rockchip/vpss/hw.c b/drivers/media/platform/rockchip/vpss/hw.c index 61e16950656b..5b48d716083c 100644 --- a/drivers/media/platform/rockchip/vpss/hw.c +++ b/drivers/media/platform/rockchip/vpss/hw.c @@ -936,6 +936,7 @@ static int rkvpss_hw_probe(struct platform_device *pdev) hw_dev->is_shutdown = false; hw_dev->is_mmu = is_iommu_enable(dev); hw_dev->is_suspend = false; + hw_dev->is_first = false; ret = of_reserved_mem_device_init(dev); if (ret) { is_mem_reserved = false; @@ -1027,6 +1028,7 @@ static int __maybe_unused rkvpss_hw_runtime_resume(struct device *dev) memset(buf, 0, RKVPSS_SW_REG_SIZE_MAX); memcpy_fromio(buf, base, RKVPSS_SW_REG_SIZE); } + hw_dev->is_first = true; } else { rkvpss_hw_reg_restore(hw_dev); hw_dev->is_suspend = false; diff --git a/drivers/media/platform/rockchip/vpss/hw.h b/drivers/media/platform/rockchip/vpss/hw.h index f694f7a3b31f..2b58e3649a4d 100644 --- a/drivers/media/platform/rockchip/vpss/hw.h +++ b/drivers/media/platform/rockchip/vpss/hw.h @@ -68,6 +68,7 @@ struct rkvpss_hw_dev { bool is_dma_contig; bool is_shutdown; bool is_suspend; + bool is_first; }; #ifdef CONFIG_VIDEO_ROCKCHIP_VPSS_V10 diff --git a/drivers/media/platform/rockchip/vpss/regs_v20.h b/drivers/media/platform/rockchip/vpss/regs_v20.h index c214ebb3f47f..b9c1b0b13e30 100644 --- a/drivers/media/platform/rockchip/vpss/regs_v20.h +++ b/drivers/media/platform/rockchip/vpss/regs_v20.h @@ -7,6 +7,8 @@ /* VPSS */ #define RKVPSS2X_VPSS_BASE 0x0000 #define RKVPSS2X_VPSS_PIPE_ACK2 (RKVPSS2X_VPSS_BASE + 0xb8) +#define RKVPSS2X_VPSS_FRAME_CNT (RKVPSS2X_VPSS_BASE + 0xc8) +#define RKVPSS2X_VPSS2ENC_DEBUG (RKVPSS2X_VPSS_BASE + 0xcc) /* CMSC identical */ @@ -259,6 +261,11 @@ #define RKVPSS2X_RATIO4_IN_FRM_END BIT(18) #define RKVPSS2X_RATIO5_IN_FRM_END BIT(19) +/* VPSS2ENC_DEBUG */ +#define RKVPSS2X_RO_VPSS2ENC_LINE_CNT(x) ((x) & 0x3fff) +#define RKVPSS2X_RO_VPSS2ENC_FRM_CNT(x) (((x) & 0xffffff) >> 16) + + /* VPSS_CTRL_SHD */ #define RKVPSS2X_VPSS2ENC_PATH_EN_SHD BIT(11) diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline_rockit.c b/drivers/media/platform/rockchip/vpss/vpss_offline_rockit.c index 2296dd2c367d..acb922cb8b20 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline_rockit.c +++ b/drivers/media/platform/rockchip/vpss/vpss_offline_rockit.c @@ -95,6 +95,7 @@ long vpss_rockit_action(int *file_id, unsigned int cmd, void *arg) case RKVPSS_CMD_CHECKPARAMS: case RKVPSS_CMD_WRAP_DVBM_INIT: case RKVPSS_CMD_WRAP_DVBM_DEINIT: + case RKVPSS_CMD_GET_WRAP_SEQ: if (!rkvpss_ofl_check_file_id(global_ofl, *file_id)) { v4l2_err(&global_ofl->v4l2_dev, "file_id error\n"); ret = -EINVAL; diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c b/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c index 1660484f9b1a..fb00305e0a13 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c +++ b/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c @@ -1776,6 +1776,8 @@ static int rkvpss_ofl_run(struct rkvpss_offline_dev *ofl, if (!ret) { v4l2_err(&ofl->v4l2_dev, "working timeout\n"); ret = -EAGAIN; + if (cfg->input.dmabuf) + rkvpss_soft_reset(ofl->hw); } else { ret = 0; } @@ -2397,6 +2399,28 @@ static void rkvpss_ofl_wrap_dvbm_deinit(struct rkvpss_offline_dev *ofl, int *id) rkvpss_ofl_dvbm_deinit(ofl, *id); } +static void rkvpss_ofl_get_wrap_seq(struct rkvpss_offline_dev *ofl, int *seq) +{ + struct rkvpss_hw_dev *hw = ofl->hw; + u32 mask, val; + + v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev, "dev_id:%d\n", *seq); + + mask = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_SENSOR_ID(7); + val = RKVPSS_VPSS2ENC_SEL | RKVPSS2X_SENSOR_ID(*seq); + rkvpss_hw_set_bits(hw, RKVPSS_VPSS_CTRL, mask, val); + + if (hw->is_first) { + hw->is_first = false; + rkvpss_hw_write(hw, RKVPSS2X_VPSS2ENC_DEBUG, 0x1); + v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev, "wrap is first\n"); + } + + *seq = RKVPSS2X_RO_VPSS2ENC_FRM_CNT(rkvpss_hw_read(ofl->hw, RKVPSS2X_VPSS2ENC_DEBUG)); + + v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev, "hw frmame coount:%d\n", *seq); +} + long rkvpss_ofl_action(struct rkvpss_offline_dev *ofl, int file_id, unsigned int cmd, void *arg) { @@ -2432,6 +2456,9 @@ long rkvpss_ofl_action(struct rkvpss_offline_dev *ofl, case RKVPSS_CMD_WRAP_DVBM_DEINIT: rkvpss_ofl_wrap_dvbm_deinit(ofl, arg); break; + case RKVPSS_CMD_GET_WRAP_SEQ: + rkvpss_ofl_get_wrap_seq(ofl, arg); + break; default: ret = -EFAULT; } diff --git a/include/uapi/linux/rk-vpss-config.h b/include/uapi/linux/rk-vpss-config.h index 530197b17c7c..07af012e9aa1 100644 --- a/include/uapi/linux/rk-vpss-config.h +++ b/include/uapi/linux/rk-vpss-config.h @@ -101,6 +101,9 @@ #define RKVPSS_CMD_WRAP_DVBM_DEINIT \ _IOW('V', BASE_VIDIOC_PRIVATE + 104, int *) +#define RKVPSS_CMD_GET_WRAP_SEQ \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 105, int *) + /********************************************************************/ /* struct rkvpss_mirror_flip