Index: head/sys/mips/mediatek/mtk_machdep.c =================================================================== --- head/sys/mips/mediatek/mtk_machdep.c (revision 340475) +++ head/sys/mips/mediatek/mtk_machdep.c (revision 340476) @@ -1,300 +1,302 @@ /*- * Copyright (C) 2015-2016 by Stanislav Galabov. All rights reserved. * Copyright (C) 2010-2011 by Aleksandr Rybalko. All rights reserved. * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "opt_platform.h" #include "opt_rt305x.h" #include #include extern int *edata; extern int *end; static char boot1_env[0x1000]; void platform_cpu_init() { /* Nothing special */ } static void mips_init(void) { struct mem_region mr[FDT_MEM_REGIONS]; uint64_t val; int i, j, mr_cnt; char *memsize; printf("entry: mips_init()\n"); bootverbose = 1; for (i = 0; i < 10; i++) phys_avail[i] = 0; dump_avail[0] = phys_avail[0] = MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); /* * The most low memory MT7621 can have. Currently MT7621 is the chip * that supports the most memory, so that seems reasonable. */ realmem = btoc(448 * 1024 * 1024); if (fdt_get_mem_regions(mr, &mr_cnt, &val) == 0) { physmem = btoc(val); printf("RAM size: %ldMB (from FDT)\n", ctob(physmem) / (1024 * 1024)); KASSERT((phys_avail[0] >= mr[0].mr_start) && \ (phys_avail[0] < (mr[0].mr_start + mr[0].mr_size)), ("First region is not within FDT memory range")); /* Limit size of the first region */ phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem))); dump_avail[1] = phys_avail[1]; /* Add the rest of the regions */ for (i = 1, j = 2; i < mr_cnt; i++, j+=2) { phys_avail[j] = mr[i].mr_start; phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size); dump_avail[j] = phys_avail[j]; dump_avail[j+1] = phys_avail[j+1]; } } else { if ((memsize = kern_getenv("memsize")) != NULL) { physmem = btoc(strtol(memsize, NULL, 0) << 20); printf("RAM size: %ldMB (from memsize)\n", ctob(physmem) / (1024 * 1024)); } else { /* All else failed, assume 32MB */ physmem = btoc(32 * 1024 * 1024); printf("RAM size: %ldMB (assumed)\n", ctob(physmem) / (1024 * 1024)); } if (mtk_soc_get_socid() == MTK_SOC_RT2880) { /* RT2880 memory start is 88000000 */ dump_avail[1] = phys_avail[1] = ctob(physmem) + 0x08000000; } else if (ctob(physmem) < (448 * 1024 * 1024)) { /* * Anything up to 448MB is assumed to be directly * mappable as low memory... */ dump_avail[1] = phys_avail[1] = ctob(physmem); } else if (mtk_soc_get_socid() == MTK_SOC_MT7621) { /* * On MT7621 the low memory is limited to 448MB, the * rest is high memory, mapped at 0x20000000 */ phys_avail[1] = 448 * 1024 * 1024; phys_avail[2] = 0x20000000; phys_avail[3] = phys_avail[2] + ctob(physmem) - phys_avail[1]; dump_avail[1] = phys_avail[1] - phys_avail[0]; dump_avail[2] = phys_avail[2]; dump_avail[3] = phys_avail[3] - phys_avail[2]; } else { /* * We have > 448MB RAM and we're not MT7621? Currently * there is no such chip, so we'll just limit the RAM to * 32MB and let the user know... */ printf("Unknown chip, assuming 32MB RAM\n"); physmem = btoc(32 * 1024 * 1024); dump_avail[1] = phys_avail[1] = ctob(physmem); } } if (physmem < realmem) realmem = physmem; init_param1(); init_param2(physmem); mips_cpu_init(); pmap_bootstrap(); mips_proc0_init(); mutex_init(); kdb_init(); #ifdef KDB if (boothowto & RB_KDB) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif } void platform_reset(void) { mtk_soc_reset(); } void platform_start(__register_t a0 __unused, __register_t a1 __unused, __register_t a2 __unused, __register_t a3 __unused) { vm_offset_t kernend; int argc = a0, i;//, res; uint32_t timer_clk; char **argv = (char **)MIPS_PHYS_TO_KSEG0(a1); char **envp = (char **)MIPS_PHYS_TO_KSEG0(a2); void *dtbp; phandle_t chosen; char buf[2048]; /* clear the BSS and SBSS segments */ kernend = (vm_offset_t)&end; memset(&edata, 0, kernend - (vm_offset_t)(&edata)); mips_postboot_fixup(); /* Initialize pcpu stuff */ mips_pcpu0_init(); dtbp = &fdt_static_dtb; if (OF_install(OFW_FDT, 0) == FALSE) while (1); if (OF_init((void *)dtbp) != 0) while (1); mtk_soc_try_early_detect(); + mtk_soc_set_cpu_model(); + if ((timer_clk = mtk_soc_get_timerclk()) == 0) timer_clk = 1000000000; /* no such speed yet */ mips_timer_early_init(timer_clk); /* initialize console so that we have printf */ boothowto |= (RB_SERIAL | RB_MULTIPLE); /* Use multiple consoles */ boothowto |= (RB_VERBOSE); cninit(); init_static_kenv(boot1_env, sizeof(boot1_env)); /* * Get bsdbootargs from FDT if specified. */ chosen = OF_finddevice("/chosen"); if (OF_getprop(chosen, "bsdbootargs", buf, sizeof(buf)) != -1) boothowto |= boot_parse_cmdline(buf); printf("FDT DTB at: 0x%08x\n", (uint32_t)dtbp); printf("CPU clock: %4dMHz\n", mtk_soc_get_cpuclk()/(1000*1000)); printf("Timer clock: %4dMHz\n", timer_clk/(1000*1000)); printf("UART clock: %4dMHz\n\n", mtk_soc_get_uartclk()/(1000*1000)); printf("U-Boot args (from %d args):\n", argc - 1); if (argc == 1) printf("\tNone\n"); for (i = 1; i < argc; i++) { char *n = "argv ", *arg; if (i > 99) break; if (argv[i]) { arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(argv[i]); printf("\targv[%d] = %s\n", i, arg); sprintf(n, "argv%d", i); kern_setenv(n, arg); } } printf("Environment:\n"); for (i = 0; envp[i] && MIPS_IS_VALID_PTR(envp[i]); i++) { char *n, *arg; arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(envp[i]); if (! MIPS_IS_VALID_PTR(arg)) continue; printf("\t%s\n", arg); n = strsep(&arg, "="); if (arg == NULL) kern_setenv(n, "1"); else kern_setenv(n, arg); } mips_init(); mips_timer_init_params(timer_clk, 0); } Index: head/sys/mips/mediatek/mtk_soc.c =================================================================== --- head/sys/mips/mediatek/mtk_soc.c (revision 340475) +++ head/sys/mips/mediatek/mtk_soc.c (revision 340476) @@ -1,477 +1,506 @@ /*- * Copyright (c) 2016 Stanislav Galabov. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static uint32_t mtk_soc_socid = MTK_SOC_UNKNOWN; static uint32_t mtk_soc_uartclk = 0; static uint32_t mtk_soc_cpuclk = MTK_CPU_CLK_880MHZ; static uint32_t mtk_soc_timerclk = MTK_CPU_CLK_880MHZ / 2; +static uint32_t mtk_soc_chipid0_3 = MTK_UNKNOWN_CHIPID0_3; +static uint32_t mtk_soc_chipid4_7 = MTK_UNKNOWN_CHIPID4_7; + static const struct ofw_compat_data compat_data[] = { { "ralink,rt2880-soc", MTK_SOC_RT2880 }, { "ralink,rt3050-soc", MTK_SOC_RT3050 }, { "ralink,rt3052-soc", MTK_SOC_RT3052 }, { "ralink,rt3350-soc", MTK_SOC_RT3350 }, { "ralink,rt3352-soc", MTK_SOC_RT3352 }, { "ralink,rt3662-soc", MTK_SOC_RT3662 }, { "ralink,rt3883-soc", MTK_SOC_RT3883 }, { "ralink,rt5350-soc", MTK_SOC_RT5350 }, { "ralink,mtk7620a-soc", MTK_SOC_MT7620A }, { "ralink,mt7620a-soc", MTK_SOC_MT7620A }, { "ralink,mtk7620n-soc", MTK_SOC_MT7620N }, { "ralink,mt7620n-soc", MTK_SOC_MT7620N }, { "mediatek,mtk7621-soc", MTK_SOC_MT7621 }, { "mediatek,mt7621-soc", MTK_SOC_MT7621 }, { "ralink,mt7621-soc", MTK_SOC_MT7621 }, { "ralink,mtk7621-soc", MTK_SOC_MT7621 }, { "ralink,mtk7628an-soc", MTK_SOC_MT7628 }, { "mediatek,mt7628an-soc", MTK_SOC_MT7628 }, { "ralink,mtk7688-soc", MTK_SOC_MT7688 }, /* Sentinel */ { NULL, MTK_SOC_UNKNOWN }, }; static uint32_t mtk_detect_cpuclk_rt2880(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val; val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= RT2880_CPU_CLKSEL_OFF; val &= RT2880_CPU_CLKSEL_MSK; switch (val) { case 0: return (MTK_CPU_CLK_250MHZ); case 1: return (MTK_CPU_CLK_266MHZ); case 2: return (MTK_CPU_CLK_280MHZ); case 3: return (MTK_CPU_CLK_300MHZ); } /* Never reached */ return (0); } static uint32_t mtk_detect_cpuclk_rt305x(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val; val = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3); if (val == RT3350_CHIPID0_3) return (MTK_CPU_CLK_320MHZ); val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= RT305X_CPU_CLKSEL_OFF; val &= RT305X_CPU_CLKSEL_MSK; return ((val == 0) ? MTK_CPU_CLK_320MHZ : MTK_CPU_CLK_384MHZ); } static uint32_t mtk_detect_cpuclk_rt3352(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val; val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= RT3352_CPU_CLKSEL_OFF; val &= RT3352_CPU_CLKSEL_MSK; if (val) return (MTK_CPU_CLK_400MHZ); return (MTK_CPU_CLK_384MHZ); } static uint32_t mtk_detect_cpuclk_rt3883(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val; val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= RT3883_CPU_CLKSEL_OFF; val &= RT3883_CPU_CLKSEL_MSK; switch (val) { case 0: return (MTK_CPU_CLK_250MHZ); case 1: return (MTK_CPU_CLK_384MHZ); case 2: return (MTK_CPU_CLK_480MHZ); case 3: return (MTK_CPU_CLK_500MHZ); } /* Never reached */ return (0); } static uint32_t mtk_detect_cpuclk_rt5350(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val1, val2; val1 = val2 = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val1 >>= RT5350_CPU_CLKSEL_OFF1; val2 >>= RT5350_CPU_CLKSEL_OFF2; val1 &= RT5350_CPU_CLKSEL_MSK; val2 &= RT5350_CPU_CLKSEL_MSK; val1 |= (val2 << 1); switch (val1) { case 0: return (MTK_CPU_CLK_360MHZ); case 1: /* Reserved value, but we return UNKNOWN */ return (MTK_CPU_CLK_UNKNOWN); case 2: return (MTK_CPU_CLK_320MHZ); case 3: return (MTK_CPU_CLK_300MHZ); } /* Never reached */ return (0); } static uint32_t mtk_detect_cpuclk_mt7620(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val, mul, div, res; val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG1); if (val & MT7620_CPU_CLK_AUX0) return (MTK_CPU_CLK_480MHZ); val = bus_space_read_4(bst, bsh, SYSCTL_MT7620_CPLL_CFG0); if (!(val & MT7620_CPLL_SW_CFG)) return (MTK_CPU_CLK_600MHZ); mul = MT7620_PLL_MULT_RATIO_BASE + ((val >> MT7620_PLL_MULT_RATIO_OFF) & MT7620_PLL_MULT_RATIO_MSK); div = (val >> MT7620_PLL_DIV_RATIO_OFF) & MT7620_PLL_DIV_RATIO_MSK; if (div != MT7620_PLL_DIV_RATIO_MSK) div += MT7620_PLL_DIV_RATIO_BASE; else div = MT7620_PLL_DIV_RATIO_MAX; res = (MT7620_XTAL_40 * mul) / div; return (MTK_MHZ(res)); } static uint32_t mtk_detect_cpuclk_mt7621(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val, div, res; val = bus_space_read_4(bst, bsh, SYSCTL_CLKCFG0); if (val & MT7621_USES_MEMDIV) { div = bus_space_read_4(bst, bsh, MTK_MT7621_CLKDIV_REG); div >>= MT7621_MEMDIV_OFF; div &= MT7621_MEMDIV_MSK; div += MT7621_MEMDIV_BASE; val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= MT7621_CLKSEL_OFF; val &= MT7621_CLKSEL_MSK; if (val >= MT7621_CLKSEL_25MHZ_VAL) res = div * MT7621_CLKSEL_25MHZ; else if (val >= MT7621_CLKSEL_20MHZ_VAL) res = div * MT7621_CLKSEL_20MHZ; else res = div * 0; /* XXX: not sure about this */ } else { val = bus_space_read_4(bst, bsh, SYSCTL_CUR_CLK_STS); div = (val >> MT7621_CLK_STS_DIV_OFF) & MT7621_CLK_STS_MSK; val &= MT7621_CLK_STS_MSK; res = (MT7621_CLK_STS_BASE * val) / div; } return (MTK_MHZ(res)); } static uint32_t mtk_detect_cpuclk_mt7628(bus_space_tag_t bst, bus_space_handle_t bsh) { uint32_t val; val = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG); val >>= MT7628_CPU_CLKSEL_OFF; val &= MT7628_CPU_CLKSEL_MSK; if (val) return (MTK_CPU_CLK_580MHZ); return (MTK_CPU_CLK_575MHZ); } void mtk_soc_try_early_detect(void) { bus_space_tag_t bst; bus_space_handle_t bsh; uint32_t base; phandle_t node; int i; if ((node = OF_finddevice("/")) == -1) return; for (i = 0; compat_data[i].ocd_str != NULL; i++) { if (ofw_bus_node_is_compatible(node, compat_data[i].ocd_str)) { mtk_soc_socid = compat_data[i].ocd_data; break; } } if (mtk_soc_socid == MTK_SOC_UNKNOWN) { /* We don't know the SoC, so we don't know how to get clocks */ return; } bst = fdtbus_bs_tag; if (mtk_soc_socid == MTK_SOC_RT2880) base = MTK_RT2880_BASE; else if (mtk_soc_socid == MTK_SOC_MT7621) base = MTK_MT7621_BASE; else base = MTK_DEFAULT_BASE; if (bus_space_map(bst, base, MTK_DEFAULT_SIZE, 0, &bsh)) return; + /* Get our CHIP ID */ + mtk_soc_chipid0_3 = bus_space_read_4(bst, bsh, SYSCTL_CHIPID0_3); + mtk_soc_chipid4_7 = bus_space_read_4(bst, bsh, SYSCTL_CHIPID4_7); + /* First, figure out the CPU clock */ switch (mtk_soc_socid) { case MTK_SOC_RT2880: mtk_soc_cpuclk = mtk_detect_cpuclk_rt2880(bst, bsh); break; case MTK_SOC_RT3050: /* fallthrough */ case MTK_SOC_RT3052: case MTK_SOC_RT3350: mtk_soc_cpuclk = mtk_detect_cpuclk_rt305x(bst, bsh); break; case MTK_SOC_RT3352: mtk_soc_cpuclk = mtk_detect_cpuclk_rt3352(bst, bsh); break; case MTK_SOC_RT3662: /* fallthrough */ case MTK_SOC_RT3883: mtk_soc_cpuclk = mtk_detect_cpuclk_rt3883(bst, bsh); break; case MTK_SOC_RT5350: mtk_soc_cpuclk = mtk_detect_cpuclk_rt5350(bst, bsh); break; case MTK_SOC_MT7620A: /* fallthrough */ case MTK_SOC_MT7620N: mtk_soc_cpuclk = mtk_detect_cpuclk_mt7620(bst, bsh); break; case MTK_SOC_MT7621: mtk_soc_cpuclk = mtk_detect_cpuclk_mt7621(bst, bsh); break; case MTK_SOC_MT7628: /* fallthrough */ case MTK_SOC_MT7688: mtk_soc_cpuclk = mtk_detect_cpuclk_mt7628(bst, bsh); break; default: /* We don't know the SoC, so we can't find the CPU clock */ break; } /* Now figure out the timer clock */ if (mtk_soc_socid == MTK_SOC_MT7621) { #ifdef notyet /* * We use the GIC timer for timing source and its clock freq is * the same as the CPU's clock freq */ mtk_soc_timerclk = mtk_soc_cpuclk; #else /* * When GIC timer and MIPS timer are ready to co-exist and * GIC timer is actually implemented, we need to switch to it. * Until then we use a fake GIC timer, which is actually a * normal MIPS ticker, so the timer clock is half the CPU clock */ mtk_soc_timerclk = mtk_soc_cpuclk / 2; #endif } else { /* * We use the MIPS ticker for the rest for now, so * the CPU clock is divided by 2 */ mtk_soc_timerclk = mtk_soc_cpuclk / 2; } switch (mtk_soc_socid) { case MTK_SOC_RT2880: mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_2; break; case MTK_SOC_RT3350: /* fallthrough */ case MTK_SOC_RT3050: /* fallthrough */ case MTK_SOC_RT3052: /* UART clock is CPU clock / 3 */ mtk_soc_uartclk = mtk_soc_cpuclk / MTK_UARTDIV_3; break; case MTK_SOC_RT3352: /* fallthrough */ case MTK_SOC_RT3662: /* fallthrough */ case MTK_SOC_RT3883: /* fallthrough */ case MTK_SOC_RT5350: /* fallthrough */ case MTK_SOC_MT7620A: /* fallthrough */ case MTK_SOC_MT7620N: /* fallthrough */ case MTK_SOC_MT7628: /* fallthrough */ case MTK_SOC_MT7688: /* UART clock is always 40MHz */ mtk_soc_uartclk = MTK_UART_CLK_40MHZ; break; case MTK_SOC_MT7621: /* UART clock is always 50MHz */ mtk_soc_uartclk = MTK_UART_CLK_50MHZ; break; default: /* We don't know the SoC, so we don't know the UART clock */ break; } bus_space_unmap(bst, bsh, MTK_DEFAULT_SIZE); +} + +extern char cpu_model[]; + +void +mtk_soc_set_cpu_model(void) +{ + uint32_t *p_model = (uint32_t *)cpu_model; + + /* + * CHIPID is always 2x32 bit registers, containing the ASCII + * representation of the chip, so use that directly. + * + * The info is either pre-populated in mtk_soc_try_early_detect() or + * it is left at its default value of "unknown " if it could not be + * obtained for some reason. + */ + p_model[0] = mtk_soc_chipid0_3; + p_model[1] = mtk_soc_chipid4_7; + + /* Null-terminate the string */ + cpu_model[8] = 0; } uint32_t mtk_soc_get_uartclk(void) { return mtk_soc_uartclk; } uint32_t mtk_soc_get_cpuclk(void) { return mtk_soc_cpuclk; } uint32_t mtk_soc_get_timerclk(void) { return mtk_soc_timerclk; } uint32_t mtk_soc_get_socid(void) { return mtk_soc_socid; } /* * The following are generic reset and clock functions */ /* Default reset time is 100ms */ #define DEFAULT_RESET_TIME 100000 int mtk_soc_reset_device(device_t dev) { int res; res = fdt_reset_assert_all(dev); if (res == 0) { DELAY(DEFAULT_RESET_TIME); res = fdt_reset_deassert_all(dev); if (res == 0) DELAY(DEFAULT_RESET_TIME); } return (res); } int mtk_soc_stop_clock(device_t dev) { return (fdt_clock_disable_all(dev)); } int mtk_soc_start_clock(device_t dev) { return (fdt_clock_enable_all(dev)); } int mtk_soc_assert_reset(device_t dev) { return (fdt_reset_assert_all(dev)); } int mtk_soc_deassert_reset(device_t dev) { return (fdt_reset_deassert_all(dev)); } void mtk_soc_reset(void) { mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 0, 1); mtk_sysctl_clr_set(SYSCTL_RSTCTRL, 1, 0); } Index: head/sys/mips/mediatek/mtk_soc.h =================================================================== --- head/sys/mips/mediatek/mtk_soc.h (revision 340475) +++ head/sys/mips/mediatek/mtk_soc.h (revision 340476) @@ -1,137 +1,138 @@ /*- * Copyright (c) 2016 Stanislav Galabov. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _MTK_SOC_H_ #define _MTK_SOC_H_ enum mtk_soc_id { MTK_SOC_UNKNOWN, MTK_SOC_RT2880, MTK_SOC_RT3050, MTK_SOC_RT3052, MTK_SOC_RT3350, MTK_SOC_RT3352, MTK_SOC_RT3662, MTK_SOC_RT3883, MTK_SOC_RT5350, MTK_SOC_MT7620A, MTK_SOC_MT7620N, MTK_SOC_MT7621, MTK_SOC_MT7628, MTK_SOC_MT7688, MTK_SOC_MAX }; #define RT2880_CPU_CLKSEL_OFF 20 #define RT2880_CPU_CLKSEL_MSK 0x3 #define RT305X_CPU_CLKSEL_OFF 18 #define RT305X_CPU_CLKSEL_MSK 0x1 #define RT3352_CPU_CLKSEL_OFF 8 #define RT3352_CPU_CLKSEL_MSK 0x1 #define RT3883_CPU_CLKSEL_OFF 8 #define RT3883_CPU_CLKSEL_MSK 0x3 #define RT5350_CPU_CLKSEL_OFF1 8 #define RT5350_CPU_CLKSEL_OFF2 10 #define RT5350_CPU_CLKSEL_MSK 0x1 #define MT7628_CPU_CLKSEL_OFF 6 #define MT7628_CPU_CLKSEL_MSK 0x1 #define MT7620_CPU_CLK_AUX0 (1u<<24) #define MT7620_CPLL_SW_CFG (1u<<31) #define MT7620_PLL_MULT_RATIO_OFF 16 #define MT7620_PLL_MULT_RATIO_MSK 0x7 #define MT7620_PLL_MULT_RATIO_BASE 24 #define MT7620_PLL_DIV_RATIO_OFF 10 #define MT7620_PLL_DIV_RATIO_MSK 0x3 #define MT7620_PLL_DIV_RATIO_BASE 2 #define MT7620_PLL_DIV_RATIO_MAX 8 #define MT7620_XTAL_40 40 #define MT7621_USES_MEMDIV (1u<<30) #define MT7621_MEMDIV_OFF 4 #define MT7621_MEMDIV_MSK 0x7f #define MT7621_MEMDIV_BASE 1 #define MT7621_CLKSEL_OFF 6 #define MT7621_CLKSEL_MSK 0x7 #define MT7621_CLKSEL_25MHZ_VAL 6 #define MT7621_CLKSEL_20MHZ_VAL 3 #define MT7621_CLKSEL_20MHZ 20 #define MT7621_CLKSEL_25MHZ 25 #define MT7621_CLK_STS_DIV_OFF 8 #define MT7621_CLK_STS_MSK 0x1f #define MT7621_CLK_STS_BASE 500 #define MTK_MT7621_CLKDIV_REG 0x5648 #define MTK_MT7621_CLKDIV_OFF 4 #define MTK_MT7621_CLKDIV_MSK 0x7f #define MTK_MHZ(x) ((x) * 1000 * 1000) #define MTK_CPU_CLK_UNKNOWN 0 #define MTK_CPU_CLK_233MHZ 233333333 #define MTK_CPU_CLK_250MHZ 250000000 #define MTK_CPU_CLK_266MHZ 266666666 #define MTK_CPU_CLK_280MHZ 280000000 #define MTK_CPU_CLK_300MHZ 300000000 #define MTK_CPU_CLK_320MHZ 320000000 #define MTK_CPU_CLK_360MHZ 360000000 #define MTK_CPU_CLK_384MHZ 384000000 #define MTK_CPU_CLK_400MHZ 400000000 #define MTK_CPU_CLK_480MHZ 480000000 #define MTK_CPU_CLK_500MHZ 500000000 #define MTK_CPU_CLK_575MHZ 575000000 #define MTK_CPU_CLK_580MHZ 580000000 #define MTK_CPU_CLK_600MHZ 600000000 #define MTK_CPU_CLK_880MHZ 880000000 #define MTK_UART_CLK_40MHZ 40000000 #define MTK_UART_CLK_50MHZ 50000000 #define MTK_UARTDIV_2 2 #define MTK_UARTDIV_3 3 #define MTK_DEFAULT_BASE 0x10000000 #define MTK_RT2880_BASE 0x00300000 #define MTK_MT7621_BASE 0x1e000000 #define MTK_DEFAULT_SIZE 0x6000 extern void mtk_soc_try_early_detect(void); +extern void mtk_soc_set_cpu_model(void); extern uint32_t mtk_soc_get_uartclk(void); extern uint32_t mtk_soc_get_cpuclk(void); extern uint32_t mtk_soc_get_timerclk(void); extern uint32_t mtk_soc_get_socid(void); extern int mtk_soc_reset_device(device_t); extern int mtk_soc_stop_clock(device_t); extern int mtk_soc_start_clock(device_t); extern int mtk_soc_assert_reset(device_t); extern int mtk_soc_deassert_reset(device_t); extern void mtk_soc_reset(void); #endif /* _MTK_SOC_H_ */ Index: head/sys/mips/mediatek/mtk_sysctl.h =================================================================== --- head/sys/mips/mediatek/mtk_sysctl.h (revision 340475) +++ head/sys/mips/mediatek/mtk_sysctl.h (revision 340476) @@ -1,61 +1,64 @@ /*- * Copyright (c) 2016 Stanislav Galabov. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _MTK_SYSCTL_H_ #define _MTK_SYSCTL_H_ /* System Control */ #define SYSCTL_CHIPID0_3 0x00 #define SYSCTL_CHIPID4_7 0x04 #define SYSCTL_REVID 0x0C #define SYSCTL_REVID_MASK 0xFFFF #define SYSCTL_MT7621_REV_E 0x0101 #define SYSCTL_SYSCFG 0x10 #define SYSCTL_SYSCFG1 0x14 #define SYSCTL_CLKCFG0 0x2C #define SYSCTL_CLKCFG1 0x30 #define SYSCTL_RSTCTRL 0x34 #define SYSCTL_GPIOMODE 0x60 #define SYSCTL_CUR_CLK_STS 0x44 #define SYSCTL_MT7620_CPLL_CFG0 0x54 #define SYSCTL_MT7620_CPLL_CFG1 0x58 #define SYSCFG1_USB_HOST_MODE (1<<10) #define RT3350_CHIPID0_3 0x33335452 +#define MTK_UNKNOWN_CHIPID0_3 0x6E6B6E75 /* "unkn" */ +#define MTK_UNKNOWN_CHIPID4_7 0x206E776F /* "own " */ + extern uint32_t mtk_sysctl_get(uint32_t); extern void mtk_sysctl_set(uint32_t, uint32_t); extern void mtk_sysctl_clr_set(uint32_t, uint32_t, uint32_t); #endif /* _MTK_SYSCTL_H_ */