From patchwork Thu Oct 15 23:14:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11840297 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 64D8E17CA for ; Thu, 15 Oct 2020 23:14:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 50070207BC for ; Thu, 15 Oct 2020 23:14:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731088AbgJOXO3 (ORCPT ); Thu, 15 Oct 2020 19:14:29 -0400 Received: from vsp-unauthed02.binero.net ([195.74.38.227]:65386 "EHLO vsp-unauthed02.binero.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730870AbgJOXO3 (ORCPT ); Thu, 15 Oct 2020 19:14:29 -0400 X-Halon-ID: 240a1678-0f3c-11eb-9f83-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2fef.dip0.t-ipconnect.de [79.202.47.239]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 240a1678-0f3c-11eb-9f83-005056917a89; Fri, 16 Oct 2020 01:14:14 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Laurent Pinchart , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH 1/5] rcar-vin: Use scratch buffer when not in running state Date: Fri, 16 Oct 2020 01:14:04 +0200 Message-Id: <20201015231408.2399933-2-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> References: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org In its early stages the VIN driver did not use an internal scratch buffer. This lead to a unnecessary complex start and stop behavior, specially for TB/BT. The driver now always allocates a scratch buffer to deal with buffer under-runs, use the scratch buffer to also simplify starting and stopping. When capture is starting use the scratch buffer instead of a user-space buffers while syncing the driver with the hardware state. This allows the driver to know that no user-space buffers is given to the hardware before the running state is reached. When capture is stopping use the scratch buffer instead of leaving the user-space buffers in place and add a check that all user-space buffers are processed by the hardware before transitioning from the stopping to stopped state. This allows the driver to know all user-space buffers given to the hardware are fully processed. This change in itself does not improve the driver much but it paves way for future simplifications and enhancements. One direct improvement of this change is that TB/BT buffers returned to user-space wile stopping will always contains both fields, that was not guaranteed before. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-dma.c | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 692dea300b0de8b5..ca90bde8d29f77d1 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -905,7 +905,7 @@ static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) vin->format.sizeimage / 2; break; } - } else if (list_empty(&vin->buf_list)) { + } else if (vin->state != RUNNING || list_empty(&vin->buf_list)) { vin->buf_hw[slot].buffer = NULL; vin->buf_hw[slot].type = FULL; phys_addr = vin->scratch_phys; @@ -998,12 +998,6 @@ static irqreturn_t rvin_irq(int irq, void *data) goto done; } - /* Nothing to do if capture status is 'STOPPING' */ - if (vin->state == STOPPING) { - vin_dbg(vin, "IRQ while state stopping\n"); - goto done; - } - /* Prepare for capture and update state */ vnms = rvin_read(vin, VNMS_REG); slot = (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; @@ -1313,14 +1307,32 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) static void rvin_stop_streaming(struct vb2_queue *vq) { struct rvin_dev *vin = vb2_get_drv_priv(vq); + unsigned int i, retries; unsigned long flags; - int retries = 0; + bool buffersFreed; spin_lock_irqsave(&vin->qlock, flags); vin->state = STOPPING; + /* Wait until only scratch buffer is used, max 3 interrupts. */ + retries = 0; + while (retries++ < RVIN_RETRIES) { + buffersFreed = true; + for (i = 0; i < HW_BUFFER_NUM; i++) + if (vin->buf_hw[i].buffer) + buffersFreed = false; + + if (buffersFreed) + break; + + spin_unlock_irqrestore(&vin->qlock, flags); + msleep(RVIN_TIMEOUT_MS); + spin_lock_irqsave(&vin->qlock, flags); + } + /* Wait for streaming to stop */ + retries = 0; while (retries++ < RVIN_RETRIES) { rvin_capture_stop(vin); @@ -1336,7 +1348,7 @@ static void rvin_stop_streaming(struct vb2_queue *vq) spin_lock_irqsave(&vin->qlock, flags); } - if (vin->state != STOPPED) { + if (!buffersFreed || vin->state != STOPPED) { /* * If this happens something have gone horribly wrong. * Set state to stopped to prevent the interrupt handler From patchwork Thu Oct 15 23:14:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11840299 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84D6914B5 for ; Thu, 15 Oct 2020 23:14:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 71BA6207C4 for ; Thu, 15 Oct 2020 23:14:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732765AbgJOXOc (ORCPT ); Thu, 15 Oct 2020 19:14:32 -0400 Received: from vsp-unauthed02.binero.net ([195.74.38.227]:12210 "EHLO vsp-unauthed02.binero.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730957AbgJOXOb (ORCPT ); Thu, 15 Oct 2020 19:14:31 -0400 X-Halon-ID: 2484ced0-0f3c-11eb-9f83-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2fef.dip0.t-ipconnect.de [79.202.47.239]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 2484ced0-0f3c-11eb-9f83-005056917a89; Fri, 16 Oct 2020 01:14:15 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Laurent Pinchart , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH 2/5] rcar-vin: Remove handling of user-space buffers when stopping Date: Fri, 16 Oct 2020 01:14:05 +0200 Message-Id: <20201015231408.2399933-3-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> References: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org When returning buffers to user-space it's no longer needed to examine the buffers given to hardware as recent changes guarantees the only buffer present in the hardware registers when the driver is not in the running state is the scratch buffer. Remove the special case and rename the function to better describe it now only deals with buffers queued to the driver but not yet recorded in the hardware registers. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-dma.c | 31 +++++----------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index ca90bde8d29f77d1..680160f9f851d8a3 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1051,27 +1051,10 @@ static irqreturn_t rvin_irq(int irq, void *data) } /* Need to hold qlock before calling */ -static void return_all_buffers(struct rvin_dev *vin, - enum vb2_buffer_state state) +static void return_unused_buffers(struct rvin_dev *vin, + enum vb2_buffer_state state) { struct rvin_buffer *buf, *node; - struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM]; - unsigned int i, n; - - for (i = 0; i < HW_BUFFER_NUM; i++) { - freed[i] = vin->buf_hw[i].buffer; - vin->buf_hw[i].buffer = NULL; - - for (n = 0; n < i; n++) { - if (freed[i] == freed[n]) { - freed[i] = NULL; - break; - } - } - - if (freed[i]) - vb2_buffer_done(&freed[i]->vb2_buf, state); - } list_for_each_entry_safe(buf, node, &vin->buf_list, list) { vb2_buffer_done(&buf->vb.vb2_buf, state); @@ -1271,7 +1254,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) &vin->scratch_phys, GFP_KERNEL); if (!vin->scratch) { spin_lock_irqsave(&vin->qlock, flags); - return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); spin_unlock_irqrestore(&vin->qlock, flags); vin_err(vin, "Failed to allocate scratch buffer\n"); return -ENOMEM; @@ -1280,7 +1263,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) ret = rvin_set_stream(vin, 1); if (ret) { spin_lock_irqsave(&vin->qlock, flags); - return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); spin_unlock_irqrestore(&vin->qlock, flags); goto out; } @@ -1291,7 +1274,7 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) ret = rvin_capture_start(vin); if (ret) { - return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); rvin_set_stream(vin, 0); } @@ -1358,8 +1341,8 @@ static void rvin_stop_streaming(struct vb2_queue *vq) vin->state = STOPPED; } - /* Release all active buffers */ - return_all_buffers(vin, VB2_BUF_STATE_ERROR); + /* Return all unused buffers. */ + return_unused_buffers(vin, VB2_BUF_STATE_ERROR); spin_unlock_irqrestore(&vin->qlock, flags); From patchwork Thu Oct 15 23:14:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11840301 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD73317D1 for ; Thu, 15 Oct 2020 23:14:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9F2B0207C4 for ; Thu, 15 Oct 2020 23:14:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731173AbgJOXOa (ORCPT ); Thu, 15 Oct 2020 19:14:30 -0400 Received: from bin-mail-out-05.binero.net ([195.74.38.228]:62666 "EHLO bin-mail-out-05.binero.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730957AbgJOXOa (ORCPT ); Thu, 15 Oct 2020 19:14:30 -0400 X-Halon-ID: 24f6fac1-0f3c-11eb-9f83-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2fef.dip0.t-ipconnect.de [79.202.47.239]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 24f6fac1-0f3c-11eb-9f83-005056917a89; Fri, 16 Oct 2020 01:14:16 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Laurent Pinchart , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH 3/5] rcar-vin: Cache the CSI-2 channel selection value Date: Fri, 16 Oct 2020 01:14:06 +0200 Message-Id: <20201015231408.2399933-4-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> References: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org In preparation of suspend/resume support cache the chsel value when written to the register so it can be restored on resume if needed. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-dma.c | 2 ++ drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 680160f9f851d8a3..f65deac4c2dbed54 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1456,6 +1456,8 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) vin_dbg(vin, "Set IFMD 0x%x\n", ifmd); + vin->chsel = chsel; + /* Restore VNMC. */ rvin_write(vin, vnmc, VNMC_REG); diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 8396e0e45478fe4f..2fef23470e3ddfe3 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -189,6 +189,7 @@ struct rvin_info { * @state: keeps track of operation state * * @is_csi: flag to mark the VIN as using a CSI-2 subdevice + * @chsel Cached value of the current CSI-2 channel selection * * @mbus_code: media bus format code * @format: active V4L2 pixel format @@ -232,6 +233,7 @@ struct rvin_dev { enum rvin_dma_state state; bool is_csi; + unsigned int chsel; u32 mbus_code; struct v4l2_pix_format format; From patchwork Thu Oct 15 23:14:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11840305 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7D83417D1 for ; Thu, 15 Oct 2020 23:14:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 682112080C for ; Thu, 15 Oct 2020 23:14:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732767AbgJOXOg (ORCPT ); Thu, 15 Oct 2020 19:14:36 -0400 Received: from bin-mail-out-06.binero.net ([195.74.38.229]:57699 "EHLO bin-mail-out-06.binero.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726877AbgJOXOc (ORCPT ); Thu, 15 Oct 2020 19:14:32 -0400 X-Halon-ID: 255f27c2-0f3c-11eb-9f83-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2fef.dip0.t-ipconnect.de [79.202.47.239]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 255f27c2-0f3c-11eb-9f83-005056917a89; Fri, 16 Oct 2020 01:14:16 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Laurent Pinchart , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH 4/5] rcar-vin: Break out hardware start and stop to new methods Date: Fri, 16 Oct 2020 01:14:07 +0200 Message-Id: <20201015231408.2399933-5-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> References: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org To support suspend and resume the ability to start and stop the hardware needs to be available internally in the driver. Currently this code is in the start and stop callbacks of the vb2_ops struct. In these callbacks the code is intertwined with buffer allocation and freeing. Prepare for suspend and resume support by braking out the hardware start/stop code into new methods. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-dma.c | 78 +++++++++++++--------- drivers/media/platform/rcar-vin/rcar-vin.h | 3 + 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index f65deac4c2dbed54..5a5f0e5007478c8d 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1050,16 +1050,20 @@ static irqreturn_t rvin_irq(int irq, void *data) return IRQ_RETVAL(handled); } -/* Need to hold qlock before calling */ static void return_unused_buffers(struct rvin_dev *vin, enum vb2_buffer_state state) { struct rvin_buffer *buf, *node; + unsigned long flags; + + spin_lock_irqsave(&vin->qlock, flags); list_for_each_entry_safe(buf, node, &vin->buf_list, list) { vb2_buffer_done(&buf->vb.vb2_buf, state); list_del(&buf->list); } + + spin_unlock_irqrestore(&vin->qlock, flags); } static int rvin_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, @@ -1243,53 +1247,55 @@ static int rvin_set_stream(struct rvin_dev *vin, int on) return ret; } -static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) +int rvin_start_streaming(struct rvin_dev *vin) { - struct rvin_dev *vin = vb2_get_drv_priv(vq); unsigned long flags; int ret; - /* Allocate scratch buffer. */ - vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, - &vin->scratch_phys, GFP_KERNEL); - if (!vin->scratch) { - spin_lock_irqsave(&vin->qlock, flags); - return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); - spin_unlock_irqrestore(&vin->qlock, flags); - vin_err(vin, "Failed to allocate scratch buffer\n"); - return -ENOMEM; - } - ret = rvin_set_stream(vin, 1); - if (ret) { - spin_lock_irqsave(&vin->qlock, flags); - return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); - spin_unlock_irqrestore(&vin->qlock, flags); - goto out; - } + if (ret) + return ret; spin_lock_irqsave(&vin->qlock, flags); vin->sequence = 0; ret = rvin_capture_start(vin); - if (ret) { - return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); + if (ret) rvin_set_stream(vin, 0); - } spin_unlock_irqrestore(&vin->qlock, flags); -out: - if (ret) - dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, - vin->scratch_phys); return ret; } -static void rvin_stop_streaming(struct vb2_queue *vq) +static int rvin_start_streaming_vq(struct vb2_queue *vq, unsigned int count) { struct rvin_dev *vin = vb2_get_drv_priv(vq); + int ret = -ENOMEM; + + /* Allocate scratch buffer. */ + vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, + &vin->scratch_phys, GFP_KERNEL); + if (!vin->scratch) + goto err_scratch; + + ret = rvin_start_streaming(vin); + if (ret) + goto err_start; + + return 0; +err_start: + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, + vin->scratch_phys); +err_scratch: + return_unused_buffers(vin, VB2_BUF_STATE_QUEUED); + + return ret; +} + +void rvin_stop_streaming(struct rvin_dev *vin) +{ unsigned int i, retries; unsigned long flags; bool buffersFreed; @@ -1341,27 +1347,33 @@ static void rvin_stop_streaming(struct vb2_queue *vq) vin->state = STOPPED; } - /* Return all unused buffers. */ - return_unused_buffers(vin, VB2_BUF_STATE_ERROR); - spin_unlock_irqrestore(&vin->qlock, flags); rvin_set_stream(vin, 0); /* disable interrupts */ rvin_disable_interrupts(vin); +} + +static void rvin_stop_streaming_vq(struct vb2_queue *vq) +{ + struct rvin_dev *vin = vb2_get_drv_priv(vq); + + rvin_stop_streaming(vin); /* Free scratch buffer. */ dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, vin->scratch_phys); + + return_unused_buffers(vin, VB2_BUF_STATE_ERROR); } static const struct vb2_ops rvin_qops = { .queue_setup = rvin_queue_setup, .buf_prepare = rvin_buffer_prepare, .buf_queue = rvin_buffer_queue, - .start_streaming = rvin_start_streaming, - .stop_streaming = rvin_stop_streaming, + .start_streaming = rvin_start_streaming_vq, + .stop_streaming = rvin_stop_streaming_vq, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, }; diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 2fef23470e3ddfe3..4ec8584709c847a9 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -299,4 +299,7 @@ void rvin_crop_scale_comp(struct rvin_dev *vin); int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel); void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha); +int rvin_start_streaming(struct rvin_dev *vin); +void rvin_stop_streaming(struct rvin_dev *vin); + #endif From patchwork Thu Oct 15 23:14:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 11840303 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 387F514B5 for ; Thu, 15 Oct 2020 23:14:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 228DC207DE for ; Thu, 15 Oct 2020 23:14:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387422AbgJOXOg (ORCPT ); Thu, 15 Oct 2020 19:14:36 -0400 Received: from bin-mail-out-06.binero.net ([195.74.38.229]:46490 "EHLO bin-mail-out-06.binero.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731189AbgJOXOb (ORCPT ); Thu, 15 Oct 2020 19:14:31 -0400 X-Halon-ID: 25deee0c-0f3c-11eb-9f83-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p4fca2fef.dip0.t-ipconnect.de [79.202.47.239]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 25deee0c-0f3c-11eb-9f83-005056917a89; Fri, 16 Oct 2020 01:14:17 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: Laurent Pinchart , linux-media@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH 5/5] rcar-vin: Add support for suspend and resume Date: Fri, 16 Oct 2020 01:14:08 +0200 Message-Id: <20201015231408.2399933-6-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> References: <20201015231408.2399933-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add support for suspend and resume by stopping and starting the video pipeline while still retaining all buffers given to the driver by user-space and internally allocated ones, this gives the application a seamless experience. Buffers are never returned to user-space unprocessed so user-space don't notice when suspending. When resuming the driver restarts the capture session using the internal scratch buffer, this happens before user-space is unfrozen, this leads to speedy response times once the application resumes its execution. As the entire pipeline is stopped on suspend all subdevices in use are also stopped, and if they enter a shutdown state when not streaming (such as the R-Car CSI-2 driver) they too will be suspended and resumed in sync with the VIN driver. To be able to do keep track of which VINs should be resumed a new internal state SUSPENDED is added to recode this. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-core.c | 51 +++++++++++++++++++++ drivers/media/platform/rcar-vin/rcar-vin.h | 10 ++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 34d003e0e9b9c25a..4adf4ce518f79c93 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -918,6 +918,54 @@ static int rvin_mc_init(struct rvin_dev *vin) return ret; } +/* ----------------------------------------------------------------------------- + * Suspend / Resume + */ + +static int __maybe_unused rvin_suspend(struct device *dev) +{ + struct rvin_dev *vin = dev_get_drvdata(dev); + + if (vin->state != RUNNING) + return 0; + + rvin_stop_streaming(vin); + + vin->state = SUSPENDED; + + return 0; +} + +static int __maybe_unused rvin_resume(struct device *dev) +{ + struct rvin_dev *vin = dev_get_drvdata(dev); + + if (vin->state != SUSPENDED) + return 0; + + /* + * Restore group master CHSEL setting. + * + * This needs to be by every VIN resuming not only the master + * as we don't know if and in which order the master VINs will + * be resumed. + */ + if (vin->info->use_mc) { + unsigned int master_id = rvin_group_id_to_master(vin->id); + struct rvin_dev *master = vin->group->vin[master_id]; + int ret; + + if (WARN_ON(!master)) + return -ENODEV; + + ret = rvin_set_channel_routing(master, master->chsel); + if (ret) + return ret; + } + + return rvin_start_streaming(vin); +} + /* ----------------------------------------------------------------------------- * Platform Device Driver */ @@ -1421,9 +1469,12 @@ static int rcar_vin_remove(struct platform_device *pdev) return 0; } +static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume); + static struct platform_driver rcar_vin_driver = { .driver = { .name = "rcar-vin", + .pm = &rvin_pm_ops, .of_match_table = rvin_of_id_table, }, .probe = rcar_vin_probe, diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 4ec8584709c847a9..4539bd53d9d41e9c 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -49,16 +49,18 @@ enum rvin_csi_id { }; /** - * STOPPED - No operation in progress - * STARTING - Capture starting up - * RUNNING - Operation in progress have buffers - * STOPPING - Stopping operation + * STOPPED - No operation in progress + * STARTING - Capture starting up + * RUNNING - Operation in progress have buffers + * STOPPING - Stopping operation + * SUSPENDED - Capture is suspended */ enum rvin_dma_state { STOPPED = 0, STARTING, RUNNING, STOPPING, + SUSPENDED, }; /**