Re: [PATCH] Samsung SoCs: CPU detection support (v4)

From: Ben Dooks
Date: Tue Mar 30 2010 - 21:04:44 EST


On Wed, Mar 24, 2010 at 04:09:43PM +0900, Kyungmin Park wrote:
> Store the CPU ID to cpu_id variable and use it to detect CPU
>
> On S3C64XX, Some pheripherals such as OneNAND have different configuration
> and handle it differently to do this it needs to detect CPU ID.

Just do it like everything else on these platfroms do and use
a rename-able platform device. I do not like the cpu_is macros, it
makes it harder to deal with autoloading modules.

It isn't as if there are plenty of drivers in the s3c/s5p series already
doing this.

> Also S5PC1XX is supported.
>
> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
> ---
> diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
> index d316b4a..5fd5e1b 100644
> --- a/arch/arm/plat-samsung/include/plat/cpu.h
> +++ b/arch/arm/plat-samsung/include/plat/cpu.h
> @@ -15,6 +15,8 @@
> #ifndef __SAMSUNG_PLAT_CPU_H
> #define __SAMSUNG_PLAT_CPU_H
>
> +#include <plat/cpuid.h>
> +
> #define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
>
> #ifndef MHZ
> diff --git a/arch/arm/plat-samsung/include/plat/cpuid.h b/arch/arm/plat-samsung/include/plat/cpuid.h
> new file mode 100644
> index 0000000..bd7162c
> --- /dev/null
> +++ b/arch/arm/plat-samsung/include/plat/cpuid.h
> @@ -0,0 +1,199 @@
> +/*
> + * arch/arm/plat-samsung/include/mach/cpuid.h
> + *
> + * Samsung cpu type detection
> + *
> + * Copyright (C) 2008-2010 Samsung Electronics
> + * Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
> + *
> + * Derived from OMAP cpu.h
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#ifndef __ASM_ARCH_SAMSUNG_CPU_H
> +#define __ASM_ARCH_SAMSUNG_CPU_H
> +
> +extern unsigned long samsung_cpu_id(void);
> +
> +/*
> + * cpu_is_s3c24xx(): True for s3c2400, s3c2410, s3c2440 and so on
> + * cpu_is_s3c241x(): True fro s3c2410, s3c2412
> + * cpu_is_s3c244x(): True fro s3c2440, s3c2442, s3c2443
> + * cpu_is_s3c64xx(): True for s3c6400, s3c6410
> + * cpu_is_s5pc1xx(): True for s5pc100, s5pc110
> + * cpu_is_s5p64xx(): True for s5p6442
> + */
> +#define GET_SAMSUNG_CLASS ((samsung_cpu_id() >> 24) & 0xff)
> +
> +#define IS_SAMSUNG_CLASS(class, id) \
> +static inline int is_##class (void) \
> +{ \
> + return (GET_SAMSUNG_CLASS == (id)) ? 1 : 0; \
> +}
> +
> +#define GET_SAMSUNG_SUBCLASS ((samsung_cpu_id() >> 20) & 0xfff)
> +
> +#define IS_SAMSUNG_SUBCLASS(subclass, id) \
> +static inline int is_##subclass (void) \
> +{ \
> + return (GET_SAMSUNG_SUBCLASS == (id)) ? 1 : 0; \
> +}
> +
> +IS_SAMSUNG_CLASS(s3c24xx, 0x24)
> +IS_SAMSUNG_CLASS(s3c64xx, 0x64)
> +IS_SAMSUNG_CLASS(s5pc1xx, 0xc1)
> +
> +IS_SAMSUNG_SUBCLASS(s3c241x, 0x241)
> +IS_SAMSUNG_SUBCLASS(s3c244x, 0x244)
> +IS_SAMSUNG_SUBCLASS(s5p64xx, 0x644)
> +
> +#define cpu_is_s3c24xx() 0
> +#define cpu_is_s3c241x() 0
> +#define cpu_is_s3c244x() 0
> +#define cpu_is_s3c64xx() 0
> +#define cpu_is_s5pc1xx() 0
> +#define cpu_is_s5p64xx() 0
> +
> +#if defined(CONFIG_ARCH_S3C2410)
> +# undef cpu_is_s3c24xx
> +# undef cpu_is_s3c241x
> +# undef cpu_is_s3c244x
> +# define cpu_is_s3c24xx() is_s3c24xx()
> +# define cpu_is_s3c241x() is_s3c241x()
> +# define cpu_is_s3c244x() is_s3c244x()
> +#endif
> +
> +#if defined(CONFIG_ARCH_S3C64XX)
> +# undef cpu_is_s3c64xx
> +# define cpu_is_s3c64xx() is_s3c64xx()
> +#endif
> +
> +#if defined(CONFIG_ARCH_S5PC1XX) || defined(CONFIG_ARCH_S5PC11X)
> +# undef cpu_is_s5pc1xx
> +# define cpu_is_s5pc1xx() is_s5pc1xx()
> +#endif
> +
> +#if defined(CONFIG_ARCH_S5P64XX)
> +# undef cpu_is_s5p64xx
> +# define cpu_is_s5p64xx() is_s5p64xx()
> +#endif
> +
> +/*
> + * Macros to detect individual cpu types.
> + * cpu_is_s3c2410(): True for s3c2410
> + * cpu_is_s3c2440(): True for s3c2440
> + * cpu_is_s3c6400(): True for s3c6400
> + * cpu_is_s3c6410(): True for s3c6410
> + * cpu_is_s5pc100(): True for s5pc100
> + * cpu_is_s5pc110(): True for s5pc110
> + * cpu_is_s5p6442(): True for s5p6442
> + *
> + * Exception:
> + * Store Revision A to 1
> + * s3c2410a -> s3c2411
> + * s3c2440a -> s3c2441
> + */
> +
> +#define GET_SAMSUNG_TYPE ((samsung_cpu_id() >> 16) & 0xffff)
> +
> +#define IS_SAMSUNG_TYPE(type, id) \
> +static inline int is_##type (void) \
> +{ \
> + return (GET_SAMSUNG_TYPE == (id)) ? 1 : 0; \
> +}
> +
> +IS_SAMSUNG_TYPE(s3c2400, 0x2400)
> +IS_SAMSUNG_TYPE(s3c2410, 0x2410)
> +IS_SAMSUNG_TYPE(s3c2410a, 0x2411)
> +IS_SAMSUNG_TYPE(s3c2412, 0x2412)
> +IS_SAMSUNG_TYPE(s3c2440, 0x2440)
> +IS_SAMSUNG_TYPE(s3c2440a, 0x2441)
> +IS_SAMSUNG_TYPE(s3c2442, 0x2442)
> +IS_SAMSUNG_TYPE(s3c2443, 0x2443)
> +IS_SAMSUNG_TYPE(s3c6400, 0x6400)
> +IS_SAMSUNG_TYPE(s3c6410, 0x6410)
> +IS_SAMSUNG_TYPE(s5pc100, 0xc100)
> +IS_SAMSUNG_TYPE(s5pc110, 0xc110)
> +IS_SAMSUNG_TYPE(s5p6442, 0x6442)
> +
> +#define cpu_is_s3c2400() 0
> +#define cpu_is_s3c2410() 0
> +#define cpu_is_s3c2410a() 0
> +#define cpu_is_s3c2412() 0
> +#define cpu_is_s3c2440() 0
> +#define cpu_is_s3c2440a() 0
> +#define cpu_is_s3c2442() 0
> +#define cpu_is_s3c2443() 0
> +#define cpu_is_s3c6400() 0
> +#define cpu_is_s3c6410() 0
> +#define cpu_is_s5pc100() 0
> +#define cpu_is_s5pc110() 0
> +#define cpu_is_s5p6442() 0
> +
> +#if defined(CONFIG_ARCH_S3C2410)
> +# undef cpu_is_s3c2400
> +# define cpu_is_s3c2400() is_s3c2400()
> +#endif
> +
> +#if defined(CONFIG_CPU_S3C2410)
> +# undef cpu_is_s3c2410
> +# undef cpu_is_s3c2410a
> +# define cpu_is_s3c2410() is_s3c2410()
> +# define cpu_is_s3c2410a() is_s3c2410a()
> +#endif
> +
> +#if defined(CONFIG_CPU_S3C2412)
> +# undef cpu_is_s3c2412
> +# define cpu_is_s3c2412() is_s3c2412()
> +#endif
> +
> +#if defined(CONFIG_CPU_S3C2440)
> +# undef cpu_is_s3c2440
> +# undef cpu_is_s3c2440a
> +# define cpu_is_s3c2440() is_s3c2440()
> +# define cpu_is_s3c2440a() is_s3c2440a()
> +#endif
> +
> +#if defined(CONFIG_CPU_S3C2442)
> +# undef cpu_is_s3c2442
> +# define cpu_is_s3c2442() is_s3c2442()
> +#endif
> +
> +#if defined(CONFIG_CPU_S3C2443)
> +# undef cpu_is_s3c2443
> +# define cpu_is_s3c2443() is_s3c2443()
> +#endif
> +
> +#if defined(CONFIG_ARCH_S3C64XX)
> +# undef cpu_is_s3c6400
> +# undef cpu_is_s3c6410
> +# define cpu_is_s3c6400() is_s3c6400()
> +# define cpu_is_s3c6410() is_s3c6410()
> +#endif
> +
> +#if defined(CONFIG_ARCH_S5PC1XX) || defined(CONFIG_ARCH_S5PC11X)
> +# undef cpu_is_s5pc100
> +# undef cpu_is_s5pc110
> +# define cpu_is_s5pc100() is_s5pc100()
> +# define cpu_is_s5pc110() is_s5pc110()
> +#endif
> +
> +#if defined(CONFIG_CPU_S5P6442)
> +# undef cpu_is_s5p6442
> +# define cpu_is_s5p6442() is_s5p6442()
> +#endif
> +
> +#endif
> diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
> index 6790edf..cb3560d 100644
> --- a/arch/arm/plat-samsung/init.c
> +++ b/arch/arm/plat-samsung/init.c
> @@ -30,6 +30,44 @@
> #include <plat/regs-serial.h>
>
> static struct cpu_table *cpu;
> +static unsigned long cpu_id;
> +
> +unsigned long samsung_cpu_id(void)
> +{
> + return cpu_id;
> +}
> +EXPORT_SYMBOL(samsung_cpu_id);
> +
> +static void __init set_cpu_id(unsigned long idcode)
> +{
> + /*
> + * cpu_id encoding is as follows
> + * cpu_id & 0xff000000 -> S3C Class (24xx/64xx/C1xx)
> + * cpu_id & 0xfff00000 -> S3C Sub Class (241x/244x)
> + * cpu_id & 0xffff0000 -> S3C Type (2410/2440/6400/6410/C100/C110)
> + *
> + * Remains[15:0] are reserved
> + *
> + * 24xx/64xx is started from 0x30000000
> + * C1xx is started from 0x40000000
> + *
> + * Exception:
> + * Store Revision A to 1 such as
> + * s3c2410A to s3c2411
> + * s3c2440A to s3c2441
> + */
> + if ((idcode >> 28) == 0x4)
> + cpu_id = 0xC0000000 | ((idcode & 0x00fff000) << 4);
> + else
> + cpu_id = (idcode & 0x0ffff000) << 4;
> +
> + if (idcode == 0x32410002 || idcode == 0x32440001)
> + cpu_id |= (0x1 << 16);
> + if (idcode == 0x32440aaa) /* s3c2442 */
> + cpu_id |= (0x2 << 16);
> + if (idcode == 0x0) /* s3c2400 */
> + cpu_id |= (0x2400 << 16);
> +}
>
> static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
> struct cpu_table *tab,
> @@ -53,6 +91,8 @@ void __init s3c_init_cpu(unsigned long idcode,
> panic("Unknown S3C24XX CPU");
> }
>
> + set_cpu_id(idcode);
> +
> printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
>
> if (cpu->map_io == NULL || cpu->init == NULL) {
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

--
--
Ben

Q: What's a light-year?
A: One-third less calories than a regular year.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/