Thread (7 messages) 7 messages, 4 authors, 2025-11-01

RE: [PATCH net-next v2 2/2] dpll: zl3073x: Specify phase adjustment granularity for pins

From: "Kubalewski, Arkadiusz" <arkadiusz.kubalewski@intel.com>
Date: 2025-10-31 11:57:53
Also in: linux-doc, lkml

From: Ivan Vecera <ivecera@redhat.com>
Sent: Wednesday, October 29, 2025 4:32 PM

Output pins phase adjustment values in the device are expressed
in half synth clock cycles. Use this number of cycles as output
pins' phase adjust granularity and simplify both get/set callbacks.

Reviewed-by: Michal Schmidt <redacted>
Reviewed-by: Petr Oros <redacted>
Tested-by: Prathosh Satish <Prathosh.Satish@microchip.com>
LGTM, Thank you!
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
quoted hunk ↗ jump to hunk
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
drivers/dpll/zl3073x/dpll.c | 58 +++++++++----------------------------
drivers/dpll/zl3073x/prop.c | 11 +++++++
2 files changed, 25 insertions(+), 44 deletions(-)
diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
index 93dc93eec79ed..b13eb4e342d58 100644
--- a/drivers/dpll/zl3073x/dpll.c
+++ b/drivers/dpll/zl3073x/dpll.c
@@ -35,6 +35,7 @@
 * @prio: pin priority <0, 14>
 * @selectable: pin is selectable in automatic mode
 * @esync_control: embedded sync is controllable
+ * @phase_gran: phase adjustment granularity
 * @pin_state: last saved pin state
 * @phase_offset: last saved pin phase offset
 * @freq_offset: last saved fractional frequency offset
@@ -49,6 +50,7 @@ struct zl3073x_dpll_pin {
	u8			prio;
	bool			selectable;
	bool			esync_control;
+	s32			phase_gran;
	enum dpll_pin_state	pin_state;
	s64			phase_offset;
	s64			freq_offset;
@@ -1388,25 +1390,14 @@ zl3073x_dpll_output_pin_phase_adjust_get(const
struct dpll_pin *dpll_pin,
	struct zl3073x_dpll *zldpll = dpll_priv;
	struct zl3073x_dev *zldev = zldpll->dev;
	struct zl3073x_dpll_pin *pin = pin_priv;
-	u32 synth_freq;
	s32 phase_comp;
-	u8 out, synth;
+	u8 out;
	int rc;

-	out = zl3073x_output_pin_out_get(pin->id);
-	synth = zl3073x_out_synth_get(zldev, out);
-	synth_freq = zl3073x_synth_freq_get(zldev, synth);
-
-	/* Check synth freq for zero */
-	if (!synth_freq) {
-		dev_err(zldev->dev, "Got zero synth frequency for output %u\n",
-			out);
-		return -EINVAL;
-	}
-
	guard(mutex)(&zldev->multiop_lock);

	/* Read output configuration */
+	out = zl3073x_output_pin_out_get(pin->id);
	rc = zl3073x_mb_op(zldev, ZL_REG_OUTPUT_MB_SEM, ZL_OUTPUT_MB_SEM_RD,
			   ZL_REG_OUTPUT_MB_MASK, BIT(out));
	if (rc)
@@ -1417,11 +1408,10 @@ zl3073x_dpll_output_pin_phase_adjust_get(const
struct dpll_pin *dpll_pin,
	if (rc)
		return rc;

-	/* Value in register is expressed in half synth clock cycles */
-	phase_comp *= (int)div_u64(PSEC_PER_SEC, 2 * synth_freq);
-
-	/* Reverse two's complement negation applied during 'set' */
-	*phase_adjust = -phase_comp;
+	/* Convert value to ps and reverse two's complement negation applied
+	 * during 'set'
+	 */
+	*phase_adjust = -phase_comp * pin->phase_gran;

	return rc;
}
@@ -1437,39 +1427,18 @@ zl3073x_dpll_output_pin_phase_adjust_set(const
struct dpll_pin *dpll_pin,
	struct zl3073x_dpll *zldpll = dpll_priv;
	struct zl3073x_dev *zldev = zldpll->dev;
	struct zl3073x_dpll_pin *pin = pin_priv;
-	int half_synth_cycle;
-	u32 synth_freq;
-	u8 out, synth;
+	u8 out;
	int rc;

-	/* Get attached synth */
-	out = zl3073x_output_pin_out_get(pin->id);
-	synth = zl3073x_out_synth_get(zldev, out);
-
-	/* Get synth's frequency */
-	synth_freq = zl3073x_synth_freq_get(zldev, synth);
-
-	/* Value in register is expressed in half synth clock cycles so
-	 * the given phase adjustment a multiple of half synth clock.
-	 */
-	half_synth_cycle = (int)div_u64(PSEC_PER_SEC, 2 * synth_freq);
-
-	if ((phase_adjust % half_synth_cycle) != 0) {
-		NL_SET_ERR_MSG_FMT(extack,
-				   "Phase adjustment value has to be multiple of
%d",
-				   half_synth_cycle);
-		return -EINVAL;
-	}
-	phase_adjust /= half_synth_cycle;
-
	/* The value in the register is stored as two's complement negation
-	 * of requested value.
+	 * of requested value and expressed in half synth clock cycles.
	 */
-	phase_adjust = -phase_adjust;
+	phase_adjust = -phase_adjust / pin->phase_gran;

	guard(mutex)(&zldev->multiop_lock);

	/* Read output configuration */
+	out = zl3073x_output_pin_out_get(pin->id);
	rc = zl3073x_mb_op(zldev, ZL_REG_OUTPUT_MB_SEM, ZL_OUTPUT_MB_SEM_RD,
			   ZL_REG_OUTPUT_MB_MASK, BIT(out));
	if (rc)
@@ -1758,9 +1727,10 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin
*pin, u32 index)
	if (IS_ERR(props))
		return PTR_ERR(props);

-	/* Save package label & esync capability */
+	/* Save package label, esync capability and phase adjust granularity
*/
	strscpy(pin->label, props->package_label);
	pin->esync_control = props->esync_control;
+	pin->phase_gran = props->dpll_props.phase_gran;

	if (zl3073x_dpll_is_input_pin(pin)) {
		rc = zl3073x_dpll_ref_prio_get(pin, &pin->prio);
diff --git a/drivers/dpll/zl3073x/prop.c b/drivers/dpll/zl3073x/prop.c
index 4cf7e8aefcb37..9e1fca5cdaf1e 100644
--- a/drivers/dpll/zl3073x/prop.c
+++ b/drivers/dpll/zl3073x/prop.c
@@ -208,7 +208,18 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct
zl3073x_dev *zldev,
			DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
			DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
	} else {
+		u8 out, synth;
+		u32 f;
+
		props->dpll_props.type = DPLL_PIN_TYPE_GNSS;
+
+		/* The output pin phase adjustment granularity equals half of
+		 * the synth frequency count.
+		 */
+		out = zl3073x_output_pin_out_get(index);
+		synth = zl3073x_out_synth_get(zldev, out);
+		f = 2 * zl3073x_synth_freq_get(zldev, synth);
+		props->dpll_props.phase_gran = f ? div_u64(PSEC_PER_SEC, f) :
1;
	}

	props->dpll_props.phase_range.min = S32_MIN;
--
2.51.0
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help