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