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