Commit 25f5c34b authored by Todor Tomov's avatar Todor Tomov Committed by Mauro Carvalho Chehab

media: camss: Take in account sensor skip frames

When streaming is starting ask the sensor for its skip frames value.
Max supported frame skip is 29 frames, so clip it if it is higher.
Signed-off-by: default avatarTodor Tomov <todor.tomov@linaro.org>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 9483a3f8
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
/* VFE halt timeout */ /* VFE halt timeout */
#define VFE_HALT_TIMEOUT_MS 100 #define VFE_HALT_TIMEOUT_MS 100
/* Max number of frame drop updates per frame */ /* Max number of frame drop updates per frame */
#define VFE_FRAME_DROP_UPDATES 5 #define VFE_FRAME_DROP_UPDATES 2
/* Frame drop value. NOTE: VAL + UPDATES should not exceed 31 */ /* Frame drop value. VAL + UPDATES - 1 should not exceed 31 */
#define VFE_FRAME_DROP_VAL 20 #define VFE_FRAME_DROP_VAL 30
#define VFE_NEXT_SOF_MS 500 #define VFE_NEXT_SOF_MS 500
...@@ -659,7 +659,9 @@ static int vfe_enable_output(struct vfe_line *line) ...@@ -659,7 +659,9 @@ static int vfe_enable_output(struct vfe_line *line)
struct vfe_device *vfe = to_vfe(line); struct vfe_device *vfe = to_vfe(line);
struct vfe_output *output = &line->output; struct vfe_output *output = &line->output;
const struct vfe_hw_ops *ops = vfe->ops; const struct vfe_hw_ops *ops = vfe->ops;
struct media_entity *sensor;
unsigned long flags; unsigned long flags;
unsigned int frame_skip = 0;
unsigned int i; unsigned int i;
u16 ub_size; u16 ub_size;
...@@ -667,6 +669,17 @@ static int vfe_enable_output(struct vfe_line *line) ...@@ -667,6 +669,17 @@ static int vfe_enable_output(struct vfe_line *line)
if (!ub_size) if (!ub_size)
return -EINVAL; return -EINVAL;
sensor = camss_find_sensor(&line->subdev.entity);
if (sensor) {
struct v4l2_subdev *subdev =
media_entity_to_v4l2_subdev(sensor);
v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
/* Max frame skip is 29 frames */
if (frame_skip > VFE_FRAME_DROP_VAL - 1)
frame_skip = VFE_FRAME_DROP_VAL - 1;
}
spin_lock_irqsave(&vfe->output_lock, flags); spin_lock_irqsave(&vfe->output_lock, flags);
ops->reg_update_clear(vfe, line->id); ops->reg_update_clear(vfe, line->id);
...@@ -695,10 +708,10 @@ static int vfe_enable_output(struct vfe_line *line) ...@@ -695,10 +708,10 @@ static int vfe_enable_output(struct vfe_line *line)
switch (output->state) { switch (output->state) {
case VFE_OUTPUT_SINGLE: case VFE_OUTPUT_SINGLE:
vfe_output_frame_drop(vfe, output, 1); vfe_output_frame_drop(vfe, output, 1 << frame_skip);
break; break;
case VFE_OUTPUT_CONTINUOUS: case VFE_OUTPUT_CONTINUOUS:
vfe_output_frame_drop(vfe, output, 3); vfe_output_frame_drop(vfe, output, 3 << frame_skip);
break; break;
default: default:
vfe_output_frame_drop(vfe, output, 0); vfe_output_frame_drop(vfe, output, 0);
......
...@@ -346,7 +346,7 @@ void camss_disable_clocks(int nclocks, struct camss_clock *clock) ...@@ -346,7 +346,7 @@ void camss_disable_clocks(int nclocks, struct camss_clock *clock)
* *
* Return a pointer to sensor media entity or NULL if not found * Return a pointer to sensor media entity or NULL if not found
*/ */
static struct media_entity *camss_find_sensor(struct media_entity *entity) struct media_entity *camss_find_sensor(struct media_entity *entity)
{ {
struct media_pad *pad; struct media_pad *pad;
......
...@@ -106,6 +106,7 @@ void camss_add_clock_margin(u64 *rate); ...@@ -106,6 +106,7 @@ void camss_add_clock_margin(u64 *rate);
int camss_enable_clocks(int nclocks, struct camss_clock *clock, int camss_enable_clocks(int nclocks, struct camss_clock *clock,
struct device *dev); struct device *dev);
void camss_disable_clocks(int nclocks, struct camss_clock *clock); void camss_disable_clocks(int nclocks, struct camss_clock *clock);
struct media_entity *camss_find_sensor(struct media_entity *entity);
int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock); int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock);
int camss_pm_domain_on(struct camss *camss, int id); int camss_pm_domain_on(struct camss *camss, int id);
void camss_pm_domain_off(struct camss *camss, int id); void camss_pm_domain_off(struct camss *camss, int id);
......
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