[linux-yocto] [PATCH 2/4] arm: AXM5516 emulation bringup mach-axxia
Paul Butler
butler.paul at gmail.com
Mon Oct 28 16:43:24 PDT 2013
Signed-off-by: Paul Butler <paul.butler at windriver.com>
---
arch/arm/Makefile | 4 ++
arch/arm/kernel/head.S | 8 +++
arch/arm/mach-axxia/Kconfig | 3 +
arch/arm/mach-axxia/include/mach/debug-macro.S | 34 ++++-----
arch/arm/mach-axxia/platsmp.c | 96 +++++++++++++++++++++++++-
init/main.c | 11 +++
6 files changed, 139 insertions(+), 17 deletions(-)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index db992cd..16a0b42 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -133,6 +133,10 @@ textofs-$(CONFIG_ARCH_MSM7X30) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+ifneq ($(CONFIG_ARCH_AXXIA_SIM),y)
+textofs-$(CONFIG_ARCH_AXXIA) := 0x00408000
+endif
+
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
machine-$(CONFIG_ARCH_AT91) := at91
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 3bf0c7f..bd39808 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -52,7 +52,12 @@
.equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
.macro pgtbl, rd, phys
+#ifdef CONFIG_ARCH_AXXIA
+ ldr \rd, =(TEXT_OFFSET - PG_DIR_SIZE)
+ add \rd, \rd, \phys
+#else
add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
+#endif
.endm
#ifdef CONFIG_XIP_KERNEL
@@ -289,6 +294,9 @@ __create_page_tables:
#else
orr r3, r3, #PMD_SECT_XN
#endif
+#ifdef CONFIG_ARCH_AXXIA
+ orr r7, r7, #0x20
+#endif
1: str r3, [r0], #4
#ifdef CONFIG_ARM_LPAE
str r7, [r0], #4
diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig
index 4a4922f..206c344 100644
--- a/arch/arm/mach-axxia/Kconfig
+++ b/arch/arm/mach-axxia/Kconfig
@@ -28,4 +28,7 @@ config ARCH_AXXIA_DT
If your bootloader supports Flattened Device Tree based booting,
say Y here.
+config ARCH_AXXIA_SIM
+ bool "Build for Simulation instead of Emulation or ASIC"
+
endmenu
diff --git a/arch/arm/mach-axxia/include/mach/debug-macro.S b/arch/arm/mach-axxia/include/mach/debug-macro.S
index f25a024..83d6670 100644
--- a/arch/arm/mach-axxia/include/mach/debug-macro.S
+++ b/arch/arm/mach-axxia/include/mach/debug-macro.S
@@ -10,26 +10,28 @@
* published by the Free Software Foundation.
*/
-#ifdef CONFIG_DEBUG_VEXPRESS_CA9X4_UART
-#define DEBUG_LL_PHYS_BASE 0x10000000
-#define DEBUG_LL_UART_OFFSET 0x00009000
-#endif
+/*
+ * -- NOTE --
+ *
+*/
-#ifdef CONFIG_DEBUG_VEXPRESS_RS1_UART
-#define DEBUG_LL_PHYS_BASE 0x1c000000
-#define DEBUG_LL_UART_OFFSET 0x00090000
+#if !defined(CONFIG_ARM_LPAE)
+#error "Axxia Peripherals Are Only Accessible Using the LPAE!"
#endif
-#define DEBUG_LL_VIRT_BASE 0xf8000000
+#define UART0_PHYSICAL_ADDRESS 0x0000002010080000ULL
+#define UART1_PHYSICAL_ADDRESS 0x0000002010081000ULL
+#define UART2_PHYSICAL_ADDRESS 0x0000002010082000ULL
+#define UART3_PHYSICAL_ADDRESS 0x0000002010083000ULL
-#ifndef DEBUG_LL_UART_OFFSET
-#error "Unknown vexpress UART offset"
-#endif
+#define UART0_VIRTUAL_ADDRESS 0xf0080000
+#define UART1_VIRTUAL_ADDRESS 0xf0081000
+#define UART2_VIRTUAL_ADDRESS 0xf0082000
+#define UART3_VIRTUAL_ADDRESS 0xf0083000
- .macro addruart,rp,rv,tmp
- mov \rp, #DEBUG_LL_UART_OFFSET
- orr \rv, \rp, #DEBUG_LL_VIRT_BASE
- orr \rp, \rp, #DEBUG_LL_PHYS_BASE
- .endm
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =0x10080000
+ ldr \rv, =0xf0080000
+ .endm
#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index 4ba2e7a..95859ec 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -31,6 +31,9 @@ volatile int __cpuinitdata pen_release = -1;
extern void axxia_secondary_startup(void);
+#define APB2_SER3_PHY_ADDR 0x002010030000ULL
+#define APB2_SER3_ADDR_SIZE 0x10000
+
/*
* Write pen_release in a way that is guaranteed to be visible to all
* observers, irrespective of whether they're taking part in coherency
@@ -113,7 +116,12 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
#endif
/* Wait for so long, then give up if nothing happens ... */
+#ifdef CONFIG_ARCH_AXXIA_SIM
timeout = jiffies + (1 * HZ);
+#else
+ timeout = jiffies + (10 * HZ);
+#endif
+
while (time_before(jiffies, timeout)) {
smp_rmb();
if (pen_release == -1)
@@ -159,8 +167,10 @@ void __init smp_init_cpus(void)
set_smp_cross_call(axxia_gic_raise_softirq);
}
-void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+void __init
+platform_smp_prepare_cpus(unsigned int max_cpus)
{
+#ifdef CONFIG_ARCH_AXXIA_SIM
int i;
/*
@@ -177,4 +187,88 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
*/
*(u32 *)phys_to_virt(0x10000020) =
virt_to_phys(axxia_secondary_startup);
+#else
+ int i;
+ void __iomem *apb2_ser3_base;
+ unsigned long resetVal;
+ int phys_cpu, cpu_count=0;
+ struct device_node *np;
+ unsigned long release_addr[NR_CPUS] = {0};
+ unsigned long release;
+
+ if (of_find_compatible_node(NULL, NULL, "lsi,axm5516")) {
+ for_each_node_by_name(np, "cpu") {
+ if (of_property_read_u32(np, "reg", &phys_cpu))
+ continue;
+
+ if (0 == phys_cpu)
+ continue;
+
+ if (of_property_read_u32(np, "cpu-release-addr",
+ &release))
+ continue;
+
+ release_addr[phys_cpu] = release;
+ printk(KERN_ERR
+ "%s:%d - set address for %d to 0x%08x\n",
+ __FILE__, __LINE__,
+ phys_cpu, release_addr[phys_cpu]);
+ }
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+
+ apb2_ser3_base = ioremap(APB2_SER3_PHY_ADDR, APB2_SER3_ADDR_SIZE);
+
+ for (i = 0; i < NR_CPUS; i++) {
+ /* check if this is a possible CPU and
+ it is within max_cpus range */
+ if ((cpu_possible(i)) &&
+ (cpu_count < max_cpus) &&
+ (0 != release_addr[i])) {
+ resetVal = readl(apb2_ser3_base + 0x1010);
+ phys_cpu = cpu_logical_map(i);
+ set_cpu_present(cpu_count, true);
+ if (phys_cpu != 0) {
+ writel(0xab, apb2_ser3_base+0x1000);
+ resetVal &= ~(1 << phys_cpu);
+ writel(resetVal, apb2_ser3_base+0x1010);
+ udelay(1000);
+ }
+ cpu_count++;
+ }
+ }
+
+ iounmap(apb2_ser3_base);
+
+ /*
+ * This is the entry point of the routine that the secondary
+ * cores will execute once they are released from their
+ * "holding pen".
+ */
+ *(u32 *)phys_to_virt(release) =
+ virt_to_phys(axxia_secondary_startup);
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)phys_to_virt(release),
+ sizeof(u32));
+ } else if (of_find_compatible_node(NULL, NULL, "lsi,axm5516-sim")) {
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ /*
+ * This is the entry point of the routine that the secondary
+ * cores will execute once they are released from their
+ * "holding pen".
+ */
+ *(u32 *)phys_to_virt(0x10000020) =
+ virt_to_phys(axxia_secondary_startup);
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)phys_to_virt(0x10000020),
+ sizeof(u32));
+ }
+
+ return;
+#endif
}
diff --git a/init/main.c b/init/main.c
index 6484e4e..82b4513 100644
--- a/init/main.c
+++ b/init/main.c
@@ -467,6 +467,17 @@ asmlinkage void __init start_kernel(void)
char * command_line;
extern const struct kernel_param __start___param[], __stop___param[];
+#if defined(CONFIG_ARCH_AXXIA) && defined(DEBUG_LL)
+ {
+ *(unsigned long *)(0xf0080000 + 0x24) = 13;
+ *(unsigned long *)(0xf0080000 + 0x28) = 1;
+ *(unsigned long *)(0xf0080000 + 0x2c) = 0x70;
+ *(unsigned long *)(0xf0080000 + 0x30) = 0x301;
+ *(unsigned long *)(0xf0080000 + 0x34) = 0;
+ *(unsigned long *)(0xf0080000 + 0x38) = 0x700;
+ }
+#endif /* CONFIG_ARCH_AXXIA && DEBUG_LL */
+
/*
* Need to run as early as possible, to initialize the
* lockdep hash:
--
1.8.4.1
More information about the linux-yocto
mailing list