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
50static uint32_t mtk_soc_socid = MTK_SOC_UNKNOWN;
51static uint32_t mtk_soc_uartclk = 0;
52static uint32_t mtk_soc_cpuclk = MTK_CPU_CLK_880MHZ;
53static uint32_t mtk_soc_timerclk = MTK_CPU_CLK_880MHZ / 2;
54
55static uint32_t mtk_soc_chipid0_3 = MTK_UNKNOWN_CHIPID0_3;
56static uint32_t mtk_soc_chipid4_7 = MTK_UNKNOWN_CHIPID4_7;
57
58static 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
83static uint32_t
84mtk_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
107static uint32_t
108mtk_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
123static uint32_t
124mtk_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
138static uint32_t
139mtk_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
162static uint32_t
163mtk_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
191static uint32_t
192mtk_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
218static uint32_t
219mtk_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
251static uint32_t
252mtk_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
266void
267mtk_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
399void
400mtk_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
423uint32_t
424mtk_soc_get_uartclk(void)
425{
426
427	return mtk_soc_uartclk;
428}
429
430uint32_t
431mtk_soc_get_cpuclk(void)
432{
433
434	return mtk_soc_cpuclk;
435}
436
437uint32_t
438mtk_soc_get_timerclk(void)
439{
440
441	return mtk_soc_timerclk;
442}
443
444uint32_t
445mtk_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
458int
459mtk_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
474int
475mtk_soc_stop_clock(device_t dev)
476{
477
478	return (fdt_clock_disable_all(dev));
479}
480
481int
482mtk_soc_start_clock(device_t dev)
483{
484
485	return (fdt_clock_enable_all(dev));
486}
487
488int
489mtk_soc_assert_reset(device_t dev)
490{
491
492	return (fdt_reset_assert_all(dev));
493}
494
495int
496mtk_soc_deassert_reset(device_t dev)
497{
498
499	return (fdt_reset_deassert_all(dev));
500}
501
502void
503mtk_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