2 * Copyright (c) 2016 Stanislav Galabov.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
37 #include <machine/fdt.h>
39 #include <dev/ofw/openfirm.h>
40 #include <dev/ofw/ofw_bus.h>
41 #include <dev/ofw/ofw_bus_subr.h>
43 #include <dev/fdt/fdt_common.h>
44 #include <dev/fdt/fdt_clock.h>
46 #include <mips/mediatek/fdt_reset.h>
47 #include <mips/mediatek/mtk_sysctl.h>
48 #include <mips/mediatek/mtk_soc.h>
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;
55 static uint32_t mtk_soc_chipid0_3 = MTK_UNKNOWN_CHIPID0_3;
56 static uint32_t mtk_soc_chipid4_7 = MTK_UNKNOWN_CHIPID4_7;
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 },
80 { NULL, MTK_SOC_UNKNOWN },
84 mtk_detect_cpuclk_rt2880(bus_space_tag_t bst, bus_space_handle_t bsh)
88 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
89 val >>= RT2880_CPU_CLKSEL_OFF;
90 val &= RT2880_CPU_CLKSEL_MSK;
94 return (MTK_CPU_CLK_250MHZ);
96 return (MTK_CPU_CLK_266MHZ);
98 return (MTK_CPU_CLK_280MHZ);
100 return (MTK_CPU_CLK_300MHZ);
108 mtk_detect_cpuclk_rt305x(bus_space_tag_t bst, bus_space_handle_t bsh)
112 val = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3);
113 if (val == RT3350_CHIPID0_3)
114 return (MTK_CPU_CLK_320MHZ);
116 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
117 val >>= RT305X_CPU_CLKSEL_OFF;
118 val &= RT305X_CPU_CLKSEL_MSK;
120 return ((val == 0) ? MTK_CPU_CLK_320MHZ : MTK_CPU_CLK_384MHZ);
124 mtk_detect_cpuclk_rt3352(bus_space_tag_t bst, bus_space_handle_t bsh)
128 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
129 val >>= RT3352_CPU_CLKSEL_OFF;
130 val &= RT3352_CPU_CLKSEL_MSK;
133 return (MTK_CPU_CLK_400MHZ);
135 return (MTK_CPU_CLK_384MHZ);
139 mtk_detect_cpuclk_rt3883(bus_space_tag_t bst, bus_space_handle_t bsh)
143 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
144 val >>= RT3883_CPU_CLKSEL_OFF;
145 val &= RT3883_CPU_CLKSEL_MSK;
149 return (MTK_CPU_CLK_250MHZ);
151 return (MTK_CPU_CLK_384MHZ);
153 return (MTK_CPU_CLK_480MHZ);
155 return (MTK_CPU_CLK_500MHZ);
163 mtk_detect_cpuclk_rt5350(bus_space_tag_t bst, bus_space_handle_t bsh)
167 val1 = val2 = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
169 val1 >>= RT5350_CPU_CLKSEL_OFF1;
170 val2 >>= RT5350_CPU_CLKSEL_OFF2;
171 val1 &= RT5350_CPU_CLKSEL_MSK;
172 val2 &= RT5350_CPU_CLKSEL_MSK;
177 return (MTK_CPU_CLK_360MHZ);
179 /* Reserved value, but we return UNKNOWN */
180 return (MTK_CPU_CLK_UNKNOWN);
182 return (MTK_CPU_CLK_320MHZ);
184 return (MTK_CPU_CLK_300MHZ);
192 mtk_detect_cpuclk_mt7620(bus_space_tag_t bst, bus_space_handle_t bsh)
194 uint32_t val, mul, div, res;
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);
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);
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;
208 if (div != MT7620_PLL_DIV_RATIO_MSK)
209 div += MT7620_PLL_DIV_RATIO_BASE;
211 div = MT7620_PLL_DIV_RATIO_MAX;
213 res = (MT7620_XTAL_40 * mul) / div;
215 return (MTK_MHZ(res));
219 mtk_detect_cpuclk_mt7621(bus_space_tag_t bst, bus_space_handle_t bsh)
221 uint32_t val, div, res;
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;
230 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
231 val >>= MT7621_CLKSEL_OFF;
232 val &= MT7621_CLKSEL_MSK;
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;
239 res = div * 0; /* XXX: not sure about this */
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;
245 res = (MT7621_CLK_STS_BASE * val) / div;
248 return (MTK_MHZ(res));
252 mtk_detect_cpuclk_mt7628(bus_space_tag_t bst, bus_space_handle_t bsh)
256 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
257 val >>= MT7628_CPU_CLKSEL_OFF;
258 val &= MT7628_CPU_CLKSEL_MSK;
261 return (MTK_CPU_CLK_580MHZ);
263 return (MTK_CPU_CLK_575MHZ);
267 mtk_soc_try_early_detect(void)
270 bus_space_handle_t bsh;
275 if ((node = OF_finddevice("/")) == -1)
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;
285 if (mtk_soc_socid == MTK_SOC_UNKNOWN) {
286 /* We don't know the SoC, so we don't know how to get clocks */
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;
296 base = MTK_DEFAULT_BASE;
298 if (bus_space_map(bst, base, MTK_DEFAULT_SIZE, 0, &bsh))
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);
305 /* First, figure out the CPU clock */
306 switch (mtk_soc_socid) {
308 mtk_soc_cpuclk = mtk_detect_cpuclk_rt2880(bst, bsh);
310 case MTK_SOC_RT3050: /* fallthrough */
313 mtk_soc_cpuclk = mtk_detect_cpuclk_rt305x(bst, bsh);
316 mtk_soc_cpuclk = mtk_detect_cpuclk_rt3352(bst, bsh);
318 case MTK_SOC_RT3662: /* fallthrough */
320 mtk_soc_cpuclk = mtk_detect_cpuclk_rt3883(bst, bsh);
323 mtk_soc_cpuclk = mtk_detect_cpuclk_rt5350(bst, bsh);
325 case MTK_SOC_MT7620A: /* fallthrough */
326 case MTK_SOC_MT7620N:
327 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7620(bst, bsh);
330 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7621(bst, bsh);
332 case MTK_SOC_MT7628: /* fallthrough */
334 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7628(bst, bsh);
337 /* We don't know the SoC, so we can't find the CPU clock */
341 /* Now figure out the timer clock */
342 if (mtk_soc_socid == MTK_SOC_MT7621) {
345 * We use the GIC timer for timing source and its clock freq is
346 * the same as the CPU's clock freq
348 mtk_soc_timerclk = mtk_soc_cpuclk;
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
356 mtk_soc_timerclk = mtk_soc_cpuclk / 2;
360 * We use the MIPS ticker for the rest for now, so
361 * the CPU clock is divided by 2
363 mtk_soc_timerclk = mtk_soc_cpuclk / 2;
366 switch (mtk_soc_socid) {
368 mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_2;
370 case MTK_SOC_RT3350: /* fallthrough */
371 case MTK_SOC_RT3050: /* fallthrough */
373 /* UART clock is CPU clock / 3 */
374 mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_3;
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 */
384 /* UART clock is always 40MHz */
385 mtk_soc_uartclk = MTK_UART_CLK_40MHZ;
388 /* UART clock is always 50MHz */
389 mtk_soc_uartclk = MTK_UART_CLK_50MHZ;
392 /* We don't know the SoC, so we don't know the UART clock */
396 bus_space_unmap(bst, bsh, MTK_DEFAULT_SIZE);
399 extern char cpu_model[];
402 mtk_soc_set_cpu_model(void)
404 int idx, offset = sizeof(mtk_soc_chipid0_3);
405 char *chipid0_3 = (char *)(&mtk_soc_chipid0_3);
406 char *chipid4_7 = (char *)(&mtk_soc_chipid4_7);
409 * CHIPID is always 2x32 bit registers, containing the ASCII
410 * representation of the chip, so use that directly.
412 * The info is either pre-populated in mtk_soc_try_early_detect() or
413 * it is left at its default value of "unknown " if it could not be
414 * obtained for some reason.
416 for (idx = 0; idx < offset; idx++) {
417 cpu_model[idx] = chipid0_3[idx];
418 cpu_model[idx + offset] = chipid4_7[idx];
421 /* Null-terminate the string */
422 cpu_model[2 * offset] = 0;
426 mtk_soc_get_uartclk(void)
429 return mtk_soc_uartclk;
433 mtk_soc_get_cpuclk(void)
436 return mtk_soc_cpuclk;
440 mtk_soc_get_timerclk(void)
443 return mtk_soc_timerclk;
447 mtk_soc_get_socid(void)
450 return mtk_soc_socid;
454 * The following are generic reset and clock functions
457 /* Default reset time is 100ms */
458 #define DEFAULT_RESET_TIME 100000
461 mtk_soc_reset_device(device_t dev)
465 res = fdt_reset_assert_all(dev);
467 DELAY(DEFAULT_RESET_TIME);
468 res = fdt_reset_deassert_all(dev);
470 DELAY(DEFAULT_RESET_TIME);
477 mtk_soc_stop_clock(device_t dev)
480 return (fdt_clock_disable_all(dev));
484 mtk_soc_start_clock(device_t dev)
487 return (fdt_clock_enable_all(dev));
491 mtk_soc_assert_reset(device_t dev)
494 return (fdt_reset_assert_all(dev));
498 mtk_soc_deassert_reset(device_t dev)
501 return (fdt_reset_deassert_all(dev));
508 mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1);
509 mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0);