Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146838371
D5826.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
39 KB
Referenced Files
None
Subscribers
None
D5826.id.diff
View Options
Index: head/sys/mips/mediatek/fdt_reset.h
===================================================================
--- head/sys/mips/mediatek/fdt_reset.h
+++ head/sys/mips/mediatek/fdt_reset.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2016 Stanislav Galabov
+ * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
+ * 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 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 DEV_FDT_RESET_H
+#define DEV_FDT_RESET_H
+
+#include "fdt_reset_if.h"
+
+/*
+ * Look up "resets" property in consumer's fdt data and assert or deassert all
+ * configured resets.
+ */
+int fdt_reset_assert_all(device_t consumer);
+int fdt_reset_deassert_all(device_t consumer);
+
+/*
+ * [Un]register the given device instance as a driver that implements the
+ * fdt_clock interface.
+ */
+void fdt_reset_register_provider(device_t provider);
+void fdt_reset_unregister_provider(device_t provider);
+
+#endif /* DEV_FDT_RESET_H */
+
Index: head/sys/mips/mediatek/fdt_reset.c
===================================================================
--- head/sys/mips/mediatek/fdt_reset.c
+++ head/sys/mips/mediatek/fdt_reset.c
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 2016 Stanislav Galabov
+ * Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
+ * 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "fdt_reset_if.h"
+#include <mips/mediatek/fdt_reset.h>
+
+/*
+ * Loop through all the tuples in the resets= property for a device, asserting
+ * or deasserting each reset.
+ *
+ * Be liberal about errors for now: warn about a failure to (de)assert but keep
+ * trying with any other resets in the list. Return ENXIO if any errors were
+ * found, and let the caller decide whether the problem is fatal.
+ */
+static int
+assert_deassert_all(device_t consumer, boolean_t assert)
+{
+ phandle_t rnode;
+ device_t resetdev;
+ int resetnum, err, i, ncells;
+ uint32_t *resets;
+ boolean_t anyerrors;
+
+ rnode = ofw_bus_get_node(consumer);
+ ncells = OF_getencprop_alloc(rnode, "resets", sizeof(*resets),
+ (void **)&resets);
+ if (!assert && ncells < 2) {
+ device_printf(consumer, "Warning: No resets specified in fdt "
+ "data; device may not function.");
+ return (ENXIO);
+ }
+ anyerrors = false;
+ for (i = 0; i < ncells; i += 2) {
+ resetdev = OF_device_from_xref(resets[i]);
+ resetnum = resets[i + 1];
+ if (resetdev == NULL) {
+ if (!assert)
+ device_printf(consumer, "Warning: can not find "
+ "driver for reset number %u; device may "
+ "not function\n", resetnum);
+ anyerrors = true;
+ continue;
+ }
+ if (assert)
+ err = FDT_RESET_ASSERT(resetdev, resetnum);
+ else
+ err = FDT_RESET_DEASSERT(resetdev, resetnum);
+ if (err != 0) {
+ if (!assert)
+ device_printf(consumer, "Warning: failed to "
+ "deassert reset number %u; device may not "
+ "function\n", resetnum);
+ anyerrors = true;
+ }
+ }
+ free(resets, M_OFWPROP);
+ return (anyerrors ? ENXIO : 0);
+}
+
+int
+fdt_reset_assert_all(device_t consumer)
+{
+
+ return (assert_deassert_all(consumer, true));
+}
+
+int
+fdt_reset_deassert_all(device_t consumer)
+{
+
+ return (assert_deassert_all(consumer, false));
+}
+
+void
+fdt_reset_register_provider(device_t provider)
+{
+
+ OF_device_register_xref(
+ OF_xref_from_node(ofw_bus_get_node(provider)), provider);
+}
+
+void
+fdt_reset_unregister_provider(device_t provider)
+{
+
+ OF_device_register_xref(OF_xref_from_device(provider), NULL);
+}
+
Index: head/sys/mips/mediatek/fdt_reset_if.m
===================================================================
--- head/sys/mips/mediatek/fdt_reset_if.m
+++ head/sys/mips/mediatek/fdt_reset_if.m
@@ -0,0 +1,58 @@
+#-
+# Copyright (c) 2016 Stanislav Galabov
+# Copyright (c) 2014 Ian Lepore
+# 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.
+#
+# $FreeBSD$
+#
+
+#include <sys/types.h>
+
+#
+# This is the interface that fdt_reset drivers provide to other drivers.
+# In this context, reset refers to a reset signal provided to some other
+# hardware component within the system. They are most often found within
+# embedded processors that have on-chip IO controllers.
+#
+
+INTERFACE fdt_reset;
+
+#
+# Enable/assert/apply the specified reset.
+# Returns 0 on success or a standard errno value.
+#
+METHOD int assert {
+ device_t provider;
+ int index;
+};
+
+#
+# Disable/de-assert/remove the specified reset.
+# Returns 0 on success or a standard errno value.
+#
+METHOD int deassert {
+ device_t provider;
+ int index;
+};
+
Index: head/sys/mips/mediatek/mtk_machdep.c
===================================================================
--- head/sys/mips/mediatek/mtk_machdep.c
+++ head/sys/mips/mediatek/mtk_machdep.c
@@ -0,0 +1,286 @@
+/*-
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ddb.h"
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/imgact.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/cons.h>
+#include <sys/exec.h>
+#include <sys/ucontext.h>
+#include <sys/proc.h>
+#include <sys/kdb.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/signalvar.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/user.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+
+#include <machine/cache.h>
+#include <machine/clock.h>
+#include <machine/cpu.h>
+#include <machine/cpuinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuregs.h>
+#include <machine/hwfunc.h>
+#include <machine/intr_machdep.h>
+#include <machine/locore.h>
+#include <machine/md_var.h>
+#include <machine/pte.h>
+#include <machine/sigframe.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+
+#include <mips/mediatek/mtk_sysctl.h>
+#include <mips/mediatek/mtk_soc.h>
+
+#include "opt_platform.h"
+#include "opt_rt305x.h"
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+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 (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;
+
+ /* 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();
+ 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));
+
+ 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.h
===================================================================
--- head/sys/mips/mediatek/mtk_soc.h
+++ head/sys/mips/mediatek/mtk_soc.h
@@ -0,0 +1,130 @@
+/*-
+ * 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_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 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_250MHZ 250000000
+#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_MT7621_BASE 0x1e000000
+#define MTK_DEFAULT_SIZE 0x6000
+
+extern void mtk_soc_try_early_detect(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_soc.c
===================================================================
--- head/sys/mips/mediatek/mtk_soc.c
+++ head/sys/mips/mediatek/mtk_soc.c
@@ -0,0 +1,438 @@
+/*-
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+
+#include <machine/fdt.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_clock.h>
+
+#include <mips/mediatek/fdt_reset.h>
+#include <mips/mediatek/mtk_sysctl.h>
+#include <mips/mediatek/mtk_soc.h>
+
+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 const struct ofw_compat_data compat_data[] = {
+ { "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,mtk7620n-soc", MTK_SOC_MT7620N },
+ { "mediatek,mtk7621-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_rt305x(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+ uint32_t clk;
+
+ clk = bus_space_read_4(bst, bsh, SYSCTL_SYSCFG);
+ clk >>= RT305X_CPU_CLKSEL_OFF;
+ clk &= RT305X_CPU_CLKSEL_MSK;
+
+ return ((clk == 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 (fdt_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_MT7621)
+ base = MTK_MT7621_BASE;
+ else
+ base = MTK_DEFAULT_BASE;
+
+ if (bus_space_map(bst, MTK_DEFAULT_BASE, MTK_DEFAULT_SIZE, 0, &bsh))
+ return;
+
+ /* First, figure out the CPU clock */
+ switch (mtk_soc_socid) {
+ case MTK_SOC_RT3050: /* fallthrough */
+ case MTK_SOC_RT3052:
+ mtk_soc_cpuclk = mtk_detect_cpuclk_rt305x(bst, bsh);
+ break;
+ case MTK_SOC_RT3350:
+ mtk_soc_cpuclk = MTK_CPU_CLK_320MHZ;
+ 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_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);
+}
+
+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_sysctl.h
===================================================================
--- head/sys/mips/mediatek/mtk_sysctl.h
+++ head/sys/mips/mediatek/mtk_sysctl.h
@@ -0,0 +1,59 @@
+/*-
+ * 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)
+
+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_ */
Index: head/sys/mips/mediatek/mtk_sysctl.c
===================================================================
--- head/sys/mips/mediatek/mtk_sysctl.c
+++ head/sys/mips/mediatek/mtk_sysctl.c
@@ -0,0 +1,191 @@
+/*-
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/malloc.h>
+
+#include <machine/fdt.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <mips/mediatek/mtk_sysctl.h>
+
+#include <dev/fdt/fdt_common.h>
+
+struct mtk_sysctl_softc {
+ device_t dev;
+ struct resource *mem_res;
+ int mem_rid;
+ struct mtx mtx;
+};
+
+static struct mtk_sysctl_softc *mtk_sysctl_sc = NULL;
+
+static struct ofw_compat_data compat_data[] = {
+ { "ralink,rt2880-sysc", 1 },
+ { "ralink,rt3050-sysc", 1 },
+ { "ralink,rt3352-sysc", 1 },
+ { "ralink,rt3883-sysc", 1 },
+ { "ralink,rt5350-sysc", 1 },
+ { "ralink,mt7620a-sysc", 1 },
+ { "mtk,mt7621-sysc", 1 },
+
+ /* Sentinel */
+ { NULL, 0 }
+};
+
+#define MTK_SYSCTL_LOCK(sc) mtx_lock_spin(&(sc)->mtx)
+#define MTK_SYSCTL_UNLOCK(sc) mtx_unlock_spin(&(sc)->mtx)
+#define MTK_SYSCTL_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "mtk_sysctl", MTX_SPIN)
+#define MTK_SYSCTL_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
+static int
+mtk_sysctl_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "MTK System Controller");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int mtk_sysctl_detach(device_t);
+
+static int
+mtk_sysctl_attach(device_t dev)
+{
+ struct mtk_sysctl_softc *sc = device_get_softc(dev);
+
+ if (device_get_unit(dev) != 0 || mtk_sysctl_sc != NULL) {
+ device_printf(dev, "Only one sysctl module supported\n");
+ return (ENXIO);
+ }
+
+ mtk_sysctl_sc = sc;
+
+ /* Map control/status registers. */
+ sc->mem_rid = 0;
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->mem_rid, RF_ACTIVE);
+
+ if (sc->mem_res == NULL) {
+ device_printf(dev, "couldn't map memory\n");
+ mtk_sysctl_detach(dev);
+ return (ENXIO);
+ }
+
+ sc->dev = dev;
+
+ MTK_SYSCTL_LOCK_INIT(sc);
+
+ return (0);
+}
+
+static int
+mtk_sysctl_detach(device_t dev)
+{
+ struct mtk_sysctl_softc *sc = device_get_softc(dev);
+
+ if (sc->mem_res)
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid,
+ sc->mem_res);
+
+ MTK_SYSCTL_LOCK_DESTROY(sc);
+
+ return(0);
+}
+
+uint32_t
+mtk_sysctl_get(uint32_t reg)
+{
+ uint32_t val;
+
+ MTK_SYSCTL_LOCK(mtk_sysctl_sc);
+ val = bus_read_4(mtk_sysctl_sc->mem_res, reg);
+ MTK_SYSCTL_UNLOCK(mtk_sysctl_sc);
+
+ return (val);
+}
+
+void
+mtk_sysctl_set(uint32_t reg, uint32_t val)
+{
+
+ MTK_SYSCTL_LOCK(mtk_sysctl_sc);
+ bus_write_4(mtk_sysctl_sc->mem_res, reg, val);
+ MTK_SYSCTL_UNLOCK(mtk_sysctl_sc);
+}
+
+void
+mtk_sysctl_clr_set(uint32_t reg, uint32_t clr, uint32_t set)
+{
+ uint32_t val;
+
+ MTK_SYSCTL_LOCK(mtk_sysctl_sc);
+ val = bus_read_4(mtk_sysctl_sc->mem_res, reg);
+ val &= ~(clr);
+ val |= set;
+ bus_write_4(mtk_sysctl_sc->mem_res, reg, val);
+ MTK_SYSCTL_UNLOCK(mtk_sysctl_sc);
+}
+
+static device_method_t mtk_sysctl_methods[] = {
+ DEVMETHOD(device_probe, mtk_sysctl_probe),
+ DEVMETHOD(device_attach, mtk_sysctl_attach),
+ DEVMETHOD(device_detach, mtk_sysctl_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t mtk_sysctl_driver = {
+ "sysc",
+ mtk_sysctl_methods,
+ sizeof(struct mtk_sysctl_softc),
+};
+static devclass_t mtk_sysctl_devclass;
+
+EARLY_DRIVER_MODULE(mtk_sysctl, simplebus, mtk_sysctl_driver,
+ mtk_sysctl_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_EARLY);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 7, 1:37 AM (15 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29347527
Default Alt Text
D5826.id.diff (39 KB)
Attached To
Mode
D5826: Initial import of Ralink/Mediatek MIPS SoC support #1
Attached
Detach File
Event Timeline
Log In to Comment