diff options
Diffstat (limited to 'arch/arm/kernel/pj4-cp0.c')
| -rw-r--r-- | arch/arm/kernel/pj4-cp0.c | 46 | 
1 files changed, 43 insertions, 3 deletions
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c index 679cf4d18c0..8153e36b249 100644 --- a/arch/arm/kernel/pj4-cp0.c +++ b/arch/arm/kernel/pj4-cp0.c @@ -17,6 +17,7 @@  #include <linux/init.h>  #include <linux/io.h>  #include <asm/thread_notify.h> +#include <asm/cputype.h>  static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)  { @@ -44,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,  }; @@ -71,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 @@ -78,14 +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;  }  | 
