diff options
Diffstat (limited to 'kernel/arch/arm/mach-keystone')
-rw-r--r-- | kernel/arch/arm/mach-keystone/Kconfig | 16 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/Makefile | 9 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/Makefile.boot | 1 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/keystone.c | 119 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/keystone.h | 24 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/memory.h | 24 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/platsmp.c | 57 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/pm_domain.c | 80 | ||||
-rw-r--r-- | kernel/arch/arm/mach-keystone/smc.S | 28 |
9 files changed, 358 insertions, 0 deletions
diff --git a/kernel/arch/arm/mach-keystone/Kconfig b/kernel/arch/arm/mach-keystone/Kconfig new file mode 100644 index 000000000..ea955f6db --- /dev/null +++ b/kernel/arch/arm/mach-keystone/Kconfig @@ -0,0 +1,16 @@ +config ARCH_KEYSTONE + bool "Texas Instruments Keystone Devices" + depends on ARCH_MULTI_V7 + depends on ARM_PATCH_PHYS_VIRT + select ARM_GIC + select HAVE_ARM_ARCH_TIMER + select CLKSRC_MMIO + select ARM_ERRATA_798181 if SMP + select COMMON_CLK_KEYSTONE + select ARCH_SUPPORTS_BIG_ENDIAN + select ZONE_DMA if ARM_LPAE + select MIGHT_HAVE_PCI + select PCI_DOMAINS if PCI + help + Support for boards based on the Texas Instruments Keystone family of + SoCs. diff --git a/kernel/arch/arm/mach-keystone/Makefile b/kernel/arch/arm/mach-keystone/Makefile new file mode 100644 index 000000000..25d92396f --- /dev/null +++ b/kernel/arch/arm/mach-keystone/Makefile @@ -0,0 +1,9 @@ +obj-y := keystone.o smc.o + +plus_sec := $(call as-instr,.arch_extension sec,+sec) +AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) + +obj-$(CONFIG_SMP) += platsmp.o + +# PM domain driver for Keystone SOCs +obj-$(CONFIG_ARCH_KEYSTONE) += pm_domain.o diff --git a/kernel/arch/arm/mach-keystone/Makefile.boot b/kernel/arch/arm/mach-keystone/Makefile.boot new file mode 100644 index 000000000..f3835c43a --- /dev/null +++ b/kernel/arch/arm/mach-keystone/Makefile.boot @@ -0,0 +1 @@ +zreladdr-y := 0x80008000 diff --git a/kernel/arch/arm/mach-keystone/keystone.c b/kernel/arch/arm/mach-keystone/keystone.c new file mode 100644 index 000000000..066208758 --- /dev/null +++ b/kernel/arch/arm/mach-keystone/keystone.c @@ -0,0 +1,119 @@ +/* + * Keystone2 based boards and SOC related code. + * + * Copyright 2013 Texas Instruments, Inc. + * Cyril Chemparathy <cyril@ti.com> + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ +#include <linux/io.h> +#include <linux/of.h> +#include <linux/init.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/memblock.h> + +#include <asm/setup.h> +#include <asm/mach/map.h> +#include <asm/mach/arch.h> +#include <asm/mach/time.h> +#include <asm/smp_plat.h> +#include <asm/memory.h> + +#include "memory.h" + +#include "keystone.h" + +static struct notifier_block platform_nb; +static unsigned long keystone_dma_pfn_offset __read_mostly; + +static int keystone_platform_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct device *dev = data; + + if (event != BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_DONE; + + if (!dev) + return NOTIFY_BAD; + + if (!dev->of_node) { + dev->dma_pfn_offset = keystone_dma_pfn_offset; + dev_err(dev, "set dma_pfn_offset%08lx\n", + dev->dma_pfn_offset); + } + return NOTIFY_OK; +} + +static void __init keystone_init(void) +{ + keystone_pm_runtime_init(); + if (platform_nb.notifier_call) + bus_register_notifier(&platform_bus_type, &platform_nb); + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static phys_addr_t keystone_virt_to_idmap(unsigned long x) +{ + return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; +} + +static void __init keystone_init_meminfo(void) +{ + bool lpae = IS_ENABLED(CONFIG_ARM_LPAE); + bool pvpatch = IS_ENABLED(CONFIG_ARM_PATCH_PHYS_VIRT); + phys_addr_t offset = PHYS_OFFSET - KEYSTONE_LOW_PHYS_START; + phys_addr_t mem_start, mem_end; + + mem_start = memblock_start_of_DRAM(); + mem_end = memblock_end_of_DRAM(); + + /* nothing to do if we are running out of the <32-bit space */ + if (mem_start >= KEYSTONE_LOW_PHYS_START && + mem_end <= KEYSTONE_LOW_PHYS_END) + return; + + if (!lpae || !pvpatch) { + pr_crit("Enable %s%s%s to run outside 32-bit space\n", + !lpae ? __stringify(CONFIG_ARM_LPAE) : "", + (!lpae && !pvpatch) ? " and " : "", + !pvpatch ? __stringify(CONFIG_ARM_PATCH_PHYS_VIRT) : ""); + } + + if (mem_start < KEYSTONE_HIGH_PHYS_START || + mem_end > KEYSTONE_HIGH_PHYS_END) { + pr_crit("Invalid address space for memory (%08llx-%08llx)\n", + (u64)mem_start, (u64)mem_end); + } + + offset += KEYSTONE_HIGH_PHYS_START; + __pv_phys_pfn_offset = PFN_DOWN(offset); + __pv_offset = (offset - PAGE_OFFSET); + + /* Populate the arch idmap hook */ + arch_virt_to_idmap = keystone_virt_to_idmap; + platform_nb.notifier_call = keystone_platform_notifier; + keystone_dma_pfn_offset = PFN_DOWN(KEYSTONE_HIGH_PHYS_START - + KEYSTONE_LOW_PHYS_START); + + pr_info("Switching to high address space at 0x%llx\n", (u64)offset); +} + +static const char *const keystone_match[] __initconst = { + "ti,keystone", + NULL, +}; + +DT_MACHINE_START(KEYSTONE, "Keystone") +#if defined(CONFIG_ZONE_DMA) && defined(CONFIG_ARM_LPAE) + .dma_zone_size = SZ_2G, +#endif + .smp = smp_ops(keystone_smp_ops), + .init_machine = keystone_init, + .dt_compat = keystone_match, + .init_meminfo = keystone_init_meminfo, +MACHINE_END diff --git a/kernel/arch/arm/mach-keystone/keystone.h b/kernel/arch/arm/mach-keystone/keystone.h new file mode 100644 index 000000000..cd04a1c14 --- /dev/null +++ b/kernel/arch/arm/mach-keystone/keystone.h @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Texas Instruments, Inc. + * Cyril Chemparathy <cyril@ti.com> + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#ifndef __KEYSTONE_H__ +#define __KEYSTONE_H__ + +#define KEYSTONE_MON_CPU_UP_IDX 0x00 + +#ifndef __ASSEMBLER__ + +extern struct smp_operations keystone_smp_ops; +extern void secondary_startup(void); +extern u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr); +extern int keystone_pm_runtime_init(void); + +#endif /* __ASSEMBLER__ */ +#endif /* __KEYSTONE_H__ */ diff --git a/kernel/arch/arm/mach-keystone/memory.h b/kernel/arch/arm/mach-keystone/memory.h new file mode 100644 index 000000000..b854fb18e --- /dev/null +++ b/kernel/arch/arm/mach-keystone/memory.h @@ -0,0 +1,24 @@ +/* + * Copyright 2014 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ +#ifndef __MEMORY_H +#define __MEMORY_H + +#define MAX_PHYSMEM_BITS 36 +#define SECTION_SIZE_BITS 34 + +#define KEYSTONE_LOW_PHYS_START 0x80000000ULL +#define KEYSTONE_LOW_PHYS_SIZE 0x80000000ULL /* 2G */ +#define KEYSTONE_LOW_PHYS_END (KEYSTONE_LOW_PHYS_START + \ + KEYSTONE_LOW_PHYS_SIZE - 1) + +#define KEYSTONE_HIGH_PHYS_START 0x800000000ULL +#define KEYSTONE_HIGH_PHYS_SIZE 0x400000000ULL /* 16G */ +#define KEYSTONE_HIGH_PHYS_END (KEYSTONE_HIGH_PHYS_START + \ + KEYSTONE_HIGH_PHYS_SIZE - 1) +#endif /* __MEMORY_H */ diff --git a/kernel/arch/arm/mach-keystone/platsmp.c b/kernel/arch/arm/mach-keystone/platsmp.c new file mode 100644 index 000000000..5f46a7cf9 --- /dev/null +++ b/kernel/arch/arm/mach-keystone/platsmp.c @@ -0,0 +1,57 @@ +/* + * Keystone SOC SMP platform code + * + * Copyright 2013 Texas Instruments, Inc. + * Cyril Chemparathy <cyril@ti.com> + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * Based on platsmp.c, Copyright (C) 2002 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/io.h> + +#include <asm/smp_plat.h> +#include <asm/prom.h> +#include <asm/tlbflush.h> +#include <asm/pgtable.h> + +#include "keystone.h" + +static int keystone_smp_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + unsigned long start = virt_to_idmap(&secondary_startup); + int error; + + pr_debug("keystone-smp: booting cpu %d, vector %08lx\n", + cpu, start); + + error = keystone_cpu_smc(KEYSTONE_MON_CPU_UP_IDX, cpu, start); + if (error) + pr_err("CPU %d bringup failed with %d\n", cpu, error); + + return error; +} + +#ifdef CONFIG_ARM_LPAE +static void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu) +{ + pgd_t *pgd0 = pgd_offset_k(0); + cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET); + local_flush_tlb_all(); +} +#else +static inline void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu) +{} +#endif + +struct smp_operations keystone_smp_ops __initdata = { + .smp_boot_secondary = keystone_smp_boot_secondary, + .smp_secondary_init = keystone_smp_secondary_initmem, +}; diff --git a/kernel/arch/arm/mach-keystone/pm_domain.c b/kernel/arch/arm/mach-keystone/pm_domain.c new file mode 100644 index 000000000..41bebfd29 --- /dev/null +++ b/kernel/arch/arm/mach-keystone/pm_domain.c @@ -0,0 +1,80 @@ +/* + * PM domain driver for Keystone2 devices + * + * Copyright 2013 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * Based on Kevins work on DAVINCI SOCs + * Kevin Hilman <khilman@linaro.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/pm_runtime.h> +#include <linux/pm_clock.h> +#include <linux/platform_device.h> +#include <linux/clk-provider.h> +#include <linux/of.h> + +#ifdef CONFIG_PM +static int keystone_pm_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = pm_clk_suspend(dev); + if (ret) { + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +static int keystone_pm_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + pm_clk_resume(dev); + + return pm_generic_runtime_resume(dev); +} +#endif + +static struct dev_pm_domain keystone_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend, + keystone_pm_runtime_resume, NULL) + USE_PLATFORM_PM_SLEEP_OPS + }, +}; + +static struct pm_clk_notifier_block platform_domain_notifier = { + .pm_domain = &keystone_pm_domain, +}; + +static const struct of_device_id of_keystone_table[] = { + {.compatible = "ti,keystone"}, + { /* end of list */ }, +}; + +int __init keystone_pm_runtime_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, of_keystone_table); + if (!np) + return 0; + + pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier); + + return 0; +} diff --git a/kernel/arch/arm/mach-keystone/smc.S b/kernel/arch/arm/mach-keystone/smc.S new file mode 100644 index 000000000..d15de8179 --- /dev/null +++ b/kernel/arch/arm/mach-keystone/smc.S @@ -0,0 +1,28 @@ +/* + * Keystone Secure APIs + * + * Copyright (C) 2013 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shilimkar@ti.com> + * + * This program is free software,you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/linkage.h> + +/** + * u32 keystone_cpu_smc(u32 command, u32 cpu, u32 addr) + * + * Low level CPU monitor API + * @command: Monitor command. + * @cpu: CPU Number + * @addr: Kernel jump address for boot CPU + * + * Return: Non zero value on failure + */ +ENTRY(keystone_cpu_smc) + stmfd sp!, {r4-r11, lr} + smc #0 + ldmfd sp!, {r4-r11, pc} +ENDPROC(keystone_cpu_smc) |