Startup secondary core on sun7i. Creates a new backwards compatible SMP boot protocol.

This commit is contained in:
Carl van Schaik
2013-08-14 21:11:27 +10:00
committed by Henrik Nordstrom
parent d07bcb82d9
commit a3cca42190
9 changed files with 302 additions and 0 deletions

View File

@ -39,6 +39,13 @@ COBJS += watchdog.o
ifdef DEBUG
COBJS += early_print.o
endif
ifdef CONFIG_BOARD_POSTCLK_INIT
COBJS += postclk_init.o
endif
ifdef CONFIG_SYS_SECONDARY_ON
COBJS += secondary_init.o
COBJS += smp.o
endif
ifndef CONFIG_SPL_BUILD
COBJS += key.o

View File

@ -0,0 +1,36 @@
/*
* (C) Copyright 2013
* Carl van Schaik <carl@ok-labs.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#if defined(CONFIG_SYS_SECONDARY_ON)
#include <asm/arch/smp.h>
#endif
int board_postclk_init(void)
{
#if defined(CONFIG_SYS_SECONDARY_ON)
startup_secondaries();
#endif
return 0;
}

View File

@ -0,0 +1,48 @@
/*
* A lowlevel_init function that sets up the stack to call a C function to
* perform further init.
*
* (C) Copyright 2013
* Carl van Schaik <carl@ok-labs.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <asm-offsets.h>
#include <config.h>
#include <linux/linkage.h>
ENTRY(secondary_init)
/* Get cpu number : r5 */
mrc p15, 0, r5, c0, c0, 5
and r5, r5, #0xff
/*
* Setup a secondary stack, each core gets 128 bytes.
*/
ldr sp, =secondary_stack
mov r0, #0x80
add sp, sp, r0, lsl r5
/*
* Jump to C
*/
bl secondary_start
ENDPROC(secondary_init)

View File

@ -0,0 +1,96 @@
/*
* (C) Copyright 2013
* Carl van Schaik <carl@ok-labs.com>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/smp.h>
#include <asm/arch/cpucfg.h>
/* Right now we assume only a single secondary as in sun7i */
#if defined(CONFIG_SUN7I)
#define NUM_CORES 2
#else
#error unsupported SoC
#endif
static void secondary_pen(void)
{
struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE;
while (1) {
__asm__ __volatile__("wfe" ::: "memory");
unsigned long boot_addr = readl(&cpucfg->boot_addr);
__asm__ __volatile__(
"mov r14, %0 \n"
"bx r14 \n"
: : "r" (boot_addr)
);
};
}
u32 secondary_stack[32*(NUM_CORES-1)];
void secondary_start(void)
{
secondary_pen();
}
/* Power on secondaries */
void startup_secondaries(void)
{
int i;
struct sunxi_cpucfg *cpucfg = (struct sunxi_cpucfg *)SUNXI_CPUCFG_BASE;
writel((u32)secondary_init, &cpucfg->boot_addr);
for (i = 1; i < NUM_CORES; i++) {
/* Assert CPU reset just in case */
writel(CPU_RESET_SET, &cpucfg->cpu[i].reset_ctrl);
/* Ensure CPU reset also invalidates L1 caches */
clrbits_le32(&cpucfg->general_ctrl,
GENERAL_CTRL_NO_L1_RESET_CPU(i));
/* Lock CPU */
clrbits_le32(&cpucfg->debug1_ctrl, 1 << i);
/* Ramp up power to CPU1 */
assert(i == 1);
u32 j = 0xff << 1;
do {
j = j >> 1;
writel(j, &cpucfg->cpu1_power_clamp);
} while (j != 0);
udelay(10*1000); /* 10ms */
clrbits_le32(&cpucfg->cpu1_power_off, 1);
/* Release CPU reset */
writel(CPU_RESET_CLEAR, &cpucfg->cpu[i].reset_ctrl);
/* Unlock CPU */
setbits_le32(&cpucfg->debug1_ctrl, 1 << i);
printf("Secondary CPU%d power-on\n", i);
}
}

View File

@ -86,6 +86,7 @@
#define SUNXI_TP_BASE 0x01c25000
#define SUNXI_PMU_BASE 0x01c25400
#define SUNXI_CPUCFG_BASE 0x01c25c00 /* sun7i only ? */
#define SUNXI_UART0_BASE 0x01c28000
#define SUNXI_UART1_BASE 0x01c28400

View File

@ -0,0 +1,71 @@
/*
* (C) Copyright 2013
* Carl van Schaik <carl@ok-labs.com>
*
* CPU configuration registers for the sun7i (A20).
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _SUNXI_CPUCFG_H_
#define _SUNXI_CPUCFG_H_
#ifndef __ASSEMBLY__
struct sunxi_cpu_ctrl {
u32 reset_ctrl;
u32 cpu_ctrl;
u32 status;
u32 _res[13];
};
#define CPU_RESET_SET 0
#define CPU_RESET_CLEAR 3
#define CPU_STATUS_SMP (1 << 0)
#define CPU_STATUS_WFE (1 << 1)
#define CPU_STATUS_WFI (1 << 2)
struct sunxi_cpucfg {
u32 _res1[16]; /* 0x000 */
struct sunxi_cpu_ctrl cpu[2]; /* 0x040 */
u32 _res2[48]; /* 0x0c0 */
u32 _res3; /* 0x180 */
u32 general_ctrl; /* 0x184 */
u32 _res4[2]; /* 0x188 */
u32 event_input; /* 0x190 */
u32 _res5[4]; /* 0x194 */
u32 boot_addr; /* 0x1a4 - also known as PRIVATE_REG */
u32 _res6[2]; /* 0x1a8 */
u32 cpu1_power_clamp; /* 0x1b0 */
u32 cpu1_power_off; /* 0x1b4 */
u32 _res7[10]; /* 0x1b8 */
u32 debug0_ctrl; /* 0x1e0 */
u32 debug1_ctrl; /* 0x1e4 */
};
#define GENERAL_CTRL_NO_L1_RESET_CPU(x) (1UL << (x))
#define GENERAL_CTRL_NO_L2_AUTO_RESET (1UL << 4)
#define GENERAL_CTRL_L2_RESET_SET (0UL << 5)
#define GENERAL_CTRL_L2_RESET_CLEAR (1UL << 5)
#define GENERAL_CTRL_CFGSDISABLE (1UL << 8)
#endif /* __ASSEMBLY__ */
#endif /* _SUNXI_CPUCFG_H_ */

View File

@ -0,0 +1,38 @@
/*
* (C) Copyright 2013
* Carl van Schaik <carl@ok-labs.com>
*
* CPU configuration registers for the sun7i (A20).
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _SUNXI_SMP_H_
#define _SUNXI_SMP_H_
#ifndef __ASSEMBLY__
void startup_secondaries(void);
/* Assembly entry point */
extern void secondary_init(void);
#endif /* __ASSEMBLY__ */
#endif /* _SUNXI_SMP_H_ */

View File

@ -352,6 +352,7 @@ Coby_MID8042 arm armv7 sunxi -
Coby_MID9742 arm armv7 sunxi - sunxi sun4i:COBY_MID9742,SPL
Marsboard_A10 arm armv7 sunxi - sunxi sun4i:MARSBOARD_A10,SPL,SUNXI_EMAC,NO_AXP
Marsboard_A20 arm armv7 sunxi - sunxi sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP
Marsboard_A20_debug arm armv7 sunxi - sunxi sun7i:MARSBOARD_A20,SPL,SUNXI_EMAC,NO_AXP,SYS_SECONDARY_ON
Cubieboard arm armv7 sunxi - sunxi sun4i:CUBIEBOARD,SPL,SUNXI_EMAC,STATUSLED=244
Cubieboard_FEL arm armv7 sunxi - sunxi sun4i:CUBIEBOARD,SPL_FEL,SUNXI_EMAC,STATUSLED=244
Cubieboard_512 arm armv7 sunxi - sunxi sun4i:CUBIEBOARD_512,SPL,SUNXI_EMAC,STATUSLED=244

View File

@ -34,6 +34,10 @@
#define CONFIG_SYS_PROMPT "sun7i# "
#define CONFIG_MACH_TYPE 4283
#if defined(CONFIG_SYS_SECONDARY_ON)
#define CONFIG_BOARD_POSTCLK_INIT 1
#endif
/*
* Include common sunxi configuration where most the settings are
*/