From: Michael Jones <michael.jones@matrix-vision.de>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: linux-media@vger.kernel.org,
Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>,
Hans Verkuil <hverkuil@xs4all.nl>
Subject: Re: [PATCH 4/4] omap3isp: lane shifter support
Date: Mon, 07 Mar 2011 11:53:26 +0100 [thread overview]
Message-ID: <4D74B926.3010304@matrix-vision.de> (raw)
In-Reply-To: <201103041733.23754.laurent.pinchart@ideasonboard.com>
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.jones@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
next prev parent reply other threads:[~2011-03-07 10:53 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-04 8:58 [PATCH 0/4] OMAP3-ISP lane shifter support Michael Jones
2011-03-04 8:58 ` [PATCH 1/4] v4l: add V4L2_PIX_FMT_Y12 format Michael Jones
2011-03-04 15:42 ` Laurent Pinchart
2011-03-04 8:58 ` [PATCH 2/4] media: add 8-bit bayer formats and Y12 Michael Jones
2011-03-04 15:42 ` Laurent Pinchart
2011-03-04 8:58 ` [PATCH 3/4] omap3isp: ccdc: support Y10, Y12, SGRBG8, SBGGR8 Michael Jones
2011-03-04 15:46 ` Laurent Pinchart
2011-03-04 8:58 ` [PATCH 4/4] omap3isp: lane shifter support Michael Jones
2011-03-04 16:33 ` Laurent Pinchart
2011-03-07 10:53 ` Michael Jones [this message]
2011-03-07 14:02 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D74B926.3010304@matrix-vision.de \
--to=michael.jones@matrix-vision.de \
--cc=hverkuil@xs4all.nl \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=sakari.ailus@maxwell.research.nokia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.