From: Ivan Vecera <ivecera@redhat.com>
To: Ali Rouhi <arouhi@sitime.com>, Jiri Pirko <jiri@resnulli.us>
Cc: Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Carolina Jubran <cjubran@nvidia.com>,
Oleg Zadorozhnyi <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>
Subject: Re: [PATCH net-next v12 09/12] dpll: sit9531x: implement output pin state on a DPLL
Date: Tue, 13 Oct 2026 11:46:41 +0200 [thread overview]
Message-ID: <a68ee429-c63e-4948-bc98-d895ed8066da@redhat.com> (raw)
In-Reply-To: <20261009183151.78497-10-arouhi@sitime.com>
On 10/9/26 20:31, Ali Rouhi wrote:
> From: Oleg Zadorozhnyi <Oleg.Zadorozhnyi@devoxsoftware.com>
>
> An output is driven by its PLL rather than selected by it, so its state
> says whether it carries a signal: connected while it drives, disconnected
> while it is muted. Setting the state mutes or un-mutes it by forcing the
> pad to Hi-Z, the only per-output control the device offers that leaves the
> divider alone.
>
> The force bit and the state bit are separate, and a pad follows the loaded
> configuration while the force bit is clear, so both are read to decide
> whether an output is muted and both are written to change it. Which of
> the four register banks applies depends on the slot and on whether the pad
> is single-ended or differential.
>
> A mute or un-mute is a per-output control, but each one that changes
> something runs the device-wide programming sequence of the previous
> patch, so a request for the state the output already has is answered
> from the registers without entering it. A request that fails after some
> of its writes landed still announces the change, so a subscriber is not
> left with the old state; the pin handle is read once, so a teardown
> racing the request cannot hand the notification a cleared one. A failed
> entry into the programming state is left the way a commit leaves it:
> loops re-locked and the settling time waited for.
>
> This is also where output pins start being registered at all: until now
> the registration filter took inputs only, so the output operations the
> earlier patches added -- direction and frequency -- had nothing to
> dispatch on.
>
> Signed-off-by: Oleg Zadorozhnyi <Oleg.Zadorozhnyi@devoxsoftware.com>
> Assisted-by: LLM
> Signed-off-by: Ali Rouhi <arouhi@sitime.com>
> ---
> drivers/dpll/sit9531x/core.c | 344 +++++++++++++++++++++++++++++------
> drivers/dpll/sit9531x/core.h | 7 +
> drivers/dpll/sit9531x/dpll.c | 130 +++++++++++++
> 3 files changed, 427 insertions(+), 54 deletions(-)
>
> diff --git a/drivers/dpll/sit9531x/core.c b/drivers/dpll/sit9531x/core.c
> index ea15830b0efa..19aeabd3cd4f 100644
> --- a/drivers/dpll/sit9531x/core.c
> +++ b/drivers/dpll/sit9531x/core.c
> @@ -488,71 +488,50 @@ static int sit9531x_output_forced_hiz(struct sit9531x_dev *sitdev,
> muted);
> }
>
> -/* Attempts to re-lock the output loops before reporting them open. */
> -#define SIT9531X_LOOP_LOCK_TRIES 3
> -
> /*
> - * sit9531x_prg_abort - leave the programming state without committing
> + * sit9531x_output_state_refresh - read an output's mute state back
> *
> - * Entering the state is two writes, and the second can fail with the debug
> - * block already unlocked and the part possibly already in PRG_CMD. There
> - * is nothing to commit in that case, but the loops still have to be closed
> - * and the debug key put back, which is otherwise only done by
> - * sit9531x_prg_commit().
> + * Used when a mute could not be confirmed at the time it was written. The
> + * driver does not poll output state, so without this the cached value would
> + * stand until something else happened to write it.
> + *
> + * Caller must hold sitdev->multiop_lock.
> */
> -static void sit9531x_prg_abort(struct sit9531x_dev *sitdev)
> +int sit9531x_output_state_refresh(struct sit9531x_dev *sitdev, u8 out_idx)
> {
> - u8 attempt;
> - int rc = -EIO;
> + bool muted;
> + int rc;
>
> - for (attempt = 0; attempt < SIT9531X_LOOP_LOCK_TRIES; attempt++) {
> - rc = sit9531x_write_u8(sitdev, SIT9531X_REG_PRG_DIR_GEN,
> - SIT9531X_LOOP_LOCK);
> - if (!rc)
> - break;
> - usleep_range(1000, 2000);
> - }
> + lockdep_assert_held(&sitdev->multiop_lock);
> +
> + rc = sit9531x_output_forced_hiz(sitdev, out_idx, &muted);
> if (rc)
> - dev_err(sitdev->dev,
> - "output loops left unlocked after a failed entry: %d\n",
> - rc);
> + return rc;
> +
> + sitdev->out[out_idx].enabled = !muted;
> + sitdev->out[out_idx].state_stale = false;
>
> - sit9531x_write_u8(sitdev, SIT9531X_REG_OUTSYS_DEBUG,
> - SIT9531X_DEBUG_LOCK_VAL);
> + return 0;
> }
>
> -/*
> - * Enter the output-system programming state: unlock the debug
> - * registers on Page 3 and issue the PRG_CMD state command. Register
> - * writes that reconfigure the output system only take effect when
> - * they are made inside this state.
> - */
> -static int sit9531x_prg_enter(struct sit9531x_dev *sitdev)
> +static int sit9531x_hiz_set_bit(struct sit9531x_dev *sitdev,
> + unsigned int reg, u8 bit, bool set)
> {
> + u8 cur, new_val;
> int rc;
>
> - rc = sit9531x_write_u8(sitdev, SIT9531X_REG_OUTSYS_DEBUG,
> - SIT9531X_DEBUG_UNLOCK_VAL);
> + rc = sit9531x_read_u8(sitdev, reg, &cur);
> if (rc)
> return rc;
>
> - rc = sit9531x_write_u8(sitdev, SIT9531X_REG_PRG_DIR_GEN,
> - SIT9531X_PRG_CMD_STATE);
> - if (rc) {
> - /*
> - * The debug block is unlocked at this point, and a transfer
> - * that reported an error may still have reached the part --
> - * which would leave the device in PRG_CMD with its output
> - * loops open. Callers skip the commit when the entry
> - * fails, so close both here.
> - */
> - sit9531x_prg_abort(sitdev);
> - return rc;
> - }
> + new_val = set ? (cur | BIT(bit)) : (cur & ~BIT(bit));
>
> - return 0;
> + return sit9531x_write_u8(sitdev, reg, new_val);
> }
>
> +/* Attempts to re-lock the output loops before reporting them open. */
> +#define SIT9531X_LOOP_LOCK_TRIES 3
> +
> /*
> * Commit a programming sequence started by sit9531x_prg_enter():
> * update the NVM shadow and re-lock the loops. The sleep gives the
> @@ -622,6 +601,251 @@ static int sit9531x_prg_commit(struct sit9531x_dev *sitdev)
> return 0;
> }
>
> +/*
> + * Enter the output-system programming state: unlock the debug
> + * registers on Page 3 and issue the PRG_CMD state command. Register
> + * writes that reconfigure the output system only take effect when
> + * they are made inside this state.
> + */
> +static int sit9531x_prg_enter(struct sit9531x_dev *sitdev)
> +{
> + int rc;
> +
> + rc = sit9531x_write_u8(sitdev, SIT9531X_REG_OUTSYS_DEBUG,
> + SIT9531X_DEBUG_UNLOCK_VAL);
> + if (rc)
> + return rc;
> +
> + rc = sit9531x_write_u8(sitdev, SIT9531X_REG_PRG_DIR_GEN,
> + SIT9531X_PRG_CMD_STATE);
> + if (rc) {
> + /*
> + * The debug block is unlocked at this point, and a transfer
> + * that reported an error may still have reached the part --
> + * which would leave the device in PRG_CMD with its output
> + * loops open. Callers skip the commit when the entry fails,
> + * so leave the state here the way every completed sequence
> + * does: nothing was changed, so the update commits what the
> + * part already holds, the loops are re-locked, and the
> + * settling time is waited out before the caller drops the
> + * lock and the next request programs the part. The entry
> + * failure is the error to report.
> + */
> + sit9531x_prg_commit(sitdev);
> + return rc;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * sit9531x_output_hiz_write - mute or unmute an output
> + *
> + * Muting takes control of the pin (MASK=1) and forces it to Hi-Z
> + * (STATE=0) on every Hi-Z pair of the slot -- differential, CMOS OutP
> + * and CMOS OutN -- because the output must go quiet whichever way it is
> + * wired; unmuting releases the override on all of them and hands the pin
> + * back to the device. The caller must already be in the programming
> + * state.
> + */
> +static int sit9531x_output_hiz_write(struct sit9531x_dev *sitdev, u8 slot,
> + bool mute)
> +{
> + struct sit9531x_hiz_pair p[SIT9531X_HIZ_PAIRS];
> + u8 mask[SIT9531X_HIZ_PAIRS], state[SIT9531X_HIZ_PAIRS];
> + int i, rc, undo_rc;
Reverse X-mas here, please.
With both of them...
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
next prev parent reply other threads:[~2026-10-13 9:46 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 18:31 [PATCH net-next v12 00/12] dpll: add SiTime SiT9531x DPLL clock driver Ali Rouhi
2026-10-09 18:31 ` [PATCH net-next v12 01/12] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-10-09 18:31 ` [PATCH net-next v12 02/12] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-10-09 18:31 ` [PATCH net-next v12 03/12] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-10-13 9:11 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 05/12] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-10-13 9:35 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 04/12] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-10-13 9:14 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 06/12] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-10-13 9:37 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 07/12] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-10-13 9:43 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 08/12] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-10-13 9:43 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 10/12] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-10-13 10:02 ` Ivan Vecera
2026-10-09 18:31 ` [PATCH net-next v12 09/12] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-10-13 9:46 ` Ivan Vecera [this message]
2026-10-09 18:31 ` [PATCH net-next v12 11/12] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-10-13 10:10 ` Ivan Vecera
2026-10-09 18:32 ` [PATCH net-next v12 12/12] dpll: sit9531x: model the inter-PLL sync net 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=a68ee429-c63e-4948-bc98-d895ed8066da@redhat.com \
--to=ivecera@redhat.com \
--cc=Oleg.Zadorozhnyi@devoxsoftware.com \
--cc=arkadiusz.kubalewski@intel.com \
--cc=arouhi@sitime.com \
--cc=cjubran@nvidia.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--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=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®