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>,
"kuba@kernel.org" <kuba@kernel.org>,
"pabeni@redhat.com" <pabeni@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>,
"Oleg.Zadorozhnyi@devoxsoftware.com"
<Oleg.Zadorozhnyi@devoxsoftware.com>,
"prabhakar.mahadev-lad.rj@bp.renesas.com"
<prabhakar.mahadev-lad.rj@bp.renesas.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>
Subject: [PATCH net-next v15 00/13] dpll: add SiTime SiT9531x DPLL clock driver
Date: Tue, 10 Nov 2026 20:26:09 +0000 [thread overview]
Message-ID: <20261110202607.55744-1-arouhi@sitime.com> (raw)
This series adds a DPLL subsystem driver for the SiTime SiT95316 and
SiT95317 I2C clock generators. Each device integrates four PLLs with
automatic reference selection and on-chip TDC phase-offset measurement,
and is used for synchronization in telecom, networking, and data-center
timing.
Patch 1 changes the DPLL core: phase_offset_get and phase_adjust_get
may return -ENODATA, and the core then leaves the attribute out of the
pin message instead of failing the dump. Patches 11 and 12 use it. The
rest is the device-tree binding, the driver under
drivers/dpll/sit9531x/, and the MAINTAINERS entry.
v1: https://lore.kernel.org/netdev/20260511211143.19792-1-arouhi@sitime.com/
v2: https://lore.kernel.org/netdev/20260520191943.73938-1-arouhi@sitime.com/
v3: https://lore.kernel.org/netdev/20260731180951.65725-1-arouhi@sitime.com/
v4: https://lore.kernel.org/netdev/20260806232439.27551-1-arouhi@sitime.com/
v5: https://lore.kernel.org/netdev/20260810230439.22866-1-arouhi@sitime.com/
v6: https://lore.kernel.org/netdev/20260812175337.18155-1-arouhi@sitime.com/
v7: https://lore.kernel.org/netdev/20260815221919.64226-1-arouhi@sitime.com/
v8: https://lore.kernel.org/netdev/20260902214030.20955-1-arouhi@sitime.com/
v9: https://lore.kernel.org/netdev/20260915000015.80480-1-arouhi@sitime.com/
v10: https://lore.kernel.org/netdev/20260921201108.42676-1-arouhi@sitime.com/
v11: https://lore.kernel.org/netdev/20260930233714.87679-1-arouhi@sitime.com/
v12: https://lore.kernel.org/netdev/20261009183151.78497-1-arouhi@sitime.com/
v13: https://lore.kernel.org/netdev/20261013224131.27149-1-arouhi@sitime.com/
v14: https://lore.kernel.org/netdev/20261016005823.13690-1-arouhi@sitime.com/
Most of the changes in v15 answer the netdev AI reviewer's findings on
v14 and further runs of the same reviewer on drafts of this revision.
Each fix is folded into the patch that introduces the code. The design
section below states once the decisions those findings kept returning
to. One v14 finding doesn't hold: the DIVN fraction read is not
byte-reversed, because the part stores the fraction least significant
byte first, and the kernel-doc of sit9531x_divn_static() now says so.
Rob Herring's Reviewed-by on the binding is carried on patch 3. One
sentence of its description changed since v14: it now lists the die
outputs the SiT95317 bonds out and the names its datasheet gives them.
Ivan Vecera's Reviewed-by on v14 patches 4, 6, 7, 9 and 11 is not
carried, since each of those patches changed.
Oleg and I used LLM coding assistants to write parts of the driver code
and of the commit messages, and reviewed and revised what they
produced. v14 marked each such patch with Assisted-by: LLM; v15 drops
the tag following commit 1e035297ffda ("docs: remove Assisted-by
references").
1 dpll core: omit phase attributes a driver has no value for
2 bindings: vendor prefix
3 bindings: the device schema
4 basic support: paged regmap, variant detection, probe
5 DPLL types and pin properties from system firmware
6 register the DPLL devices and pins, and keep their state
7 input pin state and operational state on a DPLL
8 input pin priority
9 pin frequency, both directions
10 output pin state (mute)
11 output phase adjust
12 phase offset through the TDC
13 the inter-PLL sync line as a pair of pins
The two bindings patches come before the driver, so the driver never
matches on a compatible string before the schema that describes it is
in the tree.
Every patch builds with only the earlier patches applied: no patch
calls something a later patch introduces. This was re-checked for this
posting patch by patch with W=1 and with sparse, and kernel-doc -Wall
is clean on every driver patch. checkpatch --strict at 80 columns is
clean except for the "does MAINTAINERS need updating?" hint on patches
5 and 6, which add files under drivers/dpll/sit9531x/; patch 4 already
covers that directory with an F: entry.
Design decisions and hardware assumptions
=========================================
Configuration ownership. The part runs a configuration it loaded before
the driver binds, from efuse or from a blob the board applies. The
driver reads that configuration and never resets the part, rewrites
loop-filter coefficients or touches a register the configurator sets.
What it changes at runtime is what the DPLL API asks it to change:
input selection and priorities, output enables, rates and delays, the
inter-PLL sync source. Where the loaded configuration puts a PLL
outside what the API can express, the driver reports what the part
does and withholds the control rather than reconfiguring the part:
a PLL in manual input select is reported in MANUAL mode with no
selection or priority setters; a half-armed fast lock registers without
the attribute. The driver does not write the part at probe or resume,
with one exception below.
Automatic selection. A PLL whose profile arbitrates by priority is
reported AUTOMATIC: the part picks among the listed inputs by the
priorities it is given, and the driver keeps the table and the active
selection register in step with the priorities it was asked for. When
a PLL that lost every input sits in holdover and an input returns, the
driver doesn't wait for the part: it re-selects the PLL when an input
edge is sampled, and once on the first sample after probe or resume,
where no edge could have been seen. Whether a PLL returns to a
higher-priority input that recovers is the profile's REVERT_EN; the
DPLL API has no attribute for revertive selection and no driver
exposes its setting.
Qualification. The driver selects on loss of signal and reports ACTIVE
from it. The frequency-drift monitors are reported as a qualification
failure on an input the PLL is not on; an input the part keeps tracking
while its drift flag is set is reported as the part reports it.
Register access. The part shows one 256-byte page at a time, selected
through the register at offset 0xFF of every page and latched on the
STOP of that write. The regmap is that flat window; the driver selects
the page itself under its own lock, remembers the page it selected,
forgets it on any failed transfer and on resume, and re-selects on the
next access. No other regmap user, debugfs included, can move the
page. The I2C_SLAVE_FORCE path of i2c-dev is the
documented debugging override and is not defended against.
Clocks and supplies. The XO is taken through
devm_clk_get_optional_enabled() for its rate and to hold a reference,
so clk_disable_unused() cannot gate an XO the loaded configuration runs
from; the enable is not what starts the XO, and the reference goes back
to the provider on unbind or a failed probe. A clock or a rail the part
must keep without a driver bound is the provider's property
(CLK_IS_CRITICAL, regulator-always-on), as for any part that is
configured before Linux runs.
VCO rate. The VCO rate is derived as Fref * DIVN, the XO rate (with the
doubler) times the PLL page's static divider, which is how the register
map defines the inner loop; the binding describes the XO and no other
reference. The estimate is bounded: a product outside the PLL's VCO
band is reported once and refuses every frequency request, and inside
the band a rate is programmed only when the estimated Fvco is a whole
multiple of it.
Output pads. The driver reads the pad-enable bits only to tell a CMOS
output from a differential one, and mutes a CMOS output by forcing both
pads off. It reports an output muted when both pads are forced off, the
only state its own mute produces; a profile that forces one pad is
reported as driven. The debug key gates the Force registers only; the
directive registers that commit a programming sequence are written
without it, as the configurator's scripts do.
Phase offset. The measurement compares the selected input against a
physical output the PLL drives, as the documented procedure does, so a
PLL with no routed, enabled output reports no phase offset (the
attribute is omitted). A sample taken while the input disappears is
rejected when the monitor reports the loss afterwards.
Notifications. The driver sends again a change notification it could
not build for a change it made itself (a failed request that moved
hardware, a read-through that moved a value, the sync-line source). It
does not retry the notifications the core sends after a successful
request: dpll_pin_prio_set() and dpll_pin_state_set() discard that
result for every driver, and a retry in the driver would notify the
change twice.
Recovery after a failed write. A sequence that fails part-way leaves
the part in a state the driver records as pending: a priority table
not latched, a forced holdover to release, a delay to re-time, an
output realignment, a debug window to close, a sync-line page half
written. The poll retries each until the write succeeds; unbind retries
once more and warns about what is left; resume drops the pending delay
and realignment, since the registers it re-reads describe the part
after a suspend that may have reloaded it, and keeps the sync-line
ownership records until a retry resolves them.
Changes in v15:
- Rebased onto net-next after the v7.4 merge window.
- New patch 1 in the DPLL core, described above.
- Patch 3: the description names the die outputs the SiT95317 bonds
out.
- Patch 6: a PLL in manual input select is reported MANUAL. A PLL
whose status read failed is marked stale and reports UNLOCKED
until a read succeeds.
- Patch 7: the poll re-selects a PLL that fell into holdover by
itself when an input returns, and once after probe or resume.
- Patches 7 to 13: a sequence that fails part-way is recorded as
pending and retried, as described under Recovery after a failed
write.
- Patch 11: phase adjust on an output no PLL drives fails with
-ENODEV; it was computed against PLL A's VCO rate. A profile delay
the s32 attribute cannot carry leaves the attribute out.
- Patch 12: a pin with no measurement returns -ENODATA instead of
zero, and a sample taken while the lane lost its signal is
rejected.
- Patch 13: resume re-reads the owner of the sync line, the output
mutes and the output delays from the part.
- Decisions that held across several patches moved out of the commit
messages into the design section above, and each message now says
only what its patch adds.
- Comments rewritten in the style of the zl3073x driver: a one-line
label, a register fact, a datasheet or procedure citation, a
locking rule, or the reason an order of operations matters.
Ali Rouhi (2):
dt-bindings: vendor-prefixes: add SiTime Corporation
dt-bindings: dpll: add SiTime SiT95316 clock generator
Oleg Zadorozhnyi (11):
dpll: omit pin phase attributes the driver has no value for
dpll: add basic SiTime SiT9531x support
dpll: sit9531x: read DPLL types and pin properties from system
firmware
dpll: sit9531x: register DPLL devices and pins
dpll: sit9531x: implement input pin state on a DPLL
dpll: sit9531x: add support to get and set priority on input pins
dpll: sit9531x: add support to get and set frequency on pins
dpll: sit9531x: implement output pin state on a DPLL
dpll: sit9531x: add support to adjust output phase
dpll: sit9531x: add support to get phase offset on the connected input
pin
dpll: sit9531x: model the inter-PLL sync line as a pair of pins
.../bindings/dpll/sitime,sit95316.yaml | 214 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
MAINTAINERS | 7 +
drivers/dpll/Kconfig | 2 +
drivers/dpll/Makefile | 1 +
drivers/dpll/dpll_netlink.c | 14 +-
drivers/dpll/sit9531x/Kconfig | 17 +
drivers/dpll/sit9531x/Makefile | 4 +
drivers/dpll/sit9531x/core.c | 5148 +++++++++++++++++
drivers/dpll/sit9531x/core.h | 433 ++
drivers/dpll/sit9531x/dpll.c | 1496 +++++
drivers/dpll/sit9531x/dpll.h | 63 +
drivers/dpll/sit9531x/prop.c | 365 ++
drivers/dpll/sit9531x/prop.h | 37 +
drivers/dpll/sit9531x/regs.h | 351 ++
15 files changed, 8150 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/dpll/sitime,sit95316.yaml
create mode 100644 drivers/dpll/sit9531x/Kconfig
create mode 100644 drivers/dpll/sit9531x/Makefile
create mode 100644 drivers/dpll/sit9531x/core.c
create mode 100644 drivers/dpll/sit9531x/core.h
create mode 100644 drivers/dpll/sit9531x/dpll.c
create mode 100644 drivers/dpll/sit9531x/dpll.h
create mode 100644 drivers/dpll/sit9531x/prop.c
create mode 100644 drivers/dpll/sit9531x/prop.h
create mode 100644 drivers/dpll/sit9531x/regs.h
base-commit: fa5196392691051963726787944db872420dfa75
--
2.39.2 (Apple Git-143)
next reply other threads:[~2026-11-10 20:26 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 20:26 Ali Rouhi [this message]
2026-11-10 20:26 ` [PATCH net-next v15 01/13] dpll: omit pin phase attributes the driver has no value for Ali Rouhi
2026-11-11 15:35 ` Ivan Vecera
2026-11-10 20:26 ` [PATCH net-next v15 02/13] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 04/13] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 03/13] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 06/13] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 05/13] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 07/13] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 09/13] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 08/13] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 10/13] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 12/13] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 11/13] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-11-10 20:26 ` [PATCH net-next v15 13/13] dpll: sit9531x: model the inter-PLL sync line as a pair of pins Ali Rouhi
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=20261110202607.55744-1-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=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=prabhakar.mahadev-lad.rj@bp.renesas.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
all inboxes | Powered by JetHome®