v4l: vsp1: Add support for the BRS entity
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 24 May 2017 21:16:57 +0000 (00:16 +0300)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Sat, 29 Jul 2017 20:46:56 +0000 (23:46 +0300)
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 modelling it as a new entity type, but reuse
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@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Acked-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/platform/vsp1/vsp1.h
drivers/media/platform/vsp1/vsp1_bru.c
drivers/media/platform/vsp1/vsp1_bru.h
drivers/media/platform/vsp1/vsp1_drm.c
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/media/platform/vsp1/vsp1_pipe.c
drivers/media/platform/vsp1/vsp1_regs.h
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_wpf.c

index 847963b6e9ebd016deda060d81450c95ed817dfa..73858a0ed35ca7a939115db705c0d52c47d0e36d 100644 (file)
@@ -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;
index 85362c5ef57a4ce9efea182698b26bc1dd4367e7..e8fd2ae3b3ebd28278e831299acde0269d7a02a9 100644 (file)
@@ -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))
                        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);
index 828a3fcadea8b7d073f6a6724ff32f4ed5ea80c5..c98ed96d8de63a4b3ac0b9f91d07d43e57c58776 100644 (file)
@@ -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__ */
index f40444a96ba698dfb3d7cb228f028a5e057b0134..daaafe7885faadfc9095a07dd7fbf533783f6ff1 100644 (file)
@@ -62,17 +62,17 @@ EXPORT_SYMBOL_GPL(vsp1_du_init);
  * @cfg: the LIF configuration
  *
  * Configure the output part of VSP DRM pipeline for the given frame @cfg.width
- * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink
- * and source pads, and the LIF sink pad.
+ * and @cfg.height. This sets up formats on the blend unit (BRU or BRS) source
+ * pad, the WPF sink and source pads, and the LIF sink pad.
  *
  * The @pipe_index argument selects which DRM pipeline to setup. The number of
  * available pipelines depend on the VSP instance.
  *
- * As the media bus code on the BRU source pad is conditioned by the
- * configuration of the BRU sink 0 pad, we also set up the formats on all BRU
+ * As the media bus code on the blend unit source pad is conditioned by the
+ * configuration of its sink 0 pad, we also set up the formats on all blend unit
  * sinks, even if the configuration will be overwritten later by
- * vsp1_du_setup_rpf(). This ensures that the BRU configuration is set to a well
- * defined state.
+ * vsp1_du_setup_rpf(). This ensures that the blend unit configuration is set to
+ * a well defined state.
  *
  * Return 0 on success or a negative error code on failure.
  */
index 5a467b118a1c607adc0969cfe038ce91631edacd..6a9aeb71aedfba0eb1026f08c6e60b0219e450c4 100644 (file)
@@ -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) |
index 71dd903263adcdc192f92882f047d76cade5a16b..c06f7db093db1c2cb99ea3380ef8c8e57e3a9e6e 100644 (file)
@@ -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),
index 4362cd4e90ba86a2381f80820665f12586e1e8ca..11f8363fa6b0f6fdb086d0584678878740291f58 100644 (file)
@@ -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,
index e817623b84e04632440d5d5155b56f96c7345c5e..9bb961298af2462a495fc1f129337d8b270492a1 100644 (file)
@@ -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);
index cd3e32af6e3b5cf572614b129578cb9e1db3c085..744217e020b956047ec339b492c6b537badb926a 100644 (file)
 #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))
 #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)
 #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
 #define VI6_HSI_CTRL_EN                        (1 << 0)
 
 /* -----------------------------------------------------------------------------
- * BRU Control Registers
+ * BRS and BRU Control Registers
  */
 
 #define VI6_ROP_NOP                    0
 #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))
 #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)
 #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)
 #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)
 #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)
index 5af3486afe07f87d51d1cade1af10fd22eb4c5ba..84139affb8711dd0814196d36c53fc2b2865fbae 100644 (file)
@@ -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 =
index 32df109b119fc353767b5c0b8a16702a5c4b1d64..b6c902be225b779e4a04beab8a1151862ad7c8b7 100644 (file)
@@ -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);