lkml.org 
[lkml]   [2019]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[Patch 07/13] media: am437x-vpfe: Use a per instance format array instead of a static one
    Date
    Using a statically defined format array would cause issue when
    multiple vpfe instance would be connected to sub-device of
    different capabilities. We need to use an instance based array
    instead to properly maintain a per port/instance format list.

    Signed-off-by: Benoit Parrot <bparrot@ti.com>
    ---
    drivers/media/platform/am437x/am437x-vpfe.c | 108 ++++++++------------
    drivers/media/platform/am437x/am437x-vpfe.h | 34 ++++++
    2 files changed, 74 insertions(+), 68 deletions(-)

    diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
    index ac759c066d00..e76dc2b3b7b8 100644
    --- a/drivers/media/platform/am437x/am437x-vpfe.c
    +++ b/drivers/media/platform/am437x/am437x-vpfe.c
    @@ -69,30 +69,6 @@ static const struct vpfe_standard vpfe_standards[] = {
    {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
    };

    -struct bus_format {
    - unsigned int width;
    - unsigned int bpp;
    -};
    -
    -/*
    - * struct vpfe_fmt - VPFE media bus format information
    - * @code: V4L2 media bus format code
    - * @shifted: V4L2 media bus format code for the same pixel layout but
    - * shifted to be 8 bits per pixel. =0 if format is not shiftable.
    - * @pixelformat: V4L2 pixel format FCC identifier
    - * @width: Bits per pixel (when transferred over a bus)
    - * @bpp: Bytes per pixel (when stored in memory)
    - * @supported: Indicates format supported by subdev
    - */
    -struct vpfe_fmt {
    - u32 fourcc;
    - u32 code;
    - struct bus_format l;
    - struct bus_format s;
    - bool supported;
    - u32 index;
    -};
    -
    static struct vpfe_fmt formats[] = {
    {
    .fourcc = V4L2_PIX_FMT_YUYV,
    @@ -101,7 +77,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_UYVY,
    .code = MEDIA_BUS_FMT_UYVY8_2X8,
    @@ -109,7 +84,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_YVYU,
    .code = MEDIA_BUS_FMT_YVYU8_2X8,
    @@ -117,7 +91,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_VYUY,
    .code = MEDIA_BUS_FMT_VYUY8_2X8,
    @@ -125,7 +98,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_SBGGR8,
    .code = MEDIA_BUS_FMT_SBGGR8_1X8,
    @@ -133,7 +105,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 2,
    .s.width = 8,
    .s.bpp = 1,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_SGBRG8,
    .code = MEDIA_BUS_FMT_SGBRG8_1X8,
    @@ -141,7 +112,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 2,
    .s.width = 8,
    .s.bpp = 1,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_SGRBG8,
    .code = MEDIA_BUS_FMT_SGRBG8_1X8,
    @@ -149,7 +119,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 2,
    .s.width = 8,
    .s.bpp = 1,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_SRGGB8,
    .code = MEDIA_BUS_FMT_SRGGB8_1X8,
    @@ -157,7 +126,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 2,
    .s.width = 8,
    .s.bpp = 1,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_RGB565,
    .code = MEDIA_BUS_FMT_RGB565_2X8_LE,
    @@ -165,7 +133,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    }, {
    .fourcc = V4L2_PIX_FMT_RGB565X,
    .code = MEDIA_BUS_FMT_RGB565_2X8_BE,
    @@ -173,7 +140,6 @@ static struct vpfe_fmt formats[] = {
    .l.bpp = 4,
    .s.width = 8,
    .s.bpp = 2,
    - .supported = false,
    },
    };

    @@ -181,13 +147,14 @@ static int
    __vpfe_get_format(struct vpfe_device *vpfe,
    struct v4l2_format *format, unsigned int *bpp);

    -static struct vpfe_fmt *find_format_by_code(unsigned int code)
    +static struct vpfe_fmt *find_format_by_code(struct vpfe_device *vpfe,
    + unsigned int code)
    {
    struct vpfe_fmt *fmt;
    unsigned int k;

    - for (k = 0; k < ARRAY_SIZE(formats); k++) {
    - fmt = &formats[k];
    + for (k = 0; k < vpfe->num_active_fmt; k++) {
    + fmt = vpfe->active_fmt[k];
    if (fmt->code == code)
    return fmt;
    }
    @@ -195,13 +162,14 @@ static struct vpfe_fmt *find_format_by_code(unsigned int code)
    return NULL;
    }

    -static struct vpfe_fmt *find_format_by_pix(unsigned int pixelformat)
    +static struct vpfe_fmt *find_format_by_pix(struct vpfe_device *vpfe,
    + unsigned int pixelformat)
    {
    struct vpfe_fmt *fmt;
    unsigned int k;

    - for (k = 0; k < ARRAY_SIZE(formats); k++) {
    - fmt = &formats[k];
    + for (k = 0; k < vpfe->num_active_fmt; k++) {
    + fmt = vpfe->active_fmt[k];
    if (fmt->fourcc == pixelformat)
    return fmt;
    }
    @@ -218,7 +186,7 @@ mbus_to_pix(struct vpfe_device *vpfe,
    unsigned int bus_width = sdinfo->vpfe_param.bus_width;
    struct vpfe_fmt *fmt;

    - fmt = find_format_by_code(mbus->code);
    + fmt = find_format_by_code(vpfe, mbus->code);
    if (WARN_ON(fmt == NULL)) {
    pr_err("Invalid mbus code set\n");
    *bpp = 1;
    @@ -241,12 +209,12 @@ static void pix_to_mbus(struct vpfe_device *vpfe,
    {
    struct vpfe_fmt *fmt;

    - fmt = find_format_by_pix(pix_fmt->pixelformat);
    + fmt = find_format_by_pix(vpfe, pix_fmt->pixelformat);
    if (!fmt) {
    /* default to first entry */
    vpfe_dbg(3, vpfe, "Invalid pixel code: %x, default used instead\n",
    pix_fmt->pixelformat);
    - fmt = &formats[0];
    + fmt = vpfe->active_fmt[0];
    }

    memset(mbus_fmt, 0, sizeof(*mbus_fmt));
    @@ -1494,8 +1462,7 @@ static int vpfe_enum_fmt(struct file *file, void *priv,
    {
    struct vpfe_device *vpfe = video_drvdata(file);
    struct vpfe_subdev_info *sdinfo;
    - struct vpfe_fmt *fmt = NULL;
    - unsigned int k;
    + struct vpfe_fmt *fmt;

    vpfe_dbg(2, vpfe, "vpfe_enum_format index:%d\n",
    f->index);
    @@ -1504,17 +1471,10 @@ static int vpfe_enum_fmt(struct file *file, void *priv,
    if (!sdinfo->sd)
    return -EINVAL;

    - if (f->index > ARRAY_SIZE(formats))
    + if (f->index >= vpfe->num_active_fmt)
    return -EINVAL;

    - for (k = 0; k < ARRAY_SIZE(formats); k++) {
    - if (formats[k].index == f->index) {
    - fmt = &formats[k];
    - break;
    - }
    - }
    - if (!fmt)
    - return -EINVAL;
    + fmt = vpfe->active_fmt[f->index];

    f->pixelformat = fmt->fourcc;

    @@ -1593,7 +1553,7 @@ static int vpfe_enum_size(struct file *file, void *priv,
    vpfe_dbg(2, vpfe, "vpfe_enum_size\n");

    /* check for valid format */
    - fmt = find_format_by_pix(fsize->pixel_format);
    + fmt = find_format_by_pix(vpfe, fsize->pixel_format);
    if (!fmt) {
    vpfe_dbg(3, vpfe, "Invalid pixel code: %x, default used instead\n",
    fsize->pixel_format);
    @@ -2281,8 +2241,10 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
    struct vpfe_device, v4l2_dev);
    struct v4l2_subdev_mbus_code_enum mbus_code;
    struct vpfe_subdev_info *sdinfo;
    + struct vpfe_fmt *fmt;
    + int ret = 0;
    bool found = false;
    - int i, j;
    + int i, j, k;

    vpfe_dbg(1, vpfe, "vpfe_async_bound\n");

    @@ -2304,27 +2266,37 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,

    vpfe->video_dev.tvnorms |= sdinfo->inputs[0].std;

    - /* setup the supported formats & indexes */
    - for (j = 0, i = 0; ; ++j) {
    - struct vpfe_fmt *fmt;
    - int ret;
    -
    + vpfe->num_active_fmt = 0;
    + for (j = 0, i = 0; (ret != -EINVAL); ++j) {
    memset(&mbus_code, 0, sizeof(mbus_code));
    mbus_code.index = j;
    mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
    ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
    - NULL, &mbus_code);
    + NULL, &mbus_code);
    if (ret)
    - break;
    -
    - fmt = find_format_by_code(mbus_code.code);
    - if (!fmt)
    continue;

    - fmt->supported = true;
    - fmt->index = i++;
    + vpfe_dbg(3, vpfe,
    + "subdev %s: code: %04x idx: %d\n",
    + subdev->name, mbus_code.code, j);
    +
    + for (k = 0; k < ARRAY_SIZE(formats); k++) {
    + fmt = &formats[k];
    + if (mbus_code.code != fmt->code)
    + continue;
    + vpfe->active_fmt[i] = fmt;
    + vpfe_dbg(3, vpfe,
    + "matched fourcc: %4.4s code: %04x idx: %d\n",
    + (char *)&fmt->fourcc, mbus_code.code, i);
    + vpfe->num_active_fmt = ++i;
    + }
    }

    + if (!i) {
    + vpfe_err(vpfe, "No suitable format reported by subdev %s\n",
    + subdev->name);
    + return -EINVAL;
    + }
    return 0;
    }

    diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h
    index 2dde09780215..6f25750f84e4 100644
    --- a/drivers/media/platform/am437x/am437x-vpfe.h
    +++ b/drivers/media/platform/am437x/am437x-vpfe.h
    @@ -215,6 +215,37 @@ struct vpfe_ccdc {
    u32 ccdc_ctx[VPFE_REG_END / sizeof(u32)];
    };

    +/*
    + * struct bus_format - VPFE bus format information
    + * @width: Bits per pixel (when transferred over a bus)
    + * @bpp: Bytes per pixel (when stored in memory)
    + */
    +struct bus_format {
    + unsigned int width;
    + unsigned int bpp;
    +};
    +
    +/*
    + * struct vpfe_fmt - VPFE media bus format information
    + * @fourcc: V4L2 pixel format code
    + * @code: V4L2 media bus format code
    + * @l: 10 bit bus format info
    + * @s: 8 bit bus format info
    + */
    +struct vpfe_fmt {
    + u32 fourcc;
    + u32 code;
    + struct bus_format l;
    + struct bus_format s;
    +};
    +
    +/*
    + * This value needs to be at least as large as the number of entry in
    + * formats[].
    + * When formats[] is modified make sure to adjust this value also.
    + */
    +#define VPFE_MAX_ACTIVE_FMT 10
    +
    struct vpfe_device {
    /* V4l2 specific parameters */
    /* Identifies video device for this channel */
    @@ -252,6 +283,9 @@ struct vpfe_device {
    struct v4l2_format fmt;
    /* Used to store current bytes per pixel based on current format */
    unsigned int bpp;
    + struct vpfe_fmt *active_fmt[VPFE_MAX_ACTIVE_FMT];
    + unsigned int num_active_fmt;
    +
    /*
    * used when IMP is chained to store the crop window which
    * is different from the image window
    --
    2.17.1
    \
     
     \ /
      Last update: 2019-09-09 18:27    [W:2.940 / U:0.276 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site