[PATCH] ARM: exynos4: fix secondary CPU boot

Kyungmin Park kmpark at infradead.org
Wed Jun 29 01:52:37 EDT 2011


It's first step to handle the EVT.

Acked-by: Kyungmin Park <kyungmin.park at samsung.com>


> Jazz is not dead. It just smells funny...
> From a24392183d396fab790557b0efb35e840c9e8a81 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <marc.zyngier at arm.com>
> Date: Fri, 20 May 2011 14:38:25 +0100
> Subject: [PATCH] ARM: exynos4: fix secondary CPU boot on early SoC revisions
>
> It appears that the system-wide flags register that used to be at
> 0x02025000 on the first revision of Exynos4 has moved to 0x02020000.
>
> The kernel has been updated accordingly, but this unfortunately leaves
> early boards without SMP support (the secondary CPU spins endlessly
> in BL0 waiting for an address to be written at that memory location).
>
> Solve the problem by providing an s3c_get_chip_id() function, common
> to all s3c/s5p implementations, and test the result on the secondary boot
> path.
>
> Revision table, as provided by Kyungmin Park <kmpark at infradead.org>:
> 0x4320 0200 EVT0
> 0x4321 0210 EVT1
> 0x4321 0211 EVT2
>
> The last 8 bits can be overrided by efuses, so only bits [16:19] are
> used to identify the revision.
>
> Tested on a vintage SMDK-v310.
>
> Cc: Kukjin Kim <kgene.kim at samsung.com>
> Cc: Kyungmin Park <kmpark at infradead.org>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/mach-exynos4/include/mach/map.h |    1 +
>  arch/arm/mach-exynos4/platsmp.c          |   22 +++++++++++++++++++++-
>  arch/arm/plat-samsung/include/plat/cpu.h |    2 ++
>  arch/arm/plat-samsung/init.c             |    8 ++++++++
>  4 files changed, 32 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
> index 57d8074..da08f5c 100644
> --- a/arch/arm/mach-exynos4/include/mach/map.h
> +++ b/arch/arm/mach-exynos4/include/mach/map.h
> @@ -24,6 +24,7 @@
>  #include <plat/map-s5p.h>
>
>  #define EXYNOS4_PA_SYSRAM              0x02020000
> +#define EXYNOS4_PA_SYSRAM_EVT0         0x02025000
>
>  #define EXYNOS4_PA_FIMC0               0x11800000
>  #define EXYNOS4_PA_FIMC1               0x11810000
> diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
> index c5e65a0..086d1e3 100644
> --- a/arch/arm/mach-exynos4/platsmp.c
> +++ b/arch/arm/mach-exynos4/platsmp.c
> @@ -26,6 +26,8 @@
>  #include <asm/smp_scu.h>
>  #include <asm/unified.h>
>
> +#include <plat/cpu.h>
> +
>  #include <mach/hardware.h>
>  #include <mach/regs-clock.h>
>
> @@ -170,6 +172,24 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
>         * system-wide flags register. The boot monitor waits
>         * until it receives a soft interrupt, and then the
>         * secondary CPU branches to this address.
> +        *
> +        * EVT0 has the system-wide flags register at a different
> +        * address, hence the following hackery...
>         */
> -       __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)), S5P_VA_SYSRAM);
> +       if (s3c_get_chip_id() & 0xF0000UL)
> +               __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
> +                            S5P_VA_SYSRAM);
> +       else {
> +               void __iomem *sysram_evt0;
> +
> +               sysram_evt0 = ioremap(EXYNOS4_PA_SYSRAM_EVT0, SZ_4K);
> +               if (!sysram_evt0) {
> +                       pr_err("Unable to remap EXYNOS4_PA_SYSRAM_EVT0\n");
> +                       return;
> +               }
> +               __raw_writel(BSYM(virt_to_phys(exynos4_secondary_startup)),
> +                            sysram_evt0);
> +               iounmap(sysram_evt0);
> +       }
> +
>  }
> diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
> index c0a5741..41573cc 100644
> --- a/arch/arm/plat-samsung/include/plat/cpu.h
> +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> @@ -44,6 +44,8 @@ struct cpu_table {
>  extern void s3c_init_cpu(unsigned long idcode,
>                         struct cpu_table *cpus, unsigned int cputab_size);
>
> +extern unsigned long s3c_get_chip_id(void);
> +
>  /* core initialisation functions */
>
>  extern void s3c24xx_init_irq(void);
> diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
> index 79d10fc..320b88f 100644
> --- a/arch/arm/plat-samsung/init.c
> +++ b/arch/arm/plat-samsung/init.c
> @@ -30,6 +30,7 @@
>  #include <plat/regs-serial.h>
>
>  static struct cpu_table *cpu;
> +static unsigned long s3c_chip_id;
>
>  static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
>                                                struct cpu_table *tab,
> @@ -60,6 +61,8 @@ void __init s3c_init_cpu(unsigned long idcode,
>                panic("Unsupported Samsung CPU");
>        }
>
> +       s3c_chip_id = idcode;
> +
>        cpu->map_io();
>  }
>
> @@ -140,6 +143,11 @@ void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
>                (cpu->init_uarts)(cfg, no);
>  }
>
> +unsigned long s3c_get_chip_id(void)
> +{
> +       return s3c_chip_id;
> +}
> +
>  static int __init s3c_arch_init(void)
>  {
>        int ret;
> --
> 1.7.0.4
>
>



More information about the linux-arm-kernel mailing list