[linux-yocto] [PATCH 17/94] arm: AXM5516 emulation bringup mach-axxia

Paul Butler butler.paul at gmail.com
Thu Nov 7 17:12:31 PST 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.3.4




More information about the linux-yocto mailing list