v4l: vsp1: Add support for multiple LIF instances
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 21 Jun 2017 13:10:18 +0000 (16:10 +0300)
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Thu, 3 Aug 2017 13:17:20 +0000 (16:17 +0300)
The VSP2-DL instance (present in the H3 ES2.0 and M3-N SoCs) has two LIF
instances. Adapt the driver infrastructure to support multiple LIFs.
Support for multiple display pipelines will be added separately.

The change to the entity routing table removes the ability to connect
the LIF output to the HGO or HGT histogram generators. This feature is
only available on Gen2 hardware, isn't supported by the rest of the
driver, and has no known use case, so this isn't an issue.

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_drm.c
drivers/media/platform/vsp1/vsp1_drv.c
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/platform/vsp1/vsp1_lif.h
drivers/media/platform/vsp1/vsp1_regs.h

index 73858a0ed35ca7a939115db705c0d52c47d0e36d..78ef838416b303a971cccb526031b78a829ccddd 100644 (file)
@@ -41,11 +41,11 @@ struct vsp1_rwpf;
 struct vsp1_sru;
 struct vsp1_uds;
 
+#define VSP1_MAX_LIF           2
 #define VSP1_MAX_RPF           5
 #define VSP1_MAX_UDS           3
 #define VSP1_MAX_WPF           4
 
-#define VSP1_HAS_LIF           (1 << 0)
 #define VSP1_HAS_LUT           (1 << 1)
 #define VSP1_HAS_SRU           (1 << 2)
 #define VSP1_HAS_BRU           (1 << 3)
@@ -61,6 +61,7 @@ struct vsp1_device_info {
        const char *model;
        unsigned int gen;
        unsigned int features;
+       unsigned int lif_count;
        unsigned int rpf_count;
        unsigned int uds_count;
        unsigned int wpf_count;
@@ -84,7 +85,7 @@ struct vsp1_device {
        struct vsp1_hgt *hgt;
        struct vsp1_hsit *hsi;
        struct vsp1_hsit *hst;
-       struct vsp1_lif *lif;
+       struct vsp1_lif *lif[VSP1_MAX_LIF];
        struct vsp1_lut *lut;
        struct vsp1_rwpf *rpf[VSP1_MAX_RPF];
        struct vsp1_sru *sru;
index daaafe7885faadfc9095a07dd7fbf533783f6ff1..4e1b893e8f51864bc463b802557dd2e944819a32 100644 (file)
@@ -181,7 +181,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int pipe_index,
                format.format.code);
 
        format.pad = LIF_PAD_SINK;
-       ret = v4l2_subdev_call(&vsp1->lif->entity.subdev, pad, set_fmt, NULL,
+       ret = v4l2_subdev_call(&vsp1->lif[0]->entity.subdev, pad, set_fmt, NULL,
                               &format);
        if (ret < 0)
                return ret;
@@ -599,15 +599,15 @@ int vsp1_drm_init(struct vsp1_device *vsp1)
 
        vsp1->bru->entity.sink = &vsp1->wpf[0]->entity;
        vsp1->bru->entity.sink_pad = 0;
-       vsp1->wpf[0]->entity.sink = &vsp1->lif->entity;
+       vsp1->wpf[0]->entity.sink = &vsp1->lif[0]->entity;
        vsp1->wpf[0]->entity.sink_pad = 0;
 
        list_add_tail(&vsp1->bru->entity.list_pipe, &pipe->entities);
        list_add_tail(&vsp1->wpf[0]->entity.list_pipe, &pipe->entities);
-       list_add_tail(&vsp1->lif->entity.list_pipe, &pipe->entities);
+       list_add_tail(&vsp1->lif[0]->entity.list_pipe, &pipe->entities);
 
        pipe->bru = &vsp1->bru->entity;
-       pipe->lif = &vsp1->lif->entity;
+       pipe->lif = &vsp1->lif[0]->entity;
        pipe->output = vsp1->wpf[0];
        pipe->output->pipe = pipe;
        pipe->frame_end = vsp1_du_pipeline_frame_end;
index d1682a9719af8468589403e75c02b0849e413427..962e4c304076875f6731d52336e064879f239685 100644 (file)
@@ -168,10 +168,13 @@ static int vsp1_uapi_create_links(struct vsp1_device *vsp1)
                        return ret;
        }
 
-       if (vsp1->lif) {
-               ret = media_create_pad_link(&vsp1->wpf[0]->entity.subdev.entity,
+       for (i = 0; i < vsp1->info->lif_count; ++i) {
+               if (!vsp1->lif[i])
+                       continue;
+
+               ret = media_create_pad_link(&vsp1->wpf[i]->entity.subdev.entity,
                                            RWPF_PAD_SOURCE,
-                                           &vsp1->lif->entity.subdev.entity,
+                                           &vsp1->lif[i]->entity.subdev.entity,
                                            LIF_PAD_SINK, 0);
                if (ret < 0)
                        return ret;
@@ -334,18 +337,23 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
        }
 
        /*
-        * The LIF is only supported when used in conjunction with the DU, in
+        * The LIFs are only supported when used in conjunction with the DU, in
         * which case the userspace API is disabled. If the userspace API is
-        * enabled skip the LIF, even when present.
+        * enabled skip the LIFs, even when present.
         */
-       if (vsp1->info->features & VSP1_HAS_LIF && !vsp1->info->uapi) {
-               vsp1->lif = vsp1_lif_create(vsp1);
-               if (IS_ERR(vsp1->lif)) {
-                       ret = PTR_ERR(vsp1->lif);
-                       goto done;
-               }
+       if (!vsp1->info->uapi) {
+               for (i = 0; i < vsp1->info->lif_count; ++i) {
+                       struct vsp1_lif *lif;
+
+                       lif = vsp1_lif_create(vsp1, i);
+                       if (IS_ERR(lif)) {
+                               ret = PTR_ERR(lif);
+                               goto done;
+                       }
 
-               list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities);
+                       vsp1->lif[i] = lif;
+                       list_add_tail(&lif->entity.list_dev, &vsp1->entities);
+               }
        }
 
        if (vsp1->info->features & VSP1_HAS_LUT) {
@@ -638,8 +646,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .version = VI6_IP_VERSION_MODEL_VSPD_GEN2,
                .model = "VSP1-D",
                .gen = 2,
-               .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LIF
-                         | VSP1_HAS_LUT,
+               .features = VSP1_HAS_BRU | VSP1_HAS_HGO | VSP1_HAS_LUT,
+               .lif_count = 1,
                .rpf_count = 4,
                .uds_count = 1,
                .wpf_count = 1,
@@ -672,8 +680,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .version = VI6_IP_VERSION_MODEL_VSPD_V2H,
                .model = "VSP1V-D",
                .gen = 2,
-               .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT
-                         | VSP1_HAS_LIF,
+               .features = VSP1_HAS_BRU | VSP1_HAS_CLU | VSP1_HAS_LUT,
+               .lif_count = 1,
                .rpf_count = 4,
                .uds_count = 1,
                .wpf_count = 1,
@@ -721,7 +729,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .version = VI6_IP_VERSION_MODEL_VSPD_GEN3,
                .model = "VSP2-D",
                .gen = 3,
-               .features = VSP1_HAS_BRU | VSP1_HAS_LIF | VSP1_HAS_WPF_VFLIP,
+               .features = VSP1_HAS_BRU | VSP1_HAS_WPF_VFLIP,
+               .lif_count = 1,
                .rpf_count = 5,
                .wpf_count = 2,
                .num_bru_inputs = 5,
@@ -729,7 +738,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .version = VI6_IP_VERSION_MODEL_VSPD_V3,
                .model = "VSP2-D",
                .gen = 3,
-               .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_LIF,
+               .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+               .lif_count = 1,
                .rpf_count = 5,
                .wpf_count = 1,
                .num_bru_inputs = 5,
@@ -737,7 +747,8 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
                .version = VI6_IP_VERSION_MODEL_VSPDL_GEN3,
                .model = "VSP2-DL",
                .gen = 3,
-               .features = VSP1_HAS_BRS | VSP1_HAS_BRU | VSP1_HAS_LIF,
+               .features = VSP1_HAS_BRS | VSP1_HAS_BRU,
+               .lif_count = 2,
                .rpf_count = 5,
                .wpf_count = 2,
                .num_bru_inputs = 5,
index c06f7db093db1c2cb99ea3380ef8c8e57e3a9e6e..54de15095709d24def304b5d7839cd36a7c89caf 100644 (file)
@@ -468,7 +468,8 @@ static const struct vsp1_route vsp1_routes[] = {
        { VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 },
        VSP1_ENTITY_ROUTE(HSI),
        VSP1_ENTITY_ROUTE(HST),
-       { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, }, VI6_DPR_NODE_LIF },
+       { VSP1_ENTITY_LIF, 0, 0, { 0, }, 0 },
+       { VSP1_ENTITY_LIF, 1, 0, { 0, }, 0 },
        VSP1_ENTITY_ROUTE(LUT),
        VSP1_ENTITY_ROUTE_RPF(0),
        VSP1_ENTITY_ROUTE_RPF(1),
index 702487f895b39e293254ed806de279f7933f5445..e6fa16d7fda897d342ef99274d31cef4948a050e 100644 (file)
@@ -30,7 +30,7 @@
 static inline void vsp1_lif_write(struct vsp1_lif *lif, struct vsp1_dl_list *dl,
                                  u32 reg, u32 data)
 {
-       vsp1_dl_list_write(dl, reg, data);
+       vsp1_dl_list_write(dl, reg + lif->entity.index * VI6_LIF_OFFSET, data);
 }
 
 /* -----------------------------------------------------------------------------
@@ -165,7 +165,7 @@ static const struct vsp1_entity_operations lif_entity_ops = {
  * Initialization and Cleanup
  */
 
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index)
 {
        struct vsp1_lif *lif;
        int ret;
@@ -176,6 +176,7 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
 
        lif->entity.ops = &lif_entity_ops;
        lif->entity.type = VSP1_ENTITY_LIF;
+       lif->entity.index = index;
 
        /*
         * The LIF is never exposed to userspace, but media entity registration
index 7b35879028de0436b3b9a58e0e444ecdfcbd51ad..3417339379b110fbdb7cdfa1e726ef3c64f4eca0 100644 (file)
@@ -32,6 +32,6 @@ static inline struct vsp1_lif *to_lif(struct v4l2_subdev *subdev)
        return container_of(subdev, struct vsp1_lif, entity.subdev);
 }
 
-struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1);
+struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1, unsigned int index);
 
 #endif /* __VSP1_LIF_H__ */
index ab439a60a1007f3d2d3315ae95952c472619e485..007e2bbc26c04bdc01f3d8121a1afc31162830f2 100644 (file)
 #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_LIF               55              /* Gen2 only */
 #define VI6_DPR_NODE_WPF(n)            (56 + (n))
 #define VI6_DPR_NODE_UNUSED            63
 
  * LIF Control Registers
  */
 
+#define VI6_LIF_OFFSET                 (-0x100)
+
 #define VI6_LIF_CTRL                   0x3b00
 #define VI6_LIF_CTRL_OBTH_MASK         (0x7ff << 16)
 #define VI6_LIF_CTRL_OBTH_SHIFT                16