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 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 80static uint32_t 81mtk_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 104static uint32_t 105mtk_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 120static uint32_t 121mtk_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 135static uint32_t 136mtk_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 159static uint32_t 160mtk_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 188static uint32_t 189mtk_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 215static uint32_t 216mtk_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 248static uint32_t 249mtk_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 263void 264mtk_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 392uint32_t 393mtk_soc_get_uartclk(void) 394{ 395 396 return mtk_soc_uartclk; 397} 398 399uint32_t 400mtk_soc_get_cpuclk(void) 401{ 402 403 return mtk_soc_cpuclk; 404} 405 406uint32_t 407mtk_soc_get_timerclk(void) 408{ 409 410 return mtk_soc_timerclk; 411} 412 413uint32_t 414mtk_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 427int 428mtk_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 443int 444mtk_soc_stop_clock(device_t dev) 445{ 446 447 return (fdt_clock_disable_all(dev)); 448} 449 450int 451mtk_soc_start_clock(device_t dev) 452{ 453 454 return (fdt_clock_enable_all(dev)); 455} 456 457int 458mtk_soc_assert_reset(device_t dev) 459{ 460 461 return (fdt_reset_assert_all(dev)); 462} 463 464int 465mtk_soc_deassert_reset(device_t dev) 466{ 467 468 return (fdt_reset_deassert_all(dev)); 469} 470 471void 472mtk_soc_reset(void) 473{ 474 475 mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1); 476 mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0); 477} 478