xref: /rk3399_ARM-atf/plat/intel/soc/stratix10/soc/s10_clock_manager.c (revision 394fa5d499fdfc1a0ddcaa3f2640cf5c49c25b63)
1 /*
2  * Copyright (c) 2019, Intel Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch.h>
8 #include <arch_helpers.h>
9 #include <assert.h>
10 #include <drivers/delay_timer.h>
11 #include <lib/mmio.h>
12 #include <platform_def.h>
13 #include <platform_private.h>
14 
15 #include "s10_clock_manager.h"
16 #include "s10_handoff.h"
17 
18 static const CLOCK_SOURCE_CONFIG  clk_source = {
19 	/* clk_freq_of_eosc1 */
20 	(uint32_t) 25000000,
21 	/* clk_freq_of_f2h_free */
22 	(uint32_t) 460000000,
23 	/* clk_freq_of_cb_intosc_ls */
24 	(uint32_t) 50000000,
25 };
26 
27 void wait_pll_lock(void)
28 {
29 	uint32_t data;
30 
31 	do {
32 		data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT);
33 	} while ((ALT_CLKMGR_STAT_MAINPLLLOCKED(data) == 0) ||
34 			(ALT_CLKMGR_STAT_PERPLLLOCKED(data) == 0));
35 }
36 
37 void wait_fsm(void)
38 {
39 	uint32_t data;
40 
41 	do {
42 		data = mmio_read_32(ALT_CLKMGR + ALT_CLKMGR_STAT);
43 	} while (ALT_CLKMGR_STAT_BUSY(data) == ALT_CLKMGR_STAT_BUSY_E_BUSY);
44 }
45 
46 void config_clkmgr_handoff(handoff *hoff_ptr)
47 {
48 	uint32_t m_div, refclk_div, mscnt, hscnt;
49 
50 	/* Bypass all mainpllgrp's clocks */
51 	mmio_write_32(ALT_CLKMGR_MAINPLL +
52 			ALT_CLKMGR_MAINPLL_BYPASS,
53 			0x7);
54 	wait_fsm();
55 	/* Bypass all perpllgrp's clocks */
56 	mmio_write_32(ALT_CLKMGR_PERPLL +
57 			ALT_CLKMGR_PERPLL_BYPASS,
58 			0x7f);
59 	wait_fsm();
60 
61 	/* Setup main PLL dividers */
62 	m_div = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(hoff_ptr->main_pll_fdbck);
63 	refclk_div = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(
64 			hoff_ptr->main_pll_pllglob);
65 	mscnt = 200 / ((6 + m_div) / refclk_div);
66 	hscnt = (m_div + 6) * mscnt / refclk_div - 9;
67 
68 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB,
69 			hoff_ptr->main_pll_pllglob);
70 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK,
71 			hoff_ptr->main_pll_fdbck);
72 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_VCOCALIB,
73 			ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(hscnt) |
74 			ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(mscnt));
75 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC0,
76 			hoff_ptr->main_pll_pllc0);
77 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1,
78 			hoff_ptr->main_pll_pllc1);
79 
80 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV,
81 			hoff_ptr->main_pll_nocdiv);
82 
83 	/* Setup peripheral PLL dividers */
84 	m_div = ALT_CLKMGR_PERPLL_FDBCK_MDIV(hoff_ptr->per_pll_fdbck);
85 	refclk_div = ALT_CLKMGR_PERPLL_PLLGLOB_REFCLKDIV(
86 			hoff_ptr->per_pll_pllglob);
87 	mscnt = 200 / ((6 + m_div) / refclk_div);
88 	hscnt = (m_div + 6) * mscnt / refclk_div - 9;
89 
90 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB,
91 			hoff_ptr->per_pll_pllglob);
92 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_FDBCK,
93 			hoff_ptr->per_pll_fdbck);
94 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_VCOCALIB,
95 			ALT_CLKMGR_PERPLL_VCOCALIB_HSCNT_SET(hscnt) |
96 			ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(mscnt));
97 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC0,
98 			hoff_ptr->per_pll_pllc0);
99 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1,
100 			hoff_ptr->per_pll_pllc1);
101 
102 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_GPIODIV,
103 			ALT_CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(
104 			hoff_ptr->per_pll_gpiodiv));
105 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EMACCTL,
106 			hoff_ptr->per_pll_emacctl);
107 
108 
109 	/* Take both PLL out of reset and power up */
110 	mmio_setbits_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB,
111 			ALT_CLKMGR_MAINPLL_PLLGLOB_PD_SET_MSK |
112 			ALT_CLKMGR_MAINPLL_PLLGLOB_RST_SET_MSK);
113 	mmio_setbits_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB,
114 			ALT_CLKMGR_PERPLL_PLLGLOB_PD_SET_MSK |
115 			ALT_CLKMGR_PERPLL_PLLGLOB_RST_SET_MSK);
116 
117 	wait_pll_lock();
118 
119 	/* Dividers for C2 to C9 only init after PLLs are lock. */
120 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK, 0xff);
121 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK, 0xff);
122 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK, 0xff);
123 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK, 0xff);
124 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK, 0xff);
125 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK, 0xff);
126 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK, 0xff);
127 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK, 0xff);
128 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK, 0xff);
129 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK, 0xff);
130 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK, 0xff);
131 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK, 0xff);
132 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK, 0xff);
133 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK, 0xff);
134 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK, 0xff);
135 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK, 0xff);
136 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK, 0xff);
137 
138 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_MPUCLK,
139 			hoff_ptr->main_pll_mpuclk);
140 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK,
141 			hoff_ptr->main_pll_nocclk);
142 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR2CLK,
143 			hoff_ptr->main_pll_cntr2clk);
144 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR3CLK,
145 			hoff_ptr->main_pll_cntr3clk);
146 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR4CLK,
147 			hoff_ptr->main_pll_cntr4clk);
148 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR5CLK,
149 			hoff_ptr->main_pll_cntr5clk);
150 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK,
151 			hoff_ptr->main_pll_cntr6clk);
152 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR7CLK,
153 			hoff_ptr->main_pll_cntr7clk);
154 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR8CLK,
155 			hoff_ptr->main_pll_cntr8clk);
156 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR9CLK,
157 			hoff_ptr->main_pll_cntr9clk);
158 
159 	/* Peripheral PLL Clock Source and Counters/Divider */
160 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR2CLK,
161 			hoff_ptr->per_pll_cntr2clk);
162 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR3CLK,
163 			hoff_ptr->per_pll_cntr3clk);
164 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR4CLK,
165 			hoff_ptr->per_pll_cntr4clk);
166 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR5CLK,
167 			hoff_ptr->per_pll_cntr5clk);
168 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR6CLK,
169 			hoff_ptr->per_pll_cntr6clk);
170 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR7CLK,
171 			hoff_ptr->per_pll_cntr7clk);
172 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR8CLK,
173 			hoff_ptr->per_pll_cntr8clk);
174 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_CNTR9CLK,
175 			hoff_ptr->per_pll_cntr9clk);
176 
177 	/* Take all PLLs out of bypass */
178 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_BYPASS, 0);
179 	wait_fsm();
180 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_BYPASS, 0);
181 	wait_fsm();
182 
183 	/* Set safe mode/ out of boot mode */
184 	mmio_clrbits_32(ALT_CLKMGR + ALT_CLKMGR_CTRL,
185 		ALT_CLKMGR_CTRL_BOOTMODE_SET_MSK);
186 	wait_fsm();
187 
188 	/* 10 Enable mainpllgrp's software-managed clock */
189 	mmio_write_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_EN,
190 			ALT_CLKMGR_MAINPLL_EN_RESET);
191 	mmio_write_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_EN,
192 			ALT_CLKMGR_PERPLL_EN_RESET);
193 
194 	/* Clear loss lock  interrupt status register that */
195 	/* might be set during configuration */
196 	mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR,
197 			ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK |
198 			ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);
199 }
200 
201 int get_wdt_clk(handoff *hoff_ptr)
202 {
203 	int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk;
204 	int data32, mdiv, refclkdiv, ref_clk;
205 
206 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB);
207 
208 	switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) {
209 	case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1:
210 		ref_clk = clk_source.clk_freq_of_eosc1;
211 		break;
212 	case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC:
213 		ref_clk = clk_source.clk_freq_of_cb_intosc_ls;
214 		break;
215 	case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S:
216 		ref_clk = clk_source.clk_freq_of_f2h_free;
217 		break;
218 	default:
219 		ref_clk = 0;
220 		assert(0);
221 		break;
222 	}
223 
224 	refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32);
225 	data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK);
226 	mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32);
227 	ref_clk = (ref_clk / refclkdiv) * (6 + mdiv);
228 
229 	main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff);
230 	l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1);
231 	l4_sys_free_clk = l3_main_free_clk / 4;
232 
233 	return l4_sys_free_clk;
234 }
235