diff options
Diffstat (limited to 'arch/arm/kernel/pj4-cp0.c')
-rw-r--r-- | arch/arm/kernel/pj4-cp0.c | 42 |
1 files changed, 39 insertions, 3 deletions
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) | |||
45 | return NOTIFY_DONE; | 45 | return NOTIFY_DONE; |
46 | } | 46 | } |
47 | 47 | ||
48 | static struct notifier_block iwmmxt_notifier_block = { | 48 | static struct notifier_block __maybe_unused iwmmxt_notifier_block = { |
49 | .notifier_call = iwmmxt_do, | 49 | .notifier_call = iwmmxt_do, |
50 | }; | 50 | }; |
51 | 51 | ||
@@ -72,6 +72,33 @@ static void __init pj4_cp_access_write(u32 value) | |||
72 | : "=r" (temp) : "r" (value)); | 72 | : "=r" (temp) : "r" (value)); |
73 | } | 73 | } |
74 | 74 | ||
75 | static int __init pj4_get_iwmmxt_version(void) | ||
76 | { | ||
77 | u32 cp_access, wcid; | ||
78 | |||
79 | cp_access = pj4_cp_access_read(); | ||
80 | pj4_cp_access_write(cp_access | 0xf); | ||
81 | |||
82 | /* check if coprocessor 0 and 1 are available */ | ||
83 | if ((pj4_cp_access_read() & 0xf) != 0xf) { | ||
84 | pj4_cp_access_write(cp_access); | ||
85 | return -ENODEV; | ||
86 | } | ||
87 | |||
88 | /* read iWMMXt coprocessor id register p1, c0 */ | ||
89 | __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid)); | ||
90 | |||
91 | pj4_cp_access_write(cp_access); | ||
92 | |||
93 | /* iWMMXt v1 */ | ||
94 | if ((wcid & 0xffffff00) == 0x56051000) | ||
95 | return 1; | ||
96 | /* iWMMXt v2 */ | ||
97 | if ((wcid & 0xffffff00) == 0x56052000) | ||
98 | return 2; | ||
99 | |||
100 | return -EINVAL; | ||
101 | } | ||
75 | 102 | ||
76 | /* | 103 | /* |
77 | * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy | 104 | * 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) | |||
79 | */ | 106 | */ |
80 | static int __init pj4_cp0_init(void) | 107 | static int __init pj4_cp0_init(void) |
81 | { | 108 | { |
82 | u32 cp_access; | 109 | u32 __maybe_unused cp_access; |
110 | int vers; | ||
83 | 111 | ||
84 | if (!cpu_is_pj4()) | 112 | if (!cpu_is_pj4()) |
85 | return 0; | 113 | return 0; |
86 | 114 | ||
115 | vers = pj4_get_iwmmxt_version(); | ||
116 | if (vers < 0) | ||
117 | return 0; | ||
118 | |||
119 | #ifndef CONFIG_IWMMXT | ||
120 | pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n"); | ||
121 | #else | ||
87 | cp_access = pj4_cp_access_read() & ~0xf; | 122 | cp_access = pj4_cp_access_read() & ~0xf; |
88 | pj4_cp_access_write(cp_access); | 123 | pj4_cp_access_write(cp_access); |
89 | 124 | ||
90 | printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); | 125 | pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers); |
91 | elf_hwcap |= HWCAP_IWMMXT; | 126 | elf_hwcap |= HWCAP_IWMMXT; |
92 | thread_register_notifier(&iwmmxt_notifier_block); | 127 | thread_register_notifier(&iwmmxt_notifier_block); |
128 | #endif | ||
93 | 129 | ||
94 | return 0; | 130 | return 0; |
95 | } | 131 | } |