xref: /aosp_15_r20/external/pigweed/pw_clock_tree/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1.. _module-pw_clock_tree:
2
3================
4pw_clock_tree
5================
6.. pigweed-module::
7   :name: pw_clock_tree
8
9   - **Constinit compatible**: Clock tree elements can be declared as ``constinit``
10   - **Platform independent**: Clock tree management sits above the platform layer
11   - **Handles complex topologies**: Clock tree elements can be used to model
12     complex clock tree topologies
13
14``pw_clock_tree`` provides class definitions to implement a platform
15specific clock tree management solution. By passing the clock tree element
16that clocks a particular device to the corresponding device driver, the
17device driver can ensure that the clock is only enabled when required to
18maximize power savings.
19
20For example the clock tree functionality could be integrated into a uart device driver
21like this:
22
23.. literalinclude:: examples.cc
24   :language: cpp
25   :linenos:
26   :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversClassDef]
27   :end-before: // Device constructor that optionally accepts
28
29It could be initialized and used like this:
30
31.. literalinclude:: examples.cc
32   :language: cpp
33   :linenos:
34   :start-after: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage]
35   :end-before: [pw_clock_tree-examples-IntegrationIntoDeviceDriversUsage]
36
37.. grid:: 2
38
39   .. grid-item-card:: :octicon:`rocket` Quickstart
40      :link: module-pw_clock_tree-examples
41      :link-type: ref
42      :class-item: sales-pitch-cta-primary
43
44      Examples that show how to integrate a clock tree into a device driver,
45      and how to define and use platform specific clock tree elements.
46
47   .. grid-item-card:: :octicon:`code-square` Reference
48      :link: module-pw_clock_tree-reference
49      :link-type: ref
50      :class-item: sales-pitch-cta-secondary
51
52      API references for ``pw::clock_tree::Element``,
53      ``pw::clock_tree::DependentElement``, ``pw::clock_tree::ClockTree``,
54      and more.
55
56
57--------
58Overview
59--------
60.. cpp:namespace-push:: pw::clock_tree::ClockTree
61
62Pigweed's clock tree module provides the ability to represent the clock tree of an embedded
63device, and to manage the individual clocks and clock tree elements.
64
65The :cpp:class:`ClockTree` implements two basic methods that apply to all clock tree elements:
66
67* :cpp:func:`Acquire`
68* :cpp:func:`Release`
69
70In addition, clock divider elements can use the :cpp:func:`SetDividerValue` method to update the current
71clock divider value.
72
73.. cpp:namespace-pop::
74
75.. cpp:namespace-push:: pw::clock_tree::Element
76
77The clock tree module defines the :cpp:class:`Element` abstract class from which all
78other classes are derived from. The :cpp:class:`Element` abstract class implements basic reference
79counting methods :cpp:func:`IncRef` and :cpp:func:`DecRef`, but requires derived classes to use the
80reference counting methods to properly acquire and release references to clock
81tree elements. If an :cpp:class:`Element` reference is passed to a constructor of a
82derived :cpp:class:`Element`, the class object depends on the referenced :cpp:class:`Element` object.
83
84Three derived abstract classes are defined for :cpp:class:`Element`:
85
86.. cpp:namespace-pop::
87
88.. cpp:namespace-push:: pw::clock_tree
89
90* :cpp:class:`ElementBlocking` for clock tree elements that might block when acquired or released.
91  Acquiring or releasing such a clock tree element might fail.
92* :cpp:class:`ElementNonBlockingCannotFail` for clock tree elements that will not block when
93  acquired or released. Acquiring or releasing such a clock tree element will always succeed.
94* :cpp:class:`ElementNonBlockingMightFail` for clock tree elements that will not block when
95  acquired or released. Acquiring or releasing such a clock tree element might fail.
96
97:cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementsNonBlockingMightFail` elements can
98be acquired from an interrupt context.
99
100All classes representing a clock tree element should be implemented as a template and accept
101:cpp:class:`ElementBlocking`, :cpp:class:`ElementNonBlockingCannotFail` or
102:cpp:class:`ElementNonBlockingMightFail` as a template argument. Only if it is known at compile time
103that a clock tree element can only be either blocking or non-blocking, one can directly derive the
104class from :cpp:class:`ElementBlocking` or :cpp:class:`ElementNonBlockingCannotFail` /
105:cpp:class:`ElementNonBlockingMightFail`, respectively.
106
107.. cpp:namespace-pop::
108
109.. cpp:namespace-push:: pw::clock_tree::ElementController
110
111For ease of use :cpp:class:`ElementController` encapsulates :cpp:class:`ClockTree` and :cpp:class:`Element` into a single object and provides :cpp:func:`Acquire` and :cpp:func:`Release` methods that check whether both optional objects have been specified, and only if yes, call the respective :cpp:class:`ClockTree` methods, otherwise they return ``pw::OkStatus()``.
112
113.. cpp:namespace-pop::
114
115---------------
116Synchronization
117---------------
118.. cpp:namespace-push:: pw::clock_tree
119
120The clock tree class uses a mutex to serialize access to :cpp:class:`ElementBlocking` clock tree
121elements, and uses an interrupt spin lock to serialize access to
122:cpp:class:`ElementNonBlockingCannotFail` and :cpp:class:`ElementNonBlockingMightFail` clock tree
123elements. :cpp:class:`ElementBlocking` clock tree elements and
124:cpp:class:`ElementNonBlockingCannotFail` / :cpp:class:`ElementNonBlockingMightFail` clock tree
125elements are not serialized with each other, while :cpp:class:`ElementNonBlockingCannotFail` and
126:cpp:class:`ElementNonBlockingMightFail` are serialized with each other.
127
128.. cpp:namespace-pop::
129
130.. toctree::
131   :hidden:
132   :maxdepth: 1
133
134   examples
135   api
136   implementations
137