]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/mediatek/mtk_soc.c
Merge OpenSSL 1.1.1d.
[FreeBSD/FreeBSD.git] / sys / mips / mediatek / mtk_soc.c
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
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
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
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
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
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
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
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
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
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 extern char cpu_model[];
400
401 void
402 mtk_soc_set_cpu_model(void)
403 {
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);
407
408         /*
409          * CHIPID is always 2x32 bit registers, containing the ASCII
410          * representation of the chip, so use that directly.
411          *
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.
415          */
416         for (idx = 0; idx < offset; idx++) {
417                 cpu_model[idx] = chipid0_3[idx];
418                 cpu_model[idx + offset] = chipid4_7[idx];
419         }
420
421         /* Null-terminate the string */
422         cpu_model[2 * offset] = 0;
423 }
424
425 uint32_t
426 mtk_soc_get_uartclk(void)
427 {
428
429         return mtk_soc_uartclk;
430 }
431
432 uint32_t
433 mtk_soc_get_cpuclk(void)
434 {
435
436         return mtk_soc_cpuclk;
437 }
438
439 uint32_t
440 mtk_soc_get_timerclk(void)
441 {
442
443         return mtk_soc_timerclk;
444 }
445
446 uint32_t
447 mtk_soc_get_socid(void)
448 {
449
450         return mtk_soc_socid;
451 }
452
453 /*
454  * The following are generic reset and clock functions
455  */
456
457 /* Default reset time is 100ms */
458 #define DEFAULT_RESET_TIME      100000
459
460 int
461 mtk_soc_reset_device(device_t dev)
462 {
463         int res;
464
465         res = fdt_reset_assert_all(dev);
466         if (res == 0) {
467                 DELAY(DEFAULT_RESET_TIME);
468                 res = fdt_reset_deassert_all(dev);
469                 if (res == 0)
470                         DELAY(DEFAULT_RESET_TIME);
471         }
472
473         return (res);
474 }
475
476 int
477 mtk_soc_stop_clock(device_t dev)
478 {
479
480         return (fdt_clock_disable_all(dev));
481 }
482
483 int
484 mtk_soc_start_clock(device_t dev)
485 {
486
487         return (fdt_clock_enable_all(dev));
488 }
489
490 int
491 mtk_soc_assert_reset(device_t dev)
492 {
493
494         return (fdt_reset_assert_all(dev));
495 }
496
497 int
498 mtk_soc_deassert_reset(device_t dev)
499 {
500
501         return (fdt_reset_deassert_all(dev));
502 }
503
504 void
505 mtk_soc_reset(void)
506 {
507
508         mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1);
509         mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0);
510 }