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