mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-14 21:10:27 +01:00
ipq40x: Added multicore support
-Device IO commands are not supported -CPU down is supported by waiting in loop -Need reboot to execute bootipq command Change-Id: Id10eef0c8e5feb636716461c58ba1640dfe46658 Signed-off-by: Santan Kumar <santank@codeaurora.org>
This commit is contained in:
parent
8d9a453c47
commit
b7af9b06d2
4 changed files with 181 additions and 2 deletions
|
|
@ -13,9 +13,61 @@
|
|||
#include <asm/system.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
ENTRY(ak_secondary_cpu_reinit)
|
||||
ENTRY(dk_secondary_cpu_reinit)
|
||||
mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
|
||||
and r1, r0, #0xf /* return CPU ID in cluster */
|
||||
sub r0, r1, #1
|
||||
/* Now r1 has the cpu number,
|
||||
* this will serve as index to "struct cpu_entry_arg"
|
||||
* struct cpu_entry_arg {
|
||||
* void *stack_ptr; +0 1c 38 54
|
||||
* volatile void *gd_ptr; +4 20 3c
|
||||
* void *arg_ptr; +8 24 40
|
||||
* int cpu_up; +0xc 28 44
|
||||
* int cmd_complete; +0x10 2c 48
|
||||
* int cmd_result; +0x14 30 4c
|
||||
* void *stack_top_ptr; +0x18 34 50
|
||||
* +0x1c (next entry in core[])
|
||||
* };
|
||||
*/
|
||||
ldr r4, =globl_core_array
|
||||
mov r3, #0x1c
|
||||
mul r2, r0, r3
|
||||
ldr r0, [r4]
|
||||
add r0, r0, r2
|
||||
/* For us r0 has the arg structure pointer
|
||||
struct cpu_entry_arg {
|
||||
void *stack_ptr;
|
||||
void *gd_ptr;
|
||||
void *arg_ptr;
|
||||
int cpu_up;
|
||||
int cmd_complete;
|
||||
int cmd_result;
|
||||
};
|
||||
*/
|
||||
ldr sp, [r0] /* stack_ptr */
|
||||
bic sp, sp, #7 /* 8-byte alignment required for stack */
|
||||
/* gd address is always in r9, but if u-boot changes Tomorrow,
|
||||
* we have to change here. Note :- --> ARM: use r9 for gd
|
||||
*/
|
||||
ldr r9, [r0, #0x4]
|
||||
/* store success in cpu_up */
|
||||
mov r3, #1
|
||||
str r3, [r0, #0xc]
|
||||
add r1, r0, #0x10
|
||||
add r2, r0, #0x14
|
||||
ldr r0, [r0, #0x8]
|
||||
bl secondary_core_entry
|
||||
self_reloop:
|
||||
b self_reloop
|
||||
ENDPROC(ak_secondary_cpu_reinit)
|
||||
ENDPROC(dk_secondary_cpu_reinit)
|
||||
|
||||
ENTRY(dk_secondary_cpu_init)
|
||||
ENTRY(ak_secondary_cpu_init)
|
||||
mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
|
||||
and r1, r0, #0xf /* return CPU ID in cluster */
|
||||
and r1, r0, #0xf /* return CPU ID in cluster */
|
||||
sub r0, r1, #1
|
||||
/* Now r1 has the cpu number,
|
||||
* this will serve as index to "struct cpu_entry_arg"
|
||||
|
|
@ -93,6 +145,7 @@ self_loop:
|
|||
b self_loop
|
||||
ENDPROC(secondary_cpu_init)
|
||||
ENDPROC(ak_secondary_cpu_init)
|
||||
ENDPROC(dk_secondary_cpu_init)
|
||||
|
||||
ENTRY(send_event)
|
||||
dsb
|
||||
|
|
@ -107,6 +160,12 @@ ENTRY(wait_event)
|
|||
bx r0
|
||||
ENDPROC(wait_event)
|
||||
|
||||
ENTRY(get_cpu_id)
|
||||
mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
|
||||
and r0, r0, #0xf /* return CPU ID in cluster */
|
||||
bx lr
|
||||
ENDPROC(get_cpu_id)
|
||||
|
||||
.globl globl_core_array
|
||||
globl_core_array:
|
||||
.word 0
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
#define TCSR_USB_HSPHY_DEVICE_MODE 0x00C700E70
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define CPU0_APCS_SAW2_VCTL 0x0b089014
|
||||
#define CPU0_APCS_CPU_PWR_CTL 0x0b088004
|
||||
|
||||
#define CPU_APCS_SAW2_VCTL(cpuid) (CPU0_APCS_SAW2_VCTL + (cpuid * 0x10000))
|
||||
#define CPU_APCS_CPU_PWR_CTL(cpuid) (CPU0_APCS_CPU_PWR_CTL + (cpuid * 0x10000))
|
||||
|
||||
#ifndef CONFIG_SDHCI_SUPPORT
|
||||
qca_mmc mmc_host;
|
||||
#else
|
||||
|
|
@ -508,5 +514,112 @@ unsigned int get_dts_machid(unsigned int machid)
|
|||
*/
|
||||
int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, bool gpt_flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern void dk_secondary_cpu_init(void);
|
||||
extern void dk_secondary_cpu_reinit(void);
|
||||
/*
|
||||
* Set the cold/warm boot address for one of the CPU cores.
|
||||
*/
|
||||
int scm_set_boot_addr(bool enable_sec_core)
|
||||
{
|
||||
int ret;
|
||||
struct {
|
||||
unsigned int flags;
|
||||
unsigned long addr;
|
||||
} cmd;
|
||||
|
||||
if (!enable_sec_core)
|
||||
return -1;
|
||||
|
||||
cmd.addr = (unsigned long)dk_secondary_cpu_init;
|
||||
cmd.flags = 0xff;
|
||||
|
||||
ret = scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
|
||||
&cmd, sizeof(cmd), NULL, 0);
|
||||
if (ret) {
|
||||
printf("--- %s: scm_call failed ret = %d\n", __func__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_secondary_core_off(unsigned int cpuid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secondary_core_already_reset[NR_CPUS];
|
||||
static int scm_boot_addr_already_set;
|
||||
extern int get_cpu_id(void);
|
||||
static volatile int core_var;
|
||||
|
||||
volatile void bring_secondary_core_down(unsigned int state)
|
||||
{
|
||||
int current_cpu_id;
|
||||
|
||||
current_cpu_id = (1 << get_cpu_id());
|
||||
core_var &= (~current_cpu_id);
|
||||
while (!(core_var & current_cpu_id)) {
|
||||
cp_delay();
|
||||
}
|
||||
dk_secondary_cpu_reinit();
|
||||
}
|
||||
|
||||
static int kpssv1_release_secondary(unsigned int cpuid)
|
||||
{
|
||||
dcache_enable();
|
||||
|
||||
writel(0xa4, CPU_APCS_SAW2_VCTL(cpuid));
|
||||
barrier();
|
||||
udelay(512);
|
||||
|
||||
writel(0x109, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
writel(0x101, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
barrier();
|
||||
udelay(1);
|
||||
|
||||
writel(0x121, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
barrier();
|
||||
udelay(2);
|
||||
|
||||
writel(0x120, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
barrier();
|
||||
udelay(2);
|
||||
|
||||
writel(0x100, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
barrier();
|
||||
udelay(100);
|
||||
|
||||
writel(0x180, CPU_APCS_CPU_PWR_CTL(cpuid));
|
||||
barrier();
|
||||
|
||||
dcache_disable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!secondary_core_already_reset[cpuid]) {
|
||||
if (!scm_boot_addr_already_set) {
|
||||
err = scm_set_boot_addr(true);
|
||||
core_var = 0;
|
||||
if (!err) {
|
||||
scm_boot_addr_already_set = 1;
|
||||
kpssv1_release_secondary(cpuid);
|
||||
secondary_core_already_reset[cpuid] = 1;
|
||||
} else
|
||||
return err;
|
||||
} else {
|
||||
kpssv1_release_secondary(cpuid);
|
||||
secondary_core_already_reset[cpuid] = 1;
|
||||
}
|
||||
} else {
|
||||
core_var |= (1 << cpuid);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -924,6 +924,7 @@ int ipq_get_tz_version(char *version_name, int buf_size)
|
|||
|
||||
void forever(void) { while (1); }
|
||||
extern void ak_secondary_cpu_init(void);
|
||||
extern void ak_secondary_cpu_reinit(void);
|
||||
extern void send_event(void);
|
||||
/*
|
||||
* Set the cold/warm boot address for one of the CPU cores.
|
||||
|
|
@ -1001,7 +1002,7 @@ extern void wait_event(void (*)(void));
|
|||
|
||||
void bring_secondary_core_down(unsigned int state)
|
||||
{
|
||||
wait_event(ak_secondary_cpu_init);
|
||||
wait_event(ak_secondary_cpu_reinit);
|
||||
}
|
||||
|
||||
static int krait_release_secondary(void)
|
||||
|
|
|
|||
|
|
@ -277,6 +277,12 @@ typedef struct {
|
|||
|
||||
#define CONFIG_LIB_UUID
|
||||
|
||||
#define CONFIG_SMP_CMD_SUPPORT
|
||||
|
||||
#ifdef CONFIG_SMP_CMD_SUPPORT
|
||||
#define NR_CPUS 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CRASH DUMP ENABLE
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue