[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 1/1] Support Odroid-XU board (Exynos 5410)
XEN/ARM: Add support for the Odroid-XU board. The Odroid-XU from hardkernel is an Exynos 5410 based board. This patch adds support to the above said board. Signed-off-by: Suriyan Ramasami <suriyan.r@xxxxxxxxx> --- Changes between versions as follows: v4: a. Lots of Xen coding style changes. b. Directly assign cpu_up_send_sgi for 5250. c. S5P_PA_SYSRAM renamed to EXYNOS5250_PA_SYSRAM so it is clear that newer platforms should use the device tree for information. d. Use __raw_readl and _raw_writel instead of readl and writel e. Leave function names consistent with what Linux uses so that it avoids confusion and is easier to backport in the future. f. Remove "samsung,exynos5422-pmu" as no such thing exists. g. Use XENLOG_DEBUG instead of XENLOG_INFO for power_base_address. h. iounmap(power) in the failure case. i. As its generic, call the new platform exynos5. v3: a. Separate commit message and change log. b. Define odroid-xu as a separate platform API. c. Use mainline linux's way of retrieving sysram from DT. d. Use mainline linux's way of bringing up secondary CPUs. e. Keep the #defines in the local C file. f. Bringing up newer Exynos platforms should be easier. v2: a. Set startup address in exynos5_smp_init() only once. b. Turn on power to each core in exynos5_cpu_up(). c. Create single PLATFORM with smp_init, and cpu_up which dispatches to correct code. d. Check return code of io_remap for power. e. Use read* write* calls for MMIO mapped addresses. f. Xen coding style changes. v1: Add Odroid-XU board support --- xen/arch/arm/platforms/exynos5.c | 169 +++++++++++++++++++++++++++++--- xen/include/asm-arm/platforms/exynos5.h | 2 +- 2 files changed, 158 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c index b65c2c2..6c28279 100644 --- a/xen/arch/arm/platforms/exynos5.c +++ b/xen/arch/arm/platforms/exynos5.c @@ -23,10 +23,16 @@ #include <xen/domain_page.h> #include <xen/mm.h> #include <xen/vmap.h> +#include <xen/delay.h> #include <asm/platforms/exynos5.h> #include <asm/platform.h> #include <asm/io.h> +#define EXYNOS_ARM_CORE0_CONFIG 0x2000 +#define EXYNOS_ARM_CORE_CONFIG(_nr) (0x80 * (_nr)) +#define EXYNOS_ARM_CORE_STATUS(_nr) (EXYNOS_ARM_CORE_CONFIG(_nr) + 0x4) +#define S5P_CORE_LOCAL_PWR_EN 0x3 + static int exynos5_init_time(void) { uint32_t reg; @@ -51,7 +57,7 @@ static int exynos5_init_time(void) } /* Additional mappings for dom0 (Not in the DTS) */ -static int exynos5_specific_mapping(struct domain *d) +static int exynos5250_specific_mapping(struct domain *d) { /* Map the chip ID */ map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID), 1, @@ -64,11 +70,11 @@ static int exynos5_specific_mapping(struct domain *d) return 0; } -static int __init exynos5_smp_init(void) +static int __init exynos_smp_init(paddr_t pa_sysram) { void __iomem *sysram; - sysram = ioremap_nocache(S5P_PA_SYSRAM, PAGE_SIZE); + sysram = ioremap_nocache(pa_sysram, PAGE_SIZE); if ( !sysram ) { dprintk(XENLOG_ERR, "Unable to map exynos5 MMIO\n"); @@ -84,6 +90,129 @@ static int __init exynos5_smp_init(void) return 0; } +static int __init exynos5250_smp_init(void) +{ + return exynos_smp_init(EXYNOS5250_PA_SYSRAM); +} + +static int __init exynos5_smp_init(void) +{ + struct dt_device_node *node; + u64 sysram_ns_base_addr; + u64 size; + int rc; + + node = dt_find_compatible_node(NULL, NULL, "samsung,exynos4210-sysram-ns"); + if ( !node ) + { + dprintk(XENLOG_ERR, "samsung,exynos4210-sysram-ns missing in DT\n"); + return -ENXIO; + } + + rc = dt_device_get_address(node, 0, &sysram_ns_base_addr, &size); + if ( rc ) + { + dprintk(XENLOG_ERR, "Error in \"samsung,exynos4210-sysram-ns\"\n"); + return -ENXIO; + } + + dprintk(XENLOG_INFO, "sysram_ns_base_addr: %016llx size: %016llx\n", + sysram_ns_base_addr, size); + + return exynos_smp_init(sysram_ns_base_addr + 0x1c); +} + +static int exynos_cpu_power_state(void __iomem *power, int cpu) +{ + return __raw_readl(power + EXYNOS_ARM_CORE_STATUS(cpu)) & + S5P_CORE_LOCAL_PWR_EN; +} + +static void exynos_cpu_power_up(void __iomem *power, int cpu) +{ + __raw_writel(S5P_CORE_LOCAL_PWR_EN, + power + EXYNOS_ARM_CORE_CONFIG(cpu)); +} + +static int exynos5_cpu_power_up(void __iomem *power, int cpu) +{ + unsigned int timeout; + + if ( !exynos_cpu_power_state(power, cpu) ) + { + exynos_cpu_power_up(power, cpu); + timeout = 10; + + /* wait max 10 ms until cpu is on */ + while ( exynos_cpu_power_state(power, cpu) != S5P_CORE_LOCAL_PWR_EN ) + { + if ( timeout-- == 0 ) + break; + + mdelay(1); + } + + if ( timeout == 0 ) + { + dprintk(XENLOG_ERR, "CPU%d power enable failed", cpu); + return -ETIMEDOUT; + } + } + return 0; +} + +static int exynos5_cpu_up(int cpu) +{ + static const struct dt_device_match exynos_dt_pmu_matches[] __initconst = + { + DT_MATCH_COMPATIBLE("samsung,exynos5250-pmu"), + DT_MATCH_COMPATIBLE("samsung,exynos5410-pmu"), + DT_MATCH_COMPATIBLE("samsung,exynos5420-pmu"), + { /*sentinel*/ }, + }; + void __iomem *power; + u64 power_base_addr; + u64 size; + struct dt_device_node *node; + int rc; + + node = dt_find_matching_node(NULL, exynos_dt_pmu_matches); + if ( !node ) + { + dprintk(XENLOG_ERR, "samsung,exynos5XXX-pmu missing in DT\n"); + return -ENXIO; + } + + rc = dt_device_get_address(node, 0, &power_base_addr, &size); + if ( rc ) + { + dprintk(XENLOG_ERR, "Error in \"samsung,exynos5XXXX-pmu\"\n"); + return -ENXIO; + } + + dprintk(XENLOG_DEBUG, "power_base_addr: %016llx size: %016llx\n", + power_base_addr, size); + + power = ioremap_nocache(power_base_addr + + EXYNOS_ARM_CORE0_CONFIG, PAGE_SIZE); + if ( !power ) + { + dprintk(XENLOG_ERR, "Unable to map power MMIO\n"); + return -EFAULT; + } + + rc = exynos5_cpu_power_up(power, cpu); + if ( rc ) + { + iounmap(power); + return -ETIMEDOUT; + } + + iounmap(power); + + return cpu_up_send_sgi(cpu); +} + static void exynos5_reset(void) { void __iomem *pmu; @@ -98,15 +227,10 @@ static void exynos5_reset(void) } writel(1, pmu + EXYNOS5_SWRESET); + iounmap(pmu); } -static const char * const exynos5_dt_compat[] __initconst = -{ - "samsung,exynos5250", - NULL -}; - static const struct dt_device_match exynos5_blacklist_dev[] __initconst = { /* Multi core Timer @@ -117,12 +241,33 @@ static const struct dt_device_match exynos5_blacklist_dev[] __initconst = { /* sentinel */ }, }; +static const char * const exynos5250_dt_compat[] __initconst = +{ + "samsung,exynos5250", + NULL +}; + +static const char * const exynos5410_dt_compat[] __initconst = +{ + "samsung,exynos5410", + NULL +}; + +PLATFORM_START(exynos5250, "SAMSUNG EXYNOS5250") + .compatible = exynos5250_dt_compat, + .init_time = exynos5_init_time, + .specific_mapping = exynos5250_specific_mapping, + .smp_init = exynos5250_smp_init, + .cpu_up = cpu_up_send_sgi, + .reset = exynos5_reset, + .blacklist_dev = exynos5_blacklist_dev, +PLATFORM_END + PLATFORM_START(exynos5, "SAMSUNG EXYNOS5") - .compatible = exynos5_dt_compat, + .compatible = exynos5410_dt_compat, .init_time = exynos5_init_time, - .specific_mapping = exynos5_specific_mapping, .smp_init = exynos5_smp_init, - .cpu_up = cpu_up_send_sgi, + .cpu_up = exynos5_cpu_up, .reset = exynos5_reset, .blacklist_dev = exynos5_blacklist_dev, PLATFORM_END diff --git a/xen/include/asm-arm/platforms/exynos5.h b/xen/include/asm-arm/platforms/exynos5.h index ea941e7..7676313 100644 --- a/xen/include/asm-arm/platforms/exynos5.h +++ b/xen/include/asm-arm/platforms/exynos5.h @@ -12,7 +12,7 @@ #define EXYNOS5_SWRESET 0x0400 /* Relative to PA_PMU */ -#define S5P_PA_SYSRAM 0x02020000 +#define EXYNOS5250_PA_SYSRAM 0x02020000 #endif /* __ASM_ARM_PLATFORMS_EXYNOS5_H */ /* -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |