From: Ivan Vecera <ivecera@redhat.com>
To: netdev@vger.kernel.org
Cc: Chris du Quesnay <Chris.duQuesnay@microchip.com>,
Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
Jakub Kicinski <kuba@kernel.org>, Jiri Pirko <jiri@resnulli.us>,
Min Li <min.li@microchip.com>, Paolo Abeni <pabeni@redhat.com>,
Petr Oros <poros@redhat.com>,
Richard Cochran <richardcochran@gmail.com>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next 5/6] dpll: zl3073x: factor out output pin frequency helper
Date: Mon, 28 Sep 2026 20:55:51 +0200 [thread overview]
Message-ID: <20260928185552.1103515-6-ivecera@redhat.com> (raw)
In-Reply-To: <20260928185552.1103515-1-ivecera@redhat.com>
Extract the divisor and N-division computation from the output pin
frequency_set callback into zl3073x_dpll_output_pin_freq_set(), which
updates a struct zl3073x_out without committing it to hardware. This
lets the upcoming PTP periodic output support reuse the same P-pin,
N-pin and N-divided frequency handling.
No functional change intended.
Tested-by: Chris du Quesnay <Chris.duQuesnay@microchip.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
drivers/dpll/zl3073x/dpll.c | 135 ++++++++++++++++++++----------------
1 file changed, 74 insertions(+), 61 deletions(-)
diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
index fcf91aba2988af..0a36a2acf15b9f 100644
--- a/drivers/dpll/zl3073x/dpll.c
+++ b/drivers/dpll/zl3073x/dpll.c
@@ -1032,96 +1032,109 @@ zl3073x_dpll_output_pin_frequency_get(const struct dpll_pin *dpll_pin,
return 0;
}
+/**
+ * zl3073x_dpll_output_pin_freq_set - compute output config for pin frequency
+ * @pin: output pin to set the frequency for
+ * @out: output state to update, not committed to hardware
+ * @frequency: requested pin frequency in Hz
+ *
+ * Updates the divisor and N-division fields of @out so the given output
+ * pin runs at the requested frequency. For non N-divided formats the
+ * divisor is shared by both pins of the output pair. The caller is
+ * responsible for committing @out with zl3073x_out_state_set().
+ *
+ * Return: 0 on success, -EINVAL if the frequency cannot be represented
+ */
static int
-zl3073x_dpll_output_pin_frequency_set(const struct dpll_pin *dpll_pin,
- void *pin_priv,
- const struct dpll_device *dpll,
- void *dpll_priv, u64 frequency,
- struct netlink_ext_ack *extack)
+zl3073x_dpll_output_pin_freq_set(struct zl3073x_dpll_pin *pin,
+ struct zl3073x_out *out, u64 frequency)
{
- struct zl3073x_dpll *zldpll = dpll_priv;
- struct zl3073x_dev *zldev = zldpll->dev;
- struct zl3073x_dpll_pin *pin = pin_priv;
- struct zl3073x_dpll_pin *sibling = NULL;
- const struct zl3073x_synth *synth;
+ struct zl3073x_dev *zldev = pin->dpll->dev;
u32 new_div, synth_freq;
- struct zl3073x_out out;
- u8 out_id;
- int rc;
+ u8 synth;
- mutex_lock(&zldpll->lock);
-
- out_id = zl3073x_output_pin_out_get(pin->id);
- out = *zl3073x_out_state_get(zldev, out_id);
-
- /* Get attached synth frequency and compute new divisor */
- synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(&out));
- synth_freq = zl3073x_synth_freq_get(synth);
+ synth = zl3073x_out_synth_get(out);
+ synth_freq = zl3073x_dev_synth_freq_get(zldev, synth);
new_div = synth_freq / (u32)frequency;
- /* Check signal format */
- if (!zl3073x_out_is_ndiv(&out)) {
+ if (!zl3073x_out_is_ndiv(out)) {
/* For non N-divided signal formats the frequency is computed
* as division of synth frequency and output divisor, which
* is shared by both pins of the output pair.
*/
- out.div = new_div;
+ out->div = new_div;
/* For 50/50 duty cycle the divisor is equal to width */
- out.width = new_div;
-
- /* Commit output configuration */
- rc = zl3073x_out_state_set(zldev, out_id, &out);
- if (rc)
- goto unlock;
+ out->width = new_div;
- /* The other pin's frequency changed too - it has to be
- * notified about the change.
- */
- sibling = zl3073x_dpll_output_pin_sibling_get(pin);
-
- goto unlock;
+ return 0;
}
if (zl3073x_dpll_is_p_pin(pin)) {
- /* We are going to change output frequency for P-pin but
- * if the requested frequency is less than current N-pin
- * frequency then indicate a failure as we are not able
- * to compute N-pin divisor to keep its frequency unchanged.
- *
- * Update divisor for N-pin to keep N-pin frequency.
+ /* Changing the P-pin frequency, rescale the N-pin divisor to
+ * keep the N-pin frequency unchanged. Fail if the requested
+ * frequency is too low to represent the current N-pin one.
*/
- out.esync_n_period = (out.esync_n_period * out.div) / new_div;
- if (!out.esync_n_period) {
- rc = -EINVAL;
- goto unlock;
- }
+ out->esync_n_period = out->esync_n_period * out->div / new_div;
+ if (!out->esync_n_period)
+ return -EINVAL;
/* Update the output divisor */
- out.div = new_div;
+ out->div = new_div;
/* For 50/50 duty cycle the divisor is equal to width */
- out.width = out.div;
+ out->width = new_div;
} else {
- /* We are going to change frequency of N-pin but if
- * the requested freq is greater or equal than freq of P-pin
- * in the output pair we cannot compute divisor for the N-pin.
- * In this case indicate a failure.
- *
- * Update divisor for N-pin
+ /* Changing the N-pin frequency. Fail if the requested
+ * frequency is higher than or does not divide the P-pin one.
*/
- out.esync_n_period = div64_u64(synth_freq, frequency * out.div);
- if (!out.esync_n_period) {
- rc = -EINVAL;
- goto unlock;
- }
+ out->esync_n_period = div64_u64(synth_freq,
+ frequency * out->div);
+ if (!out->esync_n_period)
+ return -EINVAL;
}
/* For 50/50 duty cycle the divisor is equal to width */
- out.esync_n_width = out.esync_n_period;
+ out->esync_n_width = out->esync_n_period;
+
+ return 0;
+}
+
+static int
+zl3073x_dpll_output_pin_frequency_set(const struct dpll_pin *dpll_pin,
+ void *pin_priv,
+ const struct dpll_device *dpll,
+ void *dpll_priv, u64 frequency,
+ struct netlink_ext_ack *extack)
+{
+ struct zl3073x_dpll *zldpll = dpll_priv;
+ struct zl3073x_dev *zldev = zldpll->dev;
+ struct zl3073x_dpll_pin *pin = pin_priv;
+ struct zl3073x_dpll_pin *sibling = NULL;
+ struct zl3073x_out out;
+ u8 out_id;
+ int rc;
+
+ mutex_lock(&zldpll->lock);
+
+ out_id = zl3073x_output_pin_out_get(pin->id);
+ out = *zl3073x_out_state_get(zldev, out_id);
+
+ rc = zl3073x_dpll_output_pin_freq_set(pin, &out, frequency);
+ if (rc)
+ goto unlock;
/* Commit output configuration */
rc = zl3073x_out_state_set(zldev, out_id, &out);
+ if (rc)
+ goto unlock;
+
+ /* For non N-divided formats the divisor is shared, so the other
+ * pin's frequency changed too and has to be notified.
+ */
+ if (!zl3073x_out_is_ndiv(&out))
+ sibling = zl3073x_dpll_output_pin_sibling_get(pin);
+
unlock:
mutex_unlock(&zldpll->lock);
--
2.55.0
next prev parent reply other threads:[~2026-09-28 18:56 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 18:55 [PATCH net-next 0/6] dpll: zl3073x: add PTP periodic output support Ivan Vecera
2026-09-28 18:55 ` [PATCH net-next 1/6] dpll: zl3073x: notify sibling pin when shared output config changes Ivan Vecera
2026-09-28 18:55 ` [PATCH net-next 2/6] dpll: zl3073x: add GPO support for output pins Ivan Vecera
2026-09-28 18:55 ` [PATCH net-next 3/6] dpll: zl3073x: allow enabling/disabling " Ivan Vecera
2026-09-28 18:55 ` [PATCH net-next 4/6] dpll: zl3073x: consolidate pin capabilities into bitmap Ivan Vecera
2026-09-28 18:55 ` Ivan Vecera [this message]
2026-09-28 18:55 ` [PATCH net-next 6/6] dpll: zl3073x: add PTP periodic output support Ivan Vecera
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=20260928185552.1103515-6-ivecera@redhat.com \
--to=ivecera@redhat.com \
--cc=Chris.duQuesnay@microchip.com \
--cc=arkadiusz.kubalewski@intel.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=min.li@microchip.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=poros@redhat.com \
--cc=richardcochran@gmail.com \
--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®