mirror of
https://github.com/linux-sunxi/u-boot-sunxi.git
synced 2024-02-12 11:16:03 +08:00
Startup secondary core on sun7i. Creates a new backwards compatible SMP boot protocol.
This commit is contained in:

committed by
Henrik Nordstrom

parent
d07bcb82d9
commit
a3cca42190
@ -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
|
||||
|
36
arch/arm/cpu/armv7/sunxi/postclk_init.c
Normal file
36
arch/arm/cpu/armv7/sunxi/postclk_init.c
Normal 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;
|
||||
}
|
48
arch/arm/cpu/armv7/sunxi/secondary_init.S
Normal file
48
arch/arm/cpu/armv7/sunxi/secondary_init.S
Normal 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)
|
||||
|
96
arch/arm/cpu/armv7/sunxi/smp.c
Normal file
96
arch/arm/cpu/armv7/sunxi/smp.c
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
71
arch/arm/include/asm/arch-sunxi/cpucfg.h
Normal file
71
arch/arm/include/asm/arch-sunxi/cpucfg.h
Normal 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_ */
|
38
arch/arm/include/asm/arch-sunxi/smp.h
Normal file
38
arch/arm/include/asm/arch-sunxi/smp.h
Normal 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_ */
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user