[U-Boot] [PATCH] mx6: add support of multi-processor command

Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 131 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ 3 files changed, 145 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..a805be8 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> + +int cpu_reset(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg |= SRC_SCR_CORE_1_RESET_MASK; + break; + + case 2: + reg |= SRC_SCR_CORE_2_RESET_MASK; + break; + + case 3: + reg |= SRC_SCR_CORE_3_RESET_MASK; + break; + } + + /* Software reset of the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int cpu_status(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK)); + break; + + case 2: + printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK)); + break; + + case 3: + printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK)); + break; + } + + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + __raw_writel(boot_addr, &src->gpr3); + reg |= SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + __raw_writel(boot_addr, &src->gpr5); + reg |= SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + __raw_writel(boot_addr, &src->gpr7); + reg |= SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* CPU N is ready to start */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int is_core_valid(unsigned int nr) +{ + if (nr < 0 || nr >= CONFIG_NUM_CPUS) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg &= ~SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + reg &= ~SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + reg &= ~SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* Disable the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr;

On Sat, Jun 21, 2014 at 3:29 PM, Gabriel Huau contact@huau-gabriel.fr wrote:
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Please provide a commit log explaining in details the purpose of the "multi-processor" command.

This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 131 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ 3 files changed, 145 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..a805be8 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> + +int cpu_reset(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg |= SRC_SCR_CORE_1_RESET_MASK; + break; + + case 2: + reg |= SRC_SCR_CORE_2_RESET_MASK; + break; + + case 3: + reg |= SRC_SCR_CORE_3_RESET_MASK; + break; + } + + /* Software reset of the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int cpu_status(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK)); + break; + + case 2: + printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK)); + break; + + case 3: + printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK)); + break; + } + + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + __raw_writel(boot_addr, &src->gpr3); + reg |= SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + __raw_writel(boot_addr, &src->gpr5); + reg |= SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + __raw_writel(boot_addr, &src->gpr7); + reg |= SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* CPU N is ready to start */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int is_core_valid(unsigned int nr) +{ + if (nr < 0 || nr >= CONFIG_NUM_CPUS) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg &= ~SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + reg &= ~SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + reg &= ~SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* Disable the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr;

Hello Gabriel,
On 22-06-14 01:55, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
funny..
+int is_core_valid(unsigned int nr) +{
- if (nr < 0 || nr >= CONFIG_NUM_CPUS)
return 0;
- return 1;
+}
I am not sure if u-boot has rules for it, but personally I would prefer not to test values which are obvious unsigned for negativity, since it causes unnecessary noise when compiling u-boot with W=1, W=2.
Regards, Jeroen

Agreed, I'll submit a patch to fix that.
Regards, Gabriel
On 06/22/2014 02:14 AM, Jeroen Hofstee wrote:
Hello Gabriel,
On 22-06-14 01:55, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
funny..
+int is_core_valid(unsigned int nr) +{
- if (nr < 0 || nr >= CONFIG_NUM_CPUS)
return 0;
- return 1;
+}
I am not sure if u-boot has rules for it, but personally I would prefer not to test values which are obvious unsigned for negativity, since it causes unnecessary noise when compiling u-boot with W=1, W=2.
Regards, Jeroen

This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- Changes for v2: - Add a commit log message to explain the purpose of this patch Changes for v3: - Remove unnecessary check for unsigned values when they are negative
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 131 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ 3 files changed, 145 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..8105fcc --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h> + +int cpu_reset(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg |= SRC_SCR_CORE_1_RESET_MASK; + break; + + case 2: + reg |= SRC_SCR_CORE_2_RESET_MASK; + break; + + case 3: + reg |= SRC_SCR_CORE_3_RESET_MASK; + break; + } + + /* Software reset of the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int cpu_status(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK)); + break; + + case 2: + printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK)); + break; + + case 3: + printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK)); + break; + } + + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + __raw_writel(boot_addr, &src->gpr3); + reg |= SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + __raw_writel(boot_addr, &src->gpr5); + reg |= SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + __raw_writel(boot_addr, &src->gpr7); + reg |= SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* CPU N is ready to start */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int is_core_valid(unsigned int nr) +{ + if (nr >= CONFIG_NUM_CPUS) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg &= ~SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + reg &= ~SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + reg &= ~SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* Disable the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr;

Hi Gabriel,
On 22/06/2014 18:56, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 131 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ 3 files changed, 145 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c
Do you have a user of this code ? I do not see it at the mopment.
new file mode 100644 index 0000000..8105fcc --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,131 @@ +/*
- (C) Copyright 2014
- Gabriel Huau contact@huau-gabriel.fr
- (C) Copyright 2009 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h>
+int cpu_reset(int nr) +{
As cpu__ are quite too generic and could conflict, I suggest to use more specific names indicating that you are enabling/disabling a core on the cpu. Something like imx_core_reset() or whatever you choose.
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg |= SRC_SCR_CORE_1_RESET_MASK;
break;
- case 2:
reg |= SRC_SCR_CORE_2_RESET_MASK;
break;
- case 3:
reg |= SRC_SCR_CORE_3_RESET_MASK;
break;
- }
- /* Software reset of the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int cpu_status(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK));
break;
- case 2:
printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK));
break;
- case 3:
printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK));
break;
- }
- return 0;
+}
+int cpu_release(int nr, int argc, char *const argv[]) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- uint32_t boot_addr;
- boot_addr = simple_strtoul(argv[0], NULL, 16);
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
__raw_writel(boot_addr, &src->gpr3);
reg |= SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
__raw_writel(boot_addr, &src->gpr5);
reg |= SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
__raw_writel(boot_addr, &src->gpr7);
reg |= SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* CPU N is ready to start */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int is_core_valid(unsigned int nr) +{
- if (nr >= CONFIG_NUM_CPUS)
And where is defined CONFIG_NUM_CPUS ?
Why do we have to configure it ? The number is related to the running SOC and cannot be changed.
return 0;
- return 1;
+}
+int cpu_disable(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg &= ~SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
reg &= ~SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
reg &= ~SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* Disable the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
/* System Reset Controller (SRC) */ struct src { u32 scr;
Best regards, Stefano Babic

Hi Stefano,
On 06/24/2014 05:50 AM, Stefano Babic wrote:
Hi Gabriel,
On 22/06/2014 18:56, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 131 +++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ 3 files changed, 145 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c
Do you have a user of this code ? I do not see it at the mopment.
I didn't enable the configuration in the board file so it won't be available by default, should I do it? or should we leave the user to add this command in their board file?
new file mode 100644 index 0000000..8105fcc --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,131 @@ +/*
- (C) Copyright 2014
- Gabriel Huau contact@huau-gabriel.fr
- (C) Copyright 2009 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/imx-regs.h>
+int cpu_reset(int nr) +{
As cpu__ are quite too generic and could conflict, I suggest to use more specific names indicating that you are enabling/disabling a core on the cpu. Something like imx_core_reset() or whatever you choose.
The name 'cpu_reset' is not really my choice, when you enable the command MP you have to defines these functions (common/cmd_mp.c), I'm open to any suggestion but anyway we will have to define these function (except if I missed something).
To avoid any conflict, I've defined them in the SoC code (they did the same for PowerPC), so another SoC can define these functions without any conflict.
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg |= SRC_SCR_CORE_1_RESET_MASK;
break;
- case 2:
reg |= SRC_SCR_CORE_2_RESET_MASK;
break;
- case 3:
reg |= SRC_SCR_CORE_3_RESET_MASK;
break;
- }
- /* Software reset of the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int cpu_status(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK));
break;
- case 2:
printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK));
break;
- case 3:
printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK));
break;
- }
- return 0;
+}
+int cpu_release(int nr, int argc, char *const argv[]) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- uint32_t boot_addr;
- boot_addr = simple_strtoul(argv[0], NULL, 16);
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
__raw_writel(boot_addr, &src->gpr3);
reg |= SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
__raw_writel(boot_addr, &src->gpr5);
reg |= SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
__raw_writel(boot_addr, &src->gpr7);
reg |= SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* CPU N is ready to start */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int is_core_valid(unsigned int nr) +{
- if (nr >= CONFIG_NUM_CPUS)
And where is defined CONFIG_NUM_CPUS ?
Why do we have to configure it ? The number is related to the running SOC and cannot be changed.
By default, I didn't enable the common MP for the mx6, but the CONFIG_NUM_CPUS should be defined in the config file of the SoC (Quad => 4, Dual => 2, Solo => 1). I think a better way will be to read directly the SCU registers to get the current CPU configuration of the board, I'll update the patch.
return 0;
- return 1;
+}
+int cpu_disable(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg &= ~SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
reg &= ~SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
reg &= ~SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* Disable the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
- /* System Reset Controller (SRC) */ struct src { u32 scr;
Best regards, Stefano Babic

This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- Changes for v2: - Add a commit log message to explain the purpose of this patch Changes for v3: - Remove unnecessary check for unsigned values when they are negative Changes for v4: - Add CONFIG_MP to the common mx6 configuration - Get the number of CPUs dynamically instead of using a macro
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 134 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 ++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ arch/arm/include/asm/arch-mx6/sys_proto.h | 2 + include/configs/mx6_common.h | 2 + 6 files changed, 158 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index d7285fc..ec08526 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -9,3 +9,4 @@
obj-y := soc.o clock.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..85003d3 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,134 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h> + +int cpu_reset(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg |= SRC_SCR_CORE_1_RESET_MASK; + break; + + case 2: + reg |= SRC_SCR_CORE_2_RESET_MASK; + break; + + case 3: + reg |= SRC_SCR_CORE_3_RESET_MASK; + break; + } + + /* Software reset of the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int cpu_status(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK)); + break; + + case 2: + printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK)); + break; + + case 3: + printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK)); + break; + } + + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + __raw_writel(boot_addr, &src->gpr3); + reg |= SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + __raw_writel(boot_addr, &src->gpr5); + reg |= SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + __raw_writel(boot_addr, &src->gpr7); + reg |= SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* CPU N is ready to start */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int is_core_valid(unsigned int core) +{ + uint32_t nr_cores = get_nr_cpus(); + + if (core > nr_cores) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg &= ~SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + reg &= ~SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + reg &= ~SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* Disable the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 1725279..9a01b7e 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -35,6 +35,12 @@ struct scu_regs { u32 fpga_rev; };
+u32 get_nr_cpus(void) +{ + struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; + return readl(&scu->config) & 3; +} + u32 get_cpu_rev(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 1f19727..3f8c2ee 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -225,6 +225,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 38851a1..b2558e7 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -11,6 +11,8 @@ #include <asm/imx-common/regs-common.h> #include "../arch-imx/cpu.h"
+u32 get_nr_cpus(void); + #define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev) u32 get_cpu_rev(void);
diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index 8a8920f..44489da 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -29,4 +29,6 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif
+#define CONFIG_MP + #endif

Hi Gabriel,
On 25/06/2014 04:32, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 134 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 ++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ arch/arm/include/asm/arch-mx6/sys_proto.h | 2 + include/configs/mx6_common.h | 2 + 6 files changed, 158 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
Your patch breaks some i.MX6 boards:
Configuring for udoo_quad - Board: udoo, Options: IMX_CONFIG=board/udoo/udoo.cfg,MX6Q,DDR_MB=1024 common/board_f.c:45:20: fatal error: asm/mp.h: No such file or directory make[1]: *** [common/board_f.o] Error 1
In fact, board_f.c includes asm/mp.h if CONFIG_MP is set. Can you take a look ? Thanks !
Best regards, Stefano Babic

This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- Changes for v2: - Add a commit log message to explain the purpose of this patch Changes for v3: - Remove unnecessary check for unsigned values when they are negative Changes for v4: - Add CONFIG_MP to the common mx6 configuration - Get the number of CPUs dynamically instead of using a macro Changes for v5: - Rebase on the last update of the tree (conflicts solved) - Add a dummy header to solve build issue regarding the common/board_f.c
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 134 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 ++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + arch/arm/include/asm/mp.h | 11 +++ include/configs/mx6_common.h | 2 + 7 files changed, 168 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c create mode 100644 arch/arm/include/asm/mp.h
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index 6dc9f8e..bf6effc 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -10,3 +10,4 @@ obj-y := soc.o clock.o obj-$(CONFIG_SPL_BUILD) += ddr.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..85003d3 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,134 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h> + +int cpu_reset(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg |= SRC_SCR_CORE_1_RESET_MASK; + break; + + case 2: + reg |= SRC_SCR_CORE_2_RESET_MASK; + break; + + case 3: + reg |= SRC_SCR_CORE_3_RESET_MASK; + break; + } + + /* Software reset of the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int cpu_status(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK)); + break; + + case 2: + printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK)); + break; + + case 3: + printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK)); + break; + } + + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + __raw_writel(boot_addr, &src->gpr3); + reg |= SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + __raw_writel(boot_addr, &src->gpr5); + reg |= SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + __raw_writel(boot_addr, &src->gpr7); + reg |= SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* CPU N is ready to start */ + __raw_writel(reg, &src->scr); + + return 0; +} + +int is_core_valid(unsigned int core) +{ + uint32_t nr_cores = get_nr_cpus(); + + if (core > nr_cores) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + uint32_t reg; + struct src *src = (struct src *)SRC_BASE_ADDR; + + reg = __raw_readl(&src->scr); + + switch (nr) { + case 1: + reg &= ~SRC_SCR_CORE_1_ENABLE_MASK; + break; + + case 2: + reg &= ~SRC_SCR_CORE_2_ENABLE_MASK; + break; + + case 3: + reg &= ~SRC_SCR_CORE_3_ENABLE_MASK; + break; + } + + /* Disable the CPU N */ + __raw_writel(reg, &src->scr); + + return 0; +} diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index f20bdeb..19429b2 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -35,6 +35,12 @@ struct scu_regs { u32 fpga_rev; };
+u32 get_nr_cpus(void) +{ + struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; + return readl(&scu->config) & 3; +} + u32 get_cpu_rev(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index a69a753..a90cbe9 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -227,6 +227,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 42d30f5..7cbc133 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -14,6 +14,7 @@ #define soc_rev() (get_cpu_rev() & 0xFF) #define is_soc_rev(rev) (soc_rev() - rev)
+#define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev) u32 get_cpu_rev(void);
/* returns MXC_CPU_ value */ diff --git a/arch/arm/include/asm/mp.h b/arch/arm/include/asm/mp.h new file mode 100644 index 0000000..8cf8d88 --- /dev/null +++ b/arch/arm/include/asm/mp.h @@ -0,0 +1,11 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_MP_H_ +#define _ASM_MP_H_ + +#endif diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e4a5cc5..135a3f5 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -28,4 +28,6 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif
+#define CONFIG_MP + #endif

Dear Gabriel Huau,
In message 1405204264-10922-1-git-send-email-contact@huau-gabriel.fr you wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Has this patch really to be specific for the quad core version? Can we not also support the dual core version in the same way?
...
+int cpu_reset(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg |= SRC_SCR_CORE_1_RESET_MASK;
break;
- case 2:
reg |= SRC_SCR_CORE_2_RESET_MASK;
break;
- case 3:
reg |= SRC_SCR_CORE_3_RESET_MASK;
break;
- }
I feel this should not be hardwired for 4 cores, and I also think we should avoid using such a switch statement here. All you need is an index into an array.
+int cpu_status(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK));
break;
- case 2:
printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK));
break;
- case 3:
printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK));
break;
- }
Ditto. Such code duplication does not scale. Please rework to avoid the switch.
- switch (nr) {
- case 1:
__raw_writel(boot_addr, &src->gpr3);
reg |= SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
__raw_writel(boot_addr, &src->gpr5);
reg |= SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
__raw_writel(boot_addr, &src->gpr7);
reg |= SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* CPU N is ready to start */
- __raw_writel(reg, &src->scr);
Ditto here.
And can you please explain why you are using __raw_writel() here?
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg &= ~SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
reg &= ~SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
reg &= ~SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* Disable the CPU N */
- __raw_writel(reg, &src->scr);
Again, please avoid the switch.
We have read-modify-write macros which you could use, unless you really have to use the __raw_*() accessors. Why is this needed?
Best regards,
Wolfgang Denk

Hi Wolfgang,
On 07/13/2014 02:58 AM, Wolfgang Denk wrote:
Dear Gabriel Huau,
In message 1405204264-10922-1-git-send-email-contact@huau-gabriel.fr you wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Has this patch really to be specific for the quad core version? Can we not also support the dual core version in the same way?
...
Nope, but it makes sense for only Dual and Quad version. I'll update the commit message to be more specific.
+int cpu_reset(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg |= SRC_SCR_CORE_1_RESET_MASK;
break;
- case 2:
reg |= SRC_SCR_CORE_2_RESET_MASK;
break;
- case 3:
reg |= SRC_SCR_CORE_3_RESET_MASK;
break;
- }
I feel this should not be hardwired for 4 cores, and I also think we should avoid using such a switch statement here. All you need is an index into an array.
Agreed.
+int cpu_status(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK));
break;
- case 2:
printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK));
break;
- case 3:
printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK));
break;
- }
Ditto. Such code duplication does not scale. Please rework to avoid the switch.
- switch (nr) {
- case 1:
__raw_writel(boot_addr, &src->gpr3);
reg |= SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
__raw_writel(boot_addr, &src->gpr5);
reg |= SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
__raw_writel(boot_addr, &src->gpr7);
reg |= SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* CPU N is ready to start */
- __raw_writel(reg, &src->scr);
Ditto here.
And can you please explain why you are using __raw_writel() here?
No particular reason, I'll update with the generic macro.
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg &= ~SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
reg &= ~SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
reg &= ~SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* Disable the CPU N */
- __raw_writel(reg, &src->scr);
Again, please avoid the switch.
We have read-modify-write macros which you could use, unless you really have to use the __raw_*() accessors. Why is this needed?
Best regards,
Wolfgang Denk
I'll send a version 6 with your correction.
Regards, Gabriel

Hi Gabriel,
On 13/07/2014 00:31, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
However, I get several warnings applying your patch:
arch/arm/include/asm/arch/sys_proto.h:17:0: warning: "is_soc_rev" redefined [enabled by default] arch/arm/include/asm/arch/sys_proto.h:15:0: note: this is the location of the previous definition
and:
arch/arm/cpu/armv7/mx6/mp.c:101:2: warning: implicit declaration of function 'get_nr_cpus' [-Wimplicit-function-declaration] In file included from arch/arm/imx-common/cpu.c:15:0:
You muxt fix them.
- Add a dummy header to solve build issue regarding the common/board_f.c
I do not think this is the best solution. An empty file is a file that is not needed.
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 134 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 ++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + arch/arm/include/asm/mp.h | 11 +++ include/configs/mx6_common.h | 2 + 7 files changed, 168 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c create mode 100644 arch/arm/include/asm/mp.h
I have just investigate a bit. The file is included by common/board_f.c but it is, frankly, quite not used. There are several prototype inside it:
void setup_mp(void); void cpu_mp_lmb_reserve(struct lmb *lmb); int is_core_disabled(int nr);
They are not used at all.
u32 determine_mp_bootpg(unsigned int *pagesize);
This is the only one that is used.
Then it makes more sense to drop mp.h from board_f.c and add a prototype for determine_mp_bootpg(). This function is already protected by:
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index 6dc9f8e..bf6effc 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -10,3 +10,4 @@ obj-y := soc.o clock.o obj-$(CONFIG_SPL_BUILD) += ddr.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..85003d3 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,134 @@ +/*
- (C) Copyright 2014
- Gabriel Huau contact@huau-gabriel.fr
- (C) Copyright 2009 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h>
+int cpu_reset(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg |= SRC_SCR_CORE_1_RESET_MASK;
break;
- case 2:
reg |= SRC_SCR_CORE_2_RESET_MASK;
break;
- case 3:
reg |= SRC_SCR_CORE_3_RESET_MASK;
break;
- }
- /* Software reset of the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int cpu_status(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
printf("core 1: %d\n", !!(reg & SRC_SCR_CORE_1_ENABLE_MASK));
break;
- case 2:
printf("core 2: %d\n", !!(reg & SRC_SCR_CORE_2_ENABLE_MASK));
break;
- case 3:
printf("core 3: %d\n", !!(reg & SRC_SCR_CORE_3_ENABLE_MASK));
break;
- }
- return 0;
+}
+int cpu_release(int nr, int argc, char *const argv[]) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- uint32_t boot_addr;
- boot_addr = simple_strtoul(argv[0], NULL, 16);
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
__raw_writel(boot_addr, &src->gpr3);
reg |= SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
__raw_writel(boot_addr, &src->gpr5);
reg |= SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
__raw_writel(boot_addr, &src->gpr7);
reg |= SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* CPU N is ready to start */
- __raw_writel(reg, &src->scr);
- return 0;
+}
+int is_core_valid(unsigned int core) +{
- uint32_t nr_cores = get_nr_cpus();
- if (core > nr_cores)
return 0;
- return 1;
+}
+int cpu_disable(int nr) +{
- uint32_t reg;
- struct src *src = (struct src *)SRC_BASE_ADDR;
- reg = __raw_readl(&src->scr);
- switch (nr) {
- case 1:
reg &= ~SRC_SCR_CORE_1_ENABLE_MASK;
break;
- case 2:
reg &= ~SRC_SCR_CORE_2_ENABLE_MASK;
break;
- case 3:
reg &= ~SRC_SCR_CORE_3_ENABLE_MASK;
break;
- }
- /* Disable the CPU N */
- __raw_writel(reg, &src->scr);
- return 0;
+} diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index f20bdeb..19429b2 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -35,6 +35,12 @@ struct scu_regs { u32 fpga_rev; };
+u32 get_nr_cpus(void) +{
- struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
- return readl(&scu->config) & 3;
+}
u32 get_cpu_rev(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index a69a753..a90cbe9 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -227,6 +227,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
/* System Reset Controller (SRC) */ struct src { u32 scr; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 42d30f5..7cbc133 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -14,6 +14,7 @@ #define soc_rev() (get_cpu_rev() & 0xFF) #define is_soc_rev(rev) (soc_rev() - rev)
+#define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev)
You see, is_soc_rev() is defined twice !
u32 get_cpu_rev(void);
/* returns MXC_CPU_ value */ diff --git a/arch/arm/include/asm/mp.h b/arch/arm/include/asm/mp.h new file mode 100644 index 0000000..8cf8d88 --- /dev/null +++ b/arch/arm/include/asm/mp.h @@ -0,0 +1,11 @@ +/*
- (C) Copyright 2014
- Gabriel Huau contact@huau-gabriel.fr
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _ASM_MP_H_ +#define _ASM_MP_H_
+#endif diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e4a5cc5..135a3f5 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -28,4 +28,6 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif
+#define CONFIG_MP
#endif
Best regards, Stefano Babic

On 07/15/2014 12:49 AM, Stefano Babic wrote:
Hi Gabriel,
On 13/07/2014 00:31, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on the different cores of the i.MX6DQ. For example: we can run Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
However, I get several warnings applying your patch:
arch/arm/include/asm/arch/sys_proto.h:17:0: warning: "is_soc_rev" redefined [enabled by default] arch/arm/include/asm/arch/sys_proto.h:15:0: note: this is the location of the previous definition
and:
arch/arm/cpu/armv7/mx6/mp.c:101:2: warning: implicit declaration of function 'get_nr_cpus' [-Wimplicit-function-declaration] In file included from arch/arm/imx-common/cpu.c:15:0:
You muxt fix them.
My bad during the merge conflict, I'll fix that for the next version of the patch.
- Add a dummy header to solve build issue regarding the common/board_f.c
I do not think this is the best solution. An empty file is a file that is not needed.
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 134 ++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 ++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + arch/arm/include/asm/mp.h | 11 +++ include/configs/mx6_common.h | 2 + 7 files changed, 168 insertions(+) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c create mode 100644 arch/arm/include/asm/mp.h
I have just investigate a bit. The file is included by common/board_f.c but it is, frankly, quite not used. There are several prototype inside it:
void setup_mp(void); void cpu_mp_lmb_reserve(struct lmb *lmb); int is_core_disabled(int nr);
They are not used at all.
u32 determine_mp_bootpg(unsigned int *pagesize);
This is the only one that is used.
Then it makes more sense to drop mp.h from board_f.c and add a prototype for determine_mp_bootpg(). This function is already protected by:
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I agree adding an empty is not necessary the best solution, but I'd rather not to add any cpu/board specific defines in the common/ folder. That's why I think we should keep CONFIG_PM as this is a generic define. If necessary, I can propose another patch to fix it.
Best regards, Stefano Babic

Hi Gabriel,
On 15/07/2014 16:13, gabriel huau wrote:
I have just investigate a bit. The file is included by common/board_f.c but it is, frankly, quite not used. There are several prototype inside it:
void setup_mp(void); void cpu_mp_lmb_reserve(struct lmb *lmb); int is_core_disabled(int nr);
They are not used at all.
u32 determine_mp_bootpg(unsigned int *pagesize);
This is the only one that is used.
Then it makes more sense to drop mp.h from board_f.c and add a prototype for determine_mp_bootpg(). This function is already protected by:
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I agree adding an empty is not necessary the best solution, but I'd rather not to add any cpu/board specific defines in the common/ folder. That's why I think we should keep CONFIG_PM as this is a generic define. If necessary, I can propose another patch to fix it.
I think we are saying the same thing. I agree letting CONFIG_MP, this is not the point. But prototype for determine_mp_bootg() can be moved in a powerpc include file and board_f does not need to include any mp.h
Best regards, Stefano Babic

Agreed, I misunderstood sorry. I'll do the modification for the next version of the patch.
Thanks! Regards, Gabriel
On 07/15/2014 12:35 PM, Stefano Babic wrote:
Hi Gabriel,
On 15/07/2014 16:13, gabriel huau wrote:
I have just investigate a bit. The file is included by common/board_f.c but it is, frankly, quite not used. There are several prototype inside it:
void setup_mp(void); void cpu_mp_lmb_reserve(struct lmb *lmb); int is_core_disabled(int nr);
They are not used at all.
u32 determine_mp_bootpg(unsigned int *pagesize);
This is the only one that is used.
Then it makes more sense to drop mp.h from board_f.c and add a prototype for determine_mp_bootpg(). This function is already protected by:
#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I agree adding an empty is not necessary the best solution, but I'd rather not to add any cpu/board specific defines in the common/ folder. That's why I think we should keep CONFIG_PM as this is a generic define. If necessary, I can propose another patch to fix it.
I think we are saying the same thing. I agree letting CONFIG_MP, this is not the point. But prototype for determine_mp_bootg() can be moved in a powerpc include file and board_f does not need to include any mp.h
Best regards, Stefano Babic

This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr --- Changes for v2: - Add a commit log message to explain the purpose of this patch Changes for v3: - Remove unnecessary check for unsigned values when they are negative Changes for v4: - Add CONFIG_MP to the common mx6 configuration - Get the number of CPUs dynamically instead of using a macro Changes for v5: - Rebase on the last update of the tree (conflicts solved) Changes for v6: - Remove useless switch case - Update board_f to not depend on mp.h unnecessary - Fix build warnings - Update commit message
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 87 +++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 +++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + common/board_f.c | 8 +-- include/configs/mx6_common.h | 2 + 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index 6dc9f8e..bf6effc 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -10,3 +10,4 @@ obj-y := soc.o clock.o obj-$(CONFIG_SPL_BUILD) += ddr.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..9f034d6 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2014 + * Gabriel Huau contact@huau-gabriel.fr + * + * (C) Copyright 2009 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h> + +#define MAX_CPUS 4 +static struct src *src = (struct src *)SRC_BASE_ADDR; + +static uint32_t cpu_reset_mask[MAX_CPUS] = { + 0, /* We don't really want to modify the cpu0 */ + SRC_SCR_CORE_1_RESET_MASK, + SRC_SCR_CORE_2_RESET_MASK, + SRC_SCR_CORE_3_RESET_MASK +}; + +static uint32_t cpu_ctrl_mask[MAX_CPUS] = { + 0, /* We don't really want to modify the cpu0 */ + SRC_SCR_CORE_1_ENABLE_MASK, + SRC_SCR_CORE_2_ENABLE_MASK, + SRC_SCR_CORE_3_ENABLE_MASK +}; + +int cpu_reset(int nr) +{ + /* Software reset of the CPU N */ + src->scr |= cpu_reset_mask[nr]; + return 0; +} + +int cpu_status(int nr) +{ + printf("core %d => %d\n", nr, !!(src->scr & cpu_ctrl_mask[nr])); + return 0; +} + +int cpu_release(int nr, int argc, char *const argv[]) +{ + uint32_t boot_addr; + + boot_addr = simple_strtoul(argv[0], NULL, 16); + + switch (nr) { + case 1: + src->gpr3 = boot_addr; + break; + case 2: + src->gpr5 = boot_addr; + break; + case 3: + src->gpr7 = boot_addr; + break; + default: + return 1; + } + + /* CPU N is ready to start */ + src->scr |= cpu_ctrl_mask[nr]; + + return 0; +} + +int is_core_valid(unsigned int core) +{ + uint32_t nr_cores = get_nr_cpus(); + + if (core > nr_cores) + return 0; + + return 1; +} + +int cpu_disable(int nr) +{ + /* Disable the CPU N */ + src->scr &= ~cpu_ctrl_mask[nr]; + return 0; +} diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index f20bdeb..19429b2 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -35,6 +35,12 @@ struct scu_regs { u32 fpga_rev; };
+u32 get_nr_cpus(void) +{ + struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; + return readl(&scu->config) & 3; +} + u32 get_cpu_rev(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index a69a753..a90cbe9 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -227,6 +227,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET) + /* System Reset Controller (SRC) */ struct src { u32 scr; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 42d30f5..306d699 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -14,6 +14,7 @@ #define soc_rev() (get_cpu_rev() & 0xFF) #define is_soc_rev(rev) (soc_rev() - rev)
+u32 get_nr_cpus(void); u32 get_cpu_rev(void);
/* returns MXC_CPU_ value */ diff --git a/common/board_f.c b/common/board_f.c index 6203d85..e1dbdf3 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core * boot code is reserved and not used by any part of u-boot diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e4a5cc5..135a3f5 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -28,4 +28,6 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif
+#define CONFIG_MP + #endif

Hi Gabriel,
On 26/07/2014 20:35, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
Changes for v6:
- Remove useless switch case
- Update board_f to not depend on mp.h unnecessary
- Fix build warnings
- Update commit message
arch/arm/cpu/armv7/mx6/Makefile | 1 + arch/arm/cpu/armv7/mx6/mp.c | 87 +++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/mx6/soc.c | 6 +++ arch/arm/include/asm/arch-mx6/imx-regs.h | 13 +++++ arch/arm/include/asm/arch-mx6/sys_proto.h | 1 + common/board_f.c | 8 +-- include/configs/mx6_common.h | 2 + 7 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 arch/arm/cpu/armv7/mx6/mp.c
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile index 6dc9f8e..bf6effc 100644 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ b/arch/arm/cpu/armv7/mx6/Makefile @@ -10,3 +10,4 @@ obj-y := soc.o clock.o obj-$(CONFIG_SPL_BUILD) += ddr.o obj-$(CONFIG_SECURE_BOOT) += hab.o +obj-$(CONFIG_MP) += mp.o diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c new file mode 100644 index 0000000..9f034d6 --- /dev/null +++ b/arch/arm/cpu/armv7/mx6/mp.c @@ -0,0 +1,87 @@ +/*
- (C) Copyright 2014
- Gabriel Huau contact@huau-gabriel.fr
- (C) Copyright 2009 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/errno.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/imx-regs.h>
+#define MAX_CPUS 4 +static struct src *src = (struct src *)SRC_BASE_ADDR;
+static uint32_t cpu_reset_mask[MAX_CPUS] = {
- 0, /* We don't really want to modify the cpu0 */
- SRC_SCR_CORE_1_RESET_MASK,
- SRC_SCR_CORE_2_RESET_MASK,
- SRC_SCR_CORE_3_RESET_MASK
+};
+static uint32_t cpu_ctrl_mask[MAX_CPUS] = {
- 0, /* We don't really want to modify the cpu0 */
- SRC_SCR_CORE_1_ENABLE_MASK,
- SRC_SCR_CORE_2_ENABLE_MASK,
- SRC_SCR_CORE_3_ENABLE_MASK
+};
+int cpu_reset(int nr) +{
- /* Software reset of the CPU N */
- src->scr |= cpu_reset_mask[nr];
- return 0;
+}
+int cpu_status(int nr) +{
- printf("core %d => %d\n", nr, !!(src->scr & cpu_ctrl_mask[nr]));
- return 0;
+}
+int cpu_release(int nr, int argc, char *const argv[]) +{
- uint32_t boot_addr;
- boot_addr = simple_strtoul(argv[0], NULL, 16);
- switch (nr) {
- case 1:
src->gpr3 = boot_addr;
break;
- case 2:
src->gpr5 = boot_addr;
break;
- case 3:
src->gpr7 = boot_addr;
break;
- default:
return 1;
- }
- /* CPU N is ready to start */
- src->scr |= cpu_ctrl_mask[nr];
- return 0;
+}
+int is_core_valid(unsigned int core) +{
- uint32_t nr_cores = get_nr_cpus();
- if (core > nr_cores)
return 0;
- return 1;
+}
+int cpu_disable(int nr) +{
- /* Disable the CPU N */
- src->scr &= ~cpu_ctrl_mask[nr];
- return 0;
+} diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index f20bdeb..19429b2 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -35,6 +35,12 @@ struct scu_regs { u32 fpga_rev; };
+u32 get_nr_cpus(void) +{
- struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
- return readl(&scu->config) & 3;
+}
u32 get_cpu_rev(void) { struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index a69a753..a90cbe9 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -227,6 +227,19 @@
extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+#define SRC_SCR_CORE_1_RESET_OFFSET 14 +#define SRC_SCR_CORE_1_RESET_MASK (1<<SRC_SCR_CORE_1_RESET_OFFSET) +#define SRC_SCR_CORE_2_RESET_OFFSET 15 +#define SRC_SCR_CORE_2_RESET_MASK (1<<SRC_SCR_CORE_2_RESET_OFFSET) +#define SRC_SCR_CORE_3_RESET_OFFSET 16 +#define SRC_SCR_CORE_3_RESET_MASK (1<<SRC_SCR_CORE_3_RESET_OFFSET) +#define SRC_SCR_CORE_1_ENABLE_OFFSET 22 +#define SRC_SCR_CORE_1_ENABLE_MASK (1<<SRC_SCR_CORE_1_ENABLE_OFFSET) +#define SRC_SCR_CORE_2_ENABLE_OFFSET 23 +#define SRC_SCR_CORE_2_ENABLE_MASK (1<<SRC_SCR_CORE_2_ENABLE_OFFSET) +#define SRC_SCR_CORE_3_ENABLE_OFFSET 24 +#define SRC_SCR_CORE_3_ENABLE_MASK (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
/* System Reset Controller (SRC) */ struct src { u32 scr; diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index 42d30f5..306d699 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -14,6 +14,7 @@ #define soc_rev() (get_cpu_rev() & 0xFF) #define is_soc_rev(rev) (soc_rev() - rev)
+u32 get_nr_cpus(void); u32 get_cpu_rev(void);
/* returns MXC_CPU_ value */ diff --git a/common/board_f.c b/common/board_f.c index 6203d85..e1dbdf3 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core * boot code is reserved and not used by any part of u-boot diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e4a5cc5..135a3f5 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -28,4 +28,6 @@ #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif
+#define CONFIG_MP
#endif
Fine with me. If there are not further comments, I will merge it soon.
Acked-by: Stefano Babic sbabic@denx.de
Best regards, Stefano Babic

On 07/28/2014 08:15 AM, Stefano Babic wrote:
Hi Gabriel,
On 26/07/2014 20:35, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
Changes for v6:
- Remove useless switch case
- Update board_f to not depend on mp.h unnecessary
- Fix build warnings
- Update commit message
<snip>
--- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I didn't notice this patch until it got merged. Why dropping CONFIG_MP here? This change breaks these boards
MPC8536DS MPC8536DS_36BIT MPC8536DS_SDCARD MPC8536DS_SPIFLASH qemu-ppce500
York

Hi York,
On 09/03/2014 11:00 AM, York Sun wrote:
On 07/28/2014 08:15 AM, Stefano Babic wrote:
Hi Gabriel,
On 26/07/2014 20:35, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
Changes for v6:
- Remove useless switch case
- Update board_f to not depend on mp.h unnecessary
- Fix build warnings
- Update commit message
<snip>
--- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I didn't notice this patch until it got merged. Why dropping CONFIG_MP here? This change breaks these boards
MPC8536DS MPC8536DS_36BIT MPC8536DS_SDCARD MPC8536DS_SPIFLASH qemu-ppce500
York
Sorry, I didn't see the break for these boards. 'asm/mp.h' is used only for the powerpc board and using CONFIG_MP force the other architecture (or board) to create an empty header. As this header was here to use only specific features (not generic), I removed it and put the include guards only for the boards needed.
Can't we add these boards to the board_f.c?
Regards, Gabriel

On 09/03/2014 11:26 AM, Gabriel Huau wrote:
Hi York,
On 09/03/2014 11:00 AM, York Sun wrote:
On 07/28/2014 08:15 AM, Stefano Babic wrote:
Hi Gabriel,
On 26/07/2014 20:35, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
Changes for v6:
- Remove useless switch case
- Update board_f to not depend on mp.h unnecessary
- Fix build warnings
- Update commit message
<snip>
--- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I didn't notice this patch until it got merged. Why dropping CONFIG_MP here? This change breaks these boards
MPC8536DS MPC8536DS_36BIT MPC8536DS_SDCARD MPC8536DS_SPIFLASH qemu-ppce500
York
Sorry, I didn't see the break for these boards. 'asm/mp.h' is used only for the powerpc board and using CONFIG_MP force the other architecture (or board) to create an empty header. As this header was here to use only specific features (not generic), I removed it and put the include guards only for the boards needed.
Can't we add these boards to the board_f.c?
I don't mind to change the guard for asm/mp.h. But you shouldn't remove the guard for the function call. Not all powerpc SoCs support SMP. You could use
+#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
York

On 09/03/2014 11:36 AM, York Sun wrote:
On 09/03/2014 11:26 AM, Gabriel Huau wrote:
Hi York,
On 09/03/2014 11:00 AM, York Sun wrote:
On 07/28/2014 08:15 AM, Stefano Babic wrote:
Hi Gabriel,
On 26/07/2014 20:35, Gabriel Huau wrote:
This allows u-boot to load different OS or Bare Metal application on different cores of the i.MX6 SoC. For example: running Android on cpu0 and a RT OS like QNX/FreeRTOS on cpu1.
Signed-off-by: Gabriel Huau contact@huau-gabriel.fr
Changes for v2:
- Add a commit log message to explain the purpose of this patch
Changes for v3:
- Remove unnecessary check for unsigned values when they are negative
Changes for v4:
- Add CONFIG_MP to the common mx6 configuration
- Get the number of CPUs dynamically instead of using a macro
Changes for v5:
- Rebase on the last update of the tree (conflicts solved)
Changes for v6:
- Remove useless switch case
- Update board_f to not depend on mp.h unnecessary
- Fix build warnings
- Update commit message
<snip>
--- a/common/board_f.c +++ b/common/board_f.c @@ -34,6 +34,9 @@ #ifdef CONFIG_MPC5xxx #include <mpc5xxx.h> #endif +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
#include <os.h> #include <post.h> @@ -43,9 +46,6 @@ #include <watchdog.h> #include <asm/errno.h> #include <asm/io.h> -#ifdef CONFIG_MP -#include <asm/mp.h> -#endif #include <asm/sections.h> #ifdef CONFIG_X86 #include <asm/init_helpers.h> @@ -381,7 +381,7 @@ static int setup_dest_addr(void) gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); -#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#if (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
I didn't notice this patch until it got merged. Why dropping CONFIG_MP here? This change breaks these boards
MPC8536DS MPC8536DS_36BIT MPC8536DS_SDCARD MPC8536DS_SPIFLASH qemu-ppce500
York
Sorry, I didn't see the break for these boards. 'asm/mp.h' is used only for the powerpc board and using CONFIG_MP force the other architecture (or board) to create an empty header. As this header was here to use only specific features (not generic), I removed it and put the include guards only for the boards needed.
Can't we add these boards to the board_f.c?
I don't mind to change the guard for asm/mp.h. But you shouldn't remove the guard for the function call. Not all powerpc SoCs support SMP. You could use
+#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) +#include <asm/mp.h> +#endif
York
Oh! I see what you mean, my bad, sorry. I'll propose the fix as soon as possible to revert the modification on the include guard and modify the one for the asm/mp.h
Regards, Gabriel
participants (7)
-
Fabio Estevam
-
Gabriel Huau
-
gabriel huau
-
Jeroen Hofstee
-
Stefano Babic
-
Wolfgang Denk
-
York Sun