linux/drivers/misc/xilinx-ai-engine/ai-engine-aie.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx AI Engine driver AIE device specific implementation
   4 *
   5 * Copyright (C) 2020 Xilinx, Inc.
   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 * Number of resources per module
  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 * Registers offsets
  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 * Register masks
  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 * AI engine SHIM reset ID.
  91 * TODO: it should follow the Linux reset framework. The ID should be in the
  92 * device tree. However, as versal resets is not ready, we hardcode it in the
  93 * driver.
  94 */
  95#define VERSAL_PM_RST_AIE_SHIM_ID                       0xc10405fU
  96
  97/* Macros to define size of a sysfs binary attribute */
  98#define AIE_PART_SYSFS_CORE_BINA_SIZE           0x4000          /* 16KB */
  99#define AIE_PART_SYSFS_DMA_BINA_SIZE            0xC800          /* 50KB */
 100#define AIE_PART_SYSFS_LOCK_BINA_SIZE           0x28000         /* 160KB */
 101#define AIE_PART_SYSFS_ERROR_BINA_SIZE          0x4000          /* 16KB */
 102#define AIE_PART_SYSFS_STATUS_BINA_SIZE         0x3c000         /* 240KB */
 103
 104static const struct aie_tile_regs aie_kernel_regs[] = {
 105        /* SHIM AXI MM Config */
 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        /* SHIM DMA ADDRESS range */
 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        /* SHIM 2nd level interrupt controller */
 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        /* SHIM 1st level interrupt controller */
 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        /* SHIM column reset */
 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        /* SHIM reset Enable */
 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        /* SHIM clock control */
 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        /* SHIM group error enable */
 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        /* Tile clock control */
 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        /* Tile group error for core module */
 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        /* Tile group error for memory module */
 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                /* AIE_ERROR_CATEGORY_STREAM */
 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                /* AIE_ERROR_CATEGORY_ACCESS */
 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                /* AIE_ERROR_CATEGORY_BUS */
 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                /* AIE_ERROR_CATEGORY_INSTRUCTION */
 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                /* AIE_ERROR_CATEGORY_ECC */
 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                /* AIE_ERROR_CATEGORY_LOCK */
 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                /* AIE_ERROR_CATEGORY_ECC */
 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                /* AIE_ERROR_CATEGORY_MEM_PARITY */
 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                /* AIE_ERROR_CATEGORY_DMA */
 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                /* AIE_ERROR_CATEGORY_BUS */
 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                /* AIE_ERROR_CATEGORY_STREAM */
 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                /* AIE_ERROR_CATEGORY_DMA */
 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/* resource attributes for core tile type */
 650static const
 651struct aie_tile_rsc_attr aie_core_tile_rscs_attr[AIE_RSCTYPE_MAX] =  {
 652        {
 653                /* perf counter */
 654                .mod_attr = {
 655                        {.num_rscs = AIE_NUM_PERF_MEM_MOD,},
 656                        {.num_rscs = AIE_NUM_PERF_CORE_MOD,},
 657                },
 658        },
 659        {
 660                /* user event */
 661                .mod_attr = {
 662                        {.num_rscs = AIE_NUM_USEREVENT_MEM_MOD,},
 663                        {.num_rscs = AIE_NUM_USEREVENT_CORE_MOD,},
 664                },
 665        },
 666        {
 667                /* trace control */
 668                .mod_attr = {
 669                        {.num_rscs = AIE_NUM_TRACECONTROL_MEM_MOD,},
 670                        {.num_rscs = AIE_NUM_TRACECONTROL_CORE_MOD,},
 671                },
 672        },
 673        {
 674                /* pc event */
 675                .mod_attr = {
 676                        {.num_rscs = AIE_NUM_PCEVENT_MEM_MOD,},
 677                        {.num_rscs = AIE_NUM_PCEVENT_CORE_MOD,},
 678                },
 679        },
 680        {
 681                /* stream switch port select */
 682                .mod_attr = {
 683                        {.num_rscs = AIE_NUM_SSSELECT_MEM_MOD,},
 684                        {.num_rscs = AIE_NUM_SSSELECT_CORE_MOD,},
 685                },
 686        },
 687        {
 688                /* broadcast */
 689                .mod_attr = {
 690                        {.num_rscs = AIE_NUM_BROADCAST_MEM_MOD,},
 691                        {.num_rscs = AIE_NUM_BROADCAST_CORE_MOD,},
 692                },
 693        },
 694        {
 695                /* combo events */
 696                .mod_attr = {
 697                        {.num_rscs = AIE_NUM_COMBOEVENT_MEM_MOD,},
 698                        {.num_rscs = AIE_NUM_COMBOEVENT_CORE_MOD,},
 699                },
 700        },
 701        {
 702                /* group events */
 703                .mod_attr = {
 704                        {.num_rscs = AIE_NUM_GROUPEVENTS_MEM_MOD,},
 705                        {.num_rscs = AIE_NUM_GROUPEVENTS_CORE_MOD,},
 706                },
 707        },
 708};
 709
 710/* resource attributes for SHIM PL tile type */
 711static const
 712struct aie_tile_rsc_attr aie_shimpl_tile_rscs_attr[AIE_RSCTYPE_MAX] =  {
 713        {
 714                /* perf counter */
 715                .mod_attr = {
 716                        {.num_rscs = AIE_NUM_PERF_PL_MOD,},
 717                },
 718        },
 719        {
 720                /* user event */
 721                .mod_attr = {
 722                        {.num_rscs = AIE_NUM_USEREVENT_PL_MOD,},
 723                },
 724        },
 725        {
 726                /* trace control */
 727                .mod_attr = {
 728                        {.num_rscs = AIE_NUM_TRACECONTROL_PL_MOD},
 729                },
 730        },
 731        {
 732                /* pc event */
 733                .mod_attr = {
 734                        {.num_rscs = AIE_NUM_PCEVENT_PL_MOD},
 735                },
 736        },
 737        {
 738                /* stream switch port select */
 739                .mod_attr = {
 740                        {.num_rscs = AIE_NUM_SSSELECT_PL_MOD},
 741                },
 742        },
 743        {
 744                /* broadcast */
 745                .mod_attr = {
 746                        {.num_rscs = AIE_NUM_BROADCAST_PL_MOD},
 747                },
 748        },
 749        {
 750                /* combo events */
 751                .mod_attr = {
 752                        {.num_rscs = AIE_NUM_COMBOEVENT_PL_MOD},
 753                },
 754        },
 755        {
 756                /* group events */
 757                .mod_attr = {
 758                        {.num_rscs = AIE_NUM_GROUPEVENTS_PL_MOD},
 759                },
 760        },
 761};
 762
 763/* modules types array of CORE tile */
 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/* modules types array of SHIM PL tile */
 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        /* SHIM row */
 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                /* SHIM row only, no memories in this range */
 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        /* Setup tile data memory information */
 928        pmem[0].mem.offset = 0;
 929        pmem[0].mem.size = KBYTES(32);
 930        /* Setup program memory information */
 931        pmem[1].mem.offset = 0x20000;
 932        pmem[1].mem.size = KBYTES(16);
 933
 934        return NUM_MEMS_PER_TILE;
 935}
 936
 937/**
 938 * aie_set_shim_reset() - Set AI engine SHIM reset
 939 * @adev: AI engine device
 940 * @range: range of AI engine tiles
 941 * @assert: true to set reset, false to unset reset
 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        /* Enable shim reset of each column */
 967        aie_set_shim_reset(adev, range, true);
 968
 969        /* Assert shim reset of AI engine array */
 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        /* Release shim reset of AI engine array */
 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        /* Disable shim reset of each column */
 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        /* Clear the bitmap of cores and memories clock state */
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                         * Reading registers of the current tile to see the next
1035                         * tile is clock gated.
1036                         */
1037                        nbitpos = loc.col * (range->size.row - 1) + loc.row;
1038
1039                        if (aie_get_tile_type(&loc) != AIE_TILE_TYPE_TILE) {
1040                                /* Checks shim tile for next core tile */
1041                                va = adev->base +
1042                                     aie_cal_regoff(adev, loc,
1043                                                    AIE_SHIMPL_CLKCNTR_REGOFF);
1044                                val = ioread32(va);
1045
1046                                /*
1047                                 * check if the clock buffer and the next clock
1048                                 * tile is set, if one of them is not set, the
1049                                 * tiles of the column are clock gated.
1050                                 */
1051                                if (!(val & AIE_SHIMPL_CLKCNTR_COLBUF_MASK) ||
1052                                    !(val & AIE_SHIMPL_CLKCNTR_NEXTCLK_MASK))
1053                                        break;
1054
1055                                /* Set next tile in the row clock state on */
1056                                aie_resource_set(&apart->cores_clk_state,
1057                                                 nbitpos, 1);
1058                                continue;
1059                        }
1060
1061                        /* Checks core tile for next tile */
1062                        va = adev->base +
1063                             aie_cal_regoff(adev, loc,
1064                                            AIE_TILE_CORE_CLKCNTR_REGOFF);
1065                        val = ioread32(va);
1066
1067                        /*
1068                         * If the next tile is gated, skip the rest of the
1069                         * column.
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         * Set the tiles in use bitmap.
1080         * In case of scanning, tiles which are powered on are considered as
1081         * tiles in use.
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/* aie_set_col_clocks() - set clocks of a range of tiles of a column
1090 * @apart: AI engine partition
1091 * @range: range of tiles of a column
1092 * @enable: true to enable the clock, false to disable
1093 * @return: 0 for success, negative value of errors.
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         * check if the range is of single colum. only single column is allowed.
1103         * check if the start row is tile row, only tile rows are allowed.
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                         * Configure SHIM clock registers to gate or
1120                         * ungate next tile.
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                         * Configure core tile clock registers to gate
1135                         * or ungate next tile.
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                /* If the tile clock is not on, jump to next column */
1147                if (!enable)
1148                        break;
1149        }
1150
1151        /* Update clock state bitmap */
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         * The tiles below the highest tile whose clock is on, need to have the
1171         * clock on. The first for loop is to scan the clock states bitmap to
1172         * see which tiles are required to be clocked on, and update the bitmap
1173         * to make sure the tiles below are also required to be clocked on.
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                /* Update clock states of a column */
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 * aie_get_core_status() - read the AI engine core status register.
1212 * @apart: AI engine partition.
1213 * @loc: location of AI engine core.
1214 * @return: 32-bit register value.
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        /* Apply core done workaround */
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 * aie_device_init_rscs_attr() - initialize AI engine device resources
1248 *                               attributes
1249 * @adev: AI engine device
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         * TODO: number of rows information of the AI engine device should get
1259         * from device tree.
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         * For now, SHIMNOC is the same as SHIMPL as there is
1275         * no SHIMNOC specific resources managed by kernel
1276         * driver yet.
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 * aie_device_init() - Initialize AI engine device struct AIE specific
1288 * @adev: AI engine device
1289 * @return: 0 for success, negative value for failure.
1290 *
1291 * This function initialize the AI engine device structure device version
1292 * specific elements such as register addressing related array shift,
1293 * column shift, and row shift; AIE device specific device operations, device
1294 * columns resource.
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        /* Get the columns resource */
1335        /* Get number of columns from AI engine memory resource */
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