[RFC,v1,06/19] media: renesas: vsp1: Move partition calculation to vsp1_pipe.c

Message ID 20231122043009.2741-7-laurent.pinchart+renesas@ideasonboard.com (mailing list archive)
State New
Headers
Series media: renesas: vsp1: Conversion to subdev active state |

Commit Message

Laurent Pinchart Nov. 22, 2023, 4:29 a.m. UTC
  The partition calculation code, located in vsp1_video.c, is not specific
to video pipelines. To prepare for its usage in DRM pipelines, move it
to vsp1_pipe.c.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 .../media/platform/renesas/vsp1/vsp1_pipe.c   |  85 ++++++++-
 .../media/platform/renesas/vsp1/vsp1_pipe.h   |   6 +-
 .../media/platform/renesas/vsp1/vsp1_video.c  | 169 +++++-------------
 3 files changed, 130 insertions(+), 130 deletions(-)
  

Comments

Jacopo Mondi June 18, 2024, 10:26 a.m. UTC | #1
Hi Laurent

On Wed, Nov 22, 2023 at 06:29:56AM GMT, Laurent Pinchart wrote:
> The partition calculation code, located in vsp1_video.c, is not specific
> to video pipelines. To prepare for its usage in DRM pipelines, move it
> to vsp1_pipe.c.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  .../media/platform/renesas/vsp1/vsp1_pipe.c   |  85 ++++++++-
>  .../media/platform/renesas/vsp1/vsp1_pipe.h   |   6 +-
>  .../media/platform/renesas/vsp1/vsp1_video.c  | 169 +++++-------------
>  3 files changed, 130 insertions(+), 130 deletions(-)
>
> diff --git a/drivers/media/platform/renesas/vsp1/vsp1_pipe.c b/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
> index 68d05243c3ee..b90240b24b3a 100644
> --- a/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
> +++ b/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
> @@ -444,6 +444,10 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
>  	vsp1_uds_set_alpha(pipe->uds, dlb, alpha);
>  }
>
> +/* -----------------------------------------------------------------------------
> + * VSP1 Partition Algorithm support
> + */
> +
>  /*
>   * Propagate the partition calculations through the pipeline
>   *
> @@ -452,10 +456,10 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
>   * source. Each entity must produce the partition required for the previous
>   * entity in the pipeline.
>   */
> -void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
> -				       struct vsp1_partition *partition,
> -				       unsigned int index,
> -				       struct vsp1_partition_window *window)
> +static void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
> +					      struct vsp1_partition *partition,
> +					      unsigned int index,
> +					      struct vsp1_partition_window *window)
>  {
>  	struct vsp1_entity *entity;
>
> @@ -466,3 +470,76 @@ void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
>  	}
>  }
>
> +/*
> + * vsp1_pipeline_calculate_partition - Calculate pipeline configuration for a
> + *	partition

stray \t ?
> + *
> + * @pipe: the pipeline
> + * @partition: partition that will hold the calculated values
> + * @div_size: pre-determined maximum partition division size
> + * @index: partition index

not really kernel doc, but I guess it doesn't hurt

The rest looks like the code code moved around has not been modified
(I presume I'll understand why in the next patches)

Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>

> + */
> +void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
> +				       struct vsp1_partition *partition,
> +				       unsigned int div_size,
> +				       unsigned int index)
> +{
> +	const struct v4l2_mbus_framefmt *format;
> +	struct vsp1_partition_window window;
> +	unsigned int modulus;
> +
> +	/*
> +	 * Partitions are computed on the size before rotation, use the format
> +	 * at the WPF sink.
> +	 */
> +	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
> +					      RWPF_PAD_SINK);
> +
> +	/* A single partition simply processes the output size in full. */
> +	if (pipe->partitions <= 1) {
> +		window.left = 0;
> +		window.width = format->width;
> +
> +		vsp1_pipeline_propagate_partition(pipe, partition, index,
> +						  &window);
> +		return;
> +	}
> +
> +	/* Initialise the partition with sane starting conditions. */
> +	window.left = index * div_size;
> +	window.width = div_size;
> +
> +	modulus = format->width % div_size;
> +
> +	/*
> +	 * We need to prevent the last partition from being smaller than the
> +	 * *minimum* width of the hardware capabilities.
> +	 *
> +	 * If the modulus is less than half of the partition size,
> +	 * the penultimate partition is reduced to half, which is added
> +	 * to the final partition: |1234|1234|1234|12|341|
> +	 * to prevent this:        |1234|1234|1234|1234|1|.
> +	 */
> +	if (modulus) {
> +		/*
> +		 * pipe->partitions is 1 based, whilst index is a 0 based index.
> +		 * Normalise this locally.
> +		 */
> +		unsigned int partitions = pipe->partitions - 1;
> +
> +		if (modulus < div_size / 2) {
> +			if (index == partitions - 1) {
> +				/* Halve the penultimate partition. */
> +				window.width = div_size / 2;
> +			} else if (index == partitions) {
> +				/* Increase the final partition. */
> +				window.width = (div_size / 2) + modulus;
> +				window.left -= div_size / 2;
> +			}
> +		} else if (index == partitions) {
> +			window.width = modulus;
> +		}
> +	}
> +
> +	vsp1_pipeline_propagate_partition(pipe, partition, index, &window);
> +}
> diff --git a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
> index 674b5748d929..02e98d843730 100644
> --- a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
> +++ b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
> @@ -166,10 +166,10 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
>  				   struct vsp1_dl_body *dlb,
>  				   unsigned int alpha);
>
> -void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
> +void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
>  				       struct vsp1_partition *partition,
> -				       unsigned int index,
> -				       struct vsp1_partition_window *window);
> +				       unsigned int div_size,
> +				       unsigned int index);
>
>  const struct vsp1_format_info *vsp1_get_format_info(struct vsp1_device *vsp1,
>  						    u32 fourcc);
> diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c
> index 9cb81b4c65ed..ea5773af54d6 100644
> --- a/drivers/media/platform/renesas/vsp1/vsp1_video.c
> +++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c
> @@ -172,129 +172,6 @@ static int __vsp1_video_try_format(struct vsp1_video *video,
>  	return 0;
>  }
>
> -/* -----------------------------------------------------------------------------
> - * VSP1 Partition Algorithm support
> - */
> -
> -/**
> - * vsp1_video_calculate_partition - Calculate the active partition output window
> - *
> - * @pipe: the pipeline
> - * @partition: partition that will hold the calculated values
> - * @div_size: pre-determined maximum partition division size
> - * @index: partition index
> - */
> -static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe,
> -					   struct vsp1_partition *partition,
> -					   unsigned int div_size,
> -					   unsigned int index)
> -{
> -	const struct v4l2_mbus_framefmt *format;
> -	struct vsp1_partition_window window;
> -	unsigned int modulus;
> -
> -	/*
> -	 * Partitions are computed on the size before rotation, use the format
> -	 * at the WPF sink.
> -	 */
> -	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
> -					      RWPF_PAD_SINK);
> -
> -	/* A single partition simply processes the output size in full. */
> -	if (pipe->partitions <= 1) {
> -		window.left = 0;
> -		window.width = format->width;
> -
> -		vsp1_pipeline_propagate_partition(pipe, partition, index,
> -						  &window);
> -		return;
> -	}
> -
> -	/* Initialise the partition with sane starting conditions. */
> -	window.left = index * div_size;
> -	window.width = div_size;
> -
> -	modulus = format->width % div_size;
> -
> -	/*
> -	 * We need to prevent the last partition from being smaller than the
> -	 * *minimum* width of the hardware capabilities.
> -	 *
> -	 * If the modulus is less than half of the partition size,
> -	 * the penultimate partition is reduced to half, which is added
> -	 * to the final partition: |1234|1234|1234|12|341|
> -	 * to prevent this:        |1234|1234|1234|1234|1|.
> -	 */
> -	if (modulus) {
> -		/*
> -		 * pipe->partitions is 1 based, whilst index is a 0 based index.
> -		 * Normalise this locally.
> -		 */
> -		unsigned int partitions = pipe->partitions - 1;
> -
> -		if (modulus < div_size / 2) {
> -			if (index == partitions - 1) {
> -				/* Halve the penultimate partition. */
> -				window.width = div_size / 2;
> -			} else if (index == partitions) {
> -				/* Increase the final partition. */
> -				window.width = (div_size / 2) + modulus;
> -				window.left -= div_size / 2;
> -			}
> -		} else if (index == partitions) {
> -			window.width = modulus;
> -		}
> -	}
> -
> -	vsp1_pipeline_propagate_partition(pipe, partition, index, &window);
> -}
> -
> -static int 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;
> -	unsigned int i;
> -
> -	/*
> -	 * Partitions are computed on the size before rotation, use the format
> -	 * at the WPF sink.
> -	 */
> -	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
> -					      RWPF_PAD_SINK);
> -	div_size = format->width;
> -
> -	/*
> -	 * Only Gen3+ hardware requires image partitioning, Gen2 will operate
> -	 * with a single partition that covers the whole output.
> -	 */
> -	if (vsp1->info->gen >= 3) {
> -		list_for_each_entry(entity, &pipe->entities, list_pipe) {
> -			unsigned int entity_max;
> -
> -			if (!entity->ops->max_width)
> -				continue;
> -
> -			entity_max = entity->ops->max_width(entity, pipe);
> -			if (entity_max)
> -				div_size = min(div_size, entity_max);
> -		}
> -	}
> -
> -	pipe->partitions = DIV_ROUND_UP(format->width, div_size);
> -	pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table),
> -				   GFP_KERNEL);
> -	if (!pipe->part_table)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < pipe->partitions; ++i)
> -		vsp1_video_calculate_partition(pipe, &pipe->part_table[i],
> -					       div_size, i);
> -
> -	return 0;
> -}
> -
>  /* -----------------------------------------------------------------------------
>   * Pipeline Management
>   */
> @@ -782,6 +659,52 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
>  	spin_unlock_irqrestore(&pipe->irqlock, flags);
>  }
>
> +static int 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;
> +	unsigned int i;
> +
> +	/*
> +	 * Partitions are computed on the size before rotation, use the format
> +	 * at the WPF sink.
> +	 */
> +	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
> +					      RWPF_PAD_SINK);
> +	div_size = format->width;
> +
> +	/*
> +	 * Only Gen3+ hardware requires image partitioning, Gen2 will operate
> +	 * with a single partition that covers the whole output.
> +	 */
> +	if (vsp1->info->gen >= 3) {
> +		list_for_each_entry(entity, &pipe->entities, list_pipe) {
> +			unsigned int entity_max;
> +
> +			if (!entity->ops->max_width)
> +				continue;
> +
> +			entity_max = entity->ops->max_width(entity, pipe);
> +			if (entity_max)
> +				div_size = min(div_size, entity_max);
> +		}
> +	}
> +
> +	pipe->partitions = DIV_ROUND_UP(format->width, div_size);
> +	pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table),
> +				   GFP_KERNEL);
> +	if (!pipe->part_table)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < pipe->partitions; ++i)
> +		vsp1_pipeline_calculate_partition(pipe, &pipe->part_table[i],
> +						  div_size, i);
> +
> +	return 0;
> +}
> +
>  static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
>  {
>  	struct vsp1_entity *entity;
> --
> Regards,
>
> Laurent Pinchart
>
>
  

Patch

diff --git a/drivers/media/platform/renesas/vsp1/vsp1_pipe.c b/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
index 68d05243c3ee..b90240b24b3a 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_pipe.c
@@ -444,6 +444,10 @@  void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 	vsp1_uds_set_alpha(pipe->uds, dlb, alpha);
 }
 
+/* -----------------------------------------------------------------------------
+ * VSP1 Partition Algorithm support
+ */
+
 /*
  * Propagate the partition calculations through the pipeline
  *
@@ -452,10 +456,10 @@  void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
  * source. Each entity must produce the partition required for the previous
  * entity in the pipeline.
  */
-void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
-				       struct vsp1_partition *partition,
-				       unsigned int index,
-				       struct vsp1_partition_window *window)
+static void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
+					      struct vsp1_partition *partition,
+					      unsigned int index,
+					      struct vsp1_partition_window *window)
 {
 	struct vsp1_entity *entity;
 
@@ -466,3 +470,76 @@  void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
 	}
 }
 
+/*
+ * vsp1_pipeline_calculate_partition - Calculate pipeline configuration for a
+ *	partition
+ *
+ * @pipe: the pipeline
+ * @partition: partition that will hold the calculated values
+ * @div_size: pre-determined maximum partition division size
+ * @index: partition index
+ */
+void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
+				       struct vsp1_partition *partition,
+				       unsigned int div_size,
+				       unsigned int index)
+{
+	const struct v4l2_mbus_framefmt *format;
+	struct vsp1_partition_window window;
+	unsigned int modulus;
+
+	/*
+	 * Partitions are computed on the size before rotation, use the format
+	 * at the WPF sink.
+	 */
+	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
+					      RWPF_PAD_SINK);
+
+	/* A single partition simply processes the output size in full. */
+	if (pipe->partitions <= 1) {
+		window.left = 0;
+		window.width = format->width;
+
+		vsp1_pipeline_propagate_partition(pipe, partition, index,
+						  &window);
+		return;
+	}
+
+	/* Initialise the partition with sane starting conditions. */
+	window.left = index * div_size;
+	window.width = div_size;
+
+	modulus = format->width % div_size;
+
+	/*
+	 * We need to prevent the last partition from being smaller than the
+	 * *minimum* width of the hardware capabilities.
+	 *
+	 * If the modulus is less than half of the partition size,
+	 * the penultimate partition is reduced to half, which is added
+	 * to the final partition: |1234|1234|1234|12|341|
+	 * to prevent this:        |1234|1234|1234|1234|1|.
+	 */
+	if (modulus) {
+		/*
+		 * pipe->partitions is 1 based, whilst index is a 0 based index.
+		 * Normalise this locally.
+		 */
+		unsigned int partitions = pipe->partitions - 1;
+
+		if (modulus < div_size / 2) {
+			if (index == partitions - 1) {
+				/* Halve the penultimate partition. */
+				window.width = div_size / 2;
+			} else if (index == partitions) {
+				/* Increase the final partition. */
+				window.width = (div_size / 2) + modulus;
+				window.left -= div_size / 2;
+			}
+		} else if (index == partitions) {
+			window.width = modulus;
+		}
+	}
+
+	vsp1_pipeline_propagate_partition(pipe, partition, index, &window);
+}
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
index 674b5748d929..02e98d843730 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
+++ b/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
@@ -166,10 +166,10 @@  void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 				   struct vsp1_dl_body *dlb,
 				   unsigned int alpha);
 
-void vsp1_pipeline_propagate_partition(struct vsp1_pipeline *pipe,
+void vsp1_pipeline_calculate_partition(struct vsp1_pipeline *pipe,
 				       struct vsp1_partition *partition,
-				       unsigned int index,
-				       struct vsp1_partition_window *window);
+				       unsigned int div_size,
+				       unsigned int index);
 
 const struct vsp1_format_info *vsp1_get_format_info(struct vsp1_device *vsp1,
 						    u32 fourcc);
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c
index 9cb81b4c65ed..ea5773af54d6 100644
--- a/drivers/media/platform/renesas/vsp1/vsp1_video.c
+++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c
@@ -172,129 +172,6 @@  static int __vsp1_video_try_format(struct vsp1_video *video,
 	return 0;
 }
 
-/* -----------------------------------------------------------------------------
- * VSP1 Partition Algorithm support
- */
-
-/**
- * vsp1_video_calculate_partition - Calculate the active partition output window
- *
- * @pipe: the pipeline
- * @partition: partition that will hold the calculated values
- * @div_size: pre-determined maximum partition division size
- * @index: partition index
- */
-static void vsp1_video_calculate_partition(struct vsp1_pipeline *pipe,
-					   struct vsp1_partition *partition,
-					   unsigned int div_size,
-					   unsigned int index)
-{
-	const struct v4l2_mbus_framefmt *format;
-	struct vsp1_partition_window window;
-	unsigned int modulus;
-
-	/*
-	 * Partitions are computed on the size before rotation, use the format
-	 * at the WPF sink.
-	 */
-	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
-					      RWPF_PAD_SINK);
-
-	/* A single partition simply processes the output size in full. */
-	if (pipe->partitions <= 1) {
-		window.left = 0;
-		window.width = format->width;
-
-		vsp1_pipeline_propagate_partition(pipe, partition, index,
-						  &window);
-		return;
-	}
-
-	/* Initialise the partition with sane starting conditions. */
-	window.left = index * div_size;
-	window.width = div_size;
-
-	modulus = format->width % div_size;
-
-	/*
-	 * We need to prevent the last partition from being smaller than the
-	 * *minimum* width of the hardware capabilities.
-	 *
-	 * If the modulus is less than half of the partition size,
-	 * the penultimate partition is reduced to half, which is added
-	 * to the final partition: |1234|1234|1234|12|341|
-	 * to prevent this:        |1234|1234|1234|1234|1|.
-	 */
-	if (modulus) {
-		/*
-		 * pipe->partitions is 1 based, whilst index is a 0 based index.
-		 * Normalise this locally.
-		 */
-		unsigned int partitions = pipe->partitions - 1;
-
-		if (modulus < div_size / 2) {
-			if (index == partitions - 1) {
-				/* Halve the penultimate partition. */
-				window.width = div_size / 2;
-			} else if (index == partitions) {
-				/* Increase the final partition. */
-				window.width = (div_size / 2) + modulus;
-				window.left -= div_size / 2;
-			}
-		} else if (index == partitions) {
-			window.width = modulus;
-		}
-	}
-
-	vsp1_pipeline_propagate_partition(pipe, partition, index, &window);
-}
-
-static int 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;
-	unsigned int i;
-
-	/*
-	 * Partitions are computed on the size before rotation, use the format
-	 * at the WPF sink.
-	 */
-	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
-					      RWPF_PAD_SINK);
-	div_size = format->width;
-
-	/*
-	 * Only Gen3+ hardware requires image partitioning, Gen2 will operate
-	 * with a single partition that covers the whole output.
-	 */
-	if (vsp1->info->gen >= 3) {
-		list_for_each_entry(entity, &pipe->entities, list_pipe) {
-			unsigned int entity_max;
-
-			if (!entity->ops->max_width)
-				continue;
-
-			entity_max = entity->ops->max_width(entity, pipe);
-			if (entity_max)
-				div_size = min(div_size, entity_max);
-		}
-	}
-
-	pipe->partitions = DIV_ROUND_UP(format->width, div_size);
-	pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table),
-				   GFP_KERNEL);
-	if (!pipe->part_table)
-		return -ENOMEM;
-
-	for (i = 0; i < pipe->partitions; ++i)
-		vsp1_video_calculate_partition(pipe, &pipe->part_table[i],
-					       div_size, i);
-
-	return 0;
-}
-
 /* -----------------------------------------------------------------------------
  * Pipeline Management
  */
@@ -782,6 +659,52 @@  static void vsp1_video_buffer_queue(struct vb2_buffer *vb)
 	spin_unlock_irqrestore(&pipe->irqlock, flags);
 }
 
+static int 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;
+	unsigned int i;
+
+	/*
+	 * Partitions are computed on the size before rotation, use the format
+	 * at the WPF sink.
+	 */
+	format = v4l2_subdev_state_get_format(pipe->output->entity.state,
+					      RWPF_PAD_SINK);
+	div_size = format->width;
+
+	/*
+	 * Only Gen3+ hardware requires image partitioning, Gen2 will operate
+	 * with a single partition that covers the whole output.
+	 */
+	if (vsp1->info->gen >= 3) {
+		list_for_each_entry(entity, &pipe->entities, list_pipe) {
+			unsigned int entity_max;
+
+			if (!entity->ops->max_width)
+				continue;
+
+			entity_max = entity->ops->max_width(entity, pipe);
+			if (entity_max)
+				div_size = min(div_size, entity_max);
+		}
+	}
+
+	pipe->partitions = DIV_ROUND_UP(format->width, div_size);
+	pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table),
+				   GFP_KERNEL);
+	if (!pipe->part_table)
+		return -ENOMEM;
+
+	for (i = 0; i < pipe->partitions; ++i)
+		vsp1_pipeline_calculate_partition(pipe, &pipe->part_table[i],
+						  div_size, i);
+
+	return 0;
+}
+
 static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe)
 {
 	struct vsp1_entity *entity;