All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacopo Mondi <jacopo+renesas@jmondi.org>
To: kieran.bingham+renesas@ideasonboard.com,
	laurent.pinchart+renesas@ideasonboard.com,
	niklas.soderlund+renesas@ragnatech.se, geert@linux-m68k.org
Cc: Jacopo Mondi <jacopo+renesas@jmondi.org>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Sakari Ailus <sakari.ailus@iki.fi>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Subject: [PATCH v4 17/17] media: gmsl: Reimplement initialization sequence
Date: Mon, 12 Apr 2021 11:34:51 +0200	[thread overview]
Message-ID: <20210412093451.14198-18-jacopo+renesas@jmondi.org> (raw)
In-Reply-To: <20210412093451.14198-1-jacopo+renesas@jmondi.org>

The current probe() procedure of the RDACM20 and RDACM21 GMSL cameras is
performed with the embedded MAX9271 serializer's noise immunity
threshold disabled. Once the camera has been initialized by probing the
embedded chips, the threshold is enabled and then compensated on the
deserializer's side by increasing the reverse channel signal amplitude
once all cameras have bound.

The probe routine is thus run without noise immunity activated which
in noisy environment conditions makes the probe sequence less reliable as
the chips configuration requires a relatively high amount of i2c
transactions.

Break chip initialization in two:
- At probe time only configure the serializer's reverse channel with
  noise immunity activated, to reduce the number of transactions
  performed without noise immunity protection enabled
- Move the chips initialization to the .init() core subdev operation
  called by the deserializer after all camera have probed and
  have increased their noise immunity threshold

The initialization routine looks like the following:

            MAX9286                  RDACM20/21

            probe()
               |
               ---------------------> |
                                      probe() {
                                         enable_threshold()
                                      }
               |<--------------------|
            v4l2 async bound {
                compensate_amplitude()
                call subdev init()
               |-------------------->|
                                     init() {
                                         access camera registers()
                                    }
               |<-------------------
            }

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
---
 drivers/media/i2c/max9286.c | 19 +++++++++---
 drivers/media/i2c/rdacm20.c | 59 ++++++++++++++++++++++---------------
 drivers/media/i2c/rdacm21.c | 59 ++++++++++++++++++++++---------------
 3 files changed, 87 insertions(+), 50 deletions(-)

diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index e1c7173f2d00..aafe55f30a0a 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -563,17 +563,28 @@ static int max9286_notify_bound(struct v4l2_async_notifier *notifier,
 	if (priv->bound_sources != priv->source_mask)
 		return 0;

+	/*
+	 * Initialize all the remote camera. Increase the channel amplitude
+	 * to compensate for the remote noise immunity threshold.
+	 */
+	max9286_reverse_channel_setup(priv, MAX9286_REV_AMP_HIGH);
+	for_each_source(priv, source) {
+		ret = v4l2_subdev_call(source->sd, core, init, 0);
+		if (ret) {
+			dev_err(&priv->client->dev,
+				"Failed to initialize camera device %u\n",
+				index);
+			return ret;
+		}
+	}
+
 	/*
 	 * All enabled sources have probed and enabled their reverse control
 	 * channels:
-	 *
-	 * - Increase the reverse channel amplitude to compensate for the
-	 *   remote ends high threshold
 	 * - Verify all configuration links are properly detected
 	 * - Disable auto-ack as communication on the control channel are now
 	 *   stable.
 	 */
-	max9286_reverse_channel_setup(priv, MAX9286_REV_AMP_HIGH);
 	max9286_check_config_link(priv, priv->source_mask);
 	max9286_configure_i2c(priv, false);

diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c
index cb725c2778c0..ce3e05ca6389 100644
--- a/drivers/media/i2c/rdacm20.c
+++ b/drivers/media/i2c/rdacm20.c
@@ -435,33 +435,12 @@ static int rdacm20_get_fmt(struct v4l2_subdev *sd,
 	return 0;
 }

-static const struct v4l2_subdev_video_ops rdacm20_video_ops = {
-	.s_stream	= rdacm20_s_stream,
-};
-
-static const struct v4l2_subdev_pad_ops rdacm20_subdev_pad_ops = {
-	.enum_mbus_code = rdacm20_enum_mbus_code,
-	.get_fmt	= rdacm20_get_fmt,
-	.set_fmt	= rdacm20_get_fmt,
-};
-
-static const struct v4l2_subdev_ops rdacm20_subdev_ops = {
-	.video		= &rdacm20_video_ops,
-	.pad		= &rdacm20_subdev_pad_ops,
-};
-
-static int rdacm20_initialize(struct rdacm20_device *dev)
+static int rdacm20_init(struct v4l2_subdev *sd, unsigned int val)
 {
+	struct rdacm20_device *dev = sd_to_rdacm20(sd);
 	unsigned int retry = 3;
 	int ret;

-	max9271_wake_up(&dev->serializer);
-
-	/* Serial link disabled during config as it needs a valid pixel clock. */
-	ret = max9271_set_serial_link(&dev->serializer, false);
-	if (ret)
-		return ret;
-
 	/*
 	 *  Ensure that we have a good link configuration before attempting to
 	 *  identify the device.
@@ -549,6 +528,40 @@ static int rdacm20_initialize(struct rdacm20_device *dev)

 	dev_info(dev->dev, "Identified RDACM20 camera module\n");

+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops rdacm20_core_ops = {
+	.init           = rdacm20_init,
+};
+
+static const struct v4l2_subdev_video_ops rdacm20_video_ops = {
+	.s_stream	= rdacm20_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops rdacm20_subdev_pad_ops = {
+	.enum_mbus_code = rdacm20_enum_mbus_code,
+	.get_fmt	= rdacm20_get_fmt,
+	.set_fmt	= rdacm20_get_fmt,
+};
+
+static const struct v4l2_subdev_ops rdacm20_subdev_ops = {
+	.core		= &rdacm20_core_ops,
+	.video		= &rdacm20_video_ops,
+	.pad		= &rdacm20_subdev_pad_ops,
+};
+
+static int rdacm20_initialize(struct rdacm20_device *dev)
+{
+	int ret;
+
+	max9271_wake_up(&dev->serializer);
+
+	/* Serial link disabled during config as it needs a valid pixel clock. */
+	ret = max9271_set_serial_link(&dev->serializer, false);
+	if (ret)
+		return ret;
+
 	/*
 	 * Set reverse channel high threshold to increase noise immunity.
 	 *
diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c
index 43c41cb800a4..7232722e59cd 100644
--- a/drivers/media/i2c/rdacm21.c
+++ b/drivers/media/i2c/rdacm21.c
@@ -315,21 +315,6 @@ static int rdacm21_get_fmt(struct v4l2_subdev *sd,
 	return 0;
 }

-static const struct v4l2_subdev_video_ops rdacm21_video_ops = {
-	.s_stream	= rdacm21_s_stream,
-};
-
-static const struct v4l2_subdev_pad_ops rdacm21_subdev_pad_ops = {
-	.enum_mbus_code = rdacm21_enum_mbus_code,
-	.get_fmt	= rdacm21_get_fmt,
-	.set_fmt	= rdacm21_get_fmt,
-};
-
-static const struct v4l2_subdev_ops rdacm21_subdev_ops = {
-	.video		= &rdacm21_video_ops,
-	.pad		= &rdacm21_subdev_pad_ops,
-};
-
 static void ov10640_power_up(struct rdacm21_device *dev)
 {
 	/* Enable GPIO0#0 (reset) and GPIO1#0 (pwdn) as output lines. */
@@ -470,17 +455,11 @@ static int ov490_initialize(struct rdacm21_device *dev)
 	return 0;
 }

-static int rdacm21_initialize(struct rdacm21_device *dev)
+static int rdacm21_init(struct v4l2_subdev *sd, unsigned int val)
 {
+	struct rdacm21_device *dev = sd_to_rdacm21(sd);
 	int ret;

-	max9271_wake_up(&dev->serializer);
-
-	/* Enable reverse channel and disable the serial link. */
-	ret = max9271_set_serial_link(&dev->serializer, false);
-	if (ret)
-		return ret;
-
 	/* Configure I2C bus at 105Kbps speed and configure GMSL. */
 	ret = max9271_configure_i2c(&dev->serializer,
 				    MAX9271_I2CSLVSH_469NS_234NS |
@@ -531,6 +510,40 @@ static int rdacm21_initialize(struct rdacm21_device *dev)
 	if (ret)
 		return ret;

+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops rdacm21_core_ops = {
+	.init		= rdacm21_init,
+};
+
+static const struct v4l2_subdev_video_ops rdacm21_video_ops = {
+	.s_stream	= rdacm21_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops rdacm21_subdev_pad_ops = {
+	.enum_mbus_code = rdacm21_enum_mbus_code,
+	.get_fmt	= rdacm21_get_fmt,
+	.set_fmt	= rdacm21_get_fmt,
+};
+
+static const struct v4l2_subdev_ops rdacm21_subdev_ops = {
+	.core		= &rdacm21_core_ops,
+	.video		= &rdacm21_video_ops,
+	.pad		= &rdacm21_subdev_pad_ops,
+};
+
+static int rdacm21_initialize(struct rdacm21_device *dev)
+{
+	int ret;
+
+	max9271_wake_up(&dev->serializer);
+
+	/* Enable reverse channel and disable the serial link. */
+	ret = max9271_set_serial_link(&dev->serializer, false);
+	if (ret)
+		return ret;
+
 	/*
 	 * Set reverse channel high threshold to increase noise immunity.
 	 *
--
2.31.1


      parent reply	other threads:[~2021-04-12  9:52 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-12  9:34 [PATCH v4 00/17] media: gmsl: Reliability improvements Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 01/17] media: i2c: max9286: Adjust parameters indent Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 02/17] media: i2c: max9286: Rename reverse_channel_mv Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 03/17] media: i2c: max9286: Cache channel amplitude Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 04/17] media: i2c: max9286: Define high " Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 05/17] media: i2c: max9286: Rework comments in .bound() Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 06/17] media: i2c: max9271: Check max9271_write() return Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 07/17] media: i2c: max9271: Introduce wake_up() function Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 08/17] media: i2c: rdacm21: Add dealy after OV490 reset Jacopo Mondi
2021-04-14 16:49   ` Kieran Bingham
2021-04-14 23:10   ` Laurent Pinchart
2021-04-12  9:34 ` [PATCH v4 09/17] media: i2c: rdacm21: Fix OV10640 powerup Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 10/17] media: i2c: rdacm21: Power up OV10640 before OV490 Jacopo Mondi
2021-04-14 23:13   ` Laurent Pinchart
2021-04-12  9:34 ` [PATCH v4 11/17] media: i2c: rdacm20: Enable noise immunity Jacopo Mondi
2021-04-14 23:14   ` Laurent Pinchart
2021-04-12  9:34 ` [PATCH v4 12/17] media: i2c: rdacm20: Embed 'serializer' field Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 13/17] media: i2c: rdacm20: Report camera module name Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 14/17] media: i2c: rdacm20: Check return values Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 15/17] media: i2c: rdacm20: Re-work ov10635 reset Jacopo Mondi
2021-04-12  9:34 ` [PATCH v4 16/17] media: v4l2-subdev: De-deprecate init() subdev op Jacopo Mondi
2021-04-15 12:31   ` Jacopo Mondi
2021-06-14  7:34   ` Jacopo Mondi
2021-06-14  8:51   ` Hans Verkuil
2021-06-14  9:45     ` Jacopo Mondi
2021-06-14  9:55       ` Hans Verkuil
2021-06-14 15:17         ` Jacopo Mondi
2021-04-12  9:34 ` Jacopo Mondi [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210412093451.14198-18-jacopo+renesas@jmondi.org \
    --to=jacopo+renesas@jmondi.org \
    --cc=geert@linux-m68k.org \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=kieran.bingham+renesas@ideasonboard.com \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=sakari.ailus@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.