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

Ben Dooks ben-linux at fluff.org
Tue Mar 30 21:04:31 EDT 2010


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 at samsung.com>
> ---
> 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 at samsung.com>
> + *
> + * 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 at lists.infradead.org
> 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.




More information about the linux-arm-kernel mailing list