diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-27 21:55:04 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-27 21:55:04 +0200 |
commit | 2b9d1c050d291693f257c98605028325f8146c84 (patch) | |
tree | 756d061271ae942141aaecd8656b035f562f4906 /arch | |
parent | Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm6... (diff) | |
parent | ARM: 8042/1: iwmmxt: allow to build iWMMXt on Marvell PJ4B (diff) | |
download | linux-2b9d1c050d291693f257c98605028325f8146c84.tar.xz linux-2b9d1c050d291693f257c98605028325f8146c84.zip |
Merge branch 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull arm fixes from Russell King:
"A number of fixes for the PJ4/iwmmxt changes which arm-soc forced me
to take during the merge window. This stuff should have been better
tested and sorted out *before* the merge window"
* 'fixes' of git://ftp.arm.linux.org.uk/~rmk/linux-arm:
ARM: 8042/1: iwmmxt: allow to build iWMMXt on Marvell PJ4B
ARM: 8041/1: pj4: fix cpu_is_pj4 check
ARM: 8040/1: pj4: properly detect existence of iWMMXt coprocessor
ARM: 8039/1: pj4: enable iWMMXt only if CONFIG_IWMMXT is set
ARM: 8038/1: iwmmxt: explicitly check for supported architectures
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/include/asm/cputype.h | 14 | ||||
-rw-r--r-- | arch/arm/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/kernel/iwmmxt.S | 8 | ||||
-rw-r--r-- | arch/arm/kernel/pj4-cp0.c | 42 |
5 files changed, 56 insertions, 15 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9916e4d206a3..db3c5414223e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1111,9 +1111,9 @@ config ARM_NR_BANKS default 8 config IWMMXT - bool "Enable iWMMXt support" if !CPU_PJ4 - depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 - default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 + bool "Enable iWMMXt support" + depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B + default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index c651e3b26ec7..4764344367d4 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -222,22 +222,22 @@ static inline int cpu_is_xsc3(void) #endif /* - * Marvell's PJ4 core is based on V7 version. It has some modification - * for coprocessor setting. For this reason, we need a way to distinguish - * it. + * Marvell's PJ4 and PJ4B cores are based on V7 version, + * but require a specical sequence for enabling coprocessors. + * For this reason, we need a way to distinguish them. */ -#ifndef CONFIG_CPU_PJ4 -#define cpu_is_pj4() 0 -#else +#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) static inline int cpu_is_pj4(void) { unsigned int id; id = read_cpuid_id(); - if ((id & 0xfffffff0) == 0x562f5840) + if ((id & 0xff0fff00) == 0x560f5800) return 1; return 0; } +#else +#define cpu_is_pj4() 0 #endif #endif diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a766bcbaf8ad..040619c32d68 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o +obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index a08783823b32..2452dd1bef53 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -19,12 +19,16 @@ #include <asm/thread_info.h> #include <asm/asm-offsets.h> -#if defined(CONFIG_CPU_PJ4) +#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) #define PJ4(code...) code #define XSC(code...) -#else +#elif defined(CONFIG_CPU_MOHAWK) || \ + defined(CONFIG_CPU_XSC3) || \ + defined(CONFIG_CPU_XSCALE) #define PJ4(code...) #define XSC(code...) code +#else +#error "Unsupported iWMMXt architecture" #endif #define MMX_WR0 (0x00) diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c index fc7208636284..8153e36b2491 100644 --- a/arch/arm/kernel/pj4-cp0.c +++ b/arch/arm/kernel/pj4-cp0.c @@ -45,7 +45,7 @@ static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) return NOTIFY_DONE; } -static struct notifier_block iwmmxt_notifier_block = { +static struct notifier_block __maybe_unused iwmmxt_notifier_block = { .notifier_call = iwmmxt_do, }; @@ -72,6 +72,33 @@ static void __init pj4_cp_access_write(u32 value) : "=r" (temp) : "r" (value)); } +static int __init pj4_get_iwmmxt_version(void) +{ + u32 cp_access, wcid; + + cp_access = pj4_cp_access_read(); + pj4_cp_access_write(cp_access | 0xf); + + /* check if coprocessor 0 and 1 are available */ + if ((pj4_cp_access_read() & 0xf) != 0xf) { + pj4_cp_access_write(cp_access); + return -ENODEV; + } + + /* read iWMMXt coprocessor id register p1, c0 */ + __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid)); + + pj4_cp_access_write(cp_access); + + /* iWMMXt v1 */ + if ((wcid & 0xffffff00) == 0x56051000) + return 1; + /* iWMMXt v2 */ + if ((wcid & 0xffffff00) == 0x56052000) + return 2; + + return -EINVAL; +} /* * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy @@ -79,17 +106,26 @@ static void __init pj4_cp_access_write(u32 value) */ static int __init pj4_cp0_init(void) { - u32 cp_access; + u32 __maybe_unused cp_access; + int vers; if (!cpu_is_pj4()) return 0; + vers = pj4_get_iwmmxt_version(); + if (vers < 0) + return 0; + +#ifndef CONFIG_IWMMXT + pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n"); +#else cp_access = pj4_cp_access_read() & ~0xf; pj4_cp_access_write(cp_access); - printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); + pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers); elf_hwcap |= HWCAP_IWMMXT; thread_register_notifier(&iwmmxt_notifier_block); +#endif return 0; } |