]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/mediatek/mtk_soc.c
MFV r329713: 8731 ASSERT3U(nui64s, <=, UINT16_MAX) fails for large blocks
[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 const struct ofw_compat_data compat_data[] = {
56         { "ralink,rt2880-soc",          MTK_SOC_RT2880 },
57         { "ralink,rt3050-soc",          MTK_SOC_RT3050 },
58         { "ralink,rt3052-soc",          MTK_SOC_RT3052 },
59         { "ralink,rt3350-soc",          MTK_SOC_RT3350 },
60         { "ralink,rt3352-soc",          MTK_SOC_RT3352 },
61         { "ralink,rt3662-soc",          MTK_SOC_RT3662 },
62         { "ralink,rt3883-soc",          MTK_SOC_RT3883 },
63         { "ralink,rt5350-soc",          MTK_SOC_RT5350 },
64         { "ralink,mtk7620a-soc",        MTK_SOC_MT7620A },
65         { "ralink,mt7620a-soc",         MTK_SOC_MT7620A },
66         { "ralink,mtk7620n-soc",        MTK_SOC_MT7620N },
67         { "ralink,mt7620n-soc",         MTK_SOC_MT7620N },
68         { "mediatek,mtk7621-soc",       MTK_SOC_MT7621 },
69         { "mediatek,mt7621-soc",        MTK_SOC_MT7621 },
70         { "ralink,mt7621-soc",          MTK_SOC_MT7621 },
71         { "ralink,mtk7621-soc",         MTK_SOC_MT7621 },
72         { "ralink,mtk7628an-soc",       MTK_SOC_MT7628 },
73         { "mediatek,mt7628an-soc",      MTK_SOC_MT7628 },
74         { "ralink,mtk7688-soc",         MTK_SOC_MT7688 },
75
76         /* Sentinel */
77         { NULL,                         MTK_SOC_UNKNOWN },
78 };
79
80 static uint32_t
81 mtk_detect_cpuclk_rt2880(bus_space_tag_t bst, bus_space_handle_t bsh)
82 {
83         uint32_t val;
84
85         val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
86         val >>= RT2880_CPU_CLKSEL_OFF;
87         val &= RT2880_CPU_CLKSEL_MSK;
88
89         switch (val) {
90         case 0:
91                 return (MTK_CPU_CLK_250MHZ);
92         case 1:
93                 return (MTK_CPU_CLK_266MHZ);
94         case 2:
95                 return (MTK_CPU_CLK_280MHZ);
96         case 3:
97                 return (MTK_CPU_CLK_300MHZ);
98         }
99
100         /* Never reached */
101         return (0);
102 }
103
104 static uint32_t
105 mtk_detect_cpuclk_rt305x(bus_space_tag_t bst, bus_space_handle_t bsh)
106 {
107         uint32_t val;
108
109         val = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3);
110         if (val == RT3350_CHIPID0_3)
111                 return (MTK_CPU_CLK_320MHZ);
112
113         val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
114         val >>= RT305X_CPU_CLKSEL_OFF;
115         val &= RT305X_CPU_CLKSEL_MSK;
116
117         return ((val == 0) ? MTK_CPU_CLK_320MHZ : MTK_CPU_CLK_384MHZ);
118 }
119
120 static uint32_t
121 mtk_detect_cpuclk_rt3352(bus_space_tag_t bst, bus_space_handle_t bsh)
122 {
123         uint32_t val;
124
125         val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
126         val >>= RT3352_CPU_CLKSEL_OFF;
127         val &= RT3352_CPU_CLKSEL_MSK;
128
129         if (val)
130                 return (MTK_CPU_CLK_400MHZ);
131
132         return (MTK_CPU_CLK_384MHZ);
133 }
134
135 static uint32_t
136 mtk_detect_cpuclk_rt3883(bus_space_tag_t bst, bus_space_handle_t bsh)
137 {
138         uint32_t val;
139
140         val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
141         val >>= RT3883_CPU_CLKSEL_OFF;
142         val &= RT3883_CPU_CLKSEL_MSK;
143
144         switch (val) {
145         case 0:
146                 return (MTK_CPU_CLK_250MHZ);
147         case 1:
148                 return (MTK_CPU_CLK_384MHZ);
149         case 2:
150                 return (MTK_CPU_CLK_480MHZ);
151         case 3:
152                 return (MTK_CPU_CLK_500MHZ);
153         }
154
155         /* Never reached */
156         return (0);
157 }
158
159 static uint32_t
160 mtk_detect_cpuclk_rt5350(bus_space_tag_t bst, bus_space_handle_t bsh)
161 {
162         uint32_t val1, val2;
163
164         val1 = val2 = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
165
166         val1 >>= RT5350_CPU_CLKSEL_OFF1;
167         val2 >>= RT5350_CPU_CLKSEL_OFF2;
168         val1 &= RT5350_CPU_CLKSEL_MSK;
169         val2 &= RT5350_CPU_CLKSEL_MSK;
170         val1 |= (val2 << 1);
171
172         switch (val1) {
173         case 0:
174                 return (MTK_CPU_CLK_360MHZ);
175         case 1:
176                 /* Reserved value, but we return UNKNOWN */
177                 return (MTK_CPU_CLK_UNKNOWN);
178         case 2:
179                 return (MTK_CPU_CLK_320MHZ);
180         case 3:
181                 return (MTK_CPU_CLK_300MHZ);
182         }
183
184         /* Never reached */
185         return (0);
186 }
187
188 static uint32_t
189 mtk_detect_cpuclk_mt7620(bus_space_tag_t bst, bus_space_handle_t bsh)
190 {
191         uint32_t val, mul, div, res;
192
193         val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG1);
194         if (val & MT7620_CPU_CLK_AUX0)
195                 return (MTK_CPU_CLK_480MHZ);
196
197         val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG0);
198         if (!(val & MT7620_CPLL_SW_CFG))
199                 return (MTK_CPU_CLK_600MHZ);
200
201         mul = MT7620_PLL_MULT_RATIO_BASE + ((val >> MT7620_PLL_MULT_RATIO_OFF) &
202             MT7620_PLL_MULT_RATIO_MSK);
203         div = (val >> MT7620_PLL_DIV_RATIO_OFF) & MT7620_PLL_DIV_RATIO_MSK;
204
205         if (div != MT7620_PLL_DIV_RATIO_MSK)
206                 div += MT7620_PLL_DIV_RATIO_BASE;
207         else
208                 div = MT7620_PLL_DIV_RATIO_MAX;
209
210         res = (MT7620_XTAL_40 * mul) / div;
211
212         return (MTK_MHZ(res));
213 }
214
215 static uint32_t
216 mtk_detect_cpuclk_mt7621(bus_space_tag_t bst, bus_space_handle_t bsh)
217 {
218         uint32_t val, div, res;
219
220         val = bus_space_read_4(bst, bsh, SYSCTL_CLKCFG0);
221         if (val & MT7621_USES_MEMDIV) {
222                 div = bus_space_read_4(bst, bsh, MTK_MT7621_CLKDIV_REG);
223                 div >>= MT7621_MEMDIV_OFF;
224                 div &= MT7621_MEMDIV_MSK;
225                 div += MT7621_MEMDIV_BASE;
226
227                 val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
228                 val >>= MT7621_CLKSEL_OFF;
229                 val &= MT7621_CLKSEL_MSK;
230
231                 if (val >= MT7621_CLKSEL_25MHZ_VAL)
232                         res = div * MT7621_CLKSEL_25MHZ;
233                 else if (val >= MT7621_CLKSEL_20MHZ_VAL)
234                         res = div * MT7621_CLKSEL_20MHZ;
235                 else
236                         res = div * 0; /* XXX: not sure about this */
237         } else {
238                 val = bus_space_read_4(bst, bsh, SYSCTL_CUR_CLK_STS);
239                 div = (val >> MT7621_CLK_STS_DIV_OFF) & MT7621_CLK_STS_MSK;
240                 val &= MT7621_CLK_STS_MSK;
241
242                 res = (MT7621_CLK_STS_BASE * val) / div;
243         }
244
245         return (MTK_MHZ(res));
246 }
247
248 static uint32_t
249 mtk_detect_cpuclk_mt7628(bus_space_tag_t bst, bus_space_handle_t bsh)
250 {
251         uint32_t val;
252
253         val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
254         val >>= MT7628_CPU_CLKSEL_OFF;
255         val &= MT7628_CPU_CLKSEL_MSK;
256
257         if (val)
258                 return (MTK_CPU_CLK_580MHZ);
259
260         return (MTK_CPU_CLK_575MHZ);
261 }
262
263 void
264 mtk_soc_try_early_detect(void)
265 {
266         bus_space_tag_t bst;
267         bus_space_handle_t bsh;
268         uint32_t base;
269         phandle_t node;
270         int i;
271
272         if ((node = OF_finddevice("/")) == -1)
273                 return;
274
275         for (i = 0; compat_data[i].ocd_str != NULL; i++) {
276                 if (ofw_bus_node_is_compatible(node, compat_data[i].ocd_str)) {
277                         mtk_soc_socid = compat_data[i].ocd_data;
278                         break;
279                 }
280         }
281
282         if (mtk_soc_socid == MTK_SOC_UNKNOWN) {
283                 /* We don't know the SoC, so we don't know how to get clocks */
284                 return;
285         }
286
287         bst = fdtbus_bs_tag;
288         if (mtk_soc_socid == MTK_SOC_RT2880)
289                 base = MTK_RT2880_BASE;
290         else if (mtk_soc_socid == MTK_SOC_MT7621)
291                 base = MTK_MT7621_BASE;
292         else
293                 base = MTK_DEFAULT_BASE;
294
295         if (bus_space_map(bst, base, MTK_DEFAULT_SIZE, 0, &bsh))
296                 return;
297
298         /* First, figure out the CPU clock */
299         switch (mtk_soc_socid) {
300         case MTK_SOC_RT2880:
301                 mtk_soc_cpuclk = mtk_detect_cpuclk_rt2880(bst, bsh);
302                 break;
303         case MTK_SOC_RT3050:  /* fallthrough */
304         case MTK_SOC_RT3052:
305         case MTK_SOC_RT3350:
306                 mtk_soc_cpuclk = mtk_detect_cpuclk_rt305x(bst, bsh);
307                 break;
308         case MTK_SOC_RT3352:
309                 mtk_soc_cpuclk = mtk_detect_cpuclk_rt3352(bst, bsh);
310                 break;
311         case MTK_SOC_RT3662:  /* fallthrough */
312         case MTK_SOC_RT3883:
313                 mtk_soc_cpuclk = mtk_detect_cpuclk_rt3883(bst, bsh);
314                 break;
315         case MTK_SOC_RT5350:
316                 mtk_soc_cpuclk = mtk_detect_cpuclk_rt5350(bst, bsh);
317                 break;
318         case MTK_SOC_MT7620A: /* fallthrough */
319         case MTK_SOC_MT7620N:
320                 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7620(bst, bsh);
321                 break;
322         case MTK_SOC_MT7621:
323                 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7621(bst, bsh);
324                 break;
325         case MTK_SOC_MT7628:  /* fallthrough */
326         case MTK_SOC_MT7688:
327                 mtk_soc_cpuclk = mtk_detect_cpuclk_mt7628(bst, bsh);
328                 break;
329         default:
330                 /* We don't know the SoC, so we can't find the CPU clock */
331                 break;
332         }
333
334         /* Now figure out the timer clock */
335         if (mtk_soc_socid == MTK_SOC_MT7621) {
336 #ifdef notyet
337                 /* 
338                  * We use the GIC timer for timing source and its clock freq is
339                  * the same as the CPU's clock freq
340                  */
341                 mtk_soc_timerclk = mtk_soc_cpuclk;
342 #else
343                 /*
344                  * When GIC timer and MIPS timer are ready to co-exist and
345                  * GIC timer is actually implemented, we need to switch to it.
346                  * Until then we use a fake GIC timer, which is actually a
347                  * normal MIPS ticker, so the timer clock is half the CPU clock
348                  */
349                 mtk_soc_timerclk = mtk_soc_cpuclk / 2;
350 #endif
351         } else {
352                 /*
353                  * We use the MIPS ticker for the rest for now, so
354                  * the CPU clock is divided by 2
355                  */
356                 mtk_soc_timerclk = mtk_soc_cpuclk / 2;
357         }
358
359         switch (mtk_soc_socid) {
360         case MTK_SOC_RT2880:
361                 mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_2;
362                 break;
363         case MTK_SOC_RT3350:  /* fallthrough */
364         case MTK_SOC_RT3050:  /* fallthrough */
365         case MTK_SOC_RT3052:
366                 /* UART clock is CPU clock / 3 */
367                 mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_3;
368                 break;
369         case MTK_SOC_RT3352:  /* fallthrough */
370         case MTK_SOC_RT3662:  /* fallthrough */
371         case MTK_SOC_RT3883:  /* fallthrough */
372         case MTK_SOC_RT5350:  /* fallthrough */
373         case MTK_SOC_MT7620A: /* fallthrough */
374         case MTK_SOC_MT7620N: /* fallthrough */
375         case MTK_SOC_MT7628:  /* fallthrough */
376         case MTK_SOC_MT7688:
377                 /* UART clock is always 40MHz */
378                 mtk_soc_uartclk = MTK_UART_CLK_40MHZ;
379                 break;
380         case MTK_SOC_MT7621:
381                 /* UART clock is always 50MHz */
382                 mtk_soc_uartclk = MTK_UART_CLK_50MHZ;
383                 break;
384         default:
385                 /* We don't know the SoC, so we don't know the UART clock */
386                 break;
387         }
388
389         bus_space_unmap(bst, bsh, MTK_DEFAULT_SIZE);
390 }
391
392 uint32_t
393 mtk_soc_get_uartclk(void)
394 {
395
396         return mtk_soc_uartclk;
397 }
398
399 uint32_t
400 mtk_soc_get_cpuclk(void)
401 {
402
403         return mtk_soc_cpuclk;
404 }
405
406 uint32_t
407 mtk_soc_get_timerclk(void)
408 {
409
410         return mtk_soc_timerclk;
411 }
412
413 uint32_t
414 mtk_soc_get_socid(void)
415 {
416
417         return mtk_soc_socid;
418 }
419
420 /*
421  * The following are generic reset and clock functions
422  */
423
424 /* Default reset time is 100ms */
425 #define DEFAULT_RESET_TIME      100000
426
427 int
428 mtk_soc_reset_device(device_t dev)
429 {
430         int res;
431
432         res = fdt_reset_assert_all(dev);
433         if (res == 0) {
434                 DELAY(DEFAULT_RESET_TIME);
435                 res = fdt_reset_deassert_all(dev);
436                 if (res == 0)
437                         DELAY(DEFAULT_RESET_TIME);
438         }
439
440         return (res);
441 }
442
443 int
444 mtk_soc_stop_clock(device_t dev)
445 {
446
447         return (fdt_clock_disable_all(dev));
448 }
449
450 int
451 mtk_soc_start_clock(device_t dev)
452 {
453
454         return (fdt_clock_enable_all(dev));
455 }
456
457 int
458 mtk_soc_assert_reset(device_t dev)
459 {
460
461         return (fdt_reset_assert_all(dev));
462 }
463
464 int
465 mtk_soc_deassert_reset(device_t dev)
466 {
467
468         return (fdt_reset_deassert_all(dev));
469 }
470
471 void
472 mtk_soc_reset(void)
473 {
474
475         mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1);
476         mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0);
477 }