Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[cascardo/linux.git] / arch / mips / include / asm / msa.h
1 /*
2  * Copyright (C) 2013 Imagination Technologies
3  * Author: Paul Burton <paul.burton@imgtec.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation;  either version 2 of the  License, or (at your
8  * option) any later version.
9  */
10 #ifndef _ASM_MSA_H
11 #define _ASM_MSA_H
12
13 #include <asm/mipsregs.h>
14
15 extern void _save_msa(struct task_struct *);
16 extern void _restore_msa(struct task_struct *);
17
18 static inline void enable_msa(void)
19 {
20         if (cpu_has_msa) {
21                 set_c0_config5(MIPS_CONF5_MSAEN);
22                 enable_fpu_hazard();
23         }
24 }
25
26 static inline void disable_msa(void)
27 {
28         if (cpu_has_msa) {
29                 clear_c0_config5(MIPS_CONF5_MSAEN);
30                 disable_fpu_hazard();
31         }
32 }
33
34 static inline int is_msa_enabled(void)
35 {
36         if (!cpu_has_msa)
37                 return 0;
38
39         return read_c0_config5() & MIPS_CONF5_MSAEN;
40 }
41
42 static inline int thread_msa_context_live(void)
43 {
44         /*
45          * Check cpu_has_msa only if it's a constant. This will allow the
46          * compiler to optimise out code for CPUs without MSA without adding
47          * an extra redundant check for CPUs with MSA.
48          */
49         if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
50                 return 0;
51
52         return test_thread_flag(TIF_MSA_CTX_LIVE);
53 }
54
55 static inline void save_msa(struct task_struct *t)
56 {
57         if (cpu_has_msa)
58                 _save_msa(t);
59 }
60
61 static inline void restore_msa(struct task_struct *t)
62 {
63         if (cpu_has_msa)
64                 _restore_msa(t);
65 }
66
67 #ifdef TOOLCHAIN_SUPPORTS_MSA
68
69 #define __BUILD_MSA_CTL_REG(name, cs)                           \
70 static inline unsigned int read_msa_##name(void)                \
71 {                                                               \
72         unsigned int reg;                                       \
73         __asm__ __volatile__(                                   \
74         "       .set    push\n"                                 \
75         "       .set    msa\n"                                  \
76         "       cfcmsa  %0, $" #cs "\n"                         \
77         "       .set    pop\n"                                  \
78         : "=r"(reg));                                           \
79         return reg;                                             \
80 }                                                               \
81                                                                 \
82 static inline void write_msa_##name(unsigned int val)           \
83 {                                                               \
84         __asm__ __volatile__(                                   \
85         "       .set    push\n"                                 \
86         "       .set    msa\n"                                  \
87         "       cfcmsa  $" #cs ", %0\n"                         \
88         "       .set    pop\n"                                  \
89         : : "r"(val));                                          \
90 }
91
92 #else /* !TOOLCHAIN_SUPPORTS_MSA */
93
94 /*
95  * Define functions using .word for the c[ft]cmsa instructions in order to
96  * allow compilation with toolchains that do not support MSA. Once all
97  * toolchains in use support MSA these can be removed.
98  */
99
100 #define __BUILD_MSA_CTL_REG(name, cs)                           \
101 static inline unsigned int read_msa_##name(void)                \
102 {                                                               \
103         unsigned int reg;                                       \
104         __asm__ __volatile__(                                   \
105         "       .set    push\n"                                 \
106         "       .set    noat\n"                                 \
107         "       .word   0x787e0059 | (" #cs " << 11)\n"         \
108         "       move    %0, $1\n"                               \
109         "       .set    pop\n"                                  \
110         : "=r"(reg));                                           \
111         return reg;                                             \
112 }                                                               \
113                                                                 \
114 static inline void write_msa_##name(unsigned int val)           \
115 {                                                               \
116         __asm__ __volatile__(                                   \
117         "       .set    push\n"                                 \
118         "       .set    noat\n"                                 \
119         "       move    $1, %0\n"                               \
120         "       .word   0x783e0819 | (" #cs " << 6)\n"          \
121         "       .set    pop\n"                                  \
122         : : "r"(val));                                          \
123 }
124
125 #endif /* !TOOLCHAIN_SUPPORTS_MSA */
126
127 #define MSA_IR          0
128 #define MSA_CSR         1
129 #define MSA_ACCESS      2
130 #define MSA_SAVE        3
131 #define MSA_MODIFY      4
132 #define MSA_REQUEST     5
133 #define MSA_MAP         6
134 #define MSA_UNMAP       7
135
136 __BUILD_MSA_CTL_REG(ir, 0)
137 __BUILD_MSA_CTL_REG(csr, 1)
138 __BUILD_MSA_CTL_REG(access, 2)
139 __BUILD_MSA_CTL_REG(save, 3)
140 __BUILD_MSA_CTL_REG(modify, 4)
141 __BUILD_MSA_CTL_REG(request, 5)
142 __BUILD_MSA_CTL_REG(map, 6)
143 __BUILD_MSA_CTL_REG(unmap, 7)
144
145 /* MSA Implementation Register (MSAIR) */
146 #define MSA_IR_REVB             0
147 #define MSA_IR_REVF             (_ULCAST_(0xff) << MSA_IR_REVB)
148 #define MSA_IR_PROCB            8
149 #define MSA_IR_PROCF            (_ULCAST_(0xff) << MSA_IR_PROCB)
150 #define MSA_IR_WRPB             16
151 #define MSA_IR_WRPF             (_ULCAST_(0x1) << MSA_IR_WRPB)
152
153 /* MSA Control & Status Register (MSACSR) */
154 #define MSA_CSR_RMB             0
155 #define MSA_CSR_RMF             (_ULCAST_(0x3) << MSA_CSR_RMB)
156 #define MSA_CSR_RM_NEAREST      0
157 #define MSA_CSR_RM_TO_ZERO      1
158 #define MSA_CSR_RM_TO_POS       2
159 #define MSA_CSR_RM_TO_NEG       3
160 #define MSA_CSR_FLAGSB          2
161 #define MSA_CSR_FLAGSF          (_ULCAST_(0x1f) << MSA_CSR_FLAGSB)
162 #define MSA_CSR_FLAGS_IB        2
163 #define MSA_CSR_FLAGS_IF        (_ULCAST_(0x1) << MSA_CSR_FLAGS_IB)
164 #define MSA_CSR_FLAGS_UB        3
165 #define MSA_CSR_FLAGS_UF        (_ULCAST_(0x1) << MSA_CSR_FLAGS_UB)
166 #define MSA_CSR_FLAGS_OB        4
167 #define MSA_CSR_FLAGS_OF        (_ULCAST_(0x1) << MSA_CSR_FLAGS_OB)
168 #define MSA_CSR_FLAGS_ZB        5
169 #define MSA_CSR_FLAGS_ZF        (_ULCAST_(0x1) << MSA_CSR_FLAGS_ZB)
170 #define MSA_CSR_FLAGS_VB        6
171 #define MSA_CSR_FLAGS_VF        (_ULCAST_(0x1) << MSA_CSR_FLAGS_VB)
172 #define MSA_CSR_ENABLESB        7
173 #define MSA_CSR_ENABLESF        (_ULCAST_(0x1f) << MSA_CSR_ENABLESB)
174 #define MSA_CSR_ENABLES_IB      7
175 #define MSA_CSR_ENABLES_IF      (_ULCAST_(0x1) << MSA_CSR_ENABLES_IB)
176 #define MSA_CSR_ENABLES_UB      8
177 #define MSA_CSR_ENABLES_UF      (_ULCAST_(0x1) << MSA_CSR_ENABLES_UB)
178 #define MSA_CSR_ENABLES_OB      9
179 #define MSA_CSR_ENABLES_OF      (_ULCAST_(0x1) << MSA_CSR_ENABLES_OB)
180 #define MSA_CSR_ENABLES_ZB      10
181 #define MSA_CSR_ENABLES_ZF      (_ULCAST_(0x1) << MSA_CSR_ENABLES_ZB)
182 #define MSA_CSR_ENABLES_VB      11
183 #define MSA_CSR_ENABLES_VF      (_ULCAST_(0x1) << MSA_CSR_ENABLES_VB)
184 #define MSA_CSR_CAUSEB          12
185 #define MSA_CSR_CAUSEF          (_ULCAST_(0x3f) << MSA_CSR_CAUSEB)
186 #define MSA_CSR_CAUSE_IB        12
187 #define MSA_CSR_CAUSE_IF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_IB)
188 #define MSA_CSR_CAUSE_UB        13
189 #define MSA_CSR_CAUSE_UF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_UB)
190 #define MSA_CSR_CAUSE_OB        14
191 #define MSA_CSR_CAUSE_OF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_OB)
192 #define MSA_CSR_CAUSE_ZB        15
193 #define MSA_CSR_CAUSE_ZF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_ZB)
194 #define MSA_CSR_CAUSE_VB        16
195 #define MSA_CSR_CAUSE_VF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_VB)
196 #define MSA_CSR_CAUSE_EB        17
197 #define MSA_CSR_CAUSE_EF        (_ULCAST_(0x1) << MSA_CSR_CAUSE_EB)
198 #define MSA_CSR_NXB             18
199 #define MSA_CSR_NXF             (_ULCAST_(0x1) << MSA_CSR_NXB)
200 #define MSA_CSR_FSB             24
201 #define MSA_CSR_FSF             (_ULCAST_(0x1) << MSA_CSR_FSB)
202
203 #endif /* _ASM_MSA_H */