[PATCH 11/21] media: atmel: atmel-isc-base: implement mbus_code support in enumfmt

Eugen.Hristev at microchip.com Eugen.Hristev at microchip.com
Thu Nov 11 01:49:18 PST 2021


On 11/8/21 4:08 PM, Eugen Hristev - M18282 wrote:
> On 11/8/21 1:20 PM, Jacopo Mondi wrote:
>> Hi Eugen
>>
>> On Fri, Nov 05, 2021 at 11:03:25AM +0000, Eugen.Hristev at microchip.com wrote:
>>> On 11/5/21 11:51 AM, Jacopo Mondi wrote:
>>>> Hi Eugen
>>>>
>>>> On Fri, Nov 05, 2021 at 10:25:59AM +0100, Jacopo Mondi wrote:
>>>>> Hi Eugen,
>>>>>
>>>>> On Fri, Oct 22, 2021 at 10:52:37AM +0300, Eugen Hristev wrote:
>>>>>> If enumfmt is called with an mbus_code, the enumfmt handler should only
>>>>>> return the formats that are supported for this mbus_code.
>>>>>> To make it more easy to understand the formats, changed the report order
>>>>>> to report first the native formats, and after that the formats that the ISC
>>>>>> can convert to.
>>>>>>
>>>>>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>>>>>
>>>>> Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
>>>>>
>>>>
>>>> Too soon! Sorry...
>>>>
>>>>> Thanks
>>>>>       j
>>>>>
>>>>>> ---
>>>>>>     drivers/media/platform/atmel/atmel-isc-base.c | 51 ++++++++++++++++---
>>>>>>     1 file changed, 43 insertions(+), 8 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>>>>>> index 2dd2511c7be1..1f7fbe5e4d79 100644
>>>>>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>>>>>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>>>>>> @@ -499,21 +499,56 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
>>>>>>        u32 index = f->index;
>>>>>>        u32 i, supported_index;
>>>>>>
>>>>>> -   if (index < isc->controller_formats_size) {
>>>>>> -           f->pixelformat = isc->controller_formats[index].fourcc;
>>>>>> -           return 0;
>>>>>> +   supported_index = 0;
>>>>>> +
>>>
>>> Hi Jacopo,
>>>
>>> This for loop below first iterates through the formats that were
>>> identified as directly supported by the subdevice.
>>> As we are able in the ISC to just dump what the subdevice can stream, we
>>> advertise all these formats here.
>>> (if the userspace requires one specific mbus code, we only advertise the
>>> corresponding format)
>>>
>>>>>> +   for (i = 0; i < isc->formats_list_size; i++) {
>>>>>> +           if (!isc->formats_list[i].sd_support)
>>>>
>>>>
>>>>>> +                   continue;
>>>>>> +           /*
>>>>>> +            * If specific mbus_code is requested, provide only
>>>>>> +            * supported formats with this mbus code
>>>>>> +            */
>>>>>> +           if (f->mbus_code && f->mbus_code !=
>>>>>> +               isc->formats_list[i].mbus_code)
>>>>>> +                   continue;
>>>>>> +           if (supported_index == index) {
>>>>>> +                   f->pixelformat = isc->formats_list[i].fourcc;
>>>>>> +                   return 0;
>>>>>> +           }
>>>>>> +           supported_index++;
>>>>>>        }
>>>>>>
>>>>>> -   index -= isc->controller_formats_size;
>>>>>> +   /*
>>>>>> +    * If the sensor does not support this mbus_code whatsoever,
>>>>>> +    * there is no reason to advertise any of our output formats
>>>>>> +    */
>>>>>> +   if (supported_index == 0)
>>>>>> +           return -EINVAL;
>>>>
>>>> Shouldn't you also return -EINVAL if index > supported_index ?
>>>
>>> No. If we could not find any format that the sensor can use
>>> (supported_index == 0), and that our ISC can also use, then we don't
>>> support anything, thus, return -EINVAL regardless of the index.
>>>
>>>>
>>>> In that case, I'm not gettng what the rest of the function is for ?
>>>>
>>>
>>> This is the case when we identified one supported format for both the
>>> sensor and the ISC (case where supported_index found earlier is >= 1)
>>>
>>>>>> +
>>>>>> +   /*
>>>>>> +    * If the sensor uses a format that is not raw, then we cannot
>>>>>> +    * convert it to any of the formats that we usually can with a
>>>>>> +    * RAW sensor. Thus, do not advertise them.
>>>>>> +    */
>>>>>> +   if (!isc->config.sd_format ||
>>>>>> +       !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>>>>>> +           return -EINVAL;
>>>>>>
>>>
>>> Next, if the current format from the subdev is not raw, we are done.
>>
>> Ok, I think here it's were I disconnect.
>>
>> I don't think you should care about the -current- format on the
>> subdev, as once you move to MC the ISC formats should be enumerated
>> regardless of the how the remote subdev is configured. Rather, you
>> should consider if IS_RAW(f->mbus_code) and from there enumerate the
>> output formats you can generate from raw bayer (in addition to the
>> ones that can be produced by dumping the sensor produced formats)
> 
> Actually , in some words, this is what I am doing.
> I am following Laurent's advice:
> enumerate the formats supported for a given mbus code.
> 
> In consequence, if the mbus code given is a raw mbus code , I can
> advertise all my ISC formats, and if the mbus code is not raw, I don't .
> 
> So I am doing what you are saying, namely three cases:
> 
> If there is no mbus code given as a parameter to this function, I
> advertise all my formats, raw, non-raw, etc.
> 
> If there is raw mbus code given, I advertise this specific raw mbus code
> if the sensor supports it, and the ISC supports it, and in addition, all
> the formats ISC can convert from raw to.
> 
> If the mbus code given is not raw, then, I can only advertise this
> specific non-raw format, since there is nothing more I can do with it.
> It wouldn't make much sense to still advertise my rgb,yuv formats, since
> they cannot be used at all, and my later try_validate_formats will bail out
> 
> 
>>
>>> But, if it's raw, we can use it to convert to a plethora of other
>>> formats. So we have to enumerate them below :
>>>
>>> With the previous checks, I am making sure that the ISC can really
>>> convert to these formats, otherwise they are badly reported
>>>
>>> Hope this makes things more clear, but please ask if something looks strange
>>>
>>
>> I think our disconnection comes from the way the supported formats are
>> defined in ISC and I think their definition could be reworkd to
>> simplify the format selection logic.
>>
>> The driver defines three lists of formats:
>>
>> - isc->controller_formats
>>
>>          static const struct isc_format sama7g5_controller_formats[] = {
>>           {
>>                   .fourcc         = V4L2_PIX_FMT_ARGB444,
>>           },
>>           {
>>                   .fourcc         = V4L2_PIX_FMT_ARGB555,
>>           },
>>           ...
>>
>>           };
>>
>>    These are listed with the output fourcc only, and if I get
>>    try_configure_pipeline() right, they can be generated from any Bayer
>>    RAW format. Is this right ?
>>
>> - isc->formats_list
>>
>>           static struct isc_format sama7g5_formats_list[] = {
>>                   {
>>                           .fourcc         = V4L2_PIX_FMT_SBGGR8,
>>                           .mbus_code      = MEDIA_BUS_FMT_SBGGR8_1X8,
>>                           .pfe_cfg0_bps   = ISC_PFE_CFG0_BPS_EIGHT,
>>                           .cfa_baycfg     = ISC_BAY_CFG_BGBG,
>>                   },
>>                   {
>>                           .fourcc         = V4L2_PIX_FMT_SGBRG8,
>>                           .mbus_code      = MEDIA_BUS_FMT_SGBRG8_1X8,
>>                           .pfe_cfg0_bps   = ISC_PFE_CFG0_BPS_EIGHT,
>>                           .cfa_baycfg     = ISC_BAY_CFG_GBGB,
>>                   },
>>
>>            ...
>>
>>            };
>>
>>     These are formats the ISC can output by dumping the sensor output,
>>     hence they require a specific format to be output from the sensor
>>
>> - isc->user_formats
>>
>>           static int isc_formats_init() {
>>
>>                   ...
>>
>>                   fmt = &isc->formats_list[0];
>>                   for (i = 0, j = 0; i < list_size; i++) {
>>                           if (fmt->sd_support)
>>                                   isc->user_formats[j++] = fmt;
>>                           fmt++;
>>                   }
>>
>>         }
>>
>>     this list is obtained at runtime by restricting the formats_list to
>>     what the sensor can actually output. I think these, if you move to
>>     MC should be removed but I'm not 100% sure it is possible with the
>>     current implementation of set_fmt().
>>
>> Do you think controller_formats and formats_list should be unified ?
>>
>> If my understanding that all controller_formats can be generated from
>> RAW Bayer formats you could model struct isc_format as
>>
>>           struct isc_format {
>>                   u32     fourcc;
>>                   bool    processed;
>>                   u32     mbus_codes
>>                   u32     cfa_baycfg;
>>                   u32     pfe_cfg0_bps;
>>           };
>>
>> and have in example:
>>
>>           {
>>                   .fourcc         = V4L2_PIX_FMT_ARGB444,
>>                   .processed      = true,
>>                   .mbus_codes     = nullptr,
>>                   ....
>>           },
>>           {
>>                   .fourcc         = V4L2_PIX_FMT_SBGGR8,
>>                   .processed      = false,
>>                   .mbus_codes     = { MEDIA_BUS_FMT_SBGGR8_1X8 }
>>                   .pfe_cfg0_bps   = ISC_PFE_CFG0_BPS_EIGHT,
>>                   .cfa_baycfg     = ISC_BAY_CFG_BGBG,
>>           },
>>
>> and when enumerating and configuring formats check that
>>
>>           if (isc_format[i].processed &&
>>               (f->mbus_code && IS_RAW(f->mbus)code))
>>
>> or
>>
>>           if (!isc_format[i].processed &&
>>               (f->mbus_code == isc_format[i].mbus_code
>>
>> if you have other restrictions as in example V4L2_PIX_FMT_YUV420
>> requiring a packed YUV format, you can implement more complex
>> validations to match processed formats, like you do in try_validate_formats()
>>
>> Also, and a bit unrelated to enum_fmt, if I got this right
>> at format configuration time you match the ISC format with
>> the sensor format. I think this should be moved to .link_validate() op time.
>>
>> The MC core calls .link_validate when streaming is started on each
>> entity part of a pipeline, and there you could make sure that the ISC output format can be produced using
>> the sensor format (and sizes). This will greatly simplify set_fmt() as
>> there you will have just to make sure the supplied format is in the
>> list of the ISC supported ones and that's it. If userspace fails to
>> configure the pipeline correctly (in example by setting a non RAW
>> Bayer sensor on the format and requesting a RAW Bayer format from ISC,
>> you will fail at s_stream() time by returning an EPIPE.

Hi Jacopo,

I tried to look over the link_validate call.
It looks like this is only called by media_pipeline_start, which most 
drivers use in start_streaming() .
However, I need the format validation to be done before that, at 
streamon() time, because after streamon() , the vb2 queue will be filled 
with buffers, and I need to know exactly which format I will be using.
So, do you think it's fine to keep the format validation at streamon() 
time instead of calling media_pipeline_start in start_streaming ?

Currently I am not calling media_pipeline_start at all.
Do you think it's required?

Or maybe I am missing something and it should be done in a different way ?

Thanks !

>>
>> Hope all of this makes a bit of sense :)
> 
> About this last part you are telling me: I have to tell you what am I
> doing right now: with this patch series, including this patch, I am
> adding support for mc handling in this driver, but! the driver is still
> completely compatible with 'the old way' like setting fmt-video for
> /dev/video0 and everything is propagated down the pipeline.
> 
> I am doing the conversion to mc-only type of driver in multiple steps.
> This series adds the 'new way' while having the 'old way' still there.
> At the moment I am working on another patch on top of this series that
> will basically remove most of my format propagation logic from
> /dev/video0 to the subdevice, and after this patch that is on the way,
> the 'old way' is gone. The sensor will *have to* be configured through
> userspace because ISC will never call set_fmt on it at all.
> 
> So the purpose of the patch you are reviewing now is to have the mbus
> code parameter in the enum_fmt_vid_cap in the way the current driver
> handles things.
> 
> So if you agree, I will let the other patch speak for itself and rework
> the logic completely .
> I am currently trying to do it at streamon() time like Laurent told me,
> but I can try to have it at validate link as well, to see how it works.
> 
> I will add that patch to the series when it's ready and I have a v2 of
> this series as well. So in baby steps, I am working towards the goal. I
> am not sure if this means that you could agree to this patch as-is, or I
> have to integrate it completely into a bigger patch that will also fix
> everything up including the format logic.
> 
> Thanks again for your review and ideas
> 
> Eugen
>>
>>>>>> +   /*
>>>>>> +    * Iterate again through the formats that we can convert to.
>>>>>> +    * However, to avoid duplicates, skip the formats that
>>>>>> +    * the sensor already supports directly
>>>>>> +    */
>>>>>> +   index -= supported_index;
>>>>>>        supported_index = 0;
>>>>>>
>>>>>> -   for (i = 0; i < isc->formats_list_size; i++) {
>>>>>> -           if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) ||
>>>>>> -               !isc->formats_list[i].sd_support)
>>>>>> +   for (i = 0; i < isc->controller_formats_size; i++) {
>>>>>> +           /* if this format is already supported by sensor, skip it */
>>>>>> +           if (find_format_by_fourcc(isc, isc->controller_formats[i].fourcc))
>>>>>>                        continue;
>>>>>>                if (supported_index == index) {
>>>>>> -                   f->pixelformat = isc->formats_list[i].fourcc;
>>>>>> +                   f->pixelformat =
>>>>>> +                           isc->controller_formats[i].fourcc;
>>>>>>                        return 0;
>>>>>>                }
>>>>>>                supported_index++;
>>>>>> --
>>>>>> 2.25.1
>>>>>>
>>>
> 



More information about the linux-arm-kernel mailing list