summaryrefslogtreecommitdiff
path: root/drivers/media/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h3
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.h5
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c19
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c25
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c40
5 files changed, 92 insertions, 0 deletions
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index 0e3e394c44cd..90a4d95c0a50 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -77,11 +77,14 @@ struct vsp1_route {
* @destroy: Destroy the entity.
* @configure: Setup the hardware based on the entity state (pipeline, formats,
* selection rectangles, ...)
+ * @max_width: Return the max supported width of data that the entity can
+ * process in a single operation.
*/
struct vsp1_entity_operations {
void (*destroy)(struct vsp1_entity *);
void (*configure)(struct vsp1_entity *, struct vsp1_pipeline *,
struct vsp1_dl_list *, enum vsp1_entity_params);
+ unsigned int (*max_width)(struct vsp1_entity *, struct vsp1_pipeline *);
};
struct vsp1_entity {
diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h
index d20d997b1fda..af4cd23d399b 100644
--- a/drivers/media/platform/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/vsp1/vsp1_pipe.h
@@ -77,6 +77,8 @@ enum vsp1_pipeline_state {
* @uds_input: entity at the input of the UDS, if the UDS is present
* @entities: list of entities in the pipeline
* @dl: display list associated with the pipeline
+ * @div_size: The maximum allowed partition size for the pipeline
+ * @partitions: The number of partitions used to process one frame
*/
struct vsp1_pipeline {
struct media_pipeline pipe;
@@ -104,6 +106,9 @@ struct vsp1_pipeline {
struct list_head entities;
struct vsp1_dl_list *dl;
+
+ unsigned int div_size;
+ unsigned int partitions;
};
void vsp1_pipeline_reset(struct vsp1_pipeline *pipe);
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 9d4a1afb6634..b4e568a3b4ed 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -306,8 +306,27 @@ static void sru_configure(struct vsp1_entity *entity,
vsp1_sru_write(sru, dl, VI6_SRU_CTRL2, param->ctrl2);
}
+static unsigned int sru_max_width(struct vsp1_entity *entity,
+ struct vsp1_pipeline *pipe)
+{
+ struct vsp1_sru *sru = to_sru(&entity->subdev);
+ struct v4l2_mbus_framefmt *input;
+ struct v4l2_mbus_framefmt *output;
+
+ input = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
+ SRU_PAD_SINK);
+ output = vsp1_entity_get_pad_format(&sru->entity, sru->entity.config,
+ SRU_PAD_SOURCE);
+
+ if (input->width != output->width)
+ return 512;
+ else
+ return 256;
+}
+
static const struct vsp1_entity_operations sru_entity_ops = {
.configure = sru_configure,
+ .max_width = sru_max_width,
};
/* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 62beae5d6944..706b6e85f47d 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -311,8 +311,33 @@ static void uds_configure(struct vsp1_entity *entity,
(output->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT));
}
+static unsigned int uds_max_width(struct vsp1_entity *entity,
+ struct vsp1_pipeline *pipe)
+{
+ struct vsp1_uds *uds = to_uds(&entity->subdev);
+ const struct v4l2_mbus_framefmt *output;
+ const struct v4l2_mbus_framefmt *input;
+ unsigned int hscale;
+
+ input = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
+ UDS_PAD_SINK);
+ output = vsp1_entity_get_pad_format(&uds->entity, uds->entity.config,
+ UDS_PAD_SOURCE);
+ hscale = output->width / input->width;
+
+ if (hscale <= 2)
+ return 256;
+ else if (hscale <= 4)
+ return 512;
+ else if (hscale <= 8)
+ return 1024;
+ else
+ return 2048;
+}
+
static const struct vsp1_entity_operations uds_entity_ops = {
.configure = uds_configure,
+ .max_width = uds_max_width,
};
/* -----------------------------------------------------------------------------
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index b8339d874df4..b903cc5471e0 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -169,6 +169,43 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
}
/* -----------------------------------------------------------------------------
+ * VSP1 Partition Algorithm support
+ */
+
+static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe)
+{
+ struct vsp1_device *vsp1 = pipe->output->entity.vsp1;
+ const struct v4l2_mbus_framefmt *format;
+ struct vsp1_entity *entity;
+ unsigned int div_size;
+
+ format = vsp1_entity_get_pad_format(&pipe->output->entity,
+ pipe->output->entity.config,
+ RWPF_PAD_SOURCE);
+ div_size = format->width;
+
+ /* Gen2 hardware doesn't require image partitioning. */
+ if (vsp1->info->gen == 2) {
+ pipe->div_size = div_size;
+ pipe->partitions = 1;
+ return;
+ }
+
+ list_for_each_entry(entity, &pipe->entities, list_pipe) {
+ unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH;
+
+ if (entity->ops->max_width) {
+ entity_max = entity->ops->max_width(entity, pipe);
+ if (entity_max)
+ div_size = min(div_size, entity_max);
+ }
+ }
+
+ pipe->div_size = div_size;
+ pipe->partitions = DIV_ROUND_UP(format->width, div_size);
+}
+
+/* -----------------------------------------------------------------------------
* Pipeline Management
*/
@@ -594,6 +631,9 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
{
struct vsp1_entity *entity;
+ /* Determine this pipelines sizes for image partitioning support. */
+ vsp1_video_pipeline_setup_partitions(pipe);
+
/* Prepare the display list. */
pipe->dl = vsp1_dl_list_get(pipe->output->dlm);
if (!pipe->dl)