Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch A80: Startup 3 additional Cortex-A7 cores in cluste...



details:   https://anonhg.NetBSD.org/src/rev/b275d0c02b20
branches:  trunk
changeset: 805001:b275d0c02b20
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Dec 11 23:35:11 2014 +0000

description:
A80: Startup 3 additional Cortex-A7 cores in cluster 0.

diffstat:

 sys/arch/arm/allwinner/awin_reg.h   |   19 ++++
 sys/arch/evbarm/awin/awin_machdep.c |   14 ++-
 sys/arch/evbarm/awin/awin_start.S   |  150 ++++++++++++++++++++++++++++++++++-
 sys/arch/evbarm/awin/platform.h     |    5 +-
 4 files changed, 177 insertions(+), 11 deletions(-)

diffs (truncated from 305 to 300 lines):

diff -r 903c896a47bf -r b275d0c02b20 sys/arch/arm/allwinner/awin_reg.h
--- a/sys/arch/arm/allwinner/awin_reg.h Thu Dec 11 23:24:12 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_reg.h Thu Dec 11 23:35:11 2014 +0000
@@ -54,6 +54,8 @@
 #define AWIN_CORE_PBASE                        0x01C00000
 #if defined(ALLWINNER_A80)
 #define AWIN_CORE_SIZE                 0x06400000      /* XXX */
+#define AWIN_A80_RCPUCFG_PBASE         0x01700000
+#define AWIN_A80_RCPUCFG_SIZE          0x00100000
 #define AWIN_A80_CORE2_PBASE           0x00800000
 #define AWIN_A80_CORE2_SIZE            0x00100000
 #define AWIN_A80_USB_PBASE             0x00a00000
@@ -2821,9 +2823,26 @@
 #define AWIN_A80_RPRCM_CIR_CLK_REG             0x0054
 #define AWIN_A80_RPRCM_APB0_RST_REG            0x00b0
 
+#define AWIN_A80_RPRCM_CLUSTER0_RST_REG                0x0004
+
+#define AWIN_A80_RPRCM_CLUSTER0_RST_REG                0x0004
+#define AWIN_A80_RPRCM_CLUSTER1_RST_REG                0x0008
+
+#define AWIN_A80_RPRCM_CLUSTER0_PWR_GATING_REG 0x0100
+#define AWIN_A80_RPRCM_CLUSTER1_PWR_GATING_REG 0x0104
+
+#define AWIN_A80_RPRCM_CLUSTER0_PRW_CLAMP_REG  0x0140
+
+#define AWIN_A80_RPRCM_CLUSTER0_PRW_CLAMP_STATUS_REG   0x0064
+
+#define AWIN_A80_RPRCM_PRIVATE_REG             0x0164
+
 #define AWIN_A80_RPRCM_APB0_GATING_CIR         __BIT(1)
 #define AWIN_A80_RPRCM_APB0_RST_CIR            __BIT(1)
 
+#define AWIN_A80_RCPUCFG_CLUSTER0_RST_REG      0x0080
+#define AWIN_A80_RCPUCFG_CLUSTER1_RST_REG      0x0084
+
 #define AWIN_A80_RSB_CMD_REG                   0x002c
 #define AWIN_A80_RSB_DAR_REG                   0x0030
 
diff -r 903c896a47bf -r b275d0c02b20 sys/arch/evbarm/awin/awin_machdep.c
--- a/sys/arch/evbarm/awin/awin_machdep.c       Thu Dec 11 23:24:12 2014 +0000
+++ b/sys/arch/evbarm/awin/awin_machdep.c       Thu Dec 11 23:35:11 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: awin_machdep.c,v 1.35 2014/12/10 17:45:53 jmcneill Exp $ */
+/*     $NetBSD: awin_machdep.c,v 1.36 2014/12/11 23:35:11 jmcneill Exp $ */
 
 /*
  * Machine dependent functions for kernel setup for TI OSK5912 board.
@@ -125,7 +125,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.35 2014/12/10 17:45:53 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_machdep.c,v 1.36 2014/12/11 23:35:11 jmcneill Exp $");
 
 #include "opt_machdep.h"
 #include "opt_ddb.h"
@@ -318,6 +318,16 @@
                .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
                .pd_cache = PTE_NOCACHE
        },
+       {
+               /*
+                * A80 CPUCFG
+                */
+               .pd_va = _A(AWIN_A80_RCPUCFG_VBASE),
+               .pd_pa = _A(AWIN_A80_RCPUCFG_PBASE),
+               .pd_size = _S(AWIN_A80_RCPUCFG_SIZE),
+               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,
+               .pd_cache = PTE_NOCACHE
+       },
 #endif
        {
                /*
diff -r 903c896a47bf -r b275d0c02b20 sys/arch/evbarm/awin/awin_start.S
--- a/sys/arch/evbarm/awin/awin_start.S Thu Dec 11 23:24:12 2014 +0000
+++ b/sys/arch/evbarm/awin/awin_start.S Thu Dec 11 23:35:11 2014 +0000
@@ -41,7 +41,7 @@
 #include <arm/allwinner/awin_reg.h>
 #include <evbarm/awin/platform.h>  
 
-RCSID("$NetBSD: awin_start.S,v 1.7 2014/12/07 18:32:13 jmcneill Exp $")
+RCSID("$NetBSD: awin_start.S,v 1.8 2014/12/11 23:35:11 jmcneill Exp $")
 
 #if defined(VERBOSE_INIT_ARM)
 #define        XPUTC(n)        mov r0, n; bl xputc
@@ -151,7 +151,7 @@
        // Make sure the cache is flushed out to RAM for the other CPUs
        bl      _C_LABEL(armv7_dcache_wbinv_all)
 
-#if defined(ALLWINNER_A20) + defined(ALLWINNER_A31) + defined(ALLWINNER_A80) > 1
+#if defined(ALLWINNER_A20) + defined(ALLWINNER_A31) > 1
        // Read SoC ID
        movw    r5, #:lower16:(AWIN_CORE_PBASE+AWIN_SRAM_OFFSET)
        movt    r5, #:upper16:(AWIN_CORE_PBASE+AWIN_SRAM_OFFSET)
@@ -168,11 +168,10 @@
        rev     r1, r1
 #endif
        lsr     r1, r1, #16
-#endif /* ALLWINNER_A20 + ALLWINNER_A31 + ALLWINNER_A80 > 1 */
 
        // MP init based on SoC ID
 #if defined(ALLWINNER_A20)
-# if defined(ALLWINNER_A31) || defined(ALLWINNER_A80)
+# if defined(ALLWINNER_A31)
        movw    r0, #AWIN_SRAM_VER_KEY_A20
        cmp     r1, r0
        bleq    a20_mpinit
@@ -181,7 +180,7 @@
 # endif
 #endif
 #if defined(ALLWINNER_A31)
-# if defined(ALLWINNER_A20) || defined(ALLWINNER_A80)
+# if defined(ALLWINNER_A20)
        movw    r0, #AWIN_SRAM_VER_KEY_A31
        cmp     r1, r0
        bleq    a31_mpinit
@@ -189,6 +188,9 @@
        bl      a31_mpinit
 # endif
 #endif
+#elif defined(ALLWINNER_A80)
+       bl      a80_mpinit
+#endif
 
        XPUTC2(#62)
 #endif /* MULTIPROCESSOR */
@@ -439,6 +441,130 @@
        .popsection
 #endif
 
+#if defined(ALLWINNER_A80)
+#ifndef KERNEL_BASES_EQUAL
+       .pushsection .text,"ax",%progbits
+#endif
+a80_mpinit:
+       mov     r4, lr                  // because we call gtmr_bootdelay
+       movw    r5, #:lower16:(AWIN_A80_RCPUCFG_PBASE)
+       movt    r5, #:upper16:(AWIN_A80_RCPUCFG_PBASE)
+       movw    r6, #:lower16:(AWIN_A80_RCPUS_PBASE+AWIN_A80_RPRCM_OFFSET)
+       movt    r6, #:upper16:(AWIN_A80_RCPUS_PBASE+AWIN_A80_RPRCM_OFFSET)
+
+       XPUTC2(#65)
+       XPUTC2(#51)
+       XPUTC2(#49)
+
+#ifdef __ARMEB__
+       setend  le                      // everything here is little-endian
+#endif
+
+       mov     r12, #1                 // CPU number
+
+a80_mpinit_cpu:
+
+       XPUTC2(r12)
+
+       /* Set where the other CPU(s) are going to execute */
+       movw    r1, #:lower16:cortex_mpstart
+       movt    r1, #:upper16:cortex_mpstart
+       str     r1, [r6, #AWIN_A80_RPRCM_PRIVATE_REG]
+       dsb
+
+       /* Assert CPU power on reset */
+       ldr     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_RST_REG]
+       mov     r0, #1
+       lsl     r0, r0, r12
+       bic     r1, r1, r0
+       str     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_RST_REG]
+
+       /* Assert CPU core reset */
+       ldr     r1, [r5, #AWIN_A80_RCPUCFG_CLUSTER0_RST_REG]
+       mov     r0, #1
+       lsl     r0, r0, r12
+       bic     r1, r1, r0
+       str     r1, [r5, #AWIN_A80_RCPUCFG_CLUSTER0_RST_REG]
+
+       /* Release power clamp */
+       mov     r1, #0x00
+       mov     r2, #0x4
+       mul     r7, r12, r2
+       add     r7, r7, #AWIN_A80_RPRCM_CLUSTER0_PRW_CLAMP_REG
+       str     r1, [r6, r7]
+       dsb
+
+       mov     r2, #0x40
+       mul     r7, r12, r2
+       add     r7, r7, #AWIN_A80_RPRCM_CLUSTER0_PRW_CLAMP_STATUS_REG
+1:
+       ldr     r1, [r5, r7]
+       cmp     r1, #0x00
+       bne     1b
+
+       /* We need to wait (at least) 10ms */
+       mov     r0, #0x3b000                    // 10.06ms
+       bl      _C_LABEL(gtmr_bootdelay)        // endian-neutral
+
+       /* Clear power-off gating */
+       ldr     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_PWR_GATING_REG] 
+       mov     r0, #1
+       lsl     r0, r0, r12
+       bic     r1, r1, r0
+       str     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_PWR_GATING_REG]
+       dsb
+
+       /* We need to wait (at least) 10ms */
+       mov     r0, #0x3b000                    // 10.06ms
+       bl      _C_LABEL(gtmr_bootdelay)        // endian-neutral
+
+       /* Bring core out of reset */
+       ldr     r1, [r5, #AWIN_A80_RCPUCFG_CLUSTER0_RST_REG]
+       mov     r0, #1
+       lsl     r0, r0, r12
+       orr     r1, r1, r0
+       str     r1, [r5, #AWIN_A80_RCPUCFG_CLUSTER0_RST_REG]
+
+       /* Bring cpu power-on out of reset */
+       ldr     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_RST_REG]
+       mov     r0, #1
+       lsl     r0, r0, r12
+       orr     r1, r1, r0
+       str     r1, [r6, #AWIN_A80_RPRCM_CLUSTER0_RST_REG]
+       dsb
+
+       /* If there is another CPU, start it */
+       add     r12, r12, #1
+       cmp     r12, #3
+       ble     a80_mpinit_cpu
+
+#ifdef __ARMEB__
+       setend  be                              // we're done with little endian
+#endif
+
+       //
+       // Wait up a second for CPU1-3 to hatch. 
+       //
+       movw    r6, #:lower16:arm_cpu_hatched
+       movt    r6, #:upper16:arm_cpu_hatched
+       mov     r5, #200                        // 200 x 5ms
+
+1:     dmb                                     // memory barrier
+       ldr     r0, [r6]                        // load hatched
+       cmp     r0, #0xe                        // our bits set yet?
+       bxge    r4                              //   yes, return
+       subs    r5, r5, #1                      // decrement count
+       bxeq    r4                              //   0? return
+       mov     r0, #0x1d800                    // 5.03ms
+       bl      _C_LABEL(gtmr_bootdelay)
+       b       1b
+
+ASEND(a80_mpinit)
+#ifndef KERNEL_BASES_EQUAL
+       .popsection
+#endif
+#endif /* ALLWINNER_A80 */
+
 #endif /* MULTIPROCESSOR */
 
 .Lmmu_init_table:
@@ -464,15 +590,25 @@
                L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
 
 #if defined(ALLWINNER_A80)
-       /* Map AWIN RCPUS (for PIO L-N) */
+       /* Map AWIN RCPUS (for PIO L-N, PRCM) */
        MMU_INIT(AWIN_A80_RCPUS_VBASE, AWIN_A80_RCPUS_PBASE,
                (AWIN_A80_RCPUS_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
                L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
 
-       /* Map AWIN RCPUS (for PIO L-N) */
+       /* Map AWIN RCPUS (for PIO L-N, PRCM) */
        MMU_INIT(AWIN_A80_RCPUS_PBASE, AWIN_A80_RCPUS_PBASE,
                (AWIN_A80_RCPUS_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
                L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+       /* Map AWIN RCPUCFG */
+       MMU_INIT(AWIN_A80_RCPUCFG_VBASE, AWIN_A80_RCPUCFG_PBASE,
+               (AWIN_A80_RCPUCFG_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+               L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+       /* Map AWIN RCPUCFG */
+       MMU_INIT(AWIN_A80_RCPUCFG_PBASE, AWIN_A80_RCPUCFG_PBASE,
+               (AWIN_A80_RCPUCFG_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+               L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
 #endif
 
        /* end of table */
diff -r 903c896a47bf -r b275d0c02b20 sys/arch/evbarm/awin/platform.h
--- a/sys/arch/evbarm/awin/platform.h   Thu Dec 11 23:24:12 2014 +0000
+++ b/sys/arch/evbarm/awin/platform.h   Thu Dec 11 23:35:11 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: platform.h,v 1.4 2014/12/07 00:36:26 jmcneill Exp $    */
+/*     $NetBSD: platform.h,v 1.5 2014/12/11 23:35:11 jmcneill Exp $    */
 /*
  * Copyright (c) 2007 Microsoft
  * All rights reserved.
@@ -56,7 +56,8 @@
 #define AWIN_A80_CORE2_VBASE   (AWIN_SRAM_VBASE + AWIN_SRAM_SIZE)
 #define AWIN_A80_USB_VBASE     (AWIN_A80_CORE2_VBASE + AWIN_A80_CORE2_SIZE)
 #define AWIN_A80_RCPUS_VBASE   (AWIN_A80_USB_VBASE + AWIN_A80_USB_SIZE)
-#define AWIN_KERNEL_IO_VEND    (AWIN_A80_RCPUS_VBASE + AWIN_A80_RCPUS_SIZE)



Home | Main Index | Thread Index | Old Index