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.ripard@xxxxxxxxxxx> > --- > 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.