1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef MOD_PIK_CLOCK_H
9 #define MOD_PIK_CLOCK_H
10 
11 #include <fwk_element.h>
12 
13 #include <stdbool.h>
14 #include <stdint.h>
15 
16 /*!
17  * \addtogroup GroupModules Modules
18  * \{
19  */
20 
21 /*!
22  * \defgroup GroupPIKClock PIK Clock Driver
23  *
24  * \details A driver for clock devices that are part of a PIK.
25  *
26  * \{
27  */
28 
29 /*!
30  * \brief APIs provided by the driver.
31  */
32 enum mod_pik_clock_api_type {
33     /*! An implementation of the Clock HAL module's clock driver API */
34     MOD_PIK_CLOCK_API_TYPE_CLOCK,
35     /*! A low-level API for direct control of CSS clocks */
36     MOD_PIK_CLOCK_API_TYPE_CSS,
37     MOD_PIK_CLOCK_API_COUNT,
38 };
39 
40 /*!
41  * \brief Sub-types of PIK clock.
42  */
43 enum mod_pik_clock_type {
44     /*! A clock with a fixed source. Only its divider can be changed. */
45     MOD_PIK_CLOCK_TYPE_SINGLE_SOURCE,
46     /*! A clock with multiple, selectable sources and at least one divider. */
47     MOD_PIK_CLOCK_TYPE_MULTI_SOURCE,
48     /*!
49      * A clock with multiple, selectable sources, at least one divider, and
50      * support for modulation.
51      */
52     MOD_PIK_CLOCK_TYPE_CLUSTER,
53 };
54 
55 /*!
56  * \brief Divider register types.
57  */
58 enum mod_pik_clock_msclock_divider {
59     /*! Divider affecting the system PLL clock source. */
60     MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS,
61     /*! Divider affecting the private or external PLL clock sources. */
62     MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT,
63 };
64 
65 /*!
66  * \brief Selectable clock sources for multi-source clocks.
67  */
68 enum mod_pik_clock_msclock_source {
69     /*! The clock is gated */
70     MOD_PIK_CLOCK_MSCLOCK_SOURCE_GATED = 0,
71     /*! The clock source is set to the system reference clock */
72     MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSREFCLK = 1,
73     /*! The clock source is set to the system PLL clock */
74     MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK = 2,
75     /*! The clock source is set to a private PLL */
76     MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK = 4,
77     /*! Number of valid clock sources */
78     MOD_PIK_CLOCK_MSCLOCK_SOURCE_MAX
79 };
80 
81 /*!
82  * \brief Selectable clock sources for V8.2 cluster clocks.
83  */
84 enum mod_clusclock_source {
85     /*! The clock is gated */
86     MOD_PIK_CLOCK_CLUSCLK_SOURCE_GATED = 0,
87     /*! The clock source is set to the system reference clock */
88     MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK = 1,
89     /*! The clock source is set to a private cluster PLL */
90     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0  = 2,
91     /*! The clock source is set to a private cluster PLL */
92     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1  = 3,
93     /*! The clock source is set to a private cluster PLL */
94     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL2  = 4,
95     /*! The clock source is set to a private cluster PLL */
96     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL3  = 5,
97     /*! The clock source is set to a private cluster PLL */
98     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL4  = 6,
99     /*! The clock source is set to a private cluster PLL */
100     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL5  = 7,
101     /*! The clock source is set to a private cluster PLL */
102     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL6  = 8,
103     /*! The clock source is set to a private cluster PLL */
104     MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL7  = 9,
105     /*! The clock source is set to the system PLL clock */
106     MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSPLLCLK = 10,
107     /*! Number of valid clock sources */
108     MOD_PIK_CLOCK_CLUSCLK_SOURCE_MAX
109 };
110 
111 /*!
112  * \brief Selectable clock sources for GPU clocks.
113  */
114 enum mod_pik_clock_gpuclock_source {
115     /*! The clock is gated */
116     MOD_PIK_CLOCK_GPUCLK_SOURCE_GATED = 0,
117     /*! The clock source is set to the system reference clock */
118     MOD_PIK_CLOCK_GPUCLK_SOURCE_SYSREFCLK = 1,
119     /*! The clock source is set to the system PLL clock */
120     MOD_PIK_CLOCK_GPUCLK_SOURCE_SYSPLLCLK = 2,
121     /*! The clock source is set to the dedicated GPU PLL */
122     MOD_PIK_CLOCK_GPUCLK_SOURCE_GPUPLLCLK = 4,
123     /*! Number of valid clock sources */
124     MOD_PIK_CLOCK_GPUCLK_SOURCE_MAX
125 };
126 
127 /*!
128  * \brief Selectable clock sources for DPU scaler clocks.
129  */
130 enum mod_pik_clock_dpuclock_source {
131     /*! The clock is gated */
132     MOD_PIK_CLOCK_DPUCLK_SOURCE_GATED = 0,
133     /*! The clock source is set to the system reference clock */
134     MOD_PIK_CLOCK_DPUCLK_SOURCE_SYSREFCLK = 1,
135     /*! The clock source is set to the dedicated display PLL */
136     MOD_PIK_CLOCK_DPUCLK_SOURCE_DISPLAYPLLCLK = 2,
137     /*! The clock source is set to a pixel clock PLL */
138     MOD_PIK_CLOCK_DPUCLK_SOURCE_PIXELCLK = 4,
139     /*! Number of valid clock sources */
140     MOD_PIK_CLOCK_DPUCLK_SOURCE_MAX
141 };
142 
143 /*!
144  * \brief Selectable clock sources for the DPU AXI clock.
145  */
146 enum mod_pik_clock_aclkdpu_source {
147     /*! The clock is gated */
148     MOD_PIK_CLOCK_ACLKDPU_SOURCE_GATED = 0,
149     /*! The clock source is set to the system reference clock */
150     MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSREFCLK = 1,
151     /*! The clock source is set to the dedicated display PLL */
152     MOD_PIK_CLOCK_ACLKDPU_SOURCE_DISPLAYPLLCLK = 2,
153     /*! The clock source is set to the system PLL clock */
154     MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSPLLCLK = 4,
155     /*! Number of valid clock sources */
156     MOD_PIK_CLOCK_ACLKDPU_SOURCE_MAX
157 };
158 
159 /*!
160  * \brief Selectable clock sources for the video processor clock.
161  */
162 enum mod_pik_clock_vpuclk_source {
163     /*! The clock is gated */
164     MOD_PIK_CLOCK_VPUCLK_SOURCE_GATED = 0,
165     /*! The clock source is set to the system reference clock */
166     MOD_PIK_CLOCK_VPUCLK_SOURCE_SYSREFCLK = 1,
167     /*! The clock source is set to the system PLL clock */
168     MOD_PIK_CLOCK_VPUCLK_SOURCE_SYSPLLCLK = 2,
169     /*! The clock source is set to the dedicated video PLL */
170     MOD_PIK_CLOCK_VPUCLK_SOURCE_VIDEOPLLCLK = 4,
171     /*! Number of valid clock sources */
172     MOD_PIK_CLOCK_VPUCLK_SOURCE_MAX
173 };
174 
175 /*!
176  * \brief Selectable clock sources for interconnect clock.
177  */
178 enum mod_pik_clock_intclk_source {
179     /*! The clock is gated */
180     MOD_PIK_CLOCK_INTCLK_SOURCE_GATED = 0,
181     /*! The clock source is set to the system reference clock */
182     MOD_PIK_CLOCK_INTCLK_SOURCE_SYSREFCLK = 1,
183     /*! The clock source is set to a private PLL */
184     MOD_PIK_CLOCK_INTCLK_SOURCE_INTPLL = 2,
185 };
186 
187 /*!
188  * \brief Selectable clock sources for DMC clock.
189  */
190 enum mod_pik_clock_dmcclk_source {
191     /*! The clock is gated */
192     MOD_PIK_CLOCK_DMCCLK_SOURCE_GATED = 0,
193     /*! The clock source is set to the system reference clock */
194     MOD_PIK_CLOCK_DMCCLK_SOURCE_REFCLK = 1,
195     /*! The clock source is set to a private PLL */
196     MOD_PIK_CLOCK_DMCCLK_SOURCE_DDRPLL = 2,
197 };
198 
199 /*!
200  * \brief Divider bitfield width.
201  */
202 enum mod_pik_clock_divider_bitfield_width {
203     /*! PIK clock with 4-bit divider. */
204     MOD_PIK_CLOCK_DIVIDER_BITFIELD_WIDTH_4BITS = 4,
205     /*! PIK clock with 5-bit divider. */
206     MOD_PIK_CLOCK_DIVIDER_BITFIELD_WIDTH_5BITS = 5,
207 };
208 
209 /*!
210  * \brief PIK clock module configuration.
211  */
212 struct mod_pik_clock_module_config {
213     /*! The maximum divider value. */
214     unsigned int divider_max;
215 };
216 
217 
218 /*!
219  * \brief Rate lookup entry.
220  */
221 struct mod_pik_clock_rate {
222     /*! Rate in Hertz. */
223     uint64_t rate;
224     /*! Clock source used to obtain the rate (multi-source clocks only). */
225     uint8_t source;
226     /*! The divider register to use (multi-source clocks only). */
227     enum mod_pik_clock_msclock_divider divider_reg;
228     /*! Divider used to obtain the rate. */
229     uint8_t divider;
230 };
231 
232 /*!
233  * \brief Subsystem clock device configuration.
234  */
235 struct mod_pik_clock_dev_config {
236     /*! The type of the clock device. */
237     enum mod_pik_clock_type type;
238 
239     /*!
240      * \brief Indicates whether the clock is part of a CSS clock group (\c true)
241      *     or operating as an independent clock (\c false).
242      *
243      * \details The value determines the API that the clock exposes during
244      *      binding. If the clock is part of a group then the
245      *      ::MOD_PIK_CLOCK_API_TYPE_CSS API is exposed for direct control via
246      *      the CSS Clock module, otherwise the ::MOD_PIK_CLOCK_API_TYPE_CLOCK
247      *      API, defined by the Clock HAL, is exposed.
248      */
249     bool is_group_member;
250 
251     /*! Pointer to the clock's control register. */
252     volatile uint32_t * const control_reg;
253 
254     /*! Pointer to the clock's modulator register, if any. */
255     volatile uint32_t * const modulator_reg;
256 
257     /*! Pointer to the clock's DIV_SYS divider register, if any. */
258     volatile uint32_t * const divsys_reg;
259 
260     /*! Pointer to the clock's DIV_EXT divider register, if any. */
261     volatile uint32_t * const divext_reg;
262 
263     /*! Pointer to the clock's rate lookup table. */
264     const struct mod_pik_clock_rate *rate_table;
265 
266     /*! The number of rates in the rate lookup table. */
267     uint32_t rate_count;
268 
269     /*! The rate, in Hz, to set during module initialization. */
270     uint64_t initial_rate;
271 
272     /*!
273      * If \c true, the driver will not attempt to set a default frequency, or to
274      * otherwise configure the PLL during the pre-runtime phase. The PLL is
275      * expected to be initialized later in response to a notification or other
276      * event.
277      */
278     const bool defer_initialization;
279 };
280 
281 /*!
282  * \}
283  */
284 
285 /*!
286  * \}
287  */
288 
289 #endif /* MOD_PIK_CLOCK_H */
290