aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Felker <dalias@libc.org>2016-03-17 19:09:37 -0400
committerRich Felker <dalias@libc.org>2016-08-04 23:29:31 -0400
commit5a846abad07f6f30adfa3e46c5c7a47d2e7b1e63 (patch)
treefc16a7c8f74a2010f0134ef3e69d20fde929bc08
parent03767daa1387f87619404bfe108ebb6aa5826e00 (diff)
sh: add support for J-Core J2 processor
At the CPU/ISA level, the J2 is compatible with SH-2, and thus the changes to add J2 support build on existing SH-2 support. However, J2 does not duplicate the memory-mapped SH-2 features like the cache interface. Instead, the cache interfaces is described in the device tree, and new code is added to be able to access the flat device tree at early boot before it is unflattened. Support is also added for receiving interrupts on trap numbers in the range 16 to 31, since the J-Core aic1 interrupt controller generates these traps. This range was unused but nominally for hardware exceptions on SH-2, and a few values in this range were used for exceptions on SH-2A, but SH-2A has its own version of the relevant code. No individual cpu subtypes are added for J2 since the intent moving forward is to represent SoCs with device tree rather than as hard-coded subtypes in the kernel. The CPU_SUBTYPE_J2 Kconfig item exists only to fit into the existing cpu selection mechanism until it is overhauled. Signed-off-by: Rich Felker <dalias@libc.org>
-rw-r--r--arch/sh/Kconfig10
-rw-r--r--arch/sh/Makefile1
-rw-r--r--arch/sh/include/asm/processor.h2
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/cpu/proc.c1
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S5
-rw-r--r--arch/sh/kernel/cpu/sh2/probe.c37
-rw-r--r--arch/sh/mm/Makefile3
-rw-r--r--arch/sh/mm/cache-j2.c65
-rw-r--r--arch/sh/mm/cache.c6
10 files changed, 127 insertions, 5 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index df6339d7bf72..2ef6f652bc50 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -186,6 +186,12 @@ config CPU_SH2A
186 select CPU_SH2 186 select CPU_SH2
187 select UNCACHED_MAPPING 187 select UNCACHED_MAPPING
188 188
189config CPU_J2
190 bool
191 select CPU_SH2
192 select OF
193 select OF_EARLY_FLATTREE
194
189config CPU_SH3 195config CPU_SH3
190 bool 196 bool
191 select CPU_HAS_INTEVT 197 select CPU_HAS_INTEVT
@@ -252,6 +258,10 @@ config CPU_SUBTYPE_SH7619
252 select CPU_SH2 258 select CPU_SH2
253 select SYS_SUPPORTS_SH_CMT 259 select SYS_SUPPORTS_SH_CMT
254 260
261config CPU_SUBTYPE_J2
262 bool "Support J2 processor"
263 select CPU_J2
264
255# SH-2A Processor Support 265# SH-2A Processor Support
256 266
257config CPU_SUBTYPE_SH7201 267config CPU_SUBTYPE_SH7201
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 3b2c8b4827d0..00476662ac2c 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -31,6 +31,7 @@ isa-y := $(isa-y)-up
31endif 31endif
32 32
33cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,) 33cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,)
34cflags-$(CONFIG_CPU_J2) := $(call cc-option,-mj2,)
34cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \ 35cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \
35 $(call cc-option,-m2a-nofpu,) \ 36 $(call cc-option,-m2a-nofpu,) \
36 $(call cc-option,-m4-nofpu,) 37 $(call cc-option,-m4-nofpu,)
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 1506897648aa..f9a09942a32d 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -15,7 +15,7 @@
15 */ 15 */
16enum cpu_type { 16enum cpu_type {
17 /* SH-2 types */ 17 /* SH-2 types */
18 CPU_SH7619, 18 CPU_SH7619, CPU_J2,
19 19
20 /* SH-2A types */ 20 /* SH-2A types */
21 CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_SH7264, CPU_SH7269, 21 CPU_SH7201, CPU_SH7203, CPU_SH7206, CPU_SH7263, CPU_SH7264, CPU_SH7269,
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index bfd9e2798008..c8b3be1b54e6 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -106,7 +106,7 @@ void __attribute__ ((weak)) l2_cache_init(void)
106/* 106/*
107 * Generic first-level cache init 107 * Generic first-level cache init
108 */ 108 */
109#ifdef CONFIG_SUPERH32 109#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2)
110static void cache_init(void) 110static void cache_init(void)
111{ 111{
112 unsigned long ccr, flags; 112 unsigned long ccr, flags;
diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c
index 9e6624c9108b..4df4b284f591 100644
--- a/arch/sh/kernel/cpu/proc.c
+++ b/arch/sh/kernel/cpu/proc.c
@@ -27,6 +27,7 @@ static const char *cpu_name[] = {
27 [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", 27 [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
28 [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", 28 [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
29 [CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734", 29 [CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734",
30 [CPU_J2] = "J2",
30 [CPU_SH_NONE] = "Unknown" 31 [CPU_SH_NONE] = "Unknown"
31}; 32};
32 33
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index a1505956ef28..16bde0efaca3 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -147,6 +147,11 @@ ENTRY(exception_handler)
147 mov #31,r8 147 mov #31,r8
148 cmp/hs r8,r9 148 cmp/hs r8,r9
149 bt trap_entry ! 64 > vec >= 31 is trap 149 bt trap_entry ! 64 > vec >= 31 is trap
150#ifdef CONFIG_CPU_J2
151 mov #16,r8
152 cmp/hs r8,r9
153 bt interrupt_entry ! 31 > vec >= 16 is interrupt
154#endif
150 155
151 mov.l 4f,r8 156 mov.l 4f,r8
152 mov r9,r4 157 mov r9,r4
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index 6c687ae812ef..152184007964 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -10,10 +10,27 @@
10 * for more details. 10 * for more details.
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/of_fdt.h>
14#include <linux/smp.h>
15#include <linux/io.h>
13#include <asm/processor.h> 16#include <asm/processor.h>
14#include <asm/cache.h> 17#include <asm/cache.h>
15 18
16void cpu_probe(void) 19#if defined(CONFIG_CPU_J2)
20extern u32 __iomem *j2_ccr_base;
21static int __init scan_cache(unsigned long node, const char *uname,
22 int depth, void *data)
23{
24 if (!of_flat_dt_is_compatible(node, "jcore,cache"))
25 return 0;
26
27 j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node);
28
29 return 1;
30}
31#endif
32
33void __ref cpu_probe(void)
17{ 34{
18#if defined(CONFIG_CPU_SUBTYPE_SH7619) 35#if defined(CONFIG_CPU_SUBTYPE_SH7619)
19 boot_cpu_data.type = CPU_SH7619; 36 boot_cpu_data.type = CPU_SH7619;
@@ -24,10 +41,28 @@ void cpu_probe(void)
24 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; 41 boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
25 boot_cpu_data.dcache.flags = 0; 42 boot_cpu_data.dcache.flags = 0;
26#endif 43#endif
44
45#if defined(CONFIG_CPU_J2)
46 unsigned cpu = hard_smp_processor_id();
47 if (cpu == 0) of_scan_flat_dt(scan_cache, NULL);
48 if (j2_ccr_base) __raw_writel(0x80000303, j2_ccr_base + 4*cpu);
49 if (cpu != 0) return;
50 boot_cpu_data.type = CPU_J2;
51
52 /* These defaults are appropriate for the original/current
53 * J2 cache. Once there is a proper framework for getting cache
54 * info from device tree, we should switch to that. */
55 boot_cpu_data.dcache.ways = 1;
56 boot_cpu_data.dcache.sets = 256;
57 boot_cpu_data.dcache.entry_shift = 5;
58 boot_cpu_data.dcache.linesz = 32;
59 boot_cpu_data.dcache.flags = 0;
60#else
27 /* 61 /*
28 * SH-2 doesn't have separate caches 62 * SH-2 doesn't have separate caches
29 */ 63 */
30 boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; 64 boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
65#endif
31 boot_cpu_data.icache = boot_cpu_data.dcache; 66 boot_cpu_data.icache = boot_cpu_data.dcache;
32 boot_cpu_data.family = CPU_FAMILY_SH2; 67 boot_cpu_data.family = CPU_FAMILY_SH2;
33} 68}
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index cee6b9999d86..92c3bd96aee5 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -4,7 +4,8 @@
4 4
5obj-y := alignment.o cache.o init.o consistent.o mmap.o 5obj-y := alignment.o cache.o init.o consistent.o mmap.o
6 6
7cacheops-$(CONFIG_CPU_SH2) := cache-sh2.o 7cacheops-$(CONFIG_CPU_J2) := cache-j2.o
8cacheops-$(CONFIG_CPU_SUBTYPE_SH7619) := cache-sh2.o
8cacheops-$(CONFIG_CPU_SH2A) := cache-sh2a.o 9cacheops-$(CONFIG_CPU_SH2A) := cache-sh2a.o
9cacheops-$(CONFIG_CPU_SH3) := cache-sh3.o 10cacheops-$(CONFIG_CPU_SH3) := cache-sh3.o
10cacheops-$(CONFIG_CPU_SH4) := cache-sh4.o flush-sh4.o 11cacheops-$(CONFIG_CPU_SH4) := cache-sh4.o flush-sh4.o
diff --git a/arch/sh/mm/cache-j2.c b/arch/sh/mm/cache-j2.c
new file mode 100644
index 000000000000..391698bcac5b
--- /dev/null
+++ b/arch/sh/mm/cache-j2.c
@@ -0,0 +1,65 @@
1/*
2 * arch/sh/mm/cache-j2.c
3 *
4 * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
5 *
6 * Released under the terms of the GNU GPL v2.0.
7 */
8
9#include <linux/init.h>
10#include <linux/mm.h>
11#include <linux/cpumask.h>
12
13#include <asm/cache.h>
14#include <asm/addrspace.h>
15#include <asm/processor.h>
16#include <asm/cacheflush.h>
17#include <asm/io.h>
18
19#define ICACHE_ENABLE 0x1
20#define DCACHE_ENABLE 0x2
21#define CACHE_ENABLE (ICACHE_ENABLE | DCACHE_ENABLE)
22#define ICACHE_FLUSH 0x100
23#define DCACHE_FLUSH 0x200
24#define CACHE_FLUSH (ICACHE_FLUSH | DCACHE_FLUSH)
25
26u32 __iomem *j2_ccr_base;
27
28static void j2_flush_icache(void *args)
29{
30 unsigned cpu;
31 for_each_possible_cpu(cpu)
32 __raw_writel(CACHE_ENABLE | ICACHE_FLUSH, j2_ccr_base + cpu);
33}
34
35static void j2_flush_dcache(void *args)
36{
37 unsigned cpu;
38 for_each_possible_cpu(cpu)
39 __raw_writel(CACHE_ENABLE | DCACHE_FLUSH, j2_ccr_base + cpu);
40}
41
42static void j2_flush_both(void *args)
43{
44 unsigned cpu;
45 for_each_possible_cpu(cpu)
46 __raw_writel(CACHE_ENABLE | CACHE_FLUSH, j2_ccr_base + cpu);
47}
48
49void __init j2_cache_init(void)
50{
51 if (!j2_ccr_base)
52 return;
53
54 local_flush_cache_all = j2_flush_both;
55 local_flush_cache_mm = j2_flush_both;
56 local_flush_cache_dup_mm = j2_flush_both;
57 local_flush_cache_page = j2_flush_both;
58 local_flush_cache_range = j2_flush_both;
59 local_flush_dcache_page = j2_flush_dcache;
60 local_flush_icache_range = j2_flush_icache;
61 local_flush_icache_page = j2_flush_icache;
62 local_flush_cache_sigtramp = j2_flush_icache;
63
64 pr_info("Initial J2 CCR is %.8x\n", __raw_readl(j2_ccr_base));
65}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 776d664a40c5..70cc52f2fab8 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -309,7 +309,11 @@ void __init cpu_cache_init(void)
309 if (unlikely(cache_disabled)) 309 if (unlikely(cache_disabled))
310 goto skip; 310 goto skip;
311 311
312 if (boot_cpu_data.family == CPU_FAMILY_SH2) { 312 if (boot_cpu_data.type == CPU_J2) {
313 extern void __weak j2_cache_init(void);
314
315 j2_cache_init();
316 } else if (boot_cpu_data.family == CPU_FAMILY_SH2) {
313 extern void __weak sh2_cache_init(void); 317 extern void __weak sh2_cache_init(void);
314 318
315 sh2_cache_init(); 319 sh2_cache_init();