1
2
3
4
5
6
7
8#include <linux/bitfield.h>
9#include <linux/firmware/xlnx-zynqmp.h>
10#include <linux/io.h>
11#include <linux/slab.h>
12#include <linux/xlnx-ai-engine.h>
13
14#include "ai-engine-internal.h"
15
16#define KBYTES(n) ((n) * 1024)
17
18#define AIE_ARRAY_SHIFT 30U
19#define AIE_COL_SHIFT 23U
20#define AIE_ROW_SHIFT 18U
21
22#define NUM_MEMS_PER_TILE 2U
23
24#define NUM_MODS_CORE_TILE 2U
25#define NUM_MODS_SHIMPL_TILE 1U
26
27
28
29
30#define AIE_NUM_PERF_CORE_MOD 4U
31#define AIE_NUM_USEREVENT_CORE_MOD 4U
32#define AIE_NUM_TRACECONTROL_CORE_MOD 1U
33#define AIE_NUM_PCEVENT_CORE_MOD 4U
34#define AIE_NUM_SSSELECT_CORE_MOD 8U
35#define AIE_NUM_BROADCAST_CORE_MOD 16U
36#define AIE_NUM_COMBOEVENT_CORE_MOD 4U
37#define AIE_NUM_GROUPEVENTS_CORE_MOD 9U
38
39#define AIE_NUM_PERF_MEM_MOD 2U
40#define AIE_NUM_USEREVENT_MEM_MOD 4U
41#define AIE_NUM_TRACECONTROL_MEM_MOD 1U
42#define AIE_NUM_PCEVENT_MEM_MOD 0U
43#define AIE_NUM_SSSELECT_MEM_MOD 0U
44#define AIE_NUM_BROADCAST_MEM_MOD 16U
45#define AIE_NUM_COMBOEVENT_MEM_MOD 4U
46#define AIE_NUM_GROUPEVENTS_MEM_MOD 8U
47
48#define AIE_NUM_PERF_PL_MOD 2U
49#define AIE_NUM_USEREVENT_PL_MOD 4U
50#define AIE_NUM_TRACECONTROL_PL_MOD 1U
51#define AIE_NUM_PCEVENT_PL_MOD 0U
52#define AIE_NUM_SSSELECT_PL_MOD 8U
53#define AIE_NUM_BROADCAST_PL_MOD 16U
54#define AIE_NUM_COMBOEVENT_PL_MOD 4U
55#define AIE_NUM_GROUPEVENTS_PL_MOD 7U
56
57
58
59
60#define AIE_SHIMNOC_L2INTR_MASK_REGOFF 0x00015000U
61#define AIE_SHIMNOC_L2INTR_INTR_REGOFF 0x00015010U
62#define AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF 0x0001d000U
63#define AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF 0x0001d13cU
64#define AIE_SHIMNOC_AXIMM_REGOFF 0x0001e020U
65#define AIE_SHIMPL_L1INTR_MASK_A_REGOFF 0x00035000U
66#define AIE_SHIMPL_L1INTR_BLOCK_NORTH_B_REGOFF 0x00035050U
67#define AIE_SHIMPL_CLKCNTR_REGOFF 0x00036040U
68#define AIE_SHIMPL_COLRESET_REGOFF 0x00036048U
69#define AIE_SHIMPL_RESET_REGOFF 0x0003604cU
70#define AIE_SHIMPL_GROUP_ERROR_REGOFF 0x0003450cU
71#define AIE_TILE_CORE_CLKCNTR_REGOFF 0x00036040U
72#define AIE_TILE_CORE_GROUP_ERROR_REGOFF 0x00034510U
73#define AIE_TILE_MEM_GROUP_ERROR_REGOFF 0x00014514U
74#define AIE_TILE_CORE_R0_REGOFF 0x00030000U
75#define AIE_TILE_CORE_LC_REGOFF 0x00030520U
76#define AIE_TILE_CORE_VRL0_REGOFF 0x00030530U
77#define AIE_TILE_CORE_AMH3_PART3_REGOFF 0x000307a0U
78
79
80
81
82#define AIE_SHIMPL_SHIMRST_MASK 0x1U
83#define AIE_SHIMPL_COLRST_MASK 0x1U
84#define AIE_SHIMPL_CLKCNTR_COLBUF_MASK 0x1U
85#define AIE_SHIMPL_CLKCNTR_NEXTCLK_MASK BIT(1)
86#define AIE_TILE_CLKCNTR_COLBUF_MASK BIT(0)
87#define AIE_TILE_CLKCNTR_NEXTCLK_MASK BIT(1)
88
89
90
91
92
93
94
95#define VERSAL_PM_RST_AIE_SHIM_ID 0xc10405fU
96
97
98#define AIE_PART_SYSFS_CORE_BINA_SIZE 0x4000
99#define AIE_PART_SYSFS_DMA_BINA_SIZE 0xC800
100#define AIE_PART_SYSFS_LOCK_BINA_SIZE 0x28000
101#define AIE_PART_SYSFS_ERROR_BINA_SIZE 0x4000
102#define AIE_PART_SYSFS_STATUS_BINA_SIZE 0x3c000
103
104static const struct aie_tile_regs aie_kernel_regs[] = {
105
106 {.attribute = AIE_TILE_TYPE_MASK_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
107 .soff = AIE_SHIMNOC_AXIMM_REGOFF,
108 .eoff = AIE_SHIMNOC_AXIMM_REGOFF,
109 },
110
111 {.attribute = AIE_TILE_TYPE_MASK_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
112 .soff = AIE_SHIMNOC_DMA_BD0_ADDRLOW_REGOFF,
113 .eoff = AIE_SHIMNOC_DMA_BD15_PACKET_REGOFF,
114 },
115
116 {.attribute = AIE_TILE_TYPE_MASK_SHIMNOC << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
117 .soff = AIE_SHIMNOC_L2INTR_MASK_REGOFF,
118 .eoff = AIE_SHIMNOC_L2INTR_INTR_REGOFF,
119 },
120
121 {.attribute = (AIE_TILE_TYPE_MASK_SHIMPL | AIE_TILE_TYPE_MASK_SHIMNOC) <<
122 AIE_REGS_ATTR_TILE_TYPE_SHIFT,
123 .soff = AIE_SHIMPL_L1INTR_MASK_A_REGOFF,
124 .eoff = AIE_SHIMPL_L1INTR_BLOCK_NORTH_B_REGOFF,
125 },
126
127 {.attribute = (AIE_TILE_TYPE_MASK_SHIMPL | AIE_TILE_TYPE_MASK_SHIMNOC) <<
128 AIE_REGS_ATTR_TILE_TYPE_SHIFT,
129 .soff = AIE_SHIMPL_COLRESET_REGOFF,
130 .eoff = AIE_SHIMPL_COLRESET_REGOFF,
131 },
132
133 {.attribute = (AIE_TILE_TYPE_MASK_SHIMPL | AIE_TILE_TYPE_MASK_SHIMNOC) <<
134 AIE_REGS_ATTR_TILE_TYPE_SHIFT,
135 .soff = AIE_SHIMPL_RESET_REGOFF,
136 .eoff = AIE_SHIMPL_RESET_REGOFF,
137 },
138
139 {.attribute = (AIE_TILE_TYPE_MASK_SHIMPL | AIE_TILE_TYPE_MASK_SHIMNOC) <<
140 AIE_REGS_ATTR_TILE_TYPE_SHIFT,
141 .soff = AIE_SHIMPL_CLKCNTR_REGOFF,
142 .eoff = AIE_SHIMPL_CLKCNTR_REGOFF,
143 },
144
145 {.attribute = (AIE_TILE_TYPE_MASK_SHIMPL | AIE_TILE_TYPE_MASK_SHIMNOC) <<
146 AIE_REGS_ATTR_TILE_TYPE_SHIFT,
147 .soff = AIE_SHIMPL_GROUP_ERROR_REGOFF,
148 .eoff = AIE_SHIMPL_GROUP_ERROR_REGOFF,
149 },
150
151 {.attribute = AIE_TILE_TYPE_MASK_TILE << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
152 .soff = AIE_TILE_CORE_CLKCNTR_REGOFF,
153 .eoff = AIE_TILE_CORE_CLKCNTR_REGOFF,
154 },
155
156 {.attribute = AIE_TILE_TYPE_MASK_TILE << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
157 .soff = AIE_TILE_CORE_GROUP_ERROR_REGOFF,
158 .eoff = AIE_TILE_CORE_GROUP_ERROR_REGOFF,
159 },
160
161 {.attribute = AIE_TILE_TYPE_MASK_TILE << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
162 .soff = AIE_TILE_MEM_GROUP_ERROR_REGOFF,
163 .eoff = AIE_TILE_MEM_GROUP_ERROR_REGOFF,
164 },
165};
166
167static const struct aie_tile_regs aie_core_32bit_regs = {
168 .attribute = AIE_TILE_TYPE_TILE << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
169 .soff = AIE_TILE_CORE_R0_REGOFF,
170 .eoff = AIE_TILE_CORE_LC_REGOFF,
171};
172
173static const struct aie_tile_regs aie_core_128bit_regs = {
174 .attribute = AIE_TILE_TYPE_TILE << AIE_REGS_ATTR_TILE_TYPE_SHIFT,
175 .soff = AIE_TILE_CORE_VRL0_REGOFF,
176 .eoff = AIE_TILE_CORE_AMH3_PART3_REGOFF,
177};
178
179static const struct aie_core_regs_attr aie_core_regs[] = {
180 {.core_regs = &aie_core_32bit_regs,
181 .width = 1,
182 },
183 {.core_regs = &aie_core_128bit_regs,
184 .width = 4,
185 },
186};
187
188static const struct aie_single_reg_field aie_col_rst = {
189 .mask = AIE_SHIMPL_COLRST_MASK,
190 .regoff = AIE_SHIMPL_COLRESET_REGOFF,
191};
192
193static const struct aie_single_reg_field aie_col_clkbuf = {
194 .mask = AIE_SHIMPL_CLKCNTR_COLBUF_MASK,
195 .regoff = AIE_SHIMPL_CLKCNTR_REGOFF,
196};
197
198static const struct aie_dma_attr aie_shimdma = {
199 .laddr = {
200 .mask = 0xffffffffU,
201 .regoff = 0U,
202 },
203 .haddr = {
204 .mask = 0xffff0000U,
205 .regoff = 0x8U,
206 },
207 .buflen = {
208 .mask = 0xffffffffU,
209 .regoff = 0x4U,
210 },
211 .sts = {
212 .mask = GENMASK(1, 0),
213 .regoff = 2U,
214 },
215 .stall = {
216 .mask = BIT(4),
217 .regoff = 1U,
218 },
219 .qsize = {
220 .mask = GENMASK(8, 6),
221 .regoff = 3U,
222 },
223 .curbd = {
224 .mask = GENMASK(19, 16),
225 .regoff = 4U,
226 },
227 .qsts = {
228 .mask = BIT(28),
229 .regoff = 1U,
230 },
231 .bd_regoff = 0x0001d000U,
232 .mm2s_sts_regoff = 0x1d164U,
233 .s2mm_sts_regoff = 0x1d160U,
234 .num_bds = 16,
235 .num_mm2s_chan = 2U,
236 .num_s2mm_chan = 2U,
237 .bd_len = 0x14U,
238};
239
240static const struct aie_dma_attr aie_tiledma = {
241 .sts = {
242 .mask = GENMASK(1, 0),
243 .regoff = 2U,
244 },
245 .stall = {
246 .mask = BIT(4),
247 .regoff = 1U,
248 },
249 .qsize = {
250 .mask = GENMASK(8, 6),
251 .regoff = 3U,
252 },
253 .curbd = {
254 .mask = GENMASK(19, 16),
255 .regoff = 4U,
256 },
257 .qsts = {
258 .mask = BIT(28),
259 .regoff = 1U,
260 },
261 .mm2s_sts_regoff = 0x1df10U,
262 .s2mm_sts_regoff = 0x1df00U,
263 .num_bds = 16,
264 .num_mm2s_chan = 2U,
265 .num_s2mm_chan = 2U,
266};
267
268static char *aie_dma_status_str[] = {
269 "idle",
270 "starting",
271 "running",
272 "stalled_on_requesting_lock",
273};
274
275static char *aie_queue_status_str[] = {
276 "okay",
277 "overflow",
278};
279
280static const struct aie_event_attr aie_pl_event = {
281 .bc_event = {
282 .mask = GENMASK(6, 0),
283 .regoff = 0x0U,
284 },
285 .group_error = {
286 .mask = GENMASK(10, 0),
287 .regoff = 0xcU,
288 },
289 .bc_regoff = 0x34010U,
290 .status_regoff = 0x34200U,
291 .group_regoff = 0x34500U,
292 .base_error_event = 62U,
293 .num_broadcasts = 16U,
294 .base_bc_event = 107U,
295 .num_events = 128U,
296};
297
298static const struct aie_event_attr aie_mem_event = {
299 .bc_event = {
300 .mask = GENMASK(6, 0),
301 .regoff = 0x0U,
302 },
303 .group_error = {
304 .mask = GENMASK(13, 0),
305 .regoff = 0x14U,
306 },
307 .bc_regoff = 0x14010U,
308 .status_regoff = 0x14200U,
309 .group_regoff = 0x14500U,
310 .base_error_event = 87U,
311 .num_broadcasts = 16U,
312 .base_bc_event = 107U,
313 .num_events = 128U,
314};
315
316static const struct aie_event_attr aie_core_event = {
317 .bc_event = {
318 .mask = GENMASK(6, 0),
319 .regoff = 0x0U,
320 },
321 .group_error = {
322 .mask = GENMASK(21, 0),
323 .regoff = 0x10U,
324 },
325 .bc_regoff = 0x34010U,
326 .status_regoff = 0x34200U,
327 .group_regoff = 0x34500U,
328 .base_error_event = 48U,
329 .num_broadcasts = 16U,
330 .base_bc_event = 107U,
331 .num_events = 128U,
332};
333
334static const struct aie_l1_intr_ctrl_attr aie_l1_intr_ctrl = {
335 .swa_status = {
336 .mask = GENMASK(19, 0),
337 .regoff = 0xcU,
338 },
339 .swb_status = {
340 .mask = GENMASK(19, 0),
341 .regoff = 0x3cU,
342 },
343 .swa_event = {
344 .mask = GENMASK(6, 0),
345 .regoff = 0x14U,
346 },
347 .swb_event = {
348 .mask = GENMASK(6, 0),
349 .regoff = 0x44U,
350 },
351 .regoff = 0x35000U,
352 .event_lsb = 8,
353 .num_broadcasts = 0x14U,
354};
355
356static const struct aie_l2_intr_ctrl_attr aie_l2_intr_ctrl = {
357 .mask = {
358 .mask = GENMASK(15, 0),
359 .regoff = 0x0U,
360 },
361 .enable = {
362 .mask = GENMASK(15, 0),
363 .regoff = 0x4U,
364 },
365 .disable = {
366 .mask = GENMASK(15, 0),
367 .regoff = 0x8U,
368 },
369 .status = {
370 .mask = GENMASK(15, 0),
371 .regoff = 0xcU,
372 },
373 .regoff = 0x15000U,
374 .num_broadcasts = 0x10U,
375};
376
377static const struct aie_event_prop aie_core_stream_error_prop[] = {
378 {
379 .event = 54U,
380 .event_str = "tlast_in_wss_words_0-2",
381 },
382 {
383 .event = 57U,
384 .event_str = "control_packet_error",
385 },
386 {
387 .event = 56U,
388 .event_str = "stream_packet_parity_error",
389 },
390};
391
392static const struct aie_event_prop aie_core_inst_error_prop[] = {
393 {
394 .event = 59U,
395 .event_str = "instruction_decompression_error",
396 },
397};
398
399static const struct aie_event_prop aie_core_ecc_error_prop[] = {
400 {
401 .event = 64U,
402 .event_str = "pm_ecc_error_2-bit",
403 },
404 {
405 .event = 62U,
406 .event_str = "pm_ecc_error_scrub_2-bit",
407 },
408};
409
410static const struct aie_event_prop aie_core_access_error_prop[] = {
411 {
412 .event = 55U,
413 .event_str = "pm_reg_access_failure",
414 },
415 {
416 .event = 66U,
417 .event_str = "dm_access_to_unavailable",
418 },
419 {
420 .event = 65U,
421 .event_str = "pm_address_out_of_range",
422 },
423 {
424 .event = 60U,
425 .event_str = "dm_address_out_of_range",
426 },
427};
428
429static const struct aie_event_prop aie_core_lock_error_prop[] = {
430 {
431 .event = 67U,
432 .event_str = "lock_access_to_unavailable",
433 },
434};
435
436static const struct aie_event_prop aie_core_bus_error_prop[] = {
437 {
438 .event = 58U,
439 .event_str = "axi-mm_slave_error",
440 },
441};
442
443static const struct aie_event_prop aie_mem_ecc_error_prop[] = {
444 {
445 .event = 88U,
446 .event_str = "dm_ecc_error_scrub_2-bit",
447 },
448 {
449 .event = 90U,
450 .event_str = "dm_ecc_error_2-bit",
451 },
452};
453
454static const struct aie_event_prop aie_mem_parity_error_prop[] = {
455 {
456 .event = 91U,
457 .event_str = "dm_parity_error_bank_2",
458 },
459 {
460 .event = 92U,
461 .event_str = "dm_parity_error_bank_3",
462 },
463 {
464 .event = 93U,
465 .event_str = "dm_parity_error_bank_4",
466 },
467 {
468 .event = 94U,
469 .event_str = "dm_parity_error_bank_5",
470 },
471 {
472 .event = 95U,
473 .event_str = "dm_parity_error_bank_6",
474 },
475 {
476 .event = 96U,
477 .event_str = "dm_parity_error_bank_7",
478 },
479};
480
481static const struct aie_event_prop aie_mem_dma_error_prop[] = {
482 {
483 .event = 97U,
484 .event_str = "dma_s2mm_0_error",
485 },
486 {
487 .event = 98U,
488 .event_str = "dma_s2mm_1_error",
489 },
490 {
491 .event = 99U,
492 .event_str = "dma_mm2s_0_error",
493 },
494 {
495 .event = 100U,
496 .event_str = "dma_mm2s_1_error",
497 },
498};
499
500static const struct aie_event_prop aie_shim_bus_error_prop[] = {
501 {
502 .event = 62U,
503 .event_str = "axi-mm_slave_tile_error",
504 },
505};
506
507static const struct aie_event_prop aie_shim_stream_error_prop[] = {
508 {
509 .event = 63U,
510 .event_str = "control_packet_error",
511 },
512 {
513 .event = 64U,
514 .event_str = "axi-mm_decode_nsu_error",
515 },
516 {
517 .event = 65U,
518 .event_str = "axi-mm_slave_nsu_error",
519 },
520 {
521 .event = 66U,
522 .event_str = "axi-mm_unsupported_traffic",
523 },
524 {
525 .event = 67U,
526 .event_str = "axi-mm_unsecure_access_in_secure_mode",
527 },
528 {
529 .event = 68U,
530 .event_str = "axi-mm_byte_strobe_error",
531 },
532};
533
534static const struct aie_event_prop aie_shim_dma_error_prop[] = {
535 {
536 .event = 69U,
537 .event_str = "dma_s2mm_0_error",
538 },
539 {
540 .event = 70U,
541 .event_str = "dma_s2mm_1_error",
542 },
543 {
544 .event = 71U,
545 .event_str = "dma_mm2s_0_error",
546 },
547 {
548 .event = 72U,
549 .event_str = "dma_mm2s_1_error",
550 },
551};
552
553static const struct aie_err_category aie_core_err_category[] = {
554 {
555
556 .err_category = AIE_ERROR_CATEGORY_STREAM,
557 .num_events = ARRAY_SIZE(aie_core_stream_error_prop),
558 .prop = aie_core_stream_error_prop,
559 },
560 {
561
562 .err_category = AIE_ERROR_CATEGORY_ACCESS,
563 .num_events = ARRAY_SIZE(aie_core_access_error_prop),
564 .prop = aie_core_access_error_prop,
565 },
566 {
567
568 .err_category = AIE_ERROR_CATEGORY_BUS,
569 .num_events = ARRAY_SIZE(aie_core_bus_error_prop),
570 .prop = aie_core_bus_error_prop,
571 },
572 {
573
574 .err_category = AIE_ERROR_CATEGORY_INSTRUCTION,
575 .num_events = ARRAY_SIZE(aie_core_inst_error_prop),
576 .prop = aie_core_inst_error_prop,
577 },
578 {
579
580 .err_category = AIE_ERROR_CATEGORY_ECC,
581 .num_events = ARRAY_SIZE(aie_core_ecc_error_prop),
582 .prop = aie_core_ecc_error_prop,
583 },
584 {
585
586 .err_category = AIE_ERROR_CATEGORY_LOCK,
587 .num_events = ARRAY_SIZE(aie_core_lock_error_prop),
588 .prop = aie_core_lock_error_prop,
589 },
590};
591
592static const struct aie_err_category aie_mem_err_category[] = {
593 {
594
595 .err_category = AIE_ERROR_CATEGORY_ECC,
596 .num_events = ARRAY_SIZE(aie_mem_ecc_error_prop),
597 .prop = aie_mem_ecc_error_prop,
598 },
599 {
600
601 .err_category = AIE_ERROR_CATEGORY_MEM_PARITY,
602 .num_events = ARRAY_SIZE(aie_mem_parity_error_prop),
603 .prop = aie_mem_parity_error_prop,
604 },
605 {
606
607 .err_category = AIE_ERROR_CATEGORY_DMA,
608 .num_events = ARRAY_SIZE(aie_mem_dma_error_prop),
609 .prop = aie_mem_dma_error_prop,
610 },
611};
612
613static const struct aie_err_category aie_shim_err_category[] = {
614 {
615
616 .err_category = AIE_ERROR_CATEGORY_BUS,
617 .num_events = ARRAY_SIZE(aie_shim_bus_error_prop),
618 .prop = aie_shim_bus_error_prop,
619 },
620 {
621
622 .err_category = AIE_ERROR_CATEGORY_STREAM,
623 .num_events = ARRAY_SIZE(aie_shim_stream_error_prop),
624 .prop = aie_shim_stream_error_prop,
625 },
626 {
627
628 .err_category = AIE_ERROR_CATEGORY_DMA,
629 .num_events = ARRAY_SIZE(aie_shim_dma_error_prop),
630 .prop = aie_shim_dma_error_prop,
631 },
632};
633
634static const struct aie_error_attr aie_core_error = {
635 .num_err_categories = ARRAY_SIZE(aie_core_err_category),
636 .err_category = aie_core_err_category,
637};
638
639static const struct aie_error_attr aie_mem_error = {
640 .num_err_categories = ARRAY_SIZE(aie_mem_err_category),
641 .err_category = aie_mem_err_category,
642};
643
644static const struct aie_error_attr aie_shim_error = {
645 .num_err_categories = ARRAY_SIZE(aie_shim_err_category),
646 .err_category = aie_shim_err_category,
647};
648
649
650static const
651struct aie_tile_rsc_attr aie_core_tile_rscs_attr[AIE_RSCTYPE_MAX] = {
652 {
653
654 .mod_attr = {
655 {.num_rscs = AIE_NUM_PERF_MEM_MOD,},
656 {.num_rscs = AIE_NUM_PERF_CORE_MOD,},
657 },
658 },
659 {
660
661 .mod_attr = {
662 {.num_rscs = AIE_NUM_USEREVENT_MEM_MOD,},
663 {.num_rscs = AIE_NUM_USEREVENT_CORE_MOD,},
664 },
665 },
666 {
667
668 .mod_attr = {
669 {.num_rscs = AIE_NUM_TRACECONTROL_MEM_MOD,},
670 {.num_rscs = AIE_NUM_TRACECONTROL_CORE_MOD,},
671 },
672 },
673 {
674
675 .mod_attr = {
676 {.num_rscs = AIE_NUM_PCEVENT_MEM_MOD,},
677 {.num_rscs = AIE_NUM_PCEVENT_CORE_MOD,},
678 },
679 },
680 {
681
682 .mod_attr = {
683 {.num_rscs = AIE_NUM_SSSELECT_MEM_MOD,},
684 {.num_rscs = AIE_NUM_SSSELECT_CORE_MOD,},
685 },
686 },
687 {
688
689 .mod_attr = {
690 {.num_rscs = AIE_NUM_BROADCAST_MEM_MOD,},
691 {.num_rscs = AIE_NUM_BROADCAST_CORE_MOD,},
692 },
693 },
694 {
695
696 .mod_attr = {
697 {.num_rscs = AIE_NUM_COMBOEVENT_MEM_MOD,},
698 {.num_rscs = AIE_NUM_COMBOEVENT_CORE_MOD,},
699 },
700 },
701 {
702
703 .mod_attr = {
704 {.num_rscs = AIE_NUM_GROUPEVENTS_MEM_MOD,},
705 {.num_rscs = AIE_NUM_GROUPEVENTS_CORE_MOD,},
706 },
707 },
708};
709
710
711static const
712struct aie_tile_rsc_attr aie_shimpl_tile_rscs_attr[AIE_RSCTYPE_MAX] = {
713 {
714
715 .mod_attr = {
716 {.num_rscs = AIE_NUM_PERF_PL_MOD,},
717 },
718 },
719 {
720
721 .mod_attr = {
722 {.num_rscs = AIE_NUM_USEREVENT_PL_MOD,},
723 },
724 },
725 {
726
727 .mod_attr = {
728 {.num_rscs = AIE_NUM_TRACECONTROL_PL_MOD},
729 },
730 },
731 {
732
733 .mod_attr = {
734 {.num_rscs = AIE_NUM_PCEVENT_PL_MOD},
735 },
736 },
737 {
738
739 .mod_attr = {
740 {.num_rscs = AIE_NUM_SSSELECT_PL_MOD},
741 },
742 },
743 {
744
745 .mod_attr = {
746 {.num_rscs = AIE_NUM_BROADCAST_PL_MOD},
747 },
748 },
749 {
750
751 .mod_attr = {
752 {.num_rscs = AIE_NUM_COMBOEVENT_PL_MOD},
753 },
754 },
755 {
756
757 .mod_attr = {
758 {.num_rscs = AIE_NUM_GROUPEVENTS_PL_MOD},
759 },
760 },
761};
762
763
764static const
765enum aie_module_type aie_core_tile_module_types[NUM_MODS_CORE_TILE] = {
766 AIE_MEM_MOD,
767 AIE_CORE_MOD,
768};
769
770
771static const
772enum aie_module_type aie_shimpl_tile_module_types[NUM_MODS_SHIMPL_TILE] = {
773 AIE_PL_MOD,
774};
775
776static const struct aie_single_reg_field aie_core_sts = {
777 .mask = GENMASK(20, 0),
778 .regoff = 0x32004U,
779};
780
781static const struct aie_single_reg_field aie_core_done = {
782 .mask = BIT(20),
783 .regoff = 0x32004U,
784};
785
786static const struct aie_single_reg_field aie_core_disable_event_sts = {
787 .mask = BIT(15),
788 .regoff = 0x32008U,
789};
790
791static const struct aie_single_reg_field aie_core_pc = {
792 .mask = GENMASK(19, 0),
793 .regoff = 0x30280U,
794};
795
796static const struct aie_single_reg_field aie_core_lr = {
797 .mask = GENMASK(19, 0),
798 .regoff = 0x302B0U,
799};
800
801static const struct aie_single_reg_field aie_core_sp = {
802 .mask = GENMASK(19, 0),
803 .regoff = 0x302A0U,
804};
805
806static char *aie_core_status_str[] = {
807 "enabled",
808 "reset",
809 "south_memory_stall",
810 "west_memory_stall",
811 "north_memory_stall",
812 "east_memory_stall",
813 "south_lock_stall",
814 "west_lock_stall",
815 "north_lock_stall",
816 "east_lock_stall",
817 "stream_stall_ss0",
818 "stream_stall_ss1",
819 "stream_stall_ms0",
820 "stream_stall_ms1",
821 "cascade_stall_scd",
822 "cascade_stall_mcd",
823 "debug_halt",
824 "ecc_error_stall",
825 "ecc_scrubbing_stall",
826 "error_halt",
827 "core_done",
828};
829
830static const struct aie_lock_attr aie_pl_lock = {
831 .sts = {
832 .mask = GENMASK(1, 0),
833 .regoff = 2U,
834 },
835 .sts_regoff = 0x14F00,
836 .num_locks = 16U,
837};
838
839static const struct aie_lock_attr aie_mem_lock = {
840 .sts = {
841 .mask = GENMASK(1, 0),
842 .regoff = 2U,
843 },
844 .sts_regoff = 0x1EF00,
845 .num_locks = 16U,
846};
847
848static char *aie_lock_status_str[] = {
849 "released_for_write",
850 "acquired_for_write",
851 "released_for_read",
852 "acquired_for_read",
853};
854
855static const struct aie_dev_attr aie_tile_dev_attr[] = {
856 AIE_TILE_DEV_ATTR_RO(core, AIE_TILE_TYPE_MASK_TILE),
857 AIE_TILE_DEV_ATTR_RO(dma, AIE_TILE_TYPE_MASK_TILE |
858 AIE_TILE_TYPE_MASK_SHIMNOC),
859 AIE_TILE_DEV_ATTR_RO(error, AIE_TILE_TYPE_MASK_TILE |
860 AIE_TILE_TYPE_MASK_SHIMNOC |
861 AIE_TILE_TYPE_MASK_SHIMPL),
862 AIE_TILE_DEV_ATTR_RO(event, AIE_TILE_TYPE_MASK_TILE |
863 AIE_TILE_TYPE_MASK_SHIMNOC |
864 AIE_TILE_TYPE_MASK_SHIMPL),
865 AIE_TILE_DEV_ATTR_RO(lock, AIE_TILE_TYPE_MASK_TILE |
866 AIE_TILE_TYPE_MASK_SHIMNOC),
867};
868
869static const struct aie_dev_attr aie_part_dev_attr[] = {
870 AIE_PART_DEV_ATTR_RO(error_stat),
871};
872
873static const struct aie_bin_attr aie_part_bin_attr[] = {
874 AIE_PART_BIN_ATTR_RO(core, AIE_PART_SYSFS_CORE_BINA_SIZE),
875 AIE_PART_BIN_ATTR_RO(dma, AIE_PART_SYSFS_DMA_BINA_SIZE),
876 AIE_PART_BIN_ATTR_RO(error, AIE_PART_SYSFS_ERROR_BINA_SIZE),
877 AIE_PART_BIN_ATTR_RO(lock, AIE_PART_SYSFS_LOCK_BINA_SIZE),
878 AIE_PART_BIN_ATTR_RO(status, AIE_PART_SYSFS_STATUS_BINA_SIZE),
879};
880
881static const struct aie_sysfs_attr aie_part_sysfs_attr = {
882 .dev_attr = aie_part_dev_attr,
883 .bin_attr = aie_part_bin_attr,
884 .num_dev_attrs = ARRAY_SIZE(aie_part_dev_attr),
885 .num_bin_attrs = ARRAY_SIZE(aie_part_bin_attr),
886};
887
888static const struct aie_sysfs_attr aie_tile_sysfs_attr = {
889 .dev_attr = aie_tile_dev_attr,
890 .bin_attr = NULL,
891 .num_dev_attrs = ARRAY_SIZE(aie_tile_dev_attr),
892 .num_bin_attrs = 0U,
893};
894
895static u32 aie_get_tile_type(struct aie_location *loc)
896{
897 if (loc->row)
898 return AIE_TILE_TYPE_TILE;
899
900 if ((loc->col % 4) < 2)
901 return AIE_TILE_TYPE_SHIMPL;
902
903 return AIE_TILE_TYPE_SHIMNOC;
904}
905
906static unsigned int aie_get_mem_info(struct aie_range *range,
907 struct aie_part_mem *pmem)
908{
909 unsigned int i;
910
911 if (range->start.row + range->size.row <= 1) {
912
913 return 0;
914 }
915 if (!pmem)
916 return NUM_MEMS_PER_TILE;
917
918 for (i = 0; i < NUM_MEMS_PER_TILE; i++) {
919 struct aie_mem *mem = &pmem[i].mem;
920
921 memcpy(&mem->range, range, sizeof(*range));
922 if (!mem->range.start.row) {
923 mem->range.start.row = 1;
924 mem->range.size.row--;
925 }
926 }
927
928 pmem[0].mem.offset = 0;
929 pmem[0].mem.size = KBYTES(32);
930
931 pmem[1].mem.offset = 0x20000;
932 pmem[1].mem.size = KBYTES(16);
933
934 return NUM_MEMS_PER_TILE;
935}
936
937
938
939
940
941
942
943static void aie_set_shim_reset(struct aie_device *adev,
944 struct aie_range *range, bool assert)
945{
946 u32 c;
947 u32 val;
948 struct aie_location loc;
949
950 val = FIELD_PREP(AIE_SHIMPL_SHIMRST_MASK, (assert ? 1 : 0));
951 loc.row = 0;
952 for (c = range->start.col; c < range->start.col + range->size.col;
953 c++) {
954 u32 regoff;
955
956 loc.col = c;
957 regoff = aie_cal_regoff(adev, loc, AIE_SHIMPL_RESET_REGOFF);
958 iowrite32(val, adev->base + regoff);
959 }
960}
961
962static int aie_reset_shim(struct aie_device *adev, struct aie_range *range)
963{
964 int ret;
965
966
967 aie_set_shim_reset(adev, range, true);
968
969
970 ret = zynqmp_pm_reset_assert(VERSAL_PM_RST_AIE_SHIM_ID,
971 PM_RESET_ACTION_ASSERT);
972 if (ret < 0) {
973 dev_err(&adev->dev, "failed to assert SHIM reset.\n");
974 return ret;
975 }
976
977
978 ret = zynqmp_pm_reset_assert(VERSAL_PM_RST_AIE_SHIM_ID,
979 PM_RESET_ACTION_RELEASE);
980 if (ret < 0) {
981 dev_err(&adev->dev, "failed to release SHIM reset.\n");
982 return ret;
983 }
984
985
986 aie_set_shim_reset(adev, range, false);
987
988 return 0;
989}
990
991static int aie_init_part_clk_state(struct aie_partition *apart)
992{
993 int ret, num_tiles;
994
995 num_tiles = apart->range.size.col * (apart->range.size.row - 1);
996
997 ret = aie_resource_initialize(&apart->cores_clk_state, num_tiles);
998 if (ret) {
999 dev_err(&apart->dev,
1000 "failed to initialize cores clock state resource.\n");
1001 return ret;
1002 }
1003
1004 ret = aie_resource_initialize(&apart->tiles_inuse, num_tiles);
1005 if (ret) {
1006 dev_err(&apart->dev,
1007 "failed to initialize tiles in use resource.\n");
1008 return ret;
1009 }
1010
1011 return 0;
1012}
1013
1014static int aie_scan_part_clocks(struct aie_partition *apart)
1015{
1016 struct aie_device *adev = apart->adev;
1017 struct aie_range *range = &apart->range;
1018 struct aie_location loc;
1019
1020
1021 aie_resource_put_region(&apart->cores_clk_state, 0,
1022 apart->cores_clk_state.total);
1023
1024 for (loc.col = range->start.col;
1025 loc.col < range->start.col + range->size.col;
1026 loc.col++) {
1027 for (loc.row = range->start.row;
1028 loc.row < range->start.row + range->size.row - 1;
1029 loc.row++) {
1030 void __iomem *va;
1031 u32 val, nbitpos;
1032
1033
1034
1035
1036
1037 nbitpos = loc.col * (range->size.row - 1) + loc.row;
1038
1039 if (aie_get_tile_type(&loc) != AIE_TILE_TYPE_TILE) {
1040
1041 va = adev->base +
1042 aie_cal_regoff(adev, loc,
1043 AIE_SHIMPL_CLKCNTR_REGOFF);
1044 val = ioread32(va);
1045
1046
1047
1048
1049
1050
1051 if (!(val & AIE_SHIMPL_CLKCNTR_COLBUF_MASK) ||
1052 !(val & AIE_SHIMPL_CLKCNTR_NEXTCLK_MASK))
1053 break;
1054
1055
1056 aie_resource_set(&apart->cores_clk_state,
1057 nbitpos, 1);
1058 continue;
1059 }
1060
1061
1062 va = adev->base +
1063 aie_cal_regoff(adev, loc,
1064 AIE_TILE_CORE_CLKCNTR_REGOFF);
1065 val = ioread32(va);
1066
1067
1068
1069
1070
1071 if (!(val & AIE_TILE_CLKCNTR_NEXTCLK_MASK))
1072 break;
1073
1074 aie_resource_set(&apart->cores_clk_state, nbitpos, 1);
1075 }
1076 }
1077
1078
1079
1080
1081
1082
1083 bitmap_copy(apart->tiles_inuse.bitmap, apart->cores_clk_state.bitmap,
1084 apart->tiles_inuse.total);
1085
1086 return 0;
1087}
1088
1089
1090
1091
1092
1093
1094
1095static int aie_set_col_clocks(struct aie_partition *apart,
1096 struct aie_range *range, bool enable)
1097{
1098 struct aie_location ploc;
1099 u32 startbit;
1100
1101
1102
1103
1104
1105 if (range->size.col != 1 || range->start.row < 1)
1106 return -EINVAL;
1107
1108 ploc.col = range->start.col;
1109 for (ploc.row = range->start.row - 1;
1110 ploc.row < range->start.row + range->size.row - 1;
1111 ploc.row++) {
1112 struct aie_device *adev = apart->adev;
1113
1114 if (!ploc.row) {
1115 void __iomem *va;
1116 u32 val = 0;
1117
1118
1119
1120
1121
1122 if (enable)
1123 val = AIE_SHIMPL_CLKCNTR_COLBUF_MASK |
1124 AIE_SHIMPL_CLKCNTR_NEXTCLK_MASK;
1125 va = adev->base +
1126 aie_cal_regoff(adev, ploc,
1127 AIE_SHIMPL_CLKCNTR_REGOFF);
1128 iowrite32(val, va);
1129 } else {
1130 void __iomem *va;
1131 u32 val = 0;
1132
1133
1134
1135
1136
1137 if (enable)
1138 val = AIE_TILE_CLKCNTR_COLBUF_MASK |
1139 AIE_TILE_CLKCNTR_NEXTCLK_MASK;
1140 va = adev->base +
1141 aie_cal_regoff(adev, ploc,
1142 AIE_TILE_CORE_CLKCNTR_REGOFF);
1143 iowrite32(val, va);
1144 }
1145
1146
1147 if (!enable)
1148 break;
1149 }
1150
1151
1152 startbit = range->start.col * (apart->range.size.row - 1) +
1153 range->start.row - 1;
1154 if (enable)
1155 aie_resource_set(&apart->cores_clk_state, startbit,
1156 range->size.row);
1157 else
1158 aie_resource_clear(&apart->cores_clk_state, startbit,
1159 range->size.row);
1160
1161 return 0;
1162}
1163
1164static int aie_set_part_clocks(struct aie_partition *apart)
1165{
1166 struct aie_range *range = &apart->range, lrange;
1167 struct aie_location loc;
1168
1169
1170
1171
1172
1173
1174
1175 for (loc.col = range->start.col;
1176 loc.col < range->start.col + range->size.col;
1177 loc.col++) {
1178 u32 startbit, inuse_toprow = 0, clk_toprow = 0;
1179
1180 startbit = loc.col * (range->size.row - 1);
1181
1182 for (loc.row = range->start.row + 1;
1183 loc.row < range->start.row + range->size.row;
1184 loc.row++) {
1185 u32 bit = startbit + loc.row - 1;
1186
1187 if (aie_resource_testbit(&apart->tiles_inuse, bit))
1188 inuse_toprow = loc.row;
1189 if (aie_resource_testbit(&apart->cores_clk_state, bit))
1190 clk_toprow = loc.row;
1191 }
1192
1193
1194 lrange.start.col = loc.col;
1195 lrange.size.col = 1;
1196 if (inuse_toprow < clk_toprow) {
1197 lrange.start.row = inuse_toprow + 1;
1198 lrange.size.row = clk_toprow - inuse_toprow;
1199 aie_set_col_clocks(apart, &lrange, false);
1200 } else if (inuse_toprow > clk_toprow) {
1201 lrange.start.row = clk_toprow + 1;
1202 lrange.size.row = inuse_toprow - clk_toprow;
1203 aie_set_col_clocks(apart, &lrange, true);
1204 }
1205 }
1206
1207 return 0;
1208}
1209
1210
1211
1212
1213
1214
1215
1216static u32 aie_get_core_status(struct aie_partition *apart,
1217 struct aie_location *loc)
1218{
1219 u32 regoff, regvalue, eventval;
1220
1221 regoff = aie_cal_regoff(apart->adev, *loc, aie_core_sts.regoff);
1222 regvalue = ioread32(apart->adev->base + regoff);
1223
1224
1225 if (!FIELD_GET(aie_core_done.mask, regvalue)) {
1226 regoff = aie_cal_regoff(apart->adev, *loc,
1227 aie_core_disable_event_sts.regoff);
1228 eventval = ioread32(apart->adev->base + regoff);
1229
1230 if (FIELD_GET(aie_core_disable_event_sts.mask, eventval))
1231 regvalue |= aie_core_done.mask;
1232 }
1233 return regvalue;
1234}
1235
1236static const struct aie_tile_operations aie_ops = {
1237 .get_tile_type = aie_get_tile_type,
1238 .get_mem_info = aie_get_mem_info,
1239 .get_core_status = aie_get_core_status,
1240 .reset_shim = aie_reset_shim,
1241 .init_part_clk_state = aie_init_part_clk_state,
1242 .scan_part_clocks = aie_scan_part_clocks,
1243 .set_part_clocks = aie_set_part_clocks,
1244};
1245
1246
1247
1248
1249
1250
1251static void aie_device_init_rscs_attr(struct aie_device *adev)
1252{
1253 struct aie_tile_attr *tattr;
1254
1255 tattr = &adev->ttype_attr[AIE_TILE_TYPE_TILE];
1256 tattr->start_row = 1;
1257
1258
1259
1260
1261 tattr->num_rows = 0xFF;
1262 tattr->num_mods = 2;
1263 tattr->rscs_attr = aie_core_tile_rscs_attr;
1264 tattr->mods = aie_core_tile_module_types;
1265
1266 tattr = &adev->ttype_attr[AIE_TILE_TYPE_SHIMPL];
1267 tattr->start_row = 0;
1268 tattr->num_rows = 1;
1269 tattr->num_mods = 1;
1270 tattr->rscs_attr = aie_shimpl_tile_rscs_attr;
1271 tattr->mods = aie_shimpl_tile_module_types;
1272
1273
1274
1275
1276
1277
1278 tattr = &adev->ttype_attr[AIE_TILE_TYPE_SHIMNOC];
1279 tattr->start_row = 0;
1280 tattr->num_rows = 1;
1281 tattr->num_mods = 1;
1282 tattr->rscs_attr = aie_shimpl_tile_rscs_attr;
1283 tattr->mods = aie_shimpl_tile_module_types;
1284}
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296int aie_device_init(struct aie_device *adev)
1297{
1298 int ret;
1299
1300 adev->array_shift = AIE_ARRAY_SHIFT;
1301 adev->col_shift = AIE_COL_SHIFT;
1302 adev->row_shift = AIE_ROW_SHIFT;
1303 adev->ops = &aie_ops;
1304 adev->num_kernel_regs = ARRAY_SIZE(aie_kernel_regs);
1305 adev->kernel_regs = aie_kernel_regs;
1306 adev->num_core_regs = ARRAY_SIZE(aie_core_regs);
1307 adev->core_regs = aie_core_regs;
1308 adev->col_rst = &aie_col_rst;
1309 adev->col_clkbuf = &aie_col_clkbuf;
1310 adev->shim_dma = &aie_shimdma;
1311 adev->tile_dma = &aie_tiledma;
1312 adev->pl_events = &aie_pl_event;
1313 adev->mem_events = &aie_mem_event;
1314 adev->core_events = &aie_core_event;
1315 adev->l1_ctrl = &aie_l1_intr_ctrl;
1316 adev->l2_ctrl = &aie_l2_intr_ctrl;
1317 adev->core_errors = &aie_core_error;
1318 adev->mem_errors = &aie_mem_error;
1319 adev->shim_errors = &aie_shim_error;
1320 adev->part_sysfs_attr = &aie_part_sysfs_attr;
1321 adev->tile_sysfs_attr = &aie_tile_sysfs_attr;
1322 adev->core_status_str = aie_core_status_str;
1323 adev->core_pc = &aie_core_pc;
1324 adev->core_lr = &aie_core_lr;
1325 adev->core_sp = &aie_core_sp;
1326 adev->dma_status_str = aie_dma_status_str;
1327 adev->queue_status_str = aie_queue_status_str;
1328 adev->pl_lock = &aie_pl_lock;
1329 adev->mem_lock = &aie_mem_lock;
1330 adev->lock_status_str = aie_lock_status_str;
1331
1332 aie_device_init_rscs_attr(adev);
1333
1334
1335
1336 ret = aie_resource_initialize(&adev->cols_res, 50);
1337 if (ret)
1338 dev_err(&adev->dev, "failed to initialize columns resource.\n");
1339
1340 return ret;
1341}
1342