[media] v4l: vsp1: Support multi-input entities
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Wed, 10 Jul 2013 21:37:27 +0000 (18:37 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Wed, 23 Apr 2014 13:18:36 +0000 (10:18 -0300)
Rework the route configuration code to support entities with multiple
sink pads.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/platform/vsp1/vsp1_entity.c
drivers/media/platform/vsp1/vsp1_entity.h
drivers/media/platform/vsp1/vsp1_hsit.c
drivers/media/platform/vsp1/vsp1_lif.c
drivers/media/platform/vsp1/vsp1_lut.c
drivers/media/platform/vsp1/vsp1_rpf.c
drivers/media/platform/vsp1/vsp1_sru.c
drivers/media/platform/vsp1/vsp1_uds.c
drivers/media/platform/vsp1/vsp1_video.c
drivers/media/platform/vsp1/vsp1_wpf.c

index 3fc9e4266caf48c26102768790258315ac7c4542..a9022f858aa550a91bd5e633a9cd5ae0d8e229ce 100644 (file)
@@ -100,8 +100,10 @@ static int vsp1_entity_link_setup(struct media_entity *entity,
                if (source->sink)
                        return -EBUSY;
                source->sink = remote->entity;
+               source->sink_pad = remote->index;
        } else {
                source->sink = NULL;
+               source->sink_pad = 0;
        }
 
        return 0;
@@ -116,42 +118,40 @@ const struct media_entity_operations vsp1_media_ops = {
  * Initialization
  */
 
+static const struct vsp1_route vsp1_routes[] = {
+       { VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } },
+       { VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } },
+       { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } },
+       { VSP1_ENTITY_LUT, 0, VI6_DPR_LUT_ROUTE, { VI6_DPR_NODE_LUT, } },
+       { VSP1_ENTITY_RPF, 0, VI6_DPR_RPF_ROUTE(0), { VI6_DPR_NODE_RPF(0), } },
+       { VSP1_ENTITY_RPF, 1, VI6_DPR_RPF_ROUTE(1), { VI6_DPR_NODE_RPF(1), } },
+       { VSP1_ENTITY_RPF, 2, VI6_DPR_RPF_ROUTE(2), { VI6_DPR_NODE_RPF(2), } },
+       { VSP1_ENTITY_RPF, 3, VI6_DPR_RPF_ROUTE(3), { VI6_DPR_NODE_RPF(3), } },
+       { VSP1_ENTITY_RPF, 4, VI6_DPR_RPF_ROUTE(4), { VI6_DPR_NODE_RPF(4), } },
+       { VSP1_ENTITY_SRU, 0, VI6_DPR_SRU_ROUTE, { VI6_DPR_NODE_SRU, } },
+       { VSP1_ENTITY_UDS, 0, VI6_DPR_UDS_ROUTE(0), { VI6_DPR_NODE_UDS(0), } },
+       { VSP1_ENTITY_UDS, 1, VI6_DPR_UDS_ROUTE(1), { VI6_DPR_NODE_UDS(1), } },
+       { VSP1_ENTITY_UDS, 2, VI6_DPR_UDS_ROUTE(2), { VI6_DPR_NODE_UDS(2), } },
+       { VSP1_ENTITY_WPF, 0, 0, { VI6_DPR_NODE_WPF(0), } },
+       { VSP1_ENTITY_WPF, 1, 0, { VI6_DPR_NODE_WPF(1), } },
+       { VSP1_ENTITY_WPF, 2, 0, { VI6_DPR_NODE_WPF(2), } },
+       { VSP1_ENTITY_WPF, 3, 0, { VI6_DPR_NODE_WPF(3), } },
+};
+
 int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
                     unsigned int num_pads)
 {
-       static const struct {
-               unsigned int id;
-               unsigned int reg;
-       } routes[] = {
-               { VI6_DPR_NODE_HSI, VI6_DPR_HSI_ROUTE },
-               { VI6_DPR_NODE_HST, VI6_DPR_HST_ROUTE },
-               { VI6_DPR_NODE_LIF, 0 },
-               { VI6_DPR_NODE_LUT, VI6_DPR_LUT_ROUTE },
-               { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) },
-               { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) },
-               { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) },
-               { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) },
-               { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) },
-               { VI6_DPR_NODE_SRU, VI6_DPR_SRU_ROUTE },
-               { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) },
-               { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) },
-               { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) },
-               { VI6_DPR_NODE_WPF(0), 0 },
-               { VI6_DPR_NODE_WPF(1), 0 },
-               { VI6_DPR_NODE_WPF(2), 0 },
-               { VI6_DPR_NODE_WPF(3), 0 },
-       };
-
        unsigned int i;
 
-       for (i = 0; i < ARRAY_SIZE(routes); ++i) {
-               if (routes[i].id == entity->id) {
-                       entity->route = routes[i].reg;
+       for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) {
+               if (vsp1_routes[i].type == entity->type &&
+                   vsp1_routes[i].index == entity->index) {
+                       entity->route = &vsp1_routes[i];
                        break;
                }
        }
 
-       if (i == ARRAY_SIZE(routes))
+       if (i == ARRAY_SIZE(vsp1_routes))
                return -EINVAL;
 
        entity->vsp1 = vsp1;
index f6fd6988aeb0913ac6c023bcb38e487709269587..3c6a5c831bcf4b96a841411e4a5821915bcfbdbf 100644 (file)
@@ -30,13 +30,31 @@ enum vsp1_entity_type {
        VSP1_ENTITY_WPF,
 };
 
+/*
+ * struct vsp1_route - Entity routing configuration
+ * @type: Entity type this routing entry is associated with
+ * @index: Entity index this routing entry is associated with
+ * @reg: Output routing configuration register
+ * @inputs: Target node value for each input
+ *
+ * Each $vsp1_route entry describes routing configuration for the entity
+ * specified by the entry's @type and @index. @reg indicates the register that
+ * holds output routing configuration for the entity, and the @inputs array
+ * store the target node value for each input of the entity.
+ */
+struct vsp1_route {
+       enum vsp1_entity_type type;
+       unsigned int index;
+       unsigned int reg;
+       unsigned int inputs[4];
+};
+
 struct vsp1_entity {
        struct vsp1_device *vsp1;
 
        enum vsp1_entity_type type;
        unsigned int index;
-       unsigned int id;
-       unsigned int route;
+       const struct vsp1_route *route;
 
        struct list_head list_dev;
        struct list_head list_pipe;
@@ -45,6 +63,7 @@ struct vsp1_entity {
        unsigned int source_pad;
 
        struct media_entity *sink;
+       unsigned int sink_pad;
 
        struct v4l2_subdev subdev;
        struct v4l2_mbus_framefmt *formats;
index 285485350d822cde0882954d1b38bd6b5b99d86f..db2950a73c60c10d918006c05da90f252f4988e0 100644 (file)
@@ -193,13 +193,10 @@ struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
 
        hsit->inverse = inverse;
 
-       if (inverse) {
+       if (inverse)
                hsit->entity.type = VSP1_ENTITY_HSI;
-               hsit->entity.id = VI6_DPR_NODE_HSI;
-       } else {
+       else
                hsit->entity.type = VSP1_ENTITY_HST;
-               hsit->entity.id = VI6_DPR_NODE_HST;
-       }
 
        ret = vsp1_entity_init(vsp1, &hsit->entity, 2);
        if (ret < 0)
index 135a78957014d38d52fc4a816611fded79d8e269..d4fb23e9c4a8d7ad248f1d788be9481732045464 100644 (file)
@@ -215,7 +215,6 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
                return ERR_PTR(-ENOMEM);
 
        lif->entity.type = VSP1_ENTITY_LIF;
-       lif->entity.id = VI6_DPR_NODE_LIF;
 
        ret = vsp1_entity_init(vsp1, &lif->entity, 2);
        if (ret < 0)
index 4e9dc7c86ef8ac3edb9543e36e956a8cd931afa2..fea36ebe256564872fcc75bd5392bee1712f66a0 100644 (file)
@@ -229,7 +229,6 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
                return ERR_PTR(-ENOMEM);
 
        lut->entity.type = VSP1_ENTITY_LUT;
-       lut->entity.id = VI6_DPR_NODE_LUT;
 
        ret = vsp1_entity_init(vsp1, &lut->entity, 2);
        if (ret < 0)
index 2b04d0f95c62e553a4d20c667678eeb3e67dc213..42444568b9fd87cbfeddb0e9454f3aa3f85db7c3 100644 (file)
@@ -176,7 +176,6 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 
        rpf->entity.type = VSP1_ENTITY_RPF;
        rpf->entity.index = index;
-       rpf->entity.id = VI6_DPR_NODE_RPF(index);
 
        ret = vsp1_entity_init(vsp1, &rpf->entity, 2);
        if (ret < 0)
index 7ab1a0b2d65690eaaf6aa8e235fa1802b4972028..aa0e04c56f3f22d07edb77a2948e6880a7c9f1d6 100644 (file)
@@ -327,7 +327,6 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
                return ERR_PTR(-ENOMEM);
 
        sru->entity.type = VSP1_ENTITY_SRU;
-       sru->entity.id = VI6_DPR_NODE_SRU;
 
        ret = vsp1_entity_init(vsp1, &sru->entity, 2);
        if (ret < 0)
index 1b20f28cbc39ae1b56fb6e3000d1ca254aa9526e..0293bdbb4401a30b318e8d663835a31ebec637f1 100644 (file)
@@ -322,7 +322,6 @@ struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index)
 
        uds->entity.type = VSP1_ENTITY_UDS;
        uds->entity.index = index;
-       uds->entity.id = VI6_DPR_NODE_UDS(index);
 
        ret = vsp1_entity_init(vsp1, &uds->entity, 2);
        if (ret < 0)
index a0595c17700fa3616cff66d1c0991d342906c7a7..1ef875d521daaf517f73784193dd0e6765e4488d 100644 (file)
@@ -461,7 +461,7 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
 
        list_for_each_entry(entity, &pipe->entities, list_pipe) {
                if (entity->route)
-                       vsp1_write(entity->vsp1, entity->route,
+                       vsp1_write(entity->vsp1, entity->route->reg,
                                   VI6_DPR_NODE_UNUSED);
 
                v4l2_subdev_call(&entity->subdev, video, s_stream, 0);
@@ -680,11 +680,12 @@ static void vsp1_entity_route_setup(struct vsp1_entity *source)
 {
        struct vsp1_entity *sink;
 
-       if (source->route == 0)
+       if (source->route->reg == 0)
                return;
 
        sink = container_of(source->sink, struct vsp1_entity, subdev.entity);
-       vsp1_write(source->vsp1, source->route, sink->id);
+       vsp1_write(source->vsp1, source->route->reg,
+                  sink->route->inputs[source->sink_pad]);
 }
 
 static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
index 11a61c601da0cfa9e6702ed480ef19acc098b196..ef9f88ead319585fdf13f9767417253039bbe82e 100644 (file)
@@ -181,7 +181,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 
        wpf->entity.type = VSP1_ENTITY_WPF;
        wpf->entity.index = index;
-       wpf->entity.id = VI6_DPR_NODE_WPF(index);
 
        ret = vsp1_entity_init(vsp1, &wpf->entity, 2);
        if (ret < 0)