summaryrefslogtreecommitdiffstats
path: root/sys/arm/rockchip
diff options
context:
space:
mode:
authorganbold <ganbold@FreeBSD.org>2014-05-09 05:39:57 +0000
committerganbold <ganbold@FreeBSD.org>2014-05-09 05:39:57 +0000
commit93d0ee130f8ff8e0455b540cdda90f18f74bd53b (patch)
tree0786ce2daed539459a17908f2a190997743d4857 /sys/arm/rockchip
parent9913c6f0ef050d749b0727b18538a39c60e5bd21 (diff)
downloadFreeBSD-src-93d0ee130f8ff8e0455b540cdda90f18f74bd53b.zip
FreeBSD-src-93d0ee130f8ff8e0455b540cdda90f18f74bd53b.tar.gz
Add the codes for enabling CPU cores of Rockchip RK3188 SoC.
Enable SMP for Radxa Rock board. Approved by: stas (mentor)
Diffstat (limited to 'sys/arm/rockchip')
-rw-r--r--sys/arm/rockchip/files.rk30xx1
-rw-r--r--sys/arm/rockchip/rk30xx_machdep.c1
-rw-r--r--sys/arm/rockchip/rk30xx_mp.c192
3 files changed, 194 insertions, 0 deletions
diff --git a/sys/arm/rockchip/files.rk30xx b/sys/arm/rockchip/files.rk30xx
index 98e3d41..e1b2a54 100644
--- a/sys/arm/rockchip/files.rk30xx
+++ b/sys/arm/rockchip/files.rk30xx
@@ -19,3 +19,4 @@ arm/rockchip/rk30xx_grf.c standard
arm/rockchip/rk30xx_wdog.c standard
arm/rockchip/rk30xx_gpio.c optional gpio
dev/usb/controller/dwc_otg_fdt.c optional dwcotg
+arm/rockchip/rk30xx_mp.c optional smp
diff --git a/sys/arm/rockchip/rk30xx_machdep.c b/sys/arm/rockchip/rk30xx_machdep.c
index 0cb9bca..4316073 100644
--- a/sys/arm/rockchip/rk30xx_machdep.c
+++ b/sys/arm/rockchip/rk30xx_machdep.c
@@ -85,6 +85,7 @@ int
initarm_devmap_init(void)
{
+ arm_devmap_add_entry(0x10000000, 0x00200000);
arm_devmap_add_entry(0x20000000, 0x00100000);
return (0);
diff --git a/sys/arm/rockchip/rk30xx_mp.c b/sys/arm/rockchip/rk30xx_mp.c
new file mode 100644
index 0000000..54457a3
--- /dev/null
+++ b/sys/arm/rockchip/rk30xx_mp.c
@@ -0,0 +1,192 @@
+/*-
+ * Copyright (c) 2014 Ganbold Tsagaankhuu <ganbold@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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/smp.h>
+
+#include <machine/smp.h>
+#include <machine/fdt.h>
+#include <machine/intr.h>
+
+#define SCU_PHYSBASE 0x1013c000
+#define SCU_SIZE 0x100
+
+#define SCU_CONTROL_REG 0x00
+#define SCU_CONTROL_ENABLE (1 << 0)
+#define SCU_STANDBY_EN (1 << 5)
+#define SCU_CONFIG_REG 0x04
+#define SCU_CONFIG_REG_NCPU_MASK 0x03
+#define SCU_CPUPOWER_REG 0x08
+#define SCU_INV_TAGS_REG 0x0c
+
+#define SCU_FILTER_START_REG 0x10
+#define SCU_FILTER_END_REG 0x14
+#define SCU_SECURE_ACCESS_REG 0x18
+#define SCU_NONSECURE_ACCESS_REG 0x1c
+
+#define IMEM_PHYSBASE 0x10080000
+#define IMEM_SIZE 0x20
+
+#define PMU_PHYSBASE 0x20004000
+#define PMU_SIZE 0x100
+#define PMU_PWRDN_CON 0x08
+#define PMU_PWRDN_SCU (1 << 4)
+
+extern char *mpentry_addr;
+static void rk30xx_boot2(void);
+
+static void
+rk30xx_boot2(void)
+{
+
+ __asm __volatile(
+ "ldr pc, 1f\n"
+ ".globl mpentry_addr\n"
+ "mpentry_addr:\n"
+ "1: .space 4\n");
+}
+
+void
+platform_mp_init_secondary(void)
+{
+
+ gic_init_secondary();
+}
+
+void
+platform_mp_setmaxid(void)
+{
+ bus_space_handle_t scu;
+ int ncpu;
+ uint32_t val;
+
+ if (mp_ncpus != 0)
+ return;
+
+ if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+ panic("Could not map the SCU");
+
+ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONFIG_REG);
+ ncpu = (val & SCU_CONFIG_REG_NCPU_MASK) + 1;
+ bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+
+ mp_ncpus = ncpu;
+ mp_maxid = ncpu - 1;
+}
+
+int
+platform_mp_probe(void)
+{
+
+ if (mp_ncpus == 0)
+ platform_mp_setmaxid();
+
+ return (mp_ncpus > 1);
+}
+
+void
+platform_mp_start_ap(void)
+{
+ bus_space_handle_t scu;
+ bus_space_handle_t imem;
+ bus_space_handle_t pmu;
+ uint32_t val;
+ int i;
+
+ if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
+ panic("Could not map the SCU");
+ if (bus_space_map(fdtbus_bs_tag, IMEM_PHYSBASE,
+ IMEM_SIZE, 0, &imem) != 0)
+ panic("Could not map the IMEM");
+ if (bus_space_map(fdtbus_bs_tag, PMU_PHYSBASE, PMU_SIZE, 0, &pmu) != 0)
+ panic("Could not map the PMU");
+
+ /*
+ * Invalidate SCU cache tags. The 0x0000ffff constant invalidates all
+ * ways on all cores 0-3. Per the ARM docs, it's harmless to write to
+ * the bits for cores that are not present.
+ */
+ bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000ffff);
+
+ /* Make sure all cores except the first are off */
+ val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+ for (i = 1; i < mp_ncpus; i++)
+ val |= 1 << i;
+ bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+ /* Enable SCU power domain */
+ val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+ val &= ~PMU_PWRDN_SCU;
+ bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+ /* Enable SCU */
+ val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
+ bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG,
+ val | SCU_CONTROL_ENABLE);
+
+ /*
+ * Cores will execute the code which resides at the start of
+ * the on-chip bootram/sram after power-on. This sram region
+ * should be reserved and the trampoline code that directs
+ * the core to the real startup code in ram should be copied
+ * into this sram region.
+ *
+ * First set boot function for the sram code.
+ */
+ mpentry_addr = (char *)pmap_kextract((vm_offset_t)mpentry);
+
+ /* Copy trampoline to sram, that runs during startup of the core */
+ bus_space_write_region_4(fdtbus_bs_tag, imem, 0,
+ (uint32_t *)&rk30xx_boot2, 8);
+
+ cpu_idcache_wbinv_all();
+ cpu_l2cache_wbinv_all();
+
+ /* Start all cores */
+ val = bus_space_read_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON);
+ for (i = 1; i < mp_ncpus; i++)
+ val &= ~(1 << i);
+ bus_space_write_4(fdtbus_bs_tag, pmu, PMU_PWRDN_CON, val);
+
+ armv7_sev();
+
+ bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, imem, IMEM_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, pmu, PMU_SIZE);
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+ pic_ipi_send(cpus, ipi);
+}
OpenPOWER on IntegriCloud