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@xxxxxxxxxxxxxxxx> > --- > .../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@xxxxxxxxxxxxxxxx> > + */ > +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 > >