* [PATCH iproute2-next v2 0/2] dpll: phase unit display and frequency monitoring
@ 2026-05-03 15:13 Ivan Vecera
2026-05-03 15:13 ` [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes Ivan Vecera
2026-05-03 15:13 ` [PATCH iproute2-next v2 2/2] dpll: add frequency monitoring support Ivan Vecera
0 siblings, 2 replies; 5+ messages in thread
From: Ivan Vecera @ 2026-05-03 15:13 UTC (permalink / raw)
To: netdev; +Cc: Petr Oros, David Ahern, Stephen Hemminger
This series improves dpll pin output formatting and adds support for
the frequency monitoring feature.
Patch 1 adds picosecond unit to phase-adjust-min, phase-adjust-max
and phase-adjust attributes. It also introduces the DPLL_PR_PHASE_OFFSET
macro that properly formats phase-offset as fractional picoseconds by
dividing the raw kernel value by DPLL_PHASE_OFFSET_DIVIDER.
Patch 2 adds support for the new frequency monitoring feature including
the DPLL_A_FREQUENCY_MONITOR device attribute and
DPLL_A_PIN_MEASURED_FREQUENCY pin attribute. The measured frequency is
displayed as fractional Hz using the DPLL_PR_MEASURED_FREQUENCY macro
since the kernel reports the value in millihertz. It also refactors
phase-offset-monitor parsing into a shared helper.
Tested on EDS2 development board with zl3073x DPLL:
# dpll pin show package-label REF0P
pin id 196:
module-name: zl3073x
clock-id: 13709406750444215013
board-label: SyncE IN M1 CLK1
package-label: REF0P
type: synce-eth-port
frequency: 125000000 Hz
measured-frequency: 124999326.000 Hz
frequency-supported:
2500000 Hz
25000000 Hz
125000000 Hz
capabilities: 0x6 state-can-change priority-can-change
phase-adjust-min: -2147483648 ps
phase-adjust-max: 2147483647 ps
phase-adjust: 0 ps
parent-device:
id 14 direction input prio 10 state selectable phase-offset 0.000 ps
id 15 direction input prio 0 state connected phase-offset 323.000 ps
Changes:
v2:
- fixed very long line in the man page
Ivan Vecera (2):
dpll: add ps unit to phase-related pin attributes
dpll: add frequency monitoring support
bash-completion/dpll | 4 +-
dpll/dpll.c | 89 +++++++++++++++++++++++++++++++++++---------
man/man8/dpll.8 | 19 +++++++++-
3 files changed, 90 insertions(+), 22 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes
2026-05-03 15:13 [PATCH iproute2-next v2 0/2] dpll: phase unit display and frequency monitoring Ivan Vecera
@ 2026-05-03 15:13 ` Ivan Vecera
2026-05-03 22:34 ` Stephen Hemminger
2026-05-03 15:13 ` [PATCH iproute2-next v2 2/2] dpll: add frequency monitoring support Ivan Vecera
1 sibling, 1 reply; 5+ messages in thread
From: Ivan Vecera @ 2026-05-03 15:13 UTC (permalink / raw)
To: netdev; +Cc: Petr Oros, David Ahern, Stephen Hemminger
Display phase-adjust-min, phase-adjust-max and phase-adjust values
with ps unit. Add DPLL_PR_PHASE_OFFSET macro that properly formats
phase-offset as fractional picoseconds by dividing the raw kernel
value by DPLL_PHASE_OFFSET_DIVIDER.
Reviewed-by: Petr Oros <poros@redhat.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
dpll/dpll.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/dpll/dpll.c b/dpll/dpll.c
index b6ba3283e0ba..e8056ff6a24b 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -410,6 +410,21 @@ static __s64 mnl_attr_get_sint(const struct nlattr *attr)
} \
} while (0)
+/* Phase offset - JSON prints raw sub-ps value, FP prints fractional ps */
+#define DPLL_PR_PHASE_OFFSET(tb, attr_id) \
+ do { \
+ if (tb[attr_id]) { \
+ __s64 val = mnl_attr_get_sint(tb[attr_id]); \
+ lldiv_t d = lldiv(llabs(val), \
+ DPLL_PHASE_OFFSET_DIVIDER); \
+ print_s64(PRINT_JSON, "phase-offset", NULL, val); \
+ print_string(PRINT_FP, NULL, " phase-offset %s", \
+ val < 0 ? "-" : ""); \
+ print_s64(PRINT_FP, NULL, "%lld.", d.quot); \
+ print_s64(PRINT_FP, NULL, "%03lld ps", d.rem); \
+ } \
+ } while (0)
+
/* Generic version with custom format */
#define DPLL_PR_ENUM_STR_FMT(tb, attr_id, name, format_str, name_func) \
do { \
@@ -1507,8 +1522,7 @@ static void dpll_pin_print_parent_devices(struct nlattr *attr)
" prio %u");
DPLL_PR_ENUM_STR_FMT(tb_parent, DPLL_A_PIN_STATE, "state",
" state %s", dpll_pin_state_name);
- DPLL_PR_SINT_FMT(tb_parent, DPLL_A_PIN_PHASE_OFFSET,
- "phase-offset", " phase-offset %" PRId64);
+ DPLL_PR_PHASE_OFFSET(tb_parent, DPLL_A_PIN_PHASE_OFFSET);
print_nl();
close_json_object();
@@ -1592,10 +1606,13 @@ static void dpll_pin_print_attrs(struct nlattr **tb)
dpll_pin_print_capabilities(tb[DPLL_A_PIN_CAPABILITIES]);
- DPLL_PR_INT(tb, DPLL_A_PIN_PHASE_ADJUST_MIN, "phase-adjust-min");
- DPLL_PR_INT(tb, DPLL_A_PIN_PHASE_ADJUST_MAX, "phase-adjust-max");
+ DPLL_PR_INT_FMT(tb, DPLL_A_PIN_PHASE_ADJUST_MIN, "phase-adjust-min",
+ " phase-adjust-min: %d ps\n");
+ DPLL_PR_INT_FMT(tb, DPLL_A_PIN_PHASE_ADJUST_MAX, "phase-adjust-max",
+ " phase-adjust-max: %d ps\n");
DPLL_PR_UINT(tb, DPLL_A_PIN_PHASE_ADJUST_GRAN, "phase-adjust-gran");
- DPLL_PR_INT(tb, DPLL_A_PIN_PHASE_ADJUST, "phase-adjust");
+ DPLL_PR_INT_FMT(tb, DPLL_A_PIN_PHASE_ADJUST, "phase-adjust",
+ " phase-adjust: %d ps\n");
if (json || !tb[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT])
DPLL_PR_SINT(tb, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH iproute2-next v2 2/2] dpll: add frequency monitoring support
2026-05-03 15:13 [PATCH iproute2-next v2 0/2] dpll: phase unit display and frequency monitoring Ivan Vecera
2026-05-03 15:13 ` [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes Ivan Vecera
@ 2026-05-03 15:13 ` Ivan Vecera
1 sibling, 0 replies; 5+ messages in thread
From: Ivan Vecera @ 2026-05-03 15:13 UTC (permalink / raw)
To: netdev; +Cc: Petr Oros, David Ahern, Stephen Hemminger
Add support for the new frequency monitoring feature from the kernel
patch series "dpll: add actual frequency monitoring feature". This
includes:
- DPLL_A_FREQUENCY_MONITOR device attribute (enable/disable)
- DPLL_A_PIN_MEASURED_FREQUENCY pin attribute displayed as fractional Hz
using DPLL_PR_MEASURED_FREQUENCY macro (kernel reports in mHz)
- device set: frequency-monitor { enable | disable }
- Refactor phase-offset-monitor to use new dpll_parse_attr_feature_state
helper shared with frequency-monitor
- Update man page and bash-completion
Reviewed-by: Petr Oros <poros@redhat.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
Changes:
v2 - fixed very long line in the man page
---
bash-completion/dpll | 4 +--
dpll/dpll.c | 62 ++++++++++++++++++++++++++++++++++----------
man/man8/dpll.8 | 19 ++++++++++++--
3 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/bash-completion/dpll b/bash-completion/dpll
index 542b99c2fce2..7ddcf529d429 100644
--- a/bash-completion/dpll
+++ b/bash-completion/dpll
@@ -100,7 +100,7 @@ _dpll_device()
COMPREPLY=( $( compgen -W "automatic manual" -- "$cur" ) )
return 0
;;
- phase-offset-monitor)
+ phase-offset-monitor|frequency-monitor)
COMPREPLY=( $( compgen -W "enable disable true false 0 1" -- "$cur" ) )
return 0
;;
@@ -110,7 +110,7 @@ _dpll_device()
;;
*)
COMPREPLY=( $( compgen -W "id mode phase-offset-monitor \
- phase-offset-avg-factor" -- "$cur" ) )
+ phase-offset-avg-factor frequency-monitor" -- "$cur" ) )
return 0
;;
esac
diff --git a/dpll/dpll.c b/dpll/dpll.c
index e8056ff6a24b..6d8c0cbb8a34 100644
--- a/dpll/dpll.c
+++ b/dpll/dpll.c
@@ -313,6 +313,26 @@ static int dpll_parse_attr_str(struct dpll *dpll, struct nlmsghdr *nlh,
return 0;
}
+static int dpll_parse_attr_feature_state(struct dpll *dpll,
+ struct nlmsghdr *nlh,
+ const char *arg_name, int attr_id)
+{
+ const char *str = dpll_argv_next(dpll);
+ bool val;
+
+ if (!str) {
+ pr_err("%s requires an argument\n", arg_name);
+ return -EINVAL;
+ }
+ if (str_to_bool(str, &val)) {
+ pr_err("invalid %s value: %s (use enable/disable)\n",
+ arg_name, str);
+ return -EINVAL;
+ }
+ mnl_attr_put_u32(nlh, attr_id, val ? 1 : 0);
+ return 0;
+}
+
static int dpll_parse_attr_enum(struct dpll *dpll, struct nlmsghdr *nlh,
const char *arg_name, int attr_id,
int (*parse_func)(struct dpll *, __u32 *))
@@ -425,6 +445,21 @@ static __s64 mnl_attr_get_sint(const struct nlattr *attr)
} \
} while (0)
+/* Measured frequency - JSON prints raw mHz value, FP prints fractional Hz */
+#define DPLL_PR_MEASURED_FREQUENCY(tb, attr_id) \
+ do { \
+ if (tb[attr_id]) { \
+ __u64 val = mnl_attr_get_u64(tb[attr_id]); \
+ lldiv_t d = lldiv(val, \
+ DPLL_PIN_MEASURED_FREQUENCY_DIVIDER); \
+ print_lluint(PRINT_JSON, "measured-frequency", \
+ NULL, val); \
+ print_s64(PRINT_FP, NULL, \
+ " measured-frequency: %lld.", d.quot); \
+ print_s64(PRINT_FP, NULL, "%03lld Hz\n", d.rem); \
+ } \
+ } while (0)
+
/* Generic version with custom format */
#define DPLL_PR_ENUM_STR_FMT(tb, attr_id, name, format_str, name_func) \
do { \
@@ -657,6 +692,7 @@ static void cmd_device_help(void)
pr_err(" dpll device set id DEVICE_ID [ mode { automatic | manual } ]\n");
pr_err(" [ phase-offset-monitor { enable | disable } ]\n");
pr_err(" [ phase-offset-avg-factor NUM ]\n");
+ pr_err(" [ frequency-monitor { enable | disable } ]\n");
pr_err(" dpll device id-get [ module-name NAME ] [ clock-id ID ] [ type TYPE ]\n");
}
@@ -1058,6 +1094,10 @@ static void dpll_device_print_attrs(const struct nlmsghdr *nlh,
str_enable_disable);
DPLL_PR_UINT(tb, DPLL_A_PHASE_OFFSET_AVG_FACTOR,
"phase-offset-avg-factor");
+ DPLL_PR_ENUM_STR_FMT(tb, DPLL_A_FREQUENCY_MONITOR,
+ "frequency-monitor",
+ " frequency-monitor: %s\n",
+ str_enable_disable);
}
/* Netlink callback - device get (single device) */
@@ -1219,25 +1259,20 @@ static int cmd_device_set(struct dpll *dpll)
dpll_parse_mode))
return -EINVAL;
} else if (dpll_argv_match(dpll, "phase-offset-monitor")) {
- const char *str = dpll_argv_next(dpll);
- bool val;
-
- if (!str) {
- pr_err("phase-offset-monitor requires an argument\n");
- return -EINVAL;
- }
- if (str_to_bool(str, &val)) {
- pr_err("invalid phase-offset-monitor value: %s (use enable/disable)\n",
- str);
+ if (dpll_parse_attr_feature_state(dpll, nlh,
+ "phase-offset-monitor",
+ DPLL_A_PHASE_OFFSET_MONITOR))
return -EINVAL;
- }
- mnl_attr_put_u32(nlh, DPLL_A_PHASE_OFFSET_MONITOR,
- val ? 1 : 0);
} else if (dpll_argv_match(dpll, "phase-offset-avg-factor")) {
if (dpll_parse_attr_u32(dpll, nlh,
"phase-offset-avg-factor",
DPLL_A_PHASE_OFFSET_AVG_FACTOR))
return -EINVAL;
+ } else if (dpll_argv_match(dpll, "frequency-monitor")) {
+ if (dpll_parse_attr_feature_state(dpll, nlh,
+ "frequency-monitor",
+ DPLL_A_FREQUENCY_MONITOR))
+ return -EINVAL;
} else {
pr_err("unknown option: %s\n", dpll_argv(dpll));
return -EINVAL;
@@ -1601,6 +1636,7 @@ static void dpll_pin_print_attrs(struct nlattr **tb)
DPLL_PR_ENUM_STR(tb, DPLL_A_PIN_TYPE, "type", dpll_pin_type_name);
DPLL_PR_U64_FMT(tb, DPLL_A_PIN_FREQUENCY, "frequency",
" frequency: %" PRIu64 " Hz\n");
+ DPLL_PR_MEASURED_FREQUENCY(tb, DPLL_A_PIN_MEASURED_FREQUENCY);
dpll_pin_print_freq_supported(tb[DPLL_A_PIN_FREQUENCY_SUPPORTED]);
diff --git a/man/man8/dpll.8 b/man/man8/dpll.8
index 89f17af74923..4b7461d15437 100644
--- a/man/man8/dpll.8
+++ b/man/man8/dpll.8
@@ -111,7 +111,7 @@ Temperature (if supported)
Type (PPS or EEC)
.RE
-.SS dpll device set id ID [ mode { automatic | manual } ] [ phase-offset-monitor { enable | disable } ] [ phase-offset-avg-factor FACTOR ]
+.SS dpll device set id ID [ PARAMETER VALUE ] ...
Configure DPLL device parameters.
@@ -140,6 +140,14 @@ When enabled, the kernel continuously measures and reports phase differences.
Set the averaging factor (1-255) applied to phase offset calculations.
Higher values provide smoother but slower-responding measurements.
+.TP
+.BI frequency-monitor " { enable | disable | true | false | 0 | 1 }"
+Enable or disable frequency monitoring on the device. When enabled, the
+kernel continuously measures and reports actual pin frequencies, which can
+be read via the
+.B measured-frequency
+field in pin show output.
+
.SS dpll device id-get [ module-name NAME ] [ clock-id ID ] [ type TYPE ]
Retrieve the device ID based on identifying attributes. Useful for scripting
@@ -233,7 +241,9 @@ Board label (hardware label from device tree or ACPI)
.IP \[bu]
Pin type (mux, ext, synce-eth-port, int-oscillator, gnss)
.IP \[bu]
-Frequency and supported frequency ranges
+Configured frequency and supported frequency ranges
+.IP \[bu]
+Measured frequency in Hz (when frequency monitoring is enabled)
.IP \[bu]
Capabilities (state-can-change, priority-can-change, direction-can-change)
.IP \[bu]
@@ -372,6 +382,11 @@ Press Ctrl+C to stop monitoring.
.B dpll device set id 0 phase-offset-monitor enable
.fi
+.SS Enable frequency monitoring on device 0
+.nf
+.B dpll device set id 0 frequency-monitor enable
+.fi
+
.SS Show all EEC devices
.nf
.B dpll device show type eec
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes
2026-05-03 15:13 ` [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes Ivan Vecera
@ 2026-05-03 22:34 ` Stephen Hemminger
2026-05-04 6:48 ` Ivan Vecera
0 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2026-05-03 22:34 UTC (permalink / raw)
To: Ivan Vecera; +Cc: netdev, Petr Oros, David Ahern
On Sun, 3 May 2026 17:13:51 +0200
Ivan Vecera <ivecera@redhat.com> wrote:
> +/* Phase offset - JSON prints raw sub-ps value, FP prints fractional ps */
> +#define DPLL_PR_PHASE_OFFSET(tb, attr_id) \
> + do { \
> + if (tb[attr_id]) { \
> + __s64 val = mnl_attr_get_sint(tb[attr_id]); \
> + lldiv_t d = lldiv(llabs(val), \
> + DPLL_PHASE_OFFSET_DIVIDER); \
> + print_s64(PRINT_JSON, "phase-offset", NULL, val); \
> + print_string(PRINT_FP, NULL, " phase-offset %s", \
> + val < 0 ? "-" : ""); \
> + print_s64(PRINT_FP, NULL, "%lld.", d.quot); \
> + print_s64(PRINT_FP, NULL, "%03lld ps", d.rem); \
> + } \
> + } while (0)
> +
> /* Gene
Any macro this big should be a function
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes
2026-05-03 22:34 ` Stephen Hemminger
@ 2026-05-04 6:48 ` Ivan Vecera
0 siblings, 0 replies; 5+ messages in thread
From: Ivan Vecera @ 2026-05-04 6:48 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Petr Oros, David Ahern
On 5/4/26 12:34 AM, Stephen Hemminger wrote:
> On Sun, 3 May 2026 17:13:51 +0200
> Ivan Vecera <ivecera@redhat.com> wrote:
>
>> +/* Phase offset - JSON prints raw sub-ps value, FP prints fractional ps */
>> +#define DPLL_PR_PHASE_OFFSET(tb, attr_id) \
>> + do { \
>> + if (tb[attr_id]) { \
>> + __s64 val = mnl_attr_get_sint(tb[attr_id]); \
>> + lldiv_t d = lldiv(llabs(val), \
>> + DPLL_PHASE_OFFSET_DIVIDER); \
>> + print_s64(PRINT_JSON, "phase-offset", NULL, val); \
>> + print_string(PRINT_FP, NULL, " phase-offset %s", \
>> + val < 0 ? "-" : ""); \
>> + print_s64(PRINT_FP, NULL, "%lld.", d.quot); \
>> + print_s64(PRINT_FP, NULL, "%03lld ps", d.rem); \
>> + } \
>> + } while (0)
>> +
>> /* Gene
>
> Any macro this big should be a function
>
Will fix this and DPLL_PR_MEASURED_FREQUENCY (in the next patch)...
Thanks,
Ivan
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-05-04 6:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-03 15:13 [PATCH iproute2-next v2 0/2] dpll: phase unit display and frequency monitoring Ivan Vecera
2026-05-03 15:13 ` [PATCH iproute2-next v2 1/2] dpll: add ps unit to phase-related pin attributes Ivan Vecera
2026-05-03 22:34 ` Stephen Hemminger
2026-05-04 6:48 ` Ivan Vecera
2026-05-03 15:13 ` [PATCH iproute2-next v2 2/2] dpll: add frequency monitoring support Ivan Vecera
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox