From patchwork Wed Mar 16 15:46:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782892 X-Patchwork-Delegate: kieran@bingham.xyz 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 DE2DFC433F5 for ; Wed, 16 Mar 2022 15:47:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357338AbiCPPsP (ORCPT ); Wed, 16 Mar 2022 11:48:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357331AbiCPPsO (ORCPT ); Wed, 16 Mar 2022 11:48:14 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1CE436D386; Wed, 16 Mar 2022 08:46:59 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id B4559240011; Wed, 16 Mar 2022 15:46:55 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 01/10] media: adv748x: Add flags to adv748x_subdev_init() Date: Wed, 16 Mar 2022 16:46:32 +0100 Message-Id: <20220316154641.511667-2-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add a flags parameter to the adv748x_subdev_init() function that allows to pass additional flags to the v4l2_subdevice. This will be used to identify the CSI-2 subdevices as multiplexed. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-afe.c | 2 +- drivers/media/i2c/adv748x/adv748x-core.c | 4 ++-- drivers/media/i2c/adv748x/adv748x-csi2.c | 2 +- drivers/media/i2c/adv748x/adv748x-hdmi.c | 2 +- drivers/media/i2c/adv748x/adv748x.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c index 02eabe10ab97..0d05e8a8887f 100644 --- a/drivers/media/i2c/adv748x/adv748x-afe.c +++ b/drivers/media/i2c/adv748x/adv748x-afe.c @@ -510,7 +510,7 @@ int adv748x_afe_init(struct adv748x_afe *afe) afe->curr_norm = V4L2_STD_NTSC_M; adv748x_subdev_init(&afe->sd, state, &adv748x_afe_ops, - MEDIA_ENT_F_ATV_DECODER, "afe"); + MEDIA_ENT_F_ATV_DECODER, 0, "afe"); /* Identify the first connector found as a default input if set */ for (i = ADV748X_PORT_AIN0; i <= ADV748X_PORT_AIN7; i++) { diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c index 4e54148147b9..0961b1468465 100644 --- a/drivers/media/i2c/adv748x/adv748x-core.c +++ b/drivers/media/i2c/adv748x/adv748x-core.c @@ -583,10 +583,10 @@ static int __maybe_unused adv748x_resume_early(struct device *dev) void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state, const struct v4l2_subdev_ops *ops, u32 function, - const char *ident) + u32 flags, const char *ident) { v4l2_subdev_init(sd, ops); - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | flags; /* the owner is the same as the i2c_client's driver owner */ sd->owner = state->dev->driver->owner; diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index bd4f3fe0e309..8c2701e1da0e 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -297,7 +297,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) return 0; adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, - MEDIA_ENT_F_VID_IF_BRIDGE, + MEDIA_ENT_F_VID_IF_BRIDGE, 0, is_txa(tx) ? "txa" : "txb"); /* Ensure that matching is based upon the endpoint fwnodes */ diff --git a/drivers/media/i2c/adv748x/adv748x-hdmi.c b/drivers/media/i2c/adv748x/adv748x-hdmi.c index 52fa7bd75660..535a21b3c350 100644 --- a/drivers/media/i2c/adv748x/adv748x-hdmi.c +++ b/drivers/media/i2c/adv748x/adv748x-hdmi.c @@ -732,7 +732,7 @@ int adv748x_hdmi_init(struct adv748x_hdmi *hdmi) hdmi->aspect_ratio.denominator = 9; adv748x_subdev_init(&hdmi->sd, state, &adv748x_ops_hdmi, - MEDIA_ENT_F_IO_DTV, "hdmi"); + MEDIA_ENT_F_IO_DTV, 0, "hdmi"); hdmi->pads[ADV748X_HDMI_SINK].flags = MEDIA_PAD_FL_SINK; hdmi->pads[ADV748X_HDMI_SOURCE].flags = MEDIA_PAD_FL_SOURCE; diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 31bac06d46b5..92c8caee6a42 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -426,7 +426,7 @@ static inline struct v4l2_subdev *adv748x_get_remote_sd(struct media_pad *pad) void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state, const struct v4l2_subdev_ops *ops, u32 function, - const char *ident); + u32 flags, const char *ident); int adv748x_register_subdevs(struct adv748x_state *state, struct v4l2_device *v4l2_dev); From patchwork Wed Mar 16 15:46:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782891 X-Patchwork-Delegate: kieran@bingham.xyz 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 9D71BC433FE for ; Wed, 16 Mar 2022 15:47:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357335AbiCPPsP (ORCPT ); Wed, 16 Mar 2022 11:48:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357329AbiCPPsO (ORCPT ); Wed, 16 Mar 2022 11:48:14 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B30176D383; Wed, 16 Mar 2022 08:46:59 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 2878C240012; Wed, 16 Mar 2022 15:46:56 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 02/10] media: adv748x: Add support for v4l2_subdev_state Date: Wed, 16 Mar 2022 16:46:33 +0100 Message-Id: <20220316154641.511667-3-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Create and initialize the v4l2_subdev_state for the adv748x CSI-2 subdevice in order to prepare to support routing of the video stream. Create the subdevice state with v4l2_subdev_init_finalize() and implement the init_cfg() operation to guarantee the state is initialized correctly with the default routing set. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 52 +++++++++++++++++++++++- drivers/media/i2c/adv748x/adv748x.h | 3 ++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 8c2701e1da0e..9e0957501d70 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -139,6 +139,45 @@ static const struct v4l2_subdev_video_ops adv748x_csi2_video_ops = { * But we must support setting the pad formats for format propagation. */ +static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + /* One route for each virtual channel. Route 0 enabled by default. */ + struct v4l2_subdev_route routes[ADV748X_CSI2_STREAMS] = { + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 1, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 2, + }, + { + .sink_pad = ADV748X_CSI2_SINK, + .sink_stream = 0, + .source_pad = ADV748X_CSI2_SOURCE, + .source_stream = 3, + }, + }; + struct v4l2_subdev_krouting routing = { + .num_routes = ADV748X_CSI2_STREAMS, + .routes = routes, + }; + + return v4l2_subdev_set_routing(sd, state, &routing); +} + static struct v4l2_mbus_framefmt * adv748x_csi2_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, @@ -228,6 +267,7 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad } static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { + .init_cfg = adv748x_csi2_init_cfg, .get_fmt = adv748x_csi2_get_format, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, @@ -297,7 +337,8 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) return 0; adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, - MEDIA_ENT_F_VID_IF_BRIDGE, 0, + MEDIA_ENT_F_VID_IF_BRIDGE, + V4L2_SUBDEV_FL_MULTIPLEXED, is_txa(tx) ? "txa" : "txb"); /* Ensure that matching is based upon the endpoint fwnodes */ @@ -314,10 +355,14 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) if (ret) return ret; - ret = adv748x_csi2_init_controls(tx); + ret = v4l2_subdev_init_finalize(&tx->sd); if (ret) goto err_free_media; + ret = adv748x_csi2_init_controls(tx); + if (ret) + goto err_free_state; + ret = v4l2_async_register_subdev(&tx->sd); if (ret) goto err_free_ctrl; @@ -326,6 +371,8 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) err_free_ctrl: v4l2_ctrl_handler_free(&tx->ctrl_hdl); +err_free_state: + v4l2_subdev_cleanup(&tx->sd); err_free_media: media_entity_cleanup(&tx->sd.entity); @@ -338,6 +385,7 @@ void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) return; v4l2_async_unregister_subdev(&tx->sd); + v4l2_subdev_cleanup(&tx->sd); media_entity_cleanup(&tx->sd.entity); v4l2_ctrl_handler_free(&tx->ctrl_hdl); } diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index 92c8caee6a42..d651c8390e6f 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -73,6 +73,9 @@ enum adv748x_csi2_pads { /* CSI2 transmitters can have 2 internal connections, HDMI/AFE */ #define ADV748X_CSI2_MAX_SUBDEVS 2 +/* CSI2 number of streams: 1 for each CSI-2 Virtual channel output. */ +#define ADV748X_CSI2_STREAMS 4 + struct adv748x_csi2 { struct adv748x_state *state; struct v4l2_mbus_framefmt format; From patchwork Wed Mar 16 15:46:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782893 X-Patchwork-Delegate: kieran@bingham.xyz 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 3C892C433FE for ; Wed, 16 Mar 2022 15:47:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230089AbiCPPsQ (ORCPT ); Wed, 16 Mar 2022 11:48:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54028 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357340AbiCPPsQ (ORCPT ); Wed, 16 Mar 2022 11:48:16 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A5336D38E; Wed, 16 Mar 2022 08:47:01 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id A75DE24000D; Wed, 16 Mar 2022 15:46:58 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 03/10] media: adv748x: Move format to subdev state Date: Wed, 16 Mar 2022 16:46:34 +0100 Message-Id: <20220316154641.511667-4-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Move format handling to the v4l2_subdev state and store it per (pad, stream) combination. Now that the image format is stored in the subdev state, it can be accessed through v4l2_subdev_get_fmt() instead of open-coding it. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 77 +++++------------------- drivers/media/i2c/adv748x/adv748x.h | 1 - 2 files changed, 16 insertions(+), 62 deletions(-) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 9e0957501d70..8326cfe6192a 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -178,78 +178,33 @@ static int adv748x_csi2_init_cfg(struct v4l2_subdev *sd, return v4l2_subdev_set_routing(sd, state, &routing); } -static struct v4l2_mbus_framefmt * -adv748x_csi2_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - unsigned int pad, u32 which) -{ - struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); - - if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(sd, sd_state, pad); - - return &tx->format; -} - -static int adv748x_csi2_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *sdformat) -{ - struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); - struct adv748x_state *state = tx->state; - struct v4l2_mbus_framefmt *mbusformat; - - mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad, - sdformat->which); - if (!mbusformat) - return -EINVAL; - - mutex_lock(&state->mutex); - - sdformat->format = *mbusformat; - - mutex_unlock(&state->mutex); - - return 0; -} - static int adv748x_csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { - struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); - struct adv748x_state *state = tx->state; - struct v4l2_mbus_framefmt *mbusformat; + struct v4l2_mbus_framefmt *fmt; int ret = 0; - mbusformat = adv748x_csi2_get_pad_format(sd, sd_state, sdformat->pad, - sdformat->which); - if (!mbusformat) + /* Do not allow to set format on the multiplexed source pad. */ + if (sdformat->pad == ADV748X_CSI2_SOURCE) return -EINVAL; - mutex_lock(&state->mutex); - - if (sdformat->pad == ADV748X_CSI2_SOURCE) { - const struct v4l2_mbus_framefmt *sink_fmt; - - sink_fmt = adv748x_csi2_get_pad_format(sd, sd_state, - ADV748X_CSI2_SINK, - sdformat->which); - - if (!sink_fmt) { - ret = -EINVAL; - goto unlock; - } + fmt = v4l2_subdev_state_get_stream_format(sd_state, sdformat->pad, + sdformat->stream); + if (!fmt) + return -EINVAL; - sdformat->format = *sink_fmt; - } + *fmt = sdformat->format; - *mbusformat = sdformat->format; + /* Propagate format to the other end of the route. */ + fmt = v4l2_subdev_state_get_opposite_stream_format(sd_state, sdformat->pad, + sdformat->stream); + if (!fmt) + return ret; -unlock: - mutex_unlock(&state->mutex); + *fmt = sdformat->format; - return ret; + return 0; } static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad, @@ -268,7 +223,7 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { .init_cfg = adv748x_csi2_init_cfg, - .get_fmt = adv748x_csi2_get_format, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, }; diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h index d651c8390e6f..98a3b3e0642a 100644 --- a/drivers/media/i2c/adv748x/adv748x.h +++ b/drivers/media/i2c/adv748x/adv748x.h @@ -78,7 +78,6 @@ enum adv748x_csi2_pads { struct adv748x_csi2 { struct adv748x_state *state; - struct v4l2_mbus_framefmt format; unsigned int page; unsigned int port; unsigned int num_lanes; From patchwork Wed Mar 16 15:46:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782894 X-Patchwork-Delegate: kieran@bingham.xyz 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 4480CC433EF for ; Wed, 16 Mar 2022 15:47:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356924AbiCPPsV (ORCPT ); Wed, 16 Mar 2022 11:48:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54092 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357347AbiCPPsR (ORCPT ); Wed, 16 Mar 2022 11:48:17 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D36096D394; Wed, 16 Mar 2022 08:47:02 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 2CEFF240005; Wed, 16 Mar 2022 15:46:59 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 04/10] media: adv748x: Implement .get_frame_desc() Date: Wed, 16 Mar 2022 16:46:35 +0100 Message-Id: <20220316154641.511667-5-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Implement the get_frame_desc subdev pad operation. Implement the get_frame_desc pad operation to allow retrieving the stream configuration of the adv748x csi2 subdevice. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 94 ++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 8326cfe6192a..91cd70739e9d 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -14,6 +14,50 @@ #include "adv748x.h" +/* Describes a format bit depth and CSI-2 defined Data Type. */ +struct adv748x_csi2_format_info { + u8 dt; + u8 bpp; +}; + +static int adv748x_csi2_get_format_info(struct adv748x_csi2 *tx, + u32 mbus_code, + struct adv748x_csi2_format_info *fmt) +{ + switch (mbus_code) { + case MEDIA_BUS_FMT_YUYV8_1X16: + case MEDIA_BUS_FMT_YUYV8_2X8: + fmt->dt = 0x1e; + fmt->bpp = 16; + break; + case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_YUYV10_1X20: + fmt->dt = 0x1f; + fmt->bpp = 20; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + case MEDIA_BUS_FMT_RGB565_2X8_LE: + case MEDIA_BUS_FMT_RGB565_2X8_BE: + fmt->dt = 0x22; + fmt->bpp = 16; + break; + case MEDIA_BUS_FMT_RGB666_1X18: + fmt->dt = 0x23; + fmt->bpp = 18; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + fmt->dt = 0x24; + fmt->bpp = 24; + break; + default: + dev_err(tx->state->dev, + "Unsupported media bus code: %u\n", mbus_code); + return -EINVAL; + } + + return 0; +} + int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, unsigned int vc) { return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT); @@ -221,11 +265,61 @@ static int adv748x_csi2_get_mbus_config(struct v4l2_subdev *sd, unsigned int pad return 0; } +static int adv748x_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + struct adv748x_csi2_format_info info = {}; + struct v4l2_mbus_frame_desc_entry *entry; + struct v4l2_subdev_route *route; + struct v4l2_subdev_state *state; + struct v4l2_mbus_framefmt *fmt; + int ret; + + if (pad != ADV748X_CSI2_SOURCE) + return -EINVAL; + + state = v4l2_subdev_lock_and_get_active_state(sd); + + /* A single route is available. */ + route = &state->routing.routes[0]; + fmt = v4l2_subdev_state_get_stream_format(state, pad, + route->source_stream); + if (!fmt) { + ret = -EINVAL; + goto out; + } + + ret = adv748x_csi2_get_format_info(tx, fmt->code, &info); + if (ret) + goto out; + + memset(fd, 0, sizeof(*fd)); + + /* A single stream is available. */ + fd->num_entries = 1; + fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; + + entry = &fd->entry[0]; + entry->stream = 0; + entry->flags = V4L2_MBUS_FRAME_DESC_FL_LEN_MAX; + entry->length = fmt->width * fmt->height * info.bpp / 8; + entry->pixelcode = fmt->code; + entry->bus.csi2.vc = route->source_stream; + entry->bus.csi2.dt = info.dt; + +out: + v4l2_subdev_unlock_state(state); + + return ret; +} + static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { .init_cfg = adv748x_csi2_init_cfg, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, + .get_frame_desc = adv748x_csi2_get_frame_desc, }; /* ----------------------------------------------------------------------------- From patchwork Wed Mar 16 15:46:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782896 X-Patchwork-Delegate: kieran@bingham.xyz 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 D6F74C4332F for ; Wed, 16 Mar 2022 15:47:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355833AbiCPPsV (ORCPT ); Wed, 16 Mar 2022 11:48:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357350AbiCPPsV (ORCPT ); Wed, 16 Mar 2022 11:48:21 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A799E6D3A5; Wed, 16 Mar 2022 08:47:04 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id CBD97240011; Wed, 16 Mar 2022 15:47:01 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 05/10] media: adv748x: Implement set_routing Date: Wed, 16 Mar 2022 16:46:36 +0100 Message-Id: <20220316154641.511667-6-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add the set_routing() subdev operation to allow userspace to configure the CSI-2 virtual channel. Signed-off-by: Jacopo Mondi --- drivers/media/i2c/adv748x/adv748x-csi2.c | 66 ++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index 91cd70739e9d..af1c2469900c 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -314,12 +314,78 @@ static int adv748x_csi2_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, return ret; } +static int adv748x_csi2_routing_validate(struct adv748x_csi2 *tx, + struct v4l2_subdev_krouting *routing) +{ + struct v4l2_subdev_route *route; + + if (routing->num_routes != 1) { + dev_err(tx->state->dev, "Unsupported number of routes %u", + routing->num_routes); + return -EINVAL; + } + + route = &routing->routes[0]; + + if (route->sink_pad != ADV748X_CSI2_SINK || + route->source_pad != ADV748X_CSI2_SOURCE) { + dev_err(tx->state->dev, + "Routes should go from the sink to the source pads.\n"); + return -EINVAL; + } + + if (route->source_stream > 4) { + dev_err(tx->state->dev, "Unsupported source stream %u\n", + route->source_stream); + return -EINVAL; + } + + if (route->sink_stream != 0) { + dev_err(tx->state->dev, "Unsupported sink stream %u\n", + route->sink_stream); + return -EINVAL; + } + + return 0; +} + +static int adv748x_csi2_set_vc_with_routing(struct adv748x_csi2 *tx, + struct v4l2_subdev_krouting *routing) +{ + struct v4l2_subdev_route *route = &routing->routes[0]; + + return adv748x_csi2_set_virtual_channel(tx, route->source_stream); +} + +static int adv748x_csi2_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); + int ret; + + ret = adv748x_csi2_routing_validate(tx, routing); + if (ret) + return ret; + + ret = v4l2_subdev_set_routing(sd, state, routing); + if (ret) + return ret; + + if (which == V4L2_SUBDEV_FORMAT_TRY) + return 0; + + return adv748x_csi2_set_vc_with_routing(tx, routing); +} + static const struct v4l2_subdev_pad_ops adv748x_csi2_pad_ops = { .init_cfg = adv748x_csi2_init_cfg, .get_fmt = v4l2_subdev_get_fmt, .set_fmt = adv748x_csi2_set_format, .get_mbus_config = adv748x_csi2_get_mbus_config, .get_frame_desc = adv748x_csi2_get_frame_desc, + .set_routing = adv748x_csi2_set_routing, }; /* ----------------------------------------------------------------------------- From patchwork Wed Mar 16 15:46:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782895 X-Patchwork-Delegate: kieran@bingham.xyz 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 86D46C43219 for ; Wed, 16 Mar 2022 15:47:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357346AbiCPPsX (ORCPT ); Wed, 16 Mar 2022 11:48:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357349AbiCPPsW (ORCPT ); Wed, 16 Mar 2022 11:48:22 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CBB2D6D394; Wed, 16 Mar 2022 08:47:07 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 6ADB0240004; Wed, 16 Mar 2022 15:47:03 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 06/10] media: rcar-csi2: Add support for multiplexed streams Date: Wed, 16 Mar 2022 16:46:37 +0100 Message-Id: <20220316154641.511667-7-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Create and initialize the v4l2_subdev_state for the R-Car CSI-2 receiver in order to prepare to support multiplexed transmitters. Create the subdevice state with v4l2_subdev_init_finalize() and implement the init_cfg() operation to guarantee the state is initialized correctly with a set of default routes. Signed-off-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-csi2.c | 66 ++++++++++++++++++++- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index d48356d99590..f4786081e3a0 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -911,11 +911,65 @@ static int rcsi2_get_pad_format(struct v4l2_subdev *sd, return 0; } +static int rcsi2_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + /* + * Routing is fixed for this device: which stream goes to the next + * processing block (VIN) is controlled by link enablement between the + * CSI-2 and the VIN itself. + * + * In example, to route VC 3 to VIN1, as an example: "csi2:3 -> vin1:0" + * + * The routing table is then fixed as streams transmitted on VC x will + * be directed to csi:0/x and will be transmitted to VINs on media link + * csi2:x->vin:0. + */ + struct v4l2_subdev_route routes[] = { + { + .sink_pad = RCAR_CSI2_SINK, + .sink_stream = 0, + .source_pad = RCAR_CSI2_SOURCE_VC0, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + { + .sink_pad = RCAR_CSI2_SINK, + .sink_stream = 1, + .source_pad = RCAR_CSI2_SOURCE_VC1, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + { + .sink_pad = RCAR_CSI2_SINK, + .sink_stream = 2, + .source_pad = RCAR_CSI2_SOURCE_VC2, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + { + .sink_pad = RCAR_CSI2_SINK, + .sink_stream = 3, + .source_pad = RCAR_CSI2_SOURCE_VC3, + .source_stream = 0, + .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, + }, + }; + + struct v4l2_subdev_krouting routing = { + .num_routes = ARRAY_SIZE(routes), + .routes = routes, + }; + + return v4l2_subdev_set_routing(sd, state, &routing); +} + static const struct v4l2_subdev_video_ops rcar_csi2_video_ops = { .s_stream = rcsi2_s_stream, }; static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = { + .init_cfg = rcsi2_init_cfg, .set_fmt = rcsi2_set_pad_format, .get_fmt = rcsi2_get_pad_format, }; @@ -1537,7 +1591,8 @@ static int rcsi2_probe(struct platform_device *pdev) v4l2_set_subdevdata(&priv->subdev, &pdev->dev); snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s %s", KBUILD_MODNAME, dev_name(&pdev->dev)); - priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; + priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | + V4L2_SUBDEV_FL_MULTIPLEXED; priv->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; priv->subdev.entity.ops = &rcar_csi2_entity_ops; @@ -1558,14 +1613,20 @@ static int rcsi2_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); + ret = v4l2_subdev_init_finalize(&priv->subdev); + if (ret) + goto error_async; + ret = v4l2_async_register_subdev(&priv->subdev); if (ret < 0) - goto error_async; + goto error_subdev; dev_info(priv->dev, "%d lanes found\n", priv->lanes); return 0; +error_subdev: + v4l2_subdev_cleanup(&priv->subdev); error_async: v4l2_async_nf_unregister(&priv->notifier); v4l2_async_nf_cleanup(&priv->notifier); @@ -1582,6 +1643,7 @@ static int rcsi2_remove(struct platform_device *pdev) v4l2_async_nf_unregister(&priv->notifier); v4l2_async_nf_cleanup(&priv->notifier); v4l2_async_unregister_subdev(&priv->subdev); + v4l2_subdev_cleanup(&priv->subdev); pm_runtime_disable(&pdev->dev); From patchwork Wed Mar 16 15:46:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782897 X-Patchwork-Delegate: kieran@bingham.xyz 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 C0148C4167B for ; Wed, 16 Mar 2022 15:47:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357353AbiCPPsX (ORCPT ); Wed, 16 Mar 2022 11:48:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54240 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357348AbiCPPsW (ORCPT ); Wed, 16 Mar 2022 11:48:22 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D04786D39E; Wed, 16 Mar 2022 08:47:07 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 0488F240002; Wed, 16 Mar 2022 15:47:04 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 07/10] media: rcar-csi2: Move format to subdev state Date: Wed, 16 Mar 2022 16:46:38 +0100 Message-Id: <20220316154641.511667-8-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Move format handling to the v4l2_subdev state and store it per (pad, stream) combination. Now that the image format is stored in the subdev state, it can be accessed through v4l2_subdev_get_fmt() instead of open-coding it. Signed-off-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-csi2.c | 48 +++++++++------------ 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index f4786081e3a0..b06af1080b04 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -870,43 +870,35 @@ static int rcsi2_s_stream(struct v4l2_subdev *sd, int enable) } static int rcsi2_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_state *state, struct v4l2_subdev_format *format) { - struct rcar_csi2 *priv = sd_to_csi2(sd); - struct v4l2_mbus_framefmt *framefmt; + struct v4l2_mbus_framefmt *fmt; - mutex_lock(&priv->lock); + /* + * Format is propagated from sink streams to source streams, so + * disallow setting format on the source pads. + */ + if (format->pad > RCAR_CSI2_SINK) + return -EINVAL; if (!rcsi2_code_to_fmt(format->format.code)) format->format.code = rcar_csi2_formats[0].code; - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - priv->mf = format->format; - } else { - framefmt = v4l2_subdev_get_try_format(sd, sd_state, 0); - *framefmt = format->format; - } - - mutex_unlock(&priv->lock); - - return 0; -} - -static int rcsi2_get_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct rcar_csi2 *priv = sd_to_csi2(sd); + fmt = v4l2_subdev_state_get_stream_format(state, format->pad, + format->stream); + if (!fmt) + return -EINVAL; - mutex_lock(&priv->lock); + *fmt = format->format; - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) - format->format = priv->mf; - else - format->format = *v4l2_subdev_get_try_format(sd, sd_state, 0); + /* Propagate format to the other end of the route. */ + fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, + format->stream); + if (!fmt) + return -EINVAL; - mutex_unlock(&priv->lock); + *fmt = format->format; return 0; } @@ -971,7 +963,7 @@ static const struct v4l2_subdev_video_ops rcar_csi2_video_ops = { static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = { .init_cfg = rcsi2_init_cfg, .set_fmt = rcsi2_set_pad_format, - .get_fmt = rcsi2_get_pad_format, + .get_fmt = v4l2_subdev_get_fmt, }; static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = { From patchwork Wed Mar 16 15:46:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782898 X-Patchwork-Delegate: kieran@bingham.xyz 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 10146C433EF for ; Wed, 16 Mar 2022 15:47:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357348AbiCPPsZ (ORCPT ); Wed, 16 Mar 2022 11:48:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357354AbiCPPsY (ORCPT ); Wed, 16 Mar 2022 11:48:24 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97D6F6D39B; Wed, 16 Mar 2022 08:47:09 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id A8B86240012; Wed, 16 Mar 2022 15:47:06 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org, =?utf-8?q?N?= =?utf-8?q?iklas_S=C3=B6derlund?= Subject: [PATCH v2 08/10] media: rcar-csi2: Config by using the remote frame_desc Date: Wed, 16 Mar 2022 16:46:39 +0100 Message-Id: <20220316154641.511667-9-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Configure the CSI-2 receiver by inspecting the remote subdev frame_desc. Configure the link clock rate, field handling and CSI-2 Virtual Channel and DT filtering using the frame descriptor retrieved from the transmitter. This change also makes mandatory for any subdevice that operates with the R-Car CSI-2 receiver to implement the .get_frame_desc() operation. [based on a patch from] Signed-off-by: Niklas Söderlund [rework based on lates multistream support] Signed-off-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-csi2.c | 138 +++++++++++++++----- 1 file changed, 105 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index b06af1080b04..39545e631e42 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -70,10 +70,7 @@ struct rcar_csi2; #define FLD_REG 0x1c #define FLD_FLD_NUM(n) (((n) & 0xff) << 16) #define FLD_DET_SEL(n) (((n) & 0x3) << 4) -#define FLD_FLD_EN4 BIT(3) -#define FLD_FLD_EN3 BIT(2) -#define FLD_FLD_EN2 BIT(1) -#define FLD_FLD_EN BIT(0) +#define FLD_FLD_EN(n) BIT((n) & 0xf) /* Automatic Standby Control */ #define ASTBY_REG 0x20 @@ -471,6 +468,17 @@ static const struct rcar_csi2_format *rcsi2_code_to_fmt(unsigned int code) return NULL; } +static const struct rcar_csi2_format *rcsi2_datatype_to_fmt(unsigned int dt) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(rcar_csi2_formats); i++) + if (rcar_csi2_formats[i].datatype == dt) + return &rcar_csi2_formats[i]; + + return NULL; +} + enum rcar_csi2_pads { RCAR_CSI2_SINK, RCAR_CSI2_SOURCE_VC0, @@ -506,7 +514,6 @@ struct rcar_csi2 { int channel_vc[4]; struct mutex lock; /* Protects mf and stream_count. */ - struct v4l2_mbus_framefmt mf; int stream_count; unsigned short lanes; @@ -555,6 +562,32 @@ static int rcsi2_exit_standby(struct rcar_csi2 *priv) return 0; } +static int rcsi2_get_remote_frame_desc(struct rcar_csi2 *priv, + struct v4l2_mbus_frame_desc *fd) +{ + struct media_pad *pad; + int ret; + + if (!priv->remote) + return -ENODEV; + + pad = media_entity_remote_pad(&priv->pads[RCAR_CSI2_SINK]); + if (!pad) + return -ENODEV; + + ret = v4l2_subdev_call(priv->remote, pad, get_frame_desc, + pad->index, fd); + if (ret) + return ret; + + if (fd->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { + dev_err(priv->dev, "Frame desc do not describe CSI-2 link"); + return -EINVAL; + } + + return 0; +} + static int rcsi2_wait_phy_start(struct rcar_csi2 *priv, unsigned int lanes) { @@ -605,11 +638,14 @@ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps) return 0; } -static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, - unsigned int lanes) +static int rcsi2_calc_mbps(struct rcar_csi2 *priv, + struct v4l2_mbus_frame_desc *fd, unsigned int lanes) { + const struct v4l2_mbus_frame_desc_entry_csi2 *csi2_desc; + const struct rcar_csi2_format *format; struct v4l2_subdev *source; struct v4l2_ctrl *ctrl; + unsigned int i; u64 mbps; if (!priv->remote) @@ -625,12 +661,30 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp, return -EINVAL; } + /* Verify that all remote streams send the same datatype. */ + csi2_desc = NULL; + for (i = 0; i < fd->num_entries; i++) { + struct v4l2_mbus_frame_desc_entry_csi2 *stream_desc; + + stream_desc = &fd->entry[i].bus.csi2; + if (!csi2_desc) + csi2_desc = stream_desc; + + if (csi2_desc->dt != stream_desc->dt) { + dev_err(priv->dev, + "Remote streams with different DT: %u - %u\n", + csi2_desc->dt, stream_desc->dt); + return -EINVAL; + } + } + format = rcsi2_datatype_to_fmt(csi2_desc->dt); + /* * Calculate the phypll in mbps. * link_freq = (pixel_rate * bits_per_sample) / (2 * nr_of_lanes) * bps = link_freq * 2 */ - mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp; + mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * format->bpp; do_div(mbps, lanes * 1000000); return mbps; @@ -676,54 +730,65 @@ static int rcsi2_get_active_lanes(struct rcar_csi2 *priv, static int rcsi2_start_receiver(struct rcar_csi2 *priv) { - const struct rcar_csi2_format *format; + const struct v4l2_subdev_stream_configs *configs; u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0; + struct v4l2_subdev_state *state; + struct v4l2_mbus_frame_desc fd; unsigned int lanes; unsigned int i; int mbps, ret; - dev_dbg(priv->dev, "Input size (%ux%u%c)\n", - priv->mf.width, priv->mf.height, - priv->mf.field == V4L2_FIELD_NONE ? 'p' : 'i'); - - /* Code is validated in set_fmt. */ - format = rcsi2_code_to_fmt(priv->mf.code); - if (!format) - return -EINVAL; + /* Get information about multiplexed link. */ + ret = rcsi2_get_remote_frame_desc(priv, &fd); + if (ret) + return ret; - /* - * Enable all supported CSI-2 channels with virtual channel and - * data type matching. - * - * NOTE: It's not possible to get individual datatype for each - * source virtual channel. Once this is possible in V4L2 - * it should be used here. - */ - for (i = 0; i < priv->info->num_channels; i++) { + for (i = 0; i < fd.num_entries; i++) { + struct v4l2_mbus_frame_desc_entry *entry = &fd.entry[i]; u32 vcdt_part; if (priv->channel_vc[i] < 0) continue; - vcdt_part = VCDT_SEL_VC(priv->channel_vc[i]) | VCDT_VCDTN_EN | - VCDT_SEL_DTN_ON | VCDT_SEL_DT(format->datatype); + vcdt_part = VCDT_SEL_VC(priv->channel_vc[i]) | + VCDT_VCDTN_EN | VCDT_SEL_DTN_ON | + VCDT_SEL_DT(entry->bus.csi2.dt); /* Store in correct reg and offset. */ if (i < 2) vcdt |= vcdt_part << ((i % 2) * 16); else vcdt2 |= vcdt_part << ((i % 2) * 16); + + dev_dbg(priv->dev, "channel %u: VC = %d, datatype = 0x%x\n", + i, priv->channel_vc[i], entry->bus.csi2.dt); } - if (priv->mf.field == V4L2_FIELD_ALTERNATE) { - fld = FLD_DET_SEL(1) | FLD_FLD_EN4 | FLD_FLD_EN3 | FLD_FLD_EN2 - | FLD_FLD_EN; + /* + * Configure field handling inspecting the formats of the + * sink pad streams. + */ + state = v4l2_subdev_lock_and_get_active_state(&priv->subdev); + configs = &state->stream_configs; + for (i = 0; i < configs->num_configs; ++i) { + const struct v4l2_subdev_stream_config *config = configs->configs; - if (priv->mf.height == 240) + if (config->pad != RCAR_CSI2_SINK) + continue; + + if (config->fmt.field != V4L2_FIELD_ALTERNATE) + continue; + + fld |= FLD_DET_SEL(1); + fld |= FLD_FLD_EN(config->stream); + + /* PAL vs NTSC. */ + if (config->fmt.height == 240) fld |= FLD_FLD_NUM(0); else fld |= FLD_FLD_NUM(1); } + v4l2_subdev_unlock_state(state); /* * Get the number of active data lanes inspecting the remote mbus @@ -736,7 +801,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv) phycnt = PHYCNT_ENABLECLK; phycnt |= (1 << lanes) - 1; - mbps = rcsi2_calc_mbps(priv, format->bpp, lanes); + mbps = rcsi2_calc_mbps(priv, &fd, lanes); if (mbps < 0) return mbps; @@ -1019,6 +1084,13 @@ static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier, struct rcar_csi2 *priv = notifier_to_csi2(notifier); int pad; + if (!v4l2_subdev_has_op(subdev, pad, get_frame_desc)) { + dev_err(priv->dev, + "Subdev %s bound failed: missing get_frame_desc()\n", + subdev->name); + return -EINVAL; + } + pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode, MEDIA_PAD_FL_SOURCE); if (pad < 0) { From patchwork Wed Mar 16 15:46:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782900 X-Patchwork-Delegate: kieran@bingham.xyz 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 C540AC433FE for ; Wed, 16 Mar 2022 15:47:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1357363AbiCPPs3 (ORCPT ); Wed, 16 Mar 2022 11:48:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357356AbiCPPs3 (ORCPT ); Wed, 16 Mar 2022 11:48:29 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EEF3C6D39E for ; Wed, 16 Mar 2022 08:47:14 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 90F1B240014; Wed, 16 Mar 2022 15:47:08 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 09/10] media: rcar-csi2: Implement set_routing Date: Wed, 16 Mar 2022 16:46:40 +0100 Message-Id: <20220316154641.511667-10-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Add the set_routing() subdev operation to allow userspace to activate routes on the R-Car CSI-2 receiver. Routing for this device is fixed. Validate that the provided route respects it. Signed-off-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-csi2.c | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index 39545e631e42..0f1f667a7aee 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -968,6 +968,42 @@ static int rcsi2_set_pad_format(struct v4l2_subdev *sd, return 0; } +static int rcsi2_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, + struct v4l2_subdev_krouting *routing) +{ + unsigned int i; + int ret = 0; + + ret = v4l2_subdev_routing_validate(sd, routing, + V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); + if (ret) + return ret; + + /* + * Routing is fixed for this device. + * + * Only routes in the form of CSI2:0/x->CSI2:x+1/0 are allowed. + * + * We have anyway to implement set_routing to mark the route as active. + */ + for (i = 0; i < routing->num_routes; ++i) { + const struct v4l2_subdev_route *route = &routing->routes[i]; + unsigned int vc = route->sink_stream; + unsigned int pad = vc + 1; + + if (route->sink_pad != 0) + return -EINVAL; + + if (route->source_pad != pad || + route->source_stream != 0) + return -EINVAL; + } + + return v4l2_subdev_set_routing(sd, state, routing); +} + static int rcsi2_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *state) { @@ -1029,6 +1065,7 @@ static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = { .init_cfg = rcsi2_init_cfg, .set_fmt = rcsi2_set_pad_format, .get_fmt = v4l2_subdev_get_fmt, + .set_routing = rcsi2_set_routing, }; static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = { From patchwork Wed Mar 16 15:46:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 12782899 X-Patchwork-Delegate: kieran@bingham.xyz 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 C511BC433FE for ; Wed, 16 Mar 2022 15:47:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239043AbiCPPs2 (ORCPT ); Wed, 16 Mar 2022 11:48:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1357363AbiCPPs1 (ORCPT ); Wed, 16 Mar 2022 11:48:27 -0400 Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [IPv6:2001:4b98:dc4:8::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7F3F6D38E; Wed, 16 Mar 2022 08:47:12 -0700 (PDT) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id 1C38D240002; Wed, 16 Mar 2022 15:47:09 +0000 (UTC) From: Jacopo Mondi To: niklas.soderlund@ragnatech.se, laurent.pinchart@ideasonboard.com Cc: Jacopo Mondi , tomi.valkeinen@ideasonboard.com, linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 10/10] media: rcar-vin: Support state-aware transmitters Date: Wed, 16 Mar 2022 16:46:41 +0100 Message-Id: <20220316154641.511667-11-jacopo+renesas@jmondi.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220316154641.511667-1-jacopo+renesas@jmondi.org> References: <20220316154641.511667-1-jacopo+renesas@jmondi.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org The VIN driver calls get_fmt() on the remove subdev to validate its format. Now that the R-Car CSI-2 driver are moved to be state-aware subdevices they need their active state when calling operations. Use the newly introduced v4l2_subdev_call_state_active() from v4l2-subdev-legacy.h. Signed-off-by: Jacopo Mondi --- drivers/media/platform/rcar-vin/rcar-dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index e08d4ca28725..68c192ea7cb5 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "rcar-vin.h" @@ -1140,7 +1141,7 @@ static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd, }; fmt.pad = pad->index; - if (v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt)) + if (v4l2_subdev_call_state_active(sd, pad, get_fmt, &fmt)) return -EPIPE; switch (fmt.format.code) {