Commit 707acfc0 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] v4l: omap4iss: csi2: Perform real frame number propagation

Compute the pipeline frame number from the frame number sent by the
sensor instead of incrementing the frame number in software. This
improves dropped frames detection.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent dd162547
...@@ -612,7 +612,12 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, ...@@ -612,7 +612,12 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
ret = v4l2_subdev_call(subdev, video, s_stream, mode); ret = v4l2_subdev_call(subdev, video, s_stream, mode);
if (ret < 0 && ret != -ENOIOCTLCMD) if (ret < 0 && ret != -ENOIOCTLCMD)
return ret; return ret;
if (subdev == &iss->csi2a.subdev ||
subdev == &iss->csi2b.subdev)
pipe->do_propagation = true;
} }
iss_print_status(pipe->output->iss); iss_print_status(pipe->output->iss);
return 0; return 0;
} }
......
...@@ -319,6 +319,8 @@ static void csi2_ctx_config(struct iss_csi2_device *csi2, ...@@ -319,6 +319,8 @@ static void csi2_ctx_config(struct iss_csi2_device *csi2,
{ {
u32 reg = 0; u32 reg = 0;
ctx->frame = 0;
/* Set up CSI2_CTx_CTRL1 */ /* Set up CSI2_CTx_CTRL1 */
if (ctx->eof_enabled) if (ctx->eof_enabled)
reg = CSI2_CTX_CTRL1_EOF_EN; reg = CSI2_CTX_CTRL1_EOF_EN;
...@@ -396,21 +398,18 @@ static void csi2_timing_config(struct iss_csi2_device *csi2, ...@@ -396,21 +398,18 @@ static void csi2_timing_config(struct iss_csi2_device *csi2,
*/ */
static void csi2_irq_ctx_set(struct iss_csi2_device *csi2, int enable) static void csi2_irq_ctx_set(struct iss_csi2_device *csi2, int enable)
{ {
u32 reg = CSI2_CTX_IRQ_FE; const u32 mask = CSI2_CTX_IRQ_FE | CSI2_CTX_IRQ_FS;
int i; int i;
if (csi2->use_fs_irq)
reg |= CSI2_CTX_IRQ_FS;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(i), iss_reg_write(csi2->iss, csi2->regs1, CSI2_CTX_IRQSTATUS(i),
reg); mask);
if (enable) if (enable)
iss_reg_set(csi2->iss, csi2->regs1, iss_reg_set(csi2->iss, csi2->regs1,
CSI2_CTX_IRQENABLE(i), reg); CSI2_CTX_IRQENABLE(i), mask);
else else
iss_reg_clr(csi2->iss, csi2->regs1, iss_reg_clr(csi2->iss, csi2->regs1,
CSI2_CTX_IRQENABLE(i), reg); CSI2_CTX_IRQENABLE(i), mask);
} }
} }
...@@ -679,8 +678,34 @@ static void csi2_isr_ctx(struct iss_csi2_device *csi2, ...@@ -679,8 +678,34 @@ static void csi2_isr_ctx(struct iss_csi2_device *csi2,
if (status & CSI2_CTX_IRQ_FS) { if (status & CSI2_CTX_IRQ_FS) {
struct iss_pipeline *pipe = struct iss_pipeline *pipe =
to_iss_pipeline(&csi2->subdev.entity); to_iss_pipeline(&csi2->subdev.entity);
if (pipe->do_propagation) u16 frame;
u16 delta;
frame = iss_reg_read(csi2->iss, csi2->regs1,
CSI2_CTX_CTRL2(ctx->ctxnum))
>> CSI2_CTX_CTRL2_FRAME_SHIFT;
if (frame == 0) {
/* A zero value means that the counter isn't implemented
* by the source. Increment the frame number in software
* in that case.
*/
atomic_inc(&pipe->frame_number); atomic_inc(&pipe->frame_number);
} else {
/* Extend the 16 bit frame number to 32 bits by
* computing the delta between two consecutive CSI2
* frame numbers and adding it to the software frame
* number. The hardware counter starts at 1 and wraps
* from 0xffff to 1 without going through 0, so subtract
* 1 when the counter wraps.
*/
delta = frame - ctx->frame;
if (frame < ctx->frame)
delta--;
ctx->frame = frame;
atomic_add(delta, &pipe->frame_number);
}
} }
if (!(status & CSI2_CTX_IRQ_FE)) if (!(status & CSI2_CTX_IRQ_FE))
...@@ -1039,7 +1064,6 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable) ...@@ -1039,7 +1064,6 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
{ {
struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd); struct iss_csi2_device *csi2 = v4l2_get_subdevdata(sd);
struct iss_device *iss = csi2->iss; struct iss_device *iss = csi2->iss;
struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
struct iss_video *video_out = &csi2->video_out; struct iss_video *video_out = &csi2->video_out;
int ret = 0; int ret = 0;
...@@ -1058,7 +1082,6 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable) ...@@ -1058,7 +1082,6 @@ static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
if (omap4iss_csiphy_acquire(csi2->phy) < 0) if (omap4iss_csiphy_acquire(csi2->phy) < 0)
return -ENODEV; return -ENODEV;
csi2->use_fs_irq = pipe->do_propagation;
csi2_configure(csi2); csi2_configure(csi2);
csi2_print_status(csi2); csi2_print_status(csi2);
......
...@@ -82,6 +82,7 @@ struct iss_csi2_ctx_cfg { ...@@ -82,6 +82,7 @@ struct iss_csi2_ctx_cfg {
u8 virtual_id; u8 virtual_id;
u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */ u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
u8 dpcm_predictor; /* 1: simple, 0: advanced */ u8 dpcm_predictor; /* 1: simple, 0: advanced */
u16 frame;
/* Fields in CSI2_CTx_CTRL1/3 - Shadowed */ /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
u16 alpha; u16 alpha;
...@@ -137,7 +138,6 @@ struct iss_csi2_device { ...@@ -137,7 +138,6 @@ struct iss_csi2_device {
u32 output; /* output to IPIPEIF, memory or both? */ u32 output; /* output to IPIPEIF, memory or both? */
bool dpcm_decompress; bool dpcm_decompress;
unsigned int frame_skip; unsigned int frame_skip;
bool use_fs_irq;
struct iss_csiphy *phy; struct iss_csiphy *phy;
struct iss_csi2_ctx_cfg contexts[ISS_CSI2_MAX_CTX_NUM + 1]; struct iss_csi2_ctx_cfg contexts[ISS_CSI2_MAX_CTX_NUM + 1];
......
...@@ -215,6 +215,8 @@ ...@@ -215,6 +215,8 @@
#define CSI2_CTX_CTRL1_CTX_EN (1 << 0) #define CSI2_CTX_CTRL1_CTX_EN (1 << 0)
#define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * i)) #define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * i))
#define CSI2_CTX_CTRL2_FRAME_MASK (0xffff << 16)
#define CSI2_CTX_CTRL2_FRAME_SHIFT 16
#define CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13 #define CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
#define CSI2_CTX_CTRL2_USER_DEF_MAP_MASK \ #define CSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
(0x3 << CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT) (0x3 << CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment