* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "ka_kernel_def_pub.h"
#include "securec.h"
#include "ascend_kernel_hal.h"
#include "ascend_platform.h"
#include "ascend_dev_num.h"
#include "soc_resmng_log.h"
#include "pbl/pbl_soc_res.h"
#ifdef STATIC_SKIP
#define STATIC
#else
#define STATIC static
#endif
#ifdef CFG_FEATURE_PG
STATIC int soc_get_pg_res_max_num(HAL_PG_INFO_TYPE info_type,
enum soc_mia_res_type *soc_res_type, unsigned int *max_num)
{
switch (info_type) {
case PG_INFO_TYPE_AIC:
*max_num = SOC_MAX_AICORE_NUM_PER_DIE;
*soc_res_type = MIA_AC_AIC;
return 0;
case PG_INFO_TYPE_HBM:
*max_num = SOC_MAX_HBM_NUM_PER_DIE;
*soc_res_type = MIA_MEM_HBM;
return 0;
case PG_INFO_TYPE_MATA:
*max_num = SOC_MAX_MATA_NUM_PER_DIE;
*soc_res_type = MIA_SYS_MATA;
return 0;
default:
return -EOPNOTSUPP;
}
}
STATIC int soc_get_pg_res(unsigned int dev_id, HAL_PG_INFO_TYPE info_type, hal_pg_info_t *pg_info)
{
unsigned int i, max_num = 0;
struct soc_mia_res_info_ex res_info = {0};
enum soc_mia_res_type soc_res_type = {0};
u64 die_num;
int ret;
ret = soc_resmng_dev_get_key_value(dev_id, "soc_die_num", &die_num);
if (ret != 0) {
soc_err("Get soc_die_num failed. (dev_id=%u; ret=%d)\n", dev_id, ret);
return ret;
}
ret = soc_get_pg_res_max_num(info_type, &soc_res_type, &max_num);
if (ret != 0) {
soc_err("Get max num failed. (dev_id=%u; info_type=%u; ret=%d)\n", dev_id, info_type, ret);
return ret;
}
for (i = 0; i < die_num; i++) {
ret = soc_resmng_dev_die_get_res(dev_id, i, soc_res_type, &res_info);
if (ret != 0) {
soc_err("Get res failed. (dev_id=%u; soc_res_type=%u; ret=%d)\n", dev_id, soc_res_type, ret);
return ret;
}
pg_info->bitmap |= res_info.bitmap << (i * max_num);
pg_info->num += res_info.total_num;
pg_info->freq = res_info.freq;
}
return 0;
}
#endif
int hal_kernel_get_pg_info(unsigned int dev_id, HAL_PG_INFO_TYPE info_type,
char* data, unsigned int size, unsigned int *ret_size)
{
#ifdef CFG_FEATURE_PG
hal_pg_info_t pg_info = {0};
int ret;
if ((dev_id >= ASCEND_DEV_MAX_NUM) || (data == NULL) || (ret_size == NULL) || (info_type >= PG_INFO_TYPE_MAX)) {
soc_err("Input para is invalid. (dev_id=%u; data_is_null=%d; ret_size_is_null=%d; info_type=%d)\n",
dev_id, (data == NULL), (ret_size == NULL), info_type);
return -EINVAL;
}
ret = soc_get_pg_res(dev_id, info_type, &pg_info);
if (ret != 0) {
soc_err("Get pg info failed. (dev_id=%u; info_type=%u; ret=%d)\n", dev_id, info_type, ret);
return ret;
}
*ret_size = sizeof(hal_pg_info_t);
if (*ret_size > size) {
soc_err("Return size is larger than input data size. (dev_id=%u; size=%u; ret_size=%u)\n",
dev_id, size, *ret_size);
return -EINVAL;
}
*(hal_pg_info_t *)data = pg_info;
return 0;
#else
return -EOPNOTSUPP;
#endif
}
KA_EXPORT_SYMBOL_GPL(hal_kernel_get_pg_info);