clear-pkgs-linux-iot-lts2018/1088-media-ici-Calculate-se...

213 lines
7.2 KiB
Diff
Raw Permalink Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Puunithaaraj Gopal <puunithaaraj.gopal@intel.com>
Date: Thu, 11 Apr 2019 16:42:32 +0800
Subject: [PATCH] media: ici: Calculate sequence id and timestamp for each
frame
Sequence id and timestamp of each frame should be calculated
during each FRAME_SOF event. Sequence id used during field
weaving operation to reorder the frame.
Sequence id of a frame can be access via frame_sequence_id member
in ici_frame_info object and timestamp of a frame can be
access via frame_timestamp in ici_frame_info object.
Change-Id: I08cd4860776043392e4fa6bb2ea91e9cd923a861
Tracked-On: PKT-2287
Tracked-On: HSDES-1507140140
Signed-off-by: Puunithaaraj Gopal <puunithaaraj.gopal@intel.com>
---
drivers/media/pci/intel/ici/ici-isys-csi2.c | 18 ++++++
.../media/pci/intel/ici/ici-isys-frame-buf.c | 64 +++++++++++++++++++
.../media/pci/intel/ici/ici-isys-pipeline.h | 3 +
drivers/media/pci/intel/ici/ici-isys-stream.c | 3 +
drivers/media/pci/intel/ici/ici-isys.c | 10 +++
drivers/media/pci/intel/ici/ici-isys.h | 1 -
6 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/drivers/media/pci/intel/ici/ici-isys-csi2.c b/drivers/media/pci/intel/ici/ici-isys-csi2.c
2020-10-27 02:14:06 +08:00
index 22cbc4ce10fd..d27119a9c5ef 100644
--- a/drivers/media/pci/intel/ici/ici-isys-csi2.c
+++ b/drivers/media/pci/intel/ici/ici-isys-csi2.c
@@ -248,9 +248,27 @@ static void ici_isys_csi2_sof_event(struct ici_isys_csi2
*csi2, unsigned int vc)
{
unsigned long flags;
+ struct ici_isys_pipeline *ip;
+ unsigned int i;
spin_lock_irqsave(&csi2->isys->lock, flags);
csi2->in_frame = true;
+
+ for(i = 0; i < INTEL_IPU4_ISYS_MAX_STREAMS; i++) {
+ if (csi2->isys->ici_pipes[i] &&
+ csi2->isys->ici_pipes[i]->vc == vc &&
+ &csi2->isys->ici_pipes[i]->csi2->asd[vc] == &csi2->asd[vc]) {
+ ip = csi2->isys->ici_pipes[i];
+ break;
+ }
+ }
+
+ if (!ip) {
+ spin_unlock_irqrestore(&csi2->isys->lock, flags);
+ return;
+ }
+
+ atomic_inc(&ip->sequence);
spin_unlock_irqrestore(&csi2->isys->lock, flags);
}
diff --git a/drivers/media/pci/intel/ici/ici-isys-frame-buf.c b/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
2020-10-27 02:14:06 +08:00
index 1dc8899e5e7b..3d2e5c96e184 100644
--- a/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
+++ b/drivers/media/pci/intel/ici/ici-isys-frame-buf.c
@@ -22,6 +22,49 @@
container_of(put_entry, struct ici_frame_buf_wrapper,\
put_frame_entry)
+static u64 get_sof_ns_delta(struct ici_isys_pipeline *ip,
+ struct ia_css_isys_resp_info *info)
+{
+ struct ipu_bus_device *adev = ip->isys->adev;
+ struct ipu_device *isp = adev->isp;
+ u64 delta, tsc_now;
+
+ if(!ipu_buttress_tsc_read(isp, &tsc_now))
+ delta = tsc_now -
+ ((u64) info->timestamp[1] << 32 | info->timestamp[0]);
+ else
+ delta = 0;
+
+ return ipu_buttress_tsc_ticks_to_ns(delta);
+}
+
+static unsigned int
+get_sof_sequence_by_timestamp(struct ici_isys_pipeline *ip,
+ struct ia_css_isys_resp_info *info)
+{
+ struct ici_isys *isys = ip->isys;
+ u64 time = (u64) info->timestamp[1] << 32 | info->timestamp[0];
+ unsigned int i;
+
+ for (i = 0; i < ICI_ISYS_MAX_PARALLEL_SOF; i++)
+ if (time == ip->seq[i].timestamp) {
+ dev_dbg(&isys->adev->dev,
+ "sof: using sequence number %u for timestamp 0 x%16.16llx\n",
+ ip->seq[i].sequence, time);
+ return ip->seq[i].sequence;
+ }
+
+ dev_dbg(&isys->adev->dev, "SOF: looking for 0x%16.16llx\n", time);
+
+ for (i = 0; i < ICI_ISYS_MAX_PARALLEL_SOF; i++)
+ dev_dbg(&isys->adev->dev,
+ "SOF: sequence %u, timestamp value 0x%16.16llx\n",
+ ip->seq[i].sequence, ip->seq[i].timestamp);
+
+ dev_dbg(&isys->adev->dev, "SOF sequence number not found\n");
+ return 0;
+}
+
static struct ici_frame_buf_wrapper
*ici_frame_buf_lookup(struct ici_isys_frame_buf_list
*buf_list,
@@ -639,6 +682,25 @@ static void frame_buf_done(
buf->frame_info.frame_planes[0].mem.userptr);
}
+void ici_isys_buf_calc_sequence_time(struct ici_frame_buf_wrapper *buf,
+ struct ici_isys_pipeline *ip,
+ struct ia_css_isys_resp_info *info)
+{
+ u64 ns;
+ u32 sequence;
+ struct timespec ts_now;
+
+ ns = ktime_get_ns();
+ ns -= get_sof_ns_delta(ip, info);
+ sequence = get_sof_sequence_by_timestamp(ip,info);
+
+ ts_now = ns_to_timespec(ns);
+
+ buf->frame_info.frame_timestamp.tv_sec = ts_now.tv_sec;
+ buf->frame_info.frame_timestamp.tv_usec = ts_now.tv_nsec / NSEC_PER_USEC;
+ buf->frame_info.frame_sequence_id = sequence;
+}
+
void ici_isys_frame_buf_ready(struct ici_isys_pipeline
*ip,
struct ia_css_isys_resp_info *info)
@@ -678,6 +740,8 @@ void ici_isys_frame_buf_ready(struct ici_isys_pipeline
list_del(&buf->node);
spin_unlock_irqrestore(&buf_list->lock, flags);
+ ici_isys_buf_calc_sequence_time(buf, ip, info);
+
/*
* For interlaced buffers, the notification to user space
* is postponed to capture_done event since the field
diff --git a/drivers/media/pci/intel/ici/ici-isys-pipeline.h b/drivers/media/pci/intel/ici/ici-isys-pipeline.h
2020-10-27 02:14:06 +08:00
index 8004d8df0c06..fa3da8dd42d4 100644
--- a/drivers/media/pci/intel/ici/ici-isys-pipeline.h
+++ b/drivers/media/pci/intel/ici/ici-isys-pipeline.h
@@ -40,6 +40,9 @@ struct ici_output_pin_data {
struct ici_isys_pipeline {
struct node_pipeline pipe;
struct ici_isys_pipeline_device *pipeline_dev;
+ atomic_t sequence;
+ unsigned int seq_index;
+ struct ici_sequence_info seq[ICI_ISYS_MAX_PARALLEL_SOF];
int source; /* SSI stream source */
int stream_handle; /* stream handle for CSS API */
unsigned int nr_output_pins; /* How many firmware pins? */
diff --git a/drivers/media/pci/intel/ici/ici-isys-stream.c b/drivers/media/pci/intel/ici/ici-isys-stream.c
2020-10-27 02:14:06 +08:00
index 1241dfaee553..ebcc72972fd0 100644
--- a/drivers/media/pci/intel/ici/ici-isys-stream.c
+++ b/drivers/media/pci/intel/ici/ici-isys-stream.c
@@ -882,6 +882,9 @@ static int ici_isys_stream_on(struct file *file, void *fh)
return 0;
}
+ ip->seq_index = 0;
+ memset(ip->seq, 0, sizeof(ip->seq));
+ atomic_set(&ip->sequence, 0);
ip->csi2 = NULL;
ip->csi2_be = NULL;
ip->asd_source = NULL;
diff --git a/drivers/media/pci/intel/ici/ici-isys.c b/drivers/media/pci/intel/ici/ici-isys.c
2020-10-27 02:14:06 +08:00
index 500491ee038f..3301c71f20e2 100644
--- a/drivers/media/pci/intel/ici/ici-isys.c
+++ b/drivers/media/pci/intel/ici/ici-isys.c
@@ -1254,6 +1254,16 @@ static int isys_isr_one_ici(struct ipu_bus_device *adev)
pipe->capture_done[i](pipe, &resp);
break;
case IA_CSS_ISYS_RESP_TYPE_FRAME_SOF:
+ pipe->seq[pipe->seq_index].sequence =
+ atomic_read(&pipe->sequence) -1;
+ pipe->seq[pipe->seq_index].timestamp = ts;
+ dev_dbg(&adev->dev,
+ "sof: handle %d: (index %u), timestamp 0x%16.16llx\n",
+ resp.stream_handle,
+ pipe->seq[pipe->seq_index].sequence,
+ ts);
+ pipe->seq_index = (pipe->seq_index + 1)
+ % ICI_ISYS_MAX_PARALLEL_SOF;
break;
case IA_CSS_ISYS_RESP_TYPE_FRAME_EOF:
break;
diff --git a/drivers/media/pci/intel/ici/ici-isys.h b/drivers/media/pci/intel/ici/ici-isys.h
2020-10-27 02:14:06 +08:00
index db46d7e6935a..a8fe61a08797 100644
--- a/drivers/media/pci/intel/ici/ici-isys.h
+++ b/drivers/media/pci/intel/ici/ici-isys.h
@@ -107,7 +107,6 @@ struct ici_isys {
spinlock_t power_lock;
u32 isr_csi2_bits;
spinlock_t lock;
- struct ipu_isys_pipeline *pipes[IPU_ISYS_MAX_STREAMS];
void *fwcom;
unsigned int line_align;
u32 legacy_port_cfg;
--
https://clearlinux.org