media: rockchip: sync frame id and timestamp for isp and ispp read back mode

Change-Id: I0c7c8dc9ce574680332936f83e034ae8787aa687
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2020-05-30 14:57:30 +08:00
committed by Tao Huang
parent 7b01e68c33
commit ccc9c32708
12 changed files with 82 additions and 32 deletions

View File

@@ -51,8 +51,11 @@ static int frame_end(struct rkisp_bridge_device *dev)
unsigned long lock_flags = 0;
if (dev->cur_buf && dev->nxt_buf) {
dev->cur_buf->frame_id =
rkisp_dmarx_get_frame_id(dev->ispdev, false) + 1;
rkisp_dmarx_get_frame(dev->ispdev,
&dev->cur_buf->frame_id,
&dev->cur_buf->frame_timestamp,
false);
dev->cur_buf->frame_id++;
v4l2_subdev_call(sd, video, s_rx_buffer, dev->cur_buf, NULL);
dev->cur_buf = NULL;
}

View File

@@ -1540,7 +1540,7 @@ static int mi_frame_end(struct rkisp_stream *stream)
(!interlaced ||
(stream->u.sp.field_rec == RKISP_FIELD_ODD &&
stream->u.sp.field == RKISP_FIELD_EVEN))) {
u64 ns = ktime_get_ns();
u64 ns = 0;
/* Dequeue a filled buffer */
for (i = 0; i < isp_fmt->mplanes; i++) {
@@ -1552,11 +1552,14 @@ static int mi_frame_end(struct rkisp_stream *stream)
}
if (stream->id == RKISP_STREAM_MP ||
stream->id == RKISP_STREAM_SP)
stream->curr_buf->vb.sequence =
rkisp_dmarx_get_frame_id(isp_dev, false);
rkisp_dmarx_get_frame(isp_dev,
&stream->curr_buf->vb.sequence,
&ns, false);
else
stream->curr_buf->vb.sequence =
atomic_read(&stream->sequence) - 1;
if (!ns)
ns = ktime_get_ns();
stream->curr_buf->vb.vb2_buf.timestamp = ns;
if (!IS_HDR_RDBK(isp_dev->hdr.op_mode)) {

View File

@@ -429,8 +429,9 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm)
struct rkisp_device *dev = csi->ispdev;
void __iomem *addr = dev->base_addr + CSI2RX_CTRL0;
struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev;
u32 cur_frame_id = rkisp_dmarx_get_frame_id(dev, true);
u32 cur_frame_id;
rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true);
if (dma2frm > 2)
dma2frm = 2;
memset(csi->filt_state, 0, sizeof(csi->filt_state));
@@ -478,19 +479,20 @@ int rkisp_csi_trigger_event(struct rkisp_csi_device *csi, void *arg)
* start read back direct
*/
csi->is_first = false;
dev->dmarx_dev.pre_frame_id =
dev->dmarx_dev.cur_frame_id;
dev->dmarx_dev.cur_frame_id = trigger->frame_id;
dev->dmarx_dev.pre_frame = dev->dmarx_dev.cur_frame;
dev->dmarx_dev.cur_frame.id = trigger->frame_id;
dev->dmarx_dev.cur_frame.timestamp = trigger->frame_timestamp;
times = trigger->times;
csi->is_isp_end = false;
} else if (csi->is_isp_end && !kfifo_is_empty(fifo)) {
/* isp idle and events in queue
* out fifo then start read back
* new event in fifo
*/
if (kfifo_out(fifo, &t, sizeof(t))) {
dev->dmarx_dev.pre_frame_id =
dev->dmarx_dev.cur_frame_id;
dev->dmarx_dev.cur_frame_id = t.frame_id;
dev->dmarx_dev.pre_frame = dev->dmarx_dev.cur_frame;
dev->dmarx_dev.cur_frame.id = t.frame_id;
dev->dmarx_dev.cur_frame.timestamp = t.frame_timestamp;
times = t.times;
}
if (trigger)

View File

@@ -934,21 +934,31 @@ static int dmarx_init(struct rkisp_device *dev, u32 id)
RKISP_ISP_PAD_SINK, stream->linked);
}
u32 rkisp_dmarx_get_frame_id(struct rkisp_device *dev, bool sync)
void rkisp_dmarx_get_frame(struct rkisp_device *dev,
u32 *id, u64 *timestamp, bool sync)
{
unsigned long flag = 0;
u32 id;
u64 frame_timestamp = 0;
u32 frame_id = 0;
if (!dev->dmarx_dev.trigger)
return atomic_read(&dev->isp_sdev.frm_sync_seq) - 1;
if (!dev->dmarx_dev.trigger && id) {
*id = atomic_read(&dev->isp_sdev.frm_sync_seq) - 1;
return;
}
spin_lock_irqsave(&dev->csi_dev.rdbk_lock, flag);
if (sync || dev->csi_dev.is_isp_end)
id = dev->dmarx_dev.cur_frame_id;
else
id = dev->dmarx_dev.pre_frame_id;
if (sync || dev->csi_dev.is_isp_end) {
frame_id = dev->dmarx_dev.cur_frame.id;
frame_timestamp = dev->dmarx_dev.cur_frame.timestamp;
} else {
frame_id = dev->dmarx_dev.pre_frame.id;
frame_timestamp = dev->dmarx_dev.pre_frame.timestamp;
}
spin_unlock_irqrestore(&dev->csi_dev.rdbk_lock, flag);
return id;
if (id)
*id = frame_id;
if (timestamp)
*timestamp = frame_timestamp;
}
int rkisp_register_dmarx_vdev(struct rkisp_device *dev)

View File

@@ -26,23 +26,29 @@ enum rkisp_dmarx_trigger {
T_MANUAL,
};
struct rkisp_dmarx_frame {
u64 timestamp;
u32 id;
};
/*
* struct rkisp_dmarx_device
* trigger: read back mode
* cur_frame_id: current frame id
* pre_frame_id: previous frame id
* cur_frame: current frame id and timestamp in ns
* pre_frame: previous frame id and timestamp in ns
*/
struct rkisp_dmarx_device {
struct rkisp_device *ispdev;
struct rkisp_stream stream[RKISP_MAX_DMARX_STREAM];
enum rkisp_dmarx_trigger trigger;
u32 cur_frame_id;
u32 pre_frame_id;
struct rkisp_dmarx_frame cur_frame;
struct rkisp_dmarx_frame pre_frame;
};
void rkisp_dmarx_isr(u32 mis_val, struct rkisp_device *dev);
void rkisp2_rawrd_isr(u32 mis_val, struct rkisp_device *dev);
u32 rkisp_dmarx_get_frame_id(struct rkisp_device *dev, bool sync);
void rkisp_dmarx_get_frame(struct rkisp_device *dev,
u32 *id, u64 *timestamp, bool sync);
void rkisp_unregister_dmarx_vdev(struct rkisp_device *dev);
int rkisp_register_dmarx_vdev(struct rkisp_device *dev);
#endif /* _RKISP_DMARX_H */

View File

@@ -32,6 +32,8 @@ struct rkisp_ispp_mode {
struct rkisp_ispp_buf {
struct list_head list;
struct dma_buf *dbuf[GROUP_BUF_MAX];
/* timestamp in ns */
u64 frame_timestamp;
u32 frame_id;
};

View File

@@ -4225,8 +4225,9 @@ rkisp_params_isr_v2x(struct rkisp_isp_params_vdev *params_vdev,
u32 isp_mis)
{
struct rkisp_device *dev = params_vdev->dev;
u32 cur_frame_id = rkisp_dmarx_get_frame_id(dev, true);
u32 cur_frame_id;
rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true);
if (isp_mis & CIF_ISP_V_START) {
if (!params_vdev->cur_buf)
return;

View File

@@ -1337,7 +1337,7 @@ rkisp_stats_isr_v2x(struct rkisp_isp_stats_vdev *stats_vdev,
struct rkisp_device *dev = stats_vdev->dev;
u32 isp_mis_tmp = 0;
struct rkisp_isp_readout_work work;
u32 cur_frame_id = rkisp_dmarx_get_frame_id(stats_vdev->dev, true);
u32 cur_frame_id;
u32 iq_isr_mask = ISP2X_SIAWB_DONE | ISP2X_SIAF_FIN |
ISP2X_YUVAE_END | ISP2X_SIHST_RDY | ISP2X_AFM_SUM_OF | ISP2X_AFM_LUM_OF;
u32 iq_3a_mask = 0;
@@ -1345,6 +1345,7 @@ rkisp_stats_isr_v2x(struct rkisp_isp_stats_vdev *stats_vdev,
u32 wr_buf_idx;
u32 temp_isp_ris, temp_isp3a_ris;
rkisp_dmarx_get_frame(stats_vdev->dev, &cur_frame_id, NULL, true);
#ifdef LOG_ISR_EXE_TIME
ktime_t in_t = ktime_get();
#endif

View File

@@ -45,6 +45,8 @@ struct rkispp_dummy_buffer {
dma_addr_t dma_addr;
void *mem_priv;
void *vaddr;
/* timestamp in ns */
u64 timestamp;
u32 size;
u32 id;
bool is_need_vaddr;

View File

@@ -37,6 +37,8 @@ struct rkispp_subdev {
struct v4l2_mbus_framefmt in_fmt;
struct isppsd_fmt out_fmt;
atomic_t frm_sync_seq;
/* timestamp in ns */
u64 frame_timestamp;
enum rkispp_state state;
};

View File

@@ -299,7 +299,12 @@ static int rkispp_frame_end(struct rkispp_stream *stream)
int i = 0;
if (stream->curr_buf) {
u64 ns = ktime_get_ns();
u64 ns;
if (dev->isp_mode & ISP_ISPP_QUICK || dev->inp == INP_DDR)
ns = ktime_get_ns();
else
ns = dev->ispp_sdev.frame_timestamp;
for (i = 0; i < fmt->mplanes; i++) {
u32 payload_size =
@@ -1865,6 +1870,8 @@ static void fec_work_event(struct rkispp_device *dev,
if (vdev->fec.cur_rd && !is_quick) {
seq = vdev->fec.cur_rd->id;
dev->ispp_sdev.frame_timestamp =
vdev->fec.cur_rd->timestamp;
atomic_set(&dev->ispp_sdev.frm_sync_seq, seq);
}
writel(FEC_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
@@ -2013,13 +2020,19 @@ static void nr_work_event(struct rkispp_device *dev,
if (is_start) {
u32 seq = 0;
u64 timestamp = 0;
if (vdev->nr.cur_rd) {
seq = vdev->nr.cur_rd->frame_id;
if (vdev->nr.cur_wr)
timestamp = vdev->nr.cur_rd->frame_timestamp;
if (vdev->nr.cur_wr) {
vdev->nr.cur_wr->id = seq;
if (!is_fec_en && !is_quick)
vdev->nr.cur_wr->timestamp = timestamp;
}
if (!is_fec_en && !is_quick) {
dev->ispp_sdev.frame_timestamp = timestamp;
atomic_set(&dev->ispp_sdev.frm_sync_seq, seq);
}
}
writel(OTHER_FORCE_UPD, base + RKISPP_CTRL_UPDATE);
@@ -2188,8 +2201,11 @@ static void tnr_work_event(struct rkispp_device *dev,
if (vdev->tnr.cur_rd) {
seq = vdev->tnr.cur_rd->frame_id;
if (vdev->tnr.cur_wr)
if (vdev->tnr.cur_wr) {
vdev->tnr.cur_wr->frame_id = seq;
vdev->tnr.cur_wr->frame_timestamp =
vdev->tnr.cur_rd->frame_timestamp;
}
}
writel(TNR_FORCE_UPD, base + RKISPP_CTRL_UPDATE);

View File

@@ -142,6 +142,8 @@
#define ISP2X_LDCH_MESH_XY_NUM 0x80000
struct isp2x_csi_trigger {
/* timestamp in ns */
u64 frame_timestamp;
u32 frame_id;
int times;
} __attribute__ ((packed));