[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 1/1] XEN/ARM: Add Odroid-XU3/XU4 support



The Odroid-XU3/XU4 from hardkernel is an Exynos 5422 based board.
Code from mcpm-exynos.c and mcpm-platsmp.c from the Linux kernel
has been used to get all the 8 cores from the 2 clusters powered
on.
The Linux DTS for these odroid uses "samsung,exynos5800" as
the machine compatible string. Hence, the same is used herein.

This change has been tested on the Odroid-XU/XU3/XU4.

Signed-off-by: Suriyan Ramasami <suriyan.r@xxxxxxxxx>
---
Changes between versions as follows:

v2:
Try to use common code as much as possible

v1:
Initial code submission
---
 xen/arch/arm/platforms/exynos5.c | 61 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index bf4964d..12aea31 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -34,9 +34,18 @@ static bool_t secure_firmware;
 #define EXYNOS_ARM_CORE_CONFIG(_nr) (EXYNOS_ARM_CORE0_CONFIG + (0x80 * (_nr)))
 #define EXYNOS_ARM_CORE_STATUS(_nr) (EXYNOS_ARM_CORE_CONFIG(_nr) + 0x4)
 #define S5P_CORE_LOCAL_PWR_EN       0x3
+#define S5P_PMU_SPARE2              0x908
 
 #define SMC_CMD_CPU1BOOT            (-4)
 
+#define EXYNOS5800_CPUS_PER_CLUSTER 4
+
+#define EXYNOS5420_KFC_CORE_RESET0  BIT(8)
+#define EXYNOS5420_KFC_ETM_RESET0   BIT(20)
+
+#define EXYNOS5420_KFC_CORE_RESET(_nr) \
+        ((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
+
 static int exynos5_init_time(void)
 {
     uint32_t reg;
@@ -166,14 +175,23 @@ static void exynos_cpu_power_up(void __iomem *power, int 
cpu)
 static int exynos5_cpu_power_up(void __iomem *power, int cpu)
 {
     unsigned int timeout;
+    unsigned int mpidr, pcpu, pcluster, cpunr;
+
+    mpidr = cpu_logical_map(cpu);
+    pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+    pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
 
-    if ( !exynos_cpu_power_state(power, cpu) )
+    cpunr = pcpu + (pcluster * EXYNOS5800_CPUS_PER_CLUSTER);
+    dprintk(XENLOG_DEBUG, "cpu: %d pcpu: %d, cluster: %d cpunr: %d\n",
+            cpu, pcpu, pcluster, cpunr);
+
+    if ( !exynos_cpu_power_state(power, cpunr) )
     {
-        exynos_cpu_power_up(power, cpu);
+        exynos_cpu_power_up(power, cpunr);
         timeout = 10;
 
         /* wait max 10 ms until cpu is on */
-        while ( exynos_cpu_power_state(power, cpu) != S5P_CORE_LOCAL_PWR_EN )
+        while ( exynos_cpu_power_state(power, cpunr) != S5P_CORE_LOCAL_PWR_EN )
         {
             if ( timeout-- == 0 )
                 break;
@@ -186,6 +204,42 @@ static int exynos5_cpu_power_up(void __iomem *power, int 
cpu)
             dprintk(XENLOG_ERR, "CPU%d power enable failed\n", cpu);
             return -ETIMEDOUT;
         }
+
+        /*
+         * This assumes the cluster number of the big cores(Cortex A15)
+         * is 0 and the Little cores(Cortex A7) is 1.
+         * When the system was booted from the Little core,
+         * they should be reset during power up cpu.
+         * Note that the below condition is true for Odroid XU3/XU4, and
+         * false for the XU and the Exynos5800 based boards.
+         */
+        if ( pcluster &&
+             pcluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1) ) {
+            /*
+             * Before we reset the Little cores, we should wait
+             * the SPARE2 register is set to 1 because the init
+             * codes of the iROM will set the register after
+             * initialization.
+            */
+
+            /* wait max 10ms for the spare register to be set to 1 */
+            timeout = 10;
+            while ( !__raw_readl(power + S5P_PMU_SPARE2) )
+            {
+                if ( timeout-- == 0 )
+                    break;
+
+                mdelay(1);
+            }
+
+            if ( timeout == 0 )
+            {
+                dprintk(XENLOG_ERR, "CPU%d SPARE2 register wait failed\n", 
cpu);
+                return -ETIMEDOUT;
+            }
+            __raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
+                         power + EXYNOS5_SWRESET);
+        }
     }
     return 0;
 }
@@ -298,6 +352,7 @@ static const char * const exynos5250_dt_compat[] 
__initconst =
 static const char * const exynos5_dt_compat[] __initconst =
 {
     "samsung,exynos5410",
+    "samsung,exynos5800",
     NULL
 };
 
-- 
2.5.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.