xref: /rk3399_ARM-atf/drivers/ti/clk/include/ti_clk_pll.h (revision a28114d66a6d43db4accef5fd5d6dab6c059e584)
1 /*
2  * Copyright (c) 2025-2026 Texas Instruments Incorporated - https://www.ti.com
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * TI Generic PLL API Header
9  *
10  * This header defines the common PLL data structures and interfaces shared
11  * across different PLL variants. It provides PLL table entries, PLL data
12  * structures for configuration parameters (VCO ranges, dividers, multipliers),
13  * and the common PLL frequency calculation functions.
14  */
15 
16 #ifndef TI_CLK_PLL_H
17 #define TI_CLK_PLL_H
18 
19 #include <ti_clk.h>
20 #include <ti_devgrps.h>
21 
22 /*
23  * PLL table entry
24  *
25  * This describes a precomputed PLL setting. This should be preferred
26  * over brute force calculated settings. Additionally, PLL table entries
27  * can be outside spec'd PLL parameters such as minimum VCO frequency.
28  *
29  * Note that the input frequency is not specified but the input frequency
30  * range can be calculated from the given parameters.
31  *
32  * Current data type sizes are chosen based on currently supported PLLs.
33  * If support for an additional PLL with a larger range is added, then
34  * the data sizes will either need to increase or be selected at compile
35  * time.
36  */
37 struct ti_pll_table_entry {
38 	/* Minimum output frequency */
39 	uint32_t freq_min_hz;
40 
41 	/* Maximum output frequency */
42 	uint32_t freq_max_hz;
43 
44 	/* Multiplier setting */
45 	uint16_t pllm;
46 
47 	/* Input divider setting */
48 	uint8_t plld;
49 
50 	/* Output divider setting */
51 	uint8_t clkod;
52 
53 	/* Fractional multiplier part */
54 	uint32_t pllfm;
55 };
56 
57 /* The SoC specific table of precomputed PLL settings */
58 extern const struct ti_pll_table_entry ti_soc_pll_table[];
59 
60 /* PLL specific const clock data. */
61 struct ti_clk_data_pll {
62 	/* Common const clock data */
63 	struct ti_clk_drv_data data;
64 
65 	/*
66 	 * Precomputed PLL entries
67 	 *
68 	 * Points to an array of indexes into the PLL table. NULL if there are no
69 	 * entries.
70 	 */
71 	const uint8_t *pll_entries;
72 
73 	/*
74 	 * Number of PLL entries
75 	 *
76 	 * Number of valid entries in pll_entries array.
77 	 */
78 	size_t pll_entries_count;
79 
80 	/*
81 	 * VCO range.
82 	 *
83 	 * This points to the valid VCO frequency range in the range table.
84 	 */
85 	uint8_t vco_range_idx;
86 
87 	/*
88 	 * VCO input range.
89 	 *
90 	 * This points to the valid VCO input frequency range in the range
91 	 * table.
92 	 */
93 	uint8_t vco_in_range_idx;
94 
95 	/*
96 	 * Default frequency.
97 	 *
98 	 * This points to an index in the default frequency table. This
99 	 * allows the PLL to be programmed to a specific frequency at boot
100 	 * time. A table entry of 0 indicates that the current state of
101 	 * the hardware should be used.
102 	 */
103 	uint8_t default_freq_idx;
104 
105 	/*
106 	 * Device Group.
107 	 *
108 	 * Device group(s) this PLL is contained in or DEVGRP_ALL to
109 	 * indicate unspecified.
110 	 */
111 	devgrp_t devgrp;
112 
113 	/*
114 	 * Enable fractional support.
115 	 *
116 	 * True to enable fractional support if supported by this PLL. If
117 	 * this is false, fractional frequencies can still be read, but
118 	 * new fractional frequencies cannot be programmed.
119 	 */
120 	bool fractional_support;
121 };
122 
123 /* Const PLL data for use by the pll_calc function. */
124 struct ti_pll_data {
125 	/* Maximum PLL divider. */
126 	uint32_t plld_max;
127 
128 	/* Maximum PLL multiplier. */
129 	uint32_t pllm_max;
130 
131 	/* Bits of fractional PLL multiplier. */
132 	uint32_t pllfm_bits;
133 
134 	/* Maximum PLL post-divider. */
135 	uint32_t clkod_max;
136 
137 	/*
138 	 * Indicate if a divider is valid.
139 	 *
140 	 * Some PLLs cannot use all values in their range, such as odd or
141 	 * even values. This callback allows the pll_calc function to skip
142 	 * over invalid values.
143 	 */
144 	bool (*plld_valid)(struct ti_clk *clkp, uint32_t plld);
145 
146 	/*
147 	 * Indicate if a multiplier is valid.
148 	 *
149 	 * Some PLLs cannot use all values in their range, such as odd or
150 	 * even values. This callback allows the pll_calc function to skip
151 	 * over invalid values.
152 	 */
153 	bool (*pllm_valid)(struct ti_clk *clkp, uint32_t pllm, bool is_frac);
154 
155 	/*
156 	 * Stride value for a given pllm.
157 	 *
158 	 * Some PLLs have additional multipliers enabled to reach certain
159 	 * pllm values. Normally, these are handled by treating the values
160 	 * in between possible values as invalid. However, when dealing with
161 	 * fractional multipliers the pll_calc function must understand that
162 	 * the fractional multiplier will also be multiplied by this value.
163 	 *
164 	 * Provide the extra multiplier value that gets applied at a given
165 	 * pllm value.
166 	 */
167 	uint32_t (*pllm_stride)(struct ti_clk *clkp, uint32_t pllm);
168 
169 	/*
170 	 * Indicate if a post-divider is valid.
171 	 *
172 	 * Some PLLs cannot use all values in their range, such as odd or
173 	 * even values. This callback allows the pll_calc function to skip
174 	 * over invalid values.
175 	 */
176 	bool (*clkod_valid)(struct ti_clk *clkp, uint32_t clkod);
177 
178 	/*
179 	 * Indicate a bin for this setting combination.
180 	 *
181 	 * Some PLLs prefer certain combinations or ranges of settings over
182 	 * others, such as a multiplier below 512. Binning allows pll_calc
183 	 * to act on that preference. This function returns a bin number for
184 	 * each pllm/plld/clkod combination passed. pll_calc will always
185 	 * prefer a setting with a higher bin value over a lower bin value.
186 	 */
187 	int32_t (*bin)(struct ti_clk *clkp, uint32_t plld, uint32_t pllm,
188 		       bool is_frac, uint32_t clkod);
189 
190 	/*
191 	 * Try to find a larger pllm value that exists in a better bin
192 	 *
193 	 * The pll calculation code functions by testing every allowable plld
194 	 * and clkod combination. For each combination, it tests a pllm value
195 	 * that produces a frequency at or below the target, and a pllm value
196 	 * that produces a frequency above the target. However, this may skip
197 	 * certain plld/pllm/clkod combinations that are in a better bin.
198 	 * This function allows the pll driver code to return a larger pllm
199 	 * value that is in a better bin than the current pllm value. It
200 	 * will be called by the pll calculation code until it returns 0.
201 	 *
202 	 * Note that the pll calculation function will assume the pllm value
203 	 * returned is valid and will not call pllm_valid to test it.
204 	 */
205 	uint32_t (*bin_next_pllm)(struct ti_clk *clkp, uint32_t plld,
206 				  uint32_t pllm, uint32_t clkod);
207 
208 	/*
209 	 * Try to find a smaller pllm value that exists in a better bin
210 	 *
211 	 * The pll calculation code functions by testing every allowable plld
212 	 * and clkod combination. For each combination, it tests a pllm value
213 	 * that produces a frequency at or below the target, and a pllm value
214 	 * that produces a frequency above the target. However, this may skip
215 	 * certain plld/pllm/clkod combinations that are in a better bin.
216 	 * This function allows the pll driver code to return a smaller pllm
217 	 * value that is in a better bin than the current pllm value. It
218 	 * will be called by the pll calculation code until it returns 0.
219 	 *
220 	 * Note that the pll calculation function will assume the pllm value
221 	 * returned is valid and will not call pllm_valid to test it.
222 	 */
223 	uint32_t (*bin_prev_pllm)(struct ti_clk *clkp, uint32_t plld,
224 				  uint32_t pllm, uint32_t clkod);
225 
226 	/*
227 	 * Return fitness value based on VCO frequency.
228 	 *
229 	 * While PLLs already have a maximum and minimum allowable VCO
230 	 * frequency, many prefer certain VCO frequencies over others. If the
231 	 * bin and frequency delta of a given pllm/plld/clkod combination are
232 	 * identical, the vco_fitness function is used to pick a preferred
233 	 * combination.
234 	 */
235 	uint32_t (*vco_fitness)(struct ti_clk *clkp, uint32_t vco, bool is_frac);
236 };
237 
238 /**
239  * ti_pll_calc() - Calculate ideal PLL settings.
240  * @clk: The PLL to calculate settings for.
241  * @pll_data: The const parameters of the PLL that give allowable settings and preferences.
242  * @input: The input frequency in Hz.
243  * @output: The desired output frequency in Hz.
244  * @min: The minimum acceptable output frequency in Hz.
245  * @max: The maximum acceptable output frequency in Hz.
246  * @plld: Storage for generated divider value.
247  * @pllm: Storage for generated multiplier value.
248  * @pllfm: Storage for generated fractional multiplier value.
249  * @clkod: Storage for generated post-divider value.
250  *
251  * This calculates the ideal settings that can be used to generate an output
252  * frequenccy given an input frequency and PLL properties. It iterates through
253  * possible divider, multiplier, and post-divider values to find the best
254  * combination. Preferences are sorted by:
255  * - bin
256  * - frequency delta
257  * - VCO fitness
258  * Where bin is the bin value returned by the bin callback, frequency delta
259  * is the difference between the desired frequency and generated frequency,
260  * and VCO fitness is the fitness value returned by the vco_fitness callback.
261  *
262  * Return: Frequency produced with the calculated plld/pllm/clkod
263  *         values. 0 if no combination could produce an output
264  *         between min and max.
265  */
266 uint32_t ti_pll_calc(struct ti_clk *clkp, const struct ti_pll_data *pll_d,
267 		     uint32_t input, uint32_t output, uint32_t min, uint32_t max,
268 		     uint32_t *plld, uint32_t *pllm, uint32_t *pllfm,
269 		     uint32_t *clkod);
270 
271 /**
272  * ti_pll_init() - Base PLL initialization function
273  * @clk: The PLL to calculate settings for.
274  *
275  * This contains the common PLL initialization code. This includes setting
276  * the default frequency if applicable.
277  *
278  * Return: 0 on success, error code on error.
279  */
280 int32_t ti_pll_init(struct ti_clk *clkp);
281 
282 #endif /* TI_CLK_PLL_H */
283