xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/1] XEN/ARM: Add Odroid-XU3/XU4 support
@ 2016-02-07 17:44 Suriyan Ramasami
  2016-02-08 15:27 ` Ian Campbell
  0 siblings, 1 reply; 3+ messages in thread
From: Suriyan Ramasami @ 2016-02-07 17:44 UTC (permalink / raw)
  To: xen-devel
  Cc: Suriyan Ramasami, julien.grall, stefano.stabellini, ian.campbell

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.

Signed-off-by: Suriyan Ramasami <suriyan.r@gmail.com>
---
 xen/arch/arm/platforms/exynos5.c | 94 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index bf4964d..60ceb2b 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -37,6 +37,15 @@ static bool_t secure_firmware;
 
 #define SMC_CMD_CPU1BOOT            (-4)
 
+#define EXYNOS5800_CPUS_PER_CLUSTER 4
+#define EXYNOS5800_NR_CLUSTERS      2
+
+#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;
@@ -163,6 +172,84 @@ static void exynos_cpu_power_up(void __iomem *power, int cpu)
                  power + EXYNOS_ARM_CORE_CONFIG(cpu));
 }
 
+static void cpu_to_pcpu(int cpu, int *pcpu, int *pcluster)
+{
+   int mpidr;
+
+   mpidr = cpu_logical_map(cpu);
+   *pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+   *pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+}
+
+static int exynos5800_cpu_power_up(void __iomem *power, int cpu)
+{
+    int timeout;
+    int pcpu, pcluster;
+    unsigned int cpunr;
+
+    cpu_to_pcpu(cpu, &pcpu, &pcluster);
+    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, cpunr);
+        timeout = 10;
+
+        /* wait max 10 ms until cpu is on */
+        while ( exynos_cpu_power_state(power, cpunr) != S5P_CORE_LOCAL_PWR_EN )
+        {
+            if ( timeout-- == 0 )
+                break;
+
+            mdelay(1);
+        }
+
+        if ( timeout == 0 )
+        {
+            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.
+         */
+        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;
+}
+
 static int exynos5_cpu_power_up(void __iomem *power, int cpu)
 {
     unsigned int timeout;
@@ -240,7 +327,10 @@ static int exynos5_cpu_up(int cpu)
         return -EFAULT;
     }
 
-    rc = exynos5_cpu_power_up(power, cpu);
+    if ( dt_machine_is_compatible("samsung,exynos5800") )
+        rc = exynos5800_cpu_power_up(power, cpu);
+    else
+        rc = exynos5_cpu_power_up(power, cpu);
     if ( rc )
     {
         iounmap(power);
@@ -298,6 +388,7 @@ static const char * const exynos5250_dt_compat[] __initconst =
 static const char * const exynos5_dt_compat[] __initconst =
 {
     "samsung,exynos5410",
+    "samsung,exynos5800",
     NULL
 };
 
@@ -318,6 +409,7 @@ PLATFORM_START(exynos5, "SAMSUNG EXYNOS5")
     .cpu_up = exynos5_cpu_up,
     .reset = exynos5_reset,
     .blacklist_dev = exynos5_blacklist_dev,
+
 PLATFORM_END
 
 /*
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-02-08 16:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-07 17:44 [PATCH v1 1/1] XEN/ARM: Add Odroid-XU3/XU4 support Suriyan Ramasami
2016-02-08 15:27 ` Ian Campbell
2016-02-08 16:54   ` Suriyan Ramasami

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).