Hi Laurent,

Thanks for the review.

On 03/04/2011 05:33 PM, Laurent Pinchart wrote:
> Hi Michael,
> 
> Thanks for the patch.
> 
> On Friday 04 March 2011 09:58:04 Michael Jones wrote:
>> Signed-off-by: Michael Jones <michael.jo...@matrix-vision.de>
>> ---
>>  drivers/media/video/omap3-isp/isp.c      |   82
>> +++++++++++++++++++++++++++++- drivers/media/video/omap3-isp/isp.h      | 
>>   4 +-
>>  drivers/media/video/omap3-isp/ispccdc.c  |    2 +-
>>  drivers/media/video/omap3-isp/ispvideo.c |   65 +++++++++++++++++-------
>>  drivers/media/video/omap3-isp/ispvideo.h |    3 +
>>  5 files changed, 134 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/media/video/omap3-isp/isp.c
>> b/drivers/media/video/omap3-isp/isp.c index 08d90fe..20e6daa 100644
>> --- a/drivers/media/video/omap3-isp/isp.c
>> +++ b/drivers/media/video/omap3-isp/isp.c
>> @@ -273,6 +273,44 @@ static void isp_power_settings(struct isp_device *isp,
>> int idle) }
>>
>>  /*
>> + * Decide whether desired output pixel code can be obtained with
>> + * the lane shifter by shifting the input pixel code.
>> + * return 1 if the combination is possible
>> + * return 0 otherwise
>> + */
>> +int omap3isp_is_shiftable(enum v4l2_mbus_pixelcode in,
>> +            enum v4l2_mbus_pixelcode out)
> 
> As you only use this function in ispvideo.c, I would move it there. You could 
> also make the function return a bool.

I thought returning a bool was inconsistent with kernel style (e.g.
isp_pipeline_is_last, ccdc_lsc_is_configured return int).

> 
>> +{
>> +    const struct isp_format_info *in_info, *out_info;
>> +    int shiftable = 0;
>> +    if ((in == 0) || (out == 0))
>> +            return 0;
> 
> Can this happen ?
> 
>> +
>> +    if (in == out)
>> +            return 1;
>> +
>> +    in_info = omap3isp_video_format_info(in);
>> +    out_info = omap3isp_video_format_info(out);
>> +    if ((!in_info) || (!out_info))
>> +            return 0;
> 
> Can this happen ?
> 

These were all relics of previous versions when I was also calling
omap3isp_is_shiftable() from ccdc_try_format().  I will move it to
ispvideo.c and remove the two if statements.

>> +
>> +    if (in_info->flavor != out_info->flavor)
>> +            return 0;
>> +
>> +    switch (in_info->bpp - out_info->bpp) {
>> +    case 2:
>> +    case 4:
>> +    case 6:
>> +            shiftable = 1;
>> +            break;
>> +    default:
>> +            shiftable = 0;
>> +    }
> 
> What about
> 
> return in_info->bpp - out_info->bpp <= 6;

As long as there are never formats which are the same flavor but shifted
1, 3, or 5 bits, that's fine.  I suppose this is a safe assumption?

> 
>> +
>> +    return shiftable;
>> +}
>> +
>> +/*
>>   * Configure the bridge and lane shifter. Valid inputs are
>>   *
>>   * CCDC_INPUT_PARALLEL: Parallel interface
>> @@ -288,6 +326,10 @@ void omap3isp_configure_bridge(struct isp_device *isp,
>>                             const struct isp_parallel_platform_data *pdata)
>>  {
>>      u32 ispctrl_val;
>> +    u32 depth_in = 0, depth_out = 0;
>> +    u32 shift;
>> +    const struct isp_format_info *fmt_info;
>> +    struct media_pad *srcpad;
>>
>>      ispctrl_val  = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
>>      ispctrl_val &= ~ISPCTRL_SHIFT_MASK;
>> @@ -298,7 +340,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
>>      switch (input) {
>>      case CCDC_INPUT_PARALLEL:
>>              ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
>> -            ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT;
>>              ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
>>              ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
>>              break;
>> @@ -319,6 +360,45 @@ void omap3isp_configure_bridge(struct isp_device *isp,
>>              return;
>>      }
>>
>> +    /* find output format from the remote end of the link connected to
>> +     * CCDC sink pad
>> +     */
>> +    srcpad = media_entity_remote_source(&isp->isp_ccdc.pads[CCDC_PAD_SINK]);
>> +    if (srcpad == NULL)
>> +            dev_err(isp->dev, "No active input to CCDC.\n");
> 
> There's no need to test for NULL, as this function will only be called on 
> streamon, so the pipeline will be valid.

OK.

> 
>> +    if (media_entity_type(srcpad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
> 
> The CCDC has no memory input, so this condition will always be true.

OK.

> 
>> +            struct v4l2_subdev *subdev =
>> +               media_entity_to_v4l2_subdev(srcpad->entity);
>> +            struct v4l2_subdev_format fmt_src;
>> +            fmt_src.pad = srcpad->index;
>> +            fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
>> +            if (!v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_src)) {
>> +                    fmt_info =
>> +                       omap3isp_video_format_info(fmt_src.format.code);
>> +                    depth_in = fmt_info ? fmt_info->bpp : 0;
>> +            }
>> +    }
>> +
>> +    /* find CCDC input format */
>> +    fmt_info = omap3isp_video_format_info
>> +            (isp->isp_ccdc.formats[CCDC_PAD_SINK].code);
>> +    depth_out = fmt_info ? fmt_info->bpp : 0;
>> +
>> +    isp->isp_ccdc.syncif.datsz = depth_out;
>> +
>> +    /* determine necessary shifting */
>> +    if (depth_in == depth_out + 6)
>> +            shift = 3;
>> +    else if (depth_in == depth_out + 4)
>> +            shift = 2;
>> +    else if (depth_in == depth_out + 2)
>> +            shift = 1;
>> +    else
>> +            shift = 0;
> 
> Maybe shift = (depth_out - depth_in) / 2; ?

First of all, the other way around: (depth_in - depth_out).  I suppose I
don't need to account for e.g. (depth_in - depth_out > 6) because then
the pipeline would've been invalid in the first place?  If I do this, I
would at least use ISPCTRL_SHIFT_MASK when writing 'shift' into
ispctrl_val as a final catch if something went wrong with shift.

> 
>> +
>> +    ispctrl_val |= shift << ISPCTRL_SHIFT_SHIFT;
>> +
>>      ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
>>      ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
>>
> 
> [snip]
> 
>> diff --git a/drivers/media/video/omap3-isp/ispccdc.c
>> b/drivers/media/video/omap3-isp/ispccdc.c index 166115d..efaf317 100644
>> --- a/drivers/media/video/omap3-isp/ispccdc.c
>> +++ b/drivers/media/video/omap3-isp/ispccdc.c
>> @@ -1132,7 +1132,7 @@ static void ccdc_configure(struct isp_ccdc_device
>> *ccdc)
>>
>>      omap3isp_configure_bridge(isp, ccdc->input, pdata);
>>
>> -    ccdc->syncif.datsz = pdata ? pdata->width : 10;
>> +    /* syncif.datsz was set in isp_configure_bridge() */
> 
> I'd rather set syncif.datsz in ispccdc.c than in isp.c, as all other syncif 
> fields are set there. It might even make sense to compute the shift value 
> here 
> and pass it to omap3isp_configure_bridge, especially with the code a couple 
> of 
> lines above to retrieve the connected subdev (which would need to be moved 
> out 
> of the if(), except for the pdata line).

Agreed.  I will move the shift computation and datsz assignment from
isp_configure_bridge() into ccdc_configure(), then pass 'shift' as a new
arg to omap3isp_configure_bridge().

> 
>>      ccdc_config_sync_if(ccdc, &ccdc->syncif);
>>
>>      /* CCDC_PAD_SINK */
>> diff --git a/drivers/media/video/omap3-isp/ispvideo.c
>> b/drivers/media/video/omap3-isp/ispvideo.c index c406043..4602d20 100644
>> --- a/drivers/media/video/omap3-isp/ispvideo.c
>> +++ b/drivers/media/video/omap3-isp/ispvideo.c
>> @@ -47,37 +47,53 @@
>>
>>  static struct isp_format_info formats[] = {
[snip]
>>      { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
>> -      V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, },
>> +      V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_2X8,
>> +      V4L2_PIX_FMT_UYVY, 16, },
>>      { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
>> -      V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, },
>> +      V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_2X8,
> 
> I don't think these two are correct. YUYV8_1X16 doesn't magically become 
> YUYV8_2X8 when shifted. As those formats can only be used by the preview 
> engine and the resizer, they're pretty much unshiftable.

OK, I'll set flavor = 0 for these and add a check to
omap3isp_is_shiftable that in and out flavors !=0.

> 
>> +      V4L2_PIX_FMT_YUYV, 16, },
>>  };
>>
>>  const struct isp_format_info *
>> @@ -243,6 +259,7 @@ static int isp_video_validate_pipeline(struct
>> isp_pipeline *pipe) return -EPIPE;
>>
>>      while (1) {
>> +            unsigned int link_has_shifter;
>>              /* Retrieve the sink format */
>>              pad = &subdev->entity.pads[0];
>>              if (!(pad->flags & MEDIA_PAD_FL_SINK))
>> @@ -271,6 +288,10 @@ static int isp_video_validate_pipeline(struct
>> isp_pipeline *pipe) return -ENOSPC;
>>              }
>>
>> +            /* if sink pad is on CCDC, the link has the lane shifter
>> +             * in the middle of it. */
>> +            link_has_shifter = (subdev == &isp->isp_ccdc.subdev);
>> +
>>              /* Retrieve the source format */
>>              pad = media_entity_remote_source(pad);
>>              if (pad == NULL ||
>> @@ -286,10 +307,18 @@ static int isp_video_validate_pipeline(struct
>> isp_pipeline *pipe) return -EPIPE;
>>
>>              /* Check if the two ends match */
>> -            if (fmt_source.format.code != fmt_sink.format.code ||
>> -                fmt_source.format.width != fmt_sink.format.width ||
>> +            if (fmt_source.format.width != fmt_sink.format.width ||
>>                  fmt_source.format.height != fmt_sink.format.height)
>>                      return -EPIPE;
>> +
>> +            if (link_has_shifter) {
>> +                    if (!omap3isp_is_shiftable(fmt_source.format.code,
>> +                                            fmt_sink.format.code)) {
>> +                            pr_debug("%s not shiftable.\n", __func__);
>> +                            return -EPIPE;
>> +                    }
>> +            } else if (fmt_source.format.code != fmt_sink.format.code)
>> +                    return -EPIPE;
>>      }
>>
>>      return 0;
>> diff --git a/drivers/media/video/omap3-isp/ispvideo.h
>> b/drivers/media/video/omap3-isp/ispvideo.h index 524a1ac..7794cb4 100644
>> --- a/drivers/media/video/omap3-isp/ispvideo.h
>> +++ b/drivers/media/video/omap3-isp/ispvideo.h
>> @@ -49,6 +49,8 @@ struct v4l2_pix_format;
>>   *  bits. Identical to @code if the format is 10 bits wide or less.
>>   * @uncompressed: V4L2 media bus format code for the corresponding
>> uncompressed
>>   *  format. Identical to @code if the format is not DPCM compressed.
>> + *  @flavor: V4L2 media bus format code for the same pixel layout but
> 
> @flavor should be aligned left on @uncompressed and @pixelformat.

oops.

-Michael

MATRIX VISION GmbH, Talstrasse 16, DE-71570 Oppenweiler
Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschaeftsfuehrer: Gerhard Thullner, Werner Armingeon, Uwe Furtner
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to