| 1db73ce0 | 14-Aug-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: zl3073x: add PTP clock support
Add PTP clock support for the ZL3073x DPLL driver. A PTP clock device is registered for each DPLL channel regardless of the initial channel state, providing gett
dpll: zl3073x: add PTP clock support
Add PTP clock support for the ZL3073x DPLL driver. A PTP clock device is registered for each DPLL channel regardless of the initial channel state, providing gettimex64, settime64, adjtime, adjfine, adjphase and getmaxphase callbacks.
Callback availability depends on the current channel state: - adjfine: when NCO pin is connected (returns -EOPNOTSUPP otherwise) - adjphase: available when tracking a reference, uses TIE write - adjtime: always available and uses * phase step for sub-second deltas when NCO pin is connected * TIE write when tracking a reference * plain ToD read-modify-write otherwise - gettime/settime: always available
The adjtime callback splits multi-second adjustments into a ToD read-modify-write for the seconds part and a sub-second mechanism (phase step or TIE write) for the remainder. On partial failure where seconds were already committed, success is returned to prevent the PTP servo from retrying and applying seconds again.
All PTP callbacks are serialized by the existing per-DPLL zldpll->lock mutex, which is also used by DPLL pin and device callbacks.
Reviewed-by: Petr Oros <poros@redhat.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Tested-by: Chris du Quesnay <Chris.duQuesnay@microchip.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Link: https://patch.msgid.link/20260814082656.306534-4-ivecera@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| 2dbf9b75 | 14-Aug-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: zl3073x: add channel ToD, phase step and TIE operations
Add low-level DPLL channel operations for ToD read/write/adjust, output phase step, delta frequency offset write and TIE (Time Interval
dpll: zl3073x: add channel ToD, phase step and TIE operations
Add low-level DPLL channel operations for ToD read/write/adjust, output phase step, delta frequency offset write and TIE (Time Interval Error) write. These serve as building blocks for the PTP clock callbacks added in the next patch.
ToD operations use a wait-before-write pattern to avoid blocking after each operation.
The tod_ready_wait helper selects the poll timeout based on the current ToD command - write operations use a longer timeout (1000 ms) than reads (30 ms).
The ToD read captures system timestamps (ptp_system_timestamp) around the HW command and completion poll to support cross-timestamping.
The TIE write operation provides sub-picosecond resolution phase adjustment for modes where the DPLL is tracking a reference (AUTO and REFLOCK).
Add output step-time mask to struct zl3073x_dev and zl3073x_dev_out_is_stepped() helper to check if an output participates in step-time operations.
Reviewed-by: Petr Oros <poros@redhat.com> Tested-by: Chris du Quesnay <Chris.duQuesnay@microchip.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Link: https://patch.msgid.link/20260814082656.306534-3-ivecera@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| 84e85c32 | 07-Aug-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: use pin owner's dpll ref for pin-level attribute setting
Pin-level attributes (frequency, phase adjust, embedded sync, reference sync) are properties of the pin itself, not of a particular DPL
dpll: use pin owner's dpll ref for pin-level attribute setting
Pin-level attributes (frequency, phase adjust, embedded sync, reference sync) are properties of the pin itself, not of a particular DPLL device. The get callbacks already use only the pin owner's DPLL reference (via dpll_pin_own_dpll_ref_first()), but the set callbacks iterate over all registered DPLL references and invoke the set operation on each one.
This is redundant because a pin is a single physical entity - setting its frequency or phase adjust once through the owner's ops is sufficient. Calling set on every registered DPLL just results in duplicate HW writes for drivers that share a pin across multiple DPLL devices (e.g. ice registers each input pin with both the EEC and PPS DPLL, zl3073x registers input pins with every DPLL channel).
Simplify dpll_pin_freq_set(), dpll_pin_esync_set(), dpll_pin_ref_sync_state_set() and dpll_pin_phase_adj_set() to call the set callback only through the owner's DPLL reference, matching the existing get-side behavior. This removes the xa_for_each iteration loops, the now-unnecessary rollback logic, and several local variables.
The -EOPNOTSUPP validation loop, which checked ops support across all owner-matching references, is replaced with a direct check on the single owner reference returned by dpll_pin_own_dpll_ref_first().
The documentation in dpll.rst is updated to reflect that pin-level attributes are set through the pin owner's dpll reference only.
No existing driver is affected: - ptp_ocp and mlx5 register each pin with a single DPLL. - ice registers input pins with two DPLLs (EEC and PPS) using identical ops and pin_priv; the set callbacks address the HW by pin index, not by DPLL, so the second call was a no-op. - zl3073x registers input pins with every DPLL channel; the set callbacks address HW by pin/ref ID regardless of DPLL. The ref_sync_set callback was the only one with per-channel behavior, addressed by the preceding patch.
Signed-off-by: Ivan Vecera <ivecera@redhat.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Link: https://patch.msgid.link/20260807095926.386923-3-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
| 3553976f | 30-Jun-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: zl3073x: add NCO virtual input pin
Add a virtual NCO (Numerically Controlled Oscillator) input pin that lets userspace switch a DPLL channel into NCO mode. A single NCO pin is shared across al
dpll: zl3073x: add NCO virtual input pin
Add a virtual NCO (Numerically Controlled Oscillator) input pin that lets userspace switch a DPLL channel into NCO mode. A single NCO pin is shared across all DPLL channels - each channel has its own independent connection state. The NCO pin is registered with the new DPLL_PIN_TYPE_INT_NCO type and reports DPLL_PIN_STATE_CONNECTED / DPLL_PIN_OPERSTATE_ACTIVE when the channel is in NCO mode.
At NCO pin registration the following bits are configured in dpll_ctrl_x: - nco_auto_read: auto-capture tracking offset on NCO entry - tod_step_reset: apply negated ToD step accumulator on NCO exit - tie_clear: PPS DPLLs set 1 to re-align outputs on NCO exit, EEC DPLLs keep 0 to prevent an unwanted TIE write
Before switching to NCO mode, dpll_df_read_x is configured with ref_ofst=0 and cmd=ACC_I so that nco_auto_read captures the accumulated I-part offset relative to the master clock. Without this, the captured df_offset would be near zero (offset relative to the input reference after lock).
On NCO entry the df_offset captured by nco_auto_read is read from the register. Per the datasheet, nco_auto_read only captures a valid offset when entering NCO from reflock, auto or holdover mode; from freerun the captured value is not meaningful and df_offset is marked as ZL_DPLL_DF_OFFSET_UNKNOWN. The same sentinel is set in chan_state_update() when the channel is not locked, and both FFO consumers (NCO pin and input pin) guard against it.
Disconnecting the NCO pin switches to freerun rather than holdover because holdover averaging is not updated during NCO mode.
When connecting the NCO pin displaces a previously connected input pin (reflock mode), a change notification is sent for that input pin.
Input reference pins are now always registered regardless of the initial DPLL mode. Previously they were skipped when the DPLL was in NCO mode, but the NCO pin provides the proper mechanism for mode transitions.
Reviewed-by: Petr Oros <poros@redhat.com> Tested-by: Chris du Quesnay <Chris.duQuesnay@microchip.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Link: https://patch.msgid.link/20260630125536.720717-6-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
| 21460118 | 30-Jun-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: zl3073x: add per-DPLL serialization lock
Add a per-DPLL mutex that serializes all operations on a given DPLL channel across DPLL netlink callbacks, the periodic kthread worker, and (in subsequ
dpll: zl3073x: add per-DPLL serialization lock
Add a per-DPLL mutex that serializes all operations on a given DPLL channel across DPLL netlink callbacks, the periodic kthread worker, and (in subsequent patches) PTP clock callbacks.
All DPLL pin and device callbacks that access mutable state take the lock as the first operation. The periodic worker holds it for the entire check cycle of each channel, deferring change notifications until after the lock is released to avoid ABBA deadlock with dpll_lock. This establishes the lock ordering: dpll_lock (subsystem, outer) -> zldpll->lock (driver, inner).
Move zl3073x_chan_state_update() from the per-device zl3073x_dev_chan_states_update() loop into the per-DPLL zl3073x_dpll_changes_check() so it runs under zldpll->lock. This serializes df_offset writes with all readers and eliminates the need for separate df_offset synchronization.
Change pin->freq_offset from atomic64_t to plain s64 since all readers and writers are now serialized by zldpll->lock, making atomic access unnecessary.
Signed-off-by: Ivan Vecera <ivecera@redhat.com> Reviewed-by: Petr Oros <poros@redhat.com> Link: https://patch.msgid.link/20260630125536.720717-5-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
| 2b11bde3 | 30-Jun-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: zl3073x: use per-operation poll timeouts
Replace the single 2s timeout in zl3073x_poll_zero_u8() with a per-caller timeout parameter. Different HW operations have different expected completion
dpll: zl3073x: use per-operation poll timeouts
Replace the single 2s timeout in zl3073x_poll_zero_u8() with a per-caller timeout parameter. Different HW operations have different expected completion times so using per-operation timeouts improves error detection. The timeout values are based on proprietary source code provided by Microchip and own measurement.
Signed-off-by: Ivan Vecera <ivecera@redhat.com> Reviewed-by: Petr Oros <poros@redhat.com> Link: https://patch.msgid.link/20260630125536.720717-4-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
| 0cc8348a | 30-Jun-2026 |
Ivan Vecera <ivecera@redhat.com> |
dpll: add DPLL_PIN_TYPE_INT_NCO pin type
Add DPLL_PIN_TYPE_INT_NCO pin type for virtual pins representing the NCO mode of a DPLL. When connected as a DPLL input, the DPLL enters NCO mode where the o
dpll: add DPLL_PIN_TYPE_INT_NCO pin type
Add DPLL_PIN_TYPE_INT_NCO pin type for virtual pins representing the NCO mode of a DPLL. When connected as a DPLL input, the DPLL enters NCO mode where the output frequency is adjusted by the host via the PTP clock interface.
Update the fractional-frequency-offset and fractional-frequency- offset-ppt attribute documentation to note that for INT_NCO pins these attributes represent the DPLL's current output frequency offset from its nominal frequency.
Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Ivan Vecera <ivecera@redhat.com> Link: https://patch.msgid.link/20260630125536.720717-3-ivecera@redhat.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
show more ...
|
| 521b6d5d | 07-Jun-2026 |
Grzegorz Nitka <grzegorz.nitka@intel.com> |
dpll: allow fwnode pins to attempt state change without capability bit
Pins registered with an fwnode may have .state_on_dpll_set implemented without advertising DPLL_PIN_CAPABILITIES_STATE_CAN_CHAN
dpll: allow fwnode pins to attempt state change without capability bit
Pins registered with an fwnode may have .state_on_dpll_set implemented without advertising DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE upfront. Requiring the bit for fwnode pins ties firmware description to driver implementation details unnecessarily.
Relax the capability check in dpll_pin_state_set() and dpll_pin_on_pin_state_set(): when a pin has an associated fwnode, bypass the capability gate and let the ops layer decide, returning -EOPNOTSUPP if .state_on_dpll_set is absent. Non-fwnode pins retain the original strict behavior.
This is used later in the series by the SyncE_Ref output pin, which relies on the fwnode path for state control.
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Link: https://patch.msgid.link/20260607183045.1213735-10-grzegorz.nitka@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| 0bf47f72 | 07-Jun-2026 |
Grzegorz Nitka <grzegorz.nitka@intel.com> |
dpll: extend pin notifier with notification source ID
Extend the DPLL pin notification API to include a source identifier indicating where the notification originates. This allows notifier consumers
dpll: extend pin notifier with notification source ID
Extend the DPLL pin notification API to include a source identifier indicating where the notification originates. This allows notifier consumers to distinguish between notifications coming from an associated DPLL instance, a parent pin, or the pin itself.
A new field, src_clock_id, is added to struct dpll_pin_notifier_info and is passed through all pin-related notification paths. Callers of dpll_pin_notify() are updated to provide a meaningful source identifier based on their context: - pin registration/unregistration uses the DPLL's clock_id, - pin-on-pin operations use the parent pin's clock_id, - pin changes use the pin's own clock_id.
As introduced in the commit ("dpll: allow registering FW-identified pin with a different DPLL"), it is possible to share the same physical pin via firmware description (fwnode) with DPLL objects from different kernel modules. This means that a given pin can be registered multiple times.
Driver such as ICE (E825 devices) rely on this mechanism when listening for the event where a shared-fwnode pin appears, while avoiding reacting to events triggered by their own registration logic.
This change only extends the notification metadata and does not alter existing semantics for drivers that do not use the new field.
Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Link: https://patch.msgid.link/20260607183045.1213735-9-grzegorz.nitka@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| 1a229210 | 07-Jun-2026 |
Grzegorz Nitka <grzegorz.nitka@intel.com> |
dpll: balance create/delete notifications in __dpll_pin_(un)register
__dpll_pin_register() emits dpll_pin_create_ntf() internally, but __dpll_pin_unregister() left the matching delete to its callers
dpll: balance create/delete notifications in __dpll_pin_(un)register
__dpll_pin_register() emits dpll_pin_create_ntf() internally, but __dpll_pin_unregister() left the matching delete to its callers. The counts then diverge on dpll_pin_on_pin_register() rollback and on dpll_pin_on_pin_unregister(), leaking stale notifications.
Emit dpll_pin_delete_ntf() inside __dpll_pin_unregister() and drop the now-redundant call in dpll_pin_unregister().
Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions") Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Link: https://patch.msgid.link/20260607183045.1213735-8-grzegorz.nitka@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| 0a5c720a | 07-Jun-2026 |
Grzegorz Nitka <grzegorz.nitka@intel.com> |
dpll: guard sync-pair removal on full pin unregister
__dpll_pin_unregister() wiped the global sync-pair state on every (dpll, ops, priv, cookie) tuple removed from a pin. When a pin is registered mu
dpll: guard sync-pair removal on full pin unregister
__dpll_pin_unregister() wiped the global sync-pair state on every (dpll, ops, priv, cookie) tuple removed from a pin. When a pin is registered multiple times and only one registration is being torn down, this dropped sync-pair pairings still in use by the surviving registrations.
Move dpll_pin_ref_sync_pair_del() inside the xa_empty(&pin->dpll_refs) branch so it only runs when the last registration is gone, alongside clearing the DPLL_REGISTERED mark.
Fixes: 58256a26bfb3 ("dpll: add reference sync get/set") Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Link: https://patch.msgid.link/20260607183045.1213735-7-grzegorz.nitka@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|
| df0ba51c | 07-Jun-2026 |
Grzegorz Nitka <grzegorz.nitka@intel.com> |
dpll: emit per-dpll delete notifications in dpll_pin_on_pin_unregister()
dpll_pin_on_pin_register() emits a creation notification for every parent->dpll_refs entry, but dpll_pin_on_pin_unregister()
dpll: emit per-dpll delete notifications in dpll_pin_on_pin_unregister()
dpll_pin_on_pin_register() emits a creation notification for every parent->dpll_refs entry, but dpll_pin_on_pin_unregister() emitted only one deletion notification outside the loop. When a pin is registered against multiple parent dplls, userspace sees N creates but a single delete and leaks per-dpll state.
Move dpll_pin_delete_ntf() into the loop and call it before __dpll_pin_unregister() so the DPLL_REGISTERED mark is still set when dpll_pin_available() is consulted.
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions") Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com> Link: https://patch.msgid.link/20260607183045.1213735-6-grzegorz.nitka@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
show more ...
|