From patchwork Thu Feb 21 10:32:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10823597 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 337076C2 for ; Thu, 21 Feb 2019 10:32:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2276E30656 for ; Thu, 21 Feb 2019 10:32:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 16DC830671; Thu, 21 Feb 2019 10:32:47 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1180730656 for ; Thu, 21 Feb 2019 10:32:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B5F389471; Thu, 21 Feb 2019 10:32:35 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id 48A83891CB for ; Thu, 21 Feb 2019 10:32:28 +0000 (UTC) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6E601D0C; Thu, 21 Feb 2019 11:32:24 +0100 (CET) From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Subject: [PATCH v5 07/19] media: vsp1: dl: Support one-shot entries in the display list Date: Thu, 21 Feb 2019 12:32:00 +0200 Message-Id: <20190221103212.28764-8-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190221103212.28764-1-laurent.pinchart+renesas@ideasonboard.com> References: <20190221103212.28764-1-laurent.pinchart+renesas@ideasonboard.com> MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1550745144; bh=+TzndeWufNGhl/x8gYm2HpvMWdwrgt3yRw+u11PT6ZE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p7/hdIYElWa7+x5MtzRZBXqeBHaQHgdQgUEuR0sl1QQFobFem/oNseQCDO3lRVv7T zjxV18ng4Bu+Qw9Bb8Fn6DGybT3ibESY6WBuFb7PisKPfvOjhbwActaJC0t/lor+Ae rElf9NG85pY79sm0nID4QOKbfUqxDEq+Egfx7qX0= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Liviu Dudau , James Qian Wang , Kieran Bingham Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP One-shot entries are used as an alternative to committing a complete new display list when a couple of registers need to be written for one frame and then reset to another value for all subsequent frames. This will be used to implement writeback support that will need to enable writeback for the duration of a single frame. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- drivers/media/platform/vsp1/vsp1_dl.c | 78 +++++++++++++++++++++++++++ drivers/media/platform/vsp1/vsp1_dl.h | 3 ++ 2 files changed, 81 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 886b3a69d329..7b4d252bfde7 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -115,6 +115,12 @@ struct vsp1_dl_body { unsigned int num_entries; unsigned int max_entries; + + unsigned int num_patches; + struct { + struct vsp1_dl_entry *entry; + u32 data; + } patches[2]; }; /** @@ -361,6 +367,7 @@ void vsp1_dl_body_put(struct vsp1_dl_body *dlb) return; dlb->num_entries = 0; + dlb->num_patches = 0; spin_lock_irqsave(&dlb->pool->lock, flags); list_add_tail(&dlb->free, &dlb->pool->free); @@ -388,6 +395,47 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data) dlb->num_entries++; } +/** + * vsp1_dl_body_write_oneshot - Write a register to a display list body for a + * single frame + * @dlb: The body + * @reg: The register address + * @value: The register value + * @reset_value: The value to reset the register to at the next vblank + * + * Display lists in continuous mode are re-used by the hardware for successive + * frames until a new display list is committed. Changing the VSP configuration + * normally requires creating and committing a new display list. This function + * offers an alternative race-free way by writing a @value to the @register in + * the display list body for a single frame, specifying in @reset_value the + * value to reset the register to one vblank after the display list is + * committed. + * + * The maximum number of one-shot entries is limited to 2 per display list body, + * and one-shot entries are counted in the total number of entries specified + * when the body is allocated by vsp1_dl_body_alloc(). + */ +void vsp1_dl_body_write_oneshot(struct vsp1_dl_body *dlb, u32 reg, u32 value, + u32 reset_value) +{ + if (WARN_ONCE(dlb->num_entries >= dlb->max_entries, + "DLB size exceeded (max %u)", dlb->max_entries)) + return; + + if (WARN_ONCE(dlb->num_patches >= ARRAY_SIZE(dlb->patches), + "DLB patches size exceeded (max %zu)", + ARRAY_SIZE(dlb->patches))) + return; + + dlb->patches[dlb->num_patches].entry = &dlb->entries[dlb->num_entries]; + dlb->patches[dlb->num_patches].data = reset_value; + dlb->num_patches++; + + dlb->entries[dlb->num_entries].addr = reg; + dlb->entries[dlb->num_entries].data = value; + dlb->num_entries++; +} + /* ----------------------------------------------------------------------------- * Display List Extended Command Management */ @@ -652,6 +700,7 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) * has at least one body, thus we reinitialise the entries list. */ dl->body0->num_entries = 0; + dl->body0->num_patches = 0; list_add_tail(&dl->list, &dl->dlm->free); } @@ -930,6 +979,35 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl, unsigned int dl_flags) * Display List Manager */ +/** + * vsp1_dlm_irq_display_start - Display list handler for the display start + * interrupt + * @dlm: the display list manager + * + * Apply all one-shot patches registered for the active display list. + */ +void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm) +{ + struct vsp1_dl_body *dlb; + struct vsp1_dl_list *dl; + unsigned int i; + + spin_lock(&dlm->lock); + + dl = dlm->active; + if (!dl) + goto done; + + list_for_each_entry(dlb, &dl->bodies, list) { + for (i = 0; i < dlb->num_patches; ++i) + dlb->patches[i].entry->data = dlb->patches[i].data; + dlb->num_patches = 0; + } + +done: + spin_unlock(&dlm->lock); +} + /** * vsp1_dlm_irq_frame_end - Display list handler for the frame end interrupt * @dlm: the display list manager diff --git a/drivers/media/platform/vsp1/vsp1_dl.h b/drivers/media/platform/vsp1/vsp1_dl.h index e0fdb145e6ed..f845607abc4c 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.h +++ b/drivers/media/platform/vsp1/vsp1_dl.h @@ -54,6 +54,7 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, unsigned int prealloc); void vsp1_dlm_destroy(struct vsp1_dl_manager *dlm); void vsp1_dlm_reset(struct vsp1_dl_manager *dlm); +void vsp1_dlm_irq_display_start(struct vsp1_dl_manager *dlm); unsigned int vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm); struct vsp1_dl_body *vsp1_dlm_dl_body_get(struct vsp1_dl_manager *dlm); @@ -71,6 +72,8 @@ struct vsp1_dl_body *vsp1_dl_body_get(struct vsp1_dl_body_pool *pool); void vsp1_dl_body_put(struct vsp1_dl_body *dlb); void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data); +void vsp1_dl_body_write_oneshot(struct vsp1_dl_body *dlb, u32 reg, u32 value, + u32 reset_value); int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb); int vsp1_dl_list_add_chain(struct vsp1_dl_list *head, struct vsp1_dl_list *dl);