From 0b0db98be7e22f5b862b62f63db7ff6ab02a3a7f Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 30 Mar 2017 19:18:30 +0300 Subject: axs103: Clean-up smp_kick_all_cpus() * Rely on default pulse polarity value * Don't mess with "multicore" value as it doesn't affect execution In essence we now do a bare minimal stuff: 1) Select HS38x2_1 with CORE_SEL=1 bits 2) Select "manual" core start (via CREG) with START_MODE=0 3) Generate cpu_start pulse with START=1 Signed-off-by: Alexey Brodkin diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c index a5e774b..57c7902 100644 --- a/board/synopsys/axs10x/axs10x.c +++ b/board/synopsys/axs10x/axs10x.c @@ -61,16 +61,14 @@ void smp_kick_all_cpus(void) { /* CPU start CREG */ #define AXC003_CREG_CPU_START 0xF0001400 - /* Bits positions in CPU start CREG */ #define BITS_START 0 -#define BITS_POLARITY 8 +#define BITS_START_MODE 4 #define BITS_CORE_SEL 9 -#define BITS_MULTICORE 12 - -#define CMD (1 << BITS_MULTICORE) | (1 << BITS_CORE_SEL) | \ - (1 << BITS_POLARITY) | (1 << BITS_START) - writel(CMD, (void __iomem *)AXC003_CREG_CPU_START); + int cmd = readl((void __iomem *)AXC003_CREG_CPU_START); + cmd |= (1 << BITS_CORE_SEL) | (1 << BITS_START); + cmd &= ~(1 << BITS_START_MODE); + writel(cmd, (void __iomem *)AXC003_CREG_CPU_START); } #endif -- cgit v0.10.2 From 2a5062ca9ecc22b88af2babf812b05dd97ecde46 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Fri, 31 Mar 2017 11:14:35 +0300 Subject: axs103: Support slave core kick-start on axs103 v1.1 firmware In axs103 v1.1 procedure to kick-start slave cores has changed quite a bit compared t previous implementation. In particular: * We used to have a generic START bit for all cores selected by CORE_SEL mask. But now we don't touch CORE_SEL at all because we have a dedicated START bit for each core: bit 0: Core 0 (master) bit 1: Core 1 (slave) * Now there's no need to select "manual" mode of core start Additional challenge for us is how to tell which axs103 firmware we're dealing with. For now we'll rely on ARC core version which was bumped from 2.1c to 3.0. Signed-off-by: Alexey Brodkin diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c index 57c7902..e6b69da 100644 --- a/board/synopsys/axs10x/axs10x.c +++ b/board/synopsys/axs10x/axs10x.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "axs10x.h" DECLARE_GLOBAL_DATA_PTR; @@ -66,9 +67,27 @@ void smp_kick_all_cpus(void) #define BITS_START_MODE 4 #define BITS_CORE_SEL 9 +/* + * In axs103 v1.1 START bits semantics has changed quite a bit. + * We used to have a generic START bit for all cores selected by CORE_SEL mask. + * But now we don't touch CORE_SEL at all because we have a dedicated START bit + * for each core: + * bit 0: Core 0 (master) + * bit 1: Core 1 (slave) + */ +#define BITS_START_CORE1 1 + +#define ARCVER_HS38_3_0 0x53 + + int core_family = read_aux_reg(ARC_AUX_IDENTITY) & 0xff; int cmd = readl((void __iomem *)AXC003_CREG_CPU_START); - cmd |= (1 << BITS_CORE_SEL) | (1 << BITS_START); - cmd &= ~(1 << BITS_START_MODE); + + if (core_family < ARCVER_HS38_3_0) { + cmd |= (1 << BITS_CORE_SEL) | (1 << BITS_START); + cmd &= ~(1 << BITS_START_MODE); + } else { + cmd |= (1 << BITS_START_CORE1); + } writel(cmd, (void __iomem *)AXC003_CREG_CPU_START); } #endif -- cgit v0.10.2 From 6cba327bd96f90818a8beede51405228c54a5251 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Thu, 30 Mar 2017 17:50:45 +0300 Subject: arcv2: Halt non-master cores Even though we expect only master core to execute U-Boot code let's make sure even if for some reason slave cores attempt to execute U-Boot in parallel with master they get halted very early. If platform wants it may kick-start slave cores before passing control to say Linux kernel or any other application that want to see all cores of SMP SoC up and running. Signed-off-by: Alexey Brodkin diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index 90ee7e0..b2ba768 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -10,6 +10,22 @@ #include ENTRY(_start) + ; Non-masters will be halted immediately, they might be kicked later + ; by platform code right before passing control to the Linux kernel + ; in bootm.c:boot_jump_linux(). + lr r5, [identity] + lsr r5, r5, 8 + bmsk r5, r5, 7 + cmp r5, 0 + mov.nz r0, r5 + bz .Lmaster_proceed + flag 1 + nop + nop + nop + +.Lmaster_proceed: + /* Setup interrupt vector base that matches "__text_start" */ sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] -- cgit v0.10.2