summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91/at91_machdep.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2012-07-11 20:17:14 +0000
committerimp <imp@FreeBSD.org>2012-07-11 20:17:14 +0000
commit515d0c1d290c1ac2fb1aa99e74ef4175c158a007 (patch)
treecdb15b34649d1c3b0b980724718c54d34344146f /sys/arm/at91/at91_machdep.c
parent003ccf85faf91187b67eb412e643bb75b87ae2a6 (diff)
downloadFreeBSD-src-515d0c1d290c1ac2fb1aa99e74ef4175c158a007.zip
FreeBSD-src-515d0c1d290c1ac2fb1aa99e74ef4175c158a007.tar.gz
Make the SoC stuff a little more modular, and start to move away from
having the CPU device that's a child of atmelarm that does stuff. o Create a linker_set for the support fucntions for the SoCs. o Rename soc_data to soc_info. o Move the delay and reset function pointers to new soc_data struct o Create elements for all known SoCs o Add lookup of the SoC we found, and print a warning if it isn't one we know about.
Diffstat (limited to 'sys/arm/at91/at91_machdep.c')
-rw-r--r--sys/arm/at91/at91_machdep.c94
1 files changed, 52 insertions, 42 deletions
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index 15e404f..0bb79bd 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$");
#include <arm/at91/at91board.h>
#include <arm/at91/at91var.h>
+#include <arm/at91/at91soc.h>
#include <arm/at91/at91_usartreg.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91sam9g20reg.h>
@@ -278,7 +279,7 @@ static const char *soc_subtype_name[] = {
[AT91_ST_SAM9X35] = "at91sam9x35",
};
-struct at91_soc_info soc_data;
+struct at91_soc_info soc_info;
/*
* Read the SoC ID from the CIDR register and try to match it against the
@@ -291,92 +292,92 @@ at91_try_id(uint32_t dbgu_base)
{
uint32_t socid;
- soc_data.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+ soc_info.cidr = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C1R);
- socid = soc_data.cidr & ~AT91_CPU_VERSION_MASK;
+ socid = soc_info.cidr & ~AT91_CPU_VERSION_MASK;
- soc_data.type = AT91_T_NONE;
- soc_data.subtype = AT91_ST_NONE;
- soc_data.family = (soc_data.cidr & AT91_CPU_FAMILY_MASK) >> 20;
- soc_data.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
+ soc_info.type = AT91_T_NONE;
+ soc_info.subtype = AT91_ST_NONE;
+ soc_info.family = (soc_info.cidr & AT91_CPU_FAMILY_MASK) >> 20;
+ soc_info.exid = *(volatile uint32_t *)(AT91_BASE + dbgu_base +
DBGU_C2R);
switch (socid) {
case AT91_CPU_CAP9:
- soc_data.type = AT91_T_CAP9;
+ soc_info.type = AT91_T_CAP9;
break;
case AT91_CPU_RM9200:
- soc_data.type = AT91_T_RM9200;
+ soc_info.type = AT91_T_RM9200;
break;
case AT91_CPU_SAM9XE128:
case AT91_CPU_SAM9XE256:
case AT91_CPU_SAM9XE512:
case AT91_CPU_SAM9260:
- soc_data.type = AT91_T_SAM9260;
- if (soc_data.family == AT91_FAMILY_SAM9XE)
- soc_data.subtype = AT91_ST_SAM9XE;
+ soc_info.type = AT91_T_SAM9260;
+ if (soc_info.family == AT91_FAMILY_SAM9XE)
+ soc_info.subtype = AT91_ST_SAM9XE;
break;
case AT91_CPU_SAM9261:
- soc_data.type = AT91_T_SAM9261;
+ soc_info.type = AT91_T_SAM9261;
break;
case AT91_CPU_SAM9263:
- soc_data.type = AT91_T_SAM9263;
+ soc_info.type = AT91_T_SAM9263;
break;
case AT91_CPU_SAM9G10:
- soc_data.type = AT91_T_SAM9G10;
+ soc_info.type = AT91_T_SAM9G10;
break;
case AT91_CPU_SAM9G20:
- soc_data.type = AT91_T_SAM9G20;
+ soc_info.type = AT91_T_SAM9G20;
break;
case AT91_CPU_SAM9G45:
- soc_data.type = AT91_T_SAM9G45;
+ soc_info.type = AT91_T_SAM9G45;
break;
case AT91_CPU_SAM9N12:
- soc_data.type = AT91_T_SAM9N12;
+ soc_info.type = AT91_T_SAM9N12;
break;
case AT91_CPU_SAM9RL64:
- soc_data.type = AT91_T_SAM9RL;
+ soc_info.type = AT91_T_SAM9RL;
break;
case AT91_CPU_SAM9X5:
- soc_data.type = AT91_T_SAM9X5;
+ soc_info.type = AT91_T_SAM9X5;
break;
default:
return (0);
}
- switch (soc_data.type) {
+ switch (soc_info.type) {
case AT91_T_SAM9G45:
- switch (soc_data.exid) {
+ switch (soc_info.exid) {
case AT91_EXID_SAM9G45:
- soc_data.subtype = AT91_ST_SAM9G45;
+ soc_info.subtype = AT91_ST_SAM9G45;
break;
case AT91_EXID_SAM9G46:
- soc_data.subtype = AT91_ST_SAM9G46;
+ soc_info.subtype = AT91_ST_SAM9G46;
break;
case AT91_EXID_SAM9M10:
- soc_data.subtype = AT91_ST_SAM9M10;
+ soc_info.subtype = AT91_ST_SAM9M10;
break;
case AT91_EXID_SAM9M11:
- soc_data.subtype = AT91_ST_SAM9M11;
+ soc_info.subtype = AT91_ST_SAM9M11;
break;
}
break;
case AT91_T_SAM9X5:
- switch (soc_data.exid) {
+ switch (soc_info.exid) {
case AT91_EXID_SAM9G15:
- soc_data.subtype = AT91_ST_SAM9G15;
+ soc_info.subtype = AT91_ST_SAM9G15;
break;
case AT91_EXID_SAM9G25:
- soc_data.subtype = AT91_ST_SAM9G25;
+ soc_info.subtype = AT91_ST_SAM9G25;
break;
case AT91_EXID_SAM9G35:
- soc_data.subtype = AT91_ST_SAM9G35;
+ soc_info.subtype = AT91_ST_SAM9G35;
break;
case AT91_EXID_SAM9X25:
- soc_data.subtype = AT91_ST_SAM9X25;
+ soc_info.subtype = AT91_ST_SAM9X25;
break;
case AT91_EXID_SAM9X35:
- soc_data.subtype = AT91_ST_SAM9X35;
+ soc_info.subtype = AT91_ST_SAM9X35;
break;
}
break;
@@ -384,18 +385,24 @@ at91_try_id(uint32_t dbgu_base)
break;
}
/*
- * Disable interrupts
+ * Disable interrupts in the DBGU unit...
*/
*(volatile uint32_t *)(AT91_BASE + dbgu_base + USART_IDR) = 0xffffffff;
/*
* Save the name for later...
*/
- snprintf(soc_data.name, sizeof(soc_data.name), "%s%s%s",
- soc_type_name[soc_data.type],
- soc_data.subtype == AT91_ST_NONE ? "" : " subtype ",
- soc_data.subtype == AT91_ST_NONE ? "" :
- soc_subtype_name[soc_data.subtype]);
+ snprintf(soc_info.name, sizeof(soc_info.name), "%s%s%s",
+ soc_type_name[soc_info.type],
+ soc_info.subtype == AT91_ST_NONE ? "" : " subtype ",
+ soc_info.subtype == AT91_ST_NONE ? "" :
+ soc_subtype_name[soc_info.subtype]);
+
+ /*
+ * try to get the matching CPU support.
+ */
+ soc_info.soc_data = at91_match_soc(soc_info.type, soc_info.subtype);
+
return (1);
}
@@ -548,6 +555,9 @@ initarm(struct arm_boot_params *abp)
cninit();
+ if (soc_info.soc_data == NULL)
+ printf("Warning: No soc support for %s found.\n", soc_info.name);
+
memsize = board_init();
physmem = memsize / PAGE_SIZE;
@@ -637,16 +647,16 @@ void
DELAY(int n)
{
- if (soc_data.delay)
- soc_data.delay(n);
+ if (soc_info.soc_data)
+ soc_info.soc_data->soc_delay(n);
}
void
cpu_reset(void)
{
- if (soc_data.reset)
- soc_data.reset();
+ if (soc_info.soc_data)
+ soc_info.soc_data->soc_reset();
while (1)
continue;
}
OpenPOWER on IntegriCloud