examples/vm_power: process CPU frequency query
[dpdk.git] / drivers / common / dpaax / caamflib / rta / load_cmd.h
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 NXP
5  */
6
7 #ifndef __RTA_LOAD_CMD_H__
8 #define __RTA_LOAD_CMD_H__
9
10 extern enum rta_sec_era rta_sec_era;
11
12 /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
13 static const uint32_t load_len_mask_allowed[] = {
14         0x000000ee,
15         0x000000fe,
16         0x000000fe,
17         0x000000fe,
18         0x000000fe,
19         0x000000fe,
20         0x000000fe,
21         0x000000fe,
22         0x000000fe,
23         0x000000fe
24 };
25
26 static const uint32_t load_off_mask_allowed[] = {
27         0x0000000f,
28         0x000000ff,
29         0x000000ff,
30         0x000000ff,
31         0x000000ff,
32         0x000000ff,
33         0x000000ff,
34         0x000000ff,
35         0x000000ff,
36         0x000000ff
37 };
38
39 #define IMM_MUST 0
40 #define IMM_CAN  1
41 #define IMM_NO   2
42 #define IMM_DSNM 3 /* it doesn't matter the src type */
43
44 enum e_lenoff {
45         LENOF_03,
46         LENOF_4,
47         LENOF_48,
48         LENOF_448,
49         LENOF_18,
50         LENOF_32,
51         LENOF_24,
52         LENOF_16,
53         LENOF_8,
54         LENOF_128,
55         LENOF_256,
56         DSNM /* it doesn't matter the length/offset values */
57 };
58
59 struct load_map {
60         uint32_t dst;
61         uint32_t dst_opcode;
62         enum e_lenoff len_off;
63         uint8_t imm_src;
64
65 };
66
67 static const struct load_map load_dst[] = {
68 /*1*/   { KEY1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
69                    LENOF_4,   IMM_MUST },
70         { KEY2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
71                    LENOF_4,   IMM_MUST },
72         { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
73                    LENOF_448, IMM_MUST },
74         { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
75                    LENOF_448, IMM_MUST },
76         { ICV1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
77                    LENOF_4,   IMM_MUST },
78         { ICV2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
79                    LENOF_4,   IMM_MUST },
80         { CCTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
81                    LENOF_4,   IMM_MUST },
82         { DCTRL,   LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
83                    DSNM,      IMM_DSNM },
84         { ICTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
85                    LENOF_4,   IMM_MUST },
86         { DPOVRD,  LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
87                    LENOF_4,   IMM_MUST },
88         { CLRW,    LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
89                    LENOF_4,   IMM_MUST },
90         { AAD1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
91                    LENOF_4,   IMM_MUST },
92         { IV1SZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
93                    LENOF_4,   IMM_MUST },
94         { ALTDS1,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
95                    LENOF_448, IMM_MUST },
96         { PKASZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
97                    LENOF_4,   IMM_MUST, },
98         { PKBSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
99                    LENOF_4,   IMM_MUST },
100         { PKNSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
101                    LENOF_4,   IMM_MUST },
102         { PKESZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
103                    LENOF_4,   IMM_MUST },
104         { NFIFO,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
105                    LENOF_48,  IMM_MUST },
106         { IFIFO,   LDST_SRCDST_BYTE_INFIFO,  LENOF_18, IMM_MUST },
107         { OFIFO,   LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
108         { MATH0,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
109                    LENOF_32,  IMM_CAN },
110         { MATH1,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
111                    LENOF_24,  IMM_CAN },
112         { MATH2,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
113                    LENOF_16,  IMM_CAN },
114         { MATH3,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
115                    LENOF_8,   IMM_CAN },
116         { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
117                    LENOF_128, IMM_CAN },
118         { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
119                    LENOF_128, IMM_CAN },
120         { KEY1,    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
121                    LENOF_32,  IMM_CAN },
122         { KEY2,    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
123                    LENOF_32,  IMM_CAN },
124         { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
125                    LENOF_256,  IMM_NO },
126         { DPID,    LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
127                    LENOF_448, IMM_MUST },
128 /*32*/  { IDFNS,   LDST_SRCDST_WORD_IFNSR, LENOF_18,  IMM_MUST },
129         { ODFNS,   LDST_SRCDST_WORD_OFNSR, LENOF_18,  IMM_MUST },
130         { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18,  IMM_MUST },
131 /*35*/  { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
132         { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
133         { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
134         { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
135         { SZL,     LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
136 /*40*/  { SZM,     LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
137 };
138
139 /*
140  * Allowed LOAD destinations for each SEC Era.
141  * Values represent the number of entries from load_dst[] that are supported.
142  */
143 static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40,
144                                             40, 40, 40, 40, 40};
145
146 static inline int
147 load_check_len_offset(int pos, uint32_t length, uint32_t offset)
148 {
149         if ((load_dst[pos].dst == DCTRL) &&
150             ((length & ~load_len_mask_allowed[rta_sec_era]) ||
151              (offset & ~load_off_mask_allowed[rta_sec_era])))
152                 goto err;
153
154         switch (load_dst[pos].len_off) {
155         case (LENOF_03):
156                 if ((length > 3) || (offset))
157                         goto err;
158                 break;
159         case (LENOF_4):
160                 if ((length != 4) || (offset != 0))
161                         goto err;
162                 break;
163         case (LENOF_48):
164                 if (!(((length == 4) && (offset == 0)) ||
165                       ((length == 8) && (offset == 0))))
166                         goto err;
167                 break;
168         case (LENOF_448):
169                 if (!(((length == 4) && (offset == 0)) ||
170                       ((length == 4) && (offset == 4)) ||
171                       ((length == 8) && (offset == 0))))
172                         goto err;
173                 break;
174         case (LENOF_18):
175                 if ((length < 1) || (length > 8) || (offset != 0))
176                         goto err;
177                 break;
178         case (LENOF_32):
179                 if ((length > 32) || (offset > 32) || ((offset + length) > 32))
180                         goto err;
181                 break;
182         case (LENOF_24):
183                 if ((length > 24) || (offset > 24) || ((offset + length) > 24))
184                         goto err;
185                 break;
186         case (LENOF_16):
187                 if ((length > 16) || (offset > 16) || ((offset + length) > 16))
188                         goto err;
189                 break;
190         case (LENOF_8):
191                 if ((length > 8) || (offset > 8) || ((offset + length) > 8))
192                         goto err;
193                 break;
194         case (LENOF_128):
195                 if ((length > 128) || (offset > 128) ||
196                     ((offset + length) > 128))
197                         goto err;
198                 break;
199         case (LENOF_256):
200                 if ((length < 1) || (length > 256) || ((length + offset) > 256))
201                         goto err;
202                 break;
203         case (DSNM):
204                 break;
205         default:
206                 goto err;
207         }
208
209         return 0;
210 err:
211         return -EINVAL;
212 }
213
214 static inline int
215 rta_load(struct program *program, uint64_t src, uint64_t dst,
216          uint32_t offset, uint32_t length, uint32_t flags)
217 {
218         uint32_t opcode = 0;
219         int pos = -1, ret = -EINVAL;
220         unsigned int start_pc = program->current_pc, i;
221
222         if (flags & SEQ)
223                 opcode = CMD_SEQ_LOAD;
224         else
225                 opcode = CMD_LOAD;
226
227         if ((length & 0xffffff00) || (offset & 0xffffff00)) {
228                 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
229                 goto err;
230         }
231
232         if (flags & SGF)
233                 opcode |= LDST_SGF;
234         if (flags & VLF)
235                 opcode |= LDST_VLF;
236
237         /* check load destination, length and offset and source type */
238         for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
239                 if (dst == load_dst[i].dst) {
240                         pos = (int)i;
241                         break;
242                 }
243         if (-1 == pos) {
244                 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
245                        program->current_pc);
246                 goto err;
247         }
248
249         if (flags & IMMED) {
250                 if (load_dst[pos].imm_src == IMM_NO) {
251                         pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
252                                program->current_pc);
253                         goto err;
254                 }
255                 opcode |= LDST_IMM;
256         } else if (load_dst[pos].imm_src == IMM_MUST) {
257                 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
258                        program->current_pc);
259                 goto err;
260         }
261
262         ret = load_check_len_offset(pos, length, offset);
263         if (ret < 0) {
264                 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
265                        program->current_pc);
266                 goto err;
267         }
268
269         opcode |= load_dst[pos].dst_opcode;
270
271         /* DESC BUFFER: length / offset values are specified in 4-byte words */
272         if (dst == DESCBUF) {
273                 opcode |= (length >> 2);
274                 opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
275         } else {
276                 opcode |= length;
277                 opcode |= (offset << LDST_OFFSET_SHIFT);
278         }
279
280         __rta_out32(program, opcode);
281         program->current_instruction++;
282
283         /* DECO CONTROL: skip writing pointer of imm data */
284         if (dst == DCTRL)
285                 return (int)start_pc;
286
287         /*
288          * For data copy, 3 possible ways to specify how to copy data:
289          *  - IMMED & !COPY: copy data directly from src( max 8 bytes)
290          *  - IMMED & COPY: copy data imm from the location specified by user
291          *  - !IMMED and is not SEQ cmd: copy the address
292          */
293         if (flags & IMMED)
294                 __rta_inline_data(program, src, flags & __COPY_MASK, length);
295         else if (!(flags & SEQ))
296                 __rta_out64(program, program->ps, src);
297
298         return (int)start_pc;
299
300  err:
301         program->first_error_pc = start_pc;
302         program->current_instruction++;
303         return ret;
304 }
305
306 #endif /* __RTA_LOAD_CMD_H__*/