Documentation/driver-api/dpll.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

The Linux kernel dpll subsystem

DPLL device/pin object, netlink command, pin selection·phase·Sync 기능과 driver lifecycle을 설명합니다.

Source pathDocumentation/driver-api/dpll.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

dpll.rst:1-635

Linux dpll subsystem은 NETLINK_GENERIC으로 Digital PLL device와 shared/MUX pin을 조회·구성하고 multicast notification을 제공합니다. manual/automatic pin selection, parent별 priority·state·direction, picosecond phase offset과 adjustment, Embedded/Reference SYNC를 명확한 nested attribute scope로 관리합니다. driver는 refcounted device/pin을 등록하고 필수 getter를 구현하며, error path에서 pin과 device allocation을 역순으로 해제해야 합니다. SyncE에서는 netdevice의 recovered clock pin을 DPLL에 연결하고 rtnetlink로 handle을 노출합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

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

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Linux kernel dpll subsystem과 DPLL 정의

1-18

SPDX license identifier는 `GPL-2.0`입니다.

PLL(Phase Locked Loop)은 device clock signal을 외부 clock signal에 syntonize해 PLL input과 같은 clock beat로 device를 동작시키는 electronic circuit입니다.

DPLL(Digital Phase Locked Loop)은 일반 PLL 동작에 digital phase detector를 포함하고 loop 안에 digital divider를 둘 수 있는 integrated circuit입니다. 따라서 DPLL input과 output frequency를 구성할 수 있습니다.

PLL과 DPLL
CircuitCore FunctionAdditional Capability
PLLSyntonize device clock to external inputSame clock beat
DPLLPLL behavior + digital phase detectorOptional divider and configurable I/O frequency

기본 clock 동기화와 digital phase/divider 기능을 비교했습니다.

Subsystem과 device object

19-45

dpll subsystem의 주 목적은 여러 input synchronization source와 여러 output type을 사용할 수 있는 Digital PLL device를 구성하는 general interface를 제공하는 것입니다. 주 interface는 event monitoring multicast group을 정의한 `NETLINK_GENERIC` protocol입니다.

dpll device object 하나는 Digital PLL circuit 하나와 연결된 pin 집합을 뜻합니다. `DPLL_CMD_DEVICE_GET` netlink command의 `do` request에는 지원 operation mode와 현재 status를 반환하고, 같은 command의 `dump` request에는 subsystem에 등록된 DPLL 목록을 반환합니다. `DPLL_CMD_DEVICE_SET`의 `do` request로 configuration을 변경합니다.

device handle은 `DPLL_A_ID`이며 특정 device의 configuration을 get/set할 때 제공해야 합니다. `DPLL_CMD_DEVICE_GET` dump 또는 하나의 device만 match하도록 attribute를 제공한 `DPLL_CMD_DEVICE_ID_GET` do request로 얻습니다.

DPLL device command
CommandRequestResult
DPLL_CMD_DEVICE_ID_GETdoResolve one DPLL_A_ID
DPLL_CMD_DEVICE_GETdo / dumpOne device / all registered devices
DPLL_CMD_DEVICE_SETdoChange device configuration

device 검색, 조회와 변경 request를 구분했습니다.

Pin object

46-64

pin은 input 또는 output을 나타내는 amorphic object이며 device 내부 component일 수도, 외부 연결일 수도 있습니다. dpll마다 pin 수는 다르지만 보통 device 하나에 여러 pin이 제공됩니다.

`DPLL_CMD_PIN_GET`의 do request는 pin property, capability와 status를 반환하고 dump request는 system에 등록된 모든 pin을 나열합니다. `DPLL_CMD_PIN_SET` do request로 configuration을 바꿉니다.

pin handle은 `DPLL_A_PIN_ID`이며 특정 pin을 get/set할 때 필요합니다. `DPLL_CMD_PIN_GET` dump 또는 하나의 pin만 match하도록 attribute를 제공한 `DPLL_CMD_PIN_ID_GET` do request로 얻습니다.

Pin selection

65-97

일반적으로 DPLL을 drive하는 selected pin은 `DPLL_A_PIN_STATE`에서 확인하며, dpll device마다 `DPLL_PIN_STATE_CONNECTED` 상태의 pin은 하나만 있어야 합니다.

pin selection은 hardware capability와 `DPLL_A_MODE`의 active work mode에 따라 manual 또는 automatic으로 수행합니다. mode마다 사용할 수 있는 pin state와 user가 요청할 수 있는 state가 다릅니다.

  • `DPLL_MODE_MANUAL`: `DPLL_PIN_STATE_CONNECTED`는 pin이 device를 drive함을, `DPLL_PIN_STATE_DISCONNECTED`는 사용하지 않음을 뜻합니다.
  • `DPLL_MODE_AUTOMATIC`: user가 `DPLL_PIN_STATE_SELECTABLE`로 automatic selection 후보에 포함하거나 `DPLL_PIN_STATE_DISCONNECTED`로 제외할 수 있습니다. selection algorithm이 input 하나에 lock한 뒤에만 user가 `DPLL_PIN_STATE_CONNECTED`를 receive할 수 있습니다.
DPLL pin state by mode
ModeUser May RequestConnected State
DPLL_MODE_MANUALCONNECTED or DISCONNECTEDUser directly selects driving pin
DPLL_MODE_AUTOMATICSELECTABLE or DISCONNECTEDReceived after algorithm locks

manual과 automatic mode에서 요청·수신할 수 있는 state를 비교했습니다.

Shared pin configuration scope

98-109

pin object 하나를 여러 dpll device에 attach할 수 있으며 configuration knob는 두 scope로 나뉩니다.

  • pin 자체에 설정: `DPLL_A_PIN_FREQUENCY`처럼 pin이 등록된 모든 dpll device에 영향을 줍니다.
  • pin-dpll tuple에 설정: `DPLL_A_PIN_PRIO`, `DPLL_A_PIN_STATE`, `DPLL_A_PIN_DIRECTION`처럼 선택한 dpll device에만 영향을 줍니다.
Shared pin configuration scope
ScopeAttributesAffected Objects
PinDPLL_A_PIN_FREQUENCYAll attached DPLLs
Pin-DPLL tuplePRIO, STATE, DIRECTIONSelected parent DPLL only

global pin 속성과 parent DPLL별 속성을 구분했습니다.

MUX-type pin

110-148

MUX-type pin은 child pin을 aggregate하는 pin multiplexer입니다. child는 dpll device에 직접 등록하는 대신 하나 이상의 MUX parent에 등록됩니다. 각 parent마다 `DPLL_A_PIN_PARENT_PIN` nested attribute를 제공합니다.

pin 하나가 여러 parent pin에 등록되면 multiple-output multiplexer처럼 동작하며 `DPLL_CMD_PIN_GET` 출력에 parent별 current state가 여러 nested attribute로 나타납니다.

attributes with current state related to each parent, like::

        'pin': [{{
          'clock-id': 282574471561216,
          'module-name': 'ice',
          'capabilities': 4,
          'id': 13,
          'parent-pin': [
          {'parent-id': 2, 'state': 'connected'},
          {'parent-id': 3, 'state': 'disconnected'}
          ],
          'type': 'synce-eth-port'
          }}]

한 번에 child pin 하나만 parent MUX에 signal을 제공할 수 있습니다. 원하는 parent에서 child state를 변경하도록 `DPLL_A_PIN_PARENT` nested attribute를 사용해 선택합니다.

Parent MUX state SET message
AttributeMeaning
DPLL_A_PIN_IDChild pin ID
DPLL_A_PIN_PARENT_PINParent-pin configuration nest
DPLL_A_PIN_PARENT_IDTarget parent pin ID inside nest
DPLL_A_PIN_STATERequested child state on parent

원문 attribute table을 nested request 구조로 보존했습니다.

Automatic mode pin priority

149-175

`DPLL_MODE_AUTOMATIC` capability가 있는 device는 보통 hardware에서 automatic selection을 수행하므로 dpll에 직접 연결된 pin만 automatic input 후보가 될 수 있습니다.

user는 input pin을 직접 선택하지 않고 직접 연결된 모든 pin에 `DPLL_A_PIN_PRIO`를 제공합니다. device는 유효 signal 가운데 priority가 가장 높은 것을 선택해 DPLL을 control합니다.

Parent DPLL priority SET message
AttributeMeaning
DPLL_A_PIN_IDConfigured pin ID
DPLL_A_PIN_PARENT_DEVICEParent DPLL configuration nest
DPLL_A_PIN_PARENT_IDTarget DPLL device ID
DPLL_A_PIN_PRIORequested priority on target DPLL

pin priority request의 parent-device nesting을 보존했습니다.

MUX-type의 child pin은 automatic input selection 대상이 아닙니다. active MUX input은 앞 절처럼 parent pin에서 원하는 child state를 요청해 구성합니다.

Phase offset 측정과 조정

176-234

device는 pin signal과 parent dpll 사이 phase difference를 측정할 수 있습니다. 지원된다면 parent별 `DPLL_A_PIN_PHASE_OFFSET`을 제공합니다. 보고 offset은 이전 평균과 현재 측정값으로 다음 식을 사용해 계산할 수 있습니다.

.. math::
   curr\_avg = prev\_avg * \frac{2^N-1}{2^N} + new\_val * \frac{1}{2^N}

`curr_avg`는 현재 보고값, `prev_avg`는 이전 보고값, `new_val`은 현재 측정값, `N`은 averaging factor입니다. device의 `DPLL_A_PHASE_OFFSET_AVG_FACTOR`가 factor를 제공하며 `DPLL_CMD_DEVICE_SET`에서 같은 attribute로 변경을 요청합니다.

pin phase adjustment를 지원하면 `DPLL_CMD_PIN_GET` 응답에 `DPLL_A_PIN_PHASE_ADJUST_MIN`, `DPLL_A_PIN_PHASE_ADJUST_MAX`, `DPLL_A_PIN_PHASE_ADJUST_GRAN`을 제공합니다. 현재 값은 `DPLL_A_PIN_PHASE_ADJUST`이고 `DPLL_CMD_PIN_SET`에서 같은 attribute로 변경합니다.

Phase measurement와 adjustment attribute
AttributeMeaning
DPLL_A_PHASE_OFFSET_AVG_FACTORConfigured averaging factor N
DPLL_A_PIN_PHASE_ADJUST_GRANAdjustment granularity
DPLL_A_PIN_PHASE_ADJUST_MIN / MAXAllowed adjustment range
DPLL_A_PIN_PHASE_ADJUSTConfigured adjustment value
DPLL_A_PIN_PARENT_DEVICE + PARENT_IDTarget parent DPLL
DPLL_A_PIN_PHASE_OFFSETMeasured pin-to-parent difference

평균화, 조정 범위와 parent별 측정값을 정리했습니다.

모든 phase 값은 signal phase의 시간 차이를 나타내는 picosecond 단위입니다. 음수는 pin signal이 dpll signal보다 빠르고 양수는 늦음을 뜻합니다. phase adjust와 min/max는 integer이지만 measured offset은 소수점 3자리의 fractional value입니다. `DPLL_PIN_PHASE_OFFSET_DIVIDER`로 나눈 몫이 integer part, 나머지가 fractional part입니다.

Phase offset monitor

235-252

phase offset은 보통 현재 active source를 기준으로 측정하지만 일부 DPLL은 모든 input을 monitor할 수 있습니다. 지원 device는 `DPLL_CMD_DEVICE_GET` 응답에 `DPLL_A_PHASE_OFFSET_MONITOR`와 current feature state를 포함합니다.

user는 `DPLL_CMD_DEVICE_SET`에서 이 attribute에 `enum dpll_feature_state` 값을 설정해 제어합니다. enable하면 input의 측정값을 `DPLL_A_PIN_PHASE_OFFSET`으로 반환합니다.

Embedded SYNC

253-273

Embedded SYNC는 pin의 base frequency에 추가 SYNC signal을 넣습니다. SYNC pulse가 발생할 때마다 base-frequency signal의 special pulse 하나를 삽입하며 user가 Embedded SYNC frequency를 구성할 수 있습니다.

capability는 현재 base frequency와 hardware capability에 종속됩니다. pin에 구성된 base frequency에 따라 지원 Embedded SYNC frequency range를 제공합니다.

Embedded SYNC attribute
AttributeMeaning
DPLL_A_PIN_ESYNC_FREQUENCYCurrent Embedded SYNC frequency
DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTEDNested supported ranges
DPLL_A_PIN_FREQUENCY_MIN / MAXRange bounds
DPLL_A_PIN_ESYNC_PULSEEmbedded SYNC pulse type

현재 frequency, 지원 range와 pulse type을 보존했습니다.

Reference SYNC

274-298

Reference SYNC는 input 두 개를 pair로 묶고 두 clock signal을 모두 사용해 DPLL을 synchronize합니다. 높은 frequency signal은 DPLL loop bandwidth에, 낮은 frequency signal은 output syntonization에 사용해 외부 source에서 고품질 loop bandwidth signal을 제공합니다.

지원 input은 결합 가능한 input 목록을 제공합니다. target pin state를 `DPLL_PIN_STATE_CONNECTED`로 요청하면 enable, `DISCONNECTED`로 요청하면 disable합니다. input pin 하나는 한 시점에 다른 pin 하나와만 결합할 수 있습니다.

Reference SYNC configuration
AttributeMeaning
DPLL_A_PIN_REFERENCE_SYNCFeature info/configuration nest
DPLL_A_PIN_IDTarget pin ID
DPLL_A_PIN_STATEConnected enables; disconnected disables

target pin과 connection state nested attribute를 보존했습니다.

Configuration command group와 permission

299-310

configuration command는 등록된 dpll device와 pin 정보를 얻고 configuration을 설정합니다. object는 실제 hardware를 반영해야 하므로 userspace가 netlink로 새 dpll device를 추가할 수 없고 각 driver가 등록해야 합니다.

모든 netlink command에는 `GENL_ADMIN_PERM`이 필요합니다. unauthorized userspace application의 spam/DoS를 방지하기 위한 것입니다.

Netlink command와 attribute 목록

311-436

device command는 `DPLL_CMD_`, device attribute는 `DPLL_A_`, pin command는 `DPLL_CMD_PIN_`, pin attribute는 `DPLL_A_PIN_` prefix를 사용하고 목적에 맞는 suffix를 붙입니다.

DPLL device netlink command catalog
CommandAttributes
DPLL_CMD_DEVICE_ID_GETDPLL_A_MODULE_NAME, DPLL_A_CLOCK_ID (IEEE 1588 EUI-64), DPLL_A_TYPE
DPLL_CMD_DEVICE_GETDPLL_A_ID, DPLL_A_MODULE_NAME, DPLL_A_CLOCK_ID, DPLL_A_MODE, DPLL_A_MODE_SUPPORTED, DPLL_A_LOCK_STATUS, DPLL_A_TEMP, DPLL_A_TYPE
DPLL_CMD_DEVICE_SETDPLL_A_ID, DPLL_A_MODE

원문 device command 표의 모든 attribute를 command별로 보존했습니다.

DPLL pin identity와 GET attribute
CommandAttributes
DPLL_CMD_PIN_ID_GETDPLL_A_PIN_MODULE_NAME, DPLL_A_PIN_CLOCK_ID, DPLL_A_PIN_BOARD_LABEL, DPLL_A_PIN_PANEL_LABEL, DPLL_A_PIN_PACKAGE_LABEL, DPLL_A_PIN_TYPE
DPLL_CMD_PIN_GET identityDPLL_A_PIN_ID, DPLL_A_PIN_MODULE_NAME, DPLL_A_PIN_CLOCK_ID, DPLL_A_PIN_BOARD_LABEL, DPLL_A_PIN_PANEL_LABEL, DPLL_A_PIN_PACKAGE_LABEL, DPLL_A_PIN_TYPE
DPLL_CMD_PIN_GET signalDPLL_A_PIN_FREQUENCY, DPLL_A_PIN_FREQUENCY_SUPPORTED{DPLL_A_PIN_ANY_FREQUENCY_MIN, DPLL_A_PIN_ANY_FREQUENCY_MAX}, DPLL_A_PIN_PHASE_ADJUST_GRAN, DPLL_A_PIN_PHASE_ADJUST_MIN, DPLL_A_PIN_PHASE_ADJUST_MAX, DPLL_A_PIN_PHASE_ADJUST
DPLL_CMD_PIN_GET parent deviceDPLL_A_PIN_PARENT_DEVICE{DPLL_A_PIN_PARENT_ID, DPLL_A_PIN_PRIO, DPLL_A_PIN_STATE, DPLL_A_PIN_DIRECTION, DPLL_A_PIN_PHASE_OFFSET}
DPLL_CMD_PIN_GET parent pinDPLL_A_PIN_PARENT_PIN{DPLL_A_PIN_PARENT_ID, DPLL_A_PIN_STATE}, DPLL_A_PIN_CAPABILITIES

PIN_ID_GET과 PIN_GET의 identity, property, phase, parent 정보를 보존했습니다.

DPLL_CMD_PIN_SET attribute
ScopeAttributes
Pin identity/globalDPLL_A_PIN_ID, DPLL_A_PIN_FREQUENCY, DPLL_A_PIN_PHASE_ADJUST
Parent DPLLDPLL_A_PIN_PARENT_DEVICE{DPLL_A_PIN_PARENT_ID, DPLL_A_PIN_DIRECTION, DPLL_A_PIN_PRIO, DPLL_A_PIN_STATE}
Parent MUX pinDPLL_A_PIN_PARENT_PIN{DPLL_A_PIN_PARENT_ID, DPLL_A_PIN_STATE}

global pin과 parent별 configuration request를 구분했습니다.

Netlink dump와 SET format

437-470

`DPLL_CMD_DEVICE_GET`과 `DPLL_CMD_PIN_GET`은 dump request를 지원합니다. response format은 do request와 같지만 system에 등록된 모든 device 또는 pin을 반환합니다.

  • `DPLL_CMD_DEVICE_SET`: system에서 unique한 `DPLL_A_ID`와 구성할 `DPLL_A_MODE`를 제공합니다.
  • `DPLL_CMD_PIN_SET`: unique `DPLL_A_PIN_ID`와 변경할 pin parameter를 제공합니다. `DPLL_A_PIN_FREQUENCY`는 연결된 모든 dpll에 영향을 주므로 `DPLL_A_PIN_PARENT_DEVICE` 안에 넣지 않습니다.
  • `DPLL_A_PIN_PRIO`, `STATE`, `DIRECTION`은 parent 하나에만 관련되므로 `DPLL_A_PIN_PARENT_DEVICE` 안에 넣고 같은 nest에 target `DPLL_A_PIN_PARENT_ID`도 제공합니다.
  • MUX child state는 `DPLL_A_PIN_PARENT_PIN` 안에 state와 target parent pin ID를 넣습니다.

여러 parameter를 한 번에 구성할 수 있지만 내부에서는 각 변경 handler를 따로 호출하며 실행 순서는 보장되지 않습니다.

PIN_SET nesting rule
AttributeLocationScope
FREQUENCYTop levelAll attached DPLLs
PRIO / STATE / DIRECTIONPARENT_DEVICE nestOne parent DPLL
MUX child STATEPARENT_PIN nestOne parent MUX pin

attribute가 영향을 주는 scope에 따라 nest 위치를 정리했습니다.

Pre-defined enum과 notification

471-500

configuration pre-defined enum은 `include/uapi/linux/dpll.h`의 kernel-doc에서 가져옵니다.

dpll device는 lock status, input/output 변화와 alarm 같은 status change를 `DPLL_MCGRP_MONITOR` multicast group으로 userspace netlink socket에 알립니다.

DPLL notification command
CommandEvent
DPLL_CMD_DEVICE_CREATE_NTFDevice created
DPLL_CMD_DEVICE_DELETE_NTFDevice deleted
DPLL_CMD_DEVICE_CHANGE_NTFDevice changed
DPLL_CMD_PIN_CREATE_NTFPin created
DPLL_CMD_PIN_DELETE_NTFPin deleted
DPLL_CMD_PIN_CHANGE_NTFPin changed

device와 pin create/delete/change event를 보존했습니다.

event format은 대응 GET command와 같습니다. `DPLL_CMD_DEVICE_` event는 `DPLL_CMD_DEVICE_GET`, `DPLL_CMD_PIN_` event는 `DPLL_CMD_PIN_GET` response format을 사용합니다.

Device driver object lifecycle와 callback

501-557

`dpll_device_get()`은 device를 할당합니다. 같은 argument로 다시 호출하면 새 object 대신 기존 pointer를 반환하고 refcount를 증가시킵니다. `dpll_device_put()`은 refcount를 줄이고 0이 되면 object를 destroy합니다.

operation set을 구현하고 `dpll_device_register()`로 등록하면 userspace에 공개됩니다. 여러 driver instance가 `dpll_device_get()`으로 같은 object reference를 얻고 자체 ops와 priv로 등록할 수 있습니다.

pin은 `dpll_pin_get()`으로 별도 할당하고 같은 argument의 후속 호출은 refcount만 늘립니다. `dpll_pin_put()`은 device put과 같은 방식입니다. hardware에 따라 `dpll_pin_register()`로 dpll device에, `dpll_pin_on_pin_register()`로 다른 MUX-type pin에 등록하며 각 registration은 callback set과 private data pointer가 필요합니다.

DPLL object lifecycle
dpll_device_get / dpll_pin_getregister ops + privsubsystem-visible objectunregisterput and destroy at refcount zero

get/register와 unregister/put의 refcount 순서를 나타냅니다.

device·pin 추가/제거 notification은 subsystem이 생성합니다. status change는 subsystem request가 성공한 뒤 자동 호출하거나 driver가 `dpll_device_change_ntf()` 또는 `dpll_pin_change_ntf()`를 호출하는 두 방식입니다.

모든 callback을 구현할 필요는 없지만 다음 callback은 필수입니다.

  • device level: `.mode_get`, `.lock_status_get`.
  • pin level: dpll device에 등록된 pin의 `.state_on_dpll_get`, parent pin에 등록된 pin의 `.state_on_pin_get`, `.direction_get`.

나머지 handler는 존재 여부를 검사하고 없으면 `-EOPNOTSUPP`를 반환합니다.

Required DPLL driver callback
LevelRequired Operations
Device.mode_get, .lock_status_get
Pin on DPLL.state_on_dpll_get, .direction_get
Pin on parent pin.state_on_pin_get, .direction_get

device와 pin registration별 필수 getter를 정리했습니다.

OCP TimeCard 구현과 error unwind

558-621

가장 단순한 구현은 OCP TimeCard driver이며 ops 구조체는 다음과 같습니다.

.. code-block:: c

        static const struct dpll_device_ops dpll_ops = {
                .lock_status_get = ptp_ocp_dpll_lock_status_get,
                .mode_get = ptp_ocp_dpll_mode_get,
                .mode_supported = ptp_ocp_dpll_mode_supported,
        };

        static const struct dpll_pin_ops dpll_pins_ops = {
                .frequency_get = ptp_ocp_dpll_frequency_get,
                .frequency_set = ptp_ocp_dpll_frequency_set,
                .direction_get = ptp_ocp_dpll_direction_get,
                .direction_set = ptp_ocp_dpll_direction_set,
                .state_on_dpll_get = ptp_ocp_dpll_state_get,
        };

device와 pin registration 예시는 다음과 같습니다.

.. code-block:: c

        clkid = pci_get_dsn(pdev);
        bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE);
        if (IS_ERR(bp->dpll)) {
                err = PTR_ERR(bp->dpll);
                dev_err(&pdev->dev, "dpll_device_alloc failed\n");
                goto out;
        }

        err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp);
        if (err)
                goto out;

        for (i = 0; i < OCP_SMA_NUM; i++) {
                bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &bp->sma[i].dpll_prop);
                if (IS_ERR(bp->sma[i].dpll_pin)) {
                        err = PTR_ERR(bp->dpll);
                        goto out_dpll;
                }

                err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops,
                                        &bp->sma[i]);
                if (err) {
                        dpll_pin_put(bp->sma[i].dpll_pin);
                        goto out_dpll;
                }
        }

error path에서는 모든 allocation을 역순으로 되돌려야 합니다.

.. code-block:: c

        while (i) {
                --i;
                dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]);
                dpll_pin_put(bp->sma[i].dpll_pin);
        }
        dpll_device_put(bp->dpll);

더 복잡한 예시는 Intel ICE driver와 NVIDIA mlx5 driver에서 찾을 수 있습니다.

SyncE enablement

622-635

SyncE를 enable하려면 dpll device와 input current state를 monitor하고 그에 맞춰 input을 구성하는 software application이 dpll device를 control할 수 있어야 합니다.

dpll input signal은 PHY netdevice에서 복구한 signal로 dpll을 drive하도록 구성할 수 있어야 합니다. `dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)`으로 pin을 netdevice 자체에 attach해 노출합니다.

노출된 `DPLL_A_PIN_ID` handle은 `RTM_NEWLINK` get response의 nested `IFLA_DPLL_PIN`에 붙으므로 user가 식별할 수 있습니다.

SyncE pin exposure
PHY netdevice recovered clockdpll_netdev_pin_set()DPLL pin drives device inputRTM_NEWLINK / IFLA_DPLL_PIN exposes DPLL_A_PIN_ID

PHY 복구 signal을 DPLL input과 rtnetlink handle로 연결하는 흐름입니다.