1.. SPDX-License-Identifier: GPL-2.0 2 3=============================== 4The Linux kernel dpll subsystem 5=============================== 6 7DPLL 8==== 9 10PLL - Phase Locked Loop is an electronic circuit which syntonizes clock 11signal of a device with an external clock signal. Effectively enabling 12device to run on the same clock signal beat as provided on a PLL input. 13 14DPLL - Digital Phase Locked Loop is an integrated circuit which in 15addition to plain PLL behavior incorporates a digital phase detector 16and may have digital divider in the loop. As a result, the frequency on 17DPLL's input and output may be configurable. 18 19Subsystem 20========= 21 22The main purpose of dpll subsystem is to provide general interface 23to configure devices that use any kind of Digital PLL and could use 24different sources of input signal to synchronize to, as well as 25different types of outputs. 26The main interface is NETLINK_GENERIC based protocol with an event 27monitoring multicast group defined. 28 29Device object 30============= 31 32Single dpll device object means single Digital PLL circuit and bunch of 33connected pins. 34It reports the supported modes of operation and current status to the 35user in response to the `do` request of netlink command 36``DPLL_CMD_DEVICE_GET`` and list of dplls registered in the subsystem 37with `dump` netlink request of the same command. 38Changing the configuration of dpll device is done with `do` request of 39netlink ``DPLL_CMD_DEVICE_SET`` command. 40A device handle is ``DPLL_A_ID``, it shall be provided to get or set 41configuration of particular device in the system. It can be obtained 42with a ``DPLL_CMD_DEVICE_GET`` `dump` request or 43a ``DPLL_CMD_DEVICE_ID_GET`` `do` request, where the one must provide 44attributes that result in single device match. 45 46Pin object 47========== 48 49A pin is amorphic object which represents either input or output, it 50could be internal component of the device, as well as externally 51connected. 52The number of pins per dpll vary, but usually multiple pins shall be 53provided for a single dpll device. 54Pin's properties, capabilities and status is provided to the user in 55response to `do` request of netlink ``DPLL_CMD_PIN_GET`` command. 56It is also possible to list all the pins that were registered in the 57system with `dump` request of ``DPLL_CMD_PIN_GET`` command. 58Configuration of a pin can be changed by `do` request of netlink 59``DPLL_CMD_PIN_SET`` command. 60Pin handle is a ``DPLL_A_PIN_ID``, it shall be provided to get or set 61configuration of particular pin in the system. It can be obtained with 62``DPLL_CMD_PIN_GET`` `dump` request or ``DPLL_CMD_PIN_ID_GET`` `do` 63request, where user provides attributes that result in single pin match. 64 65Pin selection 66============= 67 68Pin state (``DPLL_A_PIN_STATE``) reflects the administrative intent set 69by the user. Pin operational state (``DPLL_A_PIN_OPERSTATE``) reflects 70what the hardware is actually doing with the pin. 71 72Pin selection can be done either manually or automatically, depending 73on hardware capabilities and active dpll device work mode 74(``DPLL_A_MODE`` attribute). The consequence is that there are 75differences for each mode in terms of available pin states the user can 76request for a dpll device. 77 78In manual mode (``DPLL_MODE_MANUAL``) the user can request one of 79following pin states: 80 81- ``DPLL_PIN_STATE_CONNECTED`` - the pin is selected to drive dpll 82 device 83- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not selected to drive 84 dpll device 85 86In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request one of 87following pin states: 88 89- ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid 90 input for automatic selection algorithm 91- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as 92 a valid input for automatic selection algorithm 93 94Pins that have the ``DPLL_PIN_CAPABILITIES_STATE_CONNECTED_OVERRIDE`` 95capability can additionally be set to ``DPLL_PIN_STATE_CONNECTED`` in 96automatic mode, overriding the active input selection. This is useful 97for automatic-only DPLL devices where mode cannot be switched to manual. 98When such a pin is disconnected, the device returns to automatic input 99selection. 100 101The actual hardware status of a pin is reported via the operational 102state (``DPLL_A_PIN_OPERSTATE``) attribute nested under the parent 103device: 104 105- ``DPLL_PIN_OPERSTATE_ACTIVE`` - pin is qualified and actively used 106 by the DPLL 107- ``DPLL_PIN_OPERSTATE_STANDBY`` - pin is qualified but not actively 108 used by the DPLL 109- ``DPLL_PIN_OPERSTATE_NO_SIGNAL`` - pin does not have a valid signal 110- ``DPLL_PIN_OPERSTATE_QUAL_FAILED`` - pin signal failed qualification 111 checks 112 113Shared pins 114=========== 115 116A single pin object can be attached to multiple dpll devices. 117Then there are two groups of configuration knobs: 118 1191) Set on a pin - the configuration is a property of the pin itself and 120 applies to all dpll devices the pin is registered with 121 (i.e., ``DPLL_A_PIN_FREQUENCY``), 1222) Set on a pin-dpll tuple - the configuration affects only selected 123 dpll device (i.e., ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE``, 124 ``DPLL_A_PIN_DIRECTION``). 125 126MUX-type pins 127============= 128 129A pin can be MUX-type, it aggregates child pins and serves as a pin 130multiplexer. One or more pins are registered with MUX-type instead of 131being directly registered to a dpll device. 132Pins registered with a MUX-type pin provide user with additional nested 133attribute ``DPLL_A_PIN_PARENT_PIN`` for each parent they were registered 134with. 135If a pin was registered with multiple parent pins, they behave like a 136multiple output multiplexer. In this case output of a 137``DPLL_CMD_PIN_GET`` would contain multiple pin-parent nested 138attributes with current state related to each parent, like:: 139 140 'pin': [{{ 141 'clock-id': 282574471561216, 142 'module-name': 'ice', 143 'capabilities': 4, 144 'id': 13, 145 'parent-pin': [ 146 {'parent-id': 2, 'state': 'connected'}, 147 {'parent-id': 3, 'state': 'disconnected'} 148 ], 149 'type': 'synce-eth-port' 150 }}] 151 152Only one child pin can provide its signal to the parent MUX-type pin at 153a time, the selection is done by requesting change of a child pin state 154on desired parent, with the use of ``DPLL_A_PIN_PARENT`` nested 155attribute. Example of netlink `set state on parent pin` message format: 156 157 ========================== ============================================= 158 ``DPLL_A_PIN_ID`` child pin id 159 ``DPLL_A_PIN_PARENT_PIN`` nested attribute for requesting configuration 160 related to parent pin 161 ``DPLL_A_PIN_PARENT_ID`` parent pin id 162 ``DPLL_A_PIN_STATE`` requested pin state on parent 163 ========================== ============================================= 164 165Pin priority 166============ 167 168Some devices might offer a capability of automatic pin selection mode 169(enum value ``DPLL_MODE_AUTOMATIC`` of ``DPLL_A_MODE`` attribute). 170Usually, automatic selection is performed on the hardware level, which 171means only pins directly connected to the dpll can be used for automatic 172input pin selection. 173In automatic selection mode, the user cannot manually select a input 174pin for the device, instead the user shall provide all directly 175connected pins with a priority ``DPLL_A_PIN_PRIO``, the device would 176pick a highest priority valid signal and use it to control the DPLL 177device. Example of netlink `set priority on parent pin` message format: 178 179 ============================ ============================================= 180 ``DPLL_A_PIN_ID`` configured pin id 181 ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting configuration 182 related to parent dpll device 183 ``DPLL_A_PIN_PARENT_ID`` parent dpll device id 184 ``DPLL_A_PIN_PRIO`` requested pin prio on parent dpll 185 ============================ ============================================= 186 187Child pin of MUX-type pin is not capable of automatic input pin selection, 188in order to configure active input of a MUX-type pin, the user needs to 189request desired pin state of the child pin on the parent pin, 190as described in the ``MUX-type pins`` chapter. 191 192Phase offset measurement and adjustment 193======================================== 194 195Device may provide ability to measure a phase difference between signals 196on a pin and its parent dpll device. If pin-dpll phase offset measurement 197is supported, it shall be provided with ``DPLL_A_PIN_PHASE_OFFSET`` 198attribute for each parent dpll device. The reported phase offset may be 199computed as the average of prior values and the current measurement, using 200the following formula: 201 202.. math:: 203 curr\_avg = prev\_avg * \frac{2^N-1}{2^N} + new\_val * \frac{1}{2^N} 204 205where `curr_avg` is the current reported phase offset, `prev_avg` is the 206previously reported value, `new_val` is the current measurement, and `N` is 207the averaging factor. Configured averaging factor value is provided with 208``DPLL_A_PHASE_OFFSET_AVG_FACTOR`` attribute of a device and value change can 209be requested with the same attribute with ``DPLL_CMD_DEVICE_SET`` command. 210 211 ================================== ====================================== 212 ``DPLL_A_PHASE_OFFSET_AVG_FACTOR`` attr configured value of phase offset 213 averaging factor 214 ================================== ====================================== 215 216Device may also provide ability to adjust a signal phase on a pin. 217If pin phase adjustment is supported, minimal and maximal values and 218granularity that pin handle shall be provided to the user on 219``DPLL_CMD_PIN_GET`` respond with ``DPLL_A_PIN_PHASE_ADJUST_MIN``, 220``DPLL_A_PIN_PHASE_ADJUST_MAX`` and ``DPLL_A_PIN_PHASE_ADJUST_GRAN`` 221attributes. Configured phase adjust value is provided with 222``DPLL_A_PIN_PHASE_ADJUST`` attribute of a pin, and value change can be 223requested with the same attribute with ``DPLL_CMD_PIN_SET`` command. 224 225 ================================ ========================================== 226 ``DPLL_A_PIN_ID`` configured pin id 227 ``DPLL_A_PIN_PHASE_ADJUST_GRAN`` attr granularity of phase adjustment value 228 ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase adjustment 229 ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase adjustment 230 ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase 231 adjustment on parent dpll device 232 ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting 233 configuration on given parent dpll 234 device 235 ``DPLL_A_PIN_PARENT_ID`` parent dpll device id 236 ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference 237 between a pin and parent dpll device 238 ================================ ========================================== 239 240All phase related values are provided in pico seconds, which represents 241time difference between signals phase. The negative value means that 242phase of signal on pin is earlier in time than dpll's signal. Positive 243value means that phase of signal on pin is later in time than signal of 244a dpll. 245 246Phase adjust (also min and max) values are integers, but measured phase 247offset values are fractional with 3-digit decimal places and shell be 248divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and 249modulo divided to get fractional part. 250 251Phase offset monitor 252==================== 253 254Phase offset measurement is typically performed against the current active 255source. However, some DPLL (Digital Phase-Locked Loop) devices may offer 256the capability to monitor phase offsets across all available inputs. 257The attribute and current feature state shall be included in the response 258message of the ``DPLL_CMD_DEVICE_GET`` command for supported DPLL devices. 259In such cases, users can also control the feature using the 260``DPLL_CMD_DEVICE_SET`` command by setting the ``enum dpll_feature_state`` 261values for the attribute. 262Once enabled the phase offset measurements for the input shall be returned 263in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute. 264 265 =============================== ======================== 266 ``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature 267 =============================== ======================== 268 269Fractional frequency offset 270=========================== 271 272The fractional frequency offset (FFO) is reported through two attributes 273that carry the same measurement at different precisions: 274 275- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET`` in PPM (parts per million) 276- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT`` in PPT (parts per trillion) 277 278Both attributes appear at the top level of a pin and inside each 279``pin-parent-device`` nest. Two FFO types are defined: 280 281- ``DPLL_FFO_PORT_RXTX_RATE`` - RX vs TX symbol rate offset (top-level) 282- ``DPLL_FFO_PIN_DEVICE`` - pin vs parent DPLL offset (per-parent) 283 284The driver declares which types it supports via the ``supported_ffo`` 285bitmask in ``struct dpll_pin_ops``. The core only calls the ``ffo_get`` 286callback for types the driver has opted into. The requested type is 287passed to the driver in the ``struct dpll_ffo_param``. 288 289Frequency monitor 290================= 291 292Some DPLL devices may offer the capability to measure the actual 293frequency of all available input pins. The attribute and current feature state 294shall be included in the response message of the ``DPLL_CMD_DEVICE_GET`` 295command for supported DPLL devices. In such cases, users can also control 296the feature using the ``DPLL_CMD_DEVICE_SET`` command by setting the 297``enum dpll_feature_state`` values for the attribute. 298Once enabled the measured input frequency for each input pin shall be 299returned in the ``DPLL_A_PIN_MEASURED_FREQUENCY`` attribute. The value 300is in millihertz (mHz), using ``DPLL_PIN_MEASURED_FREQUENCY_DIVIDER`` 301as the divider. 302 303 =============================== ======================== 304 ``DPLL_A_FREQUENCY_MONITOR`` attr state of a feature 305 =============================== ======================== 306 307Embedded SYNC 308============= 309 310Device may provide ability to use Embedded SYNC feature. It allows 311to embed additional SYNC signal into the base frequency of a pin - a one 312special pulse of base frequency signal every time SYNC signal pulse 313happens. The user can configure the frequency of Embedded SYNC. 314The Embedded SYNC capability is always related to a given base frequency 315and HW capabilities. The user is provided a range of Embedded SYNC 316frequencies supported, depending on current base frequency configured for 317the pin. 318 319 ========================================= ================================= 320 ``DPLL_A_PIN_ESYNC_FREQUENCY`` current Embedded SYNC frequency 321 ``DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED`` nest available Embedded SYNC 322 frequency ranges 323 ``DPLL_A_PIN_FREQUENCY_MIN`` attr minimum value of frequency 324 ``DPLL_A_PIN_FREQUENCY_MAX`` attr maximum value of frequency 325 ``DPLL_A_PIN_ESYNC_PULSE`` pulse type of Embedded SYNC 326 ========================================= ================================= 327 328Reference SYNC 329============== 330 331The device may support the Reference SYNC feature, which allows the combination 332of two inputs into a input pair. In this configuration, clock signals 333from both inputs are used to synchronize the DPLL device. The higher frequency 334signal is utilized for the loop bandwidth of the DPLL, while the lower frequency 335signal is used to syntonize the output signal of the DPLL device. This feature 336enables the provision of a high-quality loop bandwidth signal from an external 337source. 338 339A capable input provides a list of inputs that can be bound with to create 340Reference SYNC. To control this feature, the user must request a desired 341state for a target pin: use ``DPLL_PIN_STATE_CONNECTED`` to enable or 342``DPLL_PIN_STATE_DISCONNECTED`` to disable the feature. An input pin can be 343bound to only one other pin at any given time. 344 345 ============================== ========================================== 346 ``DPLL_A_PIN_REFERENCE_SYNC`` nested attribute for providing info or 347 requesting configuration of the Reference 348 SYNC feature 349 ``DPLL_A_PIN_ID`` target pin id for Reference SYNC feature 350 ``DPLL_A_PIN_STATE`` state of Reference SYNC connection 351 ============================== ========================================== 352 353Configuration commands group 354============================ 355 356Configuration commands are used to get information about registered 357dpll devices (and pins), as well as set configuration of device or pins. 358As dpll devices must be abstracted and reflect real hardware, 359there is no way to add new dpll device via netlink from user space and 360each device should be registered by its driver. 361 362All netlink commands require ``GENL_ADMIN_PERM``. This is to prevent 363any spamming/DoS from unauthorized userspace applications. 364 365List of netlink commands with possible attributes 366================================================= 367 368Constants identifying command types for dpll device uses a 369``DPLL_CMD_`` prefix and suffix according to command purpose. 370The dpll device related attributes use a ``DPLL_A_`` prefix and 371suffix according to attribute purpose. 372 373 ==================================== ================================= 374 ``DPLL_CMD_DEVICE_ID_GET`` command to get device ID 375 ``DPLL_A_MODULE_NAME`` attr module name of registerer 376 ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier 377 (EUI-64), as defined by the 378 IEEE 1588 standard 379 ``DPLL_A_TYPE`` attr type of dpll device 380 ==================================== ================================= 381 382 ==================================== ================================= 383 ``DPLL_CMD_DEVICE_GET`` command to get device info or 384 dump list of available devices 385 ``DPLL_A_ID`` attr unique dpll device ID 386 ``DPLL_A_MODULE_NAME`` attr module name of registerer 387 ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier 388 (EUI-64), as defined by the 389 IEEE 1588 standard 390 ``DPLL_A_MODE`` attr selection mode 391 ``DPLL_A_MODE_SUPPORTED`` attr available selection modes 392 ``DPLL_A_LOCK_STATUS`` attr dpll device lock status 393 ``DPLL_A_TEMP`` attr device temperature info 394 ``DPLL_A_TYPE`` attr type of dpll device 395 ==================================== ================================= 396 397 ==================================== ================================= 398 ``DPLL_CMD_DEVICE_SET`` command to set dpll device config 399 ``DPLL_A_ID`` attr internal dpll device index 400 ``DPLL_A_MODE`` attr selection mode to configure 401 ==================================== ================================= 402 403Constants identifying command types for pins uses a 404``DPLL_CMD_PIN_`` prefix and suffix according to command purpose. 405The pin related attributes use a ``DPLL_A_PIN_`` prefix and suffix 406according to attribute purpose. 407 408 ==================================== ================================= 409 ``DPLL_CMD_PIN_ID_GET`` command to get pin ID 410 ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer 411 ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier 412 (EUI-64), as defined by the 413 IEEE 1588 standard 414 ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided 415 by registerer 416 ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided 417 by registerer 418 ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided 419 by registerer 420 ``DPLL_A_PIN_TYPE`` attr type of a pin 421 ==================================== ================================= 422 423 ==================================== ================================== 424 ``DPLL_CMD_PIN_GET`` command to get pin info or dump 425 list of available pins 426 ``DPLL_A_PIN_ID`` attr unique a pin ID 427 ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer 428 ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier 429 (EUI-64), as defined by the 430 IEEE 1588 standard 431 ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided 432 by registerer 433 ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided 434 by registerer 435 ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided 436 by registerer 437 ``DPLL_A_PIN_TYPE`` attr type of a pin 438 ``DPLL_A_PIN_FREQUENCY`` attr current frequency of a pin 439 ``DPLL_A_PIN_FREQUENCY_SUPPORTED`` nested attr provides supported 440 frequencies 441 ``DPLL_A_PIN_ANY_FREQUENCY_MIN`` attr minimum value of frequency 442 ``DPLL_A_PIN_ANY_FREQUENCY_MAX`` attr maximum value of frequency 443 ``DPLL_A_PIN_PHASE_ADJUST_GRAN`` attr granularity of phase 444 adjustment value 445 ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase 446 adjustment 447 ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase 448 adjustment 449 ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase 450 adjustment on parent device 451 ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent device 452 the pin is connected with 453 ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id 454 ``DPLL_A_PIN_PRIO`` attr priority of pin on the 455 dpll device 456 ``DPLL_A_PIN_STATE`` attr state of pin on the parent 457 dpll device 458 ``DPLL_A_PIN_DIRECTION`` attr direction of a pin on the 459 parent dpll device 460 ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference 461 between a pin and parent dpll 462 ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin 463 the pin is connected with 464 ``DPLL_A_PIN_PARENT_ID`` attr parent pin id 465 ``DPLL_A_PIN_STATE`` attr state of pin on the parent 466 pin 467 ``DPLL_A_PIN_CAPABILITIES`` attr bitmask of pin capabilities 468 ``DPLL_A_PIN_MEASURED_FREQUENCY`` attr measured frequency of 469 an input pin in mHz 470 ==================================== ================================== 471 472 ==================================== ================================= 473 ``DPLL_CMD_PIN_SET`` command to set pins configuration 474 ``DPLL_A_PIN_ID`` attr unique a pin ID 475 ``DPLL_A_PIN_FREQUENCY`` attr requested frequency of a pin 476 ``DPLL_A_PIN_PHASE_ADJUST`` attr requested value of phase 477 adjustment on parent device 478 ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent dpll 479 device configuration request 480 ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id 481 ``DPLL_A_PIN_DIRECTION`` attr requested direction of a pin 482 ``DPLL_A_PIN_PRIO`` attr requested priority of pin on 483 the dpll device 484 ``DPLL_A_PIN_STATE`` attr requested state of pin on 485 the dpll device 486 ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin 487 configuration request 488 ``DPLL_A_PIN_PARENT_ID`` attr parent pin id 489 ``DPLL_A_PIN_STATE`` attr requested state of pin on 490 parent pin 491 ==================================== ================================= 492 493Netlink dump requests 494===================== 495 496The ``DPLL_CMD_DEVICE_GET`` and ``DPLL_CMD_PIN_GET`` commands are 497capable of dump type netlink requests, in which case the response is in 498the same format as for their ``do`` request, but every device or pin 499registered in the system is returned. 500 501SET commands format 502=================== 503 504``DPLL_CMD_DEVICE_SET`` - to target a dpll device, the user provides 505``DPLL_A_ID``, which is unique identifier of dpll device in the system, 506as well as parameter being configured (``DPLL_A_MODE``). 507 508``DPLL_CMD_PIN_SET`` - to target a pin user must provide a 509``DPLL_A_PIN_ID``, which is unique identifier of a pin in the system. 510Also configured pin parameters must be added. 511If ``DPLL_A_PIN_FREQUENCY`` is configured, it is a property of the pin 512itself and applies to all dpll devices the pin is registered with, so the 513frequency attribute shall not be enclosed in ``DPLL_A_PIN_PARENT_DEVICE``. 514Other attributes: ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE`` or 515``DPLL_A_PIN_DIRECTION`` must be enclosed in 516``DPLL_A_PIN_PARENT_DEVICE`` as their configuration relates to only one 517of parent dplls, targeted by ``DPLL_A_PIN_PARENT_ID`` attribute which is 518also required inside that nest. 519For MUX-type pins the ``DPLL_A_PIN_STATE`` attribute is configured in 520similar way, by enclosing required state in ``DPLL_A_PIN_PARENT_PIN`` 521nested attribute and targeted parent pin id in ``DPLL_A_PIN_PARENT_ID``. 522 523In general, it is possible to configure multiple parameters at once, but 524internally each parameter change will be invoked separately, where order 525of configuration is not guaranteed by any means. 526 527Configuration pre-defined enums 528=============================== 529 530.. kernel-doc:: include/uapi/linux/dpll.h 531 532Notifications 533============= 534 535dpll device can provide notifications regarding status changes of the 536device, i.e. lock status changes, input/output changes or other alarms. 537There is one multicast group that is used to notify user-space apps via 538netlink socket: ``DPLL_MCGRP_MONITOR`` 539 540Notifications messages: 541 542 ============================== ===================================== 543 ``DPLL_CMD_DEVICE_CREATE_NTF`` dpll device was created 544 ``DPLL_CMD_DEVICE_DELETE_NTF`` dpll device was deleted 545 ``DPLL_CMD_DEVICE_CHANGE_NTF`` dpll device has changed 546 ``DPLL_CMD_PIN_CREATE_NTF`` dpll pin was created 547 ``DPLL_CMD_PIN_DELETE_NTF`` dpll pin was deleted 548 ``DPLL_CMD_PIN_CHANGE_NTF`` dpll pin has changed 549 ============================== ===================================== 550 551Events format is the same as for the corresponding get command. 552Format of ``DPLL_CMD_DEVICE_`` events is the same as response of 553``DPLL_CMD_DEVICE_GET``. 554Format of ``DPLL_CMD_PIN_`` events is same as response of 555``DPLL_CMD_PIN_GET``. 556 557Device driver implementation 558============================ 559 560Device is allocated by dpll_device_get() call. Second call with the 561same arguments will not create new object but provides pointer to 562previously created device for given arguments, it also increases 563refcount of that object. 564Device is deallocated by dpll_device_put() call, which first 565decreases the refcount, once refcount is cleared the object is 566destroyed. 567 568Device should implement set of operations and register device via 569dpll_device_register() at which point it becomes available to the 570users. Multiple driver instances can obtain reference to it with 571dpll_device_get(), as well as register dpll device with their own 572ops and priv. 573 574The pins are allocated separately with dpll_pin_get(), it works 575similarly to dpll_device_get(). Function first creates object and then 576for each call with the same arguments only the object refcount 577increases. Also dpll_pin_put() works similarly to dpll_device_put(). 578 579A pin can be registered with parent dpll device or parent pin, depending 580on hardware needs. Each registration requires registerer to provide set 581of pin callbacks, and private data pointer for calling them: 582 583- dpll_pin_register() - register pin with a dpll device, 584- dpll_pin_on_pin_register() - register pin with another MUX type pin. 585 586Notifications of adding or removing dpll devices are created within 587subsystem itself. 588Notifications about registering/deregistering pins are also invoked by 589the subsystem. 590Notifications about status changes either of dpll device or a pin are 591invoked in two ways: 592 593- after successful change was requested on dpll subsystem, the subsystem 594 calls corresponding notification, 595- requested by device driver with dpll_device_change_ntf() or 596 dpll_pin_change_ntf() when driver informs about the status change. 597 598The device driver using dpll interface is not required to implement all 599the callback operation. Nevertheless, there are few required to be 600implemented. 601Required dpll device level callback operations: 602 603- ``.mode_get``, 604- ``.lock_status_get``. 605 606Required pin level callback operations: 607 608- ``.state_on_dpll_get`` (pins registered with dpll device), 609- ``.state_on_pin_get`` (pins registered with parent pin), 610- ``.direction_get``. 611 612Every other operation handler is checked for existence and 613``-EOPNOTSUPP`` is returned in case of absence of specific handler. 614 615The simplest implementation is in the OCP TimeCard driver. The ops 616structures are defined like this: 617 618.. code-block:: c 619 620 static const struct dpll_device_ops dpll_ops = { 621 .lock_status_get = ptp_ocp_dpll_lock_status_get, 622 .mode_get = ptp_ocp_dpll_mode_get, 623 .mode_supported = ptp_ocp_dpll_mode_supported, 624 }; 625 626 static const struct dpll_pin_ops dpll_pins_ops = { 627 .frequency_get = ptp_ocp_dpll_frequency_get, 628 .frequency_set = ptp_ocp_dpll_frequency_set, 629 .direction_get = ptp_ocp_dpll_direction_get, 630 .direction_set = ptp_ocp_dpll_direction_set, 631 .state_on_dpll_get = ptp_ocp_dpll_state_get, 632 }; 633 634The registration part is then looks like this part: 635 636.. code-block:: c 637 638 clkid = pci_get_dsn(pdev); 639 bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE); 640 if (IS_ERR(bp->dpll)) { 641 err = PTR_ERR(bp->dpll); 642 dev_err(&pdev->dev, "dpll_device_alloc failed\n"); 643 goto out; 644 } 645 646 err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp); 647 if (err) 648 goto out; 649 650 for (i = 0; i < OCP_SMA_NUM; i++) { 651 bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &bp->sma[i].dpll_prop); 652 if (IS_ERR(bp->sma[i].dpll_pin)) { 653 err = PTR_ERR(bp->dpll); 654 goto out_dpll; 655 } 656 657 err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, 658 &bp->sma[i]); 659 if (err) { 660 dpll_pin_put(bp->sma[i].dpll_pin); 661 goto out_dpll; 662 } 663 } 664 665In the error path we have to rewind every allocation in the reverse order: 666 667.. code-block:: c 668 669 while (i) { 670 --i; 671 dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]); 672 dpll_pin_put(bp->sma[i].dpll_pin); 673 } 674 dpll_device_put(bp->dpll); 675 676More complex example can be found in Intel's ICE driver or nVidia's mlx5 driver. 677 678SyncE enablement 679================ 680For SyncE enablement it is required to allow control over dpll device 681for a software application which monitors and configures the inputs of 682dpll device in response to current state of a dpll device and its 683inputs. 684In such scenario, dpll device input signal shall be also configurable 685to drive dpll with signal recovered from the PHY netdevice. 686This is done by exposing a pin to the netdevice - attaching pin to the 687netdevice itself with 688``dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)``. 689Exposed pin id handle ``DPLL_A_PIN_ID`` is then identifiable by the user 690as it is attached to rtnetlink respond to get ``RTM_NEWLINK`` command in 691nested attribute ``IFLA_DPLL_PIN``. 692