From patchwork Fri Aug 4 15:57:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 9881591 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3CD4E6031B for ; Fri, 4 Aug 2017 15:57:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2A99428985 for ; Fri, 4 Aug 2017 15:57:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1DE552896F; Fri, 4 Aug 2017 15:57:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86A91289B2 for ; Fri, 4 Aug 2017 15:57:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752433AbdHDP5X (ORCPT ); Fri, 4 Aug 2017 11:57:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:35746 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752547AbdHDP5T (ORCPT ); Fri, 4 Aug 2017 11:57:19 -0400 Received: from CookieMonster.cookiemonster.local (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 76D3422CB1; Fri, 4 Aug 2017 15:57:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 76D3422CB1 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: mail.kernel.org; spf=fail smtp.mailfrom=kieran.bingham+renesas@ideasonboard.com From: Kieran Bingham To: linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Cc: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, Kieran Bingham Subject: [PATCH v3 3/7] v4l: vsp1: Calculate partition sizes at stream start Date: Fri, 4 Aug 2017 16:57:07 +0100 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Previously the active window and partition sizes for each partition were calculated for each partition every frame. This data is constant and only needs to be calculated once at the start of the stream. Extend the vsp1_pipe object to dynamically store the number of partitions required and pre-calculate the partition sizes into this table. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- drivers/media/platform/vsp1/vsp1_pipe.h | 3 ++- drivers/media/platform/vsp1/vsp1_video.c | 48 +++++++++++++++++-------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_pipe.h b/drivers/media/platform/vsp1/vsp1_pipe.h index 91a784a13422..0cfd07a187a2 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.h +++ b/drivers/media/platform/vsp1/vsp1_pipe.h @@ -82,7 +82,9 @@ enum vsp1_pipeline_state { * @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 + * @partition: The current partition for configuration to process * @current_partition: The partition number currently being configured + * @part_table: The pre-calculated partitions used by the pipeline */ struct vsp1_pipeline { struct media_pipeline pipe; @@ -117,6 +119,7 @@ struct vsp1_pipeline { unsigned int partitions; struct v4l2_rect partition; unsigned int current_partition; + struct v4l2_rect *part_table; }; void vsp1_pipeline_reset(struct vsp1_pipeline *pipe); diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index 097e4db572a9..447597f1b758 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -256,12 +256,13 @@ static struct v4l2_rect vsp1_video_partition(struct vsp1_pipeline *pipe, return partition; } -static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) +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 @@ -272,17 +273,17 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) RWPF_PAD_SINK); 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; - } + /* + * 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; - list_for_each_entry(entity, &pipe->entities, list_pipe) { - unsigned int entity_max = VSP1_VIDEO_MAX_WIDTH; + if (!entity->ops->max_width) + continue; - if (entity->ops->max_width) { entity_max = entity->ops->max_width(entity, pipe); if (entity_max) div_size = min(div_size, entity_max); @@ -291,6 +292,15 @@ static void vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) pipe->div_size = div_size; 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) + pipe->part_table[i] = vsp1_video_partition(pipe, div_size, i); + + return 0; } /* ----------------------------------------------------------------------------- @@ -373,8 +383,7 @@ static void vsp1_video_pipeline_run_partition(struct vsp1_pipeline *pipe, { struct vsp1_entity *entity; - pipe->partition = vsp1_video_partition(pipe, pipe->div_size, - pipe->current_partition); + pipe->partition = pipe->part_table[pipe->current_partition]; list_for_each_entry(entity, &pipe->entities, list_pipe) { if (entity->ops->configure) @@ -783,9 +792,12 @@ static void vsp1_video_buffer_queue(struct vb2_buffer *vb) static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) { struct vsp1_entity *entity; + int ret; /* Determine this pipelines sizes for image partitioning support. */ - vsp1_video_pipeline_setup_partitions(pipe); + ret = vsp1_video_pipeline_setup_partitions(pipe); + if (ret < 0) + return ret; /* Prepare the display list. */ pipe->dl = vsp1_dl_list_get(pipe->output->dlm); @@ -824,6 +836,7 @@ static int vsp1_video_setup_pipeline(struct vsp1_pipeline *pipe) static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) { + struct vsp1_pipeline *pipe = video->rwpf->pipe; struct vsp1_vb2_buffer *buffer; unsigned long flags; @@ -833,6 +846,12 @@ static void vsp1_video_cleanup_pipeline(struct vsp1_video *video) vb2_buffer_done(&buffer->buf.vb2_buf, VB2_BUF_STATE_ERROR); INIT_LIST_HEAD(&video->irqqueue); spin_unlock_irqrestore(&video->irqlock, flags); + + /* Release our partition table allocation */ + mutex_lock(&pipe->lock); + kfree(pipe->part_table); + pipe->part_table = NULL; + mutex_unlock(&pipe->lock); } static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) @@ -904,9 +923,8 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq) mutex_unlock(&pipe->lock); media_pipeline_stop(&video->video.entity); - vsp1_video_pipeline_put(pipe); - vsp1_video_cleanup_pipeline(video); + vsp1_video_pipeline_put(pipe); } static const struct vb2_ops vsp1_video_queue_qops = {