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?

Reply via email to