Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / arm / mach-at91 / setup.c
index 51c22a2fcea471dc344075e533a1dc64d2c51df0..961079250b837c25ca7623563285fc090dd09e00 100644 (file)
@@ -98,6 +98,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;
@@ -160,9 +167,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;
        }
 
@@ -185,7 +195,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) {
@@ -242,6 +253,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",
@@ -254,6 +313,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",
 };
 
@@ -281,6 +341,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",
 };
@@ -319,6 +383,31 @@ void __init at91_map_io(void)
                at91_boot_soc.map_io();
 }
 
+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);