Commit 726d32bf authored by Nicolas Ferre's avatar Nicolas Ferre

ARM: at91: SAMA5D4 SoC detection code and low level routines

SoC identification code, kernel uncompress and low level
debugging routines update.
On SAMA5D4, DBGU is at another address AT91_BASE_DBGU2 so another
round of detection is needed. We also had to differentiate with
SAMA5D3 SoC family and rename some variables.
Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent 2dc850b6
...@@ -73,7 +73,7 @@ static void __init sama5_dt_device_init(void) ...@@ -73,7 +73,7 @@ static void __init sama5_dt_device_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
} }
static const char *sama5_dt_board_compat[] __initdata = { static const char *sama5_dt_board_compat[] __initconst = {
"atmel,sama5", "atmel,sama5",
NULL NULL
}; };
...@@ -88,3 +88,17 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") ...@@ -88,3 +88,17 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
.init_machine = sama5_dt_device_init, .init_machine = sama5_dt_device_init,
.dt_compat = sama5_dt_board_compat, .dt_compat = sama5_dt_board_compat,
MACHINE_END MACHINE_END
static const char *sama5_alt_dt_board_compat[] __initconst = {
"atmel,sama5d4",
NULL
};
DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5 (Device Tree)")
/* Maintainer: Atmel */
.map_io = at91_alt_map_io,
.init_early = at91_dt_initialize,
.init_machine = sama5_dt_device_init,
.dt_compat = sama5_alt_dt_board_compat,
.l2c_aux_mask = ~0UL,
MACHINE_END
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
/* Map io */ /* Map io */
extern void __init at91_map_io(void); extern void __init at91_map_io(void);
extern void __init at91_alt_map_io(void);
extern void __init at91_init_sram(int bank, unsigned long base, extern void __init at91_init_sram(int bank, unsigned long base,
unsigned int length); unsigned int length);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
#define ARCH_ID_AT91M40807 0x14080745 #define ARCH_ID_AT91M40807 0x14080745
#define ARCH_ID_AT91R40008 0x44000840 #define ARCH_ID_AT91R40008 0x44000840
#define ARCH_ID_SAMA5D3 0x8A5C07C0 #define ARCH_ID_SAMA5 0x8A5C07C0
#define ARCH_EXID_AT91SAM9M11 0x00000001 #define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002 #define ARCH_EXID_AT91SAM9M10 0x00000002
...@@ -49,12 +49,19 @@ ...@@ -49,12 +49,19 @@
#define ARCH_EXID_AT91SAM9G25 0x00000003 #define ARCH_EXID_AT91SAM9G25 0x00000003
#define ARCH_EXID_AT91SAM9X25 0x00000004 #define ARCH_EXID_AT91SAM9X25 0x00000004
#define ARCH_EXID_SAMA5D3 0x00004300
#define ARCH_EXID_SAMA5D31 0x00444300 #define ARCH_EXID_SAMA5D31 0x00444300
#define ARCH_EXID_SAMA5D33 0x00414300 #define ARCH_EXID_SAMA5D33 0x00414300
#define ARCH_EXID_SAMA5D34 0x00414301 #define ARCH_EXID_SAMA5D34 0x00414301
#define ARCH_EXID_SAMA5D35 0x00584300 #define ARCH_EXID_SAMA5D35 0x00584300
#define ARCH_EXID_SAMA5D36 0x00004301 #define ARCH_EXID_SAMA5D36 0x00004301
#define ARCH_EXID_SAMA5D4 0x00000007
#define ARCH_EXID_SAMA5D41 0x00000001
#define ARCH_EXID_SAMA5D42 0x00000002
#define ARCH_EXID_SAMA5D43 0x00000003
#define ARCH_EXID_SAMA5D44 0x00000004
#define ARCH_FAMILY_AT91X92 0x09200000 #define ARCH_FAMILY_AT91X92 0x09200000
#define ARCH_FAMILY_AT91SAM9 0x01900000 #define ARCH_FAMILY_AT91SAM9 0x01900000
#define ARCH_FAMILY_AT91SAM9XE 0x02900000 #define ARCH_FAMILY_AT91SAM9XE 0x02900000
...@@ -111,6 +118,10 @@ enum at91_soc_subtype { ...@@ -111,6 +118,10 @@ enum at91_soc_subtype {
AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34,
AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36, AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36,
/* SAMA5D4 */
AT91_SOC_SAMA5D41, AT91_SOC_SAMA5D42, AT91_SOC_SAMA5D43,
AT91_SOC_SAMA5D44,
/* No subtype for this SoC */ /* No subtype for this SoC */
AT91_SOC_SUBTYPE_NONE, AT91_SOC_SUBTYPE_NONE,
......
...@@ -16,8 +16,11 @@ ...@@ -16,8 +16,11 @@
#if defined(CONFIG_AT91_DEBUG_LL_DBGU0) #if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
#define AT91_DBGU AT91_BASE_DBGU0 #define AT91_DBGU AT91_BASE_DBGU0
#else #elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
#define AT91_DBGU AT91_BASE_DBGU1 #define AT91_DBGU AT91_BASE_DBGU1
#else
/* On sama5d4, use USART3 as low level serial console */
#define AT91_DBGU SAMA5D4_BASE_USART3
#endif #endif
.macro addruart, rp, rv, tmp .macro addruart, rp, rv, tmp
......
...@@ -19,8 +19,10 @@ ...@@ -19,8 +19,10 @@
/* DBGU base */ /* DBGU base */
/* rm9200, 9260/9g20, 9261/9g10, 9rl */ /* rm9200, 9260/9g20, 9261/9g10, 9rl */
#define AT91_BASE_DBGU0 0xfffff200 #define AT91_BASE_DBGU0 0xfffff200
/* 9263, 9g45 */ /* 9263, 9g45, sama5d3 */
#define AT91_BASE_DBGU1 0xffffee00 #define AT91_BASE_DBGU1 0xffffee00
/* sama5d4 */
#define AT91_BASE_DBGU2 0xfc069000
#if defined(CONFIG_ARCH_AT91X40) #if defined(CONFIG_ARCH_AT91X40)
#include <mach/at91x40.h> #include <mach/at91x40.h>
...@@ -34,6 +36,7 @@ ...@@ -34,6 +36,7 @@
#include <mach/at91sam9x5.h> #include <mach/at91sam9x5.h>
#include <mach/at91sam9n12.h> #include <mach/at91sam9n12.h>
#include <mach/sama5d3.h> #include <mach/sama5d3.h>
#include <mach/sama5d4.h>
/* /*
* On all at91 except rm9200 and x40 have the System Controller starts * On all at91 except rm9200 and x40 have the System Controller starts
...@@ -47,6 +50,11 @@ ...@@ -47,6 +50,11 @@
* and map the same memory space * and map the same memory space
*/ */
#define AT91_BASE_SYS 0xffffc000 #define AT91_BASE_SYS 0xffffc000
/*
* On sama5d4 there is no system controller, we map some needed peripherals
*/
#define AT91_ALT_BASE_SYS 0xfc069000
#endif #endif
/* /*
...@@ -69,6 +77,13 @@ ...@@ -69,6 +77,13 @@
*/ */
#define AT91_IO_PHYS_BASE 0xFFF78000 #define AT91_IO_PHYS_BASE 0xFFF78000
#define AT91_IO_VIRT_BASE IOMEM(0xFF000000 - AT91_IO_SIZE) #define AT91_IO_VIRT_BASE IOMEM(0xFF000000 - AT91_IO_SIZE)
/*
* On sama5d4, remap the peripherals from address 0xFC069000 .. 0xFC06F000
* to 0xFB069000 .. 0xFB06F000. (24Kb)
*/
#define AT91_ALT_IO_PHYS_BASE AT91_ALT_BASE_SYS
#define AT91_ALT_IO_VIRT_BASE IOMEM(0xFB069000)
#else #else
/* /*
* Identity mapping for the non MMU case. * Identity mapping for the non MMU case.
...@@ -81,11 +96,13 @@ ...@@ -81,11 +96,13 @@
/* Convert a physical IO address to virtual IO address */ /* Convert a physical IO address to virtual IO address */
#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE) #define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
#define AT91_ALT_IO_P2V(x) ((x) - AT91_ALT_IO_PHYS_BASE + AT91_ALT_IO_VIRT_BASE)
/* /*
* Virtual to Physical Address mapping for IO devices. * Virtual to Physical Address mapping for IO devices.
*/ */
#define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS) #define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS)
#define AT91_ALT_VA_BASE_SYS AT91_ALT_IO_P2V(AT91_ALT_BASE_SYS)
/* Internal SRAM is mapped below the IO devices */ /* Internal SRAM is mapped below the IO devices */
#define AT91_SRAM_MAX SZ_1M #define AT91_SRAM_MAX SZ_1M
......
...@@ -94,7 +94,7 @@ static const u32 uarts_sam9x5[] = { ...@@ -94,7 +94,7 @@ static const u32 uarts_sam9x5[] = {
0, 0,
}; };
static const u32 uarts_sama5[] = { static const u32 uarts_sama5d3[] = {
AT91_BASE_DBGU1, AT91_BASE_DBGU1,
SAMA5D3_BASE_USART0, SAMA5D3_BASE_USART0,
SAMA5D3_BASE_USART1, SAMA5D3_BASE_USART1,
...@@ -103,6 +103,12 @@ static const u32 uarts_sama5[] = { ...@@ -103,6 +103,12 @@ static const u32 uarts_sama5[] = {
0, 0,
}; };
static const u32 uarts_sama5d4[] = {
AT91_BASE_DBGU2,
SAMA5D4_BASE_USART3,
0,
};
static inline const u32* decomp_soc_detect(void __iomem *dbgu_base) static inline const u32* decomp_soc_detect(void __iomem *dbgu_base)
{ {
u32 cidr, socid; u32 cidr, socid;
...@@ -134,8 +140,14 @@ static inline const u32* decomp_soc_detect(void __iomem *dbgu_base) ...@@ -134,8 +140,14 @@ static inline const u32* decomp_soc_detect(void __iomem *dbgu_base)
case ARCH_ID_AT91SAM9X5: case ARCH_ID_AT91SAM9X5:
return uarts_sam9x5; return uarts_sam9x5;
case ARCH_ID_SAMA5D3: case ARCH_ID_SAMA5:
return uarts_sama5; cidr = __raw_readl(dbgu_base + AT91_DBGU_EXID);
if (cidr & ARCH_EXID_SAMA5D3)
return uarts_sama5d3;
else if (cidr & ARCH_EXID_SAMA5D4)
return uarts_sama5d4;
break;
} }
/* at91sam9g10 */ /* at91sam9g10 */
...@@ -156,9 +168,10 @@ static inline void arch_decomp_setup(void) ...@@ -156,9 +168,10 @@ static inline void arch_decomp_setup(void)
const u32* usarts; const u32* usarts;
usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU0); usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU0);
if (!usarts) if (!usarts)
usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU1); usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU1);
if (!usarts)
usarts = decomp_soc_detect((void __iomem *)AT91_BASE_DBGU2);
if (!usarts) { if (!usarts) {
at91_uart = NULL; at91_uart = NULL;
return; return;
......
...@@ -25,9 +25,37 @@ ...@@ -25,9 +25,37 @@
/* -------------------------------------------------------------------- /* --------------------------------------------------------------------
* Processor initialization * Processor initialization
* -------------------------------------------------------------------- */ * -------------------------------------------------------------------- */
static struct map_desc at91_io_desc[] __initdata = {
{
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
.pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
.length = SZ_512,
.type = MT_DEVICE,
},
{
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
.pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
.length = SZ_512,
.type = MT_DEVICE,
},
{ /* On sama5d4, we use USART3 as serial console */
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
.pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
.length = SZ_256,
.type = MT_DEVICE,
},
{ /* A bunch of peripheral with fine grained IO space */
.virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
.pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
.length = SZ_2K,
.type = MT_DEVICE,
},
};
static void __init sama5d4_map_io(void) static void __init sama5d4_map_io(void)
{ {
iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE); at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE);
} }
......
...@@ -96,6 +96,13 @@ static struct map_desc at91_io_desc __initdata __maybe_unused = { ...@@ -96,6 +96,13 @@ static struct map_desc at91_io_desc __initdata __maybe_unused = {
.type = MT_DEVICE, .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) static void __init soc_detect(u32 dbgu_base)
{ {
u32 cidr, socid; u32 cidr, socid;
...@@ -158,9 +165,12 @@ static void __init soc_detect(u32 dbgu_base) ...@@ -158,9 +165,12 @@ static void __init soc_detect(u32 dbgu_base)
at91_boot_soc = at91sam9n12_soc; at91_boot_soc = at91sam9n12_soc;
break; break;
case ARCH_ID_SAMA5D3: case ARCH_ID_SAMA5:
at91_soc_initdata.type = AT91_SOC_SAMA5D3; at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
at91_boot_soc = sama5d3_soc; if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
at91_boot_soc = sama5d3_soc;
}
break; break;
} }
...@@ -183,7 +193,8 @@ static void __init soc_detect(u32 dbgu_base) ...@@ -183,7 +193,8 @@ static void __init soc_detect(u32 dbgu_base)
at91_soc_initdata.cidr = cidr; at91_soc_initdata.cidr = cidr;
/* sub version of soc */ /* 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) { if (at91_soc_initdata.type == AT91_SOC_SAM9G45) {
switch (at91_soc_initdata.exid) { switch (at91_soc_initdata.exid) {
...@@ -240,6 +251,54 @@ static void __init soc_detect(u32 dbgu_base) ...@@ -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[] = { static const char *soc_name[] = {
[AT91_SOC_RM9200] = "at91rm9200", [AT91_SOC_RM9200] = "at91rm9200",
[AT91_SOC_SAM9260] = "at91sam9260", [AT91_SOC_SAM9260] = "at91sam9260",
...@@ -252,6 +311,7 @@ static const char *soc_name[] = { ...@@ -252,6 +311,7 @@ static const char *soc_name[] = {
[AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9X5] = "at91sam9x5",
[AT91_SOC_SAM9N12] = "at91sam9n12", [AT91_SOC_SAM9N12] = "at91sam9n12",
[AT91_SOC_SAMA5D3] = "sama5d3", [AT91_SOC_SAMA5D3] = "sama5d3",
[AT91_SOC_SAMA5D4] = "sama5d4",
[AT91_SOC_UNKNOWN] = "Unknown", [AT91_SOC_UNKNOWN] = "Unknown",
}; };
...@@ -279,6 +339,10 @@ static const char *soc_subtype_name[] = { ...@@ -279,6 +339,10 @@ static const char *soc_subtype_name[] = {
[AT91_SOC_SAMA5D34] = "sama5d34", [AT91_SOC_SAMA5D34] = "sama5d34",
[AT91_SOC_SAMA5D35] = "sama5d35", [AT91_SOC_SAMA5D35] = "sama5d35",
[AT91_SOC_SAMA5D36] = "sama5d36", [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_NONE] = "None",
[AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
}; };
...@@ -341,6 +405,31 @@ void __init at91_ioremap_rstc(u32 base_addr) ...@@ -341,6 +405,31 @@ void __init at91_ioremap_rstc(u32 base_addr)
panic("Impossible to ioremap at91_rstc_base\n"); 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; void __iomem *at91_matrix_base;
EXPORT_SYMBOL_GPL(at91_matrix_base); EXPORT_SYMBOL_GPL(at91_matrix_base);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment