1fe83ffd9SSrikanth Yalavarthi /* SPDX-License-Identifier: BSD-3-Clause 2fe83ffd9SSrikanth Yalavarthi * Copyright (c) 2022 Marvell. 3fe83ffd9SSrikanth Yalavarthi */ 4fe83ffd9SSrikanth Yalavarthi 5f3442efeSSrikanth Yalavarthi #include <rte_common.h> 6f3442efeSSrikanth Yalavarthi #include <rte_dev.h> 734468620SSrikanth Yalavarthi #include <rte_devargs.h> 834468620SSrikanth Yalavarthi #include <rte_kvargs.h> 9fe83ffd9SSrikanth Yalavarthi #include <rte_mldev.h> 10fe83ffd9SSrikanth Yalavarthi #include <rte_mldev_pmd.h> 11f3442efeSSrikanth Yalavarthi #include <rte_pci.h> 12f3442efeSSrikanth Yalavarthi 13c29da752SSrikanth Yalavarthi #include <eal_firmware.h> 14c29da752SSrikanth Yalavarthi 154af704caSSrikanth Yalavarthi #include <roc_api.h> 164af704caSSrikanth Yalavarthi 174af704caSSrikanth Yalavarthi #include "cnxk_ml_dev.h" 186e402621SSrikanth Yalavarthi #include "cnxk_ml_ops.h" 194af704caSSrikanth Yalavarthi 2034468620SSrikanth Yalavarthi #define CN10K_ML_FW_PATH "fw_path" 215a7b8abdSSrikanth Yalavarthi #define CN10K_ML_FW_ENABLE_DPE_WARNINGS "enable_dpe_warnings" 225a7b8abdSSrikanth Yalavarthi #define CN10K_ML_FW_REPORT_DPE_WARNINGS "report_dpe_warnings" 235e2a82b9SSrikanth Yalavarthi #define CN10K_ML_DEV_CACHE_MODEL_DATA "cache_model_data" 24783932efSSrikanth Yalavarthi #define CN10K_ML_OCM_ALLOC_MODE "ocm_alloc_mode" 25d646b82aSSrikanth Yalavarthi #define CN10K_ML_DEV_HW_QUEUE_LOCK "hw_queue_lock" 26515e3608SSrikanth Yalavarthi #define CN10K_ML_OCM_PAGE_SIZE "ocm_page_size" 2734468620SSrikanth Yalavarthi 2834468620SSrikanth Yalavarthi #define CN10K_ML_FW_PATH_DEFAULT "/lib/firmware/mlip-fw.bin" 295a7b8abdSSrikanth Yalavarthi #define CN10K_ML_FW_ENABLE_DPE_WARNINGS_DEFAULT 1 305a7b8abdSSrikanth Yalavarthi #define CN10K_ML_FW_REPORT_DPE_WARNINGS_DEFAULT 0 315e2a82b9SSrikanth Yalavarthi #define CN10K_ML_DEV_CACHE_MODEL_DATA_DEFAULT 1 32783932efSSrikanth Yalavarthi #define CN10K_ML_OCM_ALLOC_MODE_DEFAULT "lowest" 33d646b82aSSrikanth Yalavarthi #define CN10K_ML_DEV_HW_QUEUE_LOCK_DEFAULT 1 34515e3608SSrikanth Yalavarthi #define CN10K_ML_OCM_PAGE_SIZE_DEFAULT 16384 3534468620SSrikanth Yalavarthi 36c29da752SSrikanth Yalavarthi /* ML firmware macros */ 37c29da752SSrikanth Yalavarthi #define FW_MEMZONE_NAME "ml_cn10k_fw_mz" 38c29da752SSrikanth Yalavarthi #define FW_STACK_BUFFER_SIZE 0x40000 39c29da752SSrikanth Yalavarthi #define FW_DEBUG_BUFFER_SIZE (2 * 0x20000) 40c29da752SSrikanth Yalavarthi #define FW_EXCEPTION_BUFFER_SIZE 0x400 41c29da752SSrikanth Yalavarthi #define FW_LINKER_OFFSET 0x80000 42c29da752SSrikanth Yalavarthi #define FW_WAIT_CYCLES 100 43c29da752SSrikanth Yalavarthi 445a7b8abdSSrikanth Yalavarthi /* Firmware flags */ 455a7b8abdSSrikanth Yalavarthi #define FW_ENABLE_DPE_WARNING_BITMASK BIT(0) 465a7b8abdSSrikanth Yalavarthi #define FW_REPORT_DPE_WARNING_BITMASK BIT(1) 473c9029afSSrikanth Yalavarthi #define FW_USE_DDR_POLL_ADDR_FP BIT(2) 485a7b8abdSSrikanth Yalavarthi 49783932efSSrikanth Yalavarthi static const char *const valid_args[] = {CN10K_ML_FW_PATH, 50783932efSSrikanth Yalavarthi CN10K_ML_FW_ENABLE_DPE_WARNINGS, 515e2a82b9SSrikanth Yalavarthi CN10K_ML_FW_REPORT_DPE_WARNINGS, 52783932efSSrikanth Yalavarthi CN10K_ML_DEV_CACHE_MODEL_DATA, 53783932efSSrikanth Yalavarthi CN10K_ML_OCM_ALLOC_MODE, 54d646b82aSSrikanth Yalavarthi CN10K_ML_DEV_HW_QUEUE_LOCK, 55515e3608SSrikanth Yalavarthi CN10K_ML_OCM_PAGE_SIZE, 56783932efSSrikanth Yalavarthi NULL}; 5734468620SSrikanth Yalavarthi 58515e3608SSrikanth Yalavarthi /* Supported OCM page sizes: 1KB, 2KB, 4KB, 8KB and 16KB */ 59515e3608SSrikanth Yalavarthi static const int valid_ocm_page_size[] = {1024, 2048, 4096, 8192, 16384}; 60515e3608SSrikanth Yalavarthi 61*63b82e24SSrikanth Yalavarthi /* Error type database */ 62*63b82e24SSrikanth Yalavarthi struct cn10k_ml_error_db ml_etype_db[] = { 63*63b82e24SSrikanth Yalavarthi {ML_CN10K_ETYPE_NO_ERROR, "NO_ERROR"}, {ML_CN10K_ETYPE_FW_NONFATAL, "FW_NON_FATAL"}, 64*63b82e24SSrikanth Yalavarthi {ML_CN10K_ETYPE_HW_NONFATAL, "HW_NON_FATAL"}, {ML_CN10K_ETYPE_HW_FATAL, "HW_FATAL"}, 65*63b82e24SSrikanth Yalavarthi {ML_CN10K_ETYPE_HW_WARNING, "HW_WARNING"}, {ML_CN10K_ETYPE_DRIVER, "DRIVER_ERROR"}, 66*63b82e24SSrikanth Yalavarthi {ML_CN10K_ETYPE_UNKNOWN, "UNKNOWN_ERROR"}, 67*63b82e24SSrikanth Yalavarthi }; 68*63b82e24SSrikanth Yalavarthi 69f3442efeSSrikanth Yalavarthi static int 7034468620SSrikanth Yalavarthi parse_string_arg(const char *key __rte_unused, const char *value, void *extra_args) 7134468620SSrikanth Yalavarthi { 7234468620SSrikanth Yalavarthi if (value == NULL || extra_args == NULL) 7334468620SSrikanth Yalavarthi return -EINVAL; 7434468620SSrikanth Yalavarthi 7534468620SSrikanth Yalavarthi *(char **)extra_args = strdup(value); 7634468620SSrikanth Yalavarthi 7734468620SSrikanth Yalavarthi if (!*(char **)extra_args) 7834468620SSrikanth Yalavarthi return -ENOMEM; 7934468620SSrikanth Yalavarthi 8034468620SSrikanth Yalavarthi return 0; 8134468620SSrikanth Yalavarthi } 8234468620SSrikanth Yalavarthi 8334468620SSrikanth Yalavarthi static int 845a7b8abdSSrikanth Yalavarthi parse_integer_arg(const char *key __rte_unused, const char *value, void *extra_args) 855a7b8abdSSrikanth Yalavarthi { 865a7b8abdSSrikanth Yalavarthi int *i = (int *)extra_args; 875a7b8abdSSrikanth Yalavarthi 885a7b8abdSSrikanth Yalavarthi *i = atoi(value); 895a7b8abdSSrikanth Yalavarthi if (*i < 0) { 905a7b8abdSSrikanth Yalavarthi plt_err("Argument has to be positive."); 915a7b8abdSSrikanth Yalavarthi return -EINVAL; 925a7b8abdSSrikanth Yalavarthi } 935a7b8abdSSrikanth Yalavarthi 945a7b8abdSSrikanth Yalavarthi return 0; 955a7b8abdSSrikanth Yalavarthi } 965a7b8abdSSrikanth Yalavarthi 975a7b8abdSSrikanth Yalavarthi static int 984af704caSSrikanth Yalavarthi cn10k_mldev_parse_devargs(struct rte_devargs *devargs, struct cn10k_ml_dev *cn10k_mldev) 9934468620SSrikanth Yalavarthi { 1005a7b8abdSSrikanth Yalavarthi bool enable_dpe_warnings_set = false; 1015a7b8abdSSrikanth Yalavarthi bool report_dpe_warnings_set = false; 1025e2a82b9SSrikanth Yalavarthi bool cache_model_data_set = false; 10334468620SSrikanth Yalavarthi struct rte_kvargs *kvlist = NULL; 104783932efSSrikanth Yalavarthi bool ocm_alloc_mode_set = false; 105d646b82aSSrikanth Yalavarthi bool hw_queue_lock_set = false; 106515e3608SSrikanth Yalavarthi bool ocm_page_size_set = false; 107783932efSSrikanth Yalavarthi char *ocm_alloc_mode = NULL; 10834468620SSrikanth Yalavarthi bool fw_path_set = false; 10934468620SSrikanth Yalavarthi char *fw_path = NULL; 11034468620SSrikanth Yalavarthi int ret = 0; 111515e3608SSrikanth Yalavarthi bool found; 112515e3608SSrikanth Yalavarthi uint8_t i; 11334468620SSrikanth Yalavarthi 11434468620SSrikanth Yalavarthi if (devargs == NULL) 11534468620SSrikanth Yalavarthi goto check_args; 11634468620SSrikanth Yalavarthi 11734468620SSrikanth Yalavarthi kvlist = rte_kvargs_parse(devargs->args, valid_args); 11834468620SSrikanth Yalavarthi if (kvlist == NULL) { 119f665790aSDavid Marchand plt_err("Error parsing devargs"); 12034468620SSrikanth Yalavarthi return -EINVAL; 12134468620SSrikanth Yalavarthi } 12234468620SSrikanth Yalavarthi 12334468620SSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_FW_PATH) == 1) { 12434468620SSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_FW_PATH, &parse_string_arg, &fw_path); 12534468620SSrikanth Yalavarthi if (ret < 0) { 126f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", CN10K_ML_FW_PATH); 12734468620SSrikanth Yalavarthi ret = -EINVAL; 12834468620SSrikanth Yalavarthi goto exit; 12934468620SSrikanth Yalavarthi } 13034468620SSrikanth Yalavarthi fw_path_set = true; 13134468620SSrikanth Yalavarthi } 13234468620SSrikanth Yalavarthi 1335a7b8abdSSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_FW_ENABLE_DPE_WARNINGS) == 1) { 1345a7b8abdSSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_FW_ENABLE_DPE_WARNINGS, 1354af704caSSrikanth Yalavarthi &parse_integer_arg, &cn10k_mldev->fw.enable_dpe_warnings); 1365a7b8abdSSrikanth Yalavarthi if (ret < 0) { 137f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", 1385a7b8abdSSrikanth Yalavarthi CN10K_ML_FW_ENABLE_DPE_WARNINGS); 1395a7b8abdSSrikanth Yalavarthi ret = -EINVAL; 1405a7b8abdSSrikanth Yalavarthi goto exit; 1415a7b8abdSSrikanth Yalavarthi } 1425a7b8abdSSrikanth Yalavarthi enable_dpe_warnings_set = true; 1435a7b8abdSSrikanth Yalavarthi } 1445a7b8abdSSrikanth Yalavarthi 1455a7b8abdSSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_FW_REPORT_DPE_WARNINGS) == 1) { 1465a7b8abdSSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_FW_REPORT_DPE_WARNINGS, 1474af704caSSrikanth Yalavarthi &parse_integer_arg, &cn10k_mldev->fw.report_dpe_warnings); 1485a7b8abdSSrikanth Yalavarthi if (ret < 0) { 149f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", 1505a7b8abdSSrikanth Yalavarthi CN10K_ML_FW_REPORT_DPE_WARNINGS); 1515a7b8abdSSrikanth Yalavarthi ret = -EINVAL; 1525a7b8abdSSrikanth Yalavarthi goto exit; 1535a7b8abdSSrikanth Yalavarthi } 1545a7b8abdSSrikanth Yalavarthi report_dpe_warnings_set = true; 1555a7b8abdSSrikanth Yalavarthi } 1565a7b8abdSSrikanth Yalavarthi 1575e2a82b9SSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_DEV_CACHE_MODEL_DATA) == 1) { 1585e2a82b9SSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_DEV_CACHE_MODEL_DATA, &parse_integer_arg, 1594af704caSSrikanth Yalavarthi &cn10k_mldev->cache_model_data); 1605e2a82b9SSrikanth Yalavarthi if (ret < 0) { 161f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", 1625e2a82b9SSrikanth Yalavarthi CN10K_ML_DEV_CACHE_MODEL_DATA); 1635e2a82b9SSrikanth Yalavarthi ret = -EINVAL; 1645e2a82b9SSrikanth Yalavarthi goto exit; 1655e2a82b9SSrikanth Yalavarthi } 1665e2a82b9SSrikanth Yalavarthi cache_model_data_set = true; 1675e2a82b9SSrikanth Yalavarthi } 1685e2a82b9SSrikanth Yalavarthi 169783932efSSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_OCM_ALLOC_MODE) == 1) { 170783932efSSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_OCM_ALLOC_MODE, &parse_string_arg, 171783932efSSrikanth Yalavarthi &ocm_alloc_mode); 172783932efSSrikanth Yalavarthi if (ret < 0) { 173f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", CN10K_ML_OCM_ALLOC_MODE); 174783932efSSrikanth Yalavarthi ret = -EINVAL; 175783932efSSrikanth Yalavarthi goto exit; 176783932efSSrikanth Yalavarthi } 177783932efSSrikanth Yalavarthi ocm_alloc_mode_set = true; 178783932efSSrikanth Yalavarthi } 179783932efSSrikanth Yalavarthi 180d646b82aSSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_DEV_HW_QUEUE_LOCK) == 1) { 181d646b82aSSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_DEV_HW_QUEUE_LOCK, &parse_integer_arg, 1824af704caSSrikanth Yalavarthi &cn10k_mldev->hw_queue_lock); 183d646b82aSSrikanth Yalavarthi if (ret < 0) { 184f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", 185d646b82aSSrikanth Yalavarthi CN10K_ML_DEV_HW_QUEUE_LOCK); 186d646b82aSSrikanth Yalavarthi ret = -EINVAL; 187d646b82aSSrikanth Yalavarthi goto exit; 188d646b82aSSrikanth Yalavarthi } 189d646b82aSSrikanth Yalavarthi hw_queue_lock_set = true; 190d646b82aSSrikanth Yalavarthi } 191d646b82aSSrikanth Yalavarthi 192515e3608SSrikanth Yalavarthi if (rte_kvargs_count(kvlist, CN10K_ML_OCM_PAGE_SIZE) == 1) { 193515e3608SSrikanth Yalavarthi ret = rte_kvargs_process(kvlist, CN10K_ML_OCM_PAGE_SIZE, &parse_integer_arg, 1944af704caSSrikanth Yalavarthi &cn10k_mldev->ocm_page_size); 195515e3608SSrikanth Yalavarthi if (ret < 0) { 196f665790aSDavid Marchand plt_err("Error processing arguments, key = %s", CN10K_ML_OCM_PAGE_SIZE); 197515e3608SSrikanth Yalavarthi ret = -EINVAL; 198515e3608SSrikanth Yalavarthi goto exit; 199515e3608SSrikanth Yalavarthi } 200515e3608SSrikanth Yalavarthi ocm_page_size_set = true; 201515e3608SSrikanth Yalavarthi } 202515e3608SSrikanth Yalavarthi 20334468620SSrikanth Yalavarthi check_args: 20434468620SSrikanth Yalavarthi if (!fw_path_set) 2054af704caSSrikanth Yalavarthi cn10k_mldev->fw.path = CN10K_ML_FW_PATH_DEFAULT; 20634468620SSrikanth Yalavarthi else 2074af704caSSrikanth Yalavarthi cn10k_mldev->fw.path = fw_path; 2084af704caSSrikanth Yalavarthi plt_info("ML: %s = %s", CN10K_ML_FW_PATH, cn10k_mldev->fw.path); 20934468620SSrikanth Yalavarthi 2105a7b8abdSSrikanth Yalavarthi if (!enable_dpe_warnings_set) { 2114af704caSSrikanth Yalavarthi cn10k_mldev->fw.enable_dpe_warnings = CN10K_ML_FW_ENABLE_DPE_WARNINGS_DEFAULT; 2125a7b8abdSSrikanth Yalavarthi } else { 2134af704caSSrikanth Yalavarthi if ((cn10k_mldev->fw.enable_dpe_warnings < 0) || 2144af704caSSrikanth Yalavarthi (cn10k_mldev->fw.enable_dpe_warnings > 1)) { 215f665790aSDavid Marchand plt_err("Invalid argument, %s = %d", CN10K_ML_FW_ENABLE_DPE_WARNINGS, 2164af704caSSrikanth Yalavarthi cn10k_mldev->fw.enable_dpe_warnings); 2175a7b8abdSSrikanth Yalavarthi ret = -EINVAL; 2185a7b8abdSSrikanth Yalavarthi goto exit; 2195a7b8abdSSrikanth Yalavarthi } 2205a7b8abdSSrikanth Yalavarthi } 2214af704caSSrikanth Yalavarthi plt_info("ML: %s = %d", CN10K_ML_FW_ENABLE_DPE_WARNINGS, 2224af704caSSrikanth Yalavarthi cn10k_mldev->fw.enable_dpe_warnings); 2235a7b8abdSSrikanth Yalavarthi 2245a7b8abdSSrikanth Yalavarthi if (!report_dpe_warnings_set) { 2254af704caSSrikanth Yalavarthi cn10k_mldev->fw.report_dpe_warnings = CN10K_ML_FW_REPORT_DPE_WARNINGS_DEFAULT; 2265a7b8abdSSrikanth Yalavarthi } else { 2274af704caSSrikanth Yalavarthi if ((cn10k_mldev->fw.report_dpe_warnings < 0) || 2284af704caSSrikanth Yalavarthi (cn10k_mldev->fw.report_dpe_warnings > 1)) { 229f665790aSDavid Marchand plt_err("Invalid argument, %s = %d", CN10K_ML_FW_REPORT_DPE_WARNINGS, 2304af704caSSrikanth Yalavarthi cn10k_mldev->fw.report_dpe_warnings); 2315a7b8abdSSrikanth Yalavarthi ret = -EINVAL; 2325a7b8abdSSrikanth Yalavarthi goto exit; 2335a7b8abdSSrikanth Yalavarthi } 2345a7b8abdSSrikanth Yalavarthi } 2354af704caSSrikanth Yalavarthi plt_info("ML: %s = %d", CN10K_ML_FW_REPORT_DPE_WARNINGS, 2364af704caSSrikanth Yalavarthi cn10k_mldev->fw.report_dpe_warnings); 2375a7b8abdSSrikanth Yalavarthi 2385e2a82b9SSrikanth Yalavarthi if (!cache_model_data_set) { 2394af704caSSrikanth Yalavarthi cn10k_mldev->cache_model_data = CN10K_ML_DEV_CACHE_MODEL_DATA_DEFAULT; 2405e2a82b9SSrikanth Yalavarthi } else { 2414af704caSSrikanth Yalavarthi if ((cn10k_mldev->cache_model_data < 0) || (cn10k_mldev->cache_model_data > 1)) { 242f665790aSDavid Marchand plt_err("Invalid argument, %s = %d", CN10K_ML_DEV_CACHE_MODEL_DATA, 2434af704caSSrikanth Yalavarthi cn10k_mldev->cache_model_data); 2445e2a82b9SSrikanth Yalavarthi ret = -EINVAL; 2455e2a82b9SSrikanth Yalavarthi goto exit; 2465e2a82b9SSrikanth Yalavarthi } 2475e2a82b9SSrikanth Yalavarthi } 2484af704caSSrikanth Yalavarthi plt_info("ML: %s = %d", CN10K_ML_DEV_CACHE_MODEL_DATA, cn10k_mldev->cache_model_data); 2495e2a82b9SSrikanth Yalavarthi 250783932efSSrikanth Yalavarthi if (!ocm_alloc_mode_set) { 2514af704caSSrikanth Yalavarthi cn10k_mldev->ocm.alloc_mode = CN10K_ML_OCM_ALLOC_MODE_DEFAULT; 252783932efSSrikanth Yalavarthi } else { 253783932efSSrikanth Yalavarthi if (!((strcmp(ocm_alloc_mode, "lowest") == 0) || 254783932efSSrikanth Yalavarthi (strcmp(ocm_alloc_mode, "largest") == 0))) { 255f665790aSDavid Marchand plt_err("Invalid argument, %s = %s", CN10K_ML_OCM_ALLOC_MODE, 256783932efSSrikanth Yalavarthi ocm_alloc_mode); 257783932efSSrikanth Yalavarthi ret = -EINVAL; 258783932efSSrikanth Yalavarthi goto exit; 259783932efSSrikanth Yalavarthi } 2604af704caSSrikanth Yalavarthi cn10k_mldev->ocm.alloc_mode = ocm_alloc_mode; 261783932efSSrikanth Yalavarthi } 2624af704caSSrikanth Yalavarthi plt_info("ML: %s = %s", CN10K_ML_OCM_ALLOC_MODE, cn10k_mldev->ocm.alloc_mode); 263783932efSSrikanth Yalavarthi 264d646b82aSSrikanth Yalavarthi if (!hw_queue_lock_set) { 2654af704caSSrikanth Yalavarthi cn10k_mldev->hw_queue_lock = CN10K_ML_DEV_HW_QUEUE_LOCK_DEFAULT; 266d646b82aSSrikanth Yalavarthi } else { 2674af704caSSrikanth Yalavarthi if ((cn10k_mldev->hw_queue_lock < 0) || (cn10k_mldev->hw_queue_lock > 1)) { 268f665790aSDavid Marchand plt_err("Invalid argument, %s = %d", CN10K_ML_DEV_HW_QUEUE_LOCK, 2694af704caSSrikanth Yalavarthi cn10k_mldev->hw_queue_lock); 270d646b82aSSrikanth Yalavarthi ret = -EINVAL; 271d646b82aSSrikanth Yalavarthi goto exit; 272d646b82aSSrikanth Yalavarthi } 273d646b82aSSrikanth Yalavarthi } 2744af704caSSrikanth Yalavarthi plt_info("ML: %s = %d", CN10K_ML_DEV_HW_QUEUE_LOCK, cn10k_mldev->hw_queue_lock); 275d646b82aSSrikanth Yalavarthi 276515e3608SSrikanth Yalavarthi if (!ocm_page_size_set) { 2774af704caSSrikanth Yalavarthi cn10k_mldev->ocm_page_size = CN10K_ML_OCM_PAGE_SIZE_DEFAULT; 278515e3608SSrikanth Yalavarthi } else { 2794af704caSSrikanth Yalavarthi if (cn10k_mldev->ocm_page_size < 0) { 280f665790aSDavid Marchand plt_err("Invalid argument, %s = %d", CN10K_ML_OCM_PAGE_SIZE, 2814af704caSSrikanth Yalavarthi cn10k_mldev->ocm_page_size); 282515e3608SSrikanth Yalavarthi ret = -EINVAL; 283515e3608SSrikanth Yalavarthi goto exit; 284515e3608SSrikanth Yalavarthi } 285515e3608SSrikanth Yalavarthi 286515e3608SSrikanth Yalavarthi found = false; 287515e3608SSrikanth Yalavarthi for (i = 0; i < PLT_DIM(valid_ocm_page_size); i++) { 2884af704caSSrikanth Yalavarthi if (cn10k_mldev->ocm_page_size == valid_ocm_page_size[i]) { 289515e3608SSrikanth Yalavarthi found = true; 290515e3608SSrikanth Yalavarthi break; 291515e3608SSrikanth Yalavarthi } 292515e3608SSrikanth Yalavarthi } 293515e3608SSrikanth Yalavarthi 294515e3608SSrikanth Yalavarthi if (!found) { 295f665790aSDavid Marchand plt_err("Unsupported ocm_page_size = %d", cn10k_mldev->ocm_page_size); 296515e3608SSrikanth Yalavarthi ret = -EINVAL; 297515e3608SSrikanth Yalavarthi goto exit; 298515e3608SSrikanth Yalavarthi } 299515e3608SSrikanth Yalavarthi } 3004af704caSSrikanth Yalavarthi plt_info("ML: %s = %d", CN10K_ML_OCM_PAGE_SIZE, cn10k_mldev->ocm_page_size); 301515e3608SSrikanth Yalavarthi 30234468620SSrikanth Yalavarthi exit: 30334468620SSrikanth Yalavarthi rte_kvargs_free(kvlist); 30434468620SSrikanth Yalavarthi 30534468620SSrikanth Yalavarthi return ret; 30634468620SSrikanth Yalavarthi } 30734468620SSrikanth Yalavarthi 30834468620SSrikanth Yalavarthi static int 309f3442efeSSrikanth Yalavarthi cn10k_ml_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev) 310f3442efeSSrikanth Yalavarthi { 311f3442efeSSrikanth Yalavarthi struct rte_ml_dev_pmd_init_params init_params; 3124af704caSSrikanth Yalavarthi struct cn10k_ml_dev *cn10k_mldev; 3134af704caSSrikanth Yalavarthi struct cnxk_ml_dev *cnxk_mldev; 314f3442efeSSrikanth Yalavarthi char name[RTE_ML_STR_MAX]; 315f3442efeSSrikanth Yalavarthi struct rte_ml_dev *dev; 316f3442efeSSrikanth Yalavarthi int ret; 317f3442efeSSrikanth Yalavarthi 318f3442efeSSrikanth Yalavarthi PLT_SET_USED(pci_drv); 319f3442efeSSrikanth Yalavarthi 32048c6081aSSrikanth Yalavarthi if (cnxk_ml_dev_initialized == 1) { 32148c6081aSSrikanth Yalavarthi plt_err("ML CNXK device already initialized!"); 32248c6081aSSrikanth Yalavarthi plt_err("Cannot initialize CN10K PCI dev"); 32348c6081aSSrikanth Yalavarthi return -EINVAL; 32448c6081aSSrikanth Yalavarthi } 32548c6081aSSrikanth Yalavarthi 326f3442efeSSrikanth Yalavarthi init_params = (struct rte_ml_dev_pmd_init_params){ 3274af704caSSrikanth Yalavarthi .socket_id = rte_socket_id(), .private_data_size = sizeof(struct cnxk_ml_dev)}; 328f3442efeSSrikanth Yalavarthi 329f3442efeSSrikanth Yalavarthi ret = roc_plt_init(); 330f3442efeSSrikanth Yalavarthi if (ret < 0) { 331f3442efeSSrikanth Yalavarthi plt_err("Failed to initialize platform model"); 332f3442efeSSrikanth Yalavarthi return ret; 333f3442efeSSrikanth Yalavarthi } 334f3442efeSSrikanth Yalavarthi 335f3442efeSSrikanth Yalavarthi rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); 336f3442efeSSrikanth Yalavarthi dev = rte_ml_dev_pmd_create(name, &pci_dev->device, &init_params); 337f3442efeSSrikanth Yalavarthi if (dev == NULL) { 338f3442efeSSrikanth Yalavarthi ret = -ENODEV; 339f3442efeSSrikanth Yalavarthi goto error_exit; 340f3442efeSSrikanth Yalavarthi } 341f3442efeSSrikanth Yalavarthi 342f3442efeSSrikanth Yalavarthi /* Get private data space allocated */ 3434af704caSSrikanth Yalavarthi cnxk_mldev = dev->data->dev_private; 3444af704caSSrikanth Yalavarthi cnxk_mldev->mldev = dev; 3454af704caSSrikanth Yalavarthi cn10k_mldev = &cnxk_mldev->cn10k_mldev; 346f3442efeSSrikanth Yalavarthi 347f3442efeSSrikanth Yalavarthi if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 3484af704caSSrikanth Yalavarthi cn10k_mldev->roc.pci_dev = pci_dev; 349f3442efeSSrikanth Yalavarthi 3504af704caSSrikanth Yalavarthi ret = cn10k_mldev_parse_devargs(dev->device->devargs, cn10k_mldev); 35134468620SSrikanth Yalavarthi if (ret) { 35234468620SSrikanth Yalavarthi plt_err("Failed to parse devargs ret = %d", ret); 35334468620SSrikanth Yalavarthi goto pmd_destroy; 35434468620SSrikanth Yalavarthi } 35534468620SSrikanth Yalavarthi 3564af704caSSrikanth Yalavarthi ret = roc_ml_dev_init(&cn10k_mldev->roc); 357f3442efeSSrikanth Yalavarthi if (ret) { 358f3442efeSSrikanth Yalavarthi plt_err("Failed to initialize ML ROC, ret = %d", ret); 359f3442efeSSrikanth Yalavarthi goto pmd_destroy; 360f3442efeSSrikanth Yalavarthi } 361f3442efeSSrikanth Yalavarthi 362c6d4ffe3SSrikanth Yalavarthi dev->dev_ops = &cnxk_ml_ops; 363f3442efeSSrikanth Yalavarthi } else { 364f3442efeSSrikanth Yalavarthi plt_err("CN10K ML Ops are not supported on secondary process"); 365f3442efeSSrikanth Yalavarthi dev->dev_ops = &ml_dev_dummy_ops; 366f3442efeSSrikanth Yalavarthi } 367f3442efeSSrikanth Yalavarthi 368f3442efeSSrikanth Yalavarthi dev->enqueue_burst = NULL; 369f3442efeSSrikanth Yalavarthi dev->dequeue_burst = NULL; 370f3442efeSSrikanth Yalavarthi dev->op_error_get = NULL; 371f3442efeSSrikanth Yalavarthi 37248c6081aSSrikanth Yalavarthi cnxk_ml_dev_initialized = 1; 37348c6081aSSrikanth Yalavarthi cnxk_mldev->type = CNXK_ML_DEV_TYPE_PCI; 3744af704caSSrikanth Yalavarthi cnxk_mldev->state = ML_CNXK_DEV_STATE_PROBED; 37578670f83SSrikanth Yalavarthi 376f3442efeSSrikanth Yalavarthi return 0; 377f3442efeSSrikanth Yalavarthi 378f3442efeSSrikanth Yalavarthi pmd_destroy: 379f3442efeSSrikanth Yalavarthi rte_ml_dev_pmd_destroy(dev); 380f3442efeSSrikanth Yalavarthi 381f3442efeSSrikanth Yalavarthi error_exit: 382f3442efeSSrikanth Yalavarthi plt_err("Could not create device (vendor_id: 0x%x device_id: 0x%x)", pci_dev->id.vendor_id, 383f3442efeSSrikanth Yalavarthi pci_dev->id.device_id); 384f3442efeSSrikanth Yalavarthi 385f3442efeSSrikanth Yalavarthi return ret; 386f3442efeSSrikanth Yalavarthi } 387f3442efeSSrikanth Yalavarthi 388f3442efeSSrikanth Yalavarthi static int 389f3442efeSSrikanth Yalavarthi cn10k_ml_pci_remove(struct rte_pci_device *pci_dev) 390f3442efeSSrikanth Yalavarthi { 3914af704caSSrikanth Yalavarthi struct cnxk_ml_dev *cnxk_mldev; 392f3442efeSSrikanth Yalavarthi char name[RTE_ML_STR_MAX]; 393f3442efeSSrikanth Yalavarthi struct rte_ml_dev *dev; 394f3442efeSSrikanth Yalavarthi int ret; 395f3442efeSSrikanth Yalavarthi 396f3442efeSSrikanth Yalavarthi if (pci_dev == NULL) 397f3442efeSSrikanth Yalavarthi return -EINVAL; 398f3442efeSSrikanth Yalavarthi 399f3442efeSSrikanth Yalavarthi rte_pci_device_name(&pci_dev->addr, name, sizeof(name)); 400f3442efeSSrikanth Yalavarthi 401f3442efeSSrikanth Yalavarthi dev = rte_ml_dev_pmd_get_named_dev(name); 402f3442efeSSrikanth Yalavarthi if (dev == NULL) 403f3442efeSSrikanth Yalavarthi return -ENODEV; 404f3442efeSSrikanth Yalavarthi 405f3442efeSSrikanth Yalavarthi if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 4064af704caSSrikanth Yalavarthi cnxk_mldev = dev->data->dev_private; 4074af704caSSrikanth Yalavarthi ret = roc_ml_dev_fini(&cnxk_mldev->cn10k_mldev.roc); 408f3442efeSSrikanth Yalavarthi if (ret) 409f3442efeSSrikanth Yalavarthi return ret; 410f3442efeSSrikanth Yalavarthi } 411f3442efeSSrikanth Yalavarthi 412f3442efeSSrikanth Yalavarthi return rte_ml_dev_pmd_destroy(dev); 413f3442efeSSrikanth Yalavarthi } 414f3442efeSSrikanth Yalavarthi 415c29da752SSrikanth Yalavarthi static void 416c29da752SSrikanth Yalavarthi cn10k_ml_fw_print_info(struct cn10k_ml_fw *fw) 417c29da752SSrikanth Yalavarthi { 4186e402621SSrikanth Yalavarthi plt_info("ML Firmware Version = %s", fw->req->cn10k_req.jd.fw_load.version); 419c29da752SSrikanth Yalavarthi 4206e402621SSrikanth Yalavarthi plt_ml_dbg("Firmware capabilities = 0x%016lx", fw->req->cn10k_req.jd.fw_load.cap.u64); 4216e402621SSrikanth Yalavarthi plt_ml_dbg("Version = %s", fw->req->cn10k_req.jd.fw_load.version); 4226e402621SSrikanth Yalavarthi plt_ml_dbg("core0_debug_ptr = 0x%016lx", 4236e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.core0_debug_ptr); 4246e402621SSrikanth Yalavarthi plt_ml_dbg("core1_debug_ptr = 0x%016lx", 4256e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.core1_debug_ptr); 4266e402621SSrikanth Yalavarthi plt_ml_dbg("debug_buffer_size = %u bytes", 4276e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.debug_buffer_size); 428c29da752SSrikanth Yalavarthi plt_ml_dbg("core0_exception_buffer = 0x%016lx", 4296e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.core0_exception_buffer); 430c29da752SSrikanth Yalavarthi plt_ml_dbg("core1_exception_buffer = 0x%016lx", 4316e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.core1_exception_buffer); 432c29da752SSrikanth Yalavarthi plt_ml_dbg("exception_state_size = %u bytes", 4336e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.debug.exception_state_size); 4346e402621SSrikanth Yalavarthi plt_ml_dbg("flags = 0x%016lx", fw->req->cn10k_req.jd.fw_load.flags); 435c29da752SSrikanth Yalavarthi } 436c29da752SSrikanth Yalavarthi 437c29da752SSrikanth Yalavarthi uint64_t 438c29da752SSrikanth Yalavarthi cn10k_ml_fw_flags_get(struct cn10k_ml_fw *fw) 439c29da752SSrikanth Yalavarthi { 4405a7b8abdSSrikanth Yalavarthi uint64_t flags = 0x0; 441c29da752SSrikanth Yalavarthi 4425a7b8abdSSrikanth Yalavarthi if (fw->enable_dpe_warnings) 4435a7b8abdSSrikanth Yalavarthi flags = flags | FW_ENABLE_DPE_WARNING_BITMASK; 4445a7b8abdSSrikanth Yalavarthi 4455a7b8abdSSrikanth Yalavarthi if (fw->report_dpe_warnings) 4465a7b8abdSSrikanth Yalavarthi flags = flags | FW_REPORT_DPE_WARNING_BITMASK; 4475a7b8abdSSrikanth Yalavarthi 4483c9029afSSrikanth Yalavarthi flags = flags | FW_USE_DDR_POLL_ADDR_FP; 4493c9029afSSrikanth Yalavarthi 4505a7b8abdSSrikanth Yalavarthi return flags; 451c29da752SSrikanth Yalavarthi } 452c29da752SSrikanth Yalavarthi 453c29da752SSrikanth Yalavarthi static int 454817e3e55SSrikanth Yalavarthi cn10k_ml_fw_load_asim(struct cn10k_ml_fw *fw) 455817e3e55SSrikanth Yalavarthi { 4564af704caSSrikanth Yalavarthi struct cn10k_ml_dev *cn10k_mldev; 457817e3e55SSrikanth Yalavarthi uint64_t timeout_cycle; 458817e3e55SSrikanth Yalavarthi uint64_t reg_val64; 459817e3e55SSrikanth Yalavarthi bool timeout; 460817e3e55SSrikanth Yalavarthi int ret = 0; 461817e3e55SSrikanth Yalavarthi 4624af704caSSrikanth Yalavarthi cn10k_mldev = fw->cn10k_mldev; 463817e3e55SSrikanth Yalavarthi 464817e3e55SSrikanth Yalavarthi /* Reset HEAD and TAIL debug pointer registers */ 4654af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C0); 4664af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C0); 4674af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C1); 4684af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C1); 4694af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C0); 4704af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C1); 471817e3e55SSrikanth Yalavarthi 472817e3e55SSrikanth Yalavarthi /* Set ML_MLR_BASE to base IOVA of the ML region in LLC/DRAM. */ 473817e3e55SSrikanth Yalavarthi reg_val64 = rte_eal_get_baseaddr(); 4744af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_MLR_BASE); 4754af704caSSrikanth Yalavarthi plt_ml_dbg("ML_MLR_BASE = 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_MLR_BASE)); 4764af704caSSrikanth Yalavarthi roc_ml_reg_save(&cn10k_mldev->roc, ML_MLR_BASE); 477817e3e55SSrikanth Yalavarthi 478817e3e55SSrikanth Yalavarthi /* Update FW load completion structure */ 4796e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.jce.w1.u64 = PLT_U64_CAST(&fw->req->cn10k_req.status); 4806e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.job_type = ML_CN10K_JOB_TYPE_FIRMWARE_LOAD; 4816e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.result = 4826e402621SSrikanth Yalavarthi roc_ml_addr_ap2mlip(&cn10k_mldev->roc, &fw->req->cn10k_req.result); 4836e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.flags = cn10k_ml_fw_flags_get(fw); 4846e402621SSrikanth Yalavarthi plt_write64(ML_CNXK_POLL_JOB_START, &fw->req->cn10k_req.status); 485817e3e55SSrikanth Yalavarthi plt_wmb(); 486817e3e55SSrikanth Yalavarthi 487817e3e55SSrikanth Yalavarthi /* Enqueue FW load through scratch registers */ 488817e3e55SSrikanth Yalavarthi timeout = true; 4894af704caSSrikanth Yalavarthi timeout_cycle = plt_tsc_cycles() + ML_CNXK_CMD_TIMEOUT * plt_tsc_hz(); 4906e402621SSrikanth Yalavarthi roc_ml_scratch_enqueue(&cn10k_mldev->roc, &fw->req->cn10k_req.jd); 491817e3e55SSrikanth Yalavarthi 492817e3e55SSrikanth Yalavarthi plt_rmb(); 493817e3e55SSrikanth Yalavarthi do { 4944af704caSSrikanth Yalavarthi if (roc_ml_scratch_is_done_bit_set(&cn10k_mldev->roc) && 4956e402621SSrikanth Yalavarthi (plt_read64(&fw->req->cn10k_req.status) == ML_CNXK_POLL_JOB_FINISH)) { 496817e3e55SSrikanth Yalavarthi timeout = false; 497817e3e55SSrikanth Yalavarthi break; 498817e3e55SSrikanth Yalavarthi } 499817e3e55SSrikanth Yalavarthi } while (plt_tsc_cycles() < timeout_cycle); 500817e3e55SSrikanth Yalavarthi 501817e3e55SSrikanth Yalavarthi /* Check firmware load status, clean-up and exit on failure. */ 5026e402621SSrikanth Yalavarthi if ((!timeout) && (fw->req->cn10k_req.result.error_code == 0)) { 503817e3e55SSrikanth Yalavarthi cn10k_ml_fw_print_info(fw); 504817e3e55SSrikanth Yalavarthi } else { 505817e3e55SSrikanth Yalavarthi /* Set ML to disable new jobs */ 506817e3e55SSrikanth Yalavarthi reg_val64 = (ROC_ML_CFG_JD_SIZE | ROC_ML_CFG_MLIP_ENA); 5074af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 508817e3e55SSrikanth Yalavarthi 509817e3e55SSrikanth Yalavarthi /* Clear scratch registers */ 5104af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_WORK_PTR); 5114af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_FW_CTRL); 512817e3e55SSrikanth Yalavarthi 513817e3e55SSrikanth Yalavarthi if (timeout) { 514817e3e55SSrikanth Yalavarthi plt_err("Firmware load timeout"); 515817e3e55SSrikanth Yalavarthi ret = -ETIME; 516817e3e55SSrikanth Yalavarthi } else { 517817e3e55SSrikanth Yalavarthi plt_err("Firmware load failed"); 518817e3e55SSrikanth Yalavarthi ret = -1; 519817e3e55SSrikanth Yalavarthi } 520817e3e55SSrikanth Yalavarthi 521817e3e55SSrikanth Yalavarthi return ret; 522817e3e55SSrikanth Yalavarthi } 523817e3e55SSrikanth Yalavarthi 524817e3e55SSrikanth Yalavarthi /* Reset scratch registers */ 5254af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_FW_CTRL); 5264af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_WORK_PTR); 527817e3e55SSrikanth Yalavarthi 528817e3e55SSrikanth Yalavarthi /* Disable job execution, to be enabled in start */ 5294af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 530817e3e55SSrikanth Yalavarthi reg_val64 &= ~ROC_ML_CFG_ENA; 5314af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 5324af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 533817e3e55SSrikanth Yalavarthi 534817e3e55SSrikanth Yalavarthi return ret; 535817e3e55SSrikanth Yalavarthi } 536817e3e55SSrikanth Yalavarthi 537817e3e55SSrikanth Yalavarthi static int 538c29da752SSrikanth Yalavarthi cn10k_ml_fw_load_cn10ka(struct cn10k_ml_fw *fw, void *buffer, uint64_t size) 539c29da752SSrikanth Yalavarthi { 540c29da752SSrikanth Yalavarthi union ml_a35_0_rst_vector_base_s a35_0_rst_vector_base; 541c29da752SSrikanth Yalavarthi union ml_a35_0_rst_vector_base_s a35_1_rst_vector_base; 5424af704caSSrikanth Yalavarthi struct cn10k_ml_dev *cn10k_mldev; 543c29da752SSrikanth Yalavarthi uint64_t timeout_cycle; 544c29da752SSrikanth Yalavarthi uint64_t reg_val64; 545c29da752SSrikanth Yalavarthi uint32_t reg_val32; 546c29da752SSrikanth Yalavarthi uint64_t offset; 547c29da752SSrikanth Yalavarthi bool timeout; 548c29da752SSrikanth Yalavarthi int ret = 0; 549c29da752SSrikanth Yalavarthi uint8_t i; 550c29da752SSrikanth Yalavarthi 5514af704caSSrikanth Yalavarthi cn10k_mldev = fw->cn10k_mldev; 552c29da752SSrikanth Yalavarthi 553c29da752SSrikanth Yalavarthi /* Reset HEAD and TAIL debug pointer registers */ 5544af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C0); 5554af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C0); 5564af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_HEAD_C1); 5574af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_DBG_BUFFER_TAIL_C1); 5584af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C0); 5594af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_EXCEPTION_SP_C1); 560c29da752SSrikanth Yalavarthi 561c29da752SSrikanth Yalavarthi /* (1) Write firmware images for ACC's two A35 cores to the ML region in LLC / DRAM. */ 562c29da752SSrikanth Yalavarthi rte_memcpy(PLT_PTR_ADD(fw->data, FW_LINKER_OFFSET), buffer, size); 563c29da752SSrikanth Yalavarthi 564c29da752SSrikanth Yalavarthi /* (2) Set ML(0)_MLR_BASE = Base IOVA of the ML region in LLC/DRAM. */ 565c29da752SSrikanth Yalavarthi reg_val64 = PLT_PTR_SUB_U64_CAST(fw->data, rte_eal_get_baseaddr()); 5664af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_MLR_BASE); 5674af704caSSrikanth Yalavarthi plt_ml_dbg("ML_MLR_BASE => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_MLR_BASE)); 5684af704caSSrikanth Yalavarthi roc_ml_reg_save(&cn10k_mldev->roc, ML_MLR_BASE); 569c29da752SSrikanth Yalavarthi 570c29da752SSrikanth Yalavarthi /* (3) Set ML(0)_AXI_BRIDGE_CTRL(1) = 0x184003 to remove back-pressure check on DMA AXI 571c29da752SSrikanth Yalavarthi * bridge. 572c29da752SSrikanth Yalavarthi */ 573c29da752SSrikanth Yalavarthi reg_val64 = (ROC_ML_AXI_BRIDGE_CTRL_AXI_RESP_CTRL | 574c29da752SSrikanth Yalavarthi ROC_ML_AXI_BRIDGE_CTRL_BRIDGE_CTRL_MODE | ROC_ML_AXI_BRIDGE_CTRL_NCB_WR_BLK | 575c29da752SSrikanth Yalavarthi ROC_ML_AXI_BRIDGE_CTRL_FORCE_WRESP_OK | ROC_ML_AXI_BRIDGE_CTRL_FORCE_RRESP_OK); 5764af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_AXI_BRIDGE_CTRL(1)); 577c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_AXI_BRIDGE_CTRL(1) => 0x%016lx", 5784af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_AXI_BRIDGE_CTRL(1))); 579c29da752SSrikanth Yalavarthi 580c29da752SSrikanth Yalavarthi /* (4) Set ML(0)_ANB(0..2)_BACKP_DISABLE = 0x3 to remove back-pressure on the AXI to NCB 581c29da752SSrikanth Yalavarthi * bridges. 582c29da752SSrikanth Yalavarthi */ 583c29da752SSrikanth Yalavarthi for (i = 0; i < ML_ANBX_NR; i++) { 584c29da752SSrikanth Yalavarthi reg_val64 = (ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_B_BACKP_DISABLE | 585c29da752SSrikanth Yalavarthi ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_R_BACKP_DISABLE); 5864af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_ANBX_BACKP_DISABLE(i)); 587c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_ANBX_BACKP_DISABLE(%u) => 0x%016lx", i, 5884af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_ANBX_BACKP_DISABLE(i))); 589c29da752SSrikanth Yalavarthi } 590c29da752SSrikanth Yalavarthi 591c29da752SSrikanth Yalavarthi /* (5) Set ML(0)_ANB(0..2)_NCBI_P_OVR = 0x3000 and ML(0)_ANB(0..2)_NCBI_NP_OVR = 0x3000 to 592c29da752SSrikanth Yalavarthi * signal all ML transactions as non-secure. 593c29da752SSrikanth Yalavarthi */ 594c29da752SSrikanth Yalavarthi for (i = 0; i < ML_ANBX_NR; i++) { 595c29da752SSrikanth Yalavarthi reg_val64 = (ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR | 596c29da752SSrikanth Yalavarthi ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR_VLD); 5974af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_ANBX_NCBI_P_OVR(i)); 598c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_ANBX_NCBI_P_OVR(%u) => 0x%016lx", i, 5994af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_ANBX_NCBI_P_OVR(i))); 600c29da752SSrikanth Yalavarthi 601c29da752SSrikanth Yalavarthi reg_val64 |= (ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR | 602c29da752SSrikanth Yalavarthi ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR_VLD); 6034af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_ANBX_NCBI_NP_OVR(i)); 604c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_ANBX_NCBI_NP_OVR(%u) => 0x%016lx", i, 6054af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_ANBX_NCBI_NP_OVR(i))); 606c29da752SSrikanth Yalavarthi } 607c29da752SSrikanth Yalavarthi 608c29da752SSrikanth Yalavarthi /* (6) Set ML(0)_CFG[MLIP_CLK_FORCE] = 1, to force turning on the MLIP clock. */ 6094af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 610c29da752SSrikanth Yalavarthi reg_val64 |= ROC_ML_CFG_MLIP_CLK_FORCE; 6114af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 6124af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 613c29da752SSrikanth Yalavarthi 614c29da752SSrikanth Yalavarthi /* (7) Set ML(0)_JOB_MGR_CTRL[STALL_ON_IDLE] = 0, to make sure the boot request is accepted 615c29da752SSrikanth Yalavarthi * when there is no job in the command queue. 616c29da752SSrikanth Yalavarthi */ 6174af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_JOB_MGR_CTRL); 618c29da752SSrikanth Yalavarthi reg_val64 &= ~ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE; 6194af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_JOB_MGR_CTRL); 6204af704caSSrikanth Yalavarthi plt_ml_dbg("ML_JOB_MGR_CTRL => 0x%016lx", 6214af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_JOB_MGR_CTRL)); 622c29da752SSrikanth Yalavarthi 623c29da752SSrikanth Yalavarthi /* (8) Set ML(0)_CFG[ENA] = 0 and ML(0)_CFG[MLIP_ENA] = 1 to bring MLIP out of reset while 624c29da752SSrikanth Yalavarthi * keeping the job manager disabled. 625c29da752SSrikanth Yalavarthi */ 6264af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 627c29da752SSrikanth Yalavarthi reg_val64 |= ROC_ML_CFG_MLIP_ENA; 628c29da752SSrikanth Yalavarthi reg_val64 &= ~ROC_ML_CFG_ENA; 6294af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 6304af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 631c29da752SSrikanth Yalavarthi 632c29da752SSrikanth Yalavarthi /* (9) Wait at least 70 coprocessor clock cycles. */ 633c29da752SSrikanth Yalavarthi plt_delay_us(FW_WAIT_CYCLES); 634c29da752SSrikanth Yalavarthi 635c29da752SSrikanth Yalavarthi /* (10) Write ML outbound addresses pointing to the firmware images written in step 1 to the 636c29da752SSrikanth Yalavarthi * following registers: ML(0)_A35_0_RST_VECTOR_BASE_W(0..1) for core 0, 637c29da752SSrikanth Yalavarthi * ML(0)_A35_1_RST_VECTOR_BASE_W(0..1) for core 1. The value written to each register is the 638c29da752SSrikanth Yalavarthi * AXI outbound address divided by 4. Read after write. 639c29da752SSrikanth Yalavarthi */ 640c29da752SSrikanth Yalavarthi offset = PLT_PTR_ADD_U64_CAST( 6414af704caSSrikanth Yalavarthi fw->data, FW_LINKER_OFFSET - roc_ml_reg_read64(&cn10k_mldev->roc, ML_MLR_BASE)); 642c29da752SSrikanth Yalavarthi a35_0_rst_vector_base.s.addr = (offset + ML_AXI_START_ADDR) / 4; 643c29da752SSrikanth Yalavarthi a35_1_rst_vector_base.s.addr = (offset + ML_AXI_START_ADDR) / 4; 644c29da752SSrikanth Yalavarthi 6454af704caSSrikanth Yalavarthi roc_ml_reg_write32(&cn10k_mldev->roc, a35_0_rst_vector_base.w.w0, 6464af704caSSrikanth Yalavarthi ML_A35_0_RST_VECTOR_BASE_W(0)); 6474af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_A35_0_RST_VECTOR_BASE_W(0)); 648c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_A35_0_RST_VECTOR_BASE_W(0) => 0x%08x", reg_val32); 649c29da752SSrikanth Yalavarthi 6504af704caSSrikanth Yalavarthi roc_ml_reg_write32(&cn10k_mldev->roc, a35_0_rst_vector_base.w.w1, 6514af704caSSrikanth Yalavarthi ML_A35_0_RST_VECTOR_BASE_W(1)); 6524af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_A35_0_RST_VECTOR_BASE_W(1)); 653c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_A35_0_RST_VECTOR_BASE_W(1) => 0x%08x", reg_val32); 654c29da752SSrikanth Yalavarthi 6554af704caSSrikanth Yalavarthi roc_ml_reg_write32(&cn10k_mldev->roc, a35_1_rst_vector_base.w.w0, 6564af704caSSrikanth Yalavarthi ML_A35_1_RST_VECTOR_BASE_W(0)); 6574af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_A35_1_RST_VECTOR_BASE_W(0)); 658c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_A35_1_RST_VECTOR_BASE_W(0) => 0x%08x", reg_val32); 659c29da752SSrikanth Yalavarthi 6604af704caSSrikanth Yalavarthi roc_ml_reg_write32(&cn10k_mldev->roc, a35_1_rst_vector_base.w.w1, 6614af704caSSrikanth Yalavarthi ML_A35_1_RST_VECTOR_BASE_W(1)); 6624af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_A35_1_RST_VECTOR_BASE_W(1)); 663c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_A35_1_RST_VECTOR_BASE_W(1) => 0x%08x", reg_val32); 664c29da752SSrikanth Yalavarthi 665c29da752SSrikanth Yalavarthi /* (11) Clear MLIP's ML(0)_SW_RST_CTRL[ACC_RST]. This will bring the ACC cores and other 666c29da752SSrikanth Yalavarthi * MLIP components out of reset. The cores will execute firmware from the ML region as 667c29da752SSrikanth Yalavarthi * written in step 1. 668c29da752SSrikanth Yalavarthi */ 6694af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_SW_RST_CTRL); 670c29da752SSrikanth Yalavarthi reg_val32 &= ~ROC_ML_SW_RST_CTRL_ACC_RST; 6714af704caSSrikanth Yalavarthi roc_ml_reg_write32(&cn10k_mldev->roc, reg_val32, ML_SW_RST_CTRL); 6724af704caSSrikanth Yalavarthi reg_val32 = roc_ml_reg_read32(&cn10k_mldev->roc, ML_SW_RST_CTRL); 673c29da752SSrikanth Yalavarthi plt_ml_dbg("ML_SW_RST_CTRL => 0x%08x", reg_val32); 674c29da752SSrikanth Yalavarthi 675c29da752SSrikanth Yalavarthi /* (12) Wait for notification from firmware that ML is ready for job execution. */ 6766e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.jce.w1.u64 = PLT_U64_CAST(&fw->req->cn10k_req.status); 6776e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.job_type = ML_CN10K_JOB_TYPE_FIRMWARE_LOAD; 6786e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.hdr.result = 6796e402621SSrikanth Yalavarthi roc_ml_addr_ap2mlip(&cn10k_mldev->roc, &fw->req->cn10k_req.result); 6806e402621SSrikanth Yalavarthi fw->req->cn10k_req.jd.fw_load.flags = cn10k_ml_fw_flags_get(fw); 6816e402621SSrikanth Yalavarthi plt_write64(ML_CNXK_POLL_JOB_START, &fw->req->cn10k_req.status); 682c29da752SSrikanth Yalavarthi plt_wmb(); 683c29da752SSrikanth Yalavarthi 684c29da752SSrikanth Yalavarthi /* Enqueue FW load through scratch registers */ 685c29da752SSrikanth Yalavarthi timeout = true; 6864af704caSSrikanth Yalavarthi timeout_cycle = plt_tsc_cycles() + ML_CNXK_CMD_TIMEOUT * plt_tsc_hz(); 6876e402621SSrikanth Yalavarthi roc_ml_scratch_enqueue(&cn10k_mldev->roc, &fw->req->cn10k_req.jd); 688c29da752SSrikanth Yalavarthi 689c29da752SSrikanth Yalavarthi plt_rmb(); 690c29da752SSrikanth Yalavarthi do { 6914af704caSSrikanth Yalavarthi if (roc_ml_scratch_is_done_bit_set(&cn10k_mldev->roc) && 6926e402621SSrikanth Yalavarthi (plt_read64(&fw->req->cn10k_req.status) == ML_CNXK_POLL_JOB_FINISH)) { 693c29da752SSrikanth Yalavarthi timeout = false; 694c29da752SSrikanth Yalavarthi break; 695c29da752SSrikanth Yalavarthi } 696c29da752SSrikanth Yalavarthi } while (plt_tsc_cycles() < timeout_cycle); 697c29da752SSrikanth Yalavarthi 698c29da752SSrikanth Yalavarthi /* Check firmware load status, clean-up and exit on failure. */ 6996e402621SSrikanth Yalavarthi if ((!timeout) && (fw->req->cn10k_req.result.error_code == 0)) { 700c29da752SSrikanth Yalavarthi cn10k_ml_fw_print_info(fw); 701c29da752SSrikanth Yalavarthi } else { 702c29da752SSrikanth Yalavarthi /* Set ML to disable new jobs */ 703c29da752SSrikanth Yalavarthi reg_val64 = (ROC_ML_CFG_JD_SIZE | ROC_ML_CFG_MLIP_ENA); 7044af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 705c29da752SSrikanth Yalavarthi 706c29da752SSrikanth Yalavarthi /* Clear scratch registers */ 7074af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_WORK_PTR); 7084af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_FW_CTRL); 709c29da752SSrikanth Yalavarthi 710c29da752SSrikanth Yalavarthi if (timeout) { 711c29da752SSrikanth Yalavarthi plt_err("Firmware load timeout"); 712c29da752SSrikanth Yalavarthi ret = -ETIME; 713c29da752SSrikanth Yalavarthi } else { 714c29da752SSrikanth Yalavarthi plt_err("Firmware load failed"); 715c29da752SSrikanth Yalavarthi ret = -1; 716c29da752SSrikanth Yalavarthi } 717c29da752SSrikanth Yalavarthi 718c29da752SSrikanth Yalavarthi return ret; 719c29da752SSrikanth Yalavarthi } 720c29da752SSrikanth Yalavarthi 721c29da752SSrikanth Yalavarthi /* (13) Set ML(0)_JOB_MGR_CTRL[STALL_ON_IDLE] = 0x1; this is needed to shut down the MLIP 722c29da752SSrikanth Yalavarthi * clock when there are no more jobs to process. 723c29da752SSrikanth Yalavarthi */ 7244af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_JOB_MGR_CTRL); 725c29da752SSrikanth Yalavarthi reg_val64 |= ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE; 7264af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_JOB_MGR_CTRL); 7274af704caSSrikanth Yalavarthi plt_ml_dbg("ML_JOB_MGR_CTRL => 0x%016lx", 7284af704caSSrikanth Yalavarthi roc_ml_reg_read64(&cn10k_mldev->roc, ML_JOB_MGR_CTRL)); 729c29da752SSrikanth Yalavarthi 730c29da752SSrikanth Yalavarthi /* (14) Set ML(0)_CFG[MLIP_CLK_FORCE] = 0; the MLIP clock will be turned on/off based on job 731c29da752SSrikanth Yalavarthi * activities. 732c29da752SSrikanth Yalavarthi */ 7334af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 734c29da752SSrikanth Yalavarthi reg_val64 &= ~ROC_ML_CFG_MLIP_CLK_FORCE; 7354af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 7364af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 737c29da752SSrikanth Yalavarthi 738c29da752SSrikanth Yalavarthi /* (15) Set ML(0)_CFG[ENA] to enable ML job execution. */ 7394af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 740c29da752SSrikanth Yalavarthi reg_val64 |= ROC_ML_CFG_ENA; 7414af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 7424af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 743c29da752SSrikanth Yalavarthi 744c29da752SSrikanth Yalavarthi /* Reset scratch registers */ 7454af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_FW_CTRL); 7464af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, 0, ML_SCRATCH_WORK_PTR); 747c29da752SSrikanth Yalavarthi 748c29da752SSrikanth Yalavarthi /* Disable job execution, to be enabled in start */ 7494af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 750c29da752SSrikanth Yalavarthi reg_val64 &= ~ROC_ML_CFG_ENA; 7514af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_CFG); 7524af704caSSrikanth Yalavarthi plt_ml_dbg("ML_CFG => 0x%016lx", roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG)); 753c29da752SSrikanth Yalavarthi 754c29da752SSrikanth Yalavarthi /* Additional fixes: Set RO bit to fix O2D DMA bandwidth issue on cn10ka */ 755c29da752SSrikanth Yalavarthi for (i = 0; i < ML_ANBX_NR; i++) { 7564af704caSSrikanth Yalavarthi reg_val64 = roc_ml_reg_read64(&cn10k_mldev->roc, ML_ANBX_NCBI_P_OVR(i)); 757c29da752SSrikanth Yalavarthi reg_val64 |= (ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR | 758c29da752SSrikanth Yalavarthi ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR_VLD); 7594af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val64, ML_ANBX_NCBI_P_OVR(i)); 760c29da752SSrikanth Yalavarthi } 761c29da752SSrikanth Yalavarthi 762c29da752SSrikanth Yalavarthi return ret; 763c29da752SSrikanth Yalavarthi } 764c29da752SSrikanth Yalavarthi 765c29da752SSrikanth Yalavarthi int 7664af704caSSrikanth Yalavarthi cn10k_ml_fw_load(struct cnxk_ml_dev *cnxk_mldev) 767c29da752SSrikanth Yalavarthi { 7684af704caSSrikanth Yalavarthi struct cn10k_ml_dev *cn10k_mldev; 769c29da752SSrikanth Yalavarthi const struct plt_memzone *mz; 770c29da752SSrikanth Yalavarthi struct cn10k_ml_fw *fw; 771c29da752SSrikanth Yalavarthi void *fw_buffer = NULL; 772c29da752SSrikanth Yalavarthi uint64_t mz_size = 0; 773c29da752SSrikanth Yalavarthi uint64_t fw_size = 0; 774c29da752SSrikanth Yalavarthi int ret = 0; 775c29da752SSrikanth Yalavarthi 7764af704caSSrikanth Yalavarthi cn10k_mldev = &cnxk_mldev->cn10k_mldev; 7774af704caSSrikanth Yalavarthi fw = &cn10k_mldev->fw; 7784af704caSSrikanth Yalavarthi fw->cn10k_mldev = cn10k_mldev; 779c29da752SSrikanth Yalavarthi 780817e3e55SSrikanth Yalavarthi if (roc_env_is_emulator() || roc_env_is_hw()) { 781c29da752SSrikanth Yalavarthi /* Read firmware image to a buffer */ 782c29da752SSrikanth Yalavarthi ret = rte_firmware_read(fw->path, &fw_buffer, &fw_size); 7833fa2c414SSrikanth Yalavarthi if ((ret < 0) || (fw_buffer == NULL)) { 784f665790aSDavid Marchand plt_err("Unable to read firmware data: %s", fw->path); 785c29da752SSrikanth Yalavarthi return ret; 786c29da752SSrikanth Yalavarthi } 787c29da752SSrikanth Yalavarthi 788c29da752SSrikanth Yalavarthi /* Reserve memzone for firmware load completion and data */ 7896e402621SSrikanth Yalavarthi mz_size = sizeof(struct cnxk_ml_req) + fw_size + FW_STACK_BUFFER_SIZE + 790c29da752SSrikanth Yalavarthi FW_DEBUG_BUFFER_SIZE + FW_EXCEPTION_BUFFER_SIZE; 791817e3e55SSrikanth Yalavarthi } else if (roc_env_is_asim()) { 792817e3e55SSrikanth Yalavarthi /* Reserve memzone for firmware load completion */ 7936e402621SSrikanth Yalavarthi mz_size = sizeof(struct cnxk_ml_req); 794817e3e55SSrikanth Yalavarthi } 795817e3e55SSrikanth Yalavarthi 796c29da752SSrikanth Yalavarthi mz = plt_memzone_reserve_aligned(FW_MEMZONE_NAME, mz_size, 0, ML_CN10K_ALIGN_SIZE); 797c29da752SSrikanth Yalavarthi if (mz == NULL) { 798c29da752SSrikanth Yalavarthi plt_err("plt_memzone_reserve failed : %s", FW_MEMZONE_NAME); 799c29da752SSrikanth Yalavarthi free(fw_buffer); 800c29da752SSrikanth Yalavarthi return -ENOMEM; 801c29da752SSrikanth Yalavarthi } 802c29da752SSrikanth Yalavarthi fw->req = mz->addr; 803c29da752SSrikanth Yalavarthi 804c29da752SSrikanth Yalavarthi /* Reset firmware load completion structure */ 8056e402621SSrikanth Yalavarthi memset(&fw->req->cn10k_req.jd, 0, sizeof(struct cn10k_ml_jd)); 8066e402621SSrikanth Yalavarthi memset(&fw->req->cn10k_req.jd.fw_load.version[0], '\0', MLDEV_FIRMWARE_VERSION_LENGTH); 807c29da752SSrikanth Yalavarthi 808c29da752SSrikanth Yalavarthi /* Reset device, if in active state */ 8094af704caSSrikanth Yalavarthi if (roc_ml_mlip_is_enabled(&cn10k_mldev->roc)) 8104af704caSSrikanth Yalavarthi roc_ml_mlip_reset(&cn10k_mldev->roc, true); 811c29da752SSrikanth Yalavarthi 812c29da752SSrikanth Yalavarthi /* Load firmware */ 813817e3e55SSrikanth Yalavarthi if (roc_env_is_emulator() || roc_env_is_hw()) { 8146e402621SSrikanth Yalavarthi fw->data = PLT_PTR_ADD(mz->addr, sizeof(struct cnxk_ml_req)); 815c29da752SSrikanth Yalavarthi ret = cn10k_ml_fw_load_cn10ka(fw, fw_buffer, fw_size); 816c29da752SSrikanth Yalavarthi free(fw_buffer); 817817e3e55SSrikanth Yalavarthi } else if (roc_env_is_asim()) { 818817e3e55SSrikanth Yalavarthi fw->data = NULL; 819817e3e55SSrikanth Yalavarthi ret = cn10k_ml_fw_load_asim(fw); 820817e3e55SSrikanth Yalavarthi } 821817e3e55SSrikanth Yalavarthi 822c29da752SSrikanth Yalavarthi if (ret < 0) 8234af704caSSrikanth Yalavarthi cn10k_ml_fw_unload(cnxk_mldev); 824c29da752SSrikanth Yalavarthi 825c29da752SSrikanth Yalavarthi return ret; 826c29da752SSrikanth Yalavarthi } 827c29da752SSrikanth Yalavarthi 828c29da752SSrikanth Yalavarthi void 8294af704caSSrikanth Yalavarthi cn10k_ml_fw_unload(struct cnxk_ml_dev *cnxk_mldev) 830c29da752SSrikanth Yalavarthi { 8314af704caSSrikanth Yalavarthi struct cn10k_ml_dev *cn10k_mldev; 832c29da752SSrikanth Yalavarthi const struct plt_memzone *mz; 833c29da752SSrikanth Yalavarthi uint64_t reg_val; 834c29da752SSrikanth Yalavarthi 8354af704caSSrikanth Yalavarthi cn10k_mldev = &cnxk_mldev->cn10k_mldev; 8364af704caSSrikanth Yalavarthi 837c29da752SSrikanth Yalavarthi /* Disable and reset device */ 8384af704caSSrikanth Yalavarthi reg_val = roc_ml_reg_read64(&cn10k_mldev->roc, ML_CFG); 839c29da752SSrikanth Yalavarthi reg_val &= ~ROC_ML_CFG_MLIP_ENA; 8404af704caSSrikanth Yalavarthi roc_ml_reg_write64(&cn10k_mldev->roc, reg_val, ML_CFG); 8414af704caSSrikanth Yalavarthi roc_ml_mlip_reset(&cn10k_mldev->roc, true); 842c29da752SSrikanth Yalavarthi 843c29da752SSrikanth Yalavarthi mz = plt_memzone_lookup(FW_MEMZONE_NAME); 844c29da752SSrikanth Yalavarthi if (mz != NULL) 845c29da752SSrikanth Yalavarthi plt_memzone_free(mz); 846c29da752SSrikanth Yalavarthi } 847c29da752SSrikanth Yalavarthi 848f3442efeSSrikanth Yalavarthi static struct rte_pci_id pci_id_ml_table[] = { 849f3442efeSSrikanth Yalavarthi {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_ML_PF)}, 850f3442efeSSrikanth Yalavarthi /* sentinel */ 851f3442efeSSrikanth Yalavarthi {}, 852f3442efeSSrikanth Yalavarthi }; 853f3442efeSSrikanth Yalavarthi 854f3442efeSSrikanth Yalavarthi static struct rte_pci_driver cn10k_mldev_pmd = { 855f3442efeSSrikanth Yalavarthi .id_table = pci_id_ml_table, 856f3442efeSSrikanth Yalavarthi .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA, 857f3442efeSSrikanth Yalavarthi .probe = cn10k_ml_pci_probe, 858f3442efeSSrikanth Yalavarthi .remove = cn10k_ml_pci_remove, 859f3442efeSSrikanth Yalavarthi }; 860f3442efeSSrikanth Yalavarthi 861f3442efeSSrikanth Yalavarthi RTE_PMD_REGISTER_PCI(MLDEV_NAME_CN10K_PMD, cn10k_mldev_pmd); 862f3442efeSSrikanth Yalavarthi RTE_PMD_REGISTER_PCI_TABLE(MLDEV_NAME_CN10K_PMD, pci_id_ml_table); 863f3442efeSSrikanth Yalavarthi RTE_PMD_REGISTER_KMOD_DEP(MLDEV_NAME_CN10K_PMD, "vfio-pci"); 86434468620SSrikanth Yalavarthi 865515e3608SSrikanth Yalavarthi RTE_PMD_REGISTER_PARAM_STRING(MLDEV_NAME_CN10K_PMD, CN10K_ML_FW_PATH 866515e3608SSrikanth Yalavarthi "=<path>" CN10K_ML_FW_ENABLE_DPE_WARNINGS 8675e2a82b9SSrikanth Yalavarthi "=<0|1>" CN10K_ML_FW_REPORT_DPE_WARNINGS 868783932efSSrikanth Yalavarthi "=<0|1>" CN10K_ML_DEV_CACHE_MODEL_DATA 869d646b82aSSrikanth Yalavarthi "=<0|1>" CN10K_ML_OCM_ALLOC_MODE 8703c9029afSSrikanth Yalavarthi "=<lowest|largest>" CN10K_ML_DEV_HW_QUEUE_LOCK 871bf563aa2SSrikanth Yalavarthi "=<0|1>" CN10K_ML_OCM_PAGE_SIZE "=<1024|2048|4096|8192|16384>"); 872