summaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorRich Felker <dalias@libc.org>2016-03-17 23:09:37 +0000
committerRich Felker <dalias@libc.org>2016-08-05 03:29:31 +0000
commit5a846abad07f6f30adfa3e46c5c7a47d2e7b1e63 (patch)
treefc16a7c8f74a2010f0134ef3e69d20fde929bc08 /arch/sh/kernel
parent03767daa1387f87619404bfe108ebb6aa5826e00 (diff)
downloadlinux-stable-5a846abad07f6f30adfa3e46c5c7a47d2e7b1e63.tar.gz
linux-stable-5a846abad07f6f30adfa3e46c5c7a47d2e7b1e63.tar.bz2
linux-stable-5a846abad07f6f30adfa3e46c5c7a47d2e7b1e63.zip
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>
Diffstat (limited to 'arch/sh/kernel')
-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
4 files changed, 43 insertions, 2 deletions
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)
/*
* Generic first-level cache init
*/
-#ifdef CONFIG_SUPERH32
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_CPU_J2)
static void cache_init(void)
{
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[] = {
[CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
[CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
[CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734",
+ [CPU_J2] = "J2",
[CPU_SH_NONE] = "Unknown"
};
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)
mov #31,r8
cmp/hs r8,r9
bt trap_entry ! 64 > vec >= 31 is trap
+#ifdef CONFIG_CPU_J2
+ mov #16,r8
+ cmp/hs r8,r9
+ bt interrupt_entry ! 31 > vec >= 16 is interrupt
+#endif
mov.l 4f,r8
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 @@
* for more details.
*/
#include <linux/init.h>
+#include <linux/of_fdt.h>
+#include <linux/smp.h>
+#include <linux/io.h>
#include <asm/processor.h>
#include <asm/cache.h>
-void cpu_probe(void)
+#if defined(CONFIG_CPU_J2)
+extern u32 __iomem *j2_ccr_base;
+static int __init scan_cache(unsigned long node, const char *uname,
+ int depth, void *data)
+{
+ if (!of_flat_dt_is_compatible(node, "jcore,cache"))
+ return 0;
+
+ j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node);
+
+ return 1;
+}
+#endif
+
+void __ref cpu_probe(void)
{
#if defined(CONFIG_CPU_SUBTYPE_SH7619)
boot_cpu_data.type = CPU_SH7619;
@@ -24,10 +41,28 @@ void cpu_probe(void)
boot_cpu_data.dcache.linesz = L1_CACHE_BYTES;
boot_cpu_data.dcache.flags = 0;
#endif
+
+#if defined(CONFIG_CPU_J2)
+ unsigned cpu = hard_smp_processor_id();
+ if (cpu == 0) of_scan_flat_dt(scan_cache, NULL);
+ if (j2_ccr_base) __raw_writel(0x80000303, j2_ccr_base + 4*cpu);
+ if (cpu != 0) return;
+ boot_cpu_data.type = CPU_J2;
+
+ /* These defaults are appropriate for the original/current
+ * J2 cache. Once there is a proper framework for getting cache
+ * info from device tree, we should switch to that. */
+ boot_cpu_data.dcache.ways = 1;
+ boot_cpu_data.dcache.sets = 256;
+ boot_cpu_data.dcache.entry_shift = 5;
+ boot_cpu_data.dcache.linesz = 32;
+ boot_cpu_data.dcache.flags = 0;
+#else
/*
* SH-2 doesn't have separate caches
*/
boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
+#endif
boot_cpu_data.icache = boot_cpu_data.dcache;
boot_cpu_data.family = CPU_FAMILY_SH2;
}