From patchwork Tue Aug 2 14:51:05 2016 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: 9257891 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 6A3976089F for ; Tue, 2 Aug 2016 14:52:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5BEE22853E for ; Tue, 2 Aug 2016 14:52:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5042128611; Tue, 2 Aug 2016 14:52:18 +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 D324F285AE for ; Tue, 2 Aug 2016 14:52:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965298AbcHBOwF (ORCPT ); Tue, 2 Aug 2016 10:52:05 -0400 Received: from smtp-3.sys.kth.se ([130.237.48.192]:53046 "EHLO smtp-3.sys.kth.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965216AbcHBOvm (ORCPT ); Tue, 2 Aug 2016 10:51:42 -0400 Received: from smtp-3.sys.kth.se (localhost.localdomain [127.0.0.1]) by smtp-3.sys.kth.se (Postfix) with ESMTP id CCF302B88; Tue, 2 Aug 2016 16:51:29 +0200 (CEST) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-3.sys.kth.se ([127.0.0.1]) by smtp-3.sys.kth.se (smtp-3.sys.kth.se [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 34V52u8mofxG; Tue, 2 Aug 2016 16:51:29 +0200 (CEST) X-KTH-Auth: niso [89.233.230.99] X-KTH-mail-from: niklas.soderlund+renesas@ragnatech.se Received: from bismarck.berto.se (unknown [89.233.230.99]) by smtp-3.sys.kth.se (Postfix) with ESMTPSA id CB8742685; Tue, 2 Aug 2016 16:51:28 +0200 (CEST) From: =?UTF-8?q?Niklas=20S=C3=B6derlund?= To: linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, sergei.shtylyov@cogentembedded.com, slongerbeam@gmail.com Cc: lars@metafoo.de, mchehab@kernel.org, hans.verkuil@cisco.com, =?UTF-8?q?Niklas=20S=C3=B6derlund?= Subject: [PATCHv2 5/7] media: rcar-vin: add support for V4L2_FIELD_ALTERNATE Date: Tue, 2 Aug 2016 16:51:05 +0200 Message-Id: <20160802145107.24829-6-niklas.soderlund+renesas@ragnatech.se> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20160802145107.24829-1-niklas.soderlund+renesas@ragnatech.se> References: <20160802145107.24829-1-niklas.soderlund+renesas@ragnatech.se> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The HW can capture both ODD and EVEN fields in separate buffers so it's possible to support V4L2_FIELD_ALTERNATE. This patch add support for this mode. At probe time and when S_STD is called the driver will default to use V4L2_FIELD_INTERLACED if the subdevice reports V4L2_FIELD_ALTERNATE. The driver will only change the field type if the subdevice implements G_STD, if not it will keep the default at V4L2_FIELD_ALTERNATE. The user can always explicitly ask for V4L2_FIELD_ALTERNATE in S_FTM and the driver will use that field format. Signed-off-by: Niklas Söderlund --- drivers/media/platform/rcar-vin/rcar-dma.c | 26 ++++++++++++++++++++------ drivers/media/platform/rcar-vin/rcar-v4l2.c | 13 +++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 4063775..80139ad 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -95,6 +95,7 @@ /* Video n Module Status Register bits */ #define VNMS_FBS_MASK (3 << 3) #define VNMS_FBS_SHIFT 3 +#define VNMS_FS (1 << 2) #define VNMS_AV (1 << 1) #define VNMS_CA (1 << 0) @@ -155,6 +156,7 @@ static int rvin_setup(struct rvin_dev *vin) case V4L2_FIELD_INTERLACED_BT: vnmc = VNMC_IM_FULL | VNMC_FOC; break; + case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_NONE: if (vin->continuous) { vnmc = VNMC_IM_ODD_EVEN; @@ -330,15 +332,26 @@ static bool rvin_capture_active(struct rvin_dev *vin) return rvin_read(vin, VNMS_REG) & VNMS_CA; } -static int rvin_get_active_slot(struct rvin_dev *vin) +static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) { if (vin->continuous) - return (rvin_read(vin, VNMS_REG) & VNMS_FBS_MASK) - >> VNMS_FBS_SHIFT; + return (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; return 0; } +static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) +{ + if (vin->format.field == V4L2_FIELD_ALTERNATE) { + /* If FS is set it's a Even field */ + if (vnms & VNMS_FS) + return V4L2_FIELD_BOTTOM; + return V4L2_FIELD_TOP; + } + + return vin->format.field; +} + static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) { const struct rvin_video_format *fmt; @@ -879,7 +892,7 @@ static bool rvin_fill_hw(struct rvin_dev *vin) static irqreturn_t rvin_irq(int irq, void *data) { struct rvin_dev *vin = data; - u32 int_status; + u32 int_status, vnms; int slot; unsigned int sequence, handled = 0; unsigned long flags; @@ -906,7 +919,8 @@ static irqreturn_t rvin_irq(int irq, void *data) } /* Prepare for capture and update state */ - slot = rvin_get_active_slot(vin); + vnms = rvin_read(vin, VNMS_REG); + slot = rvin_get_active_slot(vin, vnms); sequence = vin->sequence++; vin_dbg(vin, "IRQ %02d: %d\tbuf0: %c buf1: %c buf2: %c\tmore: %d\n", @@ -921,7 +935,7 @@ static irqreturn_t rvin_irq(int irq, void *data) goto done; /* Capture frame */ - vin->queue_buf[slot]->field = vin->format.field; + vin->queue_buf[slot]->field = rvin_get_active_field(vin, vnms); vin->queue_buf[slot]->sequence = sequence; vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, VB2_BUF_STATE_DONE); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index c31ac73..125f87e 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -122,9 +122,21 @@ static int rvin_reset_format(struct rvin_dev *vin) vin->format.colorspace = mf->colorspace; vin->format.field = mf->field; + /* + * If the subdevice uses ALTERNATE field mode and G_STD is + * implemented use the VIN HW to combine the two fields to + * one INTERLACED frame. The ALTERNATE field mode can still + * be requested in S_FMT and be respected, this is just the + * default which is applied at probing or when S_STD is called. + */ + if (vin->format.field == V4L2_FIELD_ALTERNATE && + v4l2_subdev_has_op(vin_to_source(vin), video, g_std)) + vin->format.field = V4L2_FIELD_INTERLACED; + switch (vin->format.field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_ALTERNATE: vin->format.height /= 2; break; case V4L2_FIELD_NONE: @@ -226,6 +238,7 @@ static int __rvin_try_format(struct rvin_dev *vin, switch (pix->field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: + case V4L2_FIELD_ALTERNATE: pix->height /= 2; source->height /= 2; break;