[PATCH v2 6/8] v4l: vsp1: Add support for the DISCOM entity
jacopo mondi
jacopo at jmondi.org
Sat Apr 28 10:40:02 UTC 2018
HI Laurent,
a few comments, mostly minor ones...
On Mon, Apr 23, 2018 at 01:34:28AM +0300, Laurent Pinchart wrote:
> The DISCOM calculates a CRC on a configurable window of the frame. It
> interfaces to the VSP through the UIF glue, hence the name used in the
> code.
>
> The module supports configuration of the CRC window through the crop
> rectangle on the ink pad of the corresponding entity. However, unlike
sink pad?
> the traditional V4L2 subdevice model, the crop rectangle does not
> influence the format on the source pad.
>
> Modeling the DISCOM as a sink-only entity would allow adhering to the
> V4L2 subdevice model at the expense of more complex code in the driver,
> as at the hardware level the UIF is handled as a sink+source entity. As
> the DISCOM is only present in R-Car Gen3 VSP-D and VSP-DL instances it
> is not exposed to userspace through V4L2 but controlled through the DU
> driver. We can thus change this model later if needed without fear of
> affecting userspace.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> ---
> Changes since v1:
>
> - Don't return uninitialized value from uif_set_selection()
> ---
> drivers/media/platform/vsp1/Makefile | 2 +-
> drivers/media/platform/vsp1/vsp1.h | 4 +
> drivers/media/platform/vsp1/vsp1_drv.c | 20 +++
> drivers/media/platform/vsp1/vsp1_entity.c | 6 +
> drivers/media/platform/vsp1/vsp1_entity.h | 1 +
> drivers/media/platform/vsp1/vsp1_regs.h | 41 +++++
> drivers/media/platform/vsp1/vsp1_uif.c | 271 ++++++++++++++++++++++++++++++
> drivers/media/platform/vsp1/vsp1_uif.h | 32 ++++
> 8 files changed, 376 insertions(+), 1 deletion(-)
> create mode 100644 drivers/media/platform/vsp1/vsp1_uif.c
> create mode 100644 drivers/media/platform/vsp1/vsp1_uif.h
>
> diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
> index 596775f932c0..4bb4dcbef7b5 100644
> --- a/drivers/media/platform/vsp1/Makefile
> +++ b/drivers/media/platform/vsp1/Makefile
> @@ -5,6 +5,6 @@ vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
> vsp1-y += vsp1_clu.o vsp1_hsit.o vsp1_lut.o
> vsp1-y += vsp1_brx.o vsp1_sru.o vsp1_uds.o
> vsp1-y += vsp1_hgo.o vsp1_hgt.o vsp1_histo.o
> -vsp1-y += vsp1_lif.o
> +vsp1-y += vsp1_lif.o vsp1_uif.o
>
> obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 9cf4e1c4b036..33f632331474 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -36,10 +36,12 @@ struct vsp1_lut;
> struct vsp1_rwpf;
> struct vsp1_sru;
> struct vsp1_uds;
> +struct vsp1_uif;
>
> #define VSP1_MAX_LIF 2
> #define VSP1_MAX_RPF 5
> #define VSP1_MAX_UDS 3
> +#define VSP1_MAX_UIF 2
> #define VSP1_MAX_WPF 4
>
> #define VSP1_HAS_LUT (1 << 1)
> @@ -60,6 +62,7 @@ struct vsp1_device_info {
> unsigned int lif_count;
> unsigned int rpf_count;
> unsigned int uds_count;
> + unsigned int uif_count;
> unsigned int wpf_count;
> unsigned int num_bru_inputs;
> bool uapi;
> @@ -86,6 +89,7 @@ struct vsp1_device {
> struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
> struct vsp1_sru *sru;
> struct vsp1_uds *uds[VSP1_MAX_UDS];
> + struct vsp1_uif *uif[VSP1_MAX_UIF];
> struct vsp1_rwpf *wpf[VSP1_MAX_WPF];
>
> struct list_head entities;
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 331a2e0af0d3..d29f9c4baebe 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -35,6 +35,7 @@
> #include "vsp1_rwpf.h"
> #include "vsp1_sru.h"
> #include "vsp1_uds.h"
> +#include "vsp1_uif.h"
> #include "vsp1_video.h"
>
> /* -----------------------------------------------------------------------------
> @@ -409,6 +410,19 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
> list_add_tail(&uds->entity.list_dev, &vsp1->entities);
> }
>
> + for (i = 0; i < vsp1->info->uif_count; ++i) {
> + struct vsp1_uif *uif;
> +
> + uif = vsp1_uif_create(vsp1, i);
> + if (IS_ERR(uif)) {
> + ret = PTR_ERR(uif);
> + goto done;
> + }
> +
> + vsp1->uif[i] = uif;
> + list_add_tail(&uif->entity.list_dev, &vsp1->entities);
> + }
> +
> for (i = 0; i < vsp1->info->wpf_count; ++i) {
> struct vsp1_rwpf *wpf;
>
> @@ -513,6 +527,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
> for (i = 0; i < vsp1->info->uds_count; ++i)
> vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED);
>
> + for (i = 0; i < vsp1->info->uif_count; ++i)
> + vsp1_write(vsp1, VI6_DPR_UIF_ROUTE(i), VI6_DPR_NODE_UNUSED);
> +
> vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED);
> vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED);
> vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED);
> @@ -740,6 +757,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
> .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
> .lif_count = 1,
> .rpf_count = 5,
> + .uif_count = 1,
> .wpf_count = 2,
> .num_bru_inputs = 5,
> }, {
> @@ -749,6 +767,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
> .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
> .lif_count = 1,
> .rpf_count = 5,
> + .uif_count = 1,
> .wpf_count = 1,
> .num_bru_inputs = 5,
> }, {
> @@ -758,6 +777,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
> .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
> .lif_count = 2,
> .rpf_count = 5,
> + .uif_count = 2,
> .wpf_count = 2,
> .num_bru_inputs = 5,
> },
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 181a583aecad..122e60eb1489 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -539,6 +539,10 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
> { VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx), \
> { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }
>
> +#define VSP1_ENTITY_ROUTE_UIF(idx) \
> + { VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx), \
> + { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }
> +
> #define VSP1_ENTITY_ROUTE_WPF(idx) \
> { VSP1_ENTITY_WPF, idx, 0, \
> { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
> @@ -567,6 +571,8 @@ static const struct vsp1_route vsp1_routes[] = {
> VSP1_ENTITY_ROUTE_UDS(0),
> VSP1_ENTITY_ROUTE_UDS(1),
> VSP1_ENTITY_ROUTE_UDS(2),
> + VSP1_ENTITY_ROUTE_UIF(0), /* Named UIF4 in the documentation */
> + VSP1_ENTITY_ROUTE_UIF(1), /* Named UIF5 in the documentation */
> VSP1_ENTITY_ROUTE_WPF(0),
> VSP1_ENTITY_ROUTE_WPF(1),
> VSP1_ENTITY_ROUTE_WPF(2),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 0839a62cfa71..94490d697dcf 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -33,6 +33,7 @@ enum vsp1_entity_type {
> VSP1_ENTITY_RPF,
> VSP1_ENTITY_SRU,
> VSP1_ENTITY_UDS,
> + VSP1_ENTITY_UIF,
> VSP1_ENTITY_WPF,
> };
>
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index 3201ad4b77d4..0d249ff9f564 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -307,6 +307,44 @@
> #define VI6_WPF_WRBCK_CTRL 0x1034
> #define VI6_WPF_WRBCK_CTRL_WBMD (1 << 0)
>
> +/* -----------------------------------------------------------------------------
> + * UIF Control Registers
> + */
> +
> +#define VI6_UIF_OFFSET 0x100
> +
> +#define VI6_UIF_DISCOM_DOCMCR 0x1c00
> +#define VI6_UIF_DISCOM_DOCMCR_CMPRU (1 << 16)
> +#define VI6_UIF_DISCOM_DOCMCR_CMPR (1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMSTR 0x1c04
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE (1 << 1)
> +#define VI6_UIF_DISCOM_DOCMSTR_CMPST (1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMCLSTR 0x1c08
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE (1 << 1)
> +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST (1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMIENR 0x1c0c
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN (1 << 1)
> +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN (1 << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMMDR 0x1c10
> +#define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n) ((n) << 16)
> +
> +#define VI6_UIF_DISCOM_DOCMPMR 0x1c14
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n) ((n) << 17)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n) ((n) << 8)
> +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF (1 << 7)
> +#define VI6_UIF_DISCOM_DOCMPMR_SEL(n) ((n) << 0)
> +
> +#define VI6_UIF_DISCOM_DOCMECRCR 0x1c18
> +#define VI6_UIF_DISCOM_DOCMCCRCR 0x1c1c
> +#define VI6_UIF_DISCOM_DOCMSPXR 0x1c20
> +#define VI6_UIF_DISCOM_DOCMSPYR 0x1c24
> +#define VI6_UIF_DISCOM_DOCMSZXR 0x1c28
> +#define VI6_UIF_DISCOM_DOCMSZYR 0x1c2c
> +
> /* -----------------------------------------------------------------------------
> * DPR Control Registers
> */
> @@ -339,7 +377,10 @@
> #define VI6_DPR_SMPPT_PT_MASK (0x3f << 0)
> #define VI6_DPR_SMPPT_PT_SHIFT 0
>
> +#define VI6_DPR_UIF_ROUTE(n) (0x2074 + (n) * 4)
> +
> #define VI6_DPR_NODE_RPF(n) (n)
> +#define VI6_DPR_NODE_UIF(n) (12 + (n))
> #define VI6_DPR_NODE_SRU 16
> #define VI6_DPR_NODE_UDS(n) (17 + (n))
> #define VI6_DPR_NODE_LUT 22
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.c b/drivers/media/platform/vsp1/vsp1_uif.c
> new file mode 100644
> index 000000000000..6de7e9c801ae
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.c
> @@ -0,0 +1,271 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * vsp1_uif.c -- R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart at ideasonboard.com)
> + */
> +
> +#include <linux/device.h>
> +#include <linux/gfp.h>
> +#include <linux/sys_soc.h>
> +
> +#include <media/media-entity.h>
> +#include <media/v4l2-subdev.h>
> +
> +#include "vsp1.h"
> +#include "vsp1_dl.h"
> +#include "vsp1_entity.h"
> +#include "vsp1_uif.h"
> +
> +#define UIF_MIN_SIZE 4U
> +#define UIF_MAX_SIZE 8190U
> +
> +/* -----------------------------------------------------------------------------
> + * Device Access
> + */
> +
> +static inline u32 vsp1_uif_read(struct vsp1_uif *uif, u32 reg)
> +{
> + return vsp1_read(uif->entity.vsp1,
> + uif->entity.index * VI6_UIF_OFFSET + reg);
> +}
> +static inline void vsp1_uif_write(struct vsp1_uif *uif, struct vsp1_dl_list *dl,
> + u32 reg, u32 data)
> +{
> + vsp1_dl_list_write(dl, reg + uif->entity.index * VI6_UIF_OFFSET, data);
> +}
> +
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif)
> +{
> + return vsp1_uif_read(uif, VI6_UIF_DISCOM_DOCMCCRCR);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Pad Operations
> + */
> +
> +static const unsigned int uif_codes[] = {
> + MEDIA_BUS_FMT_ARGB8888_1X32,
> + MEDIA_BUS_FMT_AHSV8888_1X32,
> + MEDIA_BUS_FMT_AYUV8_1X32,
> +};
> +
> +static int uif_enum_mbus_code(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + return vsp1_subdev_enum_mbus_code(subdev, cfg, code, uif_codes,
> + ARRAY_SIZE(uif_codes));
> +}
> +
> +static int uif_enum_frame_size(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_frame_size_enum *fse)
> +{
> + return vsp1_subdev_enum_frame_size(subdev, cfg, fse, UIF_MIN_SIZE,
> + UIF_MIN_SIZE, UIF_MAX_SIZE,
> + UIF_MAX_SIZE);
> +}
> +
> +static int uif_set_format(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + return vsp1_subdev_set_pad_format(subdev, cfg, fmt, uif_codes,
> + ARRAY_SIZE(uif_codes),
> + UIF_MIN_SIZE, UIF_MIN_SIZE,
> + UIF_MAX_SIZE, UIF_MAX_SIZE);
> +}
> +
> +static int uif_get_selection(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_selection *sel)
> +{
> + struct vsp1_uif *uif = to_uif(subdev);
> + struct v4l2_subdev_pad_config *config;
> + struct v4l2_mbus_framefmt *format;
> + int ret = 0;
> +
> + if (sel->pad != UIF_PAD_SINK)
> + return -EINVAL;
> +
> + mutex_lock(&uif->entity.lock);
> +
> + config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> + if (!config) {
> + ret = -EINVAL;
> + goto done;
> + }
> +
> + switch (sel->target) {
> + case V4L2_SEL_TGT_CROP_BOUNDS:
> + case V4L2_SEL_TGT_CROP_DEFAULT:
> + format = vsp1_entity_get_pad_format(&uif->entity, config,
> + UIF_PAD_SINK);
> + sel->r.left = 0;
> + sel->r.top = 0;
> + sel->r.width = format->width;
> + sel->r.height = format->height;
> + break;
> +
> + case V4L2_SEL_TGT_CROP:
> + sel->r = *vsp1_entity_get_pad_selection(&uif->entity, config,
> + sel->pad, sel->target);
> + break;
> +
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> +done:
> + mutex_unlock(&uif->entity.lock);
> + return ret;
> +}
> +
> +static int uif_set_selection(struct v4l2_subdev *subdev,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_selection *sel)
> +{
> + struct vsp1_uif *uif = to_uif(subdev);
> + struct v4l2_subdev_pad_config *config;
> + struct v4l2_mbus_framefmt *format;
> + struct v4l2_rect *selection;
> + int ret = 0;
> +
> + if (sel->pad != UIF_PAD_SINK ||
> + sel->target != V4L2_SEL_TGT_CROP)
> + return -EINVAL;
> +
> + mutex_lock(&uif->entity.lock);
> +
> + config = vsp1_entity_get_pad_config(&uif->entity, cfg, sel->which);
> + if (!config) {
> + ret = -EINVAL;
> + goto done;
> + }
> +
> + /* The crop rectangle must be inside the input frame. */
> + format = vsp1_entity_get_pad_format(&uif->entity, config, UIF_PAD_SINK);
> +
> + sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
> + sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
> + sel->r.width = clamp_t(unsigned int, sel->r.width, UIF_MIN_SIZE,
> + format->width - sel->r.left);
> + sel->r.height = clamp_t(unsigned int, sel->r.height, UIF_MIN_SIZE,
> + format->height - sel->r.top);
> +
> + /* Store the crop rectangle. */
> + selection = vsp1_entity_get_pad_selection(&uif->entity, config,
> + sel->pad, V4L2_SEL_TGT_CROP);
> + *selection = sel->r;
> +
> +done:
> + mutex_unlock(&uif->entity.lock);
> + return ret;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * V4L2 Subdevice Operations
> + */
> +
> +static const struct v4l2_subdev_pad_ops uif_pad_ops = {
> + .init_cfg = vsp1_entity_init_cfg,
> + .enum_mbus_code = uif_enum_mbus_code,
> + .enum_frame_size = uif_enum_frame_size,
> + .get_fmt = vsp1_subdev_get_pad_format,
> + .set_fmt = uif_set_format,
> + .get_selection = uif_get_selection,
> + .set_selection = uif_set_selection,
> +};
> +
> +static const struct v4l2_subdev_ops uif_ops = {
> + .pad = &uif_pad_ops,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * VSP1 Entity Operations
> + */
> +
> +static void uif_configure(struct vsp1_entity *entity,
> + struct vsp1_pipeline *pipe,
> + struct vsp1_dl_list *dl,
> + enum vsp1_entity_params params)
> +{
> + struct vsp1_uif *uif = to_uif(&entity->subdev);
> + const struct v4l2_rect *crop;
> + unsigned int left;
> + unsigned int width;
> +
> + /*
> + * Per-partition configuration isn't needed as the DISCOM is used in
> + * display pipelines only.
> + */
> + if (params != VSP1_ENTITY_PARAMS_INIT)
> + return;
> +
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMPMR,
> + VI6_UIF_DISCOM_DOCMPMR_SEL(9));
> +
> + crop = vsp1_entity_get_pad_selection(entity, entity->config,
> + UIF_PAD_SINK, V4L2_SEL_TGT_CROP);
> +
> + /* On M3-W the horizontal coordinates are twice the register value. */
> + if (uif->m3w_quirk) {
> + left = crop->left / 2;
> + width = crop->width / 2;
> + } else {
> + left = crop->left;
> + width = crop->width;
> + }
I would write this as
left = crop->left;
width = crop->width;
/* On M3-W the horizontal coordinates are twice the register value. */
if (uif->m3w_quirk) {
left /= 2;
width /= 2;
}
But that's really up to you.
> +
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPXR, left);
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSPYR, crop->top);
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZXR, width);
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMSZYR, crop->height);
> +
> + vsp1_uif_write(uif, dl, VI6_UIF_DISCOM_DOCMCR,
> + VI6_UIF_DISCOM_DOCMCR_CMPR);
> +}
> +
> +static const struct vsp1_entity_operations uif_entity_ops = {
> + .configure = uif_configure,
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Initialization and Cleanup
> + */
> +
> +static const struct soc_device_attribute vsp1_r8a7796[] = {
> + { .soc_id = "r8a7796" },
> + { /* sentinel */ }
> +};
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index)
> +{
> + struct vsp1_uif *uif;
> + char name[6];
> + int ret;
> +
> + uif = devm_kzalloc(vsp1->dev, sizeof(*uif), GFP_KERNEL);
> + if (uif == NULL)
if (!uif)
Otherwise checkpatch complains iirc.
Those are very minor comments, so feel free to add my reviewed by tag
Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
Thanks
j
> + return ERR_PTR(-ENOMEM);
> +
> + if (soc_device_match(vsp1_r8a7796))
> + uif->m3w_quirk = true;
> +
> + uif->entity.ops = &uif_entity_ops;
> + uif->entity.type = VSP1_ENTITY_UIF;
> + uif->entity.index = index;
> +
> + /* The datasheet names the two UIF instances UIF4 and UIF5. */
> + sprintf(name, "uif.%u", index + 4);
> + ret = vsp1_entity_init(vsp1, &uif->entity, name, 2, &uif_ops,
> + MEDIA_ENT_F_PROC_VIDEO_STATISTICS);
> + if (ret < 0)
> + return ERR_PTR(ret);
> +
> + return uif;
> +}
> diff --git a/drivers/media/platform/vsp1/vsp1_uif.h b/drivers/media/platform/vsp1/vsp1_uif.h
> new file mode 100644
> index 000000000000..c71ab5f6a6f8
> --- /dev/null
> +++ b/drivers/media/platform/vsp1/vsp1_uif.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * vsp1_uif.h -- R-Car VSP1 User Logic Interface
> + *
> + * Copyright (C) 2017-2018 Laurent Pinchart
> + *
> + * Contact: Laurent Pinchart (laurent.pinchart at ideasonboard.com)
> + */
> +#ifndef __VSP1_UIF_H__
> +#define __VSP1_UIF_H__
> +
> +#include "vsp1_entity.h"
> +
> +struct vsp1_device;
> +
> +#define UIF_PAD_SINK 0
> +#define UIF_PAD_SOURCE 1
> +
> +struct vsp1_uif {
> + struct vsp1_entity entity;
> + bool m3w_quirk;
> +};
> +
> +static inline struct vsp1_uif *to_uif(struct v4l2_subdev *subdev)
> +{
> + return container_of(subdev, struct vsp1_uif, entity.subdev);
> +}
> +
> +struct vsp1_uif *vsp1_uif_create(struct vsp1_device *vsp1, unsigned int index);
> +u32 vsp1_uif_get_crc(struct vsp1_uif *uif);
> +
> +#endif /* __VSP1_UIF_H__ */
> --
> Regards,
>
> Laurent Pinchart
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20180428/948d594e/attachment.sig>
More information about the dri-devel
mailing list