Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch ODROID-C1 SMP support.
details: https://anonhg.NetBSD.org/src/rev/50dde99e24ae
branches: trunk
changeset: 336442:50dde99e24ae
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sun Mar 01 15:07:49 2015 +0000
description:
ODROID-C1 SMP support.
diffstat:
sys/arch/arm/amlogic/amlogic_reg.h | 17 +++-
sys/arch/evbarm/amlogic/amlogic_machdep.c | 138 ++++++++++++++++++++++++++++-
sys/arch/evbarm/amlogic/amlogic_start.S | 116 +-----------------------
sys/arch/evbarm/conf/ODROID-C1 | 4 +-
4 files changed, 153 insertions(+), 122 deletions(-)
diffs (truncated from 378 to 300 lines):
diff -r 850fe89ff0e1 -r 50dde99e24ae sys/arch/arm/amlogic/amlogic_reg.h
--- a/sys/arch/arm/amlogic/amlogic_reg.h Sun Mar 01 15:06:09 2015 +0000
+++ b/sys/arch/arm/amlogic/amlogic_reg.h Sun Mar 01 15:07:49 2015 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 */
diff -r 850fe89ff0e1 -r 50dde99e24ae sys/arch/evbarm/amlogic/amlogic_machdep.c
--- a/sys/arch/evbarm/amlogic/amlogic_machdep.c Sun Mar 01 15:06:09 2015 +0000
+++ b/sys/arch/evbarm/amlogic/amlogic_machdep.c Sun Mar 01 15:07:49 2015 +0000
@@ -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 @@
#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 @@
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 @@
init_clocks();
consinit();
-#ifdef MULTIPROCESSOR
- arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
-#endif
#if NARML2CC > 0
/*
@@ -573,3 +576,120 @@
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
diff -r 850fe89ff0e1 -r 50dde99e24ae sys/arch/evbarm/amlogic/amlogic_start.S
--- a/sys/arch/evbarm/amlogic/amlogic_start.S Sun Mar 01 15:06:09 2015 +0000
+++ b/sys/arch/evbarm/amlogic/amlogic_start.S Sun Mar 01 15:07:49 2015 +0000
@@ -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 @@
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 @@
#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
Home |
Main Index |
Thread Index |
Old Index