media: rockchip: isp: suspend resume with rtt

Change-Id: Ibc86e518c3c464950d41166401c5ba2d9ee6c613
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2023-10-08 16:06:38 +08:00
committed by cain.cai
parent 9414fed2b7
commit 8f9f8dc62d
9 changed files with 130 additions and 12 deletions
+67 -1
View File
@@ -816,6 +816,15 @@ static int rkisp_get_reserved_mem(struct rkisp_device *isp_dev)
DMA_BIDIRECTIONAL);
ret = dma_mapping_error(dev, isp_dev->resmem_addr);
isp_dev->is_thunderboot = true;
isp_dev->is_rtt_suspend = false;
isp_dev->is_rtt_first = true;
if (device_property_read_bool(dev, "rtt-suspend")) {
isp_dev->is_rtt_suspend = true;
if (!isp_dev->hw_dev->is_thunderboot) {
isp_dev->is_thunderboot = false;
isp_dev->is_rtt_first = false;
}
}
dev_info(dev, "Allocated reserved memory, paddr: 0x%x\n", (u32)isp_dev->resmem_pa);
return ret;
}
@@ -1065,7 +1074,7 @@ static void rkisp_pm_complete(struct device *dev)
struct rkisp_hw_dev *hw = isp_dev->hw_dev;
struct rkisp_pipeline *p = &isp_dev->pipe;
struct rkisp_stream *stream;
int i, on = 1;
int i, on = 1, rd_mode = isp_dev->rd_mode;
if (isp_dev->isp_state & ISP_STOP) {
if (pm_runtime_active(dev) &&
@@ -1079,6 +1088,63 @@ static void rkisp_pm_complete(struct device *dev)
return;
}
if (isp_dev->is_rtt_suspend) {
rkisp_save_tb_info(isp_dev);
v4l2_info(&isp_dev->v4l2_dev,
"tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d mode:%d\n",
isp_dev->tb_head.enable, isp_dev->tb_head.complete,
isp_dev->tb_head.frm_total, isp_dev->tb_head.width,
isp_dev->tb_head.height, isp_dev->tb_head.camera_num,
isp_dev->tb_head.camera_index, isp_dev->tb_head.rtt_mode);
isp_dev->is_first_double = false;
switch (isp_dev->tb_head.rtt_mode) {
case RKISP_RTT_MODE_ONE_FRAME:
isp_dev->is_first_double = true;
/* switch to readback mode */
switch (rd_mode) {
case HDR_LINEX3_DDR:
isp_dev->rd_mode = HDR_RDBK_FRAME3;
break;
case HDR_LINEX2_DDR:
isp_dev->rd_mode = HDR_RDBK_FRAME2;
break;
default:
isp_dev->rd_mode = HDR_RDBK_FRAME1;
}
break;
case RKISP_RTT_MODE_MULTI_FRAME:
default:
if (isp_dev->tb_head.rtt_mode != RKISP_RTT_MODE_MULTI_FRAME)
v4l2_warn(&isp_dev->v4l2_dev,
"invalid rtt mode:%d, change to mode:%d\n",
isp_dev->tb_head.rtt_mode, RKISP_RTT_MODE_MULTI_FRAME);
if (!hw->is_single)
break;
/* switch to online mode for single sensor */
switch (rd_mode) {
case HDR_RDBK_FRAME3:
isp_dev->rd_mode = HDR_LINEX3_DDR;
break;
case HDR_RDBK_FRAME2:
isp_dev->rd_mode = HDR_LINEX2_DDR;
break;
default:
isp_dev->rd_mode = HDR_NORMAL;
}
}
isp_dev->hdr.op_mode = isp_dev->rd_mode;
if (rd_mode != isp_dev->rd_mode && hw->cur_dev_id == isp_dev->dev_id) {
rkisp_unite_write(isp_dev, CSI2RX_CTRL0,
SW_IBUF_OP_MODE(isp_dev->rd_mode), true);
if (IS_HDR_RDBK(isp_dev->rd_mode))
rkisp_unite_set_bits(isp_dev, CTRL_SWS_CFG, 0,
SW_MPIP_DROP_FRM_DIS, true);
else
rkisp_unite_clear_bits(isp_dev, CTRL_SWS_CFG,
SW_MPIP_DROP_FRM_DIS, true);
}
}
isp_dev->is_suspend = false;
isp_dev->isp_state = ISP_START | ISP_FRAME_END;
for (i = 0; i < RKISP_MAX_STREAM; i++) {
@@ -235,6 +235,10 @@ struct rkisp_device {
size_t resmem_size;
struct rkisp_thunderboot_resmem_head tb_head;
bool is_thunderboot;
/* first frame for rtt */
bool is_rtt_first;
/* suspend/resume with rtt */
bool is_rtt_suspend;
struct rkisp_tb_stream_info tb_stream_info;
unsigned int tb_addr_idx;
@@ -185,6 +185,28 @@ static void rkisp_params_vb2_buf_queue(struct vb2_buffer *vb)
spin_lock_irqsave(&params_vdev->config_lock, flags);
list_add_tail(&params_buf->queue, &params_vdev->params);
spin_unlock_irqrestore(&params_vdev->config_lock, flags);
if (params_vdev->dev->is_first_double) {
struct isp32_isp_params_cfg *params = params_buf->vaddr[0];
struct rkisp_buffer *buf;
if (!(params->module_cfg_update & ISP32_MODULE_RTT_FST))
return;
spin_lock_irqsave(&params_vdev->config_lock, flags);
while (!list_empty(&params_vdev->params)) {
buf = list_first_entry(&params_vdev->params,
struct rkisp_buffer, queue);
if (buf == params_buf)
break;
list_del(&buf->queue);
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
spin_unlock_irqrestore(&params_vdev->config_lock, flags);
dev_info(params_vdev->dev->dev,
"first params:%d for rtt resume\n", params->frame_id);
params_vdev->dev->is_first_double = false;
rkisp_trigger_read_back(params_vdev->dev, false, false, false);
}
}
static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
@@ -240,6 +240,11 @@ int rkisp_rockit_buf_done(struct rkisp_stream *stream, int cmd)
rockit_cfg->frame.u64PTS = stream->curr_buf->vb.vb2_buf.timestamp;
rockit_cfg->frame.u32TimeRef = stream->curr_buf->vb.sequence;
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"%s stream:%d seq:%d buf:0x%x done\n",
__func__, stream->id,
stream->curr_buf->vb.sequence,
stream->curr_buf->buff_addr[0]);
} else {
if (stream->ispdev->cap_dev.wrap_line &&
stream->id == RKISP_STREAM_MP) {
@@ -628,6 +628,9 @@ rkisp_stats_send_meas(struct rkisp_isp_stats_vdev *stats_vdev,
ops->get_vsm_stats(stats_vdev, cur_stat_buf);
}
if (cur_stat_buf && stats_vdev->dev->is_first_double)
cur_stat_buf->meas_type |= ISP32_STAT_RTT_FST;
if (is_dummy) {
spin_lock_irqsave(&stats_vdev->rd_lock, flags);
if (!list_empty(&stats_vdev->stat)) {
+17 -10
View File
@@ -873,6 +873,9 @@ static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current)
struct rkisp_buffer *buf;
u32 i, val;
if (!dev->is_rtt_first)
return;
for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) {
stream = &dev->dmarx_dev.stream[i];
if (!stream->ops)
@@ -956,7 +959,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
}
/* wait 2 frame to start isp for fast */
if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
if (dev->is_rtt_first && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq))
goto end;
if (max) {
@@ -1002,7 +1005,7 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
/* first frame handle twice for thunderboot
* first output stats to AIQ and wait new params to run second
*/
if (isp->is_pre_on && t.frame_id == 0) {
if (isp->is_rtt_first && t.frame_id == 0) {
isp->is_first_double = true;
isp->skip_frame = 1;
if (hw->unite != ISP_UNITE_ONE) {
@@ -1010,6 +1013,8 @@ static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd)
isp->is_frame_double = false;
}
rkisp_fast_switch_rx_buf(isp, false);
} else {
isp->is_rtt_first = false;
}
isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1;
}
@@ -1088,6 +1093,7 @@ void rkisp_check_idle(struct rkisp_device *dev, u32 irq)
if (dev->is_first_double) {
rkisp_fast_switch_rx_buf(dev, true);
dev->is_rtt_first = false;
dev->skip_frame = 0;
dev->irq_ends = 0;
return;
@@ -3024,7 +3030,8 @@ static int rkisp_rx_buf_pool_init(struct rkisp_device *dev,
pool->dbufs = dbufs;
v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev,
"%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs);
"%s type:0x%x first:%d dbufs[%d]:%p", __func__,
dbufs->type, dbufs->is_first, i, dbufs);
if (dbufs->is_resmem) {
dma = dbufs->dma;
@@ -3415,7 +3422,7 @@ static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
rkisp_get_info(isp_dev, arg);
break;
case RKISP_CMD_GET_TB_HEAD_V32:
if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) {
if (isp_dev->tb_head.complete != RKISP_TB_OK) {
ret = -EINVAL;
break;
}
@@ -3775,8 +3782,7 @@ void rkisp_unregister_isp_subdev(struct rkisp_device *isp_dev)
(cond) ? 0 : -ETIMEDOUT; \
})
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
void rkisp_save_tb_info(struct rkisp_device *isp_dev)
{
struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
void *resmem_va = phys_to_virt(isp_dev->resmem_pa);
@@ -3796,7 +3802,8 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
if (size && size < isp_dev->resmem_size) {
dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset,
size, DMA_FROM_DEVICE);
params_vdev->is_first_cfg = true;
if (isp_dev->is_rtt_first)
params_vdev->is_first_cfg = true;
if (isp_dev->isp_ver == ISP_V32) {
struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset;
@@ -3808,7 +3815,7 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
tmp->cfg.module_ens,
tmp->cfg.module_cfg_update);
}
if (param)
if (param && (isp_dev->isp_state & ISP_STOP))
params_vdev->ops->save_first_param(params_vdev, param);
} else if (size > isp_dev->resmem_size) {
v4l2_err(&isp_dev->v4l2_dev,
@@ -3819,6 +3826,7 @@ static void rkisp_save_tb_info(struct rkisp_device *isp_dev)
memcpy(&isp_dev->tb_head, head, sizeof(*head));
}
#ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP
void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
{
struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev;
@@ -3866,11 +3874,10 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev)
end:
head = &isp_dev->tb_head;
v4l2_info(&isp_dev->v4l2_dev,
"thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n",
"tb info en:%d comp:%d cnt:%d w:%d h:%d cam:%d idx:%d\n",
head->enable,
head->complete,
head->frm_total,
head->hdr_mode,
head->width,
head->height,
head->camera_num,
@@ -153,6 +153,8 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev);
static inline void rkisp_chk_tb_over(struct rkisp_device *isp_dev) {}
#endif
void rkisp_save_tb_info(struct rkisp_device *isp_dev);
void rkisp_mipi_isr(unsigned int mipi_mis, struct rkisp_device *dev);
void rkisp_mipi_v13_isr(unsigned int err1, unsigned int err2,
+8
View File
@@ -1968,6 +1968,12 @@ struct rkisp_isp2x_luma_buffer {
struct rkisp_mipi_luma luma[ISP2X_MIPI_RAW_MAX];
} __attribute__ ((packed));
enum {
RKISP_RTT_MODE_NORMAL = 0,
RKISP_RTT_MODE_MULTI_FRAME,
RKISP_RTT_MODE_ONE_FRAME,
};
/**
* struct rkisp_thunderboot_resmem_head
*/
@@ -1976,10 +1982,12 @@ struct rkisp_thunderboot_resmem_head {
__u16 complete;
__u16 frm_total;
__u16 hdr_mode;
__u16 rtt_mode;
__u16 width;
__u16 height;
__u16 camera_num;
__u16 camera_index;
__u16 md_flag;
__u32 exp_time[3];
__u32 exp_gain[3];
+2 -1
View File
@@ -52,7 +52,7 @@
#define ISP32_MODULE_CSM ISP3X_MODULE_CSM
#define ISP32_MODULE_CGC ISP3X_MODULE_CGC
#define ISP32_MODULE_VSM BIT_ULL(45)
#define ISP32_MODULE_RTT_FST BIT_ULL(62)
#define ISP32_MODULE_FORCE ISP3X_MODULE_FORCE
/* Measurement types */
@@ -70,6 +70,7 @@
#define ISP32_STAT_DHAZ ISP3X_STAT_DHAZ
#define ISP32_STAT_VSM BIT(18)
#define ISP32_STAT_INFO2DDR BIT(19)
#define ISP32_STAT_RTT_FST BIT(31)
#define ISP32_MESH_BUF_NUM ISP3X_MESH_BUF_NUM