[PATCH v2 07/14] v4l: vsp1: Add support for the BRS entity
Kieran Bingham
kieran.bingham+renesas at ideasonboard.com
Thu Jul 13 13:38:40 UTC 2017
On 26/06/17 19:12, Laurent Pinchart wrote:
> The Blend/ROP Sub Unit (BRS) is a stripped-down version of the BRU found
> in several VSP2 instances. Compared to a regular BRU, it supports two
> inputs only, and thus has no ROP unit.
>
> Add support for the BRS by modeling it as a new entity type, but reuse
s/modeling/modelling/
> the vsp1_bru object underneath. Chaining the BRU and BRS entities seems
> to be supported by the hardware but isn't implemented yet as it isn't
> the primary use case for the BRS.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> ---
> drivers/media/platform/vsp1/vsp1.h | 2 +
> drivers/media/platform/vsp1/vsp1_bru.c | 45 ++++++++++++++--------
> drivers/media/platform/vsp1/vsp1_bru.h | 4 +-
> drivers/media/platform/vsp1/vsp1_drv.c | 19 +++++++++-
> drivers/media/platform/vsp1/vsp1_entity.c | 13 ++++++-
> drivers/media/platform/vsp1/vsp1_entity.h | 1 +
> drivers/media/platform/vsp1/vsp1_pipe.c | 7 ++--
> drivers/media/platform/vsp1/vsp1_regs.h | 26 +++++++++----
> drivers/media/platform/vsp1/vsp1_video.c | 63 ++++++++++++++++++++-----------
> drivers/media/platform/vsp1/vsp1_wpf.c | 4 +-
> 10 files changed, 130 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 847963b6e9eb..73858a0ed35c 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -54,6 +54,7 @@ struct vsp1_uds;
> #define VSP1_HAS_WPF_HFLIP (1 << 6)
> #define VSP1_HAS_HGO (1 << 7)
> #define VSP1_HAS_HGT (1 << 8)
> +#define VSP1_HAS_BRS (1 << 9)
>
> struct vsp1_device_info {
> u32 version;
> @@ -76,6 +77,7 @@ struct vsp1_device {
> struct rcar_fcp_device *fcp;
> struct device *bus_master;
>
> + struct vsp1_bru *brs;
> struct vsp1_bru *bru;
> struct vsp1_clu *clu;
> struct vsp1_hgo *hgo;
> diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
> index 85362c5ef57a..e8fd2ae3b3eb 100644
> --- a/drivers/media/platform/vsp1/vsp1_bru.c
> +++ b/drivers/media/platform/vsp1/vsp1_bru.c
> @@ -33,7 +33,7 @@
> static inline void vsp1_bru_write(struct vsp1_bru *bru, struct vsp1_dl_list *dl,
> u32 reg, u32 data)
> {
> - vsp1_dl_list_write(dl, reg, data);
> + vsp1_dl_list_write(dl, bru->base + reg, data);
> }
>
> /* -----------------------------------------------------------------------------
> @@ -332,11 +332,14 @@ static void bru_configure(struct vsp1_entity *entity,
> /*
> * Route BRU input 1 as SRC input to the ROP unit and configure the ROP
> * unit with a NOP operation to make BRU input 1 available as the
> - * Blend/ROP unit B SRC input.
> + * Blend/ROP unit B SRC input. Only needed for BRU, the BRS has no ROP
> + * unit.
> */
> - vsp1_bru_write(bru, dl, VI6_BRU_ROP, VI6_BRU_ROP_DSTSEL_BRUIN(1) |
> - VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
> - VI6_BRU_ROP_AROP(VI6_ROP_NOP));
> + if (entity->type == VSP1_ENTITY_BRU)
> + vsp1_bru_write(bru, dl, VI6_BRU_ROP,
> + VI6_BRU_ROP_DSTSEL_BRUIN(1) |
> + VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
> + VI6_BRU_ROP_AROP(VI6_ROP_NOP));
>
> for (i = 0; i < bru->entity.source_pad; ++i) {
> bool premultiplied = false;
> @@ -366,12 +369,13 @@ static void bru_configure(struct vsp1_entity *entity,
> ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;
>
> /*
> - * Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to
> - * D in that order. The Blend/ROP unit B SRC is hardwired to the
> - * ROP unit output, the corresponding register bits must be set
> - * to 0.
> + * Route inputs 0 to 3 as SRC inputs to Blend/ROP units A to D
> + * in that order. In the BRU the Blend/ROP unit B SRC is
> + * hardwired to the ROP unit output, the corresponding register
> + * bits must be set to 0. The BRS has no ROP unit and doesn't
> + * need any special processing.
> */
> - if (i != 1)
> + if (!(entity->type == VSP1_ENTITY_BRU && i == 1))
If we're using this module for both BRU and BRS, would an is_bru(entity) and
is_brs(entity) be cleaner here ?
Not required - just thinking outloud...
Actaully - it's only this line that would be affected so not really needed. I
thought there would be more uses/differences.
> ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
>
> vsp1_bru_write(bru, dl, VI6_BRU_CTRL(i), ctrl);
> @@ -407,20 +411,31 @@ static const struct vsp1_entity_operations bru_entity_ops = {
> * Initialization and Cleanup
> */
>
> -struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
> +struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
> + enum vsp1_entity_type type)
> {
> struct vsp1_bru *bru;
> + unsigned int num_pads;
> + const char *name;
> int ret;
>
> bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL);
> if (bru == NULL)
> return ERR_PTR(-ENOMEM);
>
> + bru->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE : VI6_BRS_BASE;
> bru->entity.ops = &bru_entity_ops;
> - bru->entity.type = VSP1_ENTITY_BRU;
> + bru->entity.type = type;
> +
> + if (type == VSP1_ENTITY_BRU) {
> + num_pads = vsp1->info->num_bru_inputs + 1;
> + name = "bru";
> + } else {
> + num_pads = 3;
> + name = "brs";
> + }
>
> - ret = vsp1_entity_init(vsp1, &bru->entity, "bru",
> - vsp1->info->num_bru_inputs + 1, &bru_ops,
> + ret = vsp1_entity_init(vsp1, &bru->entity, name, num_pads, &bru_ops,
> MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
> if (ret < 0)
> return ERR_PTR(ret);
> @@ -435,7 +450,7 @@ struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
> bru->entity.subdev.ctrl_handler = &bru->ctrls;
>
> if (bru->ctrls.error) {
> - dev_err(vsp1->dev, "bru: failed to initialize controls\n");
> + dev_err(vsp1->dev, "%s: failed to initialize controls\n", name);
> ret = bru->ctrls.error;
> vsp1_entity_destroy(&bru->entity);
> return ERR_PTR(ret);
> diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
> index 828a3fcadea8..c98ed96d8de6 100644
> --- a/drivers/media/platform/vsp1/vsp1_bru.h
> +++ b/drivers/media/platform/vsp1/vsp1_bru.h
> @@ -26,6 +26,7 @@ struct vsp1_rwpf;
>
> struct vsp1_bru {
> struct vsp1_entity entity;
> + unsigned int base;
>
> struct v4l2_ctrl_handler ctrls;
>
> @@ -41,6 +42,7 @@ static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
> return container_of(subdev, struct vsp1_bru, entity.subdev);
> }
>
> -struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1);
> +struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1,
> + enum vsp1_entity_type type);
>
> #endif /* __VSP1_BRU_H__ */
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 5a467b118a1c..6a9aeb71aedf 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -84,6 +84,10 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data)
> *
> * - from a UDS to a UDS (UDS entities can't be chained)
> * - from an entity to itself (no loops are allowed)
> + *
> + * Furthermore, the BRS can't be connected to histogram generators, but no
> + * special check is currently needed as all VSP instances that include a BRS
> + * have no histogram generator.
> */
> static int vsp1_create_sink_links(struct vsp1_device *vsp1,
> struct vsp1_entity *sink)
> @@ -261,8 +265,18 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
> }
>
> /* Instantiate all the entities. */
> + if (vsp1->info->features & VSP1_HAS_BRS) {
> + vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS);
> + if (IS_ERR(vsp1->brs)) {
> + ret = PTR_ERR(vsp1->brs);
> + goto done;
> + }
> +
> + list_add_tail(&vsp1->brs->entity.list_dev, &vsp1->entities);
> + }
> +
> if (vsp1->info->features & VSP1_HAS_BRU) {
> - vsp1->bru = vsp1_bru_create(vsp1);
> + vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU);
> if (IS_ERR(vsp1->bru)) {
> ret = PTR_ERR(vsp1->bru);
> goto done;
> @@ -502,6 +516,9 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
> vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED);
> vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED);
>
> + if (vsp1->info->features & VSP1_HAS_BRS)
> + vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED);
> +
> vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
> (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT));
> vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) |
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
> index 71dd903263ad..c06f7db093db 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.c
> +++ b/drivers/media/platform/vsp1/vsp1_entity.c
> @@ -29,6 +29,7 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
> struct vsp1_dl_list *dl)
> {
> struct vsp1_entity *source;
> + u32 route;
>
> if (entity->type == VSP1_ENTITY_HGO) {
> u32 smppt;
> @@ -62,8 +63,14 @@ void vsp1_entity_route_setup(struct vsp1_entity *entity,
> if (source->route->reg == 0)
> return;
>
> - vsp1_dl_list_write(dl, source->route->reg,
> - source->sink->route->inputs[source->sink_pad]);
> + route = source->sink->route->inputs[source->sink_pad];
> + /*
> + * The ILV and BRS share the same data path route. The extra BRSSEL bit
> + * selects between the ILV and BRS.
> + */
> + if (source->type == VSP1_ENTITY_BRS)
> + route |= VI6_DPR_ROUTE_BRSSEL;
> + vsp1_dl_list_write(dl, source->route->reg, route);
> }
>
> /* -----------------------------------------------------------------------------
> @@ -450,6 +457,8 @@ struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
> { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }
>
> static const struct vsp1_route vsp1_routes[] = {
> + { VSP1_ENTITY_BRS, 0, VI6_DPR_ILV_BRS_ROUTE,
> + { VI6_DPR_NODE_BRS_IN(0), VI6_DPR_NODE_BRS_IN(1) }, 0 },
> { VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
> { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
> VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
> diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
> index 4362cd4e90ba..11f8363fa6b0 100644
> --- a/drivers/media/platform/vsp1/vsp1_entity.h
> +++ b/drivers/media/platform/vsp1/vsp1_entity.h
> @@ -23,6 +23,7 @@ struct vsp1_dl_list;
> struct vsp1_pipeline;
>
> enum vsp1_entity_type {
> + VSP1_ENTITY_BRS,
> VSP1_ENTITY_BRU,
> VSP1_ENTITY_CLU,
> VSP1_ENTITY_HGO,
> diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c
> index e817623b84e0..9bb961298af2 100644
> --- a/drivers/media/platform/vsp1/vsp1_pipe.c
> +++ b/drivers/media/platform/vsp1/vsp1_pipe.c
> @@ -373,10 +373,11 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
> return;
>
> /*
> - * The BRU background color has a fixed alpha value set to 255, the
> - * output alpha value is thus always equal to 255.
> + * The BRU and BRS background color has a fixed alpha value set to 255,
> + * the output alpha value is thus always equal to 255.
> */
> - if (pipe->uds_input->type == VSP1_ENTITY_BRU)
> + if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
> + pipe->uds_input->type == VSP1_ENTITY_BRS)
> alpha = 255;
>
> vsp1_uds_set_alpha(pipe->uds, dl, alpha);
> diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
> index cd3e32af6e3b..744217e020b9 100644
> --- a/drivers/media/platform/vsp1/vsp1_regs.h
> +++ b/drivers/media/platform/vsp1/vsp1_regs.h
> @@ -238,6 +238,10 @@
> #define VI6_WPF_SRCRPF_VIRACT_SUB (1 << 28)
> #define VI6_WPF_SRCRPF_VIRACT_MST (2 << 28)
> #define VI6_WPF_SRCRPF_VIRACT_MASK (3 << 28)
> +#define VI6_WPF_SRCRPF_VIRACT2_DIS (0 << 24)
> +#define VI6_WPF_SRCRPF_VIRACT2_SUB (1 << 24)
> +#define VI6_WPF_SRCRPF_VIRACT2_MST (2 << 24)
> +#define VI6_WPF_SRCRPF_VIRACT2_MASK (3 << 24)
> #define VI6_WPF_SRCRPF_RPF_ACT_DIS(n) (0 << ((n) * 2))
> #define VI6_WPF_SRCRPF_RPF_ACT_SUB(n) (1 << ((n) * 2))
> #define VI6_WPF_SRCRPF_RPF_ACT_MST(n) (2 << ((n) * 2))
> @@ -321,6 +325,8 @@
> #define VI6_DPR_HST_ROUTE 0x2044
> #define VI6_DPR_HSI_ROUTE 0x2048
> #define VI6_DPR_BRU_ROUTE 0x204c
> +#define VI6_DPR_ILV_BRS_ROUTE 0x2050
> +#define VI6_DPR_ROUTE_BRSSEL (1 << 28)
> #define VI6_DPR_ROUTE_FXA_MASK (0xff << 16)
> #define VI6_DPR_ROUTE_FXA_SHIFT 16
> #define VI6_DPR_ROUTE_FP_MASK (0x3f << 8)
> @@ -344,6 +350,7 @@
> #define VI6_DPR_NODE_CLU 29
> #define VI6_DPR_NODE_HST 30
> #define VI6_DPR_NODE_HSI 31
> +#define VI6_DPR_NODE_BRS_IN(n) (38 + (n))
> #define VI6_DPR_NODE_LIF 55
> #define VI6_DPR_NODE_WPF(n) (56 + (n))
> #define VI6_DPR_NODE_UNUSED 63
> @@ -476,7 +483,7 @@
> #define VI6_HSI_CTRL_EN (1 << 0)
>
> /* -----------------------------------------------------------------------------
> - * BRU Control Registers
> + * BRS and BRU Control Registers
> */
>
> #define VI6_ROP_NOP 0
> @@ -496,7 +503,10 @@
> #define VI6_ROP_NAND 14
> #define VI6_ROP_SET 15
>
> -#define VI6_BRU_INCTRL 0x2c00
> +#define VI6_BRU_BASE 0x2c00
> +#define VI6_BRS_BASE 0x3900
> +
> +#define VI6_BRU_INCTRL 0x0000
> #define VI6_BRU_INCTRL_NRM (1 << 28)
> #define VI6_BRU_INCTRL_DnON (1 << (16 + (n)))
> #define VI6_BRU_INCTRL_DITHn_OFF (0 << ((n) * 4))
> @@ -508,19 +518,19 @@
> #define VI6_BRU_INCTRL_DITHn_MASK (7 << ((n) * 4))
> #define VI6_BRU_INCTRL_DITHn_SHIFT ((n) * 4)
>
> -#define VI6_BRU_VIRRPF_SIZE 0x2c04
> +#define VI6_BRU_VIRRPF_SIZE 0x0004
> #define VI6_BRU_VIRRPF_SIZE_HSIZE_MASK (0x1fff << 16)
> #define VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT 16
> #define VI6_BRU_VIRRPF_SIZE_VSIZE_MASK (0x1fff << 0)
> #define VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT 0
>
> -#define VI6_BRU_VIRRPF_LOC 0x2c08
> +#define VI6_BRU_VIRRPF_LOC 0x0008
> #define VI6_BRU_VIRRPF_LOC_HCOORD_MASK (0x1fff << 16)
> #define VI6_BRU_VIRRPF_LOC_HCOORD_SHIFT 16
> #define VI6_BRU_VIRRPF_LOC_VCOORD_MASK (0x1fff << 0)
> #define VI6_BRU_VIRRPF_LOC_VCOORD_SHIFT 0
>
> -#define VI6_BRU_VIRRPF_COL 0x2c0c
> +#define VI6_BRU_VIRRPF_COL 0x000c
> #define VI6_BRU_VIRRPF_COL_A_MASK (0xff << 24)
> #define VI6_BRU_VIRRPF_COL_A_SHIFT 24
> #define VI6_BRU_VIRRPF_COL_RCR_MASK (0xff << 16)
> @@ -530,7 +540,7 @@
> #define VI6_BRU_VIRRPF_COL_BCB_MASK (0xff << 0)
> #define VI6_BRU_VIRRPF_COL_BCB_SHIFT 0
>
> -#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8 + ((n) <= 3 ? 0 : 4))
> +#define VI6_BRU_CTRL(n) (0x0010 + (n) * 8 + ((n) <= 3 ? 0 : 4))
> #define VI6_BRU_CTRL_RBC (1 << 31)
> #define VI6_BRU_CTRL_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
> #define VI6_BRU_CTRL_DSTSEL_VRPF (4 << 20)
> @@ -543,7 +553,7 @@
> #define VI6_BRU_CTRL_AROP(rop) ((rop) << 0)
> #define VI6_BRU_CTRL_AROP_MASK (0xf << 0)
>
> -#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8 + ((n) <= 3 ? 0 : 4))
> +#define VI6_BRU_BLD(n) (0x0014 + (n) * 8 + ((n) <= 3 ? 0 : 4))
> #define VI6_BRU_BLD_CBES (1 << 31)
> #define VI6_BRU_BLD_CCMDX_DST_A (0 << 28)
> #define VI6_BRU_BLD_CCMDX_255_DST_A (1 << 28)
> @@ -576,7 +586,7 @@
> #define VI6_BRU_BLD_COEFY_MASK (0xff << 0)
> #define VI6_BRU_BLD_COEFY_SHIFT 0
>
> -#define VI6_BRU_ROP 0x2c30
> +#define VI6_BRU_ROP 0x0030 /* Only available on BRU */
> #define VI6_BRU_ROP_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20)
> #define VI6_BRU_ROP_DSTSEL_VRPF (4 << 20)
> #define VI6_BRU_ROP_DSTSEL_MASK (7 << 20)
> diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
> index 5af3486afe07..84139affb871 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.c
> +++ b/drivers/media/platform/vsp1/vsp1_video.c
> @@ -481,7 +481,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
> struct media_entity_enum ent_enum;
> struct vsp1_entity *entity;
> struct media_pad *pad;
> - bool bru_found = false;
> + struct vsp1_bru *bru = NULL;
> int ret;
>
> ret = media_entity_enum_init(&ent_enum, &input->entity.vsp1->media_dev);
> @@ -511,16 +511,20 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
> media_entity_to_v4l2_subdev(pad->entity));
>
> /*
> - * A BRU is present in the pipeline, store the BRU input pad
> + * A BRU or BRS is present in the pipeline, store its input pad
> * number in the input RPF for use when configuring the RPF.
> */
> - if (entity->type == VSP1_ENTITY_BRU) {
> - struct vsp1_bru *bru = to_bru(&entity->subdev);
> + if (entity->type == VSP1_ENTITY_BRU ||
> + entity->type == VSP1_ENTITY_BRS) {
> + /* BRU and BRS can't be chained. */
> + if (bru) {
> + ret = -EPIPE;
> + goto out;
> + }
>
> + bru = to_bru(&entity->subdev);
> bru->inputs[pad->index].rpf = input;
> input->bru_input = pad->index;
> -
> - bru_found = true;
> }
>
> /* We've reached the WPF, we're done. */
> @@ -542,8 +546,7 @@ static int vsp1_video_pipeline_build_branch(struct vsp1_pipeline *pipe,
> }
>
> pipe->uds = entity;
> - pipe->uds_input = bru_found ? pipe->bru
> - : &input->entity;
> + pipe->uds_input = bru ? &bru->entity : &input->entity;
> }
>
> /* Follow the source link, ignoring any HGO or HGT. */
> @@ -589,30 +592,42 @@ static int vsp1_video_pipeline_build(struct vsp1_pipeline *pipe,
> e = to_vsp1_entity(subdev);
> list_add_tail(&e->list_pipe, &pipe->entities);
>
> - if (e->type == VSP1_ENTITY_RPF) {
> + switch (e->type) {
> + case VSP1_ENTITY_RPF:
> rwpf = to_rwpf(subdev);
> pipe->inputs[rwpf->entity.index] = rwpf;
> rwpf->video->pipe_index = ++pipe->num_inputs;
> rwpf->pipe = pipe;
> - } else if (e->type == VSP1_ENTITY_WPF) {
> + break;
> +
> + case VSP1_ENTITY_WPF:
> rwpf = to_rwpf(subdev);
> pipe->output = rwpf;
> rwpf->video->pipe_index = 0;
> rwpf->pipe = pipe;
> - } else if (e->type == VSP1_ENTITY_LIF) {
> + break;
> +
> + case VSP1_ENTITY_LIF:
> pipe->lif = e;
> - } else if (e->type == VSP1_ENTITY_BRU) {
> + break;
> +
> + case VSP1_ENTITY_BRU:
> + case VSP1_ENTITY_BRS:
> pipe->bru = e;
> - } else if (e->type == VSP1_ENTITY_HGO) {
> - struct vsp1_hgo *hgo = to_hgo(subdev);
> + break;
>
> + case VSP1_ENTITY_HGO:
> pipe->hgo = e;
> - hgo->histo.pipe = pipe;
> - } else if (e->type == VSP1_ENTITY_HGT) {
> - struct vsp1_hgt *hgt = to_hgt(subdev);
> + to_hgo(subdev)->histo.pipe = pipe;
> + break;
>
> + case VSP1_ENTITY_HGT:
> pipe->hgt = e;
> - hgt->histo.pipe = pipe;
> + to_hgt(subdev)->histo.pipe = pipe;
> + break;
> +
> + default:
> + break;
> }
> }
>
> @@ -796,12 +811,14 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
> struct vsp1_uds *uds = to_uds(&pipe->uds->subdev);
>
> /*
> - * If a BRU is present in the pipeline before the UDS, the alpha
> - * component doesn't need to be scaled as the BRU output alpha
> - * value is fixed to 255. Otherwise we need to scale the alpha
> - * component only when available at the input RPF.
> + * If a BRU or BRS is present in the pipeline before the UDS,
> + * the alpha component doesn't need to be scaled as the BRU and
> + * BRS output alpha value is fixed to 255. Otherwise we need to
> + * scale the alpha component only when available at the input
> + * RPF.
> */
> - if (pipe->uds_input->type == VSP1_ENTITY_BRU) {
> + if (pipe->uds_input->type == VSP1_ENTITY_BRU ||
> + pipe->uds_input->type == VSP1_ENTITY_BRS) {
> uds->scale_alpha = false;
> } else {
> struct vsp1_rwpf *rpf =
> diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
> index 32df109b119f..b6c902be225b 100644
> --- a/drivers/media/platform/vsp1/vsp1_wpf.c
> +++ b/drivers/media/platform/vsp1/vsp1_wpf.c
> @@ -453,7 +453,9 @@ static void wpf_configure(struct vsp1_entity *entity,
> }
>
> if (pipe->bru || pipe->num_inputs > 1)
> - srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;
> + srcrpf |= pipe->bru->type == VSP1_ENTITY_BRU
> + ? VI6_WPF_SRCRPF_VIRACT_MST
> + : VI6_WPF_SRCRPF_VIRACT2_MST;
>
> vsp1_wpf_write(wpf, dl, VI6_WPF_SRCRPF, srcrpf);
>
>
More information about the dri-devel
mailing list