• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __SOC_NVIDIA_TEGRA124_CLOCK_H__
4 #define __SOC_NVIDIA_TEGRA124_CLOCK_H__
5 
6 #include <arch/hlt.h>
7 #include <console/console.h>
8 #include <device/mmio.h>
9 #include <soc/clk_rst.h>
10 #include <stdint.h>
11 
12 enum {
13 	CLK_L_CPU = 0x1 << 0,
14 	CLK_L_COP = 0x1 << 1,
15 	CLK_L_TRIG_SYS = 0x1 << 2,
16 	CLK_L_RTC = 0x1 << 4,
17 	CLK_L_TMR = 0x1 << 5,
18 	CLK_L_UARTA = 0x1 << 6,
19 	CLK_L_UARTB = 0x1 << 7,
20 	CLK_L_GPIO = 0x1 << 8,
21 	CLK_L_SDMMC2 = 0x1 << 9,
22 	CLK_L_SPDIF = 0x1 << 10,
23 	CLK_L_I2S1 = 0x1 << 11,
24 	CLK_L_I2C1 = 0x1 << 12,
25 	CLK_L_NDFLASH = 0x1 << 13,
26 	CLK_L_SDMMC1 = 0x1 << 14,
27 	CLK_L_SDMMC4 = 0x1 << 15,
28 	CLK_L_PWM = 0x1 << 17,
29 	CLK_L_I2S2 = 0x1 << 18,
30 	CLK_L_EPP = 0x1 << 19,
31 	CLK_L_VI = 0x1 << 20,
32 	CLK_L_2D = 0x1 << 21,
33 	CLK_L_USBD = 0x1 << 22,
34 	CLK_L_ISP = 0x1 << 23,
35 	CLK_L_3D = 0x1 << 24,
36 	CLK_L_DISP2 = 0x1 << 26,
37 	CLK_L_DISP1 = 0x1 << 27,
38 	CLK_L_HOST1X = 0x1 << 28,
39 	CLK_L_VCP = 0x1 << 29,
40 	CLK_L_I2S0 = 0x1 << 30,
41 	CLK_L_CACHE2 = 0x1 << 31,
42 
43 	CLK_H_MEM = 0x1 << 0,
44 	CLK_H_AHBDMA = 0x1 << 1,
45 	CLK_H_APBDMA = 0x1 << 2,
46 	CLK_H_KBC = 0x1 << 4,
47 	CLK_H_STAT_MON = 0x1 << 5,
48 	CLK_H_PMC = 0x1 << 6,
49 	CLK_H_FUSE = 0x1 << 7,
50 	CLK_H_KFUSE = 0x1 << 8,
51 	CLK_H_SBC1 = 0x1 << 9,
52 	CLK_H_SNOR = 0x1 << 10,
53 	CLK_H_JTAG2TBC = 0x1 << 11,
54 	CLK_H_SBC2 = 0x1 << 12,
55 	CLK_H_SBC3 = 0x1 << 14,
56 	CLK_H_I2C5 = 0x1 << 15,
57 	CLK_H_DSI = 0x1 << 16,
58 	CLK_H_HSI = 0x1 << 18,
59 	CLK_H_HDMI = 0x1 << 19,
60 	CLK_H_CSI = 0x1 << 20,
61 	CLK_H_I2C2 = 0x1 << 22,
62 	CLK_H_UARTC = 0x1 << 23,
63 	CLK_H_MIPI_CAL = 0x1 << 24,
64 	CLK_H_EMC = 0x1 << 25,
65 	CLK_H_USB2 = 0x1 << 26,
66 	CLK_H_USB3 = 0x1 << 27,
67 	CLK_H_MPE = 0x1 << 28,
68 	CLK_H_VDE = 0x1 << 29,
69 	CLK_H_BSEA = 0x1 << 30,
70 	CLK_H_BSEV = 0x1 << 31,
71 
72 	CLK_U_UARTD = 0x1 << 1,
73 	CLK_U_UARTE = 0x1 << 2,
74 	CLK_U_I2C3 = 0x1 << 3,
75 	CLK_U_SBC4 = 0x1 << 4,
76 	CLK_U_SDMMC3 = 0x1 << 5,
77 	CLK_U_PCIE = 0x1 << 6,
78 	CLK_U_OWR = 0x1 << 7,
79 	CLK_U_AFI = 0x1 << 8,
80 	CLK_U_CSITE = 0x1 << 9,
81 	CLK_U_PCIEXCLK = 0x1 << 10,
82 	CLK_U_AVPUCQ = 0x1 << 11,
83 	CLK_U_TRACECLKIN = 0x1 << 13,
84 	CLK_U_SOC_THERM = 0x1 << 14,
85 	CLK_U_DTV = 0x1 << 15,
86 	CLK_U_NAND_SPEED = 0x1 << 16,
87 	CLK_U_I2C_SLOW = 0x1 << 17,
88 	CLK_U_DSIB = 0x1 << 18,
89 	CLK_U_TSEC = 0x1 << 19,
90 	CLK_U_IRAMA = 0x1 << 20,
91 	CLK_U_IRAMB = 0x1 << 21,
92 	CLK_U_IRAMC = 0x1 << 22,
93 
94 	// Clock reset.
95 	CLK_U_EMUCIF = 0x1 << 23,
96 	// Clock enable.
97 	CLK_U_IRAMD = 0x1 << 23,
98 
99 	CLK_U_CRAM2 = 0x2 << 24,
100 	CLK_U_XUSB_HOST = 0x1 << 25,
101 	CLK_U_MSENC = 0x1 << 27,
102 	CLK_U_SUS_OUT = 0x1 << 28,
103 	CLK_U_DEV2_OUT = 0x1 << 29,
104 	CLK_U_DEV1_OUT = 0x1 << 30,
105 	CLK_U_XUSB_DEV = 0x1 << 31,
106 
107 	CLK_V_CPUG = 0x1 << 0,
108 	CLK_V_CPULP = 0x1 << 1,
109 	CLK_V_3D2 = 0x1 << 2,
110 	CLK_V_MSELECT = 0x1 << 3,
111 	CLK_V_I2S3 = 0x1 << 5,
112 	CLK_V_I2S4 = 0x1 << 6,
113 	CLK_V_I2C4 = 0x1 << 7,
114 	CLK_V_SBC5 = 0x1 << 8,
115 	CLK_V_SBC6 = 0x1 << 9,
116 	CLK_V_AUDIO = 0x1 << 10,
117 	CLK_V_APBIF = 0x1 << 11,
118 	CLK_V_DAM0 = 0x1 << 12,
119 	CLK_V_DAM1 = 0x1 << 13,
120 	CLK_V_DAM2 = 0x1 << 14,
121 	CLK_V_HDA2CODEC_2X = 0x1 << 15,
122 	CLK_V_ATOMICS = 0x1 << 16,
123 	CLK_V_ACTMON = 0x1 << 23,
124 	CLK_V_EXTPERIPH1 = 0x1 << 24,
125 	CLK_V_SATA = 0x1 << 28,
126 	CLK_V_HDA = 0x1 << 29,
127 
128 	CLK_W_HDA2HDMICODEC = 0x1 << 0,
129 	CLK_W_SATACOLD = 0x1 << 1,
130 	CLK_W_CEC = 0x1 << 8,
131 	CLK_W_XUSB_PADCTL = 0x1 << 14,
132 	CLK_W_ENTROPY = 0x1 << 21,
133 	CLK_W_AMX0 = 0x1 << 25,
134 	CLK_W_ADX0 = 0x1 << 26,
135 	CLK_W_DVFS = 0x1 << 27,
136 	CLK_W_XUSB_SS = 0x1 << 28,
137 	CLK_W_MC1 = 0x1 << 30,
138 	CLK_W_EMC1 = 0x1 << 31,
139 
140 	CLK_X_AFC0 = 0x1 << 31,
141 	CLK_X_AFC1 = 0x1 << 30,
142 	CLK_X_AFC2 = 0x1 << 29,
143 	CLK_X_AFC3 = 0x1 << 28,
144 	CLK_X_AFC4 = 0x1 << 27,
145 	CLK_X_AFC5 = 0x1 << 26,
146 	CLK_X_AMX1 = 0x1 << 25,
147 	CLK_X_GPU = 0x1 << 24,
148 	CLK_X_SOR0 = 0x1 << 22,
149 	CLK_X_DPAUX = 0x1 << 21,
150 	CLK_X_ADX1 = 0x1 << 20,
151 	CLK_X_VIC = 0x1 << 18,
152 	CLK_X_CLK72MHZ = 0x1 << 17,
153 	CLK_X_HDMI_AUDIO = 0x1 << 16,
154 	CLK_X_EMC_DLL = 0x1 << 14,
155 	CLK_X_VIM2_CLK = 0x1 << 11,
156 	CLK_X_I2C6 = 0x1 << 6,
157 	CLK_X_CAM_MCLK2 = 0x1 << 5,
158 	CLK_X_CAM_MCLK = 0x1 << 4,
159 	CLK_X_SPARE = 0x1 << 0,
160 };
161 
162 /* PLL stabilization delay in usec */
163 #define CLOCK_PLL_STABLE_DELAY_US 300
164 
165 #define IO_STABILIZATION_DELAY (2)
166 
167 /* Calculate clock fractional divider value from ref and target frequencies.
168  * This is for a U7.1 format. This is not well written up in the book and
169  * there have been some questions about this macro, so here we go.
170  * U7.1 format is defined as (ddddddd+1) + (h*.5)
171  * The lowest order bit is actually a fractional bit.
172  * Hence, the divider can be thought of as 9 bits.
173  * So:
174  * divider = ((ref/freq) << 1 - 1) (upper 7 bits) |
175  *	(ref/freq & 1) (low order half-bit)
176  * however we can't do fractional arithmetic ... these are integers!
177  * So we normalize by shifting the result left 1 bit, and extracting
178  * ddddddd and h directly to the returned u8.
179  * divider = 2*(ref/freq);
180  * We want to
181  * preserve 7 bits of divisor and one bit of fraction, in 8 bits, as well as
182  * subtract one from ddddddd. Since we computed ref*2, the dddddd is now nicely
183  * situated in the upper 7 bits, and the h is sitting there in the low order
184  * bit. To subtract 1 from ddddddd, just subtract 2 from the 8-bit number
185  * and voila, upper 7 bits are (ref/freq-1), and lowest bit is h. Since you
186  * will assign this to a u8, it gets nicely truncated for you.
187  */
188 #define CLK_DIVIDER(REF, FREQ)	(DIV_ROUND_UP(((REF) * 2), (FREQ)) - 2)
189 
190 /* Calculate clock frequency value from reference and clock divider value
191  * The discussion in the book is pretty lacking.
192  * The idea is that we need to divide a ref clock by a divisor
193  * in U7.1 format, where 7 upper bits are the integer
194  * and lowest order bit is a fraction.
195  * from the book, U7.1 is (ddddddd+1) + (h*.5)
196  * To normalize to an actual number, we might do this:
197  * ((d>>7+1)&0x7f) + (d&1 >> 1)
198  * but as you might guess, the low order bit would be lost.
199  * Since we can't express the fractional bit, we need to multiply it all by 2.
200  * ((d + 2)&0xfe) + (d & 1)
201  * Since we're just adding +2, the lowest order bit is preserved. Hence
202  * (d+2) is the same as ((d + 2)&0xfe) + (d & 1)
203  *
204  * Since you multiply denominator * 2 (by NOT shifting it),
205  * you multiply numerator * 2 to cancel it out.
206  */
207 #define CLK_FREQUENCY(REF, REG)	(((REF) * 2) / ((REG) + 2))
208 
_clock_set_div(u32 * reg,const char * name,u32 div,u32 div_mask,u32 src)209 static inline void _clock_set_div(u32 *reg, const char *name, u32 div,
210 				  u32 div_mask, u32 src)
211 {
212 	// The I2C and UART divisors are 16 bit while all the others are 8 bit.
213 	// The I2C clocks are handled by the specialized macro below, but the
214 	// UART clocks aren't. Don't use this function on UART clocks.
215 	if (div & ~div_mask) {
216 		printk(BIOS_ERR, "%s clock divisor overflow!", name);
217 		hlt();
218 	}
219 	clrsetbits32(reg, CLK_SOURCE_MASK | CLK_DIVISOR_MASK,
220 		     src << CLK_SOURCE_SHIFT | div);
221 }
222 
223 #define clock_configure_irregular_source(device, src, freq, src_id) \
224 	_clock_set_div(&clk_rst->clk_src_##device, #device, \
225 		CLK_DIVIDER(TEGRA_##src##_KHZ, freq), 0xff, src_id)
226 
227 /* Warning: Some devices just use different bits for the same sources for no
228  * apparent reason. *Always* double-check the TRM before trusting this macro. */
229 #define clock_configure_source(device, src, freq) \
230 	clock_configure_irregular_source(device, src, freq, src)
231 
232 /* The I2C divisors are not 7.1 divisors like the others, they divide by n + 1
233  * directly. Also, there are internal divisors in the I2C controller itself.
234  * We can deal with those here and make it easier to select what the actual
235  * bus frequency will be. The 0x19 value is the default divisor in the
236  * clk_divisor register in the controller, and 8 is just a magic number in the
237  * documentation.
238  */
239 #define clock_configure_i2c_scl_freq(device, src, freq) \
240 	_clock_set_div(&clk_rst->clk_src_##device, #device, \
241 		DIV_ROUND_UP(TEGRA_##src##_KHZ, (freq) * (0x19 + 1) * 8) - 1, \
242 		0xffff, src)
243 
244 enum clock_source {  /* Careful: Not true for all sources, always check TRM! */
245 	PLLP = 0,
246 	PLLC2 = 1,
247 	PLLC = 2,
248 	PLLD = 2,
249 	PLLC3 = 3,
250 	PLLA = 3,
251 	PLLM = 4,
252 	PLLD2 = 5,
253 	CLK_M = 6,
254 };
255 
256 /* soc-specific */
257 #define TEGRA_CLK_M_KHZ	 clock_get_osc_khz()
258 #define TEGRA_PLLX_KHZ   CONFIG_PLLX_KHZ
259 #define TEGRA_PLLP_KHZ   (408000)
260 #define TEGRA_PLLC_KHZ   (600000)
261 #define TEGRA_PLLD_KHZ   (925000)
262 #define TEGRA_PLLU_KHZ   (960000)
263 
264 #define TEGRA_SCLK_KHZ   (300000)
265 #define TEGRA_HCLK_RATIO 1
266 #define TEGRA_HCLK_KHZ   (TEGRA_SCLK_KHZ / (1 + TEGRA_HCLK_RATIO))
267 #define TEGRA_PCLK_RATIO 0
268 #define TEGRA_PCLK_KHZ   (TEGRA_HCLK_KHZ / (1 + TEGRA_PCLK_RATIO))
269 
270 int clock_get_osc_khz(void);
271 int clock_get_pll_input_khz(void);
272 u32 clock_display(u32 frequency);
273 void clock_early_uart(void);
274 void clock_external_output(int clk_id);
275 void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
276 		 u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source,
277 		 u32 same_freq);
278 void clock_cpu0_config(void *entry);
279 void clock_cpu0_remove_reset(void);
280 void clock_halt_avp(void);
281 void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x);
282 void clock_reset_l(u32 l);
283 void clock_reset_h(u32 h);
284 void clock_reset_u(u32 u);
285 void clock_reset_v(u32 v);
286 void clock_reset_w(u32 w);
287 void clock_reset_x(u32 x);
288 void clock_init(void);
289 void clock_init_arm_generic_timer(void);
290 void sor_clock_stop(void);
291 void sor_clock_start(void);
292 
293 #endif /* __SOC_NVIDIA_TEGRA124_CLOCK_H__ */
294