From patchwork Mon Dec 13 13:49:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523574 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 740F3C433F5 for ; Mon, 13 Dec 2021 13:50:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237977AbhLMNuX (ORCPT ); Mon, 13 Dec 2021 08:50:23 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:11388 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233633AbhLMNuX (ORCPT ); Mon, 13 Dec 2021 08:50:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403423; x=1670939423; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=FqvwlZxB/OJUGSNd0nD5EpkHzuOHgqAauXHPtlBZFiw=; b=YHZfHLY0ZHHpuuMmPSal30ZlVl6GH4Jj6ax1RzJIuR3YTWjgcJl0deNe MdKSKmmcyyyYHPxWny4tFk1RpKg1MBbSW7XKEjiMIzo2nBPhu6UaEIEqD g/lqQJHt63HuBAZJ2Nua/TLeCCui+Q4T9OxsCnClJbXnGmBUENTVvpUKH 073XepZhAYdvccAJetAR0PKQjaO2l6JLXKGgBltYEiocdxLRojXIXWU+a xIaadxSgZxSY2pAuRZ6pU0PyyMvBQqd/UL3gAqb5t6hl+oeDDJWDfiDY7 NG92ef9CAGryV3FbVhBxvYqzy38+13zNvOll9KSVUiqPVCEOhQoJfJ8Ag g==; IronPort-SDR: BPxNGInRynISDrcx2C8xHGf4OqtNdF24Bqs2bt/Urfx8GwkT5dLs2SURFce6J7ki/i3TBO1Bpm KrOPzsBkd9sEZoODrLeJweua42+n2sQ5Zzy6flZbQ3Js28n0bGmGH8gOmipjpFuz0ukErBy7n6 eRSmvpEqJgKXazxoofWVJpZn/TjEQP5VjedELfAt0n4hVvPKJPunE+tx0SVav8RaQbLLodCcCX REFR6UnaCAx1FOILu2LWEC4MrGI7gqYnV7lquM6xxGGp/rNLIaXr1wH8DgWbQpbN/Df9TyGbV8 JNCIGU5mIXg4yr+NawSz0we1 X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="142189264" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:50:22 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:50:22 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:50:08 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 01/23] MAINTAINERS: add microchip csi2dc Date: Mon, 13 Dec 2021 15:49:18 +0200 Message-ID: <20211213134940.324266-2-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add Microchip CSI2DC driver in the list. Signed-off-by: Eugen Hristev Reviewed-by: Laurent Pinchart --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b2239eaff8d3..afb74460e5c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12468,6 +12468,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported F: sound/soc/atmel +MICROCHIP CSI2DC DRIVER +M: Eugen Hristev +L: linux-media@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/media/microchip,csi2dc.yaml +F: drivers/media/platform/atmel/microchip-csi2dc.c + MICROCHIP ECC DRIVER M: Tudor Ambarus L: linux-crypto@vger.kernel.org From patchwork Mon Dec 13 13:49:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80E5DC433F5 for ; Mon, 13 Dec 2021 13:51:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238071AbhLMNu7 (ORCPT ); Mon, 13 Dec 2021 08:50:59 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:48941 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238037AbhLMNu5 (ORCPT ); Mon, 13 Dec 2021 08:50:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403456; x=1670939456; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RBuS5ICluE2wg3Px9FOvNKtASYCxX8jaUL8gGrYNq6k=; b=IfoWGu27KUcFhJpmlh96HrsIhkRgHJq3wNACuksRU9YiPx+eFNF3VMXe uAUKUWWFyMXH4dDpcQkRsVjndCX2X/d9wXqqJWZj/2dogvYmJkSVrmmNu XU3sbuBKyih2Oemcn5QKXAXyDwgsTG27rU6aZ9wcs96s7efQ5FYE3hqqm gnbj7g5+sg1YocNU8f7UhWKL2+oawLc1cg4cg5UEHmV3kcNvKiX0luw2r nEeUpetwcKnavW1BRE89XKPmtecGnpCPV9ccH2UOkSiArl+3WyYOeqIAb afJA1ziMX6VkdZd0Uqq5AqgKzETTbArTSpXZ3J4YEULBO0tBTONZkcga9 g==; IronPort-SDR: kbSGUECBhMeq5gHzUHKl4/Z0NGculQS/bqv5t53c7XC2eQHBFv3WOI+6clyDWeOUTDnRSPD69U zEoYBGUKaooaLPw9JV8BE6dfkSspme/u8uj85dNg9M7vVaja0wxNFsJGbeFM+LpBKdQI32YiyV R5t+DSEOauudpgA4oGQZimCVMedez9YZgxESCMSo56T1NE0fMxnjXK+raVN66ZvLj5XPhnkzRb vEaiAODWHtGlUR8eHfRBPIHl1ieJ3e/NRVqgz5AitI0yCXvRtLfEifEdZ9pijReMI4BVCD5046 jUh/R0dSZJZoDK3LT4jLn1OR X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="79361441" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:50:56 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:50:55 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:50:47 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 03/23] media: atmel: introduce microchip csi2dc driver Date: Mon, 13 Dec 2021 15:49:20 +0200 Message-ID: <20211213134940.324266-4-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Microchip CSI2DC (CSI2 Demultiplexer Controller) is a misc bridge device that converts a byte stream in IDI Synopsys format (coming from a CSI2HOST) to a pixel stream that can be captured by a sensor controller. Signed-off-by: Eugen Hristev Reviewed-by: Jacopo Mondi --- Changes in v3: - on set format, disable setting the source sink. - removed useless request to pm_request_idle - fixed YUV DT - added last frame debug info - removed writing read only VPCOL and VPROW registers - minor cosmetic changes Changes in v2: - implement try formats - added parallel mode - moved to fwlink endpoints - many other minor corrections from Jacopo's review Changes in this revision: - addressed comments by Jacopo and Laurent as in this thread: https://www.spinics.net/lists/linux-media/msg181044.html Previous change log : Changes in v5: - only in bindings Changes in v4: - now using get_mbus_config ops to get data from the subdevice, like the virtual channel id, and the clock type. - now having possibility to select any of the RAW10 data modes - at completion time, select which formats are also available in the subdevice, and move to the dynamic list accordingly - changed the pipeline integration, do not advertise subdev ready at probe time. wait until completion is done, and then start a workqueue that will register this device as a subdevice for the next element in pipeline. - moved the s_power code into a different function called now csi2dc_power that is called with CONFIG_PM functions. This is also called at completion, to have the device ready in case CONFIG_PM is not selected on the platform. - merged try_fmt into set_fmt - driver cleanup, wrapped lines over 80 characters Changes in v2: - moved driver to platform/atmel - fixed minor things as per Sakari's review - still some things from v2 review are not yet addressed, to be followed up drivers/media/platform/Makefile | 1 + drivers/media/platform/atmel/Kconfig | 15 + drivers/media/platform/atmel/Makefile | 1 + .../media/platform/atmel/microchip-csi2dc.c | 806 ++++++++++++++++++ 4 files changed, 823 insertions(+) create mode 100644 drivers/media/platform/atmel/microchip-csi2dc.c diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 832357240e89..b18e5f704145 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/ obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel/ +obj-$(CONFIG_VIDEO_MICROCHIP_CSI2DC) += atmel/ obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/ diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig index dda2f27da317..f83bee373d82 100644 --- a/drivers/media/platform/atmel/Kconfig +++ b/drivers/media/platform/atmel/Kconfig @@ -40,3 +40,18 @@ config VIDEO_ATMEL_ISI help This module makes the ATMEL Image Sensor Interface available as a v4l2 device. + +config VIDEO_MICROCHIP_CSI2DC + tristate "Microchip CSI2 Demux Controller" + depends on VIDEO_V4L2 && COMMON_CLK && OF + depends on ARCH_AT91 || COMPILE_TEST + select MEDIA_CONTROLLER + select VIDEO_V4L2_SUBDEV_API + select V4L2_FWNODE + help + CSI2 Demux Controller driver. CSI2DC is a helper chip + that converts IDI interface byte stream to a parallel pixel stream. + It supports various RAW formats as input. + + To compile this driver as a module, choose M here: the + module will be called microchip-csi2dc. diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile index 46d264ab7948..39f0a7eba702 100644 --- a/drivers/media/platform/atmel/Makefile +++ b/drivers/media/platform/atmel/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-base.o obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o +obj-$(CONFIG_VIDEO_MICROCHIP_CSI2DC) += microchip-csi2dc.o diff --git a/drivers/media/platform/atmel/microchip-csi2dc.c b/drivers/media/platform/atmel/microchip-csi2dc.c new file mode 100644 index 000000000000..6bc549c28e05 --- /dev/null +++ b/drivers/media/platform/atmel/microchip-csi2dc.c @@ -0,0 +1,806 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Microchip CSI2 Demux Controller (CSI2DC) driver + * + * Copyright (C) 2018 Microchip Technology, Inc. + * + * Author: Eugen Hristev + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Global configuration register */ +#define CSI2DC_GCFG 0x0 + +/* MIPI sensor pixel clock is free running */ +#define CSI2DC_GCFG_MIPIFRN BIT(0) +/* GPIO parallel interface selection */ +#define CSI2DC_GCFG_GPIOSEL BIT(1) +/* Output waveform inter-line minimum delay */ +#define CSI2DC_GCFG_HLC(v) ((v) << 4) +#define CSI2DC_GCFG_HLC_MASK GENMASK(7, 4) +/* SAMA7G5 requires a HLC delay of 15 */ +#define SAMA7G5_HLC (15) + +/* Global control register */ +#define CSI2DC_GCTLR 0x04 +#define CSI2DC_GCTLR_SWRST BIT(0) + +/* Global status register */ +#define CSI2DC_GS 0x08 + +/* SSP interrupt status register */ +#define CSI2DC_SSPIS 0x28 +/* Pipe update register */ +#define CSI2DC_PU 0xc0 +/* Video pipe attributes update */ +#define CSI2DC_PU_VP BIT(0) + +/* Pipe update status register */ +#define CSI2DC_PUS 0xc4 + +/* Video pipeline Interrupt Status Register */ +#define CSI2DC_VPISR 0xf4 + +/* Video pipeline enable register */ +#define CSI2DC_VPE 0xf8 +#define CSI2DC_VPE_ENABLE BIT(0) + +/* Video pipeline configuration register */ +#define CSI2DC_VPCFG 0xfc +/* Data type */ +#define CSI2DC_VPCFG_DT(v) ((v) << 0) +#define CSI2DC_VPCFG_DT_MASK GENMASK(5, 0) +/* Virtual channel identifier */ +#define CSI2DC_VPCFG_VC(v) ((v) << 6) +#define CSI2DC_VPCFG_VC_MASK GENMASK(7, 6) +/* Decompression enable */ +#define CSI2DC_VPCFG_DE BIT(8) +/* Decoder mode */ +#define CSI2DC_VPCFG_DM(v) ((v) << 9) +#define CSI2DC_VPCFG_DM_DECODER8TO12 0 +/* Decoder predictor 2 selection */ +#define CSI2DC_VPCFG_DP2 BIT(12) +/* Recommended memory storage */ +#define CSI2DC_VPCFG_RMS BIT(13) +/* Post adjustment */ +#define CSI2DC_VPCFG_PA BIT(14) + +/* Video pipeline column register */ +#define CSI2DC_VPCOL 0x100 +/* Column number */ +#define CSI2DC_VPCOL_COL(v) ((v) << 0) +#define CSI2DC_VPCOL_COL_MASK GENMASK(15, 0) + +/* Video pipeline row register */ +#define CSI2DC_VPROW 0x104 +/* Row number */ +#define CSI2DC_VPROW_ROW(v) ((v) << 0) +#define CSI2DC_VPROW_ROW_MASK GENMASK(15, 0) + +/* Version register */ +#define CSI2DC_VERSION 0x1fc + +/* register read/write helpers */ +#define csi2dc_readl(st, reg) readl_relaxed((st)->base + (reg)) +#define csi2dc_writel(st, reg, val) writel_relaxed((val), \ + (st)->base + (reg)) + +/* supported RAW data types */ +#define CSI2DC_DT_RAW6 0x28 +#define CSI2DC_DT_RAW7 0x29 +#define CSI2DC_DT_RAW8 0x2a +#define CSI2DC_DT_RAW10 0x2b +#define CSI2DC_DT_RAW12 0x2c +#define CSI2DC_DT_RAW14 0x2d +/* YUV data types */ +#define CSI2DC_DT_YUV422_8B 0x1e + +/* + * struct csi2dc_format - CSI2DC format type struct + * @mbus_code: Media bus code for the format + * @dt: Data type constant for this format + */ +struct csi2dc_format { + u32 mbus_code; + u32 dt; +}; + +static const struct csi2dc_format csi2dc_formats[] = { + { + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, + .dt = CSI2DC_DT_RAW8, + }, { + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, + .dt = CSI2DC_DT_RAW8, + }, { + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, + .dt = CSI2DC_DT_RAW8, + }, { + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, + .dt = CSI2DC_DT_RAW8, + }, { + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, + .dt = CSI2DC_DT_RAW10, + }, { + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, + .dt = CSI2DC_DT_RAW10, + }, { + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, + .dt = CSI2DC_DT_RAW10, + }, { + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, + .dt = CSI2DC_DT_RAW10, + }, { + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, + .dt = CSI2DC_DT_YUV422_8B, + }, +}; + +enum mipi_csi_pads { + CSI2DC_PAD_SINK = 0, + CSI2DC_PAD_SOURCE = 1, + CSI2DC_PADS_NUM = 2, +}; + +/* + * struct csi2dc_device - CSI2DC device driver data/config struct + * @base: Register map base address + * @csi2dc_sd: v4l2 subdevice for the csi2dc device + * This is the subdevice that the csi2dc device itself + * registers in v4l2 subsystem + * @dev: struct device for this csi2dc device + * @pclk: Peripheral clock reference + * Input clock that clocks the hardware block internal + * logic + * @scck: Sensor Controller clock reference + * Input clock that is used to generate the pixel clock + * @format: Current saved format used in g/s fmt + * @cur_fmt: Current state format + * @try_fmt: Try format that is being tried + * @pads: Media entity pads for the csi2dc subdevice + * @clk_gated: Whether the clock is gated or free running + * @video_pipe: Whether video pipeline is configured + * @parallel_mode: The underlying subdevice is connected on a parallel bus + * @vc: Current set virtual channel + * @notifier: Async notifier that is used to bound the underlying + * subdevice to the csi2dc subdevice + * @input_sd: Reference to the underlying subdevice bound to the + * csi2dc subdevice + * @remote_pad: Pad number of the underlying subdevice that is linked + * to the csi2dc subdevice sink pad. + */ +struct csi2dc_device { + void __iomem *base; + struct v4l2_subdev csi2dc_sd; + struct device *dev; + struct clk *pclk; + struct clk *scck; + + struct v4l2_mbus_framefmt format; + + const struct csi2dc_format *cur_fmt; + const struct csi2dc_format *try_fmt; + + struct media_pad pads[CSI2DC_PADS_NUM]; + + bool clk_gated; + bool video_pipe; + bool parallel_mode; + u32 vc; + + struct v4l2_async_notifier notifier; + + struct v4l2_subdev *input_sd; + + u32 remote_pad; +}; + +static inline struct csi2dc_device * +csi2dc_sd_to_csi2dc_device(struct v4l2_subdev *csi2dc_sd) +{ + return container_of(csi2dc_sd, struct csi2dc_device, csi2dc_sd); +} + +static int csi2dc_enum_mbus_code(struct v4l2_subdev *csi2dc_sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index >= ARRAY_SIZE(csi2dc_formats)) + return -EINVAL; + + code->code = csi2dc_formats[code->index].mbus_code; + + return 0; +} + +static int csi2dc_get_fmt(struct v4l2_subdev *csi2dc_sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *format) +{ + struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); + struct v4l2_mbus_framefmt *v4l2_try_fmt; + + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd, sd_state, + format->pad); + format->format = *v4l2_try_fmt; + + return 0; + } + + format->format = csi2dc->format; + + return 0; +} + +static int csi2dc_set_fmt(struct v4l2_subdev *csi2dc_sd, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *req_fmt) +{ + struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); + const struct csi2dc_format *fmt, *try_fmt = NULL; + struct v4l2_mbus_framefmt *v4l2_try_fmt; + unsigned int i; + + /* + * Setting the source pad is disabled. + * The same format is being propagated from the sink to source. + */ + if (req_fmt->pad == CSI2DC_PAD_SOURCE) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(csi2dc_formats); i++) { + fmt = &csi2dc_formats[i]; + if (req_fmt->format.code == fmt->mbus_code) + try_fmt = fmt; + fmt++; + } + + /* in case we could not find the desired format, default to something */ + if (!try_fmt) { + try_fmt = &csi2dc_formats[0]; + + dev_dbg(csi2dc->dev, + "CSI2DC unsupported format 0x%x, defaulting to 0x%x\n", + req_fmt->format.code, csi2dc_formats[0].mbus_code); + } + + req_fmt->format.code = try_fmt->mbus_code; + req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB; + req_fmt->format.field = V4L2_FIELD_NONE; + + if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd, sd_state, + req_fmt->pad); + *v4l2_try_fmt = req_fmt->format; + /* Trying on the sink pad makes the source pad change too */ + v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd, + sd_state, + CSI2DC_PAD_SOURCE); + *v4l2_try_fmt = req_fmt->format; + + /* if we are just trying, we are done */ + return 0; + } + + /* save the format for later requests */ + csi2dc->format = req_fmt->format; + + /* update config */ + csi2dc->cur_fmt = try_fmt; + + dev_dbg(csi2dc->dev, "new format set: 0x%x @%dx%d\n", + csi2dc->format.code, csi2dc->format.width, + csi2dc->format.height); + + return 0; +} + +static int csi2dc_power(struct csi2dc_device *csi2dc, int on) +{ + int ret = 0; + + if (on) { + ret = clk_prepare_enable(csi2dc->pclk); + if (ret) { + dev_err(csi2dc->dev, "failed to enable pclk:%d\n", ret); + return ret; + } + + ret = clk_prepare_enable(csi2dc->scck); + if (ret) { + dev_err(csi2dc->dev, "failed to enable scck:%d\n", ret); + clk_disable_unprepare(csi2dc->pclk); + return ret; + } + + /* if powering up, deassert reset line */ + csi2dc_writel(csi2dc, CSI2DC_GCTLR, CSI2DC_GCTLR_SWRST); + } else { + /* if powering down, assert reset line */ + csi2dc_writel(csi2dc, CSI2DC_GCTLR, 0); + + clk_disable_unprepare(csi2dc->scck); + clk_disable_unprepare(csi2dc->pclk); + } + + return ret; +} + +static int csi2dc_get_mbus_config(struct csi2dc_device *csi2dc) +{ + struct v4l2_mbus_config mbus_config = { 0 }; + int ret; + + ret = v4l2_subdev_call(csi2dc->input_sd, pad, get_mbus_config, + csi2dc->remote_pad, &mbus_config); + if (ret == -ENOIOCTLCMD) { + dev_dbg(csi2dc->dev, + "no remote mbus configuration available\n"); + goto csi2dc_get_mbus_config_defaults; + } + + if (ret) { + dev_err(csi2dc->dev, + "failed to get remote mbus configuration\n"); + goto csi2dc_get_mbus_config_defaults; + } + + if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_0) + csi2dc->vc = 0; + else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_1) + csi2dc->vc = 1; + else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_2) + csi2dc->vc = 2; + else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_3) + csi2dc->vc = 3; + + dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc); + + csi2dc->clk_gated = mbus_config.flags & + V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK; + + dev_dbg(csi2dc->dev, "mbus_config: %s clock\n", + csi2dc->clk_gated ? "gated" : "free running"); + + return 0; + +csi2dc_get_mbus_config_defaults: + csi2dc->vc = 0; /* Virtual ID 0 by default */ + + return 0; +} + +static void csi2dc_vp_update(struct csi2dc_device *csi2dc) +{ + u32 vp, gcfg; + + if (!csi2dc->video_pipe) { + dev_err(csi2dc->dev, "video pipeline unavailable\n"); + return; + } + + if (csi2dc->parallel_mode) { + /* In parallel mode, GPIO parallel interface must be selected */ + gcfg = csi2dc_readl(csi2dc, CSI2DC_GCFG); + gcfg |= CSI2DC_GCFG_GPIOSEL; + csi2dc_writel(csi2dc, CSI2DC_GCFG, gcfg); + return; + } + + /* serial video pipeline */ + + csi2dc_writel(csi2dc, CSI2DC_GCFG, + (SAMA7G5_HLC & CSI2DC_GCFG_HLC_MASK) | + (csi2dc->clk_gated ? 0 : CSI2DC_GCFG_MIPIFRN)); + + vp = CSI2DC_VPCFG_DT(csi2dc->cur_fmt->dt) & CSI2DC_VPCFG_DT_MASK; + vp |= CSI2DC_VPCFG_VC(csi2dc->vc) & CSI2DC_VPCFG_VC_MASK; + vp &= ~CSI2DC_VPCFG_DE; + vp |= CSI2DC_VPCFG_DM(CSI2DC_VPCFG_DM_DECODER8TO12); + vp &= ~CSI2DC_VPCFG_DP2; + vp &= ~CSI2DC_VPCFG_RMS; + vp |= CSI2DC_VPCFG_PA; + + csi2dc_writel(csi2dc, CSI2DC_VPCFG, vp); + csi2dc_writel(csi2dc, CSI2DC_VPE, CSI2DC_VPE_ENABLE); + csi2dc_writel(csi2dc, CSI2DC_PU, CSI2DC_PU_VP); +} + +static int csi2dc_s_stream(struct v4l2_subdev *csi2dc_sd, int enable) +{ + struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); + int ret; + + if (enable) { + ret = pm_runtime_resume_and_get(csi2dc->dev); + if (ret < 0) + return ret; + + csi2dc_get_mbus_config(csi2dc); + + csi2dc_vp_update(csi2dc); + + return v4l2_subdev_call(csi2dc->input_sd, video, s_stream, + true); + } + + dev_dbg(csi2dc->dev, + "Last frame received: VPCOLR = %u, VPROWR= %u, VPISR = %x\n", + csi2dc_readl(csi2dc, CSI2DC_VPCOL), + csi2dc_readl(csi2dc, CSI2DC_VPROW), + csi2dc_readl(csi2dc, CSI2DC_VPISR)); + + /* stop streaming scenario */ + ret = v4l2_subdev_call(csi2dc->input_sd, video, s_stream, false); + + pm_runtime_put_sync(csi2dc->dev); + + return ret; +} + +static int csi2dc_init_cfg(struct v4l2_subdev *csi2dc_sd, + struct v4l2_subdev_state *sd_state) +{ + struct v4l2_mbus_framefmt *v4l2_try_fmt = + v4l2_subdev_get_try_format(csi2dc_sd, sd_state, 0); + + v4l2_try_fmt->height = 480; + v4l2_try_fmt->width = 640; + v4l2_try_fmt->code = csi2dc_formats[0].mbus_code; + v4l2_try_fmt->colorspace = V4L2_COLORSPACE_SRGB; + v4l2_try_fmt->field = V4L2_FIELD_NONE; + v4l2_try_fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + v4l2_try_fmt->quantization = V4L2_QUANTIZATION_DEFAULT; + v4l2_try_fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + return 0; +} + +static const struct v4l2_subdev_pad_ops csi2dc_pad_ops = { + .enum_mbus_code = csi2dc_enum_mbus_code, + .set_fmt = csi2dc_set_fmt, + .get_fmt = csi2dc_get_fmt, + .init_cfg = csi2dc_init_cfg, +}; + +static const struct v4l2_subdev_video_ops csi2dc_video_ops = { + .s_stream = csi2dc_s_stream, +}; + +static const struct v4l2_subdev_ops csi2dc_subdev_ops = { + .pad = &csi2dc_pad_ops, + .video = &csi2dc_video_ops, +}; + +static int csi2dc_async_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct csi2dc_device *csi2dc = container_of(notifier, + struct csi2dc_device, notifier); + int pad; + int ret; + + csi2dc->input_sd = subdev; + + pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode, + MEDIA_PAD_FL_SOURCE); + if (pad < 0) { + dev_err(csi2dc->dev, "Failed to find pad for %s\n", + subdev->name); + return pad; + } + + csi2dc->remote_pad = pad; + + ret = media_create_pad_link(&csi2dc->input_sd->entity, + csi2dc->remote_pad, + &csi2dc->csi2dc_sd.entity, 0, + MEDIA_LNK_FL_ENABLED); + if (ret) { + dev_err(csi2dc->dev, + "Failed to create pad link: %s to %s\n", + csi2dc->input_sd->entity.name, + csi2dc->csi2dc_sd.entity.name); + return ret; + } + + dev_dbg(csi2dc->dev, "link with %s pad: %d\n", + csi2dc->input_sd->name, csi2dc->remote_pad); + + return ret; +} + +static const struct v4l2_async_notifier_operations csi2dc_async_ops = { + .bound = csi2dc_async_bound, +}; + +static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc, + struct fwnode_handle *input_fwnode) +{ + struct v4l2_async_subdev *asd; + int ret = 0; + + v4l2_async_nf_init(&csi2dc->notifier); + + asd = v4l2_async_nf_add_fwnode_remote(&csi2dc->notifier, + input_fwnode, + struct v4l2_async_subdev); + + fwnode_handle_put(input_fwnode); + + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); + dev_err(csi2dc->dev, + "failed to add async notifier for node %pOF: %d\n", + to_of_node(input_fwnode), ret); + v4l2_async_nf_cleanup(&csi2dc->notifier); + return ret; + } + + csi2dc->notifier.ops = &csi2dc_async_ops; + + ret = v4l2_async_subdev_nf_register(&csi2dc->csi2dc_sd, + &csi2dc->notifier); + if (ret) { + dev_err(csi2dc->dev, "fail to register async notifier: %d\n", + ret); + v4l2_async_nf_cleanup(&csi2dc->notifier); + } + + return ret; +} + +static int csi2dc_of_parse(struct csi2dc_device *csi2dc, + struct device_node *of_node) +{ + struct fwnode_handle *input_fwnode, *output_fwnode; + struct v4l2_fwnode_endpoint input_endpoint = { 0 }, + output_endpoint = { 0 }; + int ret; + + input_fwnode = fwnode_graph_get_next_endpoint(of_fwnode_handle(of_node), + NULL); + if (!input_fwnode) { + dev_err(csi2dc->dev, + "missing port node at %pOF, input node is mandatory.\n", + of_node); + return -EINVAL; + } + + ret = v4l2_fwnode_endpoint_parse(input_fwnode, &input_endpoint); + if (ret) { + dev_err(csi2dc->dev, "endpoint not defined at %pOF\n", of_node); + goto csi2dc_of_parse_err; + } + + if (input_endpoint.bus_type == V4L2_MBUS_PARALLEL || + input_endpoint.bus_type == V4L2_MBUS_BT656) { + csi2dc->parallel_mode = true; + dev_dbg(csi2dc->dev, + "subdevice connected on parallel interface\n"); + } + + if (input_endpoint.bus_type == V4L2_MBUS_CSI2_DPHY) { + csi2dc->clk_gated = input_endpoint.bus.mipi_csi2.flags & + V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK; + dev_dbg(csi2dc->dev, + "subdevice connected on serial interface\n"); + dev_dbg(csi2dc->dev, "DT: %s clock\n", + csi2dc->clk_gated ? "gated" : "free running"); + } + + output_fwnode = fwnode_graph_get_next_endpoint + (of_fwnode_handle(of_node), input_fwnode); + + if (output_fwnode) + ret = v4l2_fwnode_endpoint_parse(output_fwnode, + &output_endpoint); + + fwnode_handle_put(output_fwnode); + + if (!output_fwnode || ret) { + dev_info(csi2dc->dev, + "missing output node at %pOF, data pipe available only.\n", + of_node); + } else { + if (output_endpoint.bus_type != V4L2_MBUS_PARALLEL && + output_endpoint.bus_type != V4L2_MBUS_BT656) { + dev_err(csi2dc->dev, + "output port must be parallel/bt656.\n"); + ret = -EINVAL; + goto csi2dc_of_parse_err; + } + + csi2dc->video_pipe = true; + + dev_dbg(csi2dc->dev, + "block %pOF [%d.%d]->[%d.%d] video pipeline\n", + of_node, input_endpoint.base.port, + input_endpoint.base.id, output_endpoint.base.port, + output_endpoint.base.id); + } + + /* prepare async notifier for subdevice completion */ + return csi2dc_prepare_notifier(csi2dc, input_fwnode); + +csi2dc_of_parse_err: + fwnode_handle_put(input_fwnode); + return ret; +} + +static void csi2dc_default_format(struct csi2dc_device *csi2dc) +{ + csi2dc->cur_fmt = &csi2dc_formats[0]; + + csi2dc->format.height = 480; + csi2dc->format.width = 640; + csi2dc->format.code = csi2dc_formats[0].mbus_code; + csi2dc->format.colorspace = V4L2_COLORSPACE_SRGB; + csi2dc->format.field = V4L2_FIELD_NONE; + csi2dc->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + csi2dc->format.quantization = V4L2_QUANTIZATION_DEFAULT; + csi2dc->format.xfer_func = V4L2_XFER_FUNC_DEFAULT; +} + +static int csi2dc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct csi2dc_device *csi2dc; + int ret = 0; + u32 ver; + + csi2dc = devm_kzalloc(dev, sizeof(*csi2dc), GFP_KERNEL); + if (!csi2dc) + return -ENOMEM; + + csi2dc->dev = dev; + + csi2dc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(csi2dc->base)) { + dev_err(dev, "base address not set\n"); + return PTR_ERR(csi2dc->base); + } + + csi2dc->pclk = devm_clk_get(dev, "pclk"); + if (IS_ERR(csi2dc->pclk)) { + ret = PTR_ERR(csi2dc->pclk); + dev_err(dev, "failed to get pclk: %d\n", ret); + return ret; + } + + csi2dc->scck = devm_clk_get(dev, "scck"); + if (IS_ERR(csi2dc->scck)) { + ret = PTR_ERR(csi2dc->scck); + dev_err(dev, "failed to get scck: %d\n", ret); + return ret; + } + + v4l2_subdev_init(&csi2dc->csi2dc_sd, &csi2dc_subdev_ops); + + csi2dc->csi2dc_sd.owner = THIS_MODULE; + csi2dc->csi2dc_sd.dev = dev; + snprintf(csi2dc->csi2dc_sd.name, sizeof(csi2dc->csi2dc_sd.name), + "csi2dc"); + + csi2dc->csi2dc_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + csi2dc->csi2dc_sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + + platform_set_drvdata(pdev, csi2dc); + + ret = csi2dc_of_parse(csi2dc, dev->of_node); + if (ret) + goto csi2dc_probe_cleanup_entity; + + csi2dc->pads[CSI2DC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; + if (csi2dc->video_pipe) + csi2dc->pads[CSI2DC_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + + ret = media_entity_pads_init(&csi2dc->csi2dc_sd.entity, + csi2dc->video_pipe ? CSI2DC_PADS_NUM : 1, + csi2dc->pads); + if (ret < 0) { + dev_err(dev, "media entity init failed\n"); + goto csi2dc_probe_cleanup_notifier; + } + + csi2dc_default_format(csi2dc); + + /* turn power on to validate capabilities */ + ret = csi2dc_power(csi2dc, true); + if (ret < 0) + goto csi2dc_probe_cleanup_notifier; + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + ver = csi2dc_readl(csi2dc, CSI2DC_VERSION); + + /* + * we must register the subdev after PM runtime has been requested, + * otherwise we might bound immediately and request pm_runtime_resume + * before runtime_enable. + */ + ret = v4l2_async_register_subdev(&csi2dc->csi2dc_sd); + if (ret) { + dev_err(csi2dc->dev, "failed to register the subdevice\n"); + goto csi2dc_probe_cleanup_notifier; + } + + dev_info(dev, "Microchip CSI2DC version %x\n", ver); + + return 0; + +csi2dc_probe_cleanup_notifier: + v4l2_async_nf_cleanup(&csi2dc->notifier); +csi2dc_probe_cleanup_entity: + media_entity_cleanup(&csi2dc->csi2dc_sd.entity); + + return ret; +} + +static int csi2dc_remove(struct platform_device *pdev) +{ + struct csi2dc_device *csi2dc = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + + v4l2_async_unregister_subdev(&csi2dc->csi2dc_sd); + v4l2_async_nf_unregister(&csi2dc->notifier); + v4l2_async_nf_cleanup(&csi2dc->notifier); + media_entity_cleanup(&csi2dc->csi2dc_sd.entity); + + return 0; +} + +static int __maybe_unused csi2dc_runtime_suspend(struct device *dev) +{ + struct csi2dc_device *csi2dc = dev_get_drvdata(dev); + + return csi2dc_power(csi2dc, false); +} + +static int __maybe_unused csi2dc_runtime_resume(struct device *dev) +{ + struct csi2dc_device *csi2dc = dev_get_drvdata(dev); + + return csi2dc_power(csi2dc, true); +} + +static const struct dev_pm_ops csi2dc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(csi2dc_runtime_suspend, csi2dc_runtime_resume, NULL) +}; + +static const struct of_device_id csi2dc_of_match[] = { + { .compatible = "microchip,sama7g5-csi2dc" }, + { } +}; + +MODULE_DEVICE_TABLE(of, csi2dc_of_match); + +static struct platform_driver csi2dc_driver = { + .probe = csi2dc_probe, + .remove = csi2dc_remove, + .driver = { + .name = "microchip-csi2dc", + .pm = &csi2dc_dev_pm_ops, + .of_match_table = of_match_ptr(csi2dc_of_match), + }, +}; + +module_platform_driver(csi2dc_driver); + +MODULE_AUTHOR("Eugen Hristev "); +MODULE_DESCRIPTION("Microchip CSI2 Demux Controller driver"); +MODULE_LICENSE("GPL v2"); From patchwork Mon Dec 13 13:49:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523572 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D3B0C433FE for ; Mon, 13 Dec 2021 13:51:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238085AbhLMNva (ORCPT ); Mon, 13 Dec 2021 08:51:30 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:24201 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238037AbhLMNv3 (ORCPT ); Mon, 13 Dec 2021 08:51:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403488; x=1670939488; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=szwLENg9eGEahRxwM5kjaS6EGD+dZeAptjmdZDyt9iY=; b=0yJCwE68emFNycGYeNd54h08wZkNkoWQyadDCVvIyRwI5VnugAdhpJ0Z s4dlX9y42EICaw20QC2oz8KNaoFMm5tbRoZyZ66lumbkPdL+GPe8/q+3T iQnJWbR5I2iSQ5Q9sqZd2uje4wz4hvRnai+8dKngHNSoj5BGZxyNhwZMo 6yCQn2rmtt0X/P0YLI+BIK7O/CsLcfDNpm/Qx9Hb8FIOr5qHphCYjTQUW cat/1L5NkwAPOwAKIKh+q1XTqL30v5SvJzd+05E87TUVA1V27HGU0B30I LQe8q2BJ34q6NytdJVz0repm7i2WPfBX+Ds56amTz/1LvKf5fP9pSRHR3 g==; IronPort-SDR: GopgcEjMzEa1jtvLssKvZPVdi/vFXx3ksSLVaEOOcxI5kMIjDWPA02qZLfdIZF9bz5NruKjj9j wvscf2P5ujIuIqgaigXwgiPtGx7ibKqUHP1cBXQKCRaIrcccUuwGKzJZeLeF/TJ5HX8RfIXknN qPGLi4B/hwed8TpWt3skkUnpn/xm2oamru3OshM6PZ8faTaeQO8oi9+ljbLT+NDGuoiGrdF6hU kGj1/je2PvOdIks7hJYauT7/sDKrQnBqGEsXNcQRrSFUJTvbFkmnhVIxfXH2wQfsAIOy/qpSud ucJAvf76Iq4u2gLy5texaagm X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="139571448" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:51:23 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:51:22 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:51:11 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 05/23] media: atmel: atmel-isc: replace video device name with module name Date: Mon, 13 Dec 2021 15:49:22 +0200 Message-ID: <20211213134940.324266-6-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org To have consistency with future media controller development, replace the video device name with KBUILD_MODNAME. Signed-off-by: Eugen Hristev --- drivers/media/platform/atmel/atmel-isc-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 58f468d32613..26a6090f056c 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1886,7 +1886,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) } /* Register video device */ - strscpy(vdev->name, "microchip-isc", sizeof(vdev->name)); + strscpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); vdev->release = video_device_release_empty; vdev->fops = &isc_fops; vdev->ioctl_ops = &isc_ioctl_ops; From patchwork Mon Dec 13 13:49:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF6C3C433F5 for ; Mon, 13 Dec 2021 13:51:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238173AbhLMNvp (ORCPT ); Mon, 13 Dec 2021 08:51:45 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:49039 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233698AbhLMNvo (ORCPT ); Mon, 13 Dec 2021 08:51:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403504; x=1670939504; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=c7zR7YV+/NaEAUBvJ084GX1l4HCMOCQS7YcMiVzt3gE=; b=R1GLg4Am3nZI7D3ugqjezRRcwFcdHclCLiUB5L3Ux/OCMx9KU70b+b9+ pESAO99xJ2VtDla92D7xpj11NdDtn84nEfsjIFbXKjpY2Z2h6/aL5OcJm LD6ldzSAkjRKwI5OQUrbe0HL0TMQ3jagqCifguuFq++9IKi8en7XvBRrO Kp2KfOvP6B3tIcEIxMY7F2WcmmFMgGmEChXSzg/s9XGr6YfcMT07g2U57 bD6JggaipOYlxj8ZAcm7BjlCguitulm8VkRbZs+DE5F7OcK4QpFqCGUdL AlwiRafbtZPuvJqXgL4kADnSfrymg+qpbV9KCLefYjLRI0JOmK/htSHIJ A==; IronPort-SDR: y9aGpxpaDDb9680ihLzHFrF7XWaqk8xmeaTztOF144hdzbmAuoPqba6C3pUHD4BiXa4qhpUs4a OPJ2Kzrx1HC0cQJxUoTRfFD9e4ikLMBfNaamNSmq6ErfJPz1F7oS6+xhEoMECBGjonlIZQk3t0 6Gni4F5vrRUwgkxQIXM/13MDr64gQmsHF/33NVjaurIz9PQfXIVk6YkBgsO11S90PkELUS25UY XowK2fv9oEEhD8eVKpj+RoRAY7m4NHVD9yv5SDNHZvnpX9IZNoK1mIhMztaksxWqOsuqZoqPXK t6bn0vnZ3t5RV6Nn+6TbM6mq X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="79361613" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:51:43 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:51:43 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:51:30 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 07/23] media: atmel: atmel-isc-base: use streaming status when queueing buffers Date: Mon, 13 Dec 2021 15:49:24 +0200 Message-ID: <20211213134940.324266-8-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org During experiments with libcamera, it looks like vb2_is_streaming returns true before our start streaming is called. Order of operations is streamon -> queue -> start_streaming ISC would have started the DMA immediately when a buffer is being added to the vbqueue if the queue is streaming. It is more safe to start the DMA after the start streaming of the driver is called. Thus, even if vb2queue is streaming, add the buffer to the dma queue of the driver instead of actually starting the DMA process, if the start streaming has not been called yet. Signed-off-by: Eugen Hristev --- drivers/media/platform/atmel/atmel-isc-base.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 26a6090f056c..e6c9071c04f0 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -441,12 +441,14 @@ static void isc_buffer_queue(struct vb2_buffer *vb) unsigned long flags; spin_lock_irqsave(&isc->dma_queue_lock, flags); - if (!isc->cur_frm && list_empty(&isc->dma_queue) && - vb2_is_streaming(vb->vb2_queue)) { + + if (!isc->cur_frm && list_empty(&isc->dma_queue) && !isc->stop) { isc->cur_frm = buf; isc_start_dma(isc); - } else + } else { list_add_tail(&buf->list, &isc->dma_queue); + } + spin_unlock_irqrestore(&isc->dma_queue_lock, flags); } @@ -1014,7 +1016,7 @@ static int isc_s_fmt_vid_cap(struct file *file, void *priv, { struct isc_device *isc = video_drvdata(file); - if (vb2_is_streaming(&isc->vb2_vidq)) + if (!isc->stop) return -EBUSY; return isc_set_fmt(isc, f); @@ -1536,7 +1538,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl) isc_update_awb_ctrls(isc); - if (vb2_is_streaming(&isc->vb2_vidq)) { + if (!isc->stop) { /* * If we are streaming, we can update profile to * have the new settings in place. @@ -1552,8 +1554,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl) } /* if we have autowhitebalance on, start histogram procedure */ - if (ctrls->awb == ISC_WB_AUTO && - vb2_is_streaming(&isc->vb2_vidq) && + if (ctrls->awb == ISC_WB_AUTO && !isc->stop && ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) isc_set_histogram(isc, true); @@ -1829,6 +1830,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) struct vb2_queue *q = &isc->vb2_vidq; int ret = 0; + isc->stop = true; + INIT_WORK(&isc->awb_work, isc_awb_work); ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); From patchwork Mon Dec 13 13:49:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523570 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AE039C433F5 for ; Mon, 13 Dec 2021 13:52:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238209AbhLMNwV (ORCPT ); Mon, 13 Dec 2021 08:52:21 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:23851 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233710AbhLMNwU (ORCPT ); Mon, 13 Dec 2021 08:52:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403540; x=1670939540; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QFcZqhwV54wl82Sk8IHg25ljnl0Hvg//Cvz5aknbgrg=; b=b2G8P1WmSNBHLJrBixGfm2zMKtfS+hlh7UFMa8luI0E1FA5dXhPyGl1M bFDHu60n/Z1gJUWkQb0ypavwPaPYsg7MAhfnCSxLSHn8bSbx6qN+oIr8O rTFyGQL8Y0UHNSHuTeE9Nk/ByfNqoFXvxS0A2tG0LU9geK8VdqkyBKBOk WA1OHIO/RxzjX1zKGodatUkwpA07M3XD6Kg6/qeb5nNcSReYT1n54MrBD OvOHgPmh/O+RJaju5BXnUi8OAjmrTPWuMe6bQ0EKGHehsjzvjWOEvsIPw pongaANAC6A+NB471uBi8m4UBqWsI17X6Tsn/7awr/oPWW4LIgnZILnW/ A==; IronPort-SDR: K8zkbK7wl0bJt7lWbCrSvB0r4aFrddgOq/8/l3OXVvYVwXAz5NoBE4Qx16+HpX2xenNOg2tN6o kSHQtMUAPTtSlFp7mNCqmmnnJFU9/qdd4krhJY65yQwgvrLMxXDAZUQPcEWvVBA89UH9qSvVox 4UwZ327HxO2zYaoNLTJaYFWkITHVnG7uXxNaxU/S27Aq9U0lOWzQciKYA8TrB/G0RcuSQ+OVtd mAd2GSEwxrpkC1WEresMCyGmAOaXVJeMZ4EcgdHtEfMa3nDxxkSdSS0RZ99sXbrq/fOWuU86Lg RcaqCqmdIAJddW9z64uptgsC X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="155269892" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:52:19 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:52:19 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:52:10 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 09/23] media: atmel: atmel-isc-base: report frame sizes as full supported range Date: Mon, 13 Dec 2021 15:49:26 +0200 Message-ID: <20211213134940.324266-10-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ISC supports a full broad range of frame sizes. Until now, the subdevice was queried for possible frame sizes and these were reported to the user space. However, the ISC should not care about which frame sizes the subdev supports, as long as this frame size is supported. Thus, report a continuous range from smallest frame size up to the max resolution. Signed-off-by: Eugen Hristev Reviewed-by: Jacopo Mondi --- drivers/media/platform/atmel/atmel-isc-base.c | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 3389671fbfb9..bf638d201b29 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1076,14 +1076,12 @@ static int isc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { struct isc_device *isc = video_drvdata(file); - struct v4l2_subdev_frame_size_enum fse = { - .code = isc->config.sd_format->mbus_code, - .index = fsize->index, - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; int ret = -EINVAL; int i; + if (fsize->index) + return -EINVAL; + for (i = 0; i < isc->num_user_formats; i++) if (isc->user_formats[i]->fourcc == fsize->pixel_format) ret = 0; @@ -1095,14 +1093,14 @@ static int isc_enum_framesizes(struct file *file, void *fh, if (ret) return ret; - ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, - NULL, &fse); - if (ret) - return ret; + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; - fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; - fsize->discrete.width = fse.max_width; - fsize->discrete.height = fse.max_height; + fsize->stepwise.min_width = 16; + fsize->stepwise.max_width = isc->max_width; + fsize->stepwise.min_height = 16; + fsize->stepwise.max_height = isc->max_height; + fsize->stepwise.step_width = 1; + fsize->stepwise.step_height = 1; return 0; } From patchwork Mon Dec 13 13:49:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E2F3C433EF for ; Mon, 13 Dec 2021 13:53:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233808AbhLMNxC (ORCPT ); Mon, 13 Dec 2021 08:53:02 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:23904 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233710AbhLMNxB (ORCPT ); Mon, 13 Dec 2021 08:53:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403581; x=1670939581; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=c8q+Wras26brxM0VbhR3bV7u/0zZKlKAAorzxCJq7c0=; b=UqNgc1rnpoRLaaGHpqQFIJn70ayjokFp08vaNUudQVOQUkwWq8OmONYb U9cbBnLn8+cuYHHWTH/0P0hDcqCwK/PuIaJJs6hL0R9X/PpNX3DwfbWq3 e/NSjsf5QIO5kL/lhppU8RrCFkOC0MYMkmwPjgUTCIdKjKvSQTt47GsuS qTBy887UWf/91ZbDj5NTRvPdRwgbFzvHdQJf8E3/do0jqLq4WUXHtzbeh ML0jR8iWx3GZK0j0DAh9bqZ69qMeyyya0i/+o+EW7+dyMGdQKkg2XDMRI eFBbWT11ijPHkDKrPQl1N8584lPv3nlg8ESDEfF0Vxt+mDdDq7npxbMdN A==; IronPort-SDR: fstzPoPPRs7cFYuN2U12wVtbk8seJUW2OsRmWgzhilaJ4j8gSPrUUzZbIr01DBEckhlQdze/47 3ehtb5UmHdlchEp1omYJEP3Nxonr4CI1zCOUoXeJvwRT6fGSTiNOs3pSMDUHbeb1lUzKDab0b3 7dOvix66+4bpYBwuGAW9g9lwOXw1HKDFlbJh3q7kLp6dnAt2ixkLt2qCzEfL6tZyFMLOIcEeHT fUoe8dVlErU/z6B2bzRbar8wIh8TwLPrRH722E4U9CBYI894ZSNJX1Tm30QKvAMN3MvquMJ+uO 0RG1jce60xNQg3rLscQHMoWK X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="155269943" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:53:00 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:53:00 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:52:31 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 11/23] media: atmel: atmel-isc-base: fix bytesperline value for planar formats Date: Mon, 13 Dec 2021 15:49:28 +0200 Message-ID: <20211213134940.324266-12-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The bytesperline field of the pixfmt should be only for the first plane in case of planar formats like YUV420 or YUV422. The bytesperline is used by the driver to compute the framesize. We have to report a different bpp (bytes per pixel) to v4l2 in bytesperline than the actual bpp. For example for YUV420, the real bpp is 12, but the first plane has only 8 bpp. Thus we report a bytesperline 8*width instead of 12*width. However, for real framezise we have to compute 12*width*height. Hence added a new variable to hold this information and to correctly compute the frame size. Signed-off-by: Eugen Hristev Reviewed-by: Jacopo Mondi --- drivers/media/platform/atmel/atmel-isc-base.c | 19 +++++++++++++++++-- drivers/media/platform/atmel/atmel-isc.h | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 2cb8446ff90c..d0542b97a391 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -654,6 +654,7 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 8; + isc->try_config.bpp_v4l2 = 8; break; case V4L2_PIX_FMT_SBGGR10: case V4L2_PIX_FMT_SGBRG10: @@ -663,6 +664,7 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_SBGGR12: case V4L2_PIX_FMT_SGBRG12: @@ -672,24 +674,28 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_RGB565: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_ARGB444: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_ARGB555: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_ABGR32: case V4L2_PIX_FMT_XBGR32: @@ -697,42 +703,49 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 32; + isc->try_config.bpp_v4l2 = 32; break; case V4L2_PIX_FMT_YUV420: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; isc->try_config.bpp = 12; + isc->try_config.bpp_v4l2 = 8; /* only first plane */ break; case V4L2_PIX_FMT_YUV422P: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 8; /* only first plane */ break; case V4L2_PIX_FMT_YUYV: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_UYVY: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_VYUY: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; case V4L2_PIX_FMT_GREY: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8; isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 8; + isc->try_config.bpp_v4l2 = 8; break; case V4L2_PIX_FMT_Y16: isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH; @@ -742,6 +755,7 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; isc->try_config.bpp = 16; + isc->try_config.bpp_v4l2 = 16; break; default: return -EINVAL; @@ -990,8 +1004,9 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, pixfmt->height = isc->max_height; pixfmt->field = V4L2_FIELD_NONE; - pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; - pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; + pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3; + pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) * + pixfmt->height; if (code) *code = mbus_code; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 32448ccfc636..07fa6dbf8460 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -102,6 +102,9 @@ struct isc_format { configuration. * @fourcc: Fourcc code for this format. * @bpp: Bytes per pixel in the current format. + * @bpp_v4l2: Bytes per pixel in the current format, for v4l2. + This differs from 'bpp' in the sense that in planar + formats, it refers only to the first plane. * @rlp_cfg_mode: Configuration of the RLP (rounding, limiting packaging) * @dcfg_imode: Configuration of the input of the DMA module * @dctrl_dview: Configuration of the output of the DMA module @@ -112,6 +115,7 @@ struct fmt_config { u32 fourcc; u8 bpp; + u8 bpp_v4l2; u32 rlp_cfg_mode; u32 dcfg_imode; From patchwork Mon Dec 13 13:49:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523568 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95E08C433FE for ; Mon, 13 Dec 2021 13:53:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238261AbhLMNxX (ORCPT ); Mon, 13 Dec 2021 08:53:23 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:23940 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238264AbhLMNxU (ORCPT ); Mon, 13 Dec 2021 08:53:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403600; x=1670939600; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ir9v+M5DO0zKIELA5L6fGOqP2IexYn1myL5Ikj6pBi4=; b=DKmyB9FzJgLeSH+I6Afrlt0K6aSRvH5XHHKuZosIpz1zK9OCSd3xFBef DXQgXQzcw/BO8z27rQ4mnHu626vji0b4Yhx22ifQDw2DvMXT2HB1k2hi9 XtDuS65bEzC5qSBDwYK6pcJ2t8g0Pj1uZUT1tB9GeUxLgqKpOy76+XWrc y3+kfuuj8zpWsNUAFlXq32l/msNjT8D4fUXnE3JyNxd36Iwy2sls21Mpx hpIID61v9S7Njd1lkhktf6Ree3DVkOYD5jPcWUGldy1s2NjbRqYdCb27C fd8AsaKnYNyvLqFyzoJyIO5dRMOiwIp1jVSy//rgWiKOj0bdTJY5g9+JQ Q==; IronPort-SDR: 8XAcazy1l76yCduGnUSxLV8TGY2UGGzvEohSiR7Z3j+RsOnVZ2xibaWzHPE0dzfgWbG06qaSzx uwL3ODuDv2Z5XEcI4c82R7TKbKC5MmI8fPwSA0Irhk8+yCspMfW45I6B65ghQT+hIvncIefFaz gI/WAybtcEZHmoyyYnIDPzo/0Yr/i1LlxsRjhiws1Jl2PJ8mbbvwC3ux02fSxhR2YpALmqZxXN PzJRN5F6tA8yCc1Otj2oXbRXo2CsRKS5K5YoNu7lin5IgR/iPIPYiz7glBDr8mGzkkae4MCHcK mKKs5VeTij3zamt0pA2vniGR X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="155269974" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:53:19 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:53:19 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:53:14 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 13/23] ARM: dts: at91: sama7g5: add nodes for video capture Date: Mon, 13 Dec 2021 15:49:30 +0200 Message-ID: <20211213134940.324266-14-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add node for the XISC (eXtended Image Sensor Controller) and CSI2DC (csi2 demux controller). These nodes represent the top level of the video capture hardware pipeline and are directly connected in hardware. Signed-off-by: Eugen Hristev --- Changes in v3: - change bus width for endpoints to the default 14 arch/arm/boot/dts/sama7g5.dtsi | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi index 7039311bf678..4d0a93541d5f 100644 --- a/arch/arm/boot/dts/sama7g5.dtsi +++ b/arch/arm/boot/dts/sama7g5.dtsi @@ -236,6 +236,54 @@ sdmmc2: mmc@e120c000 { status = "disabled"; }; + csi2dc: csi2dc@e1404000 { + compatible = "microchip,sama7g5-csi2dc"; + reg = <0xe1404000 0x500>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 34>, <&xisc>; + clock-names = "pclk", "scck"; + assigned-clocks = <&xisc>; + assigned-clock-rates = <266000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csi2dc_in: endpoint { + }; + }; + + port@1 { + reg = <1>; + csi2dc_out: endpoint { + bus-width = <14>; + hsync-active = <1>; + vsync-active = <1>; + remote-endpoint = <&xisc_in>; + }; + }; + }; + }; + + xisc: xisc@e1408000 { + compatible = "microchip,sama7g5-isc"; + reg = <0xe1408000 0x2000>; + interrupts = ; + clocks = <&pmc PMC_TYPE_PERIPHERAL 56>; + clock-names = "hclock"; + #clock-cells = <0>; + clock-output-names = "isc-mck"; + + port { + xisc_in: endpoint { + bus-width = <14>; + hsync-active = <1>; + vsync-active = <1>; + remote-endpoint = <&csi2dc_out>; + }; + }; + }; + pwm: pwm@e1604000 { compatible = "microchip,sama7g5-pwm", "atmel,sama5d2-pwm"; reg = <0xe1604000 0x4000>; From patchwork Mon Dec 13 13:49:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 40C28C4332F for ; Mon, 13 Dec 2021 13:54:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236386AbhLMNyM (ORCPT ); Mon, 13 Dec 2021 08:54:12 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:49251 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231211AbhLMNyM (ORCPT ); Mon, 13 Dec 2021 08:54:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403651; x=1670939651; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qOvatQr5WCLEOLjwEcdohe5rtMIJkAtFL76rRB+2+9U=; b=OuALwX3p/RR58JJLFpz0vw3+1vhL9hqC29CozQ5w8heS4drqDQJxTU7o lXkeLsJ0a4nHika77ZexwCCiH+BWmscWmcgVYzgRuSfZ40d/Hu5Fkko2l oYrXKm2s55iwQ6Z1C9duycjDK0vMUlHnBT6ERO1Fh2+LP70DL/rKiM7xj k6PrJjktsgXlZ5PX8XiIm9R/4BEX9c1oWQwKOi2/xEsO4kJUCvAfwJocy g1VYZXIbELlDBgZGQI/CVF1akbtSsR+EgRnaB6XsVrj3SkTBfHOHYKdB3 MwK8gUz2alcyd+Ov7TPKnn/n7bJDlwPLZKRFjxITvfs4qTiV0a0LgLZYW w==; IronPort-SDR: Ymmv/LRqnni8jZS0P9O/k5mXjWDllb7FpkIfx4kztAhNaPNWjNj0E4nDYlD7xbcVIAL5uZYHKL ZNgu5YEIGPC7Dd+XTrcU3UXwmT/WE1nxY8Zm8gCKOdQsK9pt6Z4q4Pl0o/UuwyakfRsJw+2wPe Xp7BSkDxYGKdTYmj5UvRMSAC0gHr0hTTEfxgoMfA8vhRZULxPjBWTYZA3IBEqcq4/c2KFDvqi3 MOmVu+wtjZswrnIVljeeA9Y/MjM8ZZtqfeaEWF0eR9ec5UJtmzF6yPeyEZARs5YVeGT1GZoG05 QAuPuqIOidzfUFa2rC7RH3yH X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="79361849" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:54:10 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:54:09 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:53:42 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 15/23] ARM: multi_v7_defconfig: add atmel video pipeline modules Date: Mon, 13 Dec 2021 15:49:32 +0200 Message-ID: <20211213134940.324266-16-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add drivers for the atmel video capture pipeline: atmel isc, xisc and microchip csi2dc. Signed-off-by: Eugen Hristev --- arch/arm/configs/multi_v7_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index c951aeed2138..92b7749a6df8 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -638,7 +638,10 @@ CONFIG_VIDEO_S5P_MIPI_CSIS=m CONFIG_VIDEO_EXYNOS_FIMC_LITE=m CONFIG_VIDEO_EXYNOS4_FIMC_IS=m CONFIG_VIDEO_RCAR_VIN=m +CONFIG_VIDEO_ATMEL_ISC=m +CONFIG_VIDEO_ATMEL_XISC=m CONFIG_VIDEO_ATMEL_ISI=m +CONFIG_VIDEO_MICROCHIP_CSI2DC=m CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m CONFIG_VIDEO_SAMSUNG_S5P_MFC=m From patchwork Mon Dec 13 13:49:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523566 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B3E2C433EF for ; Mon, 13 Dec 2021 13:54:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238355AbhLMNyx (ORCPT ); Mon, 13 Dec 2021 08:54:53 -0500 Received: from esa.microchip.iphmx.com ([68.232.154.123]:49313 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233777AbhLMNyw (ORCPT ); Mon, 13 Dec 2021 08:54:52 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403692; x=1670939692; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xR2xChyp+/mKKklRKz7BqV+4uXpgD6Ige3/1mbZJg+U=; b=CCH06MthosI+EHT+l6xitXvWAKF2iofJNyAy5mtCQqv1l92HYD31Fdev OGZSkvse4GeH+NqljlYbEskl0LiGbG99gNgnD5K1TneMKKD49tBP9Opx1 /F+iglpC4JrFqIKMip93hayYLBYuhzVFVW9jSokxSz18RIDKZwA5y1gjy t5g0WyRlRnvb4z6lHgmvBH0s8rItfYtvsdZToUObRsayDOrgcKaHQhtkM uK/sahY79GmCuWFBQaaIOcv2Gb0vUat1Uh21yHh+Vh/QAHgLydg/qDA3E feZvxGuNGBujhNb6ynigmqqzZ65D1fABv93dSw8blp592oQ7Pot79auKc A==; IronPort-SDR: TvHHYOddhrzubtSz18kcERmffyHIs4gmtnUHAlQzRDZGiX92ymjmDIVLAgEc1hNoPo0M8XxUBb Kx/yFaq//ViyZMthlNhyqDA/u6BDLb4QHXb8OinT8p61izBGXCKOz/KCdXFp9XBYKEDTkLdmrO OexstHTQC7XYDZ38Qrgm5SOQg2bWuc/L3s6z5ZcMMM3r/3AB1Mypz41iMca0SxV69UJ9iB82L7 aTI+7UcxXkicaIqpU/OZqpDOdYwAWUlW84myvf1GJ0U0aBVmvglbyucmO0lkwHLvJEwdmUrrYi F79emERL2PIkPQOJZhH1LwVb X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="79361943" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:54:51 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:54:50 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:54:24 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 17/23] media: atmel: atmel-isc-base: use mutex to lock awb workqueue from streaming Date: Mon, 13 Dec 2021 15:49:34 +0200 Message-ID: <20211213134940.324266-18-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The AWB workqueue runs in a kernel thread and needs to be synchronized w.r.t. the streaming status. It is possible that streaming is stopped while the AWB workq is running. In this case it is likely that the check for isc->stop is done at one point in time, but the AWB computations are done later, including a call to isc_update_profile, which requires streaming to be started. Thus , isc_update_profile will fail if during this operation sequence the streaming was stopped. To solve this issue, a mutex is added, that will serialize the awb work and streaming stopping, with the mention that either streaming is stopped completely including termination of the last frame is done, and after that the AWB work can check stream status and stop; either first AWB work is completed and after that the streaming can stop correctly. The awb spin lock cannot be used since this spinlock is taken in the same context and using it in the stop streaming will result in a recursion BUG. Signed-off-by: Eugen Hristev --- drivers/media/platform/atmel/atmel-isc-base.c | 31 ++++++++++++++++--- drivers/media/platform/atmel/atmel-isc.h | 1 + 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index b0c3ed21f372..53cac1aac0fd 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -401,6 +401,7 @@ static void isc_stop_streaming(struct vb2_queue *vq) struct isc_buffer *buf; int ret; + mutex_lock(&isc->awb_mutex); v4l2_ctrl_activate(isc->do_wb_ctrl, false); isc->stop = true; @@ -410,6 +411,8 @@ static void isc_stop_streaming(struct vb2_queue *vq) v4l2_err(&isc->v4l2_dev, "Timeout waiting for end of the capture\n"); + mutex_unlock(&isc->awb_mutex); + /* Disable DMA interrupt */ regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE); @@ -1416,10 +1419,6 @@ static void isc_awb_work(struct work_struct *w) u32 min, max; int ret; - /* streaming is not active anymore */ - if (isc->stop) - return; - if (ctrls->hist_stat != HIST_ENABLED) return; @@ -1470,7 +1469,24 @@ static void isc_awb_work(struct work_struct *w) } regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, hist_id | baysel | ISC_HIS_CFG_RAR); + + /* + * We have to make sure the streaming has not stopped meanwhile. + * ISC requires a frame to clock the internal profile update. + * To avoid issues, lock the sequence with a mutex + */ + mutex_lock(&isc->awb_mutex); + + /* streaming is not active anymore */ + if (isc->stop) { + mutex_unlock(&isc->awb_mutex); + return; + }; + isc_update_profile(isc); + + mutex_unlock(&isc->awb_mutex); + /* if awb has been disabled, we don't need to start another histogram */ if (ctrls->awb) regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ); @@ -1549,6 +1565,8 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl) isc_update_awb_ctrls(isc); + mutex_lock(&isc->awb_mutex); + if (!isc->stop) { /* * If we are streaming, we can update profile to @@ -1563,6 +1581,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl) */ v4l2_ctrl_activate(isc->do_wb_ctrl, false); } + mutex_unlock(&isc->awb_mutex); /* if we have autowhitebalance on, start histogram procedure */ if (ctrls->awb == ISC_WB_AUTO && !isc->stop && @@ -1754,6 +1773,7 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier, { struct isc_device *isc = container_of(notifier->v4l2_dev, struct isc_device, v4l2_dev); + mutex_destroy(&isc->awb_mutex); cancel_work_sync(&isc->awb_work); video_unregister_device(&isc->video_dev); v4l2_ctrl_handler_free(&isc->ctrls.handler); @@ -1866,6 +1886,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) isc->current_subdev = container_of(notifier, struct isc_subdev_entity, notifier); mutex_init(&isc->lock); + mutex_init(&isc->awb_mutex); + init_completion(&isc->comp); /* Initialize videobuf2 queue */ @@ -1941,6 +1963,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) video_unregister_device(vdev); isc_async_complete_err: + mutex_destroy(&isc->awb_mutex); mutex_destroy(&isc->lock); return ret; } diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 0b6370d7775f..c2cb805faff3 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -307,6 +307,7 @@ struct isc_device { struct work_struct awb_work; struct mutex lock; /* serialize access to file operations */ + struct mutex awb_mutex; /* serialize access to streaming status from awb work queue */ spinlock_t awb_lock; /* serialize access to DMA buffers from awb work queue */ struct regmap_field *pipeline[ISC_PIPE_LINE_NODE_NUM]; From patchwork Mon Dec 13 13:49:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5C102C433F5 for ; Mon, 13 Dec 2021 13:55:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237604AbhLMNzn (ORCPT ); Mon, 13 Dec 2021 08:55:43 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:8802 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234239AbhLMNzn (ORCPT ); Mon, 13 Dec 2021 08:55:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403742; x=1670939742; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RKT4TsQbf9WhAC/BzpiLxsl35EXH1/8qpv9zRIsAbvo=; b=bRYqplLljQDAqtV6FZTkqa8PnhAv8et2tdKh8ZkehFqolHf1DZGS9MPy VWXA46P75KFKGVoi0Kyz/FWqFoZD201Y13e1sCktlvsLxJXm9HN+yYc35 2EWNrO5JzHeCrb8ATYvALeTUwxymH6FXb3rY/c7qCx1rzoLh30y12NT+0 8V+gAuC32fdHNO6lZslz3UEoNvIzz6cjs7Ea909BpfyHy3cZjkotUkf1h k/0E+uEO/fJlqwfMQ14971N4ba9CLr3Rv1WR2Aj9GUIYFllls6xmvxT2U nITFkSkkDNIHd/RtkXYuIKsU/C6Gd94aDz/SD+VlbeXvNsxcgIIidvG7y w==; IronPort-SDR: Sq4wjjOofCWVGyZv5eAq0hyYwQ/zg8wi+Ss0cDbu04rvODVG5OiCUpKDM3476jcg0AIPbExT2A 80EZBygae7WIOW3RZ/VGXqprbe2Jp4I6xxH+we1wqaGmPm7tZVFvgXC01FgmufxSi29Dh2u+Ba RaRn1FxcH/drgRbAOzGpBmcTNG4rr3/YUXik5uSpZLhnOTQP2QEJUredyAnEFIl5Iqs5GZOqWa h4w/gfxw8jeYs83IOg/nGzLuLzFnqKPa4SrOIiy3RQO7smLJon0gQXiwaspzvxra51O7bXmLQc NIDKXVR8jDw/078kzsvmzVGS X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="147032929" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:55:42 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:55:41 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:55:21 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 19/23] media: atmel: atmel-isc-base: clamp wb gain coefficients Date: Mon, 13 Dec 2021 15:49:36 +0200 Message-ID: <20211213134940.324266-20-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org White balance computed gains can overflow above the 13 bits hardware coefficient that can be used, in some specific scenarios like a subexposure from the sensor when the image is mostly black. In this case the computed gain has to be clamped to the maximum value allowed by the hardware. Signed-off-by: Eugen Hristev Reviewed-by: Jacopo Mondi --- drivers/media/platform/atmel/atmel-isc-base.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index f1f1019f9d82..31c8e3029eee 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -1415,6 +1415,10 @@ static void isc_wb_update(struct isc_ctrls *ctrls) /* multiply both gains and adjust for decimals */ ctrls->gain[c] = s_gain[c] * gw_gain[c]; ctrls->gain[c] >>= 9; + + /* make sure we are not out of range */ + ctrls->gain[c] = clamp_val(ctrls->gain[c], 0, GENMASK(12, 0)); + v4l2_dbg(1, debug, &isc->v4l2_dev, "isc wb: component %d, final gain %u\n", c, ctrls->gain[c]); From patchwork Mon Dec 13 13:49:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523564 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8D10C4332F for ; Mon, 13 Dec 2021 13:56:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238436AbhLMN4M (ORCPT ); Mon, 13 Dec 2021 08:56:12 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:56599 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234036AbhLMN4L (ORCPT ); Mon, 13 Dec 2021 08:56:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403771; x=1670939771; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BVsnVhKos+4un4tF8gl8LYrlTAZbplMjYM+lMJCJPa8=; b=ngBc/F5jnOBLwGFdGrsD7QfOPLIqaxK07v+7syP/oj4E6IDG6guOeElD Qp9tqPfEtSzgXVml1ctboWygMgJzA/GyNQAHncLV90XkBZCY54b2OXFY6 8hTspISFE4KJ1+bBuPn7HV5K8lyBKbG2iQPycc6VrSVBeWU+7XoWwq+/S KSNKvBRQIxBokACcWTcZ/kno4apVB+zquX6DMZhiE1s3I82iJNE9/xmeS bZa92BfDbyrwrjWcdphTFEsAyG14+IgU3zqjYURyCergrFugKkcXHThpg JrTKebfdjX/e/FD32BzOB35kRbIIrkSz8E4M+2tOFwFXIgdEJ8J921Mcc g==; IronPort-SDR: G7m7IrJHd0B5DVO9t/yLcC/LOTuP7WI2f+VJP5DKyUBCtSmyRi7efqbCtg8lnQziE9Bw9ywpOO X811O9omQfPa7XFBgdK2NjXPd74EhOYr6PGQUdC2pT0Mx6czqzYslqqkoHXLKS9WWXf8DK58F7 OOfTdkk+jXZNcE+YqAobxO0xXIaOJvvzaF4HMrKBfQjY3k1YgNtzJMDsUZ4AidtR/5WS9PEb2X MywlScfQROuPdmflpnRg3I/qUY6ch00QwlzqCqbAM6d2G+yrOAFgeWpztXSMWOytuHd5uMH1mr c+NymNVN+vDoyj2aZ840S4TA X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="146466682" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:56:10 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:56:10 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:55:55 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 21/23] media: atmel: atmel-isc: add raw Bayer 8bit 10bit output formats Date: Mon, 13 Dec 2021 15:49:38 +0200 Message-ID: <20211213134940.324266-22-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The ISC can dump the 8 bit and 10 bit raw bayer formats directly to the memory. Thus, add them to the supported output format list. Signed-off-by: Eugen Hristev Reviewed-by: Jacopo Mondi --- .../media/platform/atmel/atmel-sama5d2-isc.c | 24 +++++++++++++++++++ .../media/platform/atmel/atmel-sama7g5-isc.c | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index a8d4ba60d3ac..025c3e8a7e95 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -88,6 +88,30 @@ static const struct isc_format sama5d2_controller_formats[] = { { .fourcc = V4L2_PIX_FMT_Y10, }, + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + }, }; /* This is a list of formats that the ISC can receive as *input* */ diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c index 38721bd902e2..9dc75eed0098 100644 --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c @@ -100,6 +100,30 @@ static const struct isc_format sama7g5_controller_formats[] = { { .fourcc = V4L2_PIX_FMT_Y16, }, + { + .fourcc = V4L2_PIX_FMT_SBGGR8, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG8, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG8, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB8, + }, + { + .fourcc = V4L2_PIX_FMT_SBGGR10, + }, + { + .fourcc = V4L2_PIX_FMT_SGBRG10, + }, + { + .fourcc = V4L2_PIX_FMT_SGRBG10, + }, + { + .fourcc = V4L2_PIX_FMT_SRGGB10, + }, }; /* This is a list of formats that the ISC can receive as *input* */ From patchwork Mon Dec 13 13:49:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eugen Hristev X-Patchwork-Id: 523563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3DFFDC433EF for ; Mon, 13 Dec 2021 13:56:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238501AbhLMN4e (ORCPT ); Mon, 13 Dec 2021 08:56:34 -0500 Received: from esa.microchip.iphmx.com ([68.232.153.233]:30453 "EHLO esa.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234036AbhLMN4c (ORCPT ); Mon, 13 Dec 2021 08:56:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1639403793; x=1670939793; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ioahXhjtNzObJIt/qQKM/Eu1tJHbqFzpWjVw7XfbcA0=; b=aAIXhI8uBL8VIYqgRzimBp1bsT99Ha728UrOr/AvXXvouuL3RrYKI/4z BTOTZHbLUGLGg+0pLiNANLsoCa7zcQoQZkmEL6+hGOIsnPNoT7402Rfhn 8ooVGvEh/RARl5VePv/J8I2gw5B8Za7Ea/+Iq6Wm8/WNejgEixuEWugSx n+Blld7+w/zp4LidU5o0yz80urXb/p5PoKLJZnUtVHGcr/ZIsbiq0DmM9 nmIV2ONwwL2KTy7PbNqGp1Cs/u8fvPP1SbJridAPZugTNdF3YCoEenea5 t8IgL/kZ4jGJcI1r0HZZUd4Ul1MwXHLm7EuxHEHYzLV4cPfbAQ3+kHjoo A==; IronPort-SDR: efJq024+DS6cB/2L+eqXRMiJe+zqHKQpoSPx16+A9DFK7vw+tG2f0W6EMNIR3IHcz0N7i7CZzg 3hu5s1dgjqaPQ8fKRbi/dZBbCroyX3cVTkXcDcjdjF5YQjc1gM3ANKbtdTIdDCv7bEF1638L+I nBjM56dONrkDVtmXt1bGylmALICNB3tpixBV0cMWs3IdO4FjjQClhO+nrBSycmQi81tVLV62lx nIlAlqd+jC62PKl1RpB0B8liWiouGT4nbFNDspxa3gwvMupSCLqI5Nm48SbX5BXYRl5YU6f8tH 79xj6jlK1PefhHV6dhD2JBDa X-IronPort-AV: E=Sophos;i="5.88,202,1635231600"; d="scan'208";a="146466723" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Dec 2021 06:56:32 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.17; Mon, 13 Dec 2021 06:56:32 -0700 Received: from ROB-ULT-M18282.microchip.com (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.2375.17 via Frontend Transport; Mon, 13 Dec 2021 06:56:25 -0700 From: Eugen Hristev To: , , , , CC: , , , , "Eugen Hristev" Subject: [PATCH v3 23/23] media: atmel: atmel-isc: change format propagation to subdev into only verification Date: Mon, 13 Dec 2021 15:49:40 +0200 Message-ID: <20211213134940.324266-24-eugen.hristev@microchip.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com> References: <20211213134940.324266-1-eugen.hristev@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org As a top MC video driver, the atmel-isc should not propagate the format to the subdevice. It should rather check at streamon() time if the subdev is properly configured with a compatible format. Removed the whole format finding logic, and reworked the format verification at streamon time, such that the ISC will return an error if the subdevice is not properly configured. With this being done, the module parameter 'sensor_prefered' makes no sense anymore. The ISC should not decide which format the sensor is using. The ISC should only cope with the situation and inform userspace if the streaming is possible in the current configuration. Signed-off-by: Eugen Hristev --- Changes in v3: - clamp to maximum resolution once the frame size from the subdev is found drivers/media/platform/atmel/atmel-isc-base.c | 271 ++++++++---------- drivers/media/platform/atmel/atmel-isc.h | 1 + 2 files changed, 126 insertions(+), 146 deletions(-) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 31c8e3029eee..00c8c9588a78 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -36,11 +36,6 @@ static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "debug level (0-2)"); -static unsigned int sensor_preferred = 1; -module_param(sensor_preferred, uint, 0644); -MODULE_PARM_DESC(sensor_preferred, - "Sensor is preferred to output the specified format (1-on 0-off), default 1"); - #define ISC_IS_FORMAT_RAW(mbus_code) \ (((mbus_code) & 0xf000) == 0x3000) @@ -532,7 +527,7 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv, * convert it to any of the formats that we usually can with a * RAW sensor. Thus, do not advertise them. */ - if (!isc->config.sd_format || + if (isc->config.sd_format && !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) return -EINVAL; @@ -621,20 +616,30 @@ static int isc_try_validate_formats(struct isc_device *isc) break; default: /* any other different formats are not supported */ + v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n"); ret = -EINVAL; } v4l2_dbg(1, debug, &isc->v4l2_dev, "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n", rgb, yuv, grey, bayer); - /* we cannot output RAW if we do not receive RAW */ - if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) + if ((bayer) && + !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n"); return -EINVAL; + } - /* we cannot output GREY if we do not receive RAW/GREY */ if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) && - !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) + !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) { + v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n"); return -EINVAL; + } + + if ((rgb || bayer || yuv) && + ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) { + v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n"); + return -EINVAL; + } return ret; } @@ -862,7 +867,7 @@ static void isc_try_fse(struct isc_device *isc, * If we do not know yet which format the subdev is using, we cannot * do anything. */ - if (!isc->try_config.sd_format) + if (!isc->config.sd_format) return; fse.code = isc->try_config.sd_format->mbus_code; @@ -883,180 +888,141 @@ static void isc_try_fse(struct isc_device *isc, } } -static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, - u32 *code) +static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f) { - int i; - struct isc_format *sd_fmt = NULL, *direct_fmt = NULL; struct v4l2_pix_format *pixfmt = &f->fmt.pix; - struct v4l2_subdev_pad_config pad_cfg = {}; - struct v4l2_subdev_state pad_state = { - .pads = &pad_cfg - }; - struct v4l2_subdev_format format = { - .which = V4L2_SUBDEV_FORMAT_TRY, - }; - u32 mbus_code; - int ret; - bool rlp_dma_direct_dump = false; + unsigned int i; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - /* Step 1: find a RAW format that is supported */ - for (i = 0; i < isc->num_user_formats; i++) { - if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) { - sd_fmt = isc->user_formats[i]; + isc->try_config.fourcc = isc->user_formats[0]->fourcc; + + /* find if the format requested is supported */ + for (i = 0; i < isc->controller_formats_size; i++) + if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) { + isc->try_config.fourcc = pixfmt->pixelformat; break; } - } - /* Step 2: We can continue with this RAW format, or we can look - * for better: maybe sensor supports directly what we need. - */ - direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat); - - /* Step 3: We have both. We decide given the module parameter which - * one to use. - */ - if (direct_fmt && sd_fmt && sensor_preferred) - sd_fmt = direct_fmt; - - /* Step 4: we do not have RAW but we have a direct format. Use it. */ - if (direct_fmt && !sd_fmt) - sd_fmt = direct_fmt; - - /* Step 5: if we are using a direct format, we need to package - * everything as 8 bit data and just dump it - */ - if (sd_fmt == direct_fmt) - rlp_dma_direct_dump = true; - - /* Step 6: We have no format. This can happen if the userspace - * requests some weird/invalid format. - * In this case, default to whatever we have - */ - if (!sd_fmt && !direct_fmt) { - sd_fmt = isc->user_formats[isc->num_user_formats - 1]; - v4l2_dbg(1, debug, &isc->v4l2_dev, - "Sensor not supporting %.4s, using %.4s\n", - (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc); - } - - if (!sd_fmt) { - ret = -EINVAL; - goto isc_try_fmt_err; - } - - /* Step 7: Print out what we decided for debugging */ - v4l2_dbg(1, debug, &isc->v4l2_dev, - "Preferring to have sensor using format %.4s\n", - (char *)&sd_fmt->fourcc); - - /* Step 8: at this moment we decided which format the subdev will use */ - isc->try_config.sd_format = sd_fmt; - - /* Limit to Atmel ISC hardware capabilities */ - if (pixfmt->width > isc->max_width) - pixfmt->width = isc->max_width; - if (pixfmt->height > isc->max_height) - pixfmt->height = isc->max_height; - - /* - * The mbus format is the one the subdev outputs. - * The pixels will be transferred in this format Sensor -> ISC - */ - mbus_code = sd_fmt->mbus_code; - - /* - * Validate formats. If the required format is not OK, default to raw. - */ - - isc->try_config.fourcc = pixfmt->pixelformat; - - if (isc_try_validate_formats(isc)) { - pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc; - /* Re-try to validate the new format */ - ret = isc_try_validate_formats(isc); - if (ret) - goto isc_try_fmt_err; - } - - ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump); - if (ret) - goto isc_try_fmt_err; - - ret = isc_try_configure_pipeline(isc); - if (ret) - goto isc_try_fmt_err; - /* Obtain frame sizes if possible to have crop requirements ready */ - isc_try_fse(isc, &pad_state); - - v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code); - ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, - &pad_state, &format); - if (ret < 0) - goto isc_try_fmt_subdev_err; + /* If we did not find the requested format, we will fallback here */ + pixfmt->pixelformat = isc->try_config.fourcc; + pixfmt->colorspace = V4L2_COLORSPACE_SRGB; + pixfmt->field = V4L2_FIELD_NONE; - v4l2_fill_pix_format(pixfmt, &format.format); + isc_try_configure_rlp_dma(isc, false); /* Limit to Atmel ISC hardware capabilities */ - if (pixfmt->width > isc->max_width) - pixfmt->width = isc->max_width; - if (pixfmt->height > isc->max_height) - pixfmt->height = isc->max_height; + v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0, + &pixfmt->height, 16, isc->max_height, 0, 0); pixfmt->field = V4L2_FIELD_NONE; pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3; pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) * pixfmt->height; - if (code) - *code = mbus_code; + isc->try_fmt = *f; return 0; +} -isc_try_fmt_err: - v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n"); -isc_try_fmt_subdev_err: - memset(&isc->try_config, 0, sizeof(isc->try_config)); +static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) +{ + isc_try_fmt(isc, f); - return ret; + /* make the try configuration active */ + isc->config = isc->try_config; + isc->fmt = isc->try_fmt; + + v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n", + (char *)&f->fmt.pix.pixelformat, + f->fmt.pix.width, f->fmt.pix.height); + + return 0; } -static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) +static int isc_validate(struct isc_device *isc) { + int ret; + int i; + struct isc_format *sd_fmt = NULL; + struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix; struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .pad = isc->remote_pad, + }; + struct v4l2_subdev_pad_config pad_cfg = {}; + struct v4l2_subdev_state pad_state = { + .pads = &pad_cfg, }; - u32 mbus_code = 0; - int ret; - ret = isc_try_fmt(isc, f, &mbus_code); + /* Get current format from subdev */ + ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL, + &format); if (ret) return ret; - v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code); - ret = v4l2_subdev_call(isc->current_subdev->sd, pad, - set_fmt, NULL, &format); - if (ret < 0) - return ret; + /* Identify the subdev's format configuration */ + for (i = 0; i < isc->num_user_formats; i++) + if (isc->user_formats[i]->mbus_code == format.format.code) { + sd_fmt = isc->user_formats[i]; + break; + } + + /* Check if the format is not supported */ + if (!sd_fmt) { + v4l2_err(&isc->v4l2_dev, + "Current subdevice is streaming a media bus code that is not supported 0x%x\n", + format.format.code); + return -EPIPE; + } + + /* At this moment we know which format the subdev will use */ + isc->try_config.sd_format = sd_fmt; + + /* If the sensor is not RAW, we can only do a direct dump */ + if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) + isc_try_configure_rlp_dma(isc, true); /* Limit to Atmel ISC hardware capabilities */ - if (f->fmt.pix.width > isc->max_width) - f->fmt.pix.width = isc->max_width; - if (f->fmt.pix.height > isc->max_height) - f->fmt.pix.height = isc->max_height; + v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0, + &format.format.height, 16, isc->max_height, 0, 0); - isc->fmt = *f; + /* Check if the frame size is the same. Otherwise we may overflow */ + if (pixfmt->height != format.format.height || + pixfmt->width != format.format.width) { + v4l2_err(&isc->v4l2_dev, + "ISC not configured with the proper frame size: %dx%d\n", + format.format.width, format.format.height); + return -EPIPE; + } + v4l2_dbg(1, debug, &isc->v4l2_dev, + "Identified subdev using format %.4s with %dx%d %d bpp\n", + (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height, + isc->try_config.bpp); + + /* Reset and restart AWB if the subdevice changed the format */ if (isc->try_config.sd_format && isc->config.sd_format && isc->try_config.sd_format != isc->config.sd_format) { isc->ctrls.hist_stat = HIST_INIT; isc_reset_awb_ctrls(isc); isc_update_v4l2_ctrls(isc); } - /* make the try configuration active */ + + /* Validate formats */ + ret = isc_try_validate_formats(isc); + if (ret) + return ret; + + /* Obtain frame sizes if possible to have crop requirements ready */ + isc_try_fse(isc, &pad_state); + + /* Configure ISC pipeline for the config */ + ret = isc_try_configure_pipeline(isc); + if (ret) + return ret; + isc->config = isc->try_config; v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n"); @@ -1064,6 +1030,19 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) return 0; } +static int isc_streamon(struct file *file, void *priv, enum v4l2_buf_type bt) +{ + struct isc_device *isc = video_drvdata(file); + int ret; + + ret = isc_validate(isc); + + if (ret) + return ret; + + return vb2_ioctl_streamon(file, priv, bt); +} + static int isc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -1080,7 +1059,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv, { struct isc_device *isc = video_drvdata(file); - return isc_try_fmt(isc, f, NULL); + return isc_try_fmt(isc, f); } static int isc_enum_input(struct file *file, void *priv, @@ -1176,7 +1155,7 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = { .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_create_bufs = vb2_ioctl_create_bufs, .vidioc_prepare_buf = vb2_ioctl_prepare_buf, - .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamon = isc_streamon, .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_parm = isc_g_parm, @@ -1879,7 +1858,7 @@ static int isc_set_default_fmt(struct isc_device *isc) }; int ret; - ret = isc_try_fmt(isc, &f, NULL); + ret = isc_try_fmt(isc, &f); if (ret) return ret; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index c2cb805faff3..7081698adddd 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -297,6 +297,7 @@ struct isc_device { struct completion comp; struct v4l2_format fmt; + struct v4l2_format try_fmt; struct isc_format **user_formats; unsigned int num_user_formats;