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