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

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



On Sun, 2016-02-07 at 09:44 -0800, Suriyan Ramasami wrote:
> 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@xxxxxxxxx>
> ---
> Â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;
> +ÂÂÂÂÂÂÂÂ}

Up to here this is the same as exynos5_cpu_power_up.

I think either of these two approaches would be acceptable to reduce the
duplication either:

move the above into a common helper called from both here and
exynos5_cpu_power_up

or

move the remainder of this function into a exynos5800_cluster_reset (or
would it be better await_reset?) function and call that from exynos5_cpu_up
after the call to exynos5_cpu_power_up when the compat string matches.

I think I have a light preference for the second option.


> +
> +ÂÂÂÂÂÂÂÂ/*
> +ÂÂÂÂÂÂÂÂÂ* 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.

If you have a reference (e.g. a URL) for this that would be useful to
include (but don't worry if there isn't one).

> +ÂÂÂÂÂÂÂÂÂÂÂÂ*/
> +
> +ÂÂÂÂÂÂÂÂÂÂÂÂ/* 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
> Â
> Â/*
_______________________________________________
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®.