dpll.rst 26 KB

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