Module Name: src
Committed By: jmcneill
Date: Sun Mar 1 15:07:49 UTC 2015
Modified Files:
src/sys/arch/arm/amlogic: amlogic_reg.h
src/sys/arch/evbarm/amlogic: amlogic_machdep.c amlogic_start.S
src/sys/arch/evbarm/conf: ODROID-C1
Log Message:
ODROID-C1 SMP support.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/amlogic/amlogic_reg.h
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/evbarm/amlogic/amlogic_machdep.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/evbarm/amlogic/amlogic_start.S
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/conf/ODROID-C1
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/arm/amlogic/amlogic_reg.h
diff -u src/sys/arch/arm/amlogic/amlogic_reg.h:1.3 src/sys/arch/arm/amlogic/amlogic_reg.h:1.4
--- src/sys/arch/arm/amlogic/amlogic_reg.h:1.3 Sat Feb 28 15:20:43 2015
+++ src/sys/arch/arm/amlogic/amlogic_reg.h Sun Mar 1 15:07:49 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: amlogic_reg.h,v 1.3 2015/02/28 15:20:43 jmcneill Exp $ */
+/* $NetBSD: amlogic_reg.h,v 1.4 2015/03/01 15:07:49 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <[email protected]>
@@ -32,7 +32,7 @@
#define CONSADDR_VA (CONSADDR - AMLOGIC_CORE_BASE + AMLOGIC_CORE_VBASE)
#define AMLOGIC_CORE_BASE 0xc0000000
-#define AMLOGIC_CORE_SIZE 0x10200000
+#define AMLOGIC_CORE_SIZE 0x1b000000
#define AMLOGIC_CORE_VBASE 0xe0000000
#define AMLOGIC_CBUS_OFFSET 0x01100000
@@ -50,10 +50,23 @@
#define AMLOGIC_PL310_OFFSET 0x04200000
+#define AMLOGIC_AOBUS_OFFSET 0x08100000
+
#define AMLOGIC_GPIOAO_OFFSET 0x08100024
#define AMLOGIC_USB0_OFFSET 0x09040000
#define AMLOGIC_USB1_OFFSET 0x090c0000
#define AMLOGIC_USB_SIZE 0x40000
+#define AMLOGIC_CPUCONF_OFFSET 0x1901ff80
+
+#define AMLOGIC_CBUS_CPU_CLK_CNTL_REG 0x419c
+
+#define AMLOGIC_AOBUS_PWR_CTRL0_REG 0xe0
+#define AMLOGIC_AOBUS_PWR_CTRL1_REG 0xe4
+#define AMLOGIC_AOBUS_PWR_MEM_PD0_REG 0xf4
+
+#define AMLOGIC_CPUCONF_CTRL_REG 0x00
+#define AMLOGIC_CPUCONF_CPU_ADDR_REG(n) (0x04 * (n))
+
#endif /* _ARM_AMLOGIC_REG_H */
Index: src/sys/arch/evbarm/amlogic/amlogic_machdep.c
diff -u src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.8 src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.9
--- src/sys/arch/evbarm/amlogic/amlogic_machdep.c:1.8 Sat Feb 28 18:50:15 2015
+++ src/sys/arch/evbarm/amlogic/amlogic_machdep.c Sun Mar 1 15:07:49 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: amlogic_machdep.c,v 1.8 2015/02/28 18:50:15 jmcneill Exp $ */
+/* $NetBSD: amlogic_machdep.c,v 1.9 2015/03/01 15:07:49 jmcneill Exp $ */
/*
* Machine dependent functions for kernel setup for TI OSK5912 board.
@@ -125,7 +125,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amlogic_machdep.c,v 1.8 2015/02/28 18:50:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amlogic_machdep.c,v 1.9 2015/03/01 15:07:49 jmcneill Exp $");
#include "opt_machdep.h"
#include "opt_ddb.h"
@@ -134,6 +134,7 @@ __KERNEL_RCSID(0, "$NetBSD: amlogic_mach
#include "opt_md.h"
#include "opt_amlogic.h"
#include "opt_arm_debug.h"
+#include "opt_multiprocessor.h"
#include "amlogic_com.h"
#if 0
@@ -328,10 +329,15 @@ initarm(void *arg)
amlogic_putchar('!');
#ifdef MULTIPROCESSOR
- uint32_t scu_cfg = bus_space_read_4(&amlogic_bs_tag,
- amlogic_core0_bsh, ROCKCHIP_SCU_OFFSET + SCU_CFG);
- arm_cpu_max = (scu_cfg & SCU_CFG_CPUMAX) + 1;
- membar_producer();
+ const bus_addr_t cbar = armreg_cbar_read();
+ if (cbar) {
+ const bus_space_handle_t scu_bsh =
+ cbar - AMLOGIC_CORE_BASE + AMLOGIC_CORE_VBASE;
+ uint32_t scu_cfg = bus_space_read_4(&amlogic_bs_tag, scu_bsh,
+ SCU_CFG);
+ arm_cpu_max = (scu_cfg & SCU_CFG_CPUMAX) + 1;
+ membar_producer();
+ }
#endif
/* Heads up ... Setup the CPU / MMU / TLB functions. */
@@ -341,9 +347,6 @@ initarm(void *arg)
init_clocks();
consinit();
-#ifdef MULTIPROCESSOR
- arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
-#endif
#if NARML2CC > 0
/*
@@ -573,3 +576,120 @@ amlogic_device_register(device_t self, v
prop_dictionary_set_uint32(dict, "offset", 0xfff00000);
}
}
+
+#if defined(MULTIPROCESSOR)
+void amlogic_mpinit(uint32_t);
+
+static void
+amlogic_mpinit_delay(u_int n)
+{
+ for (volatile int i = 0; i < n; i++)
+ ;
+}
+
+static void
+amlogic_mpinit_cpu(int cpu)
+{
+ const bus_addr_t cbar = armreg_cbar_read();
+ bus_space_tag_t bst = &amlogic_bs_tag;
+ const bus_space_handle_t scu_bsh =
+ cbar - AMLOGIC_CORE_BASE + AMLOGIC_CORE_VBASE;
+ const bus_space_handle_t ao_bsh =
+ AMLOGIC_CORE_VBASE + AMLOGIC_AOBUS_OFFSET;
+ const bus_space_handle_t cbus_bsh =
+ AMLOGIC_CORE_VBASE + AMLOGIC_CBUS_OFFSET;
+ uint32_t pwr_sts, pwr_cntl0, pwr_cntl1, cpuclk, mempd0;
+
+ pwr_sts = bus_space_read_4(bst, scu_bsh, SCU_CPU_PWR_STS);
+ pwr_sts &= ~(3 << (8 * cpu));
+ bus_space_write_4(bst, scu_bsh, SCU_CPU_PWR_STS, pwr_sts);
+
+ pwr_cntl0 = bus_space_read_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL0_REG);
+ pwr_cntl0 &= ~((3 << 18) << ((cpu - 1) * 2));
+ bus_space_write_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL0_REG, pwr_cntl0);
+
+ amlogic_mpinit_delay(5000);
+
+ cpuclk = bus_space_read_4(bst, cbus_bsh, AMLOGIC_CBUS_CPU_CLK_CNTL_REG);
+ cpuclk |= (1 << (24 + cpu));
+ bus_space_write_4(bst, cbus_bsh, AMLOGIC_CBUS_CPU_CLK_CNTL_REG, cpuclk);
+
+ mempd0 = bus_space_read_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_MEM_PD0_REG);
+ mempd0 &= ~((uint32_t)(0xf << 28) >> ((cpu - 1) * 4));
+ bus_space_write_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_MEM_PD0_REG, mempd0);
+
+ pwr_cntl1 = bus_space_read_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL1_REG);
+ pwr_cntl1 &= ~((3 << 4) << ((cpu - 1) * 2));
+ bus_space_write_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL1_REG, pwr_cntl1);
+
+ amlogic_mpinit_delay(10000);
+
+ for (;;) {
+ pwr_cntl1 = bus_space_read_4(bst, ao_bsh,
+ AMLOGIC_AOBUS_PWR_CTRL1_REG) & ((1 << 17) << (cpu - 1));
+ if (pwr_cntl1)
+ break;
+ amlogic_mpinit_delay(10000);
+ }
+
+ pwr_cntl0 = bus_space_read_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL0_REG);
+ pwr_cntl0 &= ~(1 << cpu);
+ bus_space_write_4(bst, ao_bsh, AMLOGIC_AOBUS_PWR_CTRL0_REG, pwr_cntl0);
+
+ cpuclk = bus_space_read_4(bst, cbus_bsh, AMLOGIC_CBUS_CPU_CLK_CNTL_REG);
+ cpuclk &= ~(1 << (24 + cpu));
+ bus_space_write_4(bst, cbus_bsh, AMLOGIC_CBUS_CPU_CLK_CNTL_REG, cpuclk);
+
+ bus_space_write_4(bst, scu_bsh, SCU_CPU_PWR_STS, pwr_sts);
+}
+
+void
+amlogic_mpinit(uint32_t mpinit_vec)
+{
+ const bus_addr_t cbar = armreg_cbar_read();
+ bus_space_tag_t bst = &amlogic_bs_tag;
+ volatile int i;
+ uint32_t ctrl, hatched = 0;
+ int cpu;
+
+ if (cbar == 0)
+ return;
+
+ const bus_space_handle_t scu_bsh =
+ cbar - AMLOGIC_CORE_BASE + AMLOGIC_CORE_VBASE;
+ const bus_space_handle_t cpuconf_bsh =
+ AMLOGIC_CORE_VBASE + AMLOGIC_CPUCONF_OFFSET;
+
+ const uint32_t scu_cfg = bus_space_read_4(bst, scu_bsh, SCU_CFG);
+ const u_int ncpus = (scu_cfg & SCU_CFG_CPUMAX) + 1;
+ if (ncpus < 2)
+ return;
+
+ for (cpu = 1; cpu < ncpus; cpu++) {
+ bus_space_write_4(bst, cpuconf_bsh,
+ AMLOGIC_CPUCONF_CPU_ADDR_REG(cpu), mpinit_vec);
+ amlogic_mpinit_cpu(cpu);
+ hatched |= __BIT(cpu);
+ }
+ ctrl = bus_space_read_4(bst, cpuconf_bsh, AMLOGIC_CPUCONF_CTRL_REG);
+ for (cpu = 0; cpu < ncpus; cpu++) {
+ ctrl |= __BIT(cpu);
+ }
+ bus_space_write_4(bst, cpuconf_bsh, AMLOGIC_CPUCONF_CTRL_REG, ctrl);
+
+ __asm __volatile("sev");
+
+ for (i = 0x10000000; i > 0; i--) {
+ __asm __volatile("dmb" ::: "memory");
+ if (arm_cpu_hatched == hatched)
+ break;
+ }
+
+ if (i == 0) {
+ const char *msg = "\nWARNING: Some APs failed to start\n";
+ const char *p = msg;
+ while (*p)
+ amlogic_putchar(*p++);
+ }
+}
+#endif
Index: src/sys/arch/evbarm/amlogic/amlogic_start.S
diff -u src/sys/arch/evbarm/amlogic/amlogic_start.S:1.1 src/sys/arch/evbarm/amlogic/amlogic_start.S:1.2
--- src/sys/arch/evbarm/amlogic/amlogic_start.S:1.1 Sat Feb 7 17:20:16 2015
+++ src/sys/arch/evbarm/amlogic/amlogic_start.S Sun Mar 1 15:07:49 2015
@@ -43,7 +43,7 @@
#include <arm/cortex/scu_reg.h>
-RCSID("$NetBSD: amlogic_start.S,v 1.1 2015/02/07 17:20:16 jmcneill Exp $")
+RCSID("$NetBSD: amlogic_start.S,v 1.2 2015/03/01 15:07:49 jmcneill Exp $")
#if defined(VERBOSE_INIT_ARM)
#define XPUTC(n) mov r0, n; bl xputc
@@ -152,7 +152,11 @@ _C_LABEL(amlogic_start):
XPUTC2(#60)
// Make sure the cache is flushed out to RAM for the other CPUs
bl _C_LABEL(armv7_dcache_wbinv_all)
- bl amlogic_mpinit
+
+ movw r0, #:lower16:amlogic_mpstart
+ movt r0, #:upper16:amlogic_mpstart
+ bl _C_LABEL(amlogic_mpinit)
+
XPUTC2(#62)
#endif /* MULTIPROCESSOR */
XPUTC2(#13)
@@ -171,113 +175,7 @@ _C_LABEL(amlogic_start):
#include <arm/cortex/a9_mpsubr.S>
-#define PMU_PWRDN_REG 0x0008
-#define PMU_PWRDN_SCU __BIT(4)
-
-#if defined(MULTIPROCESSOR)
-#ifndef KERNEL_BASES_EQUAL
- .pushsection .text,"ax",%progbits
-#endif
-amlogic_mptramp:
- ldr pc, 1f
-.global amlogic_mpstart_vec
-amlogic_mpstart_vec:
-1: .space 4
-
-amlogic_mpinit:
- mov r4, lr
- /* r5: SCU, r6: PMU, r7: SRAM */
- movw r5, #:lower16:(ROCKCHIP_CORE0_BASE+ROCKCHIP_SCU_OFFSET)
- movt r5, #:upper16:(ROCKCHIP_CORE0_BASE+ROCKCHIP_SCU_OFFSET)
- movw r6, #:lower16:(ROCKCHIP_CORE1_BASE+ROCKCHIP_PMU_OFFSET)
- movt r6, #:upper16:(ROCKCHIP_CORE1_BASE+ROCKCHIP_PMU_OFFSET)
- movw r7, #:lower16:(ROCKCHIP_CORE0_BASE+ROCKCHIP_SRAM_OFFSET)
- movt r7, #:upper16:(ROCKCHIP_CORE0_BASE+ROCKCHIP_SRAM_OFFSET)
-
- /* Set where the other CPU(s) are going to execute */
- XPUTC2(#118)
- movw r1, #:lower16:amlogic_mpstart
- movt r1, #:upper16:amlogic_mpstart
- ldr r0, =amlogic_mpstart_vec
- str r1, [r0]
- ldr r0, =amlogic_mptramp
- mov r2, #0
-1: ldr r1, [r0, r2]
- str r1, [r7, r2]
- add r2, r2, #4
- cmp r2, #32
- blt 1b
- dsb
-
- /* Invalid SCU cache tags */
- XPUTC2(#45)
- movw r1, #0xffff
- movt r1, #0
- str r1, [r5, #SCU_INV_ALL_REG]
-
- /* Get CPU count */
- ldr r1, [r5, #SCU_CFG]
- and r2, r1, #SCU_CFG_CPUMAX
- add r2, r2, #1
-
- /* Convert to CPU1..N mask */
- mov r7, #0
- lsl r7, r2, #1
- sub r7, r7, #1
- and r7, r7, #~1
-
- /* Power down secondary CPUs */
- XPUTC2(#46)
- ldr r1, [r6, #PMU_PWRDN_REG]
- orr r1, r1, r7
- str r1, [r6, #PMU_PWRDN_REG]
- dsb
-
- /* Power up SCU */
- XPUTC2(#46)
- ldr r1, [r6, #PMU_PWRDN_REG]
- and r1, r1, #~PMU_PWRDN_SCU
- str r1, [r6, #PMU_PWRDN_REG]
- dsb
-
- /* Enable SCU */
- XPUTC2(#46)
- ldr r1, [r5, #SCU_CTL]
- orr r1, r1, #SCU_CTL_SCU_ENA
- str r1, [r5, #SCU_CTL]
- dsb
-
- /* Power up secondary CPUs */
- XPUTC2(#33)
- ldr r1, [r6, #PMU_PWRDN_REG]
- and r1, r1, r7
- str r1, [r6, #PMU_PWRDN_REG]
- dsb
-
- XPUTC2(#49)
- XPUTC2(#50)
- XPUTC2(#51)
-
- //
- // Wait up a second for CPU1 to hatch.
- //
- movw r2, #:lower16:arm_cpu_hatched
- movt r2, #:upper16:arm_cpu_hatched
- mov r1, #0x10000000
-1: dmb
- ldr r0, [r2]
- cmp r0, r7
- beq .hatched
- subs r1, r1, #1
- bne 1b
-
-.hatched:
- bx r4
-
-ASEND(amlogic_mpinit)
-#ifndef KERNEL_BASES_EQUAL
- .popsection
-#endif
+#ifdef MULTIPROCESSOR
amlogic_mpstart:
/* invalidate cache */
Index: src/sys/arch/evbarm/conf/ODROID-C1
diff -u src/sys/arch/evbarm/conf/ODROID-C1:1.3 src/sys/arch/evbarm/conf/ODROID-C1:1.4
--- src/sys/arch/evbarm/conf/ODROID-C1:1.3 Sat Feb 28 18:52:01 2015
+++ src/sys/arch/evbarm/conf/ODROID-C1 Sun Mar 1 15:07:49 2015
@@ -1,5 +1,5 @@
#
-# $NetBSD: ODROID-C1,v 1.3 2015/02/28 18:52:01 jmcneill Exp $
+# $NetBSD: ODROID-C1,v 1.4 2015/03/01 15:07:49 jmcneill Exp $
#
# Odroid-C1 (Amlogic S805) based SBC (Single Board Computer)
#
@@ -156,7 +156,7 @@ mainbus0 at root
# The boot cpu
cpu* at mainbus?
-#options MULTIPROCESSOR
+options MULTIPROCESSOR
# A5 core devices
armperiph0 at mainbus?