Message ID | 20231122043009.2741-7-laurent.pinchart+renesas@ideasonboard.com |
---|---|
State | Superseded |
Headers | show |
Series | None | expand |
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 > >
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;
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(-)