diff --git a/drivers/media/platform/rockchip/isp/common.h b/drivers/media/platform/rockchip/isp/common.h index 18314365de96..c7acd5030972 100644 --- a/drivers/media/platform/rockchip/isp/common.h +++ b/drivers/media/platform/rockchip/isp/common.h @@ -49,6 +49,8 @@ #include #include +#include "isp_ispp.h" + #define RKISP_DEFAULT_WIDTH 800 #define RKISP_DEFAULT_HEIGHT 600 @@ -143,6 +145,7 @@ extern bool rkisp_monitor; extern bool rkisp_irq_dbg; extern bool rkisp_buf_dbg; extern u64 rkisp_debug_reg; +extern unsigned int rkisp_vicap_buf[DEV_MAX]; extern struct platform_driver rkisp_plat_drv; static inline diff --git a/drivers/media/platform/rockchip/isp/csi.c b/drivers/media/platform/rockchip/isp/csi.c index d8a7997bff9c..9b6915882cb4 100644 --- a/drivers/media/platform/rockchip/isp/csi.c +++ b/drivers/media/platform/rockchip/isp/csi.c @@ -541,7 +541,7 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) ret = rkisp_csi_get_hdr_cfg(dev, &hdr_cfg); if (dev->isp_inp & INP_CIF) { struct rkisp_vicap_mode mode; - int buf_cnt; + int buf_cnt = 0; memset(&mode, 0, sizeof(mode)); mode.name = dev->name; @@ -585,14 +585,16 @@ int rkisp_csi_config_patch(struct rkisp_device *dev) } if (dev->hdr.op_mode != HDR_NORMAL) { buf_cnt = 1; - v4l2_subdev_call(mipi_sensor, core, ioctl, - RKISP_VICAP_CMD_INIT_BUF, &buf_cnt); } } else if (mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) { - buf_cnt = RKISP_VICAP_BUF_CNT; + if (dev->vicap_buf_cnt) + buf_cnt = dev->vicap_buf_cnt; + else + buf_cnt = RKISP_VICAP_BUF_CNT; + } + if (buf_cnt) v4l2_subdev_call(mipi_sensor, core, ioctl, RKISP_VICAP_CMD_INIT_BUF, &buf_cnt); - } } else { dev->hdr.op_mode = hdr_cfg.hdr_mode; } diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 5c2fa4b5be65..301a0341bae8 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -95,6 +95,10 @@ static unsigned int rkisp_wrap_line; module_param_named(wrap_line, rkisp_wrap_line, uint, 0644); MODULE_PARM_DESC(wrap_line, "rkisp wrap line for mpp"); +unsigned int rkisp_vicap_buf[DEV_MAX]; +module_param_array_named(vicap_raw_buf, rkisp_vicap_buf, uint, NULL, 0644); +MODULE_PARM_DESC(vicap_raw_buf, "rkisp and vicap auto readback mode raw buf count"); + static DEFINE_MUTEX(rkisp_dev_mutex); static LIST_HEAD(rkisp_device_list); @@ -276,14 +280,27 @@ static int rkisp_pipeline_open(struct rkisp_pipeline *p, struct media_entity *me, bool prepare) { - int ret; struct rkisp_device *dev = container_of(p, struct rkisp_device, pipe); + struct rkisp_hw_dev *hw = dev->hw_dev; + int ret; if (WARN_ON(!p || !me)) return -EINVAL; if (atomic_inc_return(&p->power_cnt) > 1) return 0; + if (hw->is_assigned_clk) + rkisp_clk_dbg = true; + if (!(dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2))) { + dev->is_rdbk_auto = rkisp_rdbk_auto; + if (dev->is_aiisp_en) + dev->is_rdbk_auto = true; + if (rkisp_vicap_buf[dev->dev_id] > RKISP_VICAP_BUF_CNT_MAX) + rkisp_vicap_buf[dev->dev_id] = RKISP_VICAP_BUF_CNT_MAX; + dev->vicap_buf_cnt = rkisp_vicap_buf[dev->dev_id]; + } + dev->cap_dev.wait_line = rkisp_wait_line; + /* go through media graphic and get subdevs */ if (prepare) { ret = __isp_pipeline_prepare(p, me); @@ -317,6 +334,7 @@ static int rkisp_pipeline_close(struct rkisp_pipeline *p) dev->hw_dev->isp_size[dev->dev_id].is_on = false; if (dev->hw_dev->is_runing && (dev->isp_ver >= ISP_V30) && !rkisp_clk_dbg) dev->hw_dev->is_dvfs = true; + dev->is_rdbk_auto = false; return 0; } @@ -1020,16 +1038,7 @@ static int __maybe_unused rkisp_runtime_resume(struct device *dev) rkisp_update_sensor_info(isp_dev) >= 0) _set_pipeline_default_fmt(isp_dev, false); - if (isp_dev->hw_dev->is_assigned_clk) - rkisp_clk_dbg = true; - - if (isp_dev->hw_dev->unite == ISP_UNITE_ONE && - !(isp_dev->isp_inp & INP_RAWRD2)) - rkisp_rdbk_auto = true; - - isp_dev->cap_dev.wait_line = rkisp_wait_line; isp_dev->cap_dev.wrap_line = rkisp_wrap_line; - isp_dev->is_rdbk_auto = rkisp_rdbk_auto; mutex_lock(&isp_dev->hw_dev->dev_lock); ret = pm_runtime_get_sync(isp_dev->hw_dev->dev); mutex_unlock(&isp_dev->hw_dev->dev_lock); diff --git a/drivers/media/platform/rockchip/isp/dev.h b/drivers/media/platform/rockchip/isp/dev.h index 5c338a047635..5c5e17ab303f 100644 --- a/drivers/media/platform/rockchip/isp/dev.h +++ b/drivers/media/platform/rockchip/isp/dev.h @@ -282,6 +282,7 @@ struct rkisp_device { u32 rd_mode; int sw_rd_cnt; + u32 vicap_buf_cnt; struct rkisp_rx_buf_pool pv_pool[RKISP_RX_BUF_POOL_MAX]; struct mutex buf_lock; diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index d0d6d85c76ff..a64686764114 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -1820,6 +1820,7 @@ static int rkisp_config_isp(struct rkisp_device *dev) rkisp_update_regs(dev, CIF_ISP_OUT_H_SIZE, CIF_ISP_OUT_V_SIZE); } + dev->is_aiisp_upd = dev->is_aiisp_en; rkisp_config_cmsk(dev); rkisp_config_aiisp(dev); return 0; @@ -3730,6 +3731,32 @@ static void rkisp_aiisp_rd_start(struct rkisp_device *dev) "%s 0x%x:0x%x\n", __func__, ISP39_AIISP_LINE_CNT, val); } +static int rkisp_set_offline_raw_buf_cnt(struct rkisp_device *dev, int *cnt) +{ + if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2)) { + v4l2_warn(&dev->v4l2_dev, + "offline raw to user, buf count no set by this\n"); + return -EINVAL; + } + dev->vicap_buf_cnt = *cnt; + rkisp_vicap_buf[dev->dev_id] = *cnt; + return 0; +} + +static int rkisp_get_offline_raw_buf_cnt(struct rkisp_device *dev, int *cnt) +{ + if (dev->isp_inp & (INP_RAWRD0 | INP_RAWRD2)) { + v4l2_warn(&dev->v4l2_dev, + "offline raw to user, buf count no get by this\n"); + return -EINVAL; + } + if (!dev->vicap_buf_cnt) + *cnt = RKISP_VICAP_BUF_CNT; + else + *cnt = dev->vicap_buf_cnt; + return 0; +} + static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct rkisp_device *isp_dev = sd_to_isp_dev(sd); @@ -3883,6 +3910,12 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKISP_CMD_AIISP_RD_START: rkisp_aiisp_rd_start(isp_dev); break; + case RKISP_CMD_SET_OFFLINE_RAW_BUFCNT: + ret = rkisp_set_offline_raw_buf_cnt(isp_dev, arg); + break; + case RKISP_CMD_GET_OFFLINE_RAW_BUFCNT: + ret = rkisp_get_offline_raw_buf_cnt(isp_dev, arg); + break; default: ret = -ENOIOCTLCMD; } @@ -3972,6 +4005,14 @@ static long rkisp_compat_ioctl32(struct v4l2_subdev *sd, size = sizeof(struct rkisp_aiisp_cfg); cp_t_us = true; break; + case RKISP_CMD_SET_OFFLINE_RAW_BUFCNT: + size = sizeof(int); + cp_f_us = true; + break; + case RKISP_CMD_GET_OFFLINE_RAW_BUFCNT: + size = sizeof(int); + cp_t_us = true; + break; default: return -ENOIOCTLCMD; } diff --git a/include/uapi/linux/rk-isp2-config.h b/include/uapi/linux/rk-isp2-config.h index 46c04d99b450..549d54dce401 100644 --- a/include/uapi/linux/rk-isp2-config.h +++ b/include/uapi/linux/rk-isp2-config.h @@ -71,6 +71,15 @@ #define RKISP_CMD_AIISP_RD_START \ _IO('V', BASE_VIDIOC_PRIVATE + 18) +/* BASE_VIDIOC_PRIVATE + 19 for RKISP_CMD_GET_TB_HEAD_V33 */ +/* BASE_VIDIOC_PRIVATE + 20 for RKISP_CMD_SET_TB_HEAD_V33 */ + +#define RKISP_CMD_SET_OFFLINE_RAW_BUFCNT \ + _IOW('V', BASE_VIDIOC_PRIVATE + 21, int) + +#define RKISP_CMD_GET_OFFLINE_RAW_BUFCNT \ + _IOR('V', BASE_VIDIOC_PRIVATE + 22, int) + /****************ISP VIDEO IOCTL******************************/ #define RKISP_CMD_GET_CSI_MEMORY_MODE \ @@ -119,6 +128,7 @@ _IOW('V', BASE_VIDIOC_PRIVATE + 114, struct rkmodule_hdr_cfg) /* BASE_VIDIOC_PRIVATE + 115 for RKISP_CMD_GET_PARAMS_V39 */ +/* BASE_VIDIOC_PRIVATE + 116 for RKISP_CMD_GET_PARAMS_V33 */ /**********************EVENT_PRIVATE***************************/ #define RKISP_V4L2_EVENT_AIISP_LINECNT (V4L2_EVENT_PRIVATE_START + 1)