xref: /openbmc/u-boot/arch/arm/mach-imx/mx6/mp.c (revision afaea1f5)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2014
4  * Gabriel Huau <contact@huau-gabriel.fr>
5  *
6  * (C) Copyright 2009 Freescale Semiconductor, Inc.
7  */
8 
9 #include <common.h>
10 #include <asm/io.h>
11 #include <linux/errno.h>
12 #include <asm/arch/sys_proto.h>
13 #include <asm/arch/imx-regs.h>
14 
15 #define MAX_CPUS 4
16 static struct src *src = (struct src *)SRC_BASE_ADDR;
17 
18 static uint32_t cpu_reset_mask[MAX_CPUS] = {
19 	0, /* We don't really want to modify the cpu0 */
20 	SRC_SCR_CORE_1_RESET_MASK,
21 	SRC_SCR_CORE_2_RESET_MASK,
22 	SRC_SCR_CORE_3_RESET_MASK
23 };
24 
25 static uint32_t cpu_ctrl_mask[MAX_CPUS] = {
26 	0, /* We don't really want to modify the cpu0 */
27 	SRC_SCR_CORE_1_ENABLE_MASK,
28 	SRC_SCR_CORE_2_ENABLE_MASK,
29 	SRC_SCR_CORE_3_ENABLE_MASK
30 };
31 
32 int cpu_reset(u32 nr)
33 {
34 	/* Software reset of the CPU N */
35 	src->scr |= cpu_reset_mask[nr];
36 	return 0;
37 }
38 
39 int cpu_status(u32 nr)
40 {
41 	printf("core %d => %d\n", nr, !!(src->scr & cpu_ctrl_mask[nr]));
42 	return 0;
43 }
44 
45 int cpu_release(u32 nr, int argc, char *const argv[])
46 {
47 	uint32_t boot_addr;
48 
49 	boot_addr = simple_strtoul(argv[0], NULL, 16);
50 
51 	switch (nr) {
52 	case 1:
53 		src->gpr3 = boot_addr;
54 		break;
55 	case 2:
56 		src->gpr5 = boot_addr;
57 		break;
58 	case 3:
59 		src->gpr7 = boot_addr;
60 		break;
61 	default:
62 		return 1;
63 	}
64 
65 	/* CPU N is ready to start */
66 	src->scr |= cpu_ctrl_mask[nr];
67 
68 	return 0;
69 }
70 
71 int is_core_valid(unsigned int core)
72 {
73 	uint32_t nr_cores = get_nr_cpus();
74 
75 	if (core > nr_cores)
76 		return 0;
77 
78 	return 1;
79 }
80 
81 int cpu_disable(u32 nr)
82 {
83 	/* Disable the CPU N */
84 	src->scr &= ~cpu_ctrl_mask[nr];
85 	return 0;
86 }
87