Skip to content

Commit

Permalink
at91: use structure to store the current soc
Browse files Browse the repository at this point in the history
instead of reading the registers everytime

the current implementation respect the following constrain:
 - allow 1 to n soc to be enabled
 - allow to have a virtual cpu type and subtype
 - always detect the cpu type and subtype and report it
 - detect if the soc support is enabled
 - prepare for sysfs export support
 - drop soc specific code via compiler when the soc not enabled
   (via cpu_is_xxx)

Today if we read the exid we will have the same value for 9g35 and 9m11
and we will need to check the cidr too

with the new implementation we just need to check the soc subtype

this will also allow to have specific virtual subtype for rm9200 which the
board will have to specify via at91rm9200_set_type(int) as we have no way to
detect it.

this implementation is inspired by the SH cpu detection support

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Patrice Vilchez <patrice.vilchez@atmel.com>
  • Loading branch information
Jean-Christophe PLAGNIOL-VILLARD authored and Arnd Bergmann committed Jul 28, 2011
1 parent 1ff5b1b commit 8c3583b
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 120 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-at91/at91cap9.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ1) */
};

struct at91_soc __initdata at91cap9_soc = {
struct at91_init_soc __initdata at91cap9_soc = {
.map_io = at91cap9_map_io,
.default_irq_priority = at91cap9_default_irq_priority,
.init = at91cap9_initialize,
Expand Down
10 changes: 1 addition & 9 deletions arch/arm/mach-at91/at91rm9200.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,6 @@ static void at91rm9200_reset(void)
at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
}

int rm9200_type;
EXPORT_SYMBOL(rm9200_type);

void __init at91rm9200_set_type(int type)
{
rm9200_type = type;
}

/* --------------------------------------------------------------------
* AT91RM9200 processor initialization
* -------------------------------------------------------------------- */
Expand Down Expand Up @@ -379,7 +371,7 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
0 /* Advanced Interrupt Controller (IRQ6) */
};

struct at91_soc __initdata at91rm9200_soc = {
struct at91_init_soc __initdata at91rm9200_soc = {
.map_io = at91rm9200_map_io,
.default_irq_priority = at91rm9200_default_irq_priority,
.init = at91rm9200_initialize,
Expand Down
9 changes: 4 additions & 5 deletions arch/arm/mach-at91/at91sam9260.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91sam9260.h>
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
Expand Down Expand Up @@ -322,11 +323,9 @@ static void at91sam9260_poweroff(void)

static void __init at91sam9xe_map_io(void)
{
unsigned long cidr, sram_size;
unsigned long sram_size;

cidr = dbgu_readl(AT91_DBGU, CIDR);

switch (cidr & AT91_CIDR_SRAMSIZ) {
switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
case AT91_CIDR_SRAMSIZ_32K:
sram_size = 2 * SZ_16K;
break;
Expand Down Expand Up @@ -410,7 +409,7 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};

struct at91_soc __initdata at91sam9260_soc = {
struct at91_init_soc __initdata at91sam9260_soc = {
.map_io = at91sam9260_map_io,
.default_irq_priority = at91sam9260_default_irq_priority,
.init = at91sam9260_initialize,
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-at91/at91sam9261.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};

struct at91_soc __initdata at91sam9261_soc = {
struct at91_init_soc __initdata at91sam9261_soc = {
.map_io = at91sam9261_map_io,
.default_irq_priority = at91sam9261_default_irq_priority,
.init = at91sam9261_initialize,
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-at91/at91sam9263.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ1) */
};

struct at91_soc __initdata at91sam9263_soc = {
struct at91_init_soc __initdata at91sam9263_soc = {
.map_io = at91sam9263_map_io,
.default_irq_priority = at91sam9263_default_irq_priority,
.init = at91sam9263_initialize,
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-at91/at91sam9g45.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller (IRQ0) */
};

struct at91_soc __initdata at91sam9g45_soc = {
struct at91_init_soc __initdata at91sam9g45_soc = {
.map_io = at91sam9g45_map_io,
.default_irq_priority = at91sam9g45_default_irq_priority,
.init = at91sam9g45_initialize,
Expand Down
9 changes: 4 additions & 5 deletions arch/arm/mach-at91/at91sam9rl.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
#include <mach/at91sam9rl.h>
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
Expand Down Expand Up @@ -281,11 +282,9 @@ static void at91sam9rl_poweroff(void)

static void __init at91sam9rl_map_io(void)
{
unsigned long cidr, sram_size;
unsigned long sram_size;

cidr = dbgu_readl(AT91_DBGU, CIDR);

switch (cidr & AT91_CIDR_SRAMSIZ) {
switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
case AT91_CIDR_SRAMSIZ_32K:
sram_size = 2 * SZ_16K;
break;
Expand Down Expand Up @@ -359,7 +358,7 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
0, /* Advanced Interrupt Controller */
};

struct at91_soc __initdata at91sam9rl_soc = {
struct at91_init_soc __initdata at91sam9rl_soc = {
.map_io = at91sam9rl_map_io,
.default_irq_priority = at91sam9rl_default_irq_priority,
.init = at91sam9rl_initialize,
Expand Down
159 changes: 89 additions & 70 deletions arch/arm/mach-at91/include/mach/cpu.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*
* arch/arm/mach-at91/include/mach/cpu.h
*
* Copyright (C) 2006 SAN People
* Copyright (C) 2006 SAN People
* Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* 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
Expand All @@ -10,12 +11,8 @@
*
*/

#ifndef __ASM_ARCH_CPU_H
#define __ASM_ARCH_CPU_H

#include <mach/hardware.h>
#include <mach/at91_dbgu.h>

#ifndef __MACH_CPU_H__
#define __MACH_CPU_H__

#define ARCH_ID_AT91RM9200 0x09290780
#define ARCH_ID_AT91SAM9260 0x019803a0
Expand All @@ -39,16 +36,6 @@
#define ARCH_ID_AT91M40807 0x14080745
#define ARCH_ID_AT91R40008 0x44000840

static inline unsigned long at91_cpu_identify(void)
{
return (dbgu_readl(AT91_DBGU, CIDR) & ~AT91_CIDR_VERSION);
}

static inline unsigned long at91_cpu_fully_identify(void)
{
return dbgu_readl(AT91_DBGU, CIDR);
}

#define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002
#define ARCH_EXID_AT91SAM9G46 0x00000003
Expand All @@ -60,93 +47,130 @@ static inline unsigned long at91_cpu_fully_identify(void)
#define ARCH_EXID_AT91SAM9G25 0x00000003
#define ARCH_EXID_AT91SAM9X25 0x00000004

static inline unsigned long at91_exid_identify(void)
{
return dbgu_readl(AT91_DBGU, EXID);
}


#define ARCH_FAMILY_AT91X92 0x09200000
#define ARCH_FAMILY_AT91SAM9 0x01900000
#define ARCH_FAMILY_AT91SAM9XE 0x02900000

static inline unsigned long at91_arch_identify(void)
{
return (dbgu_readl(AT91_DBGU, CIDR) & AT91_CIDR_ARCH);
}

#ifdef CONFIG_ARCH_AT91CAP9
#include <mach/at91_pmc.h>

/* PMC revision */
#define ARCH_REVISION_CAP9_B 0x399
#define ARCH_REVISION_CAP9_C 0x601

static inline unsigned long at91cap9_rev_identify(void)
/* RM9200 type */
#define ARCH_REVISON_9200_BGA (0 << 0)
#define ARCH_REVISON_9200_PQFP (1 << 0)

enum at91_soc_type {
/* 920T */
AT91_SOC_RM9200,

/* CAP */
AT91_SOC_CAP9,

/* SAM92xx */
AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263,

/* SAM9Gxx */
AT91_SOC_SAM9G10, AT91_SOC_SAM9G20, AT91_SOC_SAM9G45,

/* SAM9RL */
AT91_SOC_SAM9RL,

/* SAM9X5 */
AT91_SOC_SAM9X5,

/* Unknown type */
AT91_SOC_NONE
};

enum at91_soc_subtype {
/* RM9200 */
AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP,

/* CAP9 */
AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C,

/* SAM9260 */
AT91_SOC_SAM9XE,

/* SAM9G45 */
AT91_SOC_SAM9G45ES, AT91_SOC_SAM9M10, AT91_SOC_SAM9G46, AT91_SOC_SAM9M11,

/* SAM9X5 */
AT91_SOC_SAM9G15, AT91_SOC_SAM9G35, AT91_SOC_SAM9X35,
AT91_SOC_SAM9G25, AT91_SOC_SAM9X25,

/* Unknown subtype */
AT91_SOC_SUBTYPE_NONE
};

struct at91_socinfo {
unsigned int type, subtype;
unsigned int cidr, exid;
};

extern struct at91_socinfo at91_soc_initdata;
const char *at91_get_soc_type(struct at91_socinfo *c);
const char *at91_get_soc_subtype(struct at91_socinfo *c);

static inline int at91_soc_is_detected(void)
{
return (at91_sys_read(AT91_PMC_VER));
return at91_soc_initdata.type != AT91_SOC_NONE;
}
#endif

#ifdef CONFIG_ARCH_AT91RM9200
extern int rm9200_type;
#define ARCH_REVISON_9200_BGA (0 << 0)
#define ARCH_REVISON_9200_PQFP (1 << 0)
#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200)
#define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp())
#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP)
#define cpu_is_at91rm9200() (at91_soc_initdata.type == AT91_SOC_RM9200)
#define cpu_is_at91rm9200_bga() (at91_soc_initdata.subtype == AT91_SOC_RM9200_BGA)
#define cpu_is_at91rm9200_pqfp() (at91_soc_initdata.subtype == AT91_SOC_RM9200_PQFP)
#else
#define cpu_is_at91rm9200() (0)
#define cpu_is_at91rm9200_bga() (0)
#define cpu_is_at91rm9200_pqfp() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9260
#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE)
#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe())
#define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE)
#define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260)
#else
#define cpu_is_at91sam9xe() (0)
#define cpu_is_at91sam9260() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9G20
#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20)
#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20)
#else
#define cpu_is_at91sam9g20() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9261
#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261)
#define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261)
#else
#define cpu_is_at91sam9261() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9G10
#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10)
#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10)
#else
#define cpu_is_at91sam9g10() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9263
#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263)
#define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263)
#else
#define cpu_is_at91sam9263() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9RL
#define cpu_is_at91sam9rl() (at91_cpu_identify() == ARCH_ID_AT91SAM9RL64)
#define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL)
#else
#define cpu_is_at91sam9rl() (0)
#endif

#ifdef CONFIG_ARCH_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9M10))
#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G46))
#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9M11))
#define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45)
#define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES)
#define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10)
#define cpu_is_at91sam9g46() (at91_soc_initdata.subtype == AT91_SOC_SAM9G46)
#define cpu_is_at91sam9m11() (at91_soc_initdata.subtype == AT91_SOC_SAM9M11)
#else
#define cpu_is_at91sam9g45() (0)
#define cpu_is_at91sam9g45es() (0)
Expand All @@ -156,17 +180,12 @@ extern int rm9200_type;
#endif

#ifdef CONFIG_ARCH_AT91SAM9X5
#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5)
#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G15))
#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G35))
#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \
(at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
#define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5)
#define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15)
#define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35)
#define cpu_is_at91sam9x35() (at91_soc_initdata.subtype == AT91_SOC_SAM9X35)
#define cpu_is_at91sam9g25() (at91_soc_initdata.subtype == AT91_SOC_SAM9G25)
#define cpu_is_at91sam9x25() (at91_soc_initdata.subtype == AT91_SOC_SAM9X25)
#else
#define cpu_is_at91sam9x5() (0)
#define cpu_is_at91sam9g15() (0)
Expand All @@ -177,9 +196,9 @@ extern int rm9200_type;
#endif

#ifdef CONFIG_ARCH_AT91CAP9
#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C)
#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9)
#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B)
#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C)
#else
#define cpu_is_at91cap9() (0)
#define cpu_is_at91cap9_revB() (0)
Expand All @@ -192,4 +211,4 @@ extern int rm9200_type;
*/
#define cpu_is_at32ap7000() (0)

#endif
#endif /* __MACH_CPU_H__ */
Loading

0 comments on commit 8c3583b

Please sign in to comment.