Hi Maxime,

See below rest of comments regarding framerate and compliance failure.

On 03/02/2018 03:34 PM, Maxime Ripard wrote:
> Now that we have everything in place to compute the clock rate at runtime,
> we can enable the 60fps framerate for the mode we tested it with.
> 
> Signed-off-by: Maxime Ripard <maxime.rip...@bootlin.com>
> ---
>   drivers/media/i2c/ov5640.c | 20 +++++++++++++++-----
>   1 file changed, 15 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 5510a19281a4..03838f42fb82 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -111,6 +111,7 @@ enum ov5640_mode_id {
>   enum ov5640_frame_rate {
>       OV5640_15_FPS = 0,
>       OV5640_30_FPS,
> +     OV5640_60_FPS,
>       OV5640_NUM_FRAMERATES,
>   };
>   
> @@ -144,6 +145,7 @@ MODULE_PARM_DESC(virtual_channel,
>   static const int ov5640_framerates[] = {
>       [OV5640_15_FPS] = 15,
>       [OV5640_30_FPS] = 30,
> +     [OV5640_60_FPS] = 60,
>   };
>   
>   /* regulator supplies */
> @@ -1447,6 +1449,11 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum 
> ov5640_frame_rate fr,
>           fr != OV5640_15_FPS)
>               return NULL;
>   
> +     /* Only 640x480 can operate at 60fps (for now) */
> +     if (fr == OV5640_60_FPS &&
> +         width != 640 && height != 480)
> +             return NULL;
> +

Same comment as on patchset 10/12, VGA exception put in for loop:

        for (i = OV5640_NUM_MODES - 1; i >= 0; i--) {
                mode = &ov5640_mode_data[i];

                if (!mode->reg_data)
                        continue;

                if ((nearest && mode->hact <= width &&
                     mode->vact <= height) ||
                    (!nearest && mode->hact == width &&
                     mode->vact == height)) {

                        /* 2592x1944 can only operate at 15fps */
                        if (mode->hact == 2592 && mode->vact == 1944 &&
                            fr != OV5640_15_FPS)
                                continue;/* next lower resolution */

                        /* Only 640x480 can operate at 60fps (for now) */
                        if (fr == OV5640_60_FPS &&
                            !(mode->hact == 640 && mode->vact == 480))
                                continue;/* next lower resolution */

                        break;/* select this resolution */
                }
        }


>       return mode;
>   }
>   
> @@ -1875,12 +1882,12 @@ static int ov5640_try_frame_interval(struct 
> ov5640_dev *sensor,
>       int ret;
>   
>       minfps = ov5640_framerates[OV5640_15_FPS];
> -     maxfps = ov5640_framerates[OV5640_30_FPS];
> +     maxfps = ov5640_framerates[OV5640_60_FPS];
>   
>       if (fi->numerator == 0) {
>               fi->denominator = maxfps;
>               fi->numerator = 1;
> -             return OV5640_30_FPS;
> +             return OV5640_60_FPS;

There is a problem here because we don't validate that 60fps is 
supported in the currently set mode, we must inject this framerate value 
in ov5640_find_mode(framerate, width, height) in order to validate it 
(-EINVAL if not supported):

  +             ret = OV5640_60_FPS;
  +             goto find_mode;
  +     }
[...]
+find_mode:
        mode = ov5640_find_mode(sensor, frame_rate, width, height, false);
        return mode ? ret : -EINVAL;
  }

Then we have to catch error in ov5640_s_frame_interval() and return an 
acceptable frame interval to user:

        frame_rate = ov5640_try_frame_interval(sensor, &fi->interval,
                                               mode->hact, mode->vact);
-       if (frame_rate < 0)
-               frame_rate = OV5640_15_FPS;
-
-       sensor->current_fr = frame_rate;
-       sensor->frame_interval = fi->interval;
We also have to update current framerate only if framerate has been 
validated.

+       if (frame_rate < 0) {
+               /* return a valid frame interval value */
+               fi->interval = sensor->frame_interval;
                goto out;
        }

+       sensor->current_fr = frame_rate;
+       sensor->frame_interval = fi->interval;
        sensor->pending_mode_change = true;
  out:


About 60 fps by default if (fi->numerator == 0): shouldn't we stick to a 
default value supported by all modes such as 30fps ?

>       }
>   
>       fps = DIV_ROUND_CLOSEST(fi->denominator, fi->numerator);
> @@ -1892,10 +1899,13 @@ static int ov5640_try_frame_interval(struct 
> ov5640_dev *sensor,
>               fi->denominator = minfps;
>       else if (2 * fps >= 2 * minfps + (maxfps - minfps))
>               fi->denominator = maxfps;
> -     else
> -             fi->denominator = minfps;
>   
> -     ret = (fi->denominator == minfps) ? OV5640_15_FPS : OV5640_30_FPS;
> +     if (fi->denominator == minfps)
> +             ret = OV5640_15_FPS;
> +     else if (fi->denominator == maxfps)
> +             ret = OV5640_60_FPS;
> +     else
> +             ret = OV5640_30_FPS;
>   
>       mode = ov5640_find_mode(sensor, ret, width, height, false);
>       return mode ? ret : -EINVAL;
> 

With this 60fps change, we have also to change the default mode to VGA, 
because it's the only one resolution that supports all the 3 framerates 
15/30/60:

static const struct ov5640_mode_info *
  ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
                 int width, int height, bool nearest)
  {

        if (i < 0) {
                /* no match */
                if (!nearest)
                        return NULL;
-               mode = &ov5640_mode_data[0];
+               mode = &ov5640_mode_data[OV5640_MODE_VGA_640_480];/* VGA can do 
all 
fps */
        }


Best regards,
Hugues.

Reply via email to