xref: /f-stack/freebsd/mips/mediatek/mtk_soc.c (revision 22ce4aff)
1 /*-
2  * Copyright (c) 2016 Stanislav Galabov.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/rman.h>
36 
37 #include <machine/fdt.h>
38 
39 #include <dev/ofw/openfirm.h>
40 #include <dev/ofw/ofw_bus.h>
41 #include <dev/ofw/ofw_bus_subr.h>
42 
43 #include <dev/fdt/fdt_common.h>
44 #include <dev/fdt/fdt_clock.h>
45 
46 #include <mips/mediatek/fdt_reset.h>
47 #include <mips/mediatek/mtk_sysctl.h>
48 #include <mips/mediatek/mtk_soc.h>
49 
50 static uint32_t mtk_soc_socid = MTK_SOC_UNKNOWN;
51 static uint32_t mtk_soc_uartclk = 0;
52 static uint32_t mtk_soc_cpuclk = MTK_CPU_CLK_880MHZ;
53 static uint32_t mtk_soc_timerclk = MTK_CPU_CLK_880MHZ / 2;
54 
55 static uint32_t mtk_soc_chipid0_3 = MTK_UNKNOWN_CHIPID0_3;
56 static uint32_t mtk_soc_chipid4_7 = MTK_UNKNOWN_CHIPID4_7;
57 
58 static const struct ofw_compat_data compat_data[] = {
59 	{ "ralink,rt2880-soc",		MTK_SOC_RT2880 },
60 	{ "ralink,rt3050-soc",		MTK_SOC_RT3050 },
61 	{ "ralink,rt3052-soc",		MTK_SOC_RT3052 },
62 	{ "ralink,rt3350-soc",		MTK_SOC_RT3350 },
63 	{ "ralink,rt3352-soc",		MTK_SOC_RT3352 },
64 	{ "ralink,rt3662-soc",		MTK_SOC_RT3662 },
65 	{ "ralink,rt3883-soc",		MTK_SOC_RT3883 },
66 	{ "ralink,rt5350-soc",		MTK_SOC_RT5350 },
67 	{ "ralink,mtk7620a-soc",	MTK_SOC_MT7620A },
68 	{ "ralink,mt7620a-soc",		MTK_SOC_MT7620A },
69 	{ "ralink,mtk7620n-soc",	MTK_SOC_MT7620N },
70 	{ "ralink,mt7620n-soc",		MTK_SOC_MT7620N },
71 	{ "mediatek,mtk7621-soc",	MTK_SOC_MT7621 },
72 	{ "mediatek,mt7621-soc",	MTK_SOC_MT7621 },
73 	{ "ralink,mt7621-soc",		MTK_SOC_MT7621 },
74 	{ "ralink,mtk7621-soc",		MTK_SOC_MT7621 },
75 	{ "ralink,mtk7628an-soc",	MTK_SOC_MT7628 },
76 	{ "mediatek,mt7628an-soc",	MTK_SOC_MT7628 },
77 	{ "ralink,mtk7688-soc",		MTK_SOC_MT7688 },
78 
79 	/* Sentinel */
80 	{ NULL,				MTK_SOC_UNKNOWN },
81 };
82 
83 static uint32_t
mtk_detect_cpuclk_rt2880(bus_space_tag_t bst,bus_space_handle_t bsh)84 mtk_detect_cpuclk_rt2880(bus_space_tag_t bst, bus_space_handle_t bsh)
85 {
86 	uint32_t val;
87 
88 	val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
89 	val >>= RT2880_CPU_CLKSEL_OFF;
90 	val &= RT2880_CPU_CLKSEL_MSK;
91 
92 	switch (val) {
93 	case 0:
94 		return (MTK_CPU_CLK_250MHZ);
95 	case 1:
96 		return (MTK_CPU_CLK_266MHZ);
97 	case 2:
98 		return (MTK_CPU_CLK_280MHZ);
99 	case 3:
100 		return (MTK_CPU_CLK_300MHZ);
101 	}
102 
103 	/* Never reached */
104 	return (0);
105 }
106 
107 static uint32_t
mtk_detect_cpuclk_rt305x(bus_space_tag_t bst,bus_space_handle_t bsh)108 mtk_detect_cpuclk_rt305x(bus_space_tag_t bst, bus_space_handle_t bsh)
109 {
110 	uint32_t val;
111 
112 	val = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3);
113 	if (val == RT3350_CHIPID0_3)
114 		return (MTK_CPU_CLK_320MHZ);
115 
116 	val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
117 	val >>= RT305X_CPU_CLKSEL_OFF;
118 	val &= RT305X_CPU_CLKSEL_MSK;
119 
120 	return ((val == 0) ? MTK_CPU_CLK_320MHZ : MTK_CPU_CLK_384MHZ);
121 }
122 
123 static uint32_t
mtk_detect_cpuclk_rt3352(bus_space_tag_t bst,bus_space_handle_t bsh)124 mtk_detect_cpuclk_rt3352(bus_space_tag_t bst, bus_space_handle_t bsh)
125 {
126 	uint32_t val;
127 
128 	val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
129 	val >>= RT3352_CPU_CLKSEL_OFF;
130 	val &= RT3352_CPU_CLKSEL_MSK;
131 
132 	if (val)
133 		return (MTK_CPU_CLK_400MHZ);
134 
135 	return (MTK_CPU_CLK_384MHZ);
136 }
137 
138 static uint32_t
mtk_detect_cpuclk_rt3883(bus_space_tag_t bst,bus_space_handle_t bsh)139 mtk_detect_cpuclk_rt3883(bus_space_tag_t bst, bus_space_handle_t bsh)
140 {
141 	uint32_t val;
142 
143 	val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
144 	val >>= RT3883_CPU_CLKSEL_OFF;
145 	val &= RT3883_CPU_CLKSEL_MSK;
146 
147 	switch (val) {
148 	case 0:
149 		return (MTK_CPU_CLK_250MHZ);
150 	case 1:
151 		return (MTK_CPU_CLK_384MHZ);
152 	case 2:
153 		return (MTK_CPU_CLK_480MHZ);
154 	case 3:
155 		return (MTK_CPU_CLK_500MHZ);
156 	}
157 
158 	/* Never reached */
159 	return (0);
160 }
161 
162 static uint32_t
mtk_detect_cpuclk_rt5350(bus_space_tag_t bst,bus_space_handle_t bsh)163 mtk_detect_cpuclk_rt5350(bus_space_tag_t bst, bus_space_handle_t bsh)
164 {
165 	uint32_t val1, val2;
166 
167 	val1 = val2 = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
168 
169 	val1 >>= RT5350_CPU_CLKSEL_OFF1;
170 	val2 >>= RT5350_CPU_CLKSEL_OFF2;
171 	val1 &= RT5350_CPU_CLKSEL_MSK;
172 	val2 &= RT5350_CPU_CLKSEL_MSK;
173 	val1 |= (val2 << 1);
174 
175 	switch (val1) {
176 	case 0:
177 		return (MTK_CPU_CLK_360MHZ);
178 	case 1:
179 		/* Reserved value, but we return UNKNOWN */
180 		return (MTK_CPU_CLK_UNKNOWN);
181 	case 2:
182 		return (MTK_CPU_CLK_320MHZ);
183 	case 3:
184 		return (MTK_CPU_CLK_300MHZ);
185 	}
186 
187 	/* Never reached */
188 	return (0);
189 }
190 
191 static uint32_t
mtk_detect_cpuclk_mt7620(bus_space_tag_t bst,bus_space_handle_t bsh)192 mtk_detect_cpuclk_mt7620(bus_space_tag_t bst, bus_space_handle_t bsh)
193 {
194 	uint32_t val, mul, div, res;
195 
196 	val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG1);
197 	if (val & MT7620_CPU_CLK_AUX0)
198 		return (MTK_CPU_CLK_480MHZ);
199 
200 	val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG0);
201 	if (!(val & MT7620_CPLL_SW_CFG))
202 		return (MTK_CPU_CLK_600MHZ);
203 
204 	mul = MT7620_PLL_MULT_RATIO_BASE + ((val >> MT7620_PLL_MULT_RATIO_OFF) &
205 	    MT7620_PLL_MULT_RATIO_MSK);
206 	div = (val >> MT7620_PLL_DIV_RATIO_OFF) & MT7620_PLL_DIV_RATIO_MSK;
207 
208 	if (div != MT7620_PLL_DIV_RATIO_MSK)
209 		div += MT7620_PLL_DIV_RATIO_BASE;
210 	else
211 		div = MT7620_PLL_DIV_RATIO_MAX;
212 
213 	res = (MT7620_XTAL_40 * mul) / div;
214 
215 	return (MTK_MHZ(res));
216 }
217 
218 static uint32_t
mtk_detect_cpuclk_mt7621(bus_space_tag_t bst,bus_space_handle_t bsh)219 mtk_detect_cpuclk_mt7621(bus_space_tag_t bst, bus_space_handle_t bsh)
220 {
221 	uint32_t val, div, res;
222 
223 	val = bus_space_read_4(bst, bsh, SYSCTL_CLKCFG0);
224 	if (val & MT7621_USES_MEMDIV) {
225 		div = bus_space_read_4(bst, bsh, MTK_MT7621_CLKDIV_REG);
226 		div >>= MT7621_MEMDIV_OFF;
227 		div &= MT7621_MEMDIV_MSK;
228 		div += MT7621_MEMDIV_BASE;
229 
230 		val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
231 		val >>= MT7621_CLKSEL_OFF;
232 		val &= MT7621_CLKSEL_MSK;
233 
234 		if (val >= MT7621_CLKSEL_25MHZ_VAL)
235 			res = div * MT7621_CLKSEL_25MHZ;
236 		else if (val >= MT7621_CLKSEL_20MHZ_VAL)
237 			res = div * MT7621_CLKSEL_20MHZ;
238 		else
239 			res = div * 0; /* XXX: not sure about this */
240 	} else {
241 		val = bus_space_read_4(bst, bsh, SYSCTL_CUR_CLK_STS);
242 		div = (val >> MT7621_CLK_STS_DIV_OFF) & MT7621_CLK_STS_MSK;
243 		val &= MT7621_CLK_STS_MSK;
244 
245 		res = (MT7621_CLK_STS_BASE * val) / div;
246 	}
247 
248 	return (MTK_MHZ(res));
249 }
250 
251 static uint32_t
mtk_detect_cpuclk_mt7628(bus_space_tag_t bst,bus_space_handle_t bsh)252 mtk_detect_cpuclk_mt7628(bus_space_tag_t bst, bus_space_handle_t bsh)
253 {
254 	uint32_t val;
255 
256 	val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
257 	val >>= MT7628_CPU_CLKSEL_OFF;
258 	val &= MT7628_CPU_CLKSEL_MSK;
259 
260 	if (val)
261 		return (MTK_CPU_CLK_580MHZ);
262 
263 	return (MTK_CPU_CLK_575MHZ);
264 }
265 
266 void
mtk_soc_try_early_detect(void)267 mtk_soc_try_early_detect(void)
268 {
269 	bus_space_tag_t bst;
270 	bus_space_handle_t bsh;
271 	uint32_t base;
272 	phandle_t node;
273 	int i;
274 
275 	if ((node = OF_finddevice("/")) == -1)
276 		return;
277 
278 	for (i = 0; compat_data[i].ocd_str != NULL; i++) {
279 		if (ofw_bus_node_is_compatible(node, compat_data[i].ocd_str)) {
280 			mtk_soc_socid = compat_data[i].ocd_data;
281 			break;
282 		}
283 	}
284 
285 	if (mtk_soc_socid == MTK_SOC_UNKNOWN) {
286 		/* We don't know the SoC, so we don't know how to get clocks */
287 		return;
288 	}
289 
290 	bst = fdtbus_bs_tag;
291 	if (mtk_soc_socid == MTK_SOC_RT2880)
292 		base = MTK_RT2880_BASE;
293 	else if (mtk_soc_socid == MTK_SOC_MT7621)
294 		base = MTK_MT7621_BASE;
295 	else
296 		base = MTK_DEFAULT_BASE;
297 
298 	if (bus_space_map(bst, base, MTK_DEFAULT_SIZE, 0, &bsh))
299 		return;
300 
301 	/* Get our CHIP ID */
302 	mtk_soc_chipid0_3 = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3);
303 	mtk_soc_chipid4_7 = bus_space_read_4(bst, bsh, SYSCTL_CHIPID4_7);
304 
305 	/* First, figure out the CPU clock */
306 	switch (mtk_soc_socid) {
307 	case MTK_SOC_RT2880:
308 		mtk_soc_cpuclk = mtk_detect_cpuclk_rt2880(bst, bsh);
309 		break;
310 	case MTK_SOC_RT3050:  /* fallthrough */
311 	case MTK_SOC_RT3052:
312 	case MTK_SOC_RT3350:
313 		mtk_soc_cpuclk = mtk_detect_cpuclk_rt305x(bst, bsh);
314 		break;
315 	case MTK_SOC_RT3352:
316 		mtk_soc_cpuclk = mtk_detect_cpuclk_rt3352(bst, bsh);
317 		break;
318 	case MTK_SOC_RT3662:  /* fallthrough */
319 	case MTK_SOC_RT3883:
320 		mtk_soc_cpuclk = mtk_detect_cpuclk_rt3883(bst, bsh);
321 		break;
322 	case MTK_SOC_RT5350:
323 		mtk_soc_cpuclk = mtk_detect_cpuclk_rt5350(bst, bsh);
324 		break;
325 	case MTK_SOC_MT7620A: /* fallthrough */
326 	case MTK_SOC_MT7620N:
327 		mtk_soc_cpuclk = mtk_detect_cpuclk_mt7620(bst, bsh);
328 		break;
329 	case MTK_SOC_MT7621:
330 		mtk_soc_cpuclk = mtk_detect_cpuclk_mt7621(bst, bsh);
331 		break;
332 	case MTK_SOC_MT7628:  /* fallthrough */
333 	case MTK_SOC_MT7688:
334 		mtk_soc_cpuclk = mtk_detect_cpuclk_mt7628(bst, bsh);
335 		break;
336 	default:
337 		/* We don't know the SoC, so we can't find the CPU clock */
338 		break;
339 	}
340 
341 	/* Now figure out the timer clock */
342 	if (mtk_soc_socid == MTK_SOC_MT7621) {
343 #ifdef notyet
344 		/*
345 		 * We use the GIC timer for timing source and its clock freq is
346 		 * the same as the CPU's clock freq
347 		 */
348 		mtk_soc_timerclk = mtk_soc_cpuclk;
349 #else
350 		/*
351 		 * When GIC timer and MIPS timer are ready to co-exist and
352 		 * GIC timer is actually implemented, we need to switch to it.
353 		 * Until then we use a fake GIC timer, which is actually a
354 		 * normal MIPS ticker, so the timer clock is half the CPU clock
355 		 */
356 		mtk_soc_timerclk = mtk_soc_cpuclk / 2;
357 #endif
358 	} else {
359 		/*
360 		 * We use the MIPS ticker for the rest for now, so
361 		 * the CPU clock is divided by 2
362 		 */
363 		mtk_soc_timerclk = mtk_soc_cpuclk / 2;
364 	}
365 
366 	switch (mtk_soc_socid) {
367 	case MTK_SOC_RT2880:
368 		mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_2;
369 		break;
370 	case MTK_SOC_RT3350:  /* fallthrough */
371 	case MTK_SOC_RT3050:  /* fallthrough */
372 	case MTK_SOC_RT3052:
373 		/* UART clock is CPU clock / 3 */
374 		mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_3;
375 		break;
376 	case MTK_SOC_RT3352:  /* fallthrough */
377 	case MTK_SOC_RT3662:  /* fallthrough */
378 	case MTK_SOC_RT3883:  /* fallthrough */
379 	case MTK_SOC_RT5350:  /* fallthrough */
380 	case MTK_SOC_MT7620A: /* fallthrough */
381 	case MTK_SOC_MT7620N: /* fallthrough */
382 	case MTK_SOC_MT7628:  /* fallthrough */
383 	case MTK_SOC_MT7688:
384 		/* UART clock is always 40MHz */
385 		mtk_soc_uartclk = MTK_UART_CLK_40MHZ;
386 		break;
387 	case MTK_SOC_MT7621:
388 		/* UART clock is always 50MHz */
389 		mtk_soc_uartclk = MTK_UART_CLK_50MHZ;
390 		break;
391 	default:
392 		/* We don't know the SoC, so we don't know the UART clock */
393 		break;
394 	}
395 
396 	bus_space_unmap(bst, bsh, MTK_DEFAULT_SIZE);
397 }
398 
399 void
mtk_soc_set_cpu_model(void)400 mtk_soc_set_cpu_model(void)
401 {
402 	int idx, offset = sizeof(mtk_soc_chipid0_3);
403 	char *chipid0_3 = (char *)(&mtk_soc_chipid0_3);
404 	char *chipid4_7 = (char *)(&mtk_soc_chipid4_7);
405 
406 	/*
407 	 * CHIPID is always 2x32 bit registers, containing the ASCII
408 	 * representation of the chip, so use that directly.
409 	 *
410 	 * The info is either pre-populated in mtk_soc_try_early_detect() or
411 	 * it is left at its default value of "unknown " if it could not be
412 	 * obtained for some reason.
413 	 */
414 	for (idx = 0; idx < offset; idx++) {
415 		cpu_model[idx] = chipid0_3[idx];
416 		cpu_model[idx + offset] = chipid4_7[idx];
417 	}
418 
419 	/* Null-terminate the string */
420 	cpu_model[2 * offset] = 0;
421 }
422 
423 uint32_t
mtk_soc_get_uartclk(void)424 mtk_soc_get_uartclk(void)
425 {
426 
427 	return mtk_soc_uartclk;
428 }
429 
430 uint32_t
mtk_soc_get_cpuclk(void)431 mtk_soc_get_cpuclk(void)
432 {
433 
434 	return mtk_soc_cpuclk;
435 }
436 
437 uint32_t
mtk_soc_get_timerclk(void)438 mtk_soc_get_timerclk(void)
439 {
440 
441 	return mtk_soc_timerclk;
442 }
443 
444 uint32_t
mtk_soc_get_socid(void)445 mtk_soc_get_socid(void)
446 {
447 
448 	return mtk_soc_socid;
449 }
450 
451 /*
452  * The following are generic reset and clock functions
453  */
454 
455 /* Default reset time is 100ms */
456 #define DEFAULT_RESET_TIME	100000
457 
458 int
mtk_soc_reset_device(device_t dev)459 mtk_soc_reset_device(device_t dev)
460 {
461 	int res;
462 
463 	res = fdt_reset_assert_all(dev);
464 	if (res == 0) {
465 		DELAY(DEFAULT_RESET_TIME);
466 		res = fdt_reset_deassert_all(dev);
467 		if (res == 0)
468 			DELAY(DEFAULT_RESET_TIME);
469 	}
470 
471 	return (res);
472 }
473 
474 int
mtk_soc_stop_clock(device_t dev)475 mtk_soc_stop_clock(device_t dev)
476 {
477 
478 	return (fdt_clock_disable_all(dev));
479 }
480 
481 int
mtk_soc_start_clock(device_t dev)482 mtk_soc_start_clock(device_t dev)
483 {
484 
485 	return (fdt_clock_enable_all(dev));
486 }
487 
488 int
mtk_soc_assert_reset(device_t dev)489 mtk_soc_assert_reset(device_t dev)
490 {
491 
492 	return (fdt_reset_assert_all(dev));
493 }
494 
495 int
mtk_soc_deassert_reset(device_t dev)496 mtk_soc_deassert_reset(device_t dev)
497 {
498 
499 	return (fdt_reset_deassert_all(dev));
500 }
501 
502 void
mtk_soc_reset(void)503 mtk_soc_reset(void)
504 {
505 
506 	mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1);
507 	mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0);
508 }
509