Devicetree
 help / color / mirror / Atom feed
From: Ali Rouhi <arouhi@sitime.com>
To: "jiri@resnulli.us" <jiri@resnulli.us>
Cc: "vadim.fedorenko@linux.dev" <vadim.fedorenko@linux.dev>,
	"arkadiusz.kubalewski@intel.com" <arkadiusz.kubalewski@intel.com>,
	"ivecera@redhat.com" <ivecera@redhat.com>,
	"robh@kernel.org" <robh@kernel.org>,
	"krzk+dt@kernel.org" <krzk+dt@kernel.org>,
	"conor+dt@kernel.org" <conor+dt@kernel.org>,
	"cjubran@nvidia.com" <cjubran@nvidia.com>,
	"pabeni@redhat.com" <pabeni@redhat.com>,
	"Oleg.Zadorozhnyi@devoxsoftware.com"
	<Oleg.Zadorozhnyi@devoxsoftware.com>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Ali Rouhi <arouhi@sitime.com>
Subject: [PATCH net-next v9 15/15] dpll: sit9531x: allow the device tree to override two board facts
Date: Tue, 15 Sep 2026 00:00:24 +0000	[thread overview]
Message-ID: <20260915000015.80480-16-arouhi@sitime.com> (raw)
In-Reply-To: <20260915000015.80480-1-arouhi@sitime.com>

From: Oleg Zadorozhnyi <Oleg.Zadorozhnyi@devoxsoftware.com>

Two things the driver reads from the chip can be wrong on a board, and
neither has anywhere else to come from.

The VCO frequency is derived from the feedback divider, which is exact
while the loop runs but not while a PLL sits in free-run with a divider
the configuration never programmed; a board that knows its own VCO can
state it.  The output-to-PLL routing is read from the output map
registers, which describe what the loaded configuration did -- and a board
whose outputs are fanned out differently from what those registers imply
can state that too.

Both are optional.  Absent the properties the driver behaves exactly as
before, deriving one and reading the other.

Signed-off-by: Oleg Zadorozhnyi <Oleg.Zadorozhnyi@devoxsoftware.com>
Assisted-by: Claude:claude-4-opus [chat]
Signed-off-by: Ali Rouhi <arouhi@sitime.com>
---
 drivers/dpll/sit9531x/core.c | 104 +++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/drivers/dpll/sit9531x/core.c b/drivers/dpll/sit9531x/core.c
index b15859890caa..51f7d8a4ea44 100644
--- a/drivers/dpll/sit9531x/core.c
+++ b/drivers/dpll/sit9531x/core.c
@@ -3862,6 +3862,108 @@ static u64 sit9531x_derive_clock_id(struct sit9531x_dev *sitdev)
 	return clkid;
 }
 
+/*
+ * Does an Fvco fall in the band the given PLL runs in?
+ *
+ * The two bands are disjoint, and which one applies is fixed per PLL, so a
+ * single envelope from the bottom of the low band to the top of the high
+ * one would accept both the ~1 GHz gap between them and a rate belonging to
+ * the other PLL's band.
+ */
+static bool sit9531x_fvco_in_band(u8 pll_idx, u64 fvco)
+{
+	if (pll_idx == 1 || pll_idx == 3)
+		return fvco >= SIT9531X_FVCO_HIGHBAND_MIN &&
+		       fvco <= SIT9531X_FVCO_HIGHBAND_MAX;
+
+	return fvco >= SIT9531X_FVCO_LOWBAND_MIN &&
+	       fvco <= SIT9531X_FVCO_LOWBAND_MAX;
+}
+
+/*
+ * Board-config overrides for fixed efuse/blob routing the chip registers do
+ * not describe unambiguously.  Absent properties leave pll_fvco[] zeroed
+ * (derive from DIVN) and out_pll_map_valid false (use the OUT_MAP registers).
+ */
+static void sit9531x_parse_board_config(struct sit9531x_dev *sitdev)
+{
+	u32 map[SIT9531X_MAX_OUTPUTS];
+	int n, i, rc;
+
+	if (device_property_present(sitdev->dev, "sitime,pll-fvco")) {
+		rc = device_property_read_u64_array(sitdev->dev,
+						    "sitime,pll-fvco",
+						    sitdev->pll_fvco,
+						    SIT9531X_NUM_PLLS);
+		if (rc) {
+			dev_warn(sitdev->dev,
+				 "invalid sitime,pll-fvco (%d), ignoring\n",
+				 rc);
+			memset(sitdev->pll_fvco, 0, sizeof(sitdev->pll_fvco));
+		}
+
+		/*
+		 * The override is used verbatim by the divider math, so an
+		 * implausible value (units typo, wrong cell count worked
+		 * around with zeros) must not silently misprogram DIVO.
+		 * Anything outside both VCO bands is dropped with a warning
+		 * rather than trusted.
+		 */
+		for (i = 0; i < SIT9531X_NUM_PLLS; i++) {
+			u64 f = sitdev->pll_fvco[i];
+
+			if (f && !sit9531x_fvco_in_band(i, f)) {
+				dev_warn(sitdev->dev,
+					 "PLL%c Fvco override %llu Hz is outside the band that PLL runs in, ignoring\n",
+					 'A' + i, f);
+				sitdev->pll_fvco[i] = 0;
+			}
+		}
+	}
+
+	if (!device_property_present(sitdev->dev, "sitime,output-pll-map"))
+		return;
+
+	/*
+	 * Any 1..MAX_OUTPUTS length is accepted so the 8-output SiT95317 need
+	 * not pad to 12; variant detection has not run yet and entries past
+	 * the detected num_outputs are never indexed.  Trailing entries of a
+	 * short map must read as unmapped rather than 0 (== PLLA), which
+	 * would mark unrouted outputs active in sit9531x_out_state_fetch().
+	 */
+	memset(sitdev->out_pll_map, SIT9531X_OUT_PLL_UNMAPPED,
+	       sizeof(sitdev->out_pll_map));
+
+	n = device_property_count_u32(sitdev->dev, "sitime,output-pll-map");
+	if (n <= 0 || n > SIT9531X_MAX_OUTPUTS ||
+	    device_property_read_u32_array(sitdev->dev, "sitime,output-pll-map",
+					   map, n)) {
+		dev_warn(sitdev->dev,
+			 "invalid sitime,output-pll-map, ignoring\n");
+		return;
+	}
+
+	/*
+	 * The binding allows only 0-3 and 255 per entry.  A stray value
+	 * would silently unroute an output (m >= SIT9531X_NUM_PLLS reads
+	 * as unmapped in sit9531x_out_state_fetch()), so reject the whole
+	 * property loudly instead.
+	 */
+	for (i = 0; i < n; i++) {
+		if (map[i] >= SIT9531X_NUM_PLLS &&
+		    map[i] != SIT9531X_OUT_PLL_UNMAPPED) {
+			dev_warn(sitdev->dev,
+				 "sitime,output-pll-map entry %d is %u (must be 0-3 or 255), ignoring map\n",
+				 i, map[i]);
+			return;
+		}
+	}
+
+	for (i = 0; i < n; i++)
+		sitdev->out_pll_map[i] = map[i];
+	sitdev->out_pll_map_valid = true;
+}
+
 int sit9531x_dev_probe(struct sit9531x_dev *sitdev)
 {
 	struct clk *xtal_clk;
@@ -3906,6 +4008,8 @@ int sit9531x_dev_probe(struct sit9531x_dev *sitdev)
 	if (sitdev->reset_gpio)
 		fsleep(10000);	/* internal boot after release */
 
+	sit9531x_parse_board_config(sitdev);
+
 	rc = sit9531x_read_variant_id(sitdev, &variant_id);
 	if (rc)
 		return rc;
-- 
2.39.2 (Apple Git-143)


  parent reply	other threads:[~2026-09-15  0:00 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15  0:00 [PATCH net-next v9 00/15] dpll: add SiTime SiT9531x DPLL clock driver Ali Rouhi
2026-09-15  0:00 ` [PATCH net-next v9 01/15] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-09-15  0:00 ` [PATCH net-next v9 02/15] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 03/15] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-09-17  8:42   ` Ivan Vecera
2026-09-21 20:49     ` Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 04/15] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-09-17  9:42   ` Ivan Vecera
2026-09-21 20:49     ` Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 05/15] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 06/15] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 07/15] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 08/15] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 10/15] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17  9:55   ` Ivan Vecera
2026-09-21 20:49     ` Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 09/15] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 11/15] dpll: sit9531x: add support to get and set esync on pins Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 12/15] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 14/15] dpll: sit9531x: model the inter-PLL sync net as a pair of pins Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` [PATCH net-next v9 13/15] dpll: sit9531x: add support to get fractional frequency offset Ali Rouhi
2026-09-16  0:00   ` sashiko-bot
2026-09-17 15:01   ` netdev-bot+sashiko
2026-09-15  0:00 ` Ali Rouhi [this message]
2026-09-17 15:02   ` [PATCH net-next v9 15/15] dpll: sit9531x: allow the device tree to override two board facts netdev-bot+sashiko

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=20260915000015.80480-16-arouhi@sitime.com \
    --to=arouhi@sitime.com \
    --cc=Oleg.Zadorozhnyi@devoxsoftware.com \
    --cc=arkadiusz.kubalewski@intel.com \
    --cc=cjubran@nvidia.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ivecera@redhat.com \
    --cc=jiri@resnulli.us \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=vadim.fedorenko@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox