diff options
| -rw-r--r-- | arch/arm/mach-keystone/keystone.c | 48 | ||||
| -rw-r--r-- | arch/arm/mach-keystone/memory.h | 24 | ||||
| -rw-r--r-- | arch/arm/mach-keystone/platsmp.c | 18 |
3 files changed, 89 insertions, 1 deletions
diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index e0b9e1b9cf30..155eb062e8d1 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
| 21 | #include <asm/mach/time.h> | 21 | #include <asm/mach/time.h> |
| 22 | #include <asm/smp_plat.h> | 22 | #include <asm/smp_plat.h> |
| 23 | #include <asm/memory.h> | ||
| 24 | |||
| 25 | #include "memory.h" | ||
| 23 | 26 | ||
| 24 | #include "keystone.h" | 27 | #include "keystone.h" |
| 25 | 28 | ||
| @@ -45,6 +48,50 @@ static void __init keystone_init(void) | |||
| 45 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 48 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
| 46 | } | 49 | } |
| 47 | 50 | ||
| 51 | static phys_addr_t keystone_virt_to_idmap(unsigned long x) | ||
| 52 | { | ||
| 53 | return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; | ||
| 54 | } | ||
| 55 | |||
| 56 | static void __init keystone_init_meminfo(void) | ||
| 57 | { | ||
| 58 | bool lpae = IS_ENABLED(CONFIG_ARM_LPAE); | ||
| 59 | bool pvpatch = IS_ENABLED(CONFIG_ARM_PATCH_PHYS_VIRT); | ||
| 60 | phys_addr_t offset = PHYS_OFFSET - KEYSTONE_LOW_PHYS_START; | ||
| 61 | phys_addr_t mem_start, mem_end; | ||
| 62 | |||
| 63 | BUG_ON(meminfo.nr_banks < 1); | ||
| 64 | mem_start = meminfo.bank[0].start; | ||
| 65 | mem_end = mem_start + meminfo.bank[0].size - 1; | ||
| 66 | |||
| 67 | /* nothing to do if we are running out of the <32-bit space */ | ||
| 68 | if (mem_start >= KEYSTONE_LOW_PHYS_START && | ||
| 69 | mem_end <= KEYSTONE_LOW_PHYS_END) | ||
| 70 | return; | ||
| 71 | |||
| 72 | if (!lpae || !pvpatch) { | ||
| 73 | pr_crit("Enable %s%s%s to run outside 32-bit space\n", | ||
| 74 | !lpae ? __stringify(CONFIG_ARM_LPAE) : "", | ||
| 75 | (!lpae && !pvpatch) ? " and " : "", | ||
| 76 | !pvpatch ? __stringify(CONFIG_ARM_PATCH_PHYS_VIRT) : ""); | ||
| 77 | } | ||
| 78 | |||
| 79 | if (mem_start < KEYSTONE_HIGH_PHYS_START || | ||
| 80 | mem_end > KEYSTONE_HIGH_PHYS_END) { | ||
| 81 | pr_crit("Invalid address space for memory (%08llx-%08llx)\n", | ||
| 82 | (u64)mem_start, (u64)mem_end); | ||
| 83 | } | ||
| 84 | |||
| 85 | offset += KEYSTONE_HIGH_PHYS_START; | ||
| 86 | __pv_phys_pfn_offset = PFN_DOWN(offset); | ||
| 87 | __pv_offset = (offset - PAGE_OFFSET); | ||
| 88 | |||
| 89 | /* Populate the arch idmap hook */ | ||
| 90 | arch_virt_to_idmap = keystone_virt_to_idmap; | ||
| 91 | |||
| 92 | pr_info("Switching to high address space at 0x%llx\n", (u64)offset); | ||
| 93 | } | ||
| 94 | |||
| 48 | static const char *keystone_match[] __initconst = { | 95 | static const char *keystone_match[] __initconst = { |
| 49 | "ti,keystone", | 96 | "ti,keystone", |
| 50 | NULL, | 97 | NULL, |
| @@ -76,4 +123,5 @@ DT_MACHINE_START(KEYSTONE, "Keystone") | |||
| 76 | .init_machine = keystone_init, | 123 | .init_machine = keystone_init, |
| 77 | .dt_compat = keystone_match, | 124 | .dt_compat = keystone_match, |
| 78 | .restart = keystone_restart, | 125 | .restart = keystone_restart, |
| 126 | .init_meminfo = keystone_init_meminfo, | ||
| 79 | MACHINE_END | 127 | MACHINE_END |
diff --git a/arch/arm/mach-keystone/memory.h b/arch/arm/mach-keystone/memory.h new file mode 100644 index 000000000000..b854fb18eef1 --- /dev/null +++ b/arch/arm/mach-keystone/memory.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2014 Texas Instruments, Inc. | ||
| 3 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | #ifndef __MEMORY_H | ||
| 10 | #define __MEMORY_H | ||
| 11 | |||
| 12 | #define MAX_PHYSMEM_BITS 36 | ||
| 13 | #define SECTION_SIZE_BITS 34 | ||
| 14 | |||
| 15 | #define KEYSTONE_LOW_PHYS_START 0x80000000ULL | ||
| 16 | #define KEYSTONE_LOW_PHYS_SIZE 0x80000000ULL /* 2G */ | ||
| 17 | #define KEYSTONE_LOW_PHYS_END (KEYSTONE_LOW_PHYS_START + \ | ||
| 18 | KEYSTONE_LOW_PHYS_SIZE - 1) | ||
| 19 | |||
| 20 | #define KEYSTONE_HIGH_PHYS_START 0x800000000ULL | ||
| 21 | #define KEYSTONE_HIGH_PHYS_SIZE 0x400000000ULL /* 16G */ | ||
| 22 | #define KEYSTONE_HIGH_PHYS_END (KEYSTONE_HIGH_PHYS_START + \ | ||
| 23 | KEYSTONE_HIGH_PHYS_SIZE - 1) | ||
| 24 | #endif /* __MEMORY_H */ | ||
diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c index 5cf0683577ea..5f46a7cf907b 100644 --- a/arch/arm/mach-keystone/platsmp.c +++ b/arch/arm/mach-keystone/platsmp.c | |||
| @@ -17,13 +17,16 @@ | |||
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | 18 | ||
| 19 | #include <asm/smp_plat.h> | 19 | #include <asm/smp_plat.h> |
| 20 | #include <asm/prom.h> | ||
| 21 | #include <asm/tlbflush.h> | ||
| 22 | #include <asm/pgtable.h> | ||
| 20 | 23 | ||
| 21 | #include "keystone.h" | 24 | #include "keystone.h" |
| 22 | 25 | ||
| 23 | static int keystone_smp_boot_secondary(unsigned int cpu, | 26 | static int keystone_smp_boot_secondary(unsigned int cpu, |
| 24 | struct task_struct *idle) | 27 | struct task_struct *idle) |
| 25 | { | 28 | { |
| 26 | unsigned long start = virt_to_phys(&secondary_startup); | 29 | unsigned long start = virt_to_idmap(&secondary_startup); |
| 27 | int error; | 30 | int error; |
| 28 | 31 | ||
| 29 | pr_debug("keystone-smp: booting cpu %d, vector %08lx\n", | 32 | pr_debug("keystone-smp: booting cpu %d, vector %08lx\n", |
| @@ -36,6 +39,19 @@ static int keystone_smp_boot_secondary(unsigned int cpu, | |||
| 36 | return error; | 39 | return error; |
| 37 | } | 40 | } |
| 38 | 41 | ||
| 42 | #ifdef CONFIG_ARM_LPAE | ||
| 43 | static void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu) | ||
| 44 | { | ||
| 45 | pgd_t *pgd0 = pgd_offset_k(0); | ||
| 46 | cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET); | ||
| 47 | local_flush_tlb_all(); | ||
| 48 | } | ||
| 49 | #else | ||
| 50 | static inline void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu) | ||
| 51 | {} | ||
| 52 | #endif | ||
| 53 | |||
| 39 | struct smp_operations keystone_smp_ops __initdata = { | 54 | struct smp_operations keystone_smp_ops __initdata = { |
| 40 | .smp_boot_secondary = keystone_smp_boot_secondary, | 55 | .smp_boot_secondary = keystone_smp_boot_secondary, |
| 56 | .smp_secondary_init = keystone_smp_secondary_initmem, | ||
| 41 | }; | 57 | }; |
