Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Todor Tomov <todor.tomov@linaro.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

authored by

Todor Tomov and committed by
Mauro Carvalho Chehab
25f5c34b 9483a3f8

+20 -6
+18 -5
drivers/media/platform/qcom/camss/camss-vfe.c
··· 37 37 /* VFE halt timeout */ 38 38 #define VFE_HALT_TIMEOUT_MS 100 39 39 /* Max number of frame drop updates per frame */ 40 - #define VFE_FRAME_DROP_UPDATES 5 41 - /* Frame drop value. NOTE: VAL + UPDATES should not exceed 31 */ 42 - #define VFE_FRAME_DROP_VAL 20 40 + #define VFE_FRAME_DROP_UPDATES 2 41 + /* Frame drop value. VAL + UPDATES - 1 should not exceed 31 */ 42 + #define VFE_FRAME_DROP_VAL 30 43 43 44 44 #define VFE_NEXT_SOF_MS 500 45 45 ··· 659 659 struct vfe_device *vfe = to_vfe(line); 660 660 struct vfe_output *output = &line->output; 661 661 const struct vfe_hw_ops *ops = vfe->ops; 662 + struct media_entity *sensor; 662 663 unsigned long flags; 664 + unsigned int frame_skip = 0; 663 665 unsigned int i; 664 666 u16 ub_size; 665 667 666 668 ub_size = ops->get_ub_size(vfe->id); 667 669 if (!ub_size) 668 670 return -EINVAL; 671 + 672 + sensor = camss_find_sensor(&line->subdev.entity); 673 + if (sensor) { 674 + struct v4l2_subdev *subdev = 675 + media_entity_to_v4l2_subdev(sensor); 676 + 677 + v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip); 678 + /* Max frame skip is 29 frames */ 679 + if (frame_skip > VFE_FRAME_DROP_VAL - 1) 680 + frame_skip = VFE_FRAME_DROP_VAL - 1; 681 + } 669 682 670 683 spin_lock_irqsave(&vfe->output_lock, flags); 671 684 ··· 708 695 709 696 switch (output->state) { 710 697 case VFE_OUTPUT_SINGLE: 711 - vfe_output_frame_drop(vfe, output, 1); 698 + vfe_output_frame_drop(vfe, output, 1 << frame_skip); 712 699 break; 713 700 case VFE_OUTPUT_CONTINUOUS: 714 - vfe_output_frame_drop(vfe, output, 3); 701 + vfe_output_frame_drop(vfe, output, 3 << frame_skip); 715 702 break; 716 703 default: 717 704 vfe_output_frame_drop(vfe, output, 0);
+1 -1
drivers/media/platform/qcom/camss/camss.c
··· 346 346 * 347 347 * Return a pointer to sensor media entity or NULL if not found 348 348 */ 349 - static struct media_entity *camss_find_sensor(struct media_entity *entity) 349 + struct media_entity *camss_find_sensor(struct media_entity *entity) 350 350 { 351 351 struct media_pad *pad; 352 352
+1
drivers/media/platform/qcom/camss/camss.h
··· 106 106 int camss_enable_clocks(int nclocks, struct camss_clock *clock, 107 107 struct device *dev); 108 108 void camss_disable_clocks(int nclocks, struct camss_clock *clock); 109 + struct media_entity *camss_find_sensor(struct media_entity *entity); 109 110 int camss_get_pixel_clock(struct media_entity *entity, u32 *pixel_clock); 110 111 int camss_pm_domain_on(struct camss *camss, int id); 111 112 void camss_pm_domain_off(struct camss *camss, int id);