|
@@ -96,6 +96,13 @@ static struct map_desc at91_io_desc __initdata __maybe_unused = {
|
|
|
.type = MT_DEVICE,
|
|
|
};
|
|
|
|
|
|
+static struct map_desc at91_alt_io_desc __initdata __maybe_unused = {
|
|
|
+ .virtual = (unsigned long)AT91_ALT_VA_BASE_SYS,
|
|
|
+ .pfn = __phys_to_pfn(AT91_ALT_BASE_SYS),
|
|
|
+ .length = 24 * SZ_1K,
|
|
|
+ .type = MT_DEVICE,
|
|
|
+};
|
|
|
+
|
|
|
static void __init soc_detect(u32 dbgu_base)
|
|
|
{
|
|
|
u32 cidr, socid;
|
|
@@ -158,9 +165,12 @@ static void __init soc_detect(u32 dbgu_base)
|
|
|
at91_boot_soc = at91sam9n12_soc;
|
|
|
break;
|
|
|
|
|
|
- case ARCH_ID_SAMA5D3:
|
|
|
- at91_soc_initdata.type = AT91_SOC_SAMA5D3;
|
|
|
- at91_boot_soc = sama5d3_soc;
|
|
|
+ case ARCH_ID_SAMA5:
|
|
|
+ at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
|
|
|
+ if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
|
|
|
+ at91_soc_initdata.type = AT91_SOC_SAMA5D3;
|
|
|
+ at91_boot_soc = sama5d3_soc;
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -183,7 +193,8 @@ static void __init soc_detect(u32 dbgu_base)
|
|
|
at91_soc_initdata.cidr = cidr;
|
|
|
|
|
|
/* sub version of soc */
|
|
|
- at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
|
|
|
+ if (!at91_soc_initdata.exid)
|
|
|
+ at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
|
|
|
|
|
|
if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
|
|
|
switch (at91_soc_initdata.exid) {
|
|
@@ -240,6 +251,54 @@ static void __init soc_detect(u32 dbgu_base)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void __init alt_soc_detect(u32 dbgu_base)
|
|
|
+{
|
|
|
+ u32 cidr, socid;
|
|
|
+
|
|
|
+ /* SoC ID */
|
|
|
+ cidr = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_CIDR);
|
|
|
+ socid = cidr & ~AT91_CIDR_VERSION;
|
|
|
+
|
|
|
+ switch (socid) {
|
|
|
+ case ARCH_ID_SAMA5:
|
|
|
+ at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
|
|
|
+ if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
|
|
|
+ at91_soc_initdata.type = AT91_SOC_SAMA5D3;
|
|
|
+ at91_boot_soc = sama5d3_soc;
|
|
|
+ } else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
|
|
|
+ at91_soc_initdata.type = AT91_SOC_SAMA5D4;
|
|
|
+ at91_boot_soc = sama5d4_soc;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!at91_soc_is_detected())
|
|
|
+ return;
|
|
|
+
|
|
|
+ at91_soc_initdata.cidr = cidr;
|
|
|
+
|
|
|
+ /* sub version of soc */
|
|
|
+ if (!at91_soc_initdata.exid)
|
|
|
+ at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
|
|
|
+
|
|
|
+ if (at91_soc_initdata.type == AT91_SOC_SAMA5D4) {
|
|
|
+ switch (at91_soc_initdata.exid) {
|
|
|
+ case ARCH_EXID_SAMA5D41:
|
|
|
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D41;
|
|
|
+ break;
|
|
|
+ case ARCH_EXID_SAMA5D42:
|
|
|
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D42;
|
|
|
+ break;
|
|
|
+ case ARCH_EXID_SAMA5D43:
|
|
|
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D43;
|
|
|
+ break;
|
|
|
+ case ARCH_EXID_SAMA5D44:
|
|
|
+ at91_soc_initdata.subtype = AT91_SOC_SAMA5D44;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static const char *soc_name[] = {
|
|
|
[AT91_SOC_RM9200] = "at91rm9200",
|
|
|
[AT91_SOC_SAM9260] = "at91sam9260",
|
|
@@ -252,6 +311,7 @@ static const char *soc_name[] = {
|
|
|
[AT91_SOC_SAM9X5] = "at91sam9x5",
|
|
|
[AT91_SOC_SAM9N12] = "at91sam9n12",
|
|
|
[AT91_SOC_SAMA5D3] = "sama5d3",
|
|
|
+ [AT91_SOC_SAMA5D4] = "sama5d4",
|
|
|
[AT91_SOC_UNKNOWN] = "Unknown",
|
|
|
};
|
|
|
|
|
@@ -279,6 +339,10 @@ static const char *soc_subtype_name[] = {
|
|
|
[AT91_SOC_SAMA5D34] = "sama5d34",
|
|
|
[AT91_SOC_SAMA5D35] = "sama5d35",
|
|
|
[AT91_SOC_SAMA5D36] = "sama5d36",
|
|
|
+ [AT91_SOC_SAMA5D41] = "sama5d41",
|
|
|
+ [AT91_SOC_SAMA5D42] = "sama5d42",
|
|
|
+ [AT91_SOC_SAMA5D43] = "sama5d43",
|
|
|
+ [AT91_SOC_SAMA5D44] = "sama5d44",
|
|
|
[AT91_SOC_SUBTYPE_NONE] = "None",
|
|
|
[AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
|
|
|
};
|
|
@@ -341,6 +405,31 @@ void __init at91_ioremap_rstc(u32 base_addr)
|
|
|
panic("Impossible to ioremap at91_rstc_base\n");
|
|
|
}
|
|
|
|
|
|
+void __init at91_alt_map_io(void)
|
|
|
+{
|
|
|
+ /* Map peripherals */
|
|
|
+ iotable_init(&at91_alt_io_desc, 1);
|
|
|
+
|
|
|
+ at91_soc_initdata.type = AT91_SOC_UNKNOWN;
|
|
|
+ at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_UNKNOWN;
|
|
|
+
|
|
|
+ alt_soc_detect(AT91_BASE_DBGU2);
|
|
|
+ if (!at91_soc_is_detected())
|
|
|
+ panic("AT91: Impossible to detect the SOC type");
|
|
|
+
|
|
|
+ pr_info("AT91: Detected soc type: %s\n",
|
|
|
+ at91_get_soc_type(&at91_soc_initdata));
|
|
|
+ if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
|
|
|
+ pr_info("AT91: Detected soc subtype: %s\n",
|
|
|
+ at91_get_soc_subtype(&at91_soc_initdata));
|
|
|
+
|
|
|
+ if (!at91_soc_is_enabled())
|
|
|
+ panic("AT91: Soc not enabled");
|
|
|
+
|
|
|
+ if (at91_boot_soc.map_io)
|
|
|
+ at91_boot_soc.map_io();
|
|
|
+}
|
|
|
+
|
|
|
void __iomem *at91_matrix_base;
|
|
|
EXPORT_SYMBOL_GPL(at91_matrix_base);
|
|
|
|