This commit is contained in:
Andy Ritger
2022-11-10 08:39:33 -08:00
parent 7c345b838b
commit 758b4ee818
1323 changed files with 262135 additions and 60754 deletions

View File

@@ -81,7 +81,7 @@ _nvswitch_core_bios_read
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_CORE;
cmd.hdr.size = sizeof(cmd);
cmd.hdr.size = RM_SOE_CMD_SIZE(CORE, BIOS);
cmd.cmd.core.bios.cmdType = readType;
RM_FLCN_U64_PACK(&pParams->dmaHandle, &dmaHandle);
pParams->offset = offset;

View File

@@ -40,12 +40,13 @@ _nvswitch_dump_error_entry
if ((error_entry != NULL) &&
(error_entry->error_src == NVSWITCH_ERROR_SRC_HW))
{
NVSWITCH_PRINT_SXID(device, error_entry->error_type,
NVSWITCH_PRINT_SXID_NO_BBX(device, error_entry->error_type,
"Severity %d Engine instance %02d Sub-engine instance %02d\n",
error_entry->severity, error_entry->instance, error_entry->subinstance);
NVSWITCH_PRINT_SXID(device, error_entry->error_type,
"Data {0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x}\n",
NVSWITCH_PRINT_SXID_NO_BBX(device, error_entry->error_type,
"Data {0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x}\n",
error_entry->data.raw.flags,
error_entry->data.raw.data[0], error_entry->data.raw.data[1],
error_entry->data.raw.data[2], error_entry->data.raw.data[3],
error_entry->data.raw.data[4], error_entry->data.raw.data[5],
@@ -61,7 +62,7 @@ _nvswitch_dump_error_entry
(error_entry->data.raw.data[15] != 0))
{
NVSWITCH_PRINT_SXID(device, error_entry->error_type,
NVSWITCH_PRINT_SXID_NO_BBX(device, error_entry->error_type,
"Data {0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x}\n",
error_entry->data.raw.data[ 8], error_entry->data.raw.data[ 9],
error_entry->data.raw.data[10], error_entry->data.raw.data[11],
@@ -394,10 +395,20 @@ nvswitch_translate_hw_error
{
return NVSWITCH_ERR_HW_SOE;
}
else if ((type >= NVSWITCH_ERR_HW_NPORT_MULTICASTTSTATE) &&
(type < NVSWITCH_ERR_HW_NPORT_MULTICASTTSTATE_LAST))
{
return NVSWITCH_ERR_HW_NPORT_MULTICASTTSTATE;
}
else if ((type >= NVSWITCH_ERR_HW_NPORT_REDUCTIONTSTATE) &&
(type < NVSWITCH_ERR_HW_NPORT_REDUCTIONTSTATE_LAST))
{
return NVSWITCH_ERR_HW_NPORT_REDUCTIONTSTATE;
}
else
{
// Update this assert after adding a new translation entry above
ct_assert(NVSWITCH_ERR_HW_SOE_LAST == (NVSWITCH_ERR_LAST - 1));
ct_assert(NVSWITCH_ERR_HW_NPORT_REDUCTIONTSTATE_LAST == (NVSWITCH_ERR_LAST - 1));
NVSWITCH_PRINT(NULL, ERROR,
"%s: Undefined error type\n", __FUNCTION__);

View File

@@ -409,6 +409,11 @@ flcnSetupHal
flcnSetupHal_LR10(pFlcn);
goto _flcnSetupHal_success;
}
if (nvswitch_is_ls10_device_id(pci_device_id))
{
flcnSetupHal_LS10(pFlcn);
goto _flcnSetupHal_success;
}
NVSWITCH_PRINT(NULL, ERROR,
"Flcn hal can't be setup due to unknown device id\n");

View File

@@ -264,13 +264,6 @@ _flcnQueueOpenWrite_dmem
status = _flcnQueueHasRoom_dmem(device, pFlcn, pQueue, writeSize, &bRewind);
if (NV_OK != status)
{
if (NV_ERR_INSUFFICIENT_RESOURCES == status)
{
NVSWITCH_PRINT(device, INFO,
"%s: queue is too full to write data (write-size=0x%x).\n",
__FUNCTION__, writeSize);
}
return status;
}

View File

@@ -28,6 +28,12 @@
#include "rmflcncmdif_nvswitch.h"
#include "common_nvswitch.h"
//
// Yield the CPU temporarily after openWrite() in _flcnQueueCmdWrite_IMPL()
// fails this many times in a row.
//
#define FLCN_QUEUE_CMD_WRITE_SLEEP_TRIES 1024
/*!
* @file flcnqueue_nvswitch.c
* @brief Provides all the fundamental logic for reading/writing queues.
@@ -437,6 +443,7 @@ _flcnQueueCmdWrite_IMPL
PFLCNQUEUE pQueue;
PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
NvBool bKeepPolling;
NvU32 nTries = 0;
NVSWITCH_ASSERT(pTimeout != NULL);
NVSWITCH_ASSERT(pQueueInfo != NULL);
@@ -464,6 +471,17 @@ _flcnQueueCmdWrite_IMPL
__FUNCTION__, pQueue->queueLogId);
return NV_ERR_FLCN_ERROR;
}
if (++nTries < 4)
{
NVSWITCH_PRINT(device, INFO,
"%s: queue is too full to write data (write-size=0x%x).\n",
__FUNCTION__, pCmd->cmdGen.hdr.size);
}
else if ((nTries % FLCN_QUEUE_CMD_WRITE_SLEEP_TRIES) == 0)
{
nvswitch_os_sleep(1);
}
}
else
{
@@ -474,29 +492,27 @@ _flcnQueueCmdWrite_IMPL
if (status == NV_ERR_INSUFFICIENT_RESOURCES)
{
#if defined(DEBUG)
RM_FLCN_CMD FlcnCmd;
NV_STATUS dumpStatus;
dumpStatus = flcnRtosDumpCmdQueue_nvswitch(device, pFlcn, queueLogId, &FlcnCmd);
if (dumpStatus != NV_OK)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Dumping Falcon Command queue completed with status 0x%x \n",
__FUNCTION__ , dumpStatus);
}
#endif // DEBUG
NVSWITCH_PRINT(device, ERROR,
"%s: Timeout while waiting for space (queueLogId=0x%x).\n",
__FUNCTION__, pQueue->queueLogId);
"%s: Timeout after %d tries while waiting for space (queueLogId=0x%x).\n"
"Command queue:\n",
__FUNCTION__, nTries, pQueue->queueLogId);
return NV_ERR_TIMEOUT;
}
//
// if failed to write Command due to no space,
// dump the queue contents if debug flag is on
//
#if defined(DEBUG)
if (status == NV_ERR_INSUFFICIENT_RESOURCES)
{
RM_FLCN_CMD FlcnCmd;
NV_STATUS dumpstatus;
dumpstatus = flcnRtosDumpCmdQueue_nvswitch(device, pFlcn, queueLogId, &FlcnCmd);
NVSWITCH_PRINT(device, ERROR,
"%s: Dumping Falcon Command queue completed with status =0x%x \n",
__FUNCTION__ , dumpstatus );
}
#endif
if (status != NV_OK)
{
NVSWITCH_PRINT(device, WARN,
@@ -516,7 +532,7 @@ _flcnQueueCmdWrite_IMPL
status = pQueue->close(device, pFlcn, pQueue, NV_TRUE);
if (status == NV_OK)
{
NVSWITCH_PRINT(device, INFO,
NVSWITCH_PRINT(device, MMIO,
"%s: command queued (unit-id=0x%x).\n",
__FUNCTION__, pCmd->cmdGen.hdr.unitId);
}
@@ -1563,7 +1579,7 @@ _flcnQueueCmdValidate
* @return NV_ERR_TIMEOUT
* A timeout occurred before the command completed.
*/
NV_STATUS
static NV_STATUS
_flcnQueueCmdWait_IMPL
(
nvswitch_device *device,
@@ -1628,4 +1644,3 @@ flcnQueueSetupHal
pHal->queueCmdPostNonBlocking = _flcnQueueCmdPostNonBlocking_IMPL;
pHal->queueCmdWait = _flcnQueueCmdWait_IMPL;
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -72,7 +72,7 @@ static NV_STATUS _flcnQueueReaderReadBody (nvswitch_device *, PFLCN, FLCNQUE
"status=0x%x).\n", __FUNCTION__, (id), (status))
#define NVSWITCH_PRINT_QUEUE_READER_PRINT_HDR_READ_INFO(offset) \
NVSWITCH_PRINT(device, INFO, \
NVSWITCH_PRINT(device, MMIO, \
"%s: Reading a header from DMEM @ 0x%x.\n", \
__FUNCTION__, (offset))

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2017-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2017-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -152,6 +152,17 @@ static NV_INLINE void nvswitch_clear_flags(NvU32 *val, NvU32 flags)
nvswitch_inforom_bbx_add_sxid(_d, _sxid, 0, 0, 0); \
} while(0)
#define NVSWITCH_PRINT_SXID_NO_BBX(_d, _sxid, _fmt, ...) \
do \
{ \
NVSWITCH_ASSERT(nvswitch_translate_hw_error(_sxid) != NVSWITCH_NVLINK_HW_GENERIC); \
nvswitch_os_print(NVSWITCH_DBG_LEVEL_ERROR, \
"nvidia-%s: SXid (PCI:" NVLINK_PCI_DEV_FMT "): %05d, " _fmt, \
(_d)->name, NVLINK_PCI_DEV_FMT_ARGS(&(_d)->nvlink_device->pciInfo), _sxid, \
##__VA_ARGS__); \
nvswitch_lib_smbpbi_log_sxid(_d, _sxid, _fmt, ##__VA_ARGS__); \
} while(0)
#define NVSWITCH_DEV_CMD_DISPATCH_WITH_PRIVATE_DATA(cmd, function, type, private)\
case cmd: \
{ \
@@ -189,18 +200,9 @@ static NV_INLINE void nvswitch_clear_flags(NvU32 *val, NvU32 flags)
#define NVSWITCH_MODS_CMDS_SUPPORTED NV_FALSE
#if defined(DEBUG) || defined(DEVELOP) || defined(NV_MODS)
#define NVSWITCH_TEST_CMDS_SUPPORTED NV_TRUE
#else
#define NVSWITCH_TEST_CMDS_SUPPORTED NV_FALSE
#endif
#define NVSWITCH_DEV_CMD_DISPATCH_MODS(cmd, function, type) \
NVSWITCH_DEV_CMD_DISPATCH_HELPER(cmd, NVSWITCH_MODS_CMDS_SUPPORTED, function, type)
#define NVSWITCH_DEV_CMD_DISPATCH_TEST(cmd, function, type) \
NVSWITCH_DEV_CMD_DISPATCH_HELPER(cmd, NVSWITCH_TEST_CMDS_SUPPORTED, function, type)
#define NVSWITCH_MAX_NUM_LINKS 100
#if NVSWITCH_MAX_NUM_LINKS <= 100
#define NVSWITCH_LINK_INSTANCE_LEN 2
@@ -251,9 +253,13 @@ typedef struct
NvU32 select_uphy_tables;
NvU32 link_training_mode;
NvU32 i2c_access_control;
NvU32 force_kernel_i2c;
NvU32 link_recal_settings;
NvU32 crc_bit_error_rate_short;
NvU32 crc_bit_error_rate_long;
NvU32 lp_threshold;
NvU32 minion_intr;
NvU32 surpress_link_errors_for_gpu_reset;
} NVSWITCH_REGKEY_TYPE;
//
@@ -261,14 +267,28 @@ typedef struct
//
typedef struct NVSWITCH_TASK
{
struct NVSWITCH_TASK *prev;
struct NVSWITCH_TASK *next;
void (*task_fn)(nvswitch_device *);
void (*task_fn_vdptr)(nvswitch_device *, void *);
void (*task_fn_devptr)(nvswitch_device *);
void *task_args;
NvU64 period_nsec;
NvU64 last_run_nsec;
NvU32 flags;
} NVSWITCH_TASK_TYPE;
#define NVSWITCH_TASK_TYPE_FLAGS_ALWAYS_RUN 0x1 // Run even the if not initialized
#define NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED 0x1 // Run even the if not initialized
#define NVSWITCH_TASK_TYPE_FLAGS_RUN_ONCE 0x2 // Only run the task once. Memory for task struct and args will be freed by dispatcher after running.
#define NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS 0x4 // Function accepts args as void * args.
//
// Wrapper struct for deffered SXID errors
//
typedef struct
{
NvU32 nvlipt_instance;
NvU32 link;
} NVSWITCH_DEFERRED_ERROR_REPORTING_ARGS;
//
// PLL
@@ -487,6 +507,7 @@ typedef struct NVSWITCH_TIMEOUT
#define NVSWITCH_INTERVAL_50USEC_IN_NS 50000LL
#define NVSWITCH_INTERVAL_1MSEC_IN_NS 1000000LL
#define NVSWITCH_INTERVAL_5MSEC_IN_NS 5000000LL
#define NVSWITCH_INTERVAL_750MSEC_IN_NS 750000000LL
#define NVSWITCH_INTERVAL_1SEC_IN_NS 1000000000LL
#define NVSWITCH_INTERVAL_4SEC_IN_NS 4000000000LL
@@ -516,8 +537,12 @@ void nvswitch_reg_write_32(nvswitch_device *device, NvU32 offset, NvU32 data);
NvU64 nvswitch_read_64bit_counter(nvswitch_device *device, NvU32 lo_offset, NvU32 hi_offset);
void nvswitch_timeout_create(NvU64 timeout_ns, NVSWITCH_TIMEOUT *time);
NvBool nvswitch_timeout_check(NVSWITCH_TIMEOUT *time);
void nvswitch_task_create(nvswitch_device *device,
void (*task_fn)(nvswitch_device *device), NvU64 period_nsec, NvU32 flags);
NvlStatus nvswitch_task_create(nvswitch_device *device,
void (*task_fn)(nvswitch_device *device),
NvU64 period_nsec, NvU32 flags);
NvlStatus nvswitch_task_create_args(nvswitch_device* device, void *fn_args,
void (*task_fn)(nvswitch_device* device, void *fn_args),
NvU64 period_nsec, NvU32 flags);
void nvswitch_tasks_destroy(nvswitch_device *device);
void nvswitch_free_chipdevice(nvswitch_device *device);
@@ -535,6 +560,7 @@ void nvswitch_reset_persistent_link_hw_state(nvswitch_device *device, NvU32
void nvswitch_store_topology_information(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_launch_ALI(nvswitch_device *device);
NvlStatus nvswitch_launch_ALI_link_training(nvswitch_device *device, nvlink_link *link, NvBool bSync);
NvlStatus nvswitch_inband_read_data(nvswitch_device *device, NvU8 *dest, NvU32 linkId, NvU32 *dataSize);
void nvswitch_filter_messages(nvswitch_device *device, NvU32 linkId);
NvlStatus nvswitch_set_training_mode(nvswitch_device *device);

View File

@@ -94,6 +94,8 @@
_op(NvlStatus, nvswitch_ctrl_set_latency_bins, (nvswitch_device *device, NVSWITCH_SET_LATENCY_BINS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_ingress_reqlinkid, (nvswitch_device *device, NVSWITCH_GET_INGRESS_REQLINKID_PARAMS *params), _arch) \
_op(NvU32, nvswitch_i2c_get_port_info, (nvswitch_device *device, NvU32 port), _arch) \
_op(NvlStatus, nvswitch_ctrl_register_read, (nvswitch_device *device, NVSWITCH_REGISTER_READ *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_register_write, (nvswitch_device *device, NVSWITCH_REGISTER_WRITE *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_i2c_indexed, (nvswitch_device *device, NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams), _arch) \
_op(NvlStatus, nvswitch_ctrl_therm_read_temperature, (nvswitch_device *device, NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info), _arch) \
_op(NvlStatus, nvswitch_ctrl_therm_get_temperature_limit, (nvswitch_device *device, NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS *info), _arch) \
@@ -122,7 +124,9 @@
_op(NvBool, nvswitch_is_smbpbi_supported, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_post_init_device_setup, (nvswitch_device *device), _arch) \
_op(void, nvswitch_post_init_blacklist_device_setup, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_setup_link_system_registers, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_setup_system_registers, (nvswitch_device *device), _arch) \
_op(void, nvswitch_setup_link_system_registers, (nvswitch_device *device, nvlink_link *link), _arch) \
_op(void, nvswitch_load_link_disable_settings, (nvswitch_device *device, nvlink_link *link), _arch) \
_op(NvlStatus, nvswitch_read_vbios_link_entries, (nvswitch_device *device, NvU32 tblPtr,NvU32 expected_link_entriesCount,NVLINK_CONFIG_DATA_LINKENTRY *link_entries, NvU32 *identified_link_entriesCount), _arch) \
_op(NvlStatus, nvswitch_vbios_read_structure, (nvswitch_device *device, void *structure, NvU32 offset, NvU32 *ppacked_size, const char *format), _arch) \
_op(NvlStatus, nvswitch_get_nvlink_ecc_errors, (nvswitch_device *device, NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS *p), _arch) \
@@ -137,19 +141,25 @@
_op(void, nvswitch_load_uuid, (nvswitch_device *device), _arch) \
_op(void, nvswitch_i2c_set_hw_speed_mode, (nvswitch_device *device, NvU32 port, NvU32 speedMode), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_bios_info, (nvswitch_device *device, NVSWITCH_GET_BIOS_INFO_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_inforom_version, (nvswitch_device *device, NVSWITCH_GET_INFOROM_VERSION_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_read_oob_blacklist_state, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_write_fabric_state, (nvswitch_device *device), _arch) \
_op(void, nvswitch_initialize_oms_state, (nvswitch_device *device, INFOROM_OMS_STATE *pOmsState), _arch) \
_op(NvlStatus, nvswitch_oms_inforom_flush, (nvswitch_device *device), _arch) \
_op(void, nvswitch_inforom_ecc_get_total_errors, (nvswitch_device *device, INFOROM_ECC_OBJECT *pEccGeneric, NvU64 *corCount, NvU64 *uncCount), _arch) \
_op(NvlStatus, nvswitch_bbx_setup_prologue, (nvswitch_device *device, void *pInforomBbxState), _arch) \
_op(NvlStatus, nvswitch_bbx_setup_epilogue, (nvswitch_device *device, void *pInforomBbxState), _arch) \
_op(NvlStatus, nvswitch_bbx_add_data_time, (nvswitch_device *device, void *pInforomBbxState, void *pInforomBbxData), _arch) \
_op(NvlStatus, nvswitch_bbx_add_sxid, (nvswitch_device *device, void *pInforomBbxState, void *pInforomBbxData), _arch) \
_op(NvlStatus, nvswitch_bbx_add_temperature, (nvswitch_device *device, void *pInforomBbxState, void *pInforomBbxData), _arch) \
_op(void, nvswitch_bbx_set_initial_temperature, (nvswitch_device *device, void *pInforomBbxState, void *pInforomBbxData), _arch) \
_op(NvlStatus, nvswitch_inforom_bbx_get_sxid, (nvswitch_device *device, NVSWITCH_GET_SXIDS_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_bbx_add_sxid, (nvswitch_device *device, NvU32 exceptionType, NvU32 data0, NvU32 data1, NvU32 data2), _arch) \
_op(NvlStatus, nvswitch_bbx_unload, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_bbx_load, (nvswitch_device *device, NvU64 time_ns, NvU8 osType, NvU32 osVersion), _arch) \
_op(NvlStatus, nvswitch_bbx_get_sxid, (nvswitch_device *device, NVSWITCH_GET_SXIDS_PARAMS * params), _arch) \
_op(NvlStatus, nvswitch_smbpbi_alloc, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_smbpbi_post_init_hal, (nvswitch_device *device), _arch) \
_op(void, nvswitch_smbpbi_destroy_hal, (nvswitch_device *device), _arch) \
_op(void, nvswitch_smbpbi_send_unload, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_smbpbi_dem_load, (nvswitch_device *device), _arch) \
_op(void, nvswitch_smbpbi_dem_flush, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_smbpbi_get_dem_num_messages, (nvswitch_device *device, NvU8 *pMsgCount), _arch) \
_op(void, nvswitch_smbpbi_log_message, (nvswitch_device *device, NvU32 num, NvU32 msglen, NvU8 *osErrorString), _arch) \
_op(NvlStatus, nvswitch_smbpbi_send_init_data, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_set_minion_initialized, (nvswitch_device *device, NvU32 idx_minion, NvBool initialized), _arch) \
_op(NvBool, nvswitch_is_minion_initialized, (nvswitch_device *device, NvU32 idx_minion), _arch) \
_op(NvlStatus, nvswitch_get_link_public_id, (nvswitch_device *device, NvU32 linkId, NvU32 *publicId), _arch) \
@@ -206,13 +216,19 @@
_op(void, nvswitch_apply_recal_settings, (nvswitch_device *device, nvlink_link *), _arch) \
_op(NvlStatus, nvswitch_service_nvldl_fatal_link, (nvswitch_device *device, NvU32 nvliptInstance, NvU32 link), _arch) \
_op(NvlStatus, nvswitch_service_minion_link, (nvswitch_device *device, NvU32 link_id), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_sw_info, (nvswitch_device *device, NVSWITCH_GET_SW_INFO_PARAMS *p), _arch)
_op(NvlStatus, nvswitch_ctrl_get_sw_info, (nvswitch_device *device, NVSWITCH_GET_SW_INFO_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_err_info, (nvswitch_device *device, NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret), _arch) \
_op(NvlStatus, nvswitch_ctrl_clear_counters, (nvswitch_device *device, NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS *ret), _arch)
#define NVSWITCH_HAL_FUNCTION_LIST_LS10(_op, _arch) \
_op(NvlStatus, nvswitch_launch_ALI, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_launch_ALI_link_training, (nvswitch_device *device, nvlink_link *link), _arch) \
_op(NvlStatus, nvswitch_launch_ALI_link_training, (nvswitch_device *device, nvlink_link *link, NvBool bSync), _arch) \
_op(NvlStatus, nvswitch_ctrl_inband_send_data, (nvswitch_device *device, NVSWITCH_INBAND_SEND_DATA_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_inband_read_data, (nvswitch_device *device, NVSWITCH_INBAND_READ_DATA_PARAMS *p), _arch) \
_op(void, nvswitch_send_inband_nack, (nvswitch_device *device, NvU32 *msghdr, NvU32 linkId), _arch) \
_op(NvU32, nvswitch_get_max_persistent_message_count, (nvswitch_device *device), _arch) \
_op(NvlStatus, nvswitch_ctrl_set_mc_rid_table, (nvswitch_device *device, NVSWITCH_SET_MC_RID_TABLE_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_mc_rid_table, (nvswitch_device *device, NVSWITCH_GET_MC_RID_TABLE_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_set_residency_bins, (nvswitch_device *device, NVSWITCH_SET_RESIDENCY_BINS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_residency_bins, (nvswitch_device *device, NVSWITCH_GET_RESIDENCY_BINS *p), _arch) \
_op(NvlStatus, nvswitch_ctrl_get_rb_stall_busy, (nvswitch_device *device, NVSWITCH_GET_RB_STALL_BUSY *p), _arch) \

View File

@@ -46,6 +46,20 @@
(destName)[2] = (srcName)[2]; \
}
//
// OS type defines.
//
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_OTHER 0x0
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_WIN9X 0x1
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_WIN2K 0x2
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_WIN 0x4
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_UNIX 0x5
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_MAJOR 7:0
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_MINOR 15:8
#define INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_BUILD 31:16
struct INFOROM_OBJECT_CACHE_ENTRY
{
INFOROM_OBJECT_HEADER_V1_00 header;
@@ -110,6 +124,7 @@ NvlStatus nvswitch_inforom_load_object(nvswitch_device* device,
const char *pObjectFormat, NvU8 *pPackedObject, void *pObject);
void nvswitch_inforom_read_static_data(nvswitch_device *device,
struct inforom *pInforom, RM_SOE_SMBPBI_INFOROM_DATA *pData);
void nvswitch_inforom_string_copy(inforom_U008 *pSrc, NvU8 *pDst, NvU32 size);
// InfoROM RO APIs
NvlStatus nvswitch_inforom_read_only_objects_load(nvswitch_device *device);
@@ -151,8 +166,6 @@ void nvswitch_inforom_bbx_unload(nvswitch_device * device);
NvlStatus nvswitch_inforom_bbx_add_sxid(nvswitch_device *device,
NvU32 exceptionType, NvU32 data0,
NvU32 data1, NvU32 data2);
void nvswitch_bbx_collect_current_time(nvswitch_device *device,
void *pBbxState);
NvlStatus nvswitch_inforom_bbx_get_sxid(nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS *params);

View File

@@ -125,7 +125,6 @@ typedef struct engine_descriptor
_op(PTIMER) \
_op(CPR) \
_op(TILEOUT) \
_op(TILEOUT_PERFMON) \
#define NVSWITCH_LIST_ALL_ENGINES(_op) \
_op(XVE) \
@@ -150,11 +149,6 @@ typedef struct engine_descriptor
_op(NPORT_PERFMON) \
\
_op(NVLW_PERFMON) \
_op(RX_PERFMON) \
_op(TX_PERFMON) \
\
_op(NXBAR_PERFMON) \
_op(TILE_PERFMON) \
#define ENGINE_ID_LIST(_eng) \
NVSWITCH_ENGINE_ID_##_eng,
@@ -360,12 +354,6 @@ typedef struct
NvBool bIsRepeaterMode;
// Check if BUFFER_COMPLETE is seen
volatile NvBool isBufferComplete;
// Check if BUFFER_FAIL is seen
volatile NvBool isBufferFail;
// Minion Inband Data structure
nvswitch_inband_receive_data inbandData;

View File

@@ -108,56 +108,36 @@ nvswitch_oms_inforom_flush_lr10
struct nvswitch_device *device
);
NvlStatus
nvswitch_bbx_setup_prologue_lr10
(
nvswitch_device *device,
void *pInforomBbxState
);
NvlStatus
nvswitch_bbx_setup_epilogue_lr10
(
nvswitch_device *device,
void *pInforomBbxState
);
NvlStatus
nvswitch_bbx_add_data_time_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
);
NvlStatus
nvswitch_bbx_add_sxid_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
NvU32 exceptionType,
NvU32 data0,
NvU32 data1,
NvU32 data2
);
NvlStatus
nvswitch_bbx_add_temperature_lr10
nvswitch_bbx_unload_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
);
void
nvswitch_bbx_set_initial_temperature_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
nvswitch_device *device
);
NvlStatus
nvswitch_inforom_bbx_get_sxid_lr10
nvswitch_bbx_load_lr10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS *params
NvU64 time_ns,
NvU8 osType,
NvU32 osVersion
);
NvlStatus
nvswitch_bbx_get_sxid_lr10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS * params
);
#endif //_INFOROM_LR10_H_

View File

@@ -470,11 +470,6 @@ typedef struct
_op(NPORT_PERFMON, _MULTICAST_BCAST) \
\
_op(NVLW_PERFMON, _BCAST) \
_op(RX_PERFMON, _MULTICAST_BCAST) \
_op(TX_PERFMON, _MULTICAST_BCAST) \
\
_op(NXBAR_PERFMON, _BCAST) \
_op(TILE_PERFMON, _MULTICAST_BCAST) \
typedef struct
{
@@ -648,11 +643,20 @@ NvlStatus nvswitch_ctrl_get_nvlink_lp_counters_lr10(nvswitch_device *device, NVS
NvlStatus nvswitch_service_nvldl_fatal_link_lr10(nvswitch_device *device, NvU32 nvliptInstance, NvU32 link);
NvlStatus nvswitch_ctrl_inband_send_data_lr10(nvswitch_device *device, NVSWITCH_INBAND_SEND_DATA_PARAMS *p);
NvlStatus nvswitch_ctrl_inband_read_data_lr10(nvswitch_device *device, NVSWITCH_INBAND_READ_DATA_PARAMS *p);
NvlStatus nvswitch_launch_ALI_link_training_lr10(nvswitch_device *device, nvlink_link *link);
void nvswitch_send_inband_nack_lr10(nvswitch_device *device, NvU32 *msghdr, NvU32 linkId);
NvU32 nvswitch_get_max_persistent_message_count_lr10(nvswitch_device *device);
NvlStatus nvswitch_launch_ALI_link_training_lr10(nvswitch_device *device, nvlink_link *link, NvBool bSync);
NvlStatus nvswitch_service_minion_link_lr10(nvswitch_device *device, NvU32 nvliptInstance);
void nvswitch_apply_recal_settings_lr10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_ctrl_get_sw_info_lr10(nvswitch_device *device, NVSWITCH_GET_SW_INFO_PARAMS *p);
void nvswitch_setup_link_system_registers_lr10(nvswitch_device *device, nvlink_link *link);
void nvswitch_load_link_disable_settings_lr10(nvswitch_device *device, nvlink_link *link);
NvBool nvswitch_is_smbpbi_supported_lr10(nvswitch_device *device);
NvlStatus nvswitch_ctrl_set_mc_rid_table_lr10(nvswitch_device *device, NVSWITCH_SET_MC_RID_TABLE_PARAMS *p);
NvlStatus nvswitch_ctrl_get_mc_rid_table_lr10(nvswitch_device *device, NVSWITCH_GET_MC_RID_TABLE_PARAMS *p);
NvlStatus nvswitch_launch_ALI_lr10(nvswitch_device *device);
NvlStatus nvswitch_ctrl_get_bios_info_lr10(nvswitch_device *device, NVSWITCH_GET_BIOS_INFO_PARAMS *p);
#endif //_LR10_H_

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -24,6 +24,24 @@
#ifndef _SMBPBI_LR10_H_
#define _SMBPBI_LR10_H_
NvlStatus
nvswitch_smbpbi_alloc_lr10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_post_init_hal_lr10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_destroy_hal_lr10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_get_dem_num_messages_lr10
(
@@ -31,4 +49,43 @@ nvswitch_smbpbi_get_dem_num_messages_lr10
NvU8 *pMsgCount
);
NvlStatus
nvswitch_inforom_dem_load_lr10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_dem_load_lr10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_send_unload_lr10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_dem_flush_lr10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_log_message_lr10
(
nvswitch_device *device,
NvU32 num,
NvU32 msglen,
NvU8 *osErrorString
);
NvlStatus
nvswitch_smbpbi_send_init_data_lr10
(
nvswitch_device *device
);
#endif //_SMBPBI_LR10_H_

View File

@@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _CLOCK_LS10_H_
#define _CLOCK_LS10_H_
NvlStatus
nvswitch_init_pll_config_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_init_pll_ls10
(
nvswitch_device *device
);
void
nvswitch_init_clock_gating_ls10
(
nvswitch_device *device
);
#endif //_CLOCK_LS10_H_

View File

@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _GFW_LS10_H_
#define _GFW_LS10_H_
#include "nvswitch/ls10/dev_nvlsaw_ip.h"
#include "nvswitch/ls10/dev_therm.h"
#include "nvswitch/ls10/dev_fsp_pri.h"
//
// Transcribed from GFW ucode r5 v1 scratch definition for LS10
//
#define NV_NVLSAW_SW_SCRATCH(_index) (NV_NVLSAW_SW_SCRATCH_0 + (_index)*4)
#define NV_NVLSAW_SW_BIOS_VERSION NV_NVLSAW_SW_SCRATCH(6)
#define NV_NVLSAW_SW_OEM_BIOS_VERSION NV_NVLSAW_SW_SCRATCH(7)
//-----------------------------------------------------------------------------
#define NV_GFW_GLOBAL_BOOT_PARTITION_PROGRESS NV_THERM_I2CS_SCRATCH
#define NV_GFW_GLOBAL_BOOT_PARTITION_PROGRESS_VALUE 7:0
#define NV_GFW_GLOBAL_BOOT_PARTITION_PROGRESS_VALUE_SUCCESS 0x000000FF
#define NV_NVLSAW_SW_OEM_BIOS_VERSION_BOARD_ID 31:16
#endif //_GFW_LS10_H_

View File

@@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _INFOROM_LS10_H_
#define _INFOROM_LS10_H_
NvlStatus nvswitch_inforom_nvl_log_error_event_ls10
(
nvswitch_device *device,
void *pNvlGeneric,
void *pNvlErrorEvent,
NvBool *bDirty
);
NvlStatus nvswitch_inforom_nvl_update_link_correctable_error_info_ls10
(
nvswitch_device *device,
void *pNvlGeneric,
void *pData,
NvU8 linkId,
NvU8 nvliptInstance,
NvU8 localLinkIdx,
void *pNvlErrorCounts,
NvBool *bDirty
);
void
nvswitch_initialize_oms_state_ls10
(
nvswitch_device *device,
INFOROM_OMS_STATE *pOmsState
);
NvBool
nvswitch_oms_get_device_disable_ls10
(
INFOROM_OMS_STATE *pOmsState
);
void
nvswitch_oms_set_device_disable_ls10
(
INFOROM_OMS_STATE *pOmsState,
NvBool bForceDeviceDisable
);
NvlStatus
nvswitch_oms_inforom_flush_ls10
(
struct nvswitch_device *device
);
void
nvswitch_inforom_ecc_get_total_errors_ls10
(
nvswitch_device *device,
INFOROM_ECC_OBJECT *pEccGeneric,
NvU64 *pCorrectedTotal,
NvU64 *pUncorrectedTotal
);
NvlStatus
nvswitch_bbx_add_sxid_ls10
(
nvswitch_device *device,
NvU32 exceptionType,
NvU32 data0,
NvU32 data1,
NvU32 data2
);
NvlStatus
nvswitch_bbx_unload_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_bbx_load_ls10
(
nvswitch_device *device,
NvU64 time_ns,
NvU8 osType,
NvU32 osVersion
);
NvlStatus
nvswitch_bbx_get_sxid_ls10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS * params
);
#endif //_INFOROM_LS10_H_

View File

@@ -0,0 +1,993 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _LS10_H_
#define _LS10_H_
#include "export_nvswitch.h"
#include "common_nvswitch.h"
#include "ctrl_dev_nvswitch.h"
#include "nvswitch/ls10/dev_master.h"
#define NVSWITCH_NUM_LINKS_LS10 64
#define NVSWITCH_NUM_LANES_LS10 2
#define NVSWITCH_LINKS_PER_MINION_LS10 4
#define NVSWITCH_LINKS_PER_NVLIPT_LS10 4
#define NVSWITCH_LINKS_PER_NVLW_LS10 4
#define NVSWITCH_LINKS_PER_NPG_LS10 4
#define NVSWITCH_NPORT_PER_NPG_LS10 NVSWITCH_LINKS_PER_NPG_LS10
#define NUM_PTOP_ENGINE_LS10 1
#define NUM_FUSE_ENGINE_LS10 1
#define NUM_GIN_ENGINE_LS10 1
#define NUM_JTAG_ENGINE_LS10 1
#define NUM_PMGR_ENGINE_LS10 1
#define NUM_SAW_ENGINE_LS10 1
#define NUM_ROM_ENGINE_LS10 1
#define NUM_EXTDEV_ENGINE_LS10 1
#define NUM_PTIMER_ENGINE_LS10 1
#define NUM_SOE_ENGINE_LS10 1
#define NUM_SMR_ENGINE_LS10 2
#define NUM_SE_ENGINE_LS10 1
#define NUM_THERM_ENGINE_LS10 1
#define NUM_XAL_ENGINE_LS10 1
#define NUM_XAL_FUNC_ENGINE_LS10 1
#define NUM_XTL_CONFIG_ENGINE_LS10 1
#define NUM_XPL_ENGINE_LS10 1
#define NUM_XTL_ENGINE_LS10 1
#define NUM_SYSCTRL_ENGINE_LS10 1
#define NUM_UXL_ENGINE_LS10 1
#define NUM_GPU_PTOP_ENGINE_LS10 1
#define NUM_PMC_ENGINE_LS10 1
#define NUM_PBUS_ENGINE_LS10 1
#define NUM_ROM2_ENGINE_LS10 1
#define NUM_GPIO_ENGINE_LS10 1
#define NUM_FSP_ENGINE_LS10 1
#define NUM_CLKS_SYS_ENGINE_LS10 1
#define NUM_CLKS_SYSB_ENGINE_LS10 1
#define NUM_CLKS_P0_ENGINE_LS10 4
#define NUM_CLKS_P0_BCAST_ENGINE_LS10 1
#define NUM_SAW_PM_ENGINE_LS10 1
#define NUM_PCIE_PM_ENGINE_LS10 1
#define NUM_PRT_PRI_HUB_ENGINE_LS10 16
#define NUM_PRT_PRI_RS_CTRL_ENGINE_LS10 16
#define NUM_PRT_PRI_HUB_BCAST_ENGINE_LS10 1
#define NUM_PRT_PRI_RS_CTRL_BCAST_ENGINE_LS10 1
#define NUM_SYS_PRI_HUB_ENGINE_LS10 1
#define NUM_SYS_PRI_RS_CTRL_ENGINE_LS10 1
#define NUM_SYSB_PRI_HUB_ENGINE_LS10 1
#define NUM_SYSB_PRI_RS_CTRL_ENGINE_LS10 1
#define NUM_PRI_MASTER_RS_ENGINE_LS10 1
#define NUM_NPG_ENGINE_LS10 16
#define NUM_NPG_PERFMON_ENGINE_LS10 NUM_NPG_ENGINE_LS10
#define NUM_NPORT_ENGINE_LS10 (NUM_NPG_ENGINE_LS10 * NVSWITCH_NPORT_PER_NPG_LS10)
#define NUM_NPORT_MULTICAST_ENGINE_LS10 NUM_NPG_ENGINE_LS10
#define NUM_NPORT_PERFMON_ENGINE_LS10 NUM_NPORT_ENGINE_LS10
#define NUM_NPORT_PERFMON_MULTICAST_ENGINE_LS10 NUM_NPG_ENGINE_LS10
#define NUM_NPG_BCAST_ENGINE_LS10 1
#define NUM_NPG_PERFMON_BCAST_ENGINE_LS10 NUM_NPG_BCAST_ENGINE_LS10
#define NUM_NPORT_BCAST_ENGINE_LS10 NVSWITCH_NPORT_PER_NPG_LS10
#define NUM_NPORT_MULTICAST_BCAST_ENGINE_LS10 NUM_NPG_BCAST_ENGINE_LS10
#define NUM_NPORT_PERFMON_BCAST_ENGINE_LS10 NUM_NPORT_BCAST_ENGINE_LS10
#define NUM_NPORT_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NPG_BCAST_ENGINE_LS10
#define NUM_NVLW_ENGINE_LS10 16
#define NUM_NVLIPT_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_MINION_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_PLL_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_CPR_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLW_PERFMON_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLIPT_SYS_PERFMON_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLDL_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLTLC_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLIPT_LNK_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_SYS_PERFMON_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_TX_PERFMON_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_RX_PERFMON_MULTICAST_ENGINE_LS10 NUM_NVLW_ENGINE_LS10
#define NUM_NVLDL_ENGINE_LS10 (NUM_NVLW_ENGINE_LS10 * NVSWITCH_LINKS_PER_NVLIPT_LS10)
#define NUM_NVLTLC_ENGINE_LS10 NUM_NVLDL_ENGINE_LS10
#define NUM_NVLIPT_LNK_ENGINE_LS10 NUM_NVLDL_ENGINE_LS10
#define NUM_SYS_PERFMON_ENGINE_LS10 NUM_NVLDL_ENGINE_LS10
#define NUM_TX_PERFMON_ENGINE_LS10 NUM_NVLDL_ENGINE_LS10
#define NUM_RX_PERFMON_ENGINE_LS10 NUM_NVLDL_ENGINE_LS10
#define NUM_NVLW_BCAST_ENGINE_LS10 1
#define NUM_NVLIPT_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_MINION_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_PLL_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_CPR_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLW_PERFMON_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLIPT_SYS_PERFMON_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLDL_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLTLC_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLIPT_LNK_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_SYS_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_TX_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_RX_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NVLW_BCAST_ENGINE_LS10
#define NUM_NVLDL_BCAST_ENGINE_LS10 NVSWITCH_LINKS_PER_NVLIPT_LS10
#define NUM_NVLTLC_BCAST_ENGINE_LS10 NUM_NVLDL_BCAST_ENGINE_LS10
#define NUM_NVLIPT_LNK_BCAST_ENGINE_LS10 NUM_NVLDL_BCAST_ENGINE_LS10
#define NUM_SYS_PERFMON_BCAST_ENGINE_LS10 NUM_NVLDL_BCAST_ENGINE_LS10
#define NUM_TX_PERFMON_BCAST_ENGINE_LS10 NUM_NVLDL_BCAST_ENGINE_LS10
#define NUM_RX_PERFMON_BCAST_ENGINE_LS10 NUM_NVLDL_BCAST_ENGINE_LS10
#define NUM_NXBAR_ENGINE_LS10 3
#define NUM_NXBAR_PERFMON_ENGINE_LS10 NUM_NXBAR_ENGINE_LS10
#define NUM_TILE_MULTICAST_ENGINE_LS10 NUM_NXBAR_ENGINE_LS10
#define NUM_TILE_PERFMON_MULTICAST_ENGINE_LS10 NUM_NXBAR_ENGINE_LS10
#define NUM_TILE_ENGINE_LS10 (12 * NUM_NXBAR_ENGINE_LS10)
#define NUM_TILE_PERFMON_ENGINE_LS10 NUM_TILE_ENGINE_LS10
#define NUM_TILEOUT_MULTICAST_ENGINE_LS10 NUM_NXBAR_ENGINE_LS10
#define NUM_TILEOUT_PERFMON_MULTICAST_ENGINE_LS10 NUM_NXBAR_ENGINE_LS10
#define NUM_TILEOUT_ENGINE_LS10 NUM_TILE_ENGINE_LS10
#define NUM_TILEOUT_PERFMON_ENGINE_LS10 NUM_TILE_ENGINE_LS10
#define NUM_NXBAR_BCAST_ENGINE_LS10 1
#define NUM_NXBAR_PERFMON_BCAST_ENGINE_LS10 NUM_NXBAR_BCAST_ENGINE_LS10
#define NUM_TILE_MULTICAST_BCAST_ENGINE_LS10 NUM_NXBAR_BCAST_ENGINE_LS10
#define NUM_TILE_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NXBAR_BCAST_ENGINE_LS10
#define NUM_TILE_BCAST_ENGINE_LS10 12
#define NUM_TILE_PERFMON_BCAST_ENGINE_LS10 NUM_TILE_BCAST_ENGINE_LS10
#define NUM_TILEOUT_MULTICAST_BCAST_ENGINE_LS10 NUM_NXBAR_BCAST_ENGINE_LS10
#define NUM_TILEOUT_PERFMON_MULTICAST_BCAST_ENGINE_LS10 NUM_NXBAR_BCAST_ENGINE_LS10
#define NUM_TILEOUT_BCAST_ENGINE_LS10 NUM_TILE_BCAST_ENGINE_LS10
#define NUM_TILEOUT_PERFMON_BCAST_ENGINE_LS10 NUM_TILE_BCAST_ENGINE_LS10
#define NUM_MAX_MCFLA_SLOTS_LS10 128
#define NPORT_TO_LINK_LS10(_device, _npg, _nport) \
( \
NVSWITCH_ASSERT((_npg < NUM_NPG_ENGINE_LS10)) \
, \
NVSWITCH_ASSERT((_nport < NVSWITCH_NPORT_PER_NPG_LS10)) \
, \
((_npg) * NVSWITCH_NPORT_PER_NPG_LS10 + (_nport)) \
)
#define NVSWITCH_NUM_LINKS_PER_NVLIPT_LS10 (NVSWITCH_NUM_LINKS_LS10/NUM_NVLIPT_ENGINE_LS10)
#define NVSWITCH_NVLIPT_GET_LOCAL_LINK_ID_LS10(_physlinknum) \
((_physlinknum)%NVSWITCH_NUM_LINKS_PER_NVLIPT_LS10)
#define NVSWITCH_NVLIPT_GET_LOCAL_LINK_MASK64_LS10(_nvlipt_idx) \
(NVBIT64(NVSWITCH_LINKS_PER_NVLIPT_LS10) - 1) << (_nvlipt_idx * NVSWITCH_LINKS_PER_NVLIPT_LS10);
#define DMA_ADDR_WIDTH_LS10 64
//
// Helpful IO wrappers
//
#define NVSWITCH_NPORT_WR32_LS10(_d, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, NPORT, , _engidx, _dev, _reg, _data)
#define NVSWITCH_NPORT_RD32_LS10(_d, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, NPORT, , _engidx, _dev, _reg)
#define NVSWITCH_MINION_WR32_LS10(_d, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, MINION, , _engidx, _dev, _reg, _data)
#define NVSWITCH_MINION_RD32_LS10(_d, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, MINION, , _engidx, _dev, _reg)
#define NVSWITCH_MINION_WR32_BCAST_LS10(_d, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, MINION, _BCAST, 0, _dev, _reg, _data)
#define NVSWITCH_NPG_WR32_LS10(_d, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, NPG, , _engidx, _dev, _reg, _data)
#define NVSWITCH_NPG_RD32_LS10(_d, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, NPG, , _engidx, _dev, _reg)
//
// Per-chip device information
//
#define DISCOVERY_TYPE_UNDEFINED 0
#define DISCOVERY_TYPE_DISCOVERY 1
#define DISCOVERY_TYPE_UNICAST 2
#define DISCOVERY_TYPE_BROADCAST 3
typedef struct
{
NvBool valid;
NvU32 initialized;
NvU32 version;
NvU32 disc_type;
union
{
struct
{
NvU32 cluster;
NvU32 cluster_id;
NvU32 discovery; // Used for top level only
} top;
struct
{
NvU32 uc_addr;
} uc;
struct
{
NvU32 bc_addr;
NvU32 mc_addr[3];
} bc;
} info;
} ENGINE_DISCOVERY_TYPE_LS10;
#define NVSWITCH_DECLARE_ENGINE_UC_LS10(_engine) \
ENGINE_DISCOVERY_TYPE_LS10 eng##_engine[NUM_##_engine##_ENGINE_LS10];
#define NVSWITCH_DECLARE_ENGINE_LS10(_engine) \
ENGINE_DISCOVERY_TYPE_LS10 eng##_engine[NUM_##_engine##_ENGINE_LS10]; \
ENGINE_DISCOVERY_TYPE_LS10 eng##_engine##_BCAST[NUM_##_engine##_BCAST_ENGINE_LS10];
#define NVSWITCH_LIST_LS10_ENGINE_UC(_op) \
_op(PTOP) \
_op(FUSE) \
_op(GIN) \
_op(JTAG) \
_op(PMGR) \
_op(SAW) \
_op(ROM) \
_op(EXTDEV) \
_op(PTIMER) \
_op(SOE) \
_op(SMR) \
_op(SE) \
_op(THERM) \
_op(XAL) \
_op(XAL_FUNC) \
_op(XTL_CONFIG) \
_op(XPL) \
_op(XTL) \
_op(UXL) \
_op(GPU_PTOP) \
_op(PMC) \
_op(PBUS) \
_op(ROM2) \
_op(GPIO) \
_op(FSP) \
_op(CLKS_SYS) \
_op(CLKS_SYSB) \
_op(CLKS_P0) \
_op(CLKS_P0_BCAST) \
_op(SAW_PM) \
_op(PCIE_PM) \
_op(SYS_PRI_HUB) \
_op(SYS_PRI_RS_CTRL) \
_op(SYSB_PRI_HUB) \
_op(SYSB_PRI_RS_CTRL) \
_op(PRI_MASTER_RS) \
#define NVSWITCH_LIST_PRI_HUB_LS10_ENGINE(_op) \
_op(PRT_PRI_HUB) \
_op(PRT_PRI_RS_CTRL) \
_op(PRT_PRI_HUB_BCAST) \
_op(PRT_PRI_RS_CTRL_BCAST) \
#define NVSWITCH_LIST_NPG_LS10_ENGINE(_op) \
_op(NPG) \
_op(NPG_PERFMON) \
_op(NPORT) \
_op(NPORT_MULTICAST) \
_op(NPORT_PERFMON) \
_op(NPORT_PERFMON_MULTICAST)
#define NVSWITCH_LIST_NVLW_LS10_ENGINE(_op) \
_op(NVLW) \
_op(NVLIPT) \
_op(MINION) \
_op(CPR) \
_op(NVLW_PERFMON) \
_op(NVLIPT_SYS_PERFMON) \
_op(NVLDL_MULTICAST) \
_op(NVLTLC_MULTICAST) \
_op(NVLIPT_LNK_MULTICAST) \
_op(SYS_PERFMON_MULTICAST) \
_op(TX_PERFMON_MULTICAST) \
_op(RX_PERFMON_MULTICAST) \
_op(NVLDL) \
_op(NVLTLC) \
_op(NVLIPT_LNK) \
_op(SYS_PERFMON) \
_op(TX_PERFMON) \
_op(RX_PERFMON)
#define NVSWITCH_LIST_NXBAR_LS10_ENGINE(_op) \
_op(NXBAR) \
_op(NXBAR_PERFMON) \
_op(TILE_MULTICAST) \
_op(TILE_PERFMON_MULTICAST) \
_op(TILE) \
_op(TILE_PERFMON) \
_op(TILEOUT_MULTICAST) \
_op(TILEOUT_PERFMON_MULTICAST) \
_op(TILEOUT) \
_op(TILEOUT_PERFMON)
#define NVSWITCH_LIST_LS10_ENGINE(_op) \
NVSWITCH_LIST_NPG_LS10_ENGINE(_op) \
NVSWITCH_LIST_NVLW_LS10_ENGINE(_op) \
NVSWITCH_LIST_NXBAR_LS10_ENGINE(_op)
//
// The chip-specific engine list is used to generate the code to collect
// discovered unit information and coalesce it into the data structures used by
// the common IO library (see io_nvswitch.h).
//
// The PTOP discovery table presents the information on wrappers and sub-units
// in a hierarchical manner. The top level discovery contains information
// about top level UNICAST units and IP wrappers like NPG, NVLW, and NXBAR.
// Individual units within an IP wrapper are described in discovery sub-tables.
// Each IP wrapper may have MULTICAST descriptors to allow addressing sub-units
// within a wrapper and a cluster of IP wrappers will also have a BCAST
// discovery tables, which have MULTICAST descriptors within them.
// In order to collect all the useful unit information into a single container,
// we need to pick where to find each piece within the parsed discovery table.
// Top level IP wrappers like NPG have a BCAST range to broadcast reads/writes,
// but IP sub-units like NPORT have a MULTICAST range within the BCAST IP
// wrapper to broadcast to all the sub-units in all the IP wrappers.
// So in the lists below top level IP wrappers (NPG, NVLW, and NXBAR) point
// to the _BCAST IP wrapper, but sub-unit point to the _MULTICAST range inside
// the BCAST unit (_MULTICAST_BCAST).
//
// All IP-based (0-based register manuals) engines need to be listed here to
// generate chip-specific handlers as well as in the global common list of all
// engines that have ever existed on *ANY* architecture(s) in order for them
// use common IO wrappers.
//
#define NVSWITCH_LIST_LS10_ENGINES(_op) \
_op(GIN, ) \
_op(XAL, ) \
_op(XPL, ) \
_op(XTL, ) \
_op(SAW, ) \
_op(SOE, ) \
_op(SMR, ) \
\
_op(PRT_PRI_HUB, _BCAST) \
_op(PRT_PRI_RS_CTRL, _BCAST) \
_op(SYS_PRI_HUB, ) \
_op(SYS_PRI_RS_CTRL, ) \
_op(SYSB_PRI_HUB, ) \
_op(SYSB_PRI_RS_CTRL, ) \
_op(PRI_MASTER_RS, ) \
_op(PTIMER, ) \
_op(CLKS_SYS, ) \
_op(CLKS_SYSB, ) \
_op(CLKS_P0, _BCAST) \
\
_op(NPG, _BCAST) \
_op(NPORT, _MULTICAST_BCAST) \
\
_op(NVLW, _BCAST) \
_op(MINION, _BCAST) \
_op(NVLIPT, _BCAST) \
_op(CPR, _BCAST) \
_op(NVLIPT_LNK, _MULTICAST_BCAST) \
_op(NVLTLC, _MULTICAST_BCAST) \
_op(NVLDL, _MULTICAST_BCAST) \
\
_op(NXBAR, _BCAST) \
_op(TILE, _MULTICAST_BCAST) \
_op(TILEOUT, _MULTICAST_BCAST) \
\
_op(NPG_PERFMON, _BCAST) \
_op(NPORT_PERFMON, _MULTICAST_BCAST) \
\
_op(NVLW_PERFMON, _BCAST) \
//
// These field #defines describe which physical fabric address bits are
// relevant to the specific remap table address check/remap operation.
//
#define NV_INGRESS_REMAP_ADDR_PHYS_LS10 51:39 /* LR10: 46:36 */
#define NV_INGRESS_REMAP_ADR_OFFSET_PHYS_LS10 38:21 /* LR10: 35:20 */
#define NV_INGRESS_REMAP_ADR_BASE_PHYS_LS10 38:21 /* LR10: 35:20 */
#define NV_INGRESS_REMAP_ADR_LIMIT_PHYS_LS10 38:21 /* LR10: 35:20 */
//
// Multicast REMAP table is not indexed through the same _RAM_SEL mechanism as
// other REMAP tables, but we want to be able to use the same set of APIs for
// all the REMAP tables, so define a special RAM_SEL value for MCREMAP that
// does not conflict with the existing definitions.
//
#define NV_INGRESS_REQRSPMAPADDR_RAM_SEL_SELECT_MULTICAST_REMAPRAM (DRF_MASK(NV_INGRESS_REQRSPMAPADDR_RAM_ADDRESS) + 1)
//
// NPORT Portstat information
//
//
// LS10 supports CREQ0(0), DNGRD(1), ATR(2), ATSD(3), PROBE(4), RSP0(5), CREQ1(6), and RSP1(7) VCs.
// But DNGRD(1), ATR(2), ATSD(3), and PROBE(4) will be never used.
//
#define NVSWITCH_NUM_VCS_LS10 8
typedef struct
{
NvU32 count;
NvU32 low;
NvU32 medium;
NvU32 high;
NvU32 panic;
}
NVSWITCH_LATENCY_BINS_LS10;
typedef struct
{
NvU32 count;
NvU64 start_time_nsec;
NvU64 last_read_time_nsec;
NVSWITCH_LATENCY_BINS_LS10 accum_latency[NVSWITCH_NUM_LINKS_LS10];
}
NVSWITCH_LATENCY_VC_LS10;
typedef struct
{
NvU32 sample_interval_msec;
NvU64 last_visited_time_nsec;
NVSWITCH_LATENCY_VC_LS10 latency[NVSWITCH_NUM_VCS_LS10];
} NVSWITCH_LATENCY_STATS_LS10;
#define NV_NPORT_PORTSTAT_LS10(_block, _reg, _vc, _hi_lo) (NV_NPORT_PORTSTAT ## _block ## _reg ## _0 ## _hi_lo + \
_vc * (NV_NPORT_PORTSTAT ## _block ## _reg ## _1 ## _hi_lo - NV_NPORT_PORTSTAT ## _block ## _reg ## _0 ## _hi_lo))
#define NVSWITCH_NPORT_PORTSTAT_RD32_LS10(_d, _engidx, _block, _reg, _hi_lo, _vc) \
( \
NVSWITCH_ASSERT(NVSWITCH_IS_LINK_ENG_VALID_LS10(_d, NPORT, _engidx)) \
, \
NVSWITCH_PRINT(_d, MMIO, \
"%s: MEM_RD NPORT_PORTSTAT[%d]: %s,%s,_%s,%s (%06x+%04x)\n", \
__FUNCTION__, \
_engidx, \
#_block, #_reg, #_vc, #_hi_lo, \
NVSWITCH_GET_ENG(_d, NPORT, , _engidx), \
NV_NPORT_PORTSTAT_LS10(_block, _reg, _vc, _hi_lo)) \
, \
nvswitch_reg_read_32(_d, \
NVSWITCH_GET_ENG(_d, NPORT, , _engidx) + \
NV_NPORT_PORTSTAT_LS10(_block, _reg, _vc, _hi_lo)) \
); \
((void)(_d))
#define NVSWITCH_PORTSTAT_BCAST_WR32_LS10(_d, _block, _reg, _idx, _data) \
{ \
NVSWITCH_PRINT(_d, MMIO, \
"%s: BCAST_WR NPORT_PORTSTAT: %s,%s (%06x+%04x) 0x%08x\n", \
__FUNCTION__, \
#_block, #_reg, \
NVSWITCH_GET_ENG(_d, NPORT, _BCAST, 0), \
NV_NPORT_PORTSTAT_LS10(_block, _reg, _idx, ), _data); \
NVSWITCH_OFF_WR32(_d, \
NVSWITCH_GET_ENG(_d, NPORT, _BCAST, 0) + \
NV_NPORT_PORTSTAT_LS10(_block, _reg, _idx, ), _data); \
}
#define NVSWITCH_DEFERRED_LINK_STATE_CHECK_INTERVAL_NS (10 * NVSWITCH_INTERVAL_1SEC_IN_NS)
#define NVSWITCH_DEFERRED_FAULT_UP_CHECK_INTERVAL_NS (10 * NVSWITCH_INTERVAL_1MSEC_IN_NS)
// Struct used for passing around error masks in error handling functions
typedef struct
{
NvU32 dl;
NvU32 tlcRx0;
NvU32 tlcRx0Injected;
NvU32 tlcRx1;
NvU32 tlcRx1Injected;
NvU32 liptLnk;
NvU32 liptLnkInjected;
} NVLINK_LINK_ERROR_INFO_ERR_MASKS, *PNVLINK_LINK_ERROR_INFO_ERR_MASKS;
typedef struct
{
NvBool bLinkErrorsCallBackEnabled;
NvBool bLinkStateCallBackEnabled;
NVLINK_LINK_ERROR_INFO_ERR_MASKS fatalIntrMask;
NVLINK_LINK_ERROR_INFO_ERR_MASKS nonFatalIntrMask;
} NVLINK_LINK_ERROR_REPORTING;
typedef struct
{
struct
{
NVSWITCH_ENGINE_DESCRIPTOR_TYPE common[NVSWITCH_ENGINE_ID_SIZE];
} io;
NVSWITCH_LIST_LS10_ENGINE_UC(NVSWITCH_DECLARE_ENGINE_UC_LS10)
NVSWITCH_LIST_PRI_HUB_LS10_ENGINE(NVSWITCH_DECLARE_ENGINE_UC_LS10)
NVSWITCH_LIST_LS10_ENGINE(NVSWITCH_DECLARE_ENGINE_LS10)
// Interrupts
NvU32 intr_minion_dest;
// VBIOS configuration Data
NVSWITCH_BIOS_NVLINK_CONFIG bios_config;
// GPIO
const NVSWITCH_GPIO_INFO *gpio_pin;
NvU32 gpio_pin_size;
// Latency statistics
NVSWITCH_LATENCY_STATS_LS10 *latency_stats;
// External TDIODE info
NVSWITCH_TDIODE_INFO_TYPE tdiode;
//
// Book-keep interrupt masks to restore them after reset.
// Note: There is no need to book-keep interrupt masks for NVLink units like
// DL, MINION, TLC etc. because NVLink init routines would setup them.
//
struct
{
NVSWITCH_INTERRUPT_MASK route;
NVSWITCH_INTERRUPT_MASK ingress[2];
NVSWITCH_INTERRUPT_MASK egress[2];
NVSWITCH_INTERRUPT_MASK tstate;
NVSWITCH_INTERRUPT_MASK sourcetrack;
NVSWITCH_INTERRUPT_MASK mc_tstate;
NVSWITCH_INTERRUPT_MASK red_tstate;
NVSWITCH_INTERRUPT_MASK tile;
NVSWITCH_INTERRUPT_MASK tileout;
} intr_mask;
// Ganged Link table
NvU64 *ganged_link_table;
//NVSWITCH Minion core
NvU32 minionEngArch;
NvBool riscvManifestBoot;
// Nvlink error reporting management
NVLINK_LINK_ERROR_REPORTING deferredLinkErrors[NVSWITCH_NUM_LINKS_LS10];
} ls10_device;
//
// Helpful IO wrappers
//
#define NVSWITCH_GET_CHIP_DEVICE_LS10(_device) \
( \
((_device)->chip_id == NV_PMC_BOOT_42_CHIP_ID_LS10) ? \
((ls10_device *) _device->chip_device) : \
NULL \
)
#define NVSWITCH_ENG_VALID_LS10(_d, _eng, _engidx) \
( \
((_engidx < NUM_##_eng##_ENGINE_LS10) && \
(NVSWITCH_GET_CHIP_DEVICE_LS10(_d)->eng##_eng[_engidx].valid)) ? \
NV_TRUE : NV_FALSE \
)
#define NVSWITCH_ENG_WR32_LS10(_d, _eng, _bcast, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, _eng, _bcast, _engidx, _dev, _reg, _data)
#define NVSWITCH_ENG_RD32_LS10(_d, _eng, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, _eng, , _engidx, _dev, _reg)
#define NVSWITCH_BCAST_WR32_LS10(_d, _eng, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, _eng, _BCAST, 0, _dev, _reg, _data)
#define NVSWITCH_BCAST_RD32_LS10(_d, _eng, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, _eng, _BCAST, 0, _dev, _reg)
#define NVSWITCH_SOE_WR32_LS10(_d, _instance, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, SOE, , _instance, _dev, _reg, _data)
#define NVSWITCH_SOE_RD32_LS10(_d, _instance, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, SOE, , _instance, _dev, _reg)
#define NVSWITCH_NPORT_BCAST_WR32_LS10(_d, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, NPORT, _BCAST, 0, _dev, _reg, _data)
#define NVSWITCH_SAW_WR32_LS10(_d, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, SAW, , 0, _dev, _reg, _data)
#define NVSWITCH_SAW_RD32_LS10(_d, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, SAW, , 0, _dev, _reg)
#define NVSWITCH_NPORT_MC_BCAST_WR32_LS10(_d, _dev, _reg, _data) \
NVSWITCH_BCAST_WR32_LS10(_d, NPORT, _dev, _reg, _data)
//
// Tile Column consists of 12 Tile blocks and 11 (really 12) Tileout blocks.
//
#define NUM_NXBAR_TILES_PER_TC_LS10 12
#define NUM_NXBAR_TILEOUTS_PER_TC_LS10 12
#define TILE_INDEX_LS10(_device, _nxbar, _tile) \
( \
NVSWITCH_ASSERT((_nxbar < NUM_NXBAR_ENGINE_LS10)) \
, \
NVSWITCH_ASSERT((_tile < NUM_NXBAR_TILES_PER_TC_LS10)) \
, \
((_nxbar) * NUM_NXBAR_TILES_PER_TC_LS10 + (_tile)) \
)
#define NVSWITCH_TILE_RD32(_d, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, TILE, , _engidx, _dev, _reg)
#define NVSWITCH_TILE_WR32(_d, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, TILE, , _engidx, _dev, _reg, _data)
#define NVSWITCH_TILEOUT_RD32(_d, _engidx, _dev, _reg) \
NVSWITCH_ENG_RD32(_d, TILEOUT, , _engidx, _dev, _reg)
#define NVSWITCH_TILEOUT_WR32(_d, _engidx, _dev, _reg, _data) \
NVSWITCH_ENG_WR32(_d, TILEOUT, , _engidx, _dev, _reg, _data)
//
// Per link register access routines
// LINK_* MMIO wrappers are used to reference per-link engine instances
//
#define NVSWITCH_IS_LINK_ENG_VALID_LS10(_d, _eng, _linknum) \
NVSWITCH_IS_LINK_ENG_VALID(_d, _linknum, _eng)
#define NVSWITCH_LINK_OFFSET_LS10(_d, _physlinknum, _eng, _dev, _reg) \
NVSWITCH_LINK_OFFSET(_d, _physlinknum, _eng, _dev, _reg)
#define NVSWITCH_LINK_WR32_LS10(_d, _physlinknum, _eng, _dev, _reg, _data) \
NVSWITCH_LINK_WR32(_d, _physlinknum, _eng, _dev, _reg, _data)
#define NVSWITCH_LINK_RD32_LS10(_d, _physlinknum, _eng, _dev, _reg) \
NVSWITCH_LINK_RD32(_d, _physlinknum, _eng, _dev, _reg)
#define NVSWITCH_LINK_WR32_IDX_LS10(_d, _physlinknum, _eng, _dev, _reg, _idx, _data) \
NVSWITCH_LINK_WR32_IDX(_d, _physlinknum, _eng, _dev, _reg, _idx, _data)
#define NVSWITCH_LINK_RD32_IDX_LS10(_d, _physlinknum, _eng, _dev, _reg, _idx) \
NVSWITCH_LINK_RD32_IDX(_d, _physlinknum, _eng, _dev, _reg, _idx)
#define NVSWITCH_MINION_LINK_WR32_LS10(_d, _physlinknum, _dev, _reg, _data) \
NVSWITCH_LINK_WR32(_d, _physlinknum, MINION, _dev, _reg, _data)
#define NVSWITCH_MINION_LINK_RD32_LS10(_d, _physlinknum, _dev, _reg) \
NVSWITCH_LINK_RD32(_d, _physlinknum, MINION, _dev, _reg)
//
// MINION
//
typedef const struct
{
NvU32 osCodeOffset;
NvU32 osCodeSize;
NvU32 osDataOffset;
NvU32 osDataSize;
NvU32 numApps;
NvU32 appCodeStart;
NvU32 appDataStart;
NvU32 codeOffset;
NvU32 codeSize;
NvU32 dataOffset;
NvU32 dataSize;
} FALCON_UCODE_HDR_INFO_LS10, *PFALCON_UCODE_HDR_INFO_LS10;
typedef const struct
{
//
// Version 1
// Version 2
// Vesrion 3 = for Partition boot
// Vesrion 4 = for eb riscv boot
//
NvU32 version; // structure version
NvU32 bootloaderOffset;
NvU32 bootloaderSize;
NvU32 bootloaderParamOffset;
NvU32 bootloaderParamSize;
NvU32 riscvElfOffset;
NvU32 riscvElfSize;
NvU32 appVersion; // Changelist number associated with the image
//
// Manifest contains information about Monitor and it is
// input to BR
//
NvU32 manifestOffset;
NvU32 manifestSize;
//
// Monitor Data offset within RISCV image and size
//
NvU32 monitorDataOffset;
NvU32 monitorDataSize;
//
// Monitor Code offset withtin RISCV image and size
//
NvU32 monitorCodeOffset;
NvU32 monitorCodeSize;
NvU32 bIsMonitorEnabled;
//
// Swbrom Code offset within RISCV image and size
//
NvU32 swbromCodeOffset;
NvU32 swbromCodeSize;
//
// Swbrom Data offset within RISCV image and size
//
NvU32 swbromDataOffset;
NvU32 swbromDataSize;
} RISCV_UCODE_HDR_INFO_LS10, *PRISCV_UCODE_HDR_INFO_LS10;
//
// HAL functions shared by LR10 and used by LS10
//
#define nvswitch_is_link_valid_ls10 nvswitch_is_link_valid_lr10
#define nvswitch_is_link_in_use_ls10 nvswitch_is_link_in_use_lr10
#define nvswitch_initialize_device_state_ls10 nvswitch_initialize_device_state_lr10
#define nvswitch_deassert_link_reset_ls10 nvswitch_deassert_link_reset_lr10
#define nvswitch_determine_platform_ls10 nvswitch_determine_platform_lr10
#define nvswitch_get_swap_clk_default_ls10 nvswitch_get_swap_clk_default_lr10
#define nvswitch_post_init_device_setup_ls10 nvswitch_post_init_device_setup_lr10
#define nvswitch_set_training_error_info_ls10 nvswitch_set_training_error_info_lr10
#define nvswitch_init_scratch_ls10 nvswitch_init_scratch_lr10
#define nvswitch_hw_counter_shutdown_ls10 nvswitch_hw_counter_shutdown_lr10
#define nvswitch_hw_counter_read_counter_ls10 nvswitch_hw_counter_read_counter_lr10
#define nvswitch_ecc_writeback_task_ls10 nvswitch_ecc_writeback_task_lr10
#define nvswitch_ctrl_get_routing_id_ls10 nvswitch_ctrl_get_routing_id_lr10
#define nvswitch_ctrl_set_routing_id_valid_ls10 nvswitch_ctrl_set_routing_id_valid_lr10
#define nvswitch_ctrl_set_routing_id_ls10 nvswitch_ctrl_set_routing_id_lr10
#define nvswitch_ctrl_set_routing_lan_ls10 nvswitch_ctrl_set_routing_lan_lr10
#define nvswitch_ctrl_get_routing_lan_ls10 nvswitch_ctrl_get_routing_lan_lr10
#define nvswitch_ctrl_set_routing_lan_valid_ls10 nvswitch_ctrl_set_routing_lan_valid_lr10
#define nvswitch_ctrl_set_ingress_request_table_ls10 nvswitch_ctrl_set_ingress_request_table_lr10
#define nvswitch_ctrl_get_ingress_request_table_ls10 nvswitch_ctrl_get_ingress_request_table_lr10
#define nvswitch_ctrl_set_ingress_request_valid_ls10 nvswitch_ctrl_set_ingress_request_valid_lr10
#define nvswitch_ctrl_get_ingress_response_table_ls10 nvswitch_ctrl_get_ingress_response_table_lr10
#define nvswitch_ctrl_set_ingress_response_table_ls10 nvswitch_ctrl_set_ingress_response_table_lr10
#define nvswitch_ctrl_get_info_ls10 nvswitch_ctrl_get_info_lr10
#define nvswitch_ctrl_set_switch_port_config_ls10 nvswitch_ctrl_set_switch_port_config_lr10
#define nvswitch_ctrl_get_fom_values_ls10 nvswitch_ctrl_get_fom_values_lr10
#define nvswitch_ctrl_get_throughput_counters_ls10 nvswitch_ctrl_get_throughput_counters_lr10
#define nvswitch_save_nvlink_seed_data_from_minion_to_inforom_ls10 nvswitch_save_nvlink_seed_data_from_minion_to_inforom_lr10
#define nvswitch_store_seed_data_from_inforom_to_corelib_ls10 nvswitch_store_seed_data_from_inforom_to_corelib_lr10
#define nvswitch_corelib_clear_link_state_ls10 nvswitch_corelib_clear_link_state_lr10
#define nvswitch_read_oob_blacklist_state_ls10 nvswitch_read_oob_blacklist_state_lr10
#define nvswitch_corelib_add_link_ls10 nvswitch_corelib_add_link_lr10
#define nvswitch_corelib_remove_link_ls10 nvswitch_corelib_remove_link_lr10
#define nvswitch_corelib_set_tl_link_mode_ls10 nvswitch_corelib_set_tl_link_mode_lr10
#define nvswitch_corelib_set_rx_mode_ls10 nvswitch_corelib_set_rx_mode_lr10
#define nvswitch_corelib_set_rx_detect_ls10 nvswitch_corelib_set_rx_detect_lr10
#define nvswitch_corelib_write_discovery_token_ls10 nvswitch_corelib_write_discovery_token_lr10
#define nvswitch_corelib_read_discovery_token_ls10 nvswitch_corelib_read_discovery_token_lr10
#define nvswitch_inforom_nvl_get_minion_data_ls10 nvswitch_inforom_nvl_get_minion_data_lr10
#define nvswitch_inforom_nvl_set_minion_data_ls10 nvswitch_inforom_nvl_set_minion_data_lr10
#define nvswitch_inforom_nvl_get_max_correctable_error_rate_ls10 nvswitch_inforom_nvl_get_max_correctable_error_rate_lr10
#define nvswitch_inforom_nvl_get_errors_ls10 nvswitch_inforom_nvl_get_errors_lr10
#define nvswitch_inforom_ecc_log_error_event_ls10 nvswitch_inforom_ecc_log_error_event_lr10
#define nvswitch_inforom_ecc_get_errors_ls10 nvswitch_inforom_ecc_get_errors_lr10
#define nvswitch_inforom_bbx_get_sxid_ls10 nvswitch_inforom_bbx_get_sxid_lr10
#define nvswitch_vbios_read_structure_ls10 nvswitch_vbios_read_structure_lr10
#define nvswitch_setup_system_registers_ls10 nvswitch_setup_system_registers_lr10
#define nvswitch_minion_get_initoptimize_status_ls10 nvswitch_minion_get_initoptimize_status_lr10
#define nvswitch_poll_sublink_state_ls10 nvswitch_poll_sublink_state_lr10
#define nvswitch_setup_link_loopback_mode_ls10 nvswitch_setup_link_loopback_mode_lr10
#define nvswitch_link_lane_reversed_ls10 nvswitch_link_lane_reversed_lr10
#define nvswitch_request_tl_link_state_ls10 nvswitch_request_tl_link_state_lr10
#define nvswitch_i2c_get_port_info_ls10 nvswitch_i2c_get_port_info_lr10
#define nvswitch_i2c_set_hw_speed_mode_ls10 nvswitch_i2c_set_hw_speed_mode_lr10
#define nvswitch_ctrl_get_err_info_ls10 nvswitch_ctrl_get_err_info_lr10
NvlStatus nvswitch_ctrl_get_err_info_lr10(nvswitch_device *device, NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret);
NvBool nvswitch_is_link_valid_lr10(nvswitch_device *device, NvU32 link_id);
NvBool nvswitch_is_link_in_use_lr10(nvswitch_device *device, NvU32 link_id);
NvlStatus nvswitch_initialize_device_state_lr10(nvswitch_device *device);
NvlStatus nvswitch_deassert_link_reset_lr10(nvswitch_device *device, nvlink_link *link);
void nvswitch_determine_platform_lr10(nvswitch_device *device);
NvU32 nvswitch_get_swap_clk_default_lr10(nvswitch_device *device);
NvlStatus nvswitch_post_init_device_setup_lr10(nvswitch_device *device);
NvlStatus nvswitch_set_training_error_info_lr10(nvswitch_device *device, NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS *pLinkTrainingErrorInfoParams);
void nvswitch_init_scratch_lr10(nvswitch_device *device);
void nvswitch_hw_counter_shutdown_lr10(nvswitch_device *device);
NvU64 nvswitch_hw_counter_read_counter_lr10(nvswitch_device *device);
void nvswitch_ecc_writeback_task_lr10(nvswitch_device *device);
NvlStatus nvswitch_ctrl_get_routing_id_lr10(nvswitch_device *device, NVSWITCH_GET_ROUTING_ID_PARAMS *params);
NvlStatus nvswitch_ctrl_set_routing_id_valid_lr10(nvswitch_device *device, NVSWITCH_SET_ROUTING_ID_VALID *p);
NvlStatus nvswitch_ctrl_set_routing_id_lr10(nvswitch_device *device, NVSWITCH_SET_ROUTING_ID *p);
NvlStatus nvswitch_ctrl_set_routing_lan_lr10(nvswitch_device *device, NVSWITCH_SET_ROUTING_LAN *p);
NvlStatus nvswitch_ctrl_get_routing_lan_lr10(nvswitch_device *device, NVSWITCH_GET_ROUTING_LAN_PARAMS *params);
NvlStatus nvswitch_ctrl_set_routing_lan_valid_lr10(nvswitch_device *device, NVSWITCH_SET_ROUTING_LAN_VALID *p);
NvlStatus nvswitch_ctrl_set_ingress_request_table_lr10(nvswitch_device *device, NVSWITCH_SET_INGRESS_REQUEST_TABLE *p);
NvlStatus nvswitch_ctrl_get_ingress_request_table_lr10(nvswitch_device *device, NVSWITCH_GET_INGRESS_REQUEST_TABLE_PARAMS *params);
NvlStatus nvswitch_ctrl_set_ingress_request_valid_lr10(nvswitch_device *device, NVSWITCH_SET_INGRESS_REQUEST_VALID *p);
NvlStatus nvswitch_ctrl_get_ingress_response_table_lr10(nvswitch_device *device, NVSWITCH_GET_INGRESS_RESPONSE_TABLE_PARAMS *params);
NvlStatus nvswitch_ctrl_set_ingress_response_table_lr10(nvswitch_device *device, NVSWITCH_SET_INGRESS_RESPONSE_TABLE *p);
NvlStatus nvswitch_ctrl_get_nvlink_status_lr10(nvswitch_device *device, NVSWITCH_GET_NVLINK_STATUS_PARAMS *ret);
NvlStatus nvswitch_ctrl_get_nvlink_status_ls10(nvswitch_device *device, NVSWITCH_GET_NVLINK_STATUS_PARAMS *ret);
NvlStatus nvswitch_ctrl_get_info_lr10(nvswitch_device *device, NVSWITCH_GET_INFO *p);
NvlStatus nvswitch_ctrl_set_switch_port_config_lr10(nvswitch_device *device, NVSWITCH_SET_SWITCH_PORT_CONFIG *p);
NvlStatus nvswitch_ctrl_get_fom_values_lr10(nvswitch_device *device, NVSWITCH_GET_FOM_VALUES_PARAMS *p);
NvlStatus nvswitch_ctrl_get_throughput_counters_lr10(nvswitch_device *device, NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS *p);
void nvswitch_save_nvlink_seed_data_from_minion_to_inforom_lr10(nvswitch_device *device, NvU32 linkId);
void nvswitch_store_seed_data_from_inforom_to_corelib_lr10(nvswitch_device *device);
NvlStatus nvswitch_read_oob_blacklist_state_lr10(nvswitch_device *device);
NvlStatus nvswitch_corelib_add_link_lr10(nvlink_link *link);
NvlStatus nvswitch_corelib_remove_link_lr10(nvlink_link *link);
NvlStatus nvswitch_corelib_get_dl_link_mode_lr10(nvlink_link *link, NvU64 *mode);
NvlStatus nvswitch_corelib_set_tl_link_mode_lr10(nvlink_link *link, NvU64 mode, NvU32 flags);
NvlStatus nvswitch_corelib_get_tx_mode_lr10(nvlink_link *link, NvU64 *mode, NvU32 *subMode);
NvlStatus nvswitch_corelib_set_rx_mode_lr10(nvlink_link *link, NvU64 mode, NvU32 flags);
NvlStatus nvswitch_corelib_get_rx_mode_lr10(nvlink_link *link, NvU64 *mode, NvU32 *subMode);
NvlStatus nvswitch_corelib_set_rx_detect_lr10(nvlink_link *link, NvU32 flags);
NvlStatus nvswitch_corelib_write_discovery_token_lr10(nvlink_link *link, NvU64 token);
NvlStatus nvswitch_corelib_read_discovery_token_lr10(nvlink_link *link, NvU64 *token);
NvlStatus nvswitch_corelib_set_dl_link_mode_lr10(nvlink_link *link, NvU64 mode, NvU32 flags);
NvlStatus nvswitch_corelib_set_tx_mode_lr10(nvlink_link *link, NvU64 mode, NvU32 flags);
NvlStatus nvswitch_corelib_get_tl_link_mode_lr10(nvlink_link *link, NvU64 *mode);
void nvswitch_init_buffer_ready_lr10(nvswitch_device *device, nvlink_link *link, NvBool bNportBufferReady);
NvlStatus nvswitch_inforom_nvl_get_minion_data_lr10(nvswitch_device *device, void *pNvlGeneric, NvU8 linkId, NvU32 *seedData);
NvlStatus nvswitch_inforom_nvl_set_minion_data_lr10(nvswitch_device *device, void *pNvlGeneric, NvU8 linkId, NvU32 *seedData, NvU32 size, NvBool *bDirty);
NvlStatus nvswitch_inforom_nvl_get_max_correctable_error_rate_lr10(nvswitch_device *device, NVSWITCH_GET_NVLINK_MAX_CORRECTABLE_ERROR_RATES_PARAMS *params);
NvlStatus nvswitch_inforom_nvl_get_errors_lr10(nvswitch_device *device, NVSWITCH_GET_NVLINK_ERROR_COUNTS_PARAMS *params);
NvlStatus nvswitch_inforom_ecc_log_error_event_lr10(nvswitch_device *device, INFOROM_ECC_OBJECT *pEccGeneric, INFOROM_NVS_ECC_ERROR_EVENT *err_event);
NvlStatus nvswitch_inforom_ecc_get_errors_lr10(nvswitch_device *device, NVSWITCH_GET_ECC_ERROR_COUNTS_PARAMS *params);
NvlStatus nvswitch_inforom_bbx_get_sxid_lr10(nvswitch_device *device, NVSWITCH_GET_SXIDS_PARAMS *params);
void nvswitch_init_dlpl_interrupts_lr10(nvlink_link *link);
NvlStatus nvswitch_vbios_read_structure_lr10(nvswitch_device *device, void *structure, NvU32 offset, NvU32 *ppacked_size, const char *format);
NvlStatus nvswitch_setup_system_registers_lr10(nvswitch_device *device);
NvlStatus nvswitch_minion_get_initoptimize_status_lr10(nvswitch_device *device, NvU32 linkId);
NvlStatus nvswitch_poll_sublink_state_lr10(nvswitch_device *device, nvlink_link *link);
void nvswitch_setup_link_loopback_mode_lr10(nvswitch_device *device, NvU32 linkNumber);
NvBool nvswitch_link_lane_reversed_lr10(nvswitch_device *device, NvU32 linkId);
void nvswitch_store_topology_information_lr10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_request_tl_link_state_lr10(nvlink_link *link, NvU32 tlLinkState, NvBool bSync);
NvlStatus nvswitch_wait_for_tl_request_ready_lr10(nvlink_link *link);
NvlStatus nvswitch_parse_bios_image_lr10(nvswitch_device *device);
NvU32 nvswitch_i2c_get_port_info_lr10(nvswitch_device *device, NvU32 port);
void nvswitch_i2c_set_hw_speed_mode_lr10(nvswitch_device *device, NvU32 port, NvU32 speedMode);
NvlStatus nvswitch_ctrl_i2c_indexed_lr10(nvswitch_device *device, NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams);
void nvswitch_corelib_clear_link_state_lr10(nvlink_link *link);
//
// Internal function declarations
//
NvlStatus nvswitch_corelib_set_dl_link_mode_ls10(nvlink_link *link, NvU64 mode, NvU32 flags);
NvlStatus nvswitch_corelib_set_tx_mode_ls10(nvlink_link *link, NvU64 mode, NvU32 flags);
void nvswitch_init_lpwr_regs_ls10(nvlink_link *link);
NvlStatus nvswitch_minion_service_falcon_interrupts_ls10(nvswitch_device *device, NvU32 instance);
NvlStatus nvswitch_device_discovery_ls10(nvswitch_device *device, NvU32 discovery_offset);
void nvswitch_filter_discovery_ls10(nvswitch_device *device);
NvlStatus nvswitch_process_discovery_ls10(nvswitch_device *device);
void nvswitch_lib_enable_interrupts_ls10(nvswitch_device *device);
void nvswitch_lib_disable_interrupts_ls10(nvswitch_device *device);
NvlStatus nvswitch_lib_service_interrupts_ls10(nvswitch_device *device);
NvlStatus nvswitch_lib_check_interrupts_ls10(nvswitch_device *device);
void nvswitch_initialize_interrupt_tree_ls10(nvswitch_device *device);
void nvswitch_corelib_training_complete_ls10(nvlink_link *link);
NvlStatus nvswitch_init_nport_ls10(nvswitch_device *device);
NvlStatus nvswitch_corelib_get_rx_detect_ls10(nvlink_link *link);
void nvswitch_reset_persistent_link_hw_state_ls10(nvswitch_device *device, NvU32 linkNumber);
NvlStatus nvswitch_minion_get_rxdet_status_ls10(nvswitch_device *device, NvU32 linkId);
NvlStatus nvswitch_minion_restore_seed_data_ls10(nvswitch_device *device, NvU32 linkId, NvU32 *seedData);
NvlStatus nvswitch_minion_set_sim_mode_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_minion_set_smf_settings_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_minion_select_uphy_tables_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_set_training_mode_ls10(nvswitch_device *device);
NvlStatus nvswitch_corelib_get_tl_link_mode_ls10(nvlink_link *link, NvU64 *mode);
NvU32 nvswitch_get_sublink_width_ls10(nvswitch_device *device,NvU32 linkNumber);
NvlStatus nvswitch_parse_bios_image_ls10(nvswitch_device *device);
NvBool nvswitch_is_link_in_reset_ls10(nvswitch_device *device, nvlink_link *link);
void nvswitch_corelib_get_uphy_load_ls10(nvlink_link *link, NvBool *bUnlocked);
NvlStatus nvswitch_ctrl_get_nvlink_lp_counters_ls10(nvswitch_device *device, NVSWITCH_GET_NVLINK_LP_COUNTERS_PARAMS *params);
void nvswitch_init_buffer_ready_ls10(nvswitch_device *device, nvlink_link *link, NvBool bNportBufferReady);
void nvswitch_apply_recal_settings_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_corelib_get_dl_link_mode_ls10(nvlink_link *link, NvU64 *mode);
NvlStatus nvswitch_corelib_get_tx_mode_ls10(nvlink_link *link, NvU64 *mode, NvU32 *subMode);
NvlStatus nvswitch_corelib_get_rx_mode_ls10(nvlink_link *link, NvU64 *mode, NvU32 *subMode);
NvlStatus nvswitch_ctrl_get_sw_info_ls10(nvswitch_device *device, NVSWITCH_GET_SW_INFO_PARAMS *p);
NvlStatus nvswitch_launch_ALI_link_training_ls10(nvswitch_device *device, nvlink_link *link, NvBool bSync);
NvlStatus nvswitch_service_nvldl_fatal_link_ls10(nvswitch_device *device, NvU32 nvliptInstance, NvU32 link);
NvlStatus nvswitch_ctrl_inband_send_data_ls10(nvswitch_device *device, NVSWITCH_INBAND_SEND_DATA_PARAMS *p);
NvlStatus nvswitch_ctrl_inband_read_data_ls10(nvswitch_device *device, NVSWITCH_INBAND_READ_DATA_PARAMS *p);
void nvswitch_send_inband_nack_ls10(nvswitch_device *device, NvU32 *msghdr, NvU32 linkId);
NvU32 nvswitch_get_max_persistent_message_count_ls10(nvswitch_device *device);
NvlStatus nvswitch_service_minion_link_ls10(nvswitch_device *device, NvU32 nvliptInstance);
void nvswitch_apply_recal_settings_ls10(nvswitch_device *device, nvlink_link *link);
void nvswitch_store_topology_information_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_ctrl_i2c_indexed_ls10(nvswitch_device *device, NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams);
NvBool nvswitch_i2c_is_device_access_allowed_ls10(nvswitch_device *device, NvU32 port, NvU8 addr, NvBool bIsRead);
NvlStatus nvswitch_minion_get_ali_debug_registers_ls10(nvswitch_device *device, nvlink_link *link, NVSWITCH_MINION_ALI_DEBUG_REGISTERS *params);
void nvswitch_setup_link_system_registers_ls10(nvswitch_device *device, nvlink_link *link);
void nvswitch_load_link_disable_settings_ls10(nvswitch_device *device, nvlink_link *link);
void nvswitch_execute_unilateral_link_shutdown_ls10(nvlink_link *link);
void nvswitch_init_dlpl_interrupts_ls10(nvlink_link *link);
NvlStatus nvswitch_reset_and_drain_links_ls10(nvswitch_device *device, NvU64 link_mask);
void nvswitch_service_minion_all_links_ls10(nvswitch_device *device);
//
// SU generated functions
//
NvlStatus nvswitch_nvs_top_prod_ls10(nvswitch_device *device);
NvlStatus nvswitch_apply_prod_nvlw_ls10(nvswitch_device *device);
NvlStatus nvswitch_apply_prod_nxbar_ls10(nvswitch_device *device);
NvlStatus nvswitch_launch_ALI_ls10(nvswitch_device *device);
NvlStatus nvswitch_ctrl_set_mc_rid_table_ls10(nvswitch_device *device, NVSWITCH_SET_MC_RID_TABLE_PARAMS *p);
NvlStatus nvswitch_ctrl_get_mc_rid_table_ls10(nvswitch_device *device, NVSWITCH_GET_MC_RID_TABLE_PARAMS *p);
void nvswitch_init_dlpl_interrupts_ls10(nvlink_link *link);
NvlStatus nvswitch_reset_and_drain_links_ls10(nvswitch_device *device, NvU64 link_mask);
void nvswitch_service_minion_all_links_ls10(nvswitch_device *device);
NvBool nvswitch_is_inforom_supported_ls10(nvswitch_device *device);
#endif //_LS10_H_

View File

@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _MINION_LS10_H_
#define _MINION_LS10_H_
#include "ls10.h"
#include "nvlink_inband_drv_header.h"
#define FALCON_IMEM_BLK_SIZE_BYTES_LS10 256
#define FALCON_CODE_HDR_OS_CODE_OFFSET_LS10 0
#define FALCON_CODE_HDR_OS_CODE_SIZE_LS10 1
#define FALCON_CODE_HDR_OS_DATA_OFFSET_LS10 2
#define FALCON_CODE_HDR_OS_DATA_SIZE_LS10 3
#define FALCON_CODE_HDR_NUM_APPS_LS10 4
#define FALCON_CODE_HDR_APP_CODE_START_LS10 5
#define FALCON_CODE_HDR_APP_DATA_START_LS10 ( FALCON_CODE_HDR_APP_CODE_START_LS10 + (FALCON_CODE_HDR_NUM_APPS_LS10 * 2))
#define FALCON_CODE_HDR_CODE_OFFSET_LS10 0
#define FALCON_CODE_HDR_CODE_SIZE_LS10 1
#define FALCON_CODE_HDR_DATA_OFFSET_LS10 0
#define FALCON_CODE_HDR_DATA_SIZE_LS10 1
#define NV_MINION_NVLINK_DL_STAT_ARGS_LANEID 15:12
#define NV_MINION_NVLINK_DL_STAT_ARGS_ADDRS 11:0
//
// Inband data structure
//
typedef struct inband_send_data
{
// Inband buffer at sender Minion
NvU8 *sendBuffer;
// Number of bytes of data to be sent
NvU32 bufferSize;
// Header
nvlink_inband_drv_hdr_t hdr;
} nvswitch_inband_send_data;
//
// Internal function declarations
//
NvlStatus nvswitch_minion_get_dl_status_ls10(nvswitch_device *device, NvU32 linkId, NvU32 statusIdx, NvU32 statusArgs, NvU32 *statusData);
NvlStatus nvswitch_set_minion_initialized_ls10(nvswitch_device *device, NvU32 idx_minion, NvBool initialized);
NvBool nvswitch_is_minion_initialized_ls10(nvswitch_device *device, NvU32 idx_minion);
NvlStatus nvswitch_init_minion_ls10(nvswitch_device *device);
NvlStatus nvswitch_minion_send_command_ls10(nvswitch_device *device, NvU32 linkNumber, NvU32 command, NvU32 scratch0);
NvlStatus nvswitch_minion_riscv_get_physical_address_ls10(nvswitch_device *device,NvU32 idx_minion, NvU32 target, NvLength offset, NvU64 *pRiscvPa);
NvlStatus nvswitch_minion_set_sim_mode_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_minion_set_smf_settings_ls10(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_minion_select_uphy_tables_ls10(nvswitch_device *device, nvlink_link *link);
NvBool nvswitch_minion_is_riscv_active_ls10(nvswitch_device *device, NvU32 idx_minion);
NvlStatus nvswitch_minion_clear_dl_error_counters_ls10(nvswitch_device *device, NvU32 linkId);
NvlStatus nvswitch_minion_send_inband_data_ls10(nvswitch_device *device, NvU32 linkId, nvswitch_inband_send_data *inBandData);
void nvswitch_minion_receive_inband_data_ls10(nvswitch_device *device, NvU32 linkId);
NvlStatus nvswitch_minion_log_ali_debug_registers_ls10(nvswitch_device *device, nvlink_link *link);
#endif //_MINION_LS10_H_

View File

@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _MINION_NVLINK_DEFINES_PUBLIC_H_
#define _MINION_NVLINK_DEFINES_PUBLIC_H_
// SUBCODES for DLCMD FAULT (uses DLCMDFAULR code) - dlCmdFault() - NVLINK_LINK_INT
typedef enum _MINION_STATUS
{
MINION_OK = 0,
MINION_ALARM_BUSY = 80,
} MINION_STATUS;
#endif // _MINION_NVLINK_DEFINES_PUBLIC_H_

View File

@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _MULTICAST_LS10_H_
#define _MULTICAST_LS10_H_
#define NVSWITCH_MC_TCP_LIST_SIZE_LS10 NVSWITCH_NUM_LINKS_LS10 / 2
#define NVSWITCH_MC_MAX_SPRAY_LS10 16
#define NVSWITCH_MC_NUM_COLUMNS_LS10 6
#define NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10 NVSWITCH_MC_NUM_COLUMNS_LS10 / 2
#define NVSWITCH_MC_PORTS_PER_COLUMN_LS10 11
#define NVSWITCH_MC_MIN_PORTS_PER_GROUP_LS10 1
#define PRIMARY_REPLICA_NONE 0
#define PRIMARY_REPLICA_EVEN 1
#define PRIMARY_REPLICA_ODD 2
#define NVSWITCH_MC_INVALID 0xFF
#define NVSWITCH_MC_NULL_PORT_LS10 0xF
//
// Debug and trace print toggles
// To enable tracing, define NVSWITCH_MC_TRACE
//
#if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS)
#define NVSWITCH_MC_DEBUG 1
#endif
typedef struct {
NvU32 column;
NvU32 port_offset;
} NVSWITCH_COLUMN_PORT_OFFSET_LS10;
typedef struct {
NvU8 tcp; // Tile column pair
NvU8 tcpEPort; // Port index within even column
NvU8 tcpEVCHop; // VC selection
NvU8 tcpOPort; // Port index within odd column
NvU8 tcpOVCHop; // VC selection
NvU8 roundSize; // This is no longer part of the hardware structure. We retain it here
// because it is useful in various loops
NvU8 primaryReplica;// This field is not in hardware. This code uses it to
// track which port should be primary, so that it can make a pass over
// the assembled tcp directive list and adjust portFlag and
// continueRound as needed to indicate primary replica
// valid values are:
// PRIMARY_REPLICA_NONE (0b00): no primary replica in tcp
// PRIMARY_REPLICA_EVEN (0b01): even (0) port is primary replica
// PRIMARY_REPLICA_ODD (0b10): odd (1) port is primary replica
NvBool tcpEAltPath :1;// Alternative to select from odd column
NvBool tcpOAltPath :1;// Alternative to select from even column
NvBool lastRound :1;// last TCP directive of the last round in this multicast string
// could be multiple strings in case of spray
NvBool continueRound:1;// dual meaning:
// 1) if lastRound = 1 and continueRound = 1, primary replica is in
// this TCP directive and portFlag = 0/1 selects even/odd port
// 2) if lastRound = 0 there are more TCP directives for this round.
NvBool portFlag :1;// triple meaning:
// 1) if lastRound = 1 and continueRound = 1, primary replica is in
// this TCP directive and portFlag = 0/1 selects even/odd port
// 2) If the previous TCP directive was not used to select the even/odd
// port of its predecessor, and if portFlag of the previous TCP
// directive = 1, portFlag of this TCP directive = 0/1 selects
// the even/odd port of its predecessor
// 3) if the previous TCP directive's portFlag = 0, and if it was not
// used to select the even or odd port of its predecessor, this TCP
// directive's portFlag == 1, this TCP directive contains the
// primary replica, and the next TCP directive's portFlag = 0/1
// selects the even/odd port of this TCP directive
} NVSWITCH_TCP_DIRECTIVE_LS10;
typedef struct {
NvU8 index;
NvBool use_extended_table;
NvU8 mcpl_size;
NvU8 num_spray_groups;
NvU8 ext_ptr;
NvBool no_dyn_rsp;
NvBool ext_ptr_valid;
NvBool valid;
NVSWITCH_TCP_DIRECTIVE_LS10 directives[NVSWITCH_MC_TCP_LIST_SIZE_LS10];
NvU8 spray_group_ptrs[NVSWITCH_MC_MAX_SPRAY_LS10];
} NVSWITCH_MC_RID_ENTRY_LS10;
NvlStatus nvswitch_mc_build_mcp_list_ls10(nvswitch_device *device, NvU32 *port_list,
NvU32 *ports_per_spray_string,
NvU32 *pri_replica_offsets, NvBool *replica_valid_array,
NvU8 *vchop_array,
NVSWITCH_MC_RID_ENTRY_LS10 *table_entry,
NvU32 *entries_used);
NvlStatus nvswitch_mc_unwind_directives_ls10(nvswitch_device *device,
NVSWITCH_TCP_DIRECTIVE_LS10* directives,
NvU32 *ports, NvU8 *vc_hop,
NvU32 *ports_per_spray_group, NvU32 *replica_offset,
NvBool *replica_valid);
NvlStatus nvswitch_mc_invalidate_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port, NvU32 index,
NvBool use_extended_table, NvBool zero);
NvlStatus nvswitch_mc_program_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port,
NVSWITCH_MC_RID_ENTRY_LS10 *table_entry,
NvU32 directive_list_size);
NvlStatus nvswitch_mc_read_mc_rid_entry_ls10(nvswitch_device *device, NvU32 port,
NVSWITCH_MC_RID_ENTRY_LS10 *table_entry);
#endif //_MULTICAST_LS10_H_

View File

@@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _PMGR_LS10_H_
#define _PMGR_LS10_H_
#include "ls10.h"
void
nvswitch_init_pmgr_ls10
(
nvswitch_device *device
);
void
nvswitch_init_pmgr_devices_ls10
(
nvswitch_device *device
);
NvU32
nvswitch_read_physical_id_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_get_rom_info_ls10
(
nvswitch_device *device,
NVSWITCH_EEPROM_TYPE *eeprom
);
void
nvswitch_i2c_set_hw_speed_mode_ls10
(
nvswitch_device *device,
NvU32 port,
NvU32 speedMode
);
NvBool
nvswitch_is_i2c_supported_ls10
(
nvswitch_device *device
);
#endif //_PMGR_LS10_H_

View File

@@ -0,0 +1,91 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SMBPBI_LS10_H_
#define _SMBPBI_LS10_H_
NvlStatus
nvswitch_smbpbi_alloc_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_post_init_hal_ls10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_destroy_hal_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_get_dem_num_messages_ls10
(
nvswitch_device *device,
NvU8 *pMsgCount
);
NvlStatus
nvswitch_inforom_dem_load_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_smbpbi_dem_load_ls10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_send_unload_ls10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_dem_flush_ls10
(
nvswitch_device *device
);
void
nvswitch_smbpbi_log_message_ls10
(
nvswitch_device *device,
NvU32 num,
NvU32 msglen,
NvU8 *osErrorString
);
NvlStatus
nvswitch_smbpbi_send_init_data_ls10
(
nvswitch_device *device
);
#endif //_SMBPBI_LS10_H_

View File

@@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SOE_LS10_H_
#define _SOE_LS10_H_
#include "ls10.h"
//
// Functions shared with LR10
//
#include "rmflcncmdif_nvswitch.h"
NvlStatus nvswitch_init_soe_ls10(nvswitch_device *device);
NvlStatus nvswitch_unload_soe_ls10(nvswitch_device *device);
NvlStatus nvswitch_soe_register_event_callbacks_ls10(nvswitch_device *device);
void nvswitch_cci_soe_callback_ls10(nvswitch_device *device, RM_FLCN_MSG *pGenMsg,
void *pParams, NvU32 seqDesc, NV_STATUS status);
NvlStatus nvswitch_set_nport_tprod_state_ls10(nvswitch_device *device, NvU32 nport);
void nvswitch_soe_unregister_events_ls10(nvswitch_device *device);
NvlStatus nvswitch_soe_register_event_callbacks_ls10(nvswitch_device *device);
NvlStatus nvswitch_soe_restore_nport_state_ls10(nvswitch_device *device, NvU32 nport);
NvlStatus nvswitch_soe_issue_nport_reset_ls10(nvswitch_device *device, NvU32 nport);
#endif //_SOE_LS10_H_

View File

@@ -0,0 +1,77 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _SUGEN_LS10_H_
#define _SUGEN_LS10_H_
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "nvswitch/ls10/dev_nvs_top.h"
#include "nvswitch/ls10/dev_pri_masterstation_ip.h"
#include "nvswitch/ls10/dev_pri_ringstation_sys_ip.h"
#include "nvswitch/ls10/dev_pri_ringstation_sysb_ip.h"
#include "nvswitch/ls10/dev_pri_ringstation_prt_ip.h"
#include "nvswitch/ls10/dev_pri_hub_sys_ip.h"
#include "nvswitch/ls10/dev_pri_hub_sysb_ip.h"
#include "nvswitch/ls10/dev_pri_hub_prt_ip.h"
#include "nvswitch/ls10/dev_nvlsaw_ip.h"
#include "nvswitch/ls10/dev_ctrl_ip.h"
#include "nvswitch/ls10/dev_timer_ip.h"
#include "nvswitch/ls10/dev_trim.h"
#include "nvswitch/ls10/dev_nv_xal_ep.h"
#include "nvswitch/ls10/dev_nv_xpl.h"
#include "nvswitch/ls10/dev_xtl_ep_pri.h"
#include "nvswitch/ls10/dev_soe_ip.h"
#include "nvswitch/ls10/dev_se_pri.h"
#include "nvswitch/ls10/dev_perf.h"
#include "nvswitch/ls10/dev_pmgr.h"
#include "nvswitch/ls10/dev_therm.h"
// NVLW
#include "nvswitch/ls10/dev_nvlw_ip.h"
#include "nvswitch/ls10/dev_cpr_ip.h"
#include "nvswitch/ls10/dev_nvlipt_ip.h"
#include "nvswitch/ls10/dev_nvlipt_lnk_ip.h"
#include "nvswitch/ls10/dev_nvltlc_ip.h"
#include "nvswitch/ls10/dev_nvldl_ip.h"
#include "nvswitch/ls10/dev_minion_ip.h"
// NPG/NPORT
#include "nvswitch/ls10/dev_npg_ip.h"
#include "nvswitch/ls10/dev_npgperf_ip.h"
#include "nvswitch/ls10/dev_nport_ip.h"
#include "nvswitch/ls10/dev_route_ip.h"
#include "nvswitch/ls10/dev_tstate_ip.h"
#include "nvswitch/ls10/dev_egress_ip.h"
#include "nvswitch/ls10/dev_ingress_ip.h"
#include "nvswitch/ls10/dev_sourcetrack_ip.h"
#include "nvswitch/ls10/dev_multicasttstate_ip.h"
#include "nvswitch/ls10/dev_reductiontstate_ip.h"
// NXBAR
#include "nvswitch/ls10/dev_nxbar_tile_ip.h"
#include "nvswitch/ls10/dev_nxbar_tileout_ip.h"
#endif //_SUGEN_LS10_H_

View File

@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the Software),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _THERM_LS10_H_
#define _THERM_LS10_H_
NvlStatus
nvswitch_init_thermal_ls10
(
nvswitch_device *device
);
NvlStatus
nvswitch_ctrl_therm_read_temperature_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info
);
NvlStatus
nvswitch_ctrl_therm_get_temperature_limit_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS *info
);
void
nvswitch_monitor_thermal_alert_ls10
(
nvswitch_device *device
);
#endif //_THERM_LS10_H_

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -301,6 +301,12 @@ struct NVSWITCH_OBJI2C
// I2C device allow list
NVSWITCH_I2C_DEVICE_DESCRIPTOR_TYPE *i2c_allow_list;
NvU32 i2c_allow_list_size;
// For I2C via SOE support
NvBool soeI2CSupported;
NvBool kernelI2CSupported;
void *pCpuAddr;
NvU64 dmaHandle;
};
//

View File

@@ -323,6 +323,8 @@
#define NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_40G 0x0F
#define NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_50G 0x10
#define NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_53_12500G 0x11
#define NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_100_00000G 0x12
#define NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_106_25000G 0x13
/*
* Enable/Disable periodic flush to inforom. Default is disabled.
@@ -516,13 +518,23 @@
#define NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_ENABLE 0x1
#define NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_DISABLE 0x0
/*
* NV_SWITCH_REGKEY_FORCE_KERNEL_I2C - Used to force Kernel I2C path
*
* Private: Debug use only
*/
#define NV_SWITCH_REGKEY_FORCE_KERNEL_I2C "ForceKernelI2c"
#define NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DEFAULT 0x0
#define NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_ENABLE 0x1
#define NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DISABLE 0x0
/*
* NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT - Configure the CRC bit error rate for the short interrupt
*
* Public: Available in release drivers
*/
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT "CRCBitErrorRateShort"
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_OFF 0x0
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT 0x0
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN 2:0
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP 3:3
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_TIMESCALE_MAN 6:4
@@ -534,7 +546,7 @@
* Public: Available in release drivers
*/
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG "CRCBitErrorRateLong"
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_OFF 0x000
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT 0x000
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_BUG_3365481_CASE_1 0x803
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_BUG_3365481_CASE_2 0x703
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_BUG_3365481_CASE_5 0x34D
@@ -544,4 +556,37 @@
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_TIMESCALE_MAN 6:4
#define NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_TIMESCALE_EXP 12:8
/*
* NV_SWITCH_REGKEY_SET_LP_THRESHOLD - Sets the LP Threshold Value
*
* Private: Debug use only
*/
#define NV_SWITCH_REGKEY_SET_LP_THRESHOLD "LPThreshold"
#define NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT 0x0
/*
* NV_SWITCH_REGKEY_MINION_INTERRUPTS - Enable/disable MINION interrupts
*
* Used for bug #3572329. To be removed once fmodel conflict is resolved.
*
* Public: Available in release drivers
*/
#define NV_SWITCH_REGKEY_MINION_INTERRUPTS "MINIONIntr"
#define NV_SWITCH_REGKEY_MINION_INTERRUPTS_DEFAULT 0x0
#define NV_SWITCH_REGKEY_MINION_INTERRUPTS_ENABLE 0x1
#define NV_SWITCH_REGKEY_MINION_INTERRUPTS_DISABLE 0x2
/*
* NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET - surpresses error prints/notifs
*
* When set, Heartbeat timeout, Short Error Rate and Fault Up interrupts won't be
* logged
*
* Public: Available in release drivers
*/
#define NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET "SurpressLinkErrorsForGpuReset"
#define NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_DISABLE 0x0
#define NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_ENABLE 0x1
#endif //_REGKEY_NVSWITCH_H_

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -45,6 +45,7 @@ struct smbpbi
{
SOE_SMBPBI_SHARED_SURFACE *sharedSurface;
NvU64 dmaHandle;
NvU32 logMessageNesting;
};
NvlStatus nvswitch_smbpbi_init(nvswitch_device *);
@@ -55,6 +56,5 @@ NvlStatus nvswitch_smbpbi_set_link_error_info(nvswitch_device *,
void nvswitch_smbpbi_unload(nvswitch_device *);
void nvswitch_smbpbi_destroy(nvswitch_device *);
NvlStatus nvswitch_smbpbi_refresh_ecc_counts(nvswitch_device *);
void nvswitch_smbpbi_log_message(nvswitch_device *device, NvU32 num, NvU32 msglen, NvU8 *osErrorString);
#endif //_SMBPBI_NVSWITCH_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,6 +28,7 @@
#include "nvstatus.h"
#include "flcnifcmn.h"
#include "flcn/haldefs_flcnable_nvswitch.h"
#include "common_nvswitch.h"
struct SOE;
@@ -112,6 +113,9 @@ typedef struct {
NvlStatus (*setPcieLinkSpeed)(
struct nvswitch_device *device,
NvU32 linkSpeed);
NvlStatus (*i2cAccess)(
struct nvswitch_device *device,
NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams);
} soe_hal;
// HAL functions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -27,6 +27,7 @@
#include "nvlink_errors.h"
#include "nvtypes.h"
#include "nvstatus.h"
#include "common_nvswitch.h"
typedef struct SOE SOE, *PSOE;
struct FLCNABLE;
@@ -55,5 +56,6 @@ NvlStatus soeGetPexEomStatus_HAL (struct nvswitch_device *device, NvU8 mo
NvlStatus soeGetUphyDlnCfgSpace_HAL (struct nvswitch_device *device, NvU32 regAddress, NvU32 laneSelectMask, NvU16 *pRegValue);
NvlStatus soeForceThermalSlowdown_HAL (struct nvswitch_device *device, NvBool slowdown, NvU32 periodUs);
NvlStatus soeSetPcieLinkSpeed_HAL (struct nvswitch_device *device, NvU32 linkSpeed);
NvlStatus soeI2CAccess_HAL (struct nvswitch_device *device, NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams);
#endif //_SOE_NVSWITCH_H_

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2018-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2018-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a

View File

@@ -22,19 +22,8 @@
*/
#include "common_nvswitch.h"
#include "regkey_nvswitch.h"
#include "nvVer.h"
#include "inforom/inforom_nvswitch.h"
void
nvswitch_bbx_collect_current_time
(
nvswitch_device *device,
void *pBbxState
)
{
return;
}
NvlStatus
nvswitch_inforom_bbx_add_sxid
@@ -46,7 +35,15 @@ nvswitch_inforom_bbx_add_sxid
NvU32 data2
)
{
return -NVL_ERR_NOT_SUPPORTED;
NvlStatus status;
status = device->hal.nvswitch_bbx_add_sxid(device, exceptionType, data0, data1, data2);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "nvswitch_inforom_bbx_add_sxid failed, status=%d\n", status);
}
return status;
}
void
@@ -55,6 +52,14 @@ nvswitch_inforom_bbx_unload
nvswitch_device *device
)
{
NvlStatus status;
status = device->hal.nvswitch_bbx_unload(device);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "nvswitch_inforom_bbx_unload failed, status=%d\n", status);
}
return;
}
@@ -64,7 +69,47 @@ nvswitch_inforom_bbx_load
nvswitch_device *device
)
{
return -NVL_ERR_NOT_SUPPORTED;
NvlStatus status;
NvU64 time_ns = 0;
NvU32 majorVer;
NvU32 minorVer;
NvU32 buildNum;
NvU8 osType;
NvU32 osVersion;
osType = INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_TYPE_UNIX;
status = nvswitch_os_get_os_version(&majorVer, &minorVer, &buildNum);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Failed to get OS version, status=%d\n",
__FUNCTION__, status);
return status;
}
if ((majorVer > 0xff) || (minorVer > 0xff) || (buildNum > 0xffff))
{
NVSWITCH_PRINT(device, ERROR,
"Unexpected OS versions found. majorVer: 0x%x minorVer: 0x%x buildNum: 0x%x\n",
majorVer, minorVer, buildNum);
return -NVL_ERR_NOT_SUPPORTED;;
}
osVersion =
REF_NUM(INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_MAJOR, majorVer) |
REF_NUM(INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_MINOR, minorVer) |
REF_NUM(INFOROM_BBX_OBJ_V1_00_SYSTEM_OS_BUILD, buildNum);
time_ns = nvswitch_os_get_platform_time_epoch();
status = device->hal.nvswitch_bbx_load(device, time_ns, osType, osVersion);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "nvswitch_inforom_bbx_load failed, status=%d\n", status);
}
return status;
}
NvlStatus
@@ -74,5 +119,14 @@ nvswitch_inforom_bbx_get_sxid
NVSWITCH_GET_SXIDS_PARAMS *params
)
{
return -NVL_ERR_NOT_SUPPORTED;
NvlStatus status;
status = device->hal.nvswitch_bbx_get_sxid(device, params);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "nvswitch_inforom_bbx_load failed, status=%d\n", status);
}
return status;
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2019-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2019-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -36,7 +36,6 @@
// Interface functions
static NvlStatus _nvswitch_inforom_unpack_object(const char *, NvU8 *, NvU32 *);
static NvlStatus _nvswitch_inforom_pack_object(const char *, NvU32 *, NvU8 *);
static void _nvswitch_inforom_string_copy(inforom_U008 *pSrc, NvU8 *pDst, NvU32 size);
static NvlStatus _nvswitch_inforom_read_file(nvswitch_device *device,
const char objectName[INFOROM_FS_FILE_NAME_SIZE],
NvU32 packedObjectSize, NvU8 *pPackedObject);
@@ -45,31 +44,6 @@ static NvlStatus _nvswitch_inforom_write_file(nvswitch_device *device,
NvU32 packedObjectSize,
NvU8 *pPackedObject);
/*!
* Interface to copy string of inforom object.
* inforom_U008 is NvU32, and we use 0xff bits to store the character.
* Therefore we need a special copy API.
*
* @param[in] pSrc Source pointer
* @param[out] pDst Destination pointer
* @param[in] length Length of the string
*/
static void
_nvswitch_inforom_string_copy
(
inforom_U008 *pSrc,
NvU8 *pDst,
NvU32 length
)
{
NvU32 i;
for (i = 0; i < length; ++i)
{
pDst[i] = (NvU8)(pSrc[i] & 0xff);
}
}
static NvlStatus
_nvswitch_inforom_calc_packed_object_size
(
@@ -337,6 +311,31 @@ _nvswitch_inforom_pack_object
return NVL_SUCCESS;
}
/*!
* Interface to copy string of inforom object.
* inforom_U008 is NvU32, and we use 0xff bits to store the character.
* Therefore we need a special copy API.
*
* @param[in] pSrc Source pointer
* @param[out] pDst Destination pointer
* @param[in] length Length of the string
*/
void
nvswitch_inforom_string_copy
(
inforom_U008 *pSrc,
NvU8 *pDst,
NvU32 length
)
{
NvU32 i;
for (i = 0; i < length; ++i)
{
pDst[i] = (NvU8)(pSrc[i] & 0xff);
}
}
/*!
* Read and unpack an object from the InfoROM filesystem.
*
@@ -494,7 +493,7 @@ _nvswitch_inforom_read_file
nvswitch_os_memset(pDmaBuf, 0, transferSize);
cmdSeqDesc = 0;
nvswitch_timeout_create(NVSWITCH_INTERVAL_5MSEC_IN_NS * 100, &timeout);
nvswitch_timeout_create(NVSWITCH_INTERVAL_750MSEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn, (PRM_FLCN_CMD)&soeCmd, NULL, NULL,
SOE_RM_CMDQ_LOG_ID, &cmdSeqDesc, &timeout);
if (status != NV_OK)
@@ -592,7 +591,7 @@ _nvswitch_inforom_write_file
}
cmdSeqDesc = 0;
nvswitch_timeout_create(NVSWITCH_INTERVAL_5MSEC_IN_NS * 100, &timeout);
nvswitch_timeout_create(NVSWITCH_INTERVAL_750MSEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn, (PRM_FLCN_CMD)&soeCmd, NULL, NULL,
SOE_RM_CMDQ_LOG_ID, &cmdSeqDesc, &timeout);
if (status != NV_OK)
@@ -938,11 +937,11 @@ nvswitch_inforom_read_static_data
{
pData->OBD.bValid = NV_TRUE;
pData->OBD.buildDate = (NvU32)pInforom->OBD.object.buildDate;
_nvswitch_inforom_string_copy(pInforom->OBD.object.marketingName,
nvswitch_inforom_string_copy(pInforom->OBD.object.marketingName,
pData->OBD.marketingName,
NV_ARRAY_ELEMENTS(pData->OBD.marketingName));
_nvswitch_inforom_string_copy(pInforom->OBD.object.serialNumber,
nvswitch_inforom_string_copy(pInforom->OBD.object.serialNumber,
pData->OBD.serialNum,
NV_ARRAY_ELEMENTS(pData->OBD.serialNum));
@@ -956,7 +955,7 @@ nvswitch_inforom_read_static_data
if (pInforom->OEM.bValid)
{
pData->OEM.bValid = NV_TRUE;
_nvswitch_inforom_string_copy(pInforom->OEM.object.oemInfo,
nvswitch_inforom_string_copy(pInforom->OEM.object.oemInfo,
pData->OEM.oemInfo,
NV_ARRAY_ELEMENTS(pData->OEM.oemInfo));
}
@@ -964,7 +963,7 @@ nvswitch_inforom_read_static_data
if (pInforom->IMG.bValid)
{
pData->IMG.bValid = NV_TRUE;
_nvswitch_inforom_string_copy(pInforom->IMG.object.version,
nvswitch_inforom_string_copy(pInforom->IMG.object.version,
pData->IMG.inforomVer,
NV_ARRAY_ELEMENTS(pData->IMG.inforomVer));
}
@@ -1144,7 +1143,7 @@ nvswitch_initialize_inforom_objects
status);
}
status = nvswitch_inforom_dem_load(device);
status = device->hal.nvswitch_smbpbi_dem_load(device);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO, "Failed to load DEM object, rc: %d\n",

View File

@@ -24,10 +24,13 @@
#include "common_nvswitch.h"
#include "lr10/lr10.h"
#include "lr10/inforom_lr10.h"
#include "lr10/therm_lr10.h"
#include "inforom/ifrstruct.h"
#include "nvswitch/lr10/dev_nvlsaw_ip.h"
#include "nvswitch/lr10/dev_nvlsaw_ip_addendum.h"
#include "nvswitch/lr10/dev_pmgr.h"
#include "nvVer.h"
#include "regkey_nvswitch.h"
//
// TODO: Split individual object hals to their own respective files
@@ -744,75 +747,47 @@ nvswitch_oms_set_device_disable_lr10
_oms_update_entry_checksum(pVerData->pNext);
}
NvlStatus
nvswitch_bbx_setup_prologue_lr10
(
nvswitch_device *device,
void *pInforomBbxState
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_setup_epilogue_lr10
(
nvswitch_device *device,
void *pInforomBbxState
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_add_data_time_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_add_sxid_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
NvU32 exceptionType,
NvU32 data0,
NvU32 data1,
NvU32 data2
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_add_temperature_lr10
nvswitch_bbx_unload_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
nvswitch_device *device
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
void
nvswitch_bbx_set_initial_temperature_lr10
(
nvswitch_device *device,
void *pInforomBbxState,
void *pInforomBbxData
)
{
return;
}
NvlStatus
nvswitch_inforom_bbx_get_sxid_lr10
nvswitch_bbx_load_lr10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS *params
NvU64 time_ns,
NvU8 osType,
NvU32 osVersion
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_get_sxid_lr10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS * params
)
{
return -NVL_ERR_NOT_SUPPORTED;
}

View File

@@ -399,7 +399,7 @@ nvswitch_init_dlpl_interrupts_lr10
_NVLDL_RX, _ERROR_RATE_CTRL);
// Enable RX error rate short interrupt if the regkey is set
if (crcShortRegkeyVal != NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_OFF)
if (crcShortRegkeyVal != NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT)
{
shortRateMask = DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_MAN) |
DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_THRESHOLD_EXP) |
@@ -411,7 +411,7 @@ nvswitch_init_dlpl_interrupts_lr10
crcRegVal |= crcShortRegkeyVal;
}
// Enable RX error rate long interrupt if the regkey is set
if (crcLongRegkeyVal != NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_OFF)
if (crcLongRegkeyVal != NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT)
{
longRateMask = DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_THRESHOLD_MAN) |
DRF_SHIFTMASK(NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_THRESHOLD_EXP) |
@@ -558,7 +558,15 @@ nvswitch_init_lpwr_regs_lr10
tempRegVal);
//IC Enter Threshold
lpEntryThreshold = 16110000;
if (device->regkeys.lp_threshold == NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT)
{
// TODO: get from bios. Refer Bug 3626523 for more info.
lpEntryThreshold = 16110000;
}
else
{
lpEntryThreshold = device->regkeys.lp_threshold;
}
tempRegVal = 0;
tempRegVal = FLD_SET_DRF_NUM(_NVLTLC_TX_LNK, _PWRM_IC_LP_ENTER_THRESHOLD, _THRESHOLD, lpEntryThreshold, tempRegVal);
@@ -2022,6 +2030,263 @@ nvswitch_execute_unilateral_link_shutdown_lr10
nvswitch_corelib_set_dl_link_mode_lr10(link, NVLINK_LINKSTATE_OFF, 0);
}
static NvU32
_nvswitch_get_nvlink_linerate_lr10
(
nvswitch_device *device,
NvU32 val
)
{
NvU32 lineRate = 0;
switch (val)
{
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_16G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_16_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_20G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_20_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_25G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_25_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_32G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_32_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_40G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_40_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_50G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_50_00000_GBPS;
break;
case NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_53_12500G:
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_53_12500_GBPS;
break;
default:
NVSWITCH_PRINT(device, SETUP, "%s:ERROR LINE_RATE = 0x%x requested by regkey\n",
__FUNCTION__, lineRate);
lineRate = NV_NVLIPT_LNK_CTRL_SYSTEM_LINK_CLK_CTRL_LINE_RATE_ILLEGAL_LINE_RATE;
}
return lineRate;
}
void
nvswitch_setup_link_system_registers_lr10
(
nvswitch_device *device,
nvlink_link *link
)
{
NvU32 regval, fldval;
NvU32 lineRate = 0;
NVLINK_CONFIG_DATA_LINKENTRY *vbios_link_entry = NULL;
NVSWITCH_BIOS_NVLINK_CONFIG *bios_config;
bios_config = nvswitch_get_bios_nvlink_config(device);
if ((bios_config == NULL) || (bios_config->bit_address == 0))
{
NVSWITCH_PRINT(device, WARN,
"%s: VBIOS NvLink configuration table not found\n",
__FUNCTION__);
}
//
// Identify the valid link entry to update. If not, proceed with the default settings
//
if ((bios_config == NULL) || (bios_config->bit_address == 0))
{
NVSWITCH_PRINT(device, SETUP,
"%s: No override with VBIOS - VBIOS NvLink configuration table not found\n",
__FUNCTION__);
}
else
{
vbios_link_entry = &bios_config->link_vbios_entry[bios_config->link_base_entry_assigned][link->linkNumber];
}
// LINE_RATE SYSTEM register
if (device->regkeys.nvlink_speed_control != NV_SWITCH_REGKEY_SPEED_CONTROL_SPEED_DEFAULT)
{
regval = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL);
lineRate = _nvswitch_get_nvlink_linerate_lr10(device, device->regkeys.nvlink_speed_control);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL,
_LINE_RATE, lineRate, regval);
NVSWITCH_PRINT(device, SETUP, "%s: LINE_RATE = 0x%x requested by regkey\n",
__FUNCTION__, lineRate);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL, regval);
}
// TXTRAIN SYSTEM register
regval = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL);
fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _FOM_FORMAT,
device->regkeys.txtrain_control);
if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_FOM_FORMAT_NOP)
{
NVSWITCH_PRINT(device, SETUP, "%s: FOM_FORMAT = 0x%x requested by regkey\n",
__FUNCTION__, fldval);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_FOM_FORMAT, fldval, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _TXTRAIN_FOM_FORMAT,
DRF_VAL(_NVLINK_VBIOS,_PARAM5,_TXTRAIN_FOM_FORMAT, vbios_link_entry->nvLinkparam5),
regval);
}
fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _OPTIMIZATION_ALGORITHM,
device->regkeys.txtrain_control);
if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_OPTIMIZATION_ALGORITHM_NOP)
{
NVSWITCH_PRINT(device, SETUP, "%s: OPTIMIZATION_ALGORITHM = 0x%x requested by regkey\n",
__FUNCTION__, fldval);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_OPTIMIZATION_ALGORITHM, fldval, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _TXTRAIN_OPTIMIZATION_ALGORITHM,
vbios_link_entry->nvLinkparam4, regval);
}
fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _ADJUSTMENT_ALGORITHM,
device->regkeys.txtrain_control);
if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_ADJUSTMENT_ALGORITHM_NOP)
{
NVSWITCH_PRINT(device, SETUP, "%s: ADJUSTMENT_ALGORITHM = 0x%x requested by regkey\n",
__FUNCTION__, fldval);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_ADJUSTMENT_ALGORITHM, fldval, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _TXTRAIN_ADJUSTMENT_ALGORITHM,
DRF_VAL(_NVLINK_VBIOS,_PARAM5,_TXTRAIN_ADJUSTMENT_ALGORITHM, vbios_link_entry->nvLinkparam5),
regval);
}
fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _MINIMUM_TRAIN_TIME_MANTISSA,
device->regkeys.txtrain_control);
if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_MINIMUM_TRAIN_TIME_MANTISSA_NOP)
{
NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_MANTISSA = 0x%x requested by regkey\n",
__FUNCTION__, fldval);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA, fldval, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA,
DRF_VAL(_NVLINK_VBIOS,_PARAM6,_TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA, vbios_link_entry->nvLinkparam6),
regval);
}
fldval = DRF_VAL(_SWITCH_REGKEY, _TXTRAIN_CONTROL, _MINIMUM_TRAIN_TIME_EXPONENT,
device->regkeys.txtrain_control);
if (fldval != NV_SWITCH_REGKEY_TXTRAIN_CONTROL_MINIMUM_TRAIN_TIME_EXPONENT_NOP)
{
NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_EXPONENT = 0x%x requested by regkey\n",
__FUNCTION__, fldval);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT, fldval, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT,
DRF_VAL(_NVLINK_VBIOS,_PARAM6,_TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT, vbios_link_entry->nvLinkparam6),
regval);
}
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL, regval);
// Disable L2 (Bug 3176196)
regval = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SYSTEM_LINK_AN1_CTRL);
regval = FLD_SET_DRF(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_AN1_CTRL, _PWRM_L2_ENABLE, _DISABLE, regval);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SYSTEM_LINK_AN1_CTRL, regval);
// SW WAR: Bug 3364420
nvswitch_apply_recal_settings(device, link);
return;
}
void
nvswitch_load_link_disable_settings_lr10
(
nvswitch_device *device,
nvlink_link *link
)
{
NvU32 val;
NVLINK_CONFIG_DATA_LINKENTRY *vbios_link_entry = NULL;
NVSWITCH_BIOS_NVLINK_CONFIG *bios_config;
bios_config = nvswitch_get_bios_nvlink_config(device);
if ((bios_config == NULL) || (bios_config->bit_address == 0))
{
NVSWITCH_PRINT(device, WARN,
"%s: VBIOS NvLink configuration table not found\n",
__FUNCTION__);
}
// SW CTRL - clear out LINK_DISABLE on driver load
val = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber,
NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SW_LINK_MODE_CTRL);
val = FLD_SET_DRF(_NVLIPT_LNK, _CTRL_SW_LINK_MODE_CTRL, _LINK_DISABLE,
_ENABLED, val);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber,
NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SW_LINK_MODE_CTRL, val);
//
// SYSTEM CTRL
// If the SYSTEM_CTRL setting had been overidden by another entity,
// it should also be locked, so this write would not take effect.
//
if (bios_config != NULL)
{
vbios_link_entry = &bios_config->link_vbios_entry[bios_config->link_base_entry_assigned][link->linkNumber];
}
val = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber,
NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SYSTEM_LINK_MODE_CTRL);
if ((vbios_link_entry != NULL) &&
(FLD_TEST_DRF(_NVLINK_VBIOS,_PARAM0, _LINK, _DISABLE, vbios_link_entry->nvLinkparam0)))
{
if (!nvswitch_is_link_in_reset(device, link))
{
NVSWITCH_PRINT(device, ERROR,
"%s: link #%d is not in reset, cannot set LINK_DISABLE\n",
__FUNCTION__, link->linkNumber);
return;
}
val = FLD_SET_DRF(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_MODE_CTRL, _LINK_DISABLE,
_DISABLED, val);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber,
NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SYSTEM_LINK_MODE_CTRL, val);
// Set link to invalid and unregister from corelib
device->link[link->linkNumber].valid = NV_FALSE;
nvlink_lib_unregister_link(link);
nvswitch_destroy_link(link);
return;
}
else
{
val = FLD_SET_DRF(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_MODE_CTRL, _LINK_DISABLE,
_ENABLED, val);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber,
NVLIPT_LNK, _NVLIPT_LNK, _CTRL_SYSTEM_LINK_MODE_CTRL, val);
}
return;
}
void
nvswitch_reset_persistent_link_hw_state_lr10
(
@@ -2047,7 +2312,8 @@ NvlStatus
nvswitch_launch_ALI_link_training_lr10
(
nvswitch_device *device,
nvlink_link *link
nvlink_link *link,
NvBool bSync
)
{
return NVL_ERR_NOT_IMPLEMENTED;

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -27,6 +27,163 @@
#include "nvswitch/lr10/dev_nvlsaw_ip.h"
#include "nvswitch/lr10/dev_nvlsaw_ip_addendum.h"
#include "flcn/flcn_nvswitch.h"
#include "rmflcncmdif_nvswitch.h"
#define GET_PFIFO_FROM_DEVICE(dev) (&(dev)->pSmbpbi->sharedSurface->inforomObjects.DEM.object.v1)
#define DEM_FIFO_SIZE INFOROM_DEM_OBJECT_V1_00_FIFO_SIZE
#define DEM_FIFO_PTR(x) ((x) % DEM_FIFO_SIZE)
#define DEM_PTR_DIFF(cur, next) (((next) > (cur)) ? ((next) - (cur)) : \
(DEM_FIFO_SIZE - ((cur) - (next))))
#define DEM_BYTES_OCCUPIED(pf) DEM_PTR_DIFF((pf)->readOffset, (pf)->writeOffset)
//
// See how much space is available in the FIFO.
// Must leave 1 word free so the write pointer does not
// catch up with the read pointer. That would be indistinguishable
// from an empty FIFO.
//
#define DEM_BYTES_AVAILABLE(pf) (DEM_PTR_DIFF((pf)->writeOffset, (pf)->readOffset) - \
sizeof(NvU32))
#define DEM_RECORD_SIZE_MAX (sizeof(NV_MSGBOX_DEM_RECORD) \
+ NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
#define DEM_RECORD_SIZE_MIN (sizeof(NV_MSGBOX_DEM_RECORD) + 1)
#define FIFO_REC_LOOP_ITERATOR _curPtr
#define FIFO_REC_LOOP_REC_PTR _recPtr
#define FIFO_REC_LOOP_REC_SIZE _recSize
#define FIFO_REC_LOOP_START(pf, cond) \
{ \
NvU16 _nextPtr; \
for (FIFO_REC_LOOP_ITERATOR = (pf)->readOffset; cond; FIFO_REC_LOOP_ITERATOR = _nextPtr) \
{ \
NV_MSGBOX_DEM_RECORD *FIFO_REC_LOOP_REC_PTR = (NV_MSGBOX_DEM_RECORD *) \
((pf)->fifoBuffer + FIFO_REC_LOOP_ITERATOR); \
NvU16 FIFO_REC_LOOP_REC_SIZE = \
FIFO_REC_LOOP_REC_PTR->recordSize * sizeof(NvU32);
#define FIFO_REC_LOOP_END \
_nextPtr = DEM_FIFO_PTR(FIFO_REC_LOOP_ITERATOR + FIFO_REC_LOOP_REC_SIZE); \
} \
}
static void _smbpbiDemInit(nvswitch_device *device, struct smbpbi *pSmbpbi, struct INFOROM_DEM_OBJECT_V1_00 *pFifo);
NvlStatus
nvswitch_smbpbi_alloc_lr10
(
nvswitch_device *device
)
{
NV_STATUS status;
NvU64 dmaHandle;
void *cpuAddr;
// Create DMA mapping for SMBPBI transactions
status = nvswitch_os_alloc_contig_memory(device->os_handle, &cpuAddr,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
(device->dma_addr_width == 32));
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Failed to allocate contig memory, rc:%d\n",
status);
return status;
}
nvswitch_os_memset(cpuAddr, 0, sizeof(SOE_SMBPBI_SHARED_SURFACE));
status = nvswitch_os_map_dma_region(device->os_handle, cpuAddr, &dmaHandle,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
if (status == NVL_SUCCESS)
{
device->pSmbpbi->sharedSurface = cpuAddr;
device->pSmbpbi->dmaHandle = dmaHandle;
}
else
{
NVSWITCH_PRINT(device, ERROR,
"Failed to map dma region for SMBPBI shared surface, rc:%d\n",
status);
nvswitch_os_free_contig_memory(device->os_handle, cpuAddr, sizeof(SOE_SMBPBI_SHARED_SURFACE));
}
return status;
}
NvlStatus
nvswitch_smbpbi_post_init_hal_lr10
(
nvswitch_device *device
)
{
struct smbpbi *pSmbpbi = device->pSmbpbi;
FLCN *pFlcn;
NvU64 dmaHandle;
RM_FLCN_CMD_SOE cmd;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
RM_SOE_SMBPBI_CMD_INIT *pInitCmd = &cmd.cmd.smbpbiCmd.init;
NvlStatus status;
if (!device->pInforom || !device->pSmbpbi->sharedSurface)
{
return -NVL_ERR_NOT_SUPPORTED;
}
// Populate shared surface with static InfoROM data
nvswitch_inforom_read_static_data(device, device->pInforom,
&device->pSmbpbi->sharedSurface->inforomObjects);
pFlcn = device->pSoe->pFlcn;
dmaHandle = pSmbpbi->dmaHandle;
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, INIT);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_INIT;
RM_FLCN_U64_PACK(&pInitCmd->dmaHandle, &dmaHandle);
//
// Make the interval twice the heartbeat period to avoid
// skew between driver and soe threads
//
pInitCmd->driverPollingPeriodUs = (NVSWITCH_HEARTBEAT_INTERVAL_NS / 1000) * 2;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI Init command failed. rc:%d\n",
__FUNCTION__, status);
}
return status;
}
void
nvswitch_smbpbi_destroy_hal_lr10
(
nvswitch_device *device
)
{
if (device->pSmbpbi && device->pSmbpbi->sharedSurface)
{
nvswitch_os_unmap_dma_region(device->os_handle,
device->pSmbpbi->sharedSurface,
device->pSmbpbi->dmaHandle,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
nvswitch_os_free_contig_memory(device->os_handle, device->pSmbpbi->sharedSurface,
sizeof(SOE_SMBPBI_SHARED_SURFACE));
}
}
NvlStatus
nvswitch_smbpbi_get_dem_num_messages_lr10
@@ -41,3 +198,435 @@ nvswitch_smbpbi_get_dem_num_messages_lr10
return NVL_SUCCESS;
}
NvlStatus
nvswitch_smbpbi_dem_load_lr10
(
nvswitch_device *device
)
{
NvlStatus status;
NvU8 version = 0;
NvU8 subversion = 0;
struct inforom *pInforom = device->pInforom;
NvU8 *pPackedObject = NULL;
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
if ((pInforom == NULL) || (device->pSmbpbi == NULL) ||
(device->pSmbpbi->sharedSurface == NULL))
{
return -NVL_ERR_NOT_SUPPORTED;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
status = nvswitch_inforom_get_object_version_info(device, "DEM", &version,
&subversion);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO, "no DEM object found, rc:%d\n", status);
goto nvswitch_inforom_dem_load_fail;
}
if (!INFOROM_OBJECT_SUBVERSION_SUPPORTS_NVSWITCH(subversion))
{
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
version, subversion);
status = -NVL_ERR_NOT_SUPPORTED;
goto nvswitch_inforom_dem_load_fail;
}
NVSWITCH_PRINT(device, INFO, "DEM v%u.%u found\n", version, subversion);
if (version != 1)
{
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
version, subversion);
status = -NVL_ERR_NOT_SUPPORTED;
goto nvswitch_inforom_dem_load_fail;
}
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
if (pPackedObject == NULL)
{
status = -NVL_NO_MEM;
goto nvswitch_inforom_dem_load_fail;
}
status = nvswitch_inforom_load_object(device, pInforom, "DEM",
INFOROM_DEM_OBJECT_V1_00_FMT,
pPackedObject,
pFifo);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Failed to load DEM object, rc: %d\n",
status);
goto nvswitch_inforom_dem_load_fail;
}
nvswitch_inforom_dem_load_fail:
if (pPackedObject)
{
nvswitch_os_free(pPackedObject);
}
//
// Mark the cached DEM as usable for Xid logging, even if we were
// unable to find it in the InfoROM image.
//
device->pSmbpbi->sharedSurface->inforomObjects.DEM.bValid = NV_TRUE;
_smbpbiDemInit(device, device->pSmbpbi, pFifo);
return status;
}
/*!
* Validate/Initialize the Driver Event Message (SXid) FIFO buffer
*
* @param[in] device device object pointer
* @param[in] pSmbpbi SMBPBI object pointer
* @param[in,out] pFifo DEM object pointer
*
* @return void
*/
static void
_smbpbiDemInit
(
nvswitch_device *device,
struct smbpbi *pSmbpbi,
struct INFOROM_DEM_OBJECT_V1_00 *pFifo
)
{
NvU8 msgLeft;
unsigned recordsHeld = 0;
NvU16 FIFO_REC_LOOP_ITERATOR;
NvU16 bytesOccupied;
NvU16 bytesSeen;
NvBool status = NV_FALSE;
// validate the FIFO buffer
if ((DEM_FIFO_PTR(pFifo->writeOffset) != pFifo->writeOffset) ||
(DEM_FIFO_PTR(pFifo->readOffset) != pFifo->readOffset) ||
((pFifo->writeOffset % sizeof(NvU32)) != 0) ||
((pFifo->readOffset % sizeof(NvU32)) != 0))
{
goto smbpbiDemInit_exit;
}
if (pFifo->writeOffset == pFifo->readOffset)
{
// The FIFO is empty
status = NV_TRUE;
goto smbpbiDemInit_exit;
}
//
// This HAL extracts from a scratch register the count of DEM messages
// in the FIFO that has not yet been requested by the SMBPBI client.
// If the FIFO holds more messages than that, it means those in excess
// of this count have been delivered to the client by PreOS app.
//
if (device->hal.nvswitch_smbpbi_get_dem_num_messages(device, &msgLeft) != NVL_SUCCESS)
{
// assume the maximum
msgLeft = ~0;
}
if (msgLeft == 0)
{
// Nothing of value in the FIFO. Lets reset it explicitly.
status = NV_TRUE;
pFifo->writeOffset = 0;
pFifo->readOffset = 0;
goto smbpbiDemInit_exit;
}
//
// Count the messages in the FIFO, while also checking the structure
// for integrity. Reset the FIFO in case any corruption is found.
//
bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
bytesSeen = 0;
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
if ((_recSize > DEM_RECORD_SIZE_MAX) ||
(FIFO_REC_LOOP_REC_SIZE < DEM_RECORD_SIZE_MIN))
{
goto smbpbiDemInit_exit;
}
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
++recordsHeld;
FIFO_REC_LOOP_END
if ((bytesSeen != bytesOccupied) || (msgLeft > recordsHeld))
{
goto smbpbiDemInit_exit;
}
//
// Advance the FIFO read ptr in order to remove those messages that
// have already been delivered to the client.
//
FIFO_REC_LOOP_START(pFifo, recordsHeld > msgLeft)
--recordsHeld;
FIFO_REC_LOOP_END
pFifo->readOffset = FIFO_REC_LOOP_ITERATOR;
status = NV_TRUE;
smbpbiDemInit_exit:
if (!status)
{
// Reset the FIFO
pFifo->writeOffset = 0;
pFifo->readOffset = 0;
pFifo->seqNumber = 0;
}
}
/*!
* A helper to create a new DEM FIFO record
*
* @param[in,out] pFifo DEM object pointer
* @param[in] num Xid number
* @param[in] osErrorString text message to store
* @param[in] msglen message size
* @param[out] pRecSize new record size in bytes
*
* @return ptr to the new record
* @return NULL if there's no room in the FIFO
* or dynamic allocation error
*/
static NV_MSGBOX_DEM_RECORD *
_makeNewRecord
(
INFOROM_DEM_OBJECT_V1_00 *pFifo,
NvU32 num,
NvU8 *osErrorString,
NvU32 msglen,
NvU32 *pRecSize
)
{
NV_MSGBOX_DEM_RECORD *pNewRec;
*pRecSize = NV_MIN(sizeof(NV_MSGBOX_DEM_RECORD) + msglen,
DEM_RECORD_SIZE_MAX);
if ((*pRecSize > DEM_BYTES_AVAILABLE(pFifo)) ||
((pNewRec = nvswitch_os_malloc(*pRecSize)) == NULL))
{
return NULL;
}
// Fill the new record.
nvswitch_os_memset(pNewRec, 0, *pRecSize);
pNewRec->recordSize = NV_UNSIGNED_DIV_CEIL(*pRecSize, sizeof(NvU32));
pNewRec->xidId = num;
pNewRec->seqNumber = pFifo->seqNumber++;
pNewRec->timeStamp = nvswitch_os_get_platform_time() / NVSWITCH_NSEC_PER_SEC;
if (msglen > NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
{
// The text string is too long. Truncate and notify the client.
pNewRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
_TRUNC, _SET, pNewRec->flags);
msglen = NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE - 1;
}
nvswitch_os_memcpy(pNewRec->textMessage, osErrorString, msglen);
return pNewRec;
}
/*!
* A helper to add the new record to the DEM FIFO
*
* @param[in,out] pFifo DEM object pointer
* @param[in] pNewRec the new record
* @param[in] recSize new record size in bytes
*
* @return void
*/
static void
_addNewRecord
(
INFOROM_DEM_OBJECT_V1_00 *pFifo,
NV_MSGBOX_DEM_RECORD *pNewRec,
NvU32 recSize
)
{
NvU16 rem;
NvU16 curPtr;
NvU16 copySz;
NvU8 *srcPtr;
// Copy the new record into the FIFO, handling a possible wrap-around.
rem = recSize;
curPtr = pFifo->writeOffset;
srcPtr = (NvU8 *)pNewRec;
while (rem > 0)
{
copySz = NV_MIN(rem, DEM_FIFO_SIZE - curPtr);
nvswitch_os_memcpy(pFifo->fifoBuffer + curPtr, srcPtr, copySz);
rem -= copySz;
srcPtr += copySz;
curPtr = DEM_FIFO_PTR(curPtr + copySz);
}
// Advance the FIFO write ptr.
pFifo->writeOffset = DEM_FIFO_PTR(pFifo->writeOffset +
(pNewRec->recordSize * sizeof(NvU32)));
}
/*!
* Add a Driver Event Message (SXid) to the InfoROM DEM FIFO buffer
*
* @param[in] device device object pointer
* @param[in] num Xid number
* @param[in] msglen message size
* @param[in] osErrorString text message to store
*
* @return void
*/
void
nvswitch_smbpbi_log_message_lr10
(
nvswitch_device *device,
NvU32 num,
NvU32 msglen,
NvU8 *osErrorString
)
{
INFOROM_DEM_OBJECT_V1_00 *pFifo;
NvU32 recSize;
NvU16 FIFO_REC_LOOP_ITERATOR;
NV_MSGBOX_DEM_RECORD *pNewRec;
if ((device->pSmbpbi == NULL) ||
(device->pSmbpbi->sharedSurface == NULL))
{
return;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
pNewRec = _makeNewRecord(pFifo, num, osErrorString, msglen, &recSize);
if (pNewRec != NULL)
{
_addNewRecord(pFifo, pNewRec, recSize);
nvswitch_os_free(pNewRec);
}
else
{
//
// We are unable to log this message. Mark the latest record
// with a flag telling the client that message(s) were dropped.
//
NvU16 bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
NvU16 bytesSeen;
NV_MSGBOX_DEM_RECORD *pLastRec = NULL;
// Find the newest record
bytesSeen = 0;
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
pLastRec = FIFO_REC_LOOP_REC_PTR;
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
FIFO_REC_LOOP_END
if (pLastRec != NULL)
{
pLastRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
_OVFL, _SET, pLastRec->flags);
}
}
return;
}
void
nvswitch_smbpbi_dem_flush_lr10
(
nvswitch_device *device
)
{
NvU8 *pPackedObject = NULL;
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
NvlStatus status = NVL_SUCCESS;
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
if (pPackedObject == NULL)
{
status = -NVL_NO_MEM;
goto nvswitch_smbpbi_dem_flush_exit;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
status = nvswitch_inforom_write_object(device, "DEM",
INFOROM_DEM_OBJECT_V1_00_FMT,
pFifo,
pPackedObject);
nvswitch_smbpbi_dem_flush_exit:
nvswitch_os_free(pPackedObject);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "DEM object write failed, status=%d\n",
status);
}
}
void
nvswitch_smbpbi_send_unload_lr10
(
nvswitch_device *device
)
{
FLCN *pFlcn;
RM_FLCN_CMD_SOE cmd;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
NvlStatus status;
pFlcn = device->pSoe->pFlcn;
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, UNLOAD);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_UNLOAD;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI unload command failed. rc:%d\n",
__FUNCTION__, status);
}
}
NvlStatus
nvswitch_smbpbi_send_init_data_lr10
(
nvswitch_device *device
)
{
return NVL_SUCCESS;
}

View File

@@ -1584,7 +1584,7 @@ _soeDmaStartTest
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_CORE;
cmd.hdr.size = sizeof(cmd);
cmd.hdr.size = RM_SOE_CMD_SIZE(CORE, DMA_TEST);
pDmaCmd = &cmd.cmd.core.dma_test;
RM_FLCN_U64_PACK(&pDmaCmd->dmaHandle, &dmaHandle);
@@ -2064,7 +2064,7 @@ _soeForceThermalSlowdown_LR10
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_THERM;
cmd.hdr.size = sizeof(cmd);
cmd.hdr.size = RM_SOE_CMD_SIZE(THERM, FORCE_SLOWDOWN);
cmd.cmd.therm.cmdType = RM_SOE_THERM_FORCE_SLOWDOWN;
cmd.cmd.therm.slowdown.slowdown = slowdown;
cmd.cmd.therm.slowdown.periodUs = periodUs;

View File

@@ -0,0 +1,195 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "ls10/clock_ls10.h"
#include "nvswitch/ls10/dev_trim.h"
#include "nvswitch/ls10/dev_soe_ip.h"
#include "nvswitch/ls10/dev_npgperf_ip.h"
#include "nvswitch/ls10/dev_nvlw_ip.h"
#include "nvswitch/ls10/dev_nport_ip.h"
#include "nvswitch/ls10/dev_minion_ip.h"
#include "nvswitch/ls10/dev_timer_ip.h"
#include "nvswitch/ls10/dev_minion_ip.h"
#include "nvswitch/ls10/dev_pri_hub_prt_ip.h"
#include "nvswitch/ls10/dev_pri_masterstation_ip.h"
//
// Initialize the software state of the switch PLL
//
NvlStatus
nvswitch_init_pll_config_ls10
(
nvswitch_device *device
)
{
NVSWITCH_PLL_LIMITS pll_limits;
NVSWITCH_PLL_INFO pll;
NvlStatus retval = NVL_SUCCESS;
//
// These parameters could come from schmoo'ing API, settings file or a ROM.
// If no configuration ROM settings are present, use the PLL documentation
//
// PLL40G_SMALL_ESD.doc
//
pll_limits.ref_min_mhz = 100;
pll_limits.ref_max_mhz = 100;
pll_limits.vco_min_mhz = 1750;
pll_limits.vco_max_mhz = 3800;
pll_limits.update_min_mhz = 13; // 13.5MHz
pll_limits.update_max_mhz = 38; // 38.4MHz
pll_limits.m_min = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_MDIV_MIN;
pll_limits.m_max = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_MDIV_MAX;
pll_limits.n_min = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_NDIV_MIN;
pll_limits.n_max = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_NDIV_MAX;
pll_limits.pl_min = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_PLDIV_MIN;
pll_limits.pl_max = NV_CLOCK_NVSW_SYS_SWITCHPLL_COEFF_PLDIV_MAX;
pll_limits.valid = NV_TRUE;
//
// set well known coefficients to achieve frequency
//
pll.src_freq_khz = 100000; // 100MHz
pll.M = 3;
pll.N = 80;
pll.PL = 2;
pll.dist_mode = 0; // Ignored. Only 1x supported
pll.refclk_div = NV_CLOCK_NVSW_SYS_RX_BYPASS_REFCLK_DIV_INIT;
retval = nvswitch_validate_pll_config(device, &pll, pll_limits);
if (retval != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, WARN,
"Selecting default PLL setting.\n");
// Select default, safe clock
pll.src_freq_khz = 100000; // 100MHz
pll.M = 3;
pll.N = 80;
pll.PL = 2;
pll.dist_mode = 0; // Ignored. Only 1x supported
pll.refclk_div = NV_CLOCK_NVSW_SYS_RX_BYPASS_REFCLK_DIV_INIT;
retval = nvswitch_validate_pll_config(device, &pll, pll_limits);
if (retval != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"Default PLL setting failed.\n");
return retval;
}
}
device->switch_pll = pll;
return NVL_SUCCESS;
}
//
// Check that the PLLs are initialized. VBIOS is expected to configure PLLs
//
NvlStatus
nvswitch_init_pll_ls10
(
nvswitch_device *device
)
{
NvU32 pllRegVal;
//
// Clocks should only be initialized on silicon or a clocks netlist on emulation
//
if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
{
NVSWITCH_PRINT(device, WARN,
"%s: Skipping setup of NVSwitch clocks\n",
__FUNCTION__);
return NVL_SUCCESS;
}
pllRegVal = NVSWITCH_ENG_RD32(device, CLKS_SYS, , 0, _CLOCK_NVSW_SYS, _SWITCHPLL_CFG);
if (!FLD_TEST_DRF(_CLOCK_NVSW_SYS, _SWITCHPLL_CFG, _PLL_LOCK, _TRUE, pllRegVal))
{
NVSWITCH_PRINT(device, ERROR,
"%s: _PLL_LOCK failed\n",
__FUNCTION__);
return -NVL_INITIALIZATION_TOTAL_FAILURE;
}
pllRegVal = NVSWITCH_ENG_RD32(device, CLKS_SYS, , 0, _CLOCK_NVSW_SYS, _SWITCHPLL_CTRL);
if (!FLD_TEST_DRF_NUM(_CLOCK_NVSW_SYS, _SWITCHPLL_CTRL, _PLL_FREQLOCK, 1, pllRegVal))
{
NVSWITCH_PRINT(device, ERROR,
"%s: _PLL_FREQLOCK failed\n",
__FUNCTION__);
return -NVL_INITIALIZATION_TOTAL_FAILURE;
}
pllRegVal = NVSWITCH_ENG_RD32(device, CLKS_SYS, , 0, _CLOCK_NVSW_SYS, _SWITCHCLK_SWITCH_DIVIDER);
if (!FLD_TEST_DRF_NUM(_CLOCK_NVSW_SYS, _SWITCHCLK_SWITCH_DIVIDER, _SWITCH_DIVIDER_DONE, 1, pllRegVal))
{
NVSWITCH_PRINT(device, ERROR,
"%s: _SWITCH_DIVIDER_DONE failed\n",
__FUNCTION__);
return -NVL_INITIALIZATION_TOTAL_FAILURE;
}
pllRegVal = NVSWITCH_ENG_RD32(device, CLKS_SYS, , 0, _CLOCK_NVSW_SYS, _SYSTEM_CLK_SWITCH_DIVIDER);
if (!FLD_TEST_DRF_NUM(_CLOCK_NVSW_SYS, _SYSTEM_CLK_SWITCH_DIVIDER, _SWITCH_DIVIDER_DONE, 1, pllRegVal))
{
NVSWITCH_PRINT(device, ERROR,
"%s: _SWITCH_DIVIDER_DONE for SYSTEMCLK failed\n",
__FUNCTION__);
return -NVL_INITIALIZATION_TOTAL_FAILURE;
}
return NVL_SUCCESS;
}
//
// Initialize clock gating.
//
void
nvswitch_init_clock_gating_ls10
(
nvswitch_device *device
)
{
//
// CG and PROD settings were already handled by:
// - nvswitch_nvs_top_prod_ls10
// - nvswitch_npg_prod_ls10
// - nvswitch_apply_prod_nvlw_ls10
// - nvswitch_apply_prod_nxbar_ls10
//
// which were all called by nvswitch_initialize_ip_wrappers_ls10
return;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,376 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "flcn/flcn_nvswitch.h"
#include "nvswitch/ls10/dev_falcon_v4.h"
#include "nvswitch/ls10/dev_riscv_pri.h"
//
// Functions shared with LR10
//
void flcnSetupHal_LR10(PFLCN pFlcn);
static NvU32
_flcnRiscvRegRead_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 offset
)
{
// Probably should perform some checks on the offset, the device, and the engine descriptor
return nvswitch_reg_read_32(device, NV_FALCON2_SOE_BASE + offset);
}
static void
_flcnRiscvRegWrite_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 offset,
NvU32 data
)
{
// Probably should perform some checks on the offset, the device, and the engine descriptor
nvswitch_reg_write_32(device, NV_FALCON2_SOE_BASE + offset, data);
}
/*!
* @brief Retrieve the size of the falcon data memory.
*
* @param[in] pGpu OBJGPU pointer
* @param[in] pFlcn Falcon object pointer
* @param[in] bFalconReachable If set, returns size that can be reached by Falcon
*
* @return IMEM size in bytes
*/
static NvU32
_flcnDmemSize_LS10
(
nvswitch_device *device,
PFLCN pFlcn
)
{
NvU32 data = flcnRegRead_HAL(device, pFlcn, NV_PFALCON_FALCON_HWCFG3);
return (DRF_VAL(_PFALCON, _FALCON_HWCFG3, _DMEM_TOTAL_SIZE, data) <<
FALCON_DMEM_BLKSIZE2);
}
/*
* @brief Get the destination after masking
* off all but the OFFSET and BLOCK in IMEM
*
* @param[in] dst Destination in IMEM
*
* @returns dst with only OFFSET and BLOCK bits set
*/
static NvU32
_flcnSetImemAddr_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 dst
)
{
NVSWITCH_ASSERT(0);
return 0;
}
/*!
*
* @brief Copy contents of pSrc to IMEM
*
* @param[in] pGpu OBJGPU pointer
* @param[in] pFlcn Falcon object pointer
* @param[in] dst Destination in IMEM
* @param[in] pSrc IMEM contents
* @param[in] sizeInBytes Total IMEM size in bytes
* @param[in] bSecure NV_TRUE if IMEM is signed
* @param[in] tag IMEM tag
* @param[in] port PMB port to copy IMEM
*
* @returns void
*/
static void
_flcnImemCopyTo_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 dst,
NvU8 *pSrc,
NvU32 sizeBytes,
NvBool bSecure,
NvU32 tag,
NvU8 port
)
{
}
/*!
*
* @brief Mask the DMEM destination to have only the BLK and OFFSET bits set
*
* @param[in] dst Destination in DMEM
*
* @returns masked destination value in DMEM
*/
static NvU32
_flcnSetDmemAddr_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 dst
)
{
return (dst & (DRF_SHIFTMASK(NV_PFALCON_FALCON_DMEMC_OFFS) |
DRF_SHIFTMASK(NV_PFALCON_FALCON_DMEMC_BLK)));
}
/*!
* Depending on the direction of the copy, copies 'sizeBytes' to/from 'pBuf'
* from/to DMEM offset 'dmemAddr' using DMEM access port 'port'.
*
* @param[in] pGpu GPU object pointer
* @param[in] pFlcn Falcon object pointer
* @param[in] dmemAddr The DMEM offset for the copy
* @param[in] pBuf The pointer to the buffer containing the data to copy
* @param[in] sizeBytes The number of bytes to copy
* @param[in] port The DMEM port index to use when accessing DMEM
* @param[in] bCopyFrom Boolean representing the copy direction (to/from DMEM)
*
* @return NV_OK if the data was successfully copied
* NV_ERR_INVALID_ARGUMENT if the input argument(s) is/are invalid
*/
static NV_STATUS
_flcnDmemTransfer_LS10
(
nvswitch_device *device,
PFLCN pFlcn,
NvU32 dmemAddr,
NvU8 *pBuf,
NvU32 sizeBytes,
NvU8 port,
NvBool bCopyFrom
)
{
NvU32 numWords;
NvU32 numBytes;
NvU32 *pData = (NvU32 *)pBuf;
NvU32 reg32;
NvU32 i;
// simply return if the copy-size is zero
if (sizeBytes == 0)
{
NVSWITCH_PRINT(device, ERROR, "Zero-byte copy requested\n");
NVSWITCH_ASSERT(0);
return -NVL_BAD_ARGS;
}
// the DMEM address must be 4-byte aligned
if (!NV_IS_ALIGNED(dmemAddr, FLCN_DMEM_ACCESS_ALIGNMENT))
{
NVSWITCH_PRINT(device, ERROR, "Source not 4-byte aligned. dmemAddr=0x%08x\n", dmemAddr);
NVSWITCH_ASSERT(0);
return -NVL_BAD_ARGS;
}
// calculate the number of words and bytes
numWords = sizeBytes >> 2;
numBytes = sizeBytes & NVSWITCH_MASK_BITS(2);
// mask off all but the OFFSET and BLOCK in DMEM offset
reg32 = flcnSetDmemAddr_HAL(device, pFlcn, dmemAddr);
if (bCopyFrom)
{
// mark auto-increment on read
reg32 = FLD_SET_DRF_NUM(_PFALCON, _FALCON_DMEMC, _AINCR, 0x1, reg32);
}
else
{
// mark auto-increment on write
reg32 = FLD_SET_DRF_NUM(_PFALCON, _FALCON_DMEMC, _AINCW, 0x1, reg32);
}
flcnRegWrite_HAL(device, pFlcn, NV_PFALCON_FALCON_DMEMC(port), reg32);
// directly copy as many words as possible
for (i = 0; i < numWords; i++)
{
if (bCopyFrom)
{
pData[i] = flcnRegRead_HAL(device, pFlcn, NV_PFALCON_FALCON_DMEMD(port));
}
else
{
flcnRegWrite_HAL(device, pFlcn, NV_PFALCON_FALCON_DMEMD(port), pData[i]);
}
}
// Check if there are left over bytes to copy
if (numBytes > 0)
{
NvU32 bytesCopied = numWords << 2;
//
// Read the contents first. If we're copying to the DMEM, we've set
// autoincrement on write, so reading does not modify the pointer. We
// can, thus, do a read/modify/write without needing to worry about the
// pointer having moved forward. There is no special explanation needed
// if we're copying from the DMEM since this is the last access to HW
// in that case.
//
reg32 = flcnRegRead_HAL(device, pFlcn, NV_PFALCON_FALCON_DMEMD(port));
if (bCopyFrom)
{
// Copy byte-by-byte into the buffer as required
for (i = 0; i < numBytes; i++)
{
pBuf[bytesCopied + i] = ((NvU8 *)&reg32)[i];
}
}
else
{
// Modify what we read byte-by-byte before writing to dmem
for (i = 0; i < numBytes; i++)
{
((NvU8 *)&reg32)[i] = pBuf[bytesCopied + i];
}
flcnRegWrite_HAL(device, pFlcn, NV_PFALCON_FALCON_DMEMD(port), reg32);
}
}
return NVL_SUCCESS;
}
static void
_flcnDbgInfoCaptureRiscvPcTrace_LS10
(
nvswitch_device *device,
PFLCN pFlcn
)
{
NvU32 ctl, ridx, widx, count, bufferSize;
NvBool full;
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACECTL,
DRF_DEF(_PRISCV_RISCV, _TRACECTL, _MODE, _FULL) |
DRF_DEF(_PRISCV_RISCV, _TRACECTL, _UMODE_ENABLE, _TRUE) |
DRF_DEF(_PRISCV_RISCV, _TRACECTL, _MMODE_ENABLE, _TRUE) |
DRF_DEF(_PRISCV_RISCV, _TRACECTL, _INTR_ENABLE, _FALSE) |
DRF_DEF(_PRISCV_RISCV, _TRACECTL, _HIGH_THSHD, _INIT));
ctl = flcnRiscvRegRead_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACECTL);
full = FLD_TEST_DRF_NUM(_PRISCV_RISCV, _TRACECTL,_FULL, 1, ctl);
if (full)
{
NVSWITCH_PRINT(device, INFO, "%s: Trace buffer full. Entries may have been lost.\n", __FUNCTION__);
}
// Reset and disable buffer, we don't need it during dump
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACECTL, 0);
widx = flcnRiscvRegRead_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACE_WTIDX);
widx = DRF_VAL(_PRISCV_RISCV, _TRACE_WTIDX, _WTIDX, widx);
ridx = flcnRiscvRegRead_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACE_RDIDX);
bufferSize = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _MAXIDX, ridx);
ridx = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _RDIDX, ridx);
count = widx > ridx ? widx - ridx : bufferSize + widx - ridx;
//
// Trace buffer is full when write idx == read idx and full is set,
// otherwise it is empty.
//
if (widx == ridx && !full)
count = 0;
if (count)
{
NvU32 entry;
NVSWITCH_PRINT(device, INFO, "%s: Tracebuffer has %d entries. Starting with latest.\n", __FUNCTION__, count);
ridx = widx;
for (entry = 0; entry < count; ++entry)
{
NvU64 pc;
ridx = ridx > 0 ? ridx - 1 : bufferSize - 1;
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACE_RDIDX, DRF_NUM(_PRISCV_RISCV, _TRACE_RDIDX, _RDIDX, ridx));
pc = flcnRiscvRegRead_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACEPC_HI);
pc = (pc << 32) | flcnRiscvRegRead_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACEPC_LO);
NVSWITCH_PRINT(device, INFO, "%s: TRACE[%d] = 0x%16llx\n", __FUNCTION__, entry, pc);
}
}
else
{
NVSWITCH_PRINT(device, INFO, "%s: Trace buffer is empty.\n", __FUNCTION__);
}
// reset trace buffer
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACE_RDIDX, 0);
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACE_WTIDX, 0);
// Clear full and empty bits
ctl = FLD_SET_DRF_NUM(_PRISCV_RISCV, _TRACECTL, _FULL, 0, ctl);
ctl = FLD_SET_DRF_NUM(_PRISCV_RISCV, _TRACECTL, _EMPTY, 0, ctl);
flcnRiscvRegWrite_HAL(device, pFlcn, NV_PRISCV_RISCV_TRACECTL, ctl);
}
/**
* @brief set hal function pointers for functions defined in
* LS10 (i.e. this file)
*
* this function has to be at the end of the file so that all the
* other functions are already defined.
*
* @param[in] pFlcn The flcn for which to set hals
*/
void
flcnSetupHal_LS10
(
PFLCN pFlcn
)
{
flcn_hal *pHal = pFlcn->pHal;
flcnSetupHal_LR10(pFlcn);
pHal->riscvRegRead = _flcnRiscvRegRead_LS10;
pHal->riscvRegWrite = _flcnRiscvRegWrite_LS10;
pHal->dmemTransfer = _flcnDmemTransfer_LS10;
pHal->setDmemAddr = _flcnSetDmemAddr_LS10;
pHal->imemCopyTo = _flcnImemCopyTo_LS10;
pHal->setImemAddr = _flcnSetImemAddr_LS10;
pHal->dmemSize = _flcnDmemSize_LS10;
pHal->dbgInfoCaptureRiscvPcTrace = _flcnDbgInfoCaptureRiscvPcTrace_LS10;
}

View File

@@ -0,0 +1,257 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "ls10/inforom_ls10.h"
#include "inforom/ifrstruct.h"
#include "soe/soeififr.h"
#include "rmsoecmdif.h"
#include "flcn/flcn_nvswitch.h"
#include "rmflcncmdif_nvswitch.h"
NvlStatus
nvswitch_inforom_nvl_log_error_event_ls10
(
nvswitch_device *device,
void *pNvlGeneric,
void *pNvlErrorEvent,
NvBool *bDirty
)
{
return -NVL_ERR_NOT_IMPLEMENTED;
}
NvlStatus nvswitch_inforom_nvl_update_link_correctable_error_info_ls10
(
nvswitch_device *device,
void *pNvlGeneric,
void *pData,
NvU8 linkId,
NvU8 nvliptInstance,
NvU8 localLinkIdx,
void *pNvlErrorCounts,
NvBool *bDirty
)
{
return -NVL_ERR_NOT_IMPLEMENTED;
}
NvlStatus
nvswitch_oms_inforom_flush_ls10
(
nvswitch_device *device
)
{
return -NVL_ERR_NOT_IMPLEMENTED;
}
void
nvswitch_initialize_oms_state_ls10
(
nvswitch_device *device,
INFOROM_OMS_STATE *pOmsState
)
{
return;
}
NvBool
nvswitch_oms_get_device_disable_ls10
(
INFOROM_OMS_STATE *pOmsState
)
{
return NV_FALSE;
}
void
nvswitch_oms_set_device_disable_ls10
(
INFOROM_OMS_STATE *pOmsState,
NvBool bForceDeviceDisable
)
{
return;
}
void
nvswitch_inforom_ecc_get_total_errors_ls10
(
nvswitch_device *device,
INFOROM_ECC_OBJECT *pEccGeneric,
NvU64 *pCorrectedTotal,
NvU64 *pUncorrectedTotal
)
{
return;
}
NvlStatus
nvswitch_bbx_add_sxid_ls10
(
nvswitch_device *device,
NvU32 exceptionType,
NvU32 data0,
NvU32 data1,
NvU32 data2
)
{
NvlStatus status;
FLCN *pFlcn;
RM_FLCN_CMD_SOE bbxCmd;
NvU32 cmdSeqDesc;
NVSWITCH_TIMEOUT timeout;
if (!nvswitch_is_inforom_supported_ls10(device))
{
NVSWITCH_PRINT(device, INFO, "InfoROM is not supported, skipping\n");
return NVL_SUCCESS;
}
// Avoid logging SOE related SXIDs to prevent recursive errors
if (exceptionType > NVSWITCH_ERR_HW_SOE && exceptionType < NVSWITCH_ERR_HW_SOE_LAST)
{
NVSWITCH_PRINT(device, INFO, "Not logging SXID: %d to InfoROM\n", exceptionType);
return NVL_SUCCESS;
}
pFlcn = device->pSoe->pFlcn;
nvswitch_timeout_create(NVSWITCH_INTERVAL_5MSEC_IN_NS, &timeout);
nvswitch_os_memset(&bbxCmd, 0, sizeof(bbxCmd));
bbxCmd.hdr.unitId = RM_SOE_UNIT_IFR;
bbxCmd.hdr.size = sizeof(bbxCmd);
bbxCmd.cmd.ifr.cmdType = RM_SOE_IFR_BBX_SXID_ADD;
bbxCmd.cmd.ifr.bbxSxidAdd.exceptionType = exceptionType;
bbxCmd.cmd.ifr.bbxSxidAdd.data[0] = data0;
bbxCmd.cmd.ifr.bbxSxidAdd.data[1] = data1;
bbxCmd.cmd.ifr.bbxSxidAdd.data[2] = data2;
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&bbxCmd,
NULL, // pMsg
NULL, // pPayload
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: BBX cmd %d failed. rc:%d\n",
__FUNCTION__, bbxCmd.cmd.ifr.cmdType, status);
}
return status;
}
NvlStatus
nvswitch_bbx_unload_ls10
(
nvswitch_device *device
)
{
NvlStatus status;
FLCN *pFlcn;
RM_FLCN_CMD_SOE bbxCmd;
NvU32 cmdSeqDesc;
NVSWITCH_TIMEOUT timeout;
pFlcn = device->pSoe->pFlcn;
nvswitch_timeout_create(NVSWITCH_INTERVAL_750MSEC_IN_NS, &timeout);
nvswitch_os_memset(&bbxCmd, 0, sizeof(bbxCmd));
bbxCmd.hdr.unitId = RM_SOE_UNIT_IFR;
bbxCmd.hdr.size = sizeof(bbxCmd);
bbxCmd.cmd.ifr.cmdType = RM_SOE_IFR_BBX_SHUTDOWN;
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&bbxCmd,
NULL, // pMsg
NULL, // pPayload
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: BBX cmd %d failed. rc:%d\n",
__FUNCTION__, bbxCmd.cmd.ifr.cmdType, status);
}
return status;
}
NvlStatus
nvswitch_bbx_load_ls10
(
nvswitch_device *device,
NvU64 time_ns,
NvU8 osType,
NvU32 osVersion
)
{
NvlStatus status;
FLCN *pFlcn;
RM_FLCN_CMD_SOE bbxCmd;
NvU32 cmdSeqDesc = 0;
NVSWITCH_TIMEOUT timeout;
pFlcn = device->pSoe->pFlcn;
nvswitch_timeout_create(NVSWITCH_INTERVAL_750MSEC_IN_NS, &timeout);
nvswitch_os_memset(&bbxCmd, 0, sizeof(bbxCmd));
bbxCmd.hdr.unitId = RM_SOE_UNIT_IFR;
bbxCmd.hdr.size = sizeof(bbxCmd);
bbxCmd.cmd.ifr.cmdType = RM_SOE_IFR_BBX_INITIALIZE;
bbxCmd.cmd.ifr.bbxInit.osType = osType;
bbxCmd.cmd.ifr.bbxInit.osVersion = osVersion;
RM_FLCN_U64_PACK(&bbxCmd.cmd.ifr.bbxInit.time, &time_ns);
NVSWITCH_PRINT(device, INFO, "RM_SOE_IFR_BBX_INITIALIZE called, time_ns=%llu \n", time_ns);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&bbxCmd,
NULL, // pMsg
NULL, // pPayload
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: BBX cmd %d failed. rc:%d\n",
__FUNCTION__, bbxCmd.cmd.ifr.cmdType, status);
}
return status;
}
NvlStatus
nvswitch_bbx_get_sxid_ls10
(
nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS *params
)
{
return -NVL_ERR_NOT_SUPPORTED;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,975 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "nvlink_export.h"
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "ls10/minion_ls10.h"
#include "ls10/minion_nvlink_defines_public_ls10.h"
#include "regkey_nvswitch.h"
#include "nvswitch/ls10/dev_minion_ip.h"
#include "nvswitch/ls10/dev_minion_ip_addendum.h"
#include "nvswitch/ls10/dev_ingress_ip.h"
#include "nvswitch/ls10/dev_egress_ip.h"
#include "nvswitch/ls10/dev_riscv_pri.h"
#include "nvswitch/ls10/dev_nvlphyctl_ip.h"
#include "flcn/flcn_nvswitch.h"
/*
* @Brief : Check if MINION is already running.
*
* The function assumes that if one of MINIONs is running, all of them are
* running. This approach needs to be fixed.
*
* TODO: Refactor minion code to check for each minion's status individually.
*
* @param[in] device Bootstrap MINIONs on this device
*/
static NvBool
_nvswitch_check_running_minions
(
nvswitch_device *device
)
{
NvU32 data, i;
NvBool bMinionRunning = NV_FALSE;
for (i = 0; i < NUM_MINION_ENGINE_LS10; i++)
{
if (!NVSWITCH_ENG_VALID_LS10(device, MINION, i))
{
NVSWITCH_PRINT(device, SETUP,
"%s: MINION instance %d is not valid.\n",
__FUNCTION__, i);
continue;
}
data = NVSWITCH_MINION_RD32_LS10(device, i, _CMINION, _FALCON_IRQSTAT);
if (FLD_TEST_DRF(_CMINION, _FALCON_IRQSTAT, _HALT, _FALSE, data))
{
data = NVSWITCH_MINION_RD32_LS10(device, i, _MINION, _MINION_STATUS);
if (FLD_TEST_DRF(_MINION, _MINION_STATUS, _STATUS, _BOOT, data))
{
//
// Set initialized flag if MINION is running.
// We don't want to bootstrap a falcon that is already running.
//
nvswitch_set_minion_initialized(device, i, NV_TRUE);
NVSWITCH_PRINT(device, SETUP,
"%s: MINION instance %d is already bootstrapped.\n",
__FUNCTION__, i);
bMinionRunning = NV_TRUE;
}
}
}
return bMinionRunning;
}
NvlStatus
nvswitch_minion_get_dl_status_ls10
(
nvswitch_device *device,
NvU32 linkId,
NvU32 statusIdx,
NvU32 statusArgs,
NvU32 *statusData
)
{
NVSWITCH_TIMEOUT timeout;
NvBool keepPolling;
NvU32 regData, localLinkNumber;
localLinkNumber = linkId % NVSWITCH_LINKS_PER_MINION_LS10;
if (NVSWITCH_IS_LINK_ENG_VALID_LS10(device, MINION, linkId) &&
!nvswitch_is_minion_initialized(device, NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION)))
{
NVSWITCH_PRINT(device, ERROR,
"%s: MINION %d is not initialized for link %08x.\n",
__FUNCTION__, NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION),
linkId);
return -NVL_ERR_INVALID_STATE;
}
// Query the DL status interface to get the data
NVSWITCH_MINION_LINK_WR32_LS10(device, linkId, _MINION, _NVLINK_DL_STAT(localLinkNumber),
DRF_NUM(_MINION, _NVLINK_DL_STAT, _ARGS, statusArgs) |
DRF_NUM(_MINION, _NVLINK_DL_STAT, _STATUSIDX, statusIdx));
if (IS_FMODEL(device) || IS_EMULATION(device) || IS_RTLSIM(device))
{
nvswitch_timeout_create(20 * NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
}
else
{
nvswitch_timeout_create(NVSWITCH_INTERVAL_5MSEC_IN_NS, &timeout);
}
// Poll for READY bit to be set
do
{
keepPolling = (nvswitch_timeout_check(&timeout)) ? NV_FALSE : NV_TRUE;
regData = NVSWITCH_MINION_LINK_RD32_LS10(device, linkId, _MINION, _NVLINK_DL_STAT(localLinkNumber));
if (FLD_TEST_DRF_NUM(_MINION, _NVLINK_DL_STAT, _READY, 1, regData))
{
*statusData = NVSWITCH_MINION_LINK_RD32_LS10(device, linkId, _MINION, _NVLINK_DL_STATDATA(localLinkNumber));
return NVL_SUCCESS;
}
if (IS_FMODEL(device) || IS_RTLSIM(device))
{
nvswitch_os_sleep(1);
}
}
while (keepPolling);
NVSWITCH_PRINT(device, ERROR,
"%s: Timeout waiting for DL_STAT request to complete"
" NV_MINION_NVLINK_DL_STAT(%d) = 0x%08x\n",
__FUNCTION__, linkId, regData);
return -NVL_ERR_INVALID_STATE;
}
/*
* @Brief : Send MINION DL CMD for a particular link
*
* @param[in] device Send command to MINION on this device
* @param[in] linkNumber DLCMD will be sent on this link number
*
* @return Returns true if the DLCMD passed
*/
NvlStatus
nvswitch_minion_send_command_ls10
(
nvswitch_device *device,
NvU32 linkNumber,
NvU32 command,
NvU32 scratch0
)
{
NvU32 data = 0, localLinkNumber, statData = 0;
NvU32 ingressEccRegVal = 0, egressEccRegVal = 0;
NVSWITCH_TIMEOUT timeout;
NvBool keepPolling;
localLinkNumber = linkNumber % NVSWITCH_LINKS_PER_MINION_LS10;
if (NVSWITCH_IS_LINK_ENG_VALID_LS10(device, MINION, linkNumber) &&
!nvswitch_is_minion_initialized(device, NVSWITCH_GET_LINK_ENG_INST(device, linkNumber, MINION)))
{
NVSWITCH_PRINT(device, ERROR,
"%s: MINION %d is not initialized for link %08x.\n",
__FUNCTION__, NVSWITCH_GET_LINK_ENG_INST(device, linkNumber, MINION),
linkNumber);
return NVL_SUCCESS;
}
data = NVSWITCH_MINION_LINK_RD32_LS10(device, linkNumber, _MINION, _NVLINK_DL_CMD(localLinkNumber));
if (FLD_TEST_DRF_NUM(_MINION, _NVLINK_DL_CMD, _FAULT, 1, data))
{
NVSWITCH_PRINT(device, ERROR,
"%s: MINION %d is in fault state. NV_MINION_NVLINK_DL_CMD(%d) = %08x\n",
__FUNCTION__, NVSWITCH_GET_LINK_ENG_INST(device, linkNumber, MINION),
linkNumber, data);
return -NVL_ERR_GENERIC;
}
// Write to minion scratch if needed by command
switch (command)
{
case NV_MINION_NVLINK_DL_CMD_COMMAND_CONFIGEOM:
data = 0;
data = FLD_SET_DRF_NUM(_MINION, _MISC_0, _SCRATCH_SWRW_0, scratch0, data);
NVSWITCH_MINION_WR32_LS10(device,
NVSWITCH_GET_LINK_ENG_INST(device, linkNumber, MINION), _MINION, _MISC_0, data);
break;
case NV_MINION_NVLINK_DL_CMD_COMMAND_INITPHASE1:
//
// WAR bug 2708497
// Before INITPHASE1, we must clear these values, then set back to
// _PROD after the call
// NV_INGRESS_ERR_ECC_CTRL_NCISOC_PARITY_ENABLE
// NV_EGRESS_ERR_ECC_CTRL_NCISOC_PARITY_ENABLE
//
ingressEccRegVal = NVSWITCH_NPORT_RD32_LS10(device, linkNumber, _INGRESS, _ERR_ECC_CTRL);
NVSWITCH_NPORT_WR32_LS10(device, linkNumber, _INGRESS, _ERR_ECC_CTRL,
FLD_SET_DRF(_INGRESS, _ERR_ECC_CTRL, _NCISOC_PARITY_ENABLE, _DISABLE, ingressEccRegVal));
egressEccRegVal = NVSWITCH_NPORT_RD32_LS10(device, linkNumber, _EGRESS, _ERR_ECC_CTRL);
NVSWITCH_NPORT_WR32_LS10(device, linkNumber, _EGRESS, _ERR_ECC_CTRL,
FLD_SET_DRF(_EGRESS, _ERR_ECC_CTRL, _NCISOC_PARITY_ENABLE, _DISABLE, egressEccRegVal));
break;
default:
break;
}
data = FLD_SET_DRF_NUM(_MINION, _NVLINK_DL_CMD, _COMMAND, command, data);
data = FLD_SET_DRF_NUM(_MINION, _NVLINK_DL_CMD, _FAULT, 1, data);
NVSWITCH_MINION_LINK_WR32_LS10(device, linkNumber, _MINION, _NVLINK_DL_CMD(localLinkNumber), data);
if (IS_FMODEL(device) || IS_EMULATION(device) || IS_RTLSIM(device))
{
nvswitch_timeout_create(10 * NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
}
else
{
nvswitch_timeout_create(NVSWITCH_INTERVAL_5MSEC_IN_NS, &timeout);
}
//
// We will exit this if the command is successful OR
// if timeout waiting for the READY bit to be set OR
// if it generates a MINION FAULT
//
do
{
keepPolling = (nvswitch_timeout_check(&timeout)) ? NV_FALSE : NV_TRUE;
data = NVSWITCH_MINION_LINK_RD32_LS10(device, linkNumber, _MINION, _NVLINK_DL_CMD(localLinkNumber));
if (FLD_TEST_DRF_NUM(_MINION, _NVLINK_DL_CMD, _READY, 1, data))
{
// The command has completed, success?
if (FLD_TEST_DRF_NUM(_MINION, _NVLINK_DL_CMD, _FAULT, 1, data))
{
NVSWITCH_PRINT(device, ERROR,
"%s: NVLink MINION command faulted!"
" NV_MINION_NVLINK_DL_CMD(%d) = 0x%08x\n",
__FUNCTION__, linkNumber, data);
// Pull fault code and subcode
if (nvswitch_minion_get_dl_status(device, linkNumber,
NV_NVLSTAT_MN00, 0, &statData) == NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Minion DLCMD Fault code = 0x%x, Sub-code = 0x%x\n",
__FUNCTION__,
DRF_VAL(_NVLSTAT, _MN00, _LINK_INTR_CODE, statData),
DRF_VAL(_NVLSTAT, _MN00, _LINK_INTR_SUBCODE, statData));
}
else
{
NVSWITCH_PRINT(device, ERROR,
"%s: Failed to get code and subcode from DLSTAT, link %d\n",
__FUNCTION__, linkNumber);
}
// Clear the fault and return
NVSWITCH_PRINT(device, ERROR,
"%s: Clearing NVLink MINION fault for link %d\n",
__FUNCTION__, linkNumber);
data = FLD_SET_DRF_NUM(_MINION, _NVLINK_DL_CMD, _FAULT, 1, 0x0);
NVSWITCH_MINION_LINK_WR32_LS10(device, linkNumber, _MINION, _NVLINK_DL_CMD(localLinkNumber), data);
return -NVL_ERR_INVALID_STATE;
}
else
{
NVSWITCH_PRINT(device, SETUP,
"%s: NVLink MINION command %x was sent successfully for link %d\n",
__FUNCTION__, command, linkNumber);
break;
}
}
nvswitch_os_sleep(1);
}
while (keepPolling);
if (!FLD_TEST_DRF_NUM(_MINION, _NVLINK_DL_CMD, _READY, 1, data))
{
NVSWITCH_PRINT(device, ERROR,
"%s: Timeout waiting for NVLink MINION command to complete!"
" NV_MINION_NVLINK_DL_CMD(%d) = 0x%08x\n",
__FUNCTION__, linkNumber, data);
return -NVL_ERR_INVALID_STATE;
}
if (command == NV_MINION_NVLINK_DL_CMD_COMMAND_INITPHASE1)
{
NVSWITCH_NPORT_WR32_LS10(device, linkNumber, _INGRESS, _ERR_ECC_CTRL, ingressEccRegVal);
NVSWITCH_NPORT_WR32_LS10(device, linkNumber, _EGRESS, _ERR_ECC_CTRL, egressEccRegVal);
}
return NVL_SUCCESS;
}
/*
* @Brief : Bootstrap all MINIONs on the specified device
*
* @param[in] device Bootstrap MINIONs on this device
*/
NvlStatus
nvswitch_init_minion_ls10
(
nvswitch_device *device
)
{
NvlStatus status = NVL_SUCCESS;
if (_nvswitch_check_running_minions(device))
{
return NVL_SUCCESS;
}
status = -NVL_INITIALIZATION_TOTAL_FAILURE;
return status;
}
NvlStatus
nvswitch_set_minion_initialized_ls10
(
nvswitch_device *device,
NvU32 idx_minion,
NvBool initialized
)
{
ls10_device *chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
if (!NVSWITCH_ENG_VALID_LS10(device, MINION, idx_minion))
{
return -NVL_BAD_ARGS;
}
chip_device->engMINION[idx_minion].initialized = initialized;
return NVL_SUCCESS;
}
NvBool
nvswitch_is_minion_initialized_ls10
(
nvswitch_device *device,
NvU32 idx_minion
)
{
ls10_device *chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
if (!NVSWITCH_ENG_VALID_LS10(device, MINION, idx_minion))
{
return NV_FALSE;
}
return (chip_device->engMINION[idx_minion].initialized != 0);
}
NvlStatus
nvswitch_minion_set_sim_mode_ls10
(
nvswitch_device *device,
nvlink_link *link
)
{
NvlStatus status = NVL_SUCCESS;
NvU32 dlcmd;
NvU32 linkNumber = link->linkNumber;
NvU32 localLinkNumber = linkNumber % NVSWITCH_LINKS_PER_MINION_LS10;
switch (device->regkeys.set_simmode)
{
case NV_SWITCH_REGKEY_MINION_SET_SIMMODE_FAST:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_FAST;
break;
case NV_SWITCH_REGKEY_MINION_SET_SIMMODE_MEDIUM:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_MEDIUM;
break;
case NV_SWITCH_REGKEY_MINION_SET_SIMMODE_SLOW:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_SLOW;
break;
default:
return NVL_SUCCESS;
}
status = nvswitch_minion_send_command(device, linkNumber, dlcmd, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: DLCMD 0x%x failed on link: %d\n",
__FUNCTION__, dlcmd, linkNumber);
return status;
}
// Setting RXCAL_EN_ALARM timer value
NVSWITCH_MINION_LINK_WR32_LS10(device, linkNumber, _MINION,
_NVLINK_DL_CMD_DATA(localLinkNumber),
NV_MINION_DL_CMD_DATA_RXCAL_EN_ALARM);
status = nvswitch_minion_send_command(device, linkNumber,
NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_RXCAL_EN_ALARM, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: DLCMD DBG_SETSIMMODE_RXCAL_EN_ALARM failed on link: %d\n",
__FUNCTION__, linkNumber);
return status;
}
// Setting INIT_CAL_DONE timer value
NVSWITCH_MINION_LINK_WR32_LS10(device, linkNumber, _MINION,
_NVLINK_DL_CMD_DATA(localLinkNumber),
NV_MINION_DL_CMD_DATA_INIT_CAL_DONE);
status = nvswitch_minion_send_command(device, linkNumber,
NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_INIT_CAL_DONE, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: DLCMD DBG_SETSIMMODE_INIT_CAL_DONE failed on link: %d\n",
__FUNCTION__, linkNumber);
return status;
}
return status;
}
NvlStatus
nvswitch_minion_set_smf_settings_ls10
(
nvswitch_device *device,
nvlink_link *link
)
{
NvlStatus status = NVL_SUCCESS;
NvU32 dlcmd;
NvU32 linkNumber = link->linkNumber;
switch (device->regkeys.set_smf_settings)
{
case NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_SLOW:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_SMF_VALUES_SLOW;
break;
case NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_MEDIUM:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_SMF_VALUES_MEDIUM;
break;
case NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_FAST:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_SMF_VALUES_FAST;
break;
case NV_SWITCH_REGKEY_MINION_SET_SMF_SETTINGS_MEDIUM_SERIAL:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_SMF_VALUES_MEDIUM_SERIAL;
break;
default:
return NVL_SUCCESS;
}
status = nvswitch_minion_send_command(device, linkNumber, dlcmd, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: DLCMD 0x%x failed on link: %d\n",
__FUNCTION__, dlcmd, linkNumber);
return status;
}
return status;
}
NvlStatus
nvswitch_minion_select_uphy_tables_ls10
(
nvswitch_device *device,
nvlink_link *link
)
{
NvlStatus status = NVL_SUCCESS;
NvU32 dlcmd;
NvU32 linkNumber = link->linkNumber;
switch (device->regkeys.select_uphy_tables)
{
case NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES_SHORT:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_UPHY_TABLES_SHORT;
break;
case NV_SWITCH_REGKEY_MINION_SELECT_UPHY_TABLES_FAST:
dlcmd = NV_MINION_NVLINK_DL_CMD_COMMAND_DBG_SETSIMMODE_UPHY_TABLES_FAST;
break;
default:
return NVL_SUCCESS;
}
status = nvswitch_minion_send_command(device, linkNumber, dlcmd, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: DLCMD 0x%x failed on link: %d\n",
__FUNCTION__, dlcmd, linkNumber);
return status;
}
return status;
}
NvlStatus
nvswitch_minion_get_rxdet_status_ls10
(
nvswitch_device *device,
NvU32 linkId
)
{
NvU32 statData;
NvlStatus status;
NVSWITCH_TIMEOUT timeout;
NvBool keepPolling;
if (IS_FMODEL(device) || IS_EMULATION(device) || IS_RTLSIM(device))
{
nvswitch_timeout_create(30*NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
}
else
{
nvswitch_timeout_create(20 * NVSWITCH_INTERVAL_1MSEC_IN_NS, &timeout);
}
// Poll for READY bit to be set
do
{
keepPolling = (nvswitch_timeout_check(&timeout)) ? NV_FALSE : NV_TRUE;
// Check RXDET status on MINION DL STAT interface
status = nvswitch_minion_get_dl_status(device, linkId, NV_NVLSTAT_LNK2, 0, &statData);
if (status != NVL_SUCCESS)
{
return status;
}
if (FLD_TEST_DRF(_NVLSTAT, _LNK2, _RXDET_LINK_STATUS, _FOUND, statData))
{
NVSWITCH_PRINT(device, INFO,
"%s: RXDET LINK_STATUS = FOUND on link: %d\n",
__FUNCTION__, linkId);
// Retrieve which lanes were found (should be all)
device->link[linkId].lane_rxdet_status_mask =
DRF_VAL(_NVLSTAT, _LNK2, _RXDET_LANE_STATUS, statData);
//
// MINION doesn't have knowledge of lane reversal and therefore
// reports logical lanes. We must reverse the bitmask here if applicable
// since RM reports physical lanes.
//
if (nvswitch_link_lane_reversed_lr10(device, linkId))
{
NVSWITCH_REVERSE_BITMASK_32(NVSWITCH_NUM_LANES_LS10,
device->link[linkId].lane_rxdet_status_mask);
}
return NVL_SUCCESS;
}
if (FLD_TEST_DRF(_NVLSTAT, _LNK2, _RXDET_LINK_STATUS, _TIMEOUT, statData))
{
NVSWITCH_PRINT(device, ERROR,
"%s: RXDET LINK_STATUS = TIMEOUT on link: %d\n",
__FUNCTION__, linkId);
// Retrieve which lanes were found
device->link[linkId].lane_rxdet_status_mask =
DRF_VAL(_NVLSTAT, _LNK2, _RXDET_LANE_STATUS, statData);
//
// MINION doesn't have knowledge of lane reversal and therefore
// reports logical lanes. We must reverse the bitmask here if applicable
// since RM reports physical lanes.
//
if (nvswitch_link_lane_reversed_lr10(device, linkId))
{
NVSWITCH_REVERSE_BITMASK_32(NVSWITCH_NUM_LANES_LS10,
device->link[linkId].lane_rxdet_status_mask);
}
return -NVL_ERR_INVALID_STATE;
}
nvswitch_os_sleep(1);
}
while (keepPolling);
NVSWITCH_PRINT(device, ERROR,
"%s: Timeout waiting for RXDET STATUS on link: %d\n",
__FUNCTION__, linkId);
return -NVL_ERR_INVALID_STATE;
}
/*
* @Brief : Check if the RISCV CPU has started
*
* @param[in] device The Nvswitch device
* @param[in] idx_minion MINION instance to use
*/
NvBool
nvswitch_minion_is_riscv_active_ls10
(
nvswitch_device *device,
NvU32 idx_minion
)
{
NvU32 val;
val = NVSWITCH_MINION_RD32_LS10(device, idx_minion, _CMINION_RISCV, _CPUCTL);
return FLD_TEST_DRF(_CMINION, _RISCV_CPUCTL, _ACTIVE_STAT, _ACTIVE, val);
}
NvlStatus
nvswitch_minion_clear_dl_error_counters_ls10
(
nvswitch_device *device,
NvU32 linkId
)
{
NvlStatus status;
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_DLSTAT_CLR_DLERRCNT, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s : Failed to clear error count to MINION for link # %d\n",
__FUNCTION__, linkId);
}
return status;
}
NvlStatus
nvswitch_minion_send_inband_data_ls10
(
nvswitch_device *device,
NvU32 linkId,
nvswitch_inband_send_data *inBandData
)
{
NvlStatus status = NVL_SUCCESS;
#if defined(INCLUDE_NVLINK_LIB)
NvlStatus tempStatus = NVL_SUCCESS;
NvU32 localLinkNumber = linkId % NVSWITCH_LINKS_PER_MINION_LS10;
NvU8 *sendBuffer = inBandData->sendBuffer;
NvU32 bufferSize = inBandData->bufferSize;
NvU32 data = 0;
NvU32 regval = 0;
NvU32 statData = 0;
NVSWITCH_TIMEOUT timeout;
NvBool bKeepPolling = NV_TRUE;
if (bufferSize == 0 || bufferSize > NVLINK_INBAND_MAX_XFER_SIZE)
{
NVSWITCH_PRINT(device, ERROR, "Bad Inband data size %d. Skipping Inband Send\n", bufferSize);
return -NVL_ERR_INVALID_STATE;
}
// Buffer Size must be reduced by 1 as per the minion protocol
regval = DRF_NUM(_MINION, _INBAND_SEND_DATA, _BUFFER_SIZE, (bufferSize - 1));
regval |= DRF_NUM(_MINION, _INBAND_SEND_DATA, _FLAGS,inBandData->hdr.data);
NVSWITCH_MINION_WR32_LS10(device,
NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION),
_MINION, _NVLINK_DL_CMD_DATA(localLinkNumber),
regval);
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_WRITE_TX_BUFFER_START, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer for TX_BUFFER_START failed\n", linkId);
return status;
}
while (bufferSize != 0)
{
nvswitch_os_memcpy(&data, sendBuffer, NV_MIN(sizeof(data), bufferSize));
NVSWITCH_MINION_WR32_LS10(device,
NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION),
_MINION, _NVLINK_DL_CMD_DATA(localLinkNumber),
data);
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_WRITE_TX_BUFFER_MIDDLE, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer failed\n", linkId);
goto clear_buffer;
}
bufferSize -= NV_MIN(sizeof(data), bufferSize);
sendBuffer += NV_MIN(sizeof(data), bufferSize);
}
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_WRITE_TX_BUFFER_END, 0);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer for TX_BUFFER_END\n", linkId);
goto clear_buffer;
}
// Wait for buffer complete or buffer fail
nvswitch_timeout_create(2 * NVSWITCH_INTERVAL_4SEC_IN_NS, &timeout);
do
{
bKeepPolling = !nvswitch_timeout_check(&timeout);
// DLSTAT need to explicitly checked
status = nvswitch_minion_get_dl_status(device, linkId, NV_NVLSTAT_UC01, 0, &statData);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO,"%s : Failed to poll DLSTAT register for (%s):(%d)\n",
__FUNCTION__, device->name, linkId);
status = -NVL_ERR_INVALID_STATE;
goto clear_buffer;
}
if (FLD_TEST_DRF(_NVLSTAT, _UC01, _INBAND_BUFFER_COMPLETE, _TRUE, statData))
{
return NVL_SUCCESS;
}
if (FLD_TEST_DRF(_NVLSTAT, _UC01, _INBAND_BUFFER_FAIL, _TRUE, statData))
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer BUFFER_FAILED\n", linkId);
status = -NVL_ERR_INVALID_STATE;
goto clear_buffer;
}
//
// Consider a case where both FM and RM trying to write on the same NVLink at the same time.
// Both are waiting on each other to read the buffer, but they have also blocked the ISR,
// as while waiting they hold the device lock. Thus, it is necessary to unblock one of them.
// And to do that we have service BUFFER_AVAILABLE while waiting.
//
nvswitch_service_minion_all_links_ls10(device);
nvswitch_os_sleep(10);
} while (bKeepPolling);
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Neither got BUFFER_FAIL nor BUFFER_COMPLETE\n", linkId);
clear_buffer:
tempStatus = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_CLEAR_TX_BUFFER,
0);
if (tempStatus != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer for TX_BUFFER_CLEAR\n", linkId);
return status;
}
// Check if we received BUFFER_COMPLETE is seen while doing a BUFFER_CLEAR
tempStatus = nvswitch_minion_get_dl_status(device, linkId, NV_NVLSTAT_UC01, 0, &statData);
if (tempStatus != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO,"%s : Failed to poll DLSTAT register for (%s):(%d)\n",
__FUNCTION__, device->name, linkId);
return status;
}
if (FLD_TEST_DRF(_NVLSTAT, _UC01, _INBAND_BUFFER_COMPLETE, _TRUE, statData))
{
status = NVL_SUCCESS;
}
else
{
status = bKeepPolling ? status: -NVL_ERR_STATE_IN_USE;
}
#endif
return status;
}
void
nvswitch_minion_receive_inband_data_ls10
(
nvswitch_device *device,
NvU32 linkId
)
{
NvlStatus status = NVL_SUCCESS;
#if defined(INCLUDE_NVLINK_LIB)
NvlStatus tempStatus = NVL_SUCCESS;
NvU32 numEntries = 0;
NvU32 i;
NvU32 localLinkNumber = linkId % NVSWITCH_LINKS_PER_MINION_LS10;
NvU8 *receiveBuffer;
NvU32 regVal, dataSize, remainingBuffer, bytesToXfer;
nvlink_inband_drv_hdr_t hdr;
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_READ_RX_BUFFER_START,
0);
if (status != NV_OK)
goto cleanup;
regVal = NVSWITCH_MINION_RD32_LS10(device,
NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION),
_MINION, _NVLINK_DL_CMD_DATA(localLinkNumber));
// Add 1 to the data as per minion protocol
dataSize = DRF_VAL(_MINION, _INBAND_SEND_DATA, _BUFFER_SIZE, regVal) + 1;
hdr.data = DRF_VAL(_MINION, _INBAND_SEND_DATA, _FLAGS, regVal);
numEntries = NV_ALIGN_UP(dataSize, NVLINK_INBAND_MAX_XFER_AT_ONCE)/
NVLINK_INBAND_MAX_XFER_AT_ONCE;
remainingBuffer = dataSize;
if ((hdr.data & (NVLINK_INBAND_DRV_HDR_TYPE_START |
NVLINK_INBAND_DRV_HDR_TYPE_MID |
NVLINK_INBAND_DRV_HDR_TYPE_END)) == 0)
{
NVSWITCH_PRINT(device, ERROR, "InBand: HDR is wrong\n");
goto cleanup;
}
if (hdr.data & NVLINK_INBAND_DRV_HDR_TYPE_START)
{
if (device->link[linkId].inbandData.message != NULL)
{
NVSWITCH_PRINT(device, ERROR, "InBand: Got TYPE_START for existing data\n");
NVSWITCH_ASSERT(0);
goto cleanup;
}
device->link[linkId].inbandData.message =
nvswitch_os_malloc(sizeof(nvswitch_inband_data_list));
if (device->link[linkId].inbandData.message == NULL)
{
status = -NVL_NO_MEM;
goto cleanup;
}
device->link[linkId].inbandData.message->dataSize = 0;
}
if (device->link[linkId].inbandData.message == NULL)
{
NVSWITCH_PRINT(device, ERROR, "InBand: Data being sent without _START\n");
goto cleanup;
}
receiveBuffer = device->link[linkId].inbandData.message->data;
receiveBuffer += device->link[linkId].inbandData.message->dataSize;
if (((dataSize + device->link[linkId].inbandData.message->dataSize) >
NVSWITCH_INBAND_DATA_SIZE) ||
(dataSize > NVLINK_INBAND_MAX_XFER_SIZE) ||
(dataSize == 0))
{
NVSWITCH_PRINT(device, ERROR, "InBand: Msg is of wrong Size :DataSize = %d Msg Size= %d\n",
dataSize, device->link[linkId].inbandData.message->dataSize);
NVSWITCH_ASSERT(0);
goto cleanup;
}
for (i = 0; i < numEntries; i++)
{
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_READ_RX_BUFFER_MIDDLE, 0);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer receive"
"for entry %d failed\n", linkId, i);
goto cleanup;
}
regVal = NVSWITCH_MINION_RD32_LS10(device,
NVSWITCH_GET_LINK_ENG_INST(device, linkId, MINION),
_MINION, _NVLINK_DL_CMD_DATA(localLinkNumber));
bytesToXfer = NV_MIN(remainingBuffer, NVLINK_INBAND_MAX_XFER_AT_ONCE);
nvswitch_os_memcpy(receiveBuffer, &regVal, bytesToXfer);
receiveBuffer += bytesToXfer;
remainingBuffer -= bytesToXfer;
}
status = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_READ_RX_BUFFER_END, 0);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer receive"
"for entry %d failed\n", linkId, numEntries);
goto cleanup;
}
device->link[linkId].inbandData.message->dataSize += dataSize;
if (hdr.data & NVLINK_INBAND_DRV_HDR_TYPE_END)
{
nvswitch_filter_messages(device, linkId);
}
return;
cleanup:
tempStatus = nvswitch_minion_send_command(device, linkId,
NV_MINION_NVLINK_DL_CMD_COMMAND_CLEAR_RX_BUFFER,
0);
if (tempStatus != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Link %d Inband Buffer transfer for RX_BUFFER_CLEAR\n", linkId);
return;
}
if (device->link[linkId].inbandData.message != NULL)
{
nvswitch_os_free(device->link[linkId].inbandData.message);
device->link[linkId].inbandData.message = NULL;
}
//TODO: Check if we need to send a failure msg to client?
#endif
}
NvlStatus
nvswitch_minion_get_ali_debug_registers_ls10
(
nvswitch_device *device,
nvlink_link *link,
NVSWITCH_MINION_ALI_DEBUG_REGISTERS *params
)
{
NvU32 localLinkNumber = link->linkNumber % NVSWITCH_LINKS_PER_MINION_LS10;
if (!nvswitch_minion_get_dl_status(device, link->linkNumber,
NV_NVLSTAT_MN00, 0, &(params->dlstatMn00)) == NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO,"%s : Failed to poll DLSTAT _MN00 register for (%s):(%d)\n",
__FUNCTION__, device->name, link->linkNumber);
}
if (!nvswitch_minion_get_dl_status(device, link->linkNumber, NV_NVLSTAT_UC01, 0, &(params->dlstatUc01)))
{
NVSWITCH_PRINT(device, INFO,"%s : Failed to poll DLSTAT UC01 register for (%s):(%d)\n",
__FUNCTION__, device->name, link->linkNumber);
}
params->dlstatLinkIntr = NVSWITCH_MINION_LINK_RD32_LS10(device, link->linkNumber,
_MINION, _NVLINK_LINK_INTR(localLinkNumber));
return NVL_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,349 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common_nvswitch.h"
#include "regkey_nvswitch.h"
#include "ls10/ls10.h"
#include "ls10/pmgr_ls10.h"
#include "error_nvswitch.h"
#include "pmgr_nvswitch.h"
#include "rom_nvswitch.h"
#include "export_nvswitch.h"
#include "soe/soe_nvswitch.h"
#include "soe/soeifcore.h"
#include "nvswitch/ls10/dev_pmgr.h"
static NvBool
_nvswitch_i2c_ports_priv_locked_ls10
(
nvswitch_device *device
)
{
NvU32 regVal;
regVal = NVSWITCH_REG_RD32(device, _PMGR, _I2C_PRIV_LEVEL_MASK(NVSWITCH_I2C_PORT_I2CA));
if (FLD_TEST_DRF(_PMGR, _I2C_PRIV_LEVEL_MASK, _WRITE_PROTECTION_LEVEL0, _DISABLE, regVal))
{
return NV_TRUE;
}
regVal = NVSWITCH_REG_RD32(device, _PMGR, _I2C_PRIV_LEVEL_MASK(NVSWITCH_I2C_PORT_I2CB));
if (FLD_TEST_DRF(_PMGR, _I2C_PRIV_LEVEL_MASK, _WRITE_PROTECTION_LEVEL0, _DISABLE, regVal))
{
return NV_TRUE;
}
regVal = NVSWITCH_REG_RD32(device, _PMGR, _I2C_PRIV_LEVEL_MASK(NVSWITCH_I2C_PORT_I2CC));
if (FLD_TEST_DRF(_PMGR, _I2C_PRIV_LEVEL_MASK, _WRITE_PROTECTION_LEVEL0, _DISABLE, regVal))
{
return NV_TRUE;
}
return NV_FALSE;
}
static NvlStatus
_nvswitch_i2c_init_soe_ls10
(
nvswitch_device *device
)
{
NvlStatus ret;
PNVSWITCH_OBJI2C pI2c;
pI2c = device->pI2c;
if (!nvswitch_is_soe_supported(device))
{
return -NVL_ERR_NOT_SUPPORTED;
}
// Setup DMA
ret = nvswitch_os_alloc_contig_memory(device->os_handle, &pI2c->pCpuAddr, SOE_I2C_DMA_BUF_SIZE,
(device->dma_addr_width == 32));
if (ret != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: nvswitch_os_alloc_contig_memory returned %d\n", __FUNCTION__, ret);
return ret;
}
nvswitch_os_memset(pI2c->pCpuAddr, 0, SOE_I2C_DMA_BUF_SIZE);
ret = nvswitch_os_map_dma_region(device->os_handle, pI2c->pCpuAddr, &pI2c->dmaHandle,
SOE_I2C_DMA_BUF_SIZE, NVSWITCH_DMA_DIR_BIDIRECTIONAL);
if (ret != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: nvswitch_os_map_dma_region returned %d\n", __FUNCTION__, ret);
nvswitch_os_free_contig_memory(device->os_handle, pI2c->pCpuAddr, SOE_I2C_DMA_BUF_SIZE);
pI2c->pCpuAddr = NULL;
return ret;
}
return NVL_SUCCESS;
}
/*! @brief Set up a port to use a PMGR implementation.
*
* @param[in] device NvSwitch device
* @param[in] port The port identifier for the bus.
*/
static void
_nvswitch_i2c_set_port_pmgr_ls10
(
nvswitch_device *device,
NvU32 port
)
{
PNVSWITCH_OBJI2C pI2c = device->pI2c;
NVSWITCH_ASSERT(port < NVSWITCH_MAX_I2C_PORTS);
pI2c->PortInfo[port] = FLD_SET_DRF(_I2C, _PORTINFO, _DEFINED, _PRESENT, pI2c->PortInfo[port]);
pI2c->Ports[port].defaultSpeedMode = NVSWITCH_I2C_SPEED_MODE_100KHZ;
pI2c->PortInfo[port] = FLD_SET_DRF(_I2C, _PORTINFO,
_ACCESS_ALLOWED, _TRUE,
pI2c->PortInfo[port]);
}
//
// Pre-initialize the software & hardware state of the switch I2C & GPIO interface
//
void
nvswitch_init_pmgr_ls10
(
nvswitch_device *device
)
{
PNVSWITCH_OBJI2C pI2c;
// Initialize I2C object
nvswitch_i2c_init(device);
pI2c = device->pI2c;
if (pI2c != NULL)
{
pI2c->kernelI2CSupported = NV_TRUE;
pI2c->soeI2CSupported = NV_TRUE;
if (_nvswitch_i2c_ports_priv_locked_ls10(device))
{
NVSWITCH_PRINT(device, WARN, "%s: I2C ports priv locked!\n", __FUNCTION__);
pI2c->kernelI2CSupported = NV_FALSE;
}
if (_nvswitch_i2c_init_soe_ls10(device) != NVL_SUCCESS)
{
pI2c->soeI2CSupported = NV_FALSE;
}
// Setup the 3 I2C ports
_nvswitch_i2c_set_port_pmgr_ls10(device, NVSWITCH_I2C_PORT_I2CA);
_nvswitch_i2c_set_port_pmgr_ls10(device, NVSWITCH_I2C_PORT_I2CB);
_nvswitch_i2c_set_port_pmgr_ls10(device, NVSWITCH_I2C_PORT_I2CC);
}
}
static const NVSWITCH_GPIO_INFO nvswitch_gpio_pin_Default[] =
{
NVSWITCH_DESCRIBE_GPIO_PIN( 0, _INSTANCE_ID0, 0, IN), // Instance ID bit 0
NVSWITCH_DESCRIBE_GPIO_PIN( 1, _INSTANCE_ID1, 0, IN), // Instance ID bit 1
NVSWITCH_DESCRIBE_GPIO_PIN( 2, _INSTANCE_ID2, 0, IN), // Instance ID bit 2
};
static const NvU32 nvswitch_gpio_pin_Default_size = NV_ARRAY_ELEMENTS(nvswitch_gpio_pin_Default);
//
// Initialize the software state of the switch I2C & GPIO interface
// Temporarily forcing default GPIO values.
//
// TODO: This function should be updated with the board values from DCB.
void
nvswitch_init_pmgr_devices_ls10
(
nvswitch_device *device
)
{
ls10_device *chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
PNVSWITCH_OBJI2C pI2c = device->pI2c;
if (IS_FMODEL(device) || IS_EMULATION(device) || IS_RTLSIM(device))
{
// GPIOs not modelled on non-silicon
chip_device->gpio_pin = NULL;
chip_device->gpio_pin_size = 0;
}
else
{
chip_device->gpio_pin = nvswitch_gpio_pin_Default;
chip_device->gpio_pin_size = nvswitch_gpio_pin_Default_size;
}
pI2c->device_list = NULL;
pI2c->device_list_size = 0;
}
NvlStatus
nvswitch_get_rom_info_ls10
(
nvswitch_device *device,
NVSWITCH_EEPROM_TYPE *eeprom
)
{
NVSWITCH_PRINT(device, WARN, "%s: Function not implemented\n", __FUNCTION__);
return NVL_SUCCESS;
}
/*!
* RM Control command to determine the physical id of the device.
*/
NvU32
nvswitch_read_physical_id_ls10
(
nvswitch_device *device
)
{
ls10_device *chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
NvU32 physical_id = 0;
NvU32 data;
NvU32 idx_gpio;
NvU32 input_inv;
NvU32 function_offset;
for (idx_gpio = 0; idx_gpio < chip_device->gpio_pin_size; idx_gpio++)
{
if ((chip_device->gpio_pin[idx_gpio].function >= NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID0) &&
(chip_device->gpio_pin[idx_gpio].function <= NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID6))
{
if (chip_device->gpio_pin[idx_gpio].misc == NVSWITCH_GPIO_ENTRY_MISC_IO_INV_IN)
{
input_inv = NV_PMGR_GPIO_INPUT_CNTL_1_INV_YES;
}
else
{
input_inv = NV_PMGR_GPIO_INPUT_CNTL_1_INV_NO;
}
NVSWITCH_REG_WR32(device, _PMGR, _GPIO_INPUT_CNTL_1,
DRF_NUM(_PMGR, _GPIO_INPUT_CNTL_1, _PINNUM, chip_device->gpio_pin[idx_gpio].pin) |
DRF_NUM(_PMGR, _GPIO_INPUT_CNTL_1, _INV, input_inv) |
DRF_DEF(_PMGR, _GPIO_INPUT_CNTL_1, _BYPASS_FILTER, _NO));
data = NVSWITCH_REG_RD32(device, _PMGR, _GPIO_INPUT_CNTL_1);
function_offset = chip_device->gpio_pin[idx_gpio].function -
NVSWITCH_GPIO_ENTRY_FUNCTION_INSTANCE_ID0;
physical_id |=
(DRF_VAL(_PMGR, _GPIO_INPUT_CNTL_1, _READ, data) << function_offset);
}
}
NVSWITCH_PRINT(device, SETUP, "%s Device position Id = 0x%x\n", __FUNCTION__, physical_id);
return physical_id;
}
/*!
* RM Control command to perform indexed I2C.
*/
NvlStatus
nvswitch_ctrl_i2c_indexed_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams
)
{
PNVSWITCH_OBJI2C pI2c;
pI2c = device->pI2c;
if (pI2c == NULL)
{
return -NVL_ERR_NOT_SUPPORTED;
}
if (pParams == NULL)
{
return -NVL_BAD_ARGS;
}
// SW I2C only supported by kernel driver
if (device->regkeys.force_kernel_i2c == NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_ENABLE ||
FLD_TEST_DRF(SWITCH_CTRL, _I2C_FLAGS, _FLAVOR, _SW, pParams->flags))
{
if (!pI2c->kernelI2CSupported)
{
return -NVL_ERR_NOT_SUPPORTED;
}
return nvswitch_ctrl_i2c_indexed_lr10(device, pParams);
}
if (pI2c->soeI2CSupported)
{
return soeI2CAccess_HAL(device, pParams);
}
return -NVL_ERR_NOT_SUPPORTED;
}
/*!
* Return if I2C transactions can be supported.
*
* @param[in] device The NvSwitch Device.
*
*/
NvBool
nvswitch_is_i2c_supported_ls10
(
nvswitch_device *device
)
{
return ((device->pI2c != NULL) &&
(device->pI2c->soeI2CSupported || device->pI2c->kernelI2CSupported));
}
/*!
* Return if I2C device and port is allowed access
*
* @param[in] device The NvSwitch Device.
* @param[in] port The I2C Port.
* @param[in] addr The I2C device to access.
* @param[in] bIsRead Boolean if I2C transaction is a read.
*
*/
NvBool
nvswitch_i2c_is_device_access_allowed_ls10
(
nvswitch_device *device,
NvU32 port,
NvU8 addr,
NvBool bIsRead
)
{
// Check will be performed in SOE
return NV_TRUE;
}

View File

@@ -0,0 +1,222 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "common_nvswitch.h"
#include "flcn/flcn_nvswitch.h"
#include "rmflcncmdif_nvswitch.h"
#include "nvVer.h"
NvlStatus
nvswitch_smbpbi_alloc_ls10
(
nvswitch_device *device
)
{
return NVL_SUCCESS;
}
NvlStatus
nvswitch_smbpbi_post_init_hal_ls10
(
nvswitch_device *device
)
{
return NVL_SUCCESS;
}
void
nvswitch_smbpbi_destroy_hal_ls10
(
nvswitch_device *device
)
{
}
NvlStatus
nvswitch_smbpbi_get_dem_num_messages_ls10
(
nvswitch_device *device,
NvU8 *pMsgCount
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_inforom_dem_load_ls10
(
nvswitch_device *device
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_smbpbi_dem_load_ls10
(
nvswitch_device *device
)
{
return -NVL_ERR_NOT_SUPPORTED;
}
void
nvswitch_smbpbi_log_message_ls10
(
nvswitch_device *device,
NvU32 num,
NvU32 msglen,
NvU8 *osErrorString
)
{
struct smbpbi *pSmbpbi = device->pSmbpbi;
RM_FLCN_CMD_SOE cmd;
RM_SOE_SMBPBI_CMD_LOG_MESSAGE *pLogCmd = &cmd.cmd.smbpbiCmd.logMessage;
NvU8 offset;
NvU8 segSize;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
FLCN *pFlcn;
NvlStatus status;
if ((pSmbpbi == NULL) || (device->pSoe == NULL) ||
(pSmbpbi->logMessageNesting++ != 0))
{
goto nvswitch_smbpbi_log_message_exit;
}
pFlcn = device->pSoe->pFlcn;
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, LOG_MESSAGE);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_LOG_MESSAGE;
msglen = NV_MIN(msglen, RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING);
pLogCmd->sxidId = num;
pLogCmd->msgLen = msglen;
pLogCmd->timeStamp = nvswitch_os_get_platform_time() / NVSWITCH_NSEC_PER_SEC;
for (offset = 0; msglen > 0; offset += segSize)
{
segSize = NV_MIN(msglen, RM_SOE_SMBPBI_CMD_LOG_MESSAGE_STRING_SEGMENT_SZ);
nvswitch_os_memcpy(pLogCmd->errorString, osErrorString + offset, segSize);
pLogCmd->msgOffset = offset;
pLogCmd->segSize = segSize;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI Log Message command failed. rc:%d\n",
__FUNCTION__, status);
break;
}
msglen -= segSize;
}
pSmbpbi->logMessageNesting = 0;
nvswitch_smbpbi_log_message_exit:
return;
}
NvlStatus
nvswitch_smbpbi_send_init_data_ls10
(
nvswitch_device *device
)
{
struct smbpbi *pSmbpbi = device->pSmbpbi;
RM_FLCN_CMD_SOE cmd;
RM_SOE_SMBPBI_CMD_INIT_DATA *pInitDataCmd = &cmd.cmd.smbpbiCmd.initData;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
FLCN *pFlcn = device->pSoe->pFlcn;
NvlStatus status = NVL_SUCCESS;
ct_assert(sizeof(NV_VERSION_STRING) <= sizeof(pInitDataCmd->driverVersionString));
if (pSmbpbi == NULL)
{
goto nvswitch_smbpbi_send_init_data_exit;
}
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, INIT_DATA);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_INIT_DATA;
nvswitch_os_strncpy((char *)pInitDataCmd->driverVersionString,
NV_VERSION_STRING,
sizeof(pInitDataCmd->driverVersionString));
pInitDataCmd->driverVersionString[sizeof(pInitDataCmd->driverVersionString) - 1] = 0;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI Init Data command failed. rc:%d\n",
__FUNCTION__, status);
}
else
{
NVSWITCH_PRINT(device, INFO, "%s: SMBPBI Init Data sent to SOE.\n",
__FUNCTION__);
}
nvswitch_smbpbi_send_init_data_exit:
return status;
}
void
nvswitch_smbpbi_send_unload_ls10
(
nvswitch_device *device
)
{
}
void
nvswitch_smbpbi_dem_flush_ls10
(
nvswitch_device *device
)
{
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,358 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "export_nvswitch.h"
#include "common_nvswitch.h"
#include "ls10/ls10.h"
#include "ls10/therm_ls10.h"
#include "error_nvswitch.h"
#include "soe/soeiftherm.h"
#include "nvswitch/ls10/dev_therm.h"
//
// Thermal functions
//
//
// Initialize thermal offsets for External Tdiode.
//
NvlStatus
nvswitch_init_thermal_ls10
(
nvswitch_device *device
)
{
ls10_device *chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
// Mark everything invalid
chip_device->tdiode.method = NVSWITCH_THERM_METHOD_UNKNOWN;
return NVL_SUCCESS;
}
static void
_nvswitch_read_max_tsense_temperature_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info,
NvU32 channel
)
{
NvU32 offset;
NvU32 temperature;
temperature = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_MAXIMUM_TEMPERATURE);
temperature = DRF_VAL(_THERM_TSENSE, _MAXIMUM_TEMPERATURE, _MAXIMUM_TEMPERATURE, temperature);
temperature = NV_TSENSE_FXP_9_5_TO_24_8(temperature);
if (channel == NVSWITCH_THERM_CHANNEL_LR10_TSENSE_MAX)
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_0_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_0_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
// Temperature of the sensor reported equals calculation of the max temperature reported
// from the TSENSE HUB plus the temperature offset programmed by SW. This offset needs to
// be substracted to get the actual temperature of the sensor.
temperature -= NV_TSENSE_FXP_9_5_TO_24_8(offset);
}
info->temperature[channel] = temperature;
info->status[channel] = NVL_SUCCESS;
}
static void
_nvswitch_read_external_tdiode_temperature_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info,
NvU32 channel
)
{
}
//
// nvswitch_therm_read_temperature
//
// Temperature and voltage are only available on SKUs which have thermal and
// voltage sensors.
//
NvlStatus
nvswitch_ctrl_therm_read_temperature_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS *info
)
{
NvU32 channel;
NvU32 val;
NvU32 offset;
if (!info->channelMask)
{
NVSWITCH_PRINT(device, ERROR,
"%s: No channel given in the input.\n",
__FUNCTION__);
return -NVL_BAD_ARGS;
}
nvswitch_os_memset(info->temperature, 0x0, sizeof(info->temperature));
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_MAX;
if (info->channelMask & NVBIT(channel))
{
_nvswitch_read_max_tsense_temperature_ls10(device, info, channel);
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_OFFSET_MAX;
if (info->channelMask & NVBIT(channel))
{
_nvswitch_read_max_tsense_temperature_ls10(device, info, channel);
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TDIODE;
if (info->channelMask & NVBIT(channel))
{
_nvswitch_read_external_tdiode_temperature_ls10(device, info, channel);
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TDIODE_OFFSET;
if (info->channelMask & NVBIT(channel))
{
_nvswitch_read_external_tdiode_temperature_ls10(device, info, channel);
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_0;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_0_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_0_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_0);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_0, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_1;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_1_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_1_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_1);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_1, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_2;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_2_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_2_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_2);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_2, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_3;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_3_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_3_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_3);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_3, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_4;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_4_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_4_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_4);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_4, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_5;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_5_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_5_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_5);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_5, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_6;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_6_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_6_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_6);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_6, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_7;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_7_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_7_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_7);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_7, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
channel = NVSWITCH_THERM_CHANNEL_LS10_TSENSE_8;
if (info->channelMask & NVBIT(channel))
{
offset = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_8_TEMPERATURE_MODIFICATIONS);
offset = DRF_VAL(_THERM_TSENSE, _U2_A_0_BJT_8_TEMPERATURE_MODIFICATIONS, _TEMPERATURE_OFFSET, offset);
offset = NV_TSENSE_FXP_9_5_TO_24_8(offset);
val = NVSWITCH_REG_RD32(device, _THERM, _TSENSE_U2_A_0_BJT_8);
val = DRF_VAL(_THERM, _TSENSE_U2_A_0_BJT_8, _TEMPERATURE, val);
val = NV_TSENSE_FXP_9_5_TO_24_8(val);
val -= offset;
info->temperature[channel] = val;
info->channelMask &= ~NVBIT(channel);
}
if (info->channelMask)
{
NVSWITCH_PRINT(device, ERROR,
"%s: ChannelMask %x absent on LS10.\n",
__FUNCTION__, info->channelMask);
return -NVL_BAD_ARGS;
}
return NVL_SUCCESS;
}
NvlStatus
nvswitch_ctrl_therm_get_temperature_limit_ls10
(
nvswitch_device *device,
NVSWITCH_CTRL_GET_TEMPERATURE_LIMIT_PARAMS *info
)
{
NvU32 threshold;
NvU32 temperature;
threshold = nvswitch_reg_read_32(device, NV_THERM_TSENSE_THRESHOLD_TEMPERATURES);
switch (info->thermalEventId)
{
case NVSWITCH_CTRL_THERMAL_EVENT_ID_WARN:
{
// Get Slowdown temperature
temperature = DRF_VAL(_THERM_TSENSE, _THRESHOLD_TEMPERATURES,
_WARNING_TEMPERATURE, threshold);
break;
}
case NVSWITCH_CTRL_THERMAL_EVENT_ID_OVERT:
{
// Get Shutdown temperature
temperature = DRF_VAL(_THERM_TSENSE, _THRESHOLD_TEMPERATURES,
_OVERTEMP_TEMPERATURE, threshold);
break;
}
default:
{
NVSWITCH_PRINT(device, ERROR, "Invalid Thermal Event Id: 0x%x\n", info->thermalEventId);
return -NVL_BAD_ARGS;
}
}
info->temperatureLimit = NV_TSENSE_FXP_9_5_TO_24_8(temperature);
return NVL_SUCCESS;
}
// Background task to monitor thermal warn and adjust link mode
void
nvswitch_monitor_thermal_alert_ls10
(
nvswitch_device *device
)
{
return;
}

View File

@@ -31,6 +31,9 @@
#include "flcn/flcn_nvswitch.h"
#include "soe/soe_nvswitch.h"
#include "nvVer.h"
#include "nvlink_inband_msg.h"
static NvlStatus _nvswitch_ctrl_inband_flush_data(nvswitch_device *device, NVSWITCH_INBAND_FLUSH_DATA_PARAMS *p);
#define NVSWITCH_DEV_CMD_CHECK_ADMIN NVBIT64(0)
#define NVSWITCH_DEV_CMD_CHECK_FM NVBIT64(1)
@@ -297,6 +300,14 @@ _nvswitch_corelib_write_discovery_token
NvU64 token
)
{
nvswitch_device *device = link->dev->pDevInfo;
if (link->version >= NVLINK_DEVICE_VERSION_40)
{
nvswitch_store_topology_information(device, link);
return NVL_SUCCESS;
}
return NVL_SUCCESS;
}
@@ -307,7 +318,7 @@ _nvswitch_corelib_ali_training
)
{
nvswitch_device *device = link->dev->pDevInfo;
return device->hal.nvswitch_launch_ALI_link_training(device, link);
return device->hal.nvswitch_launch_ALI_link_training(device, link, NV_FALSE);
}
void
@@ -379,11 +390,15 @@ _nvswitch_init_device_regkeys
NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_short,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_OFF);
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_SHORT_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, crc_bit_error_rate_long,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG,
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_OFF);
NV_SWITCH_REGKEY_CRC_BIT_ERROR_RATE_LONG_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, surpress_link_errors_for_gpu_reset,
NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET,
NV_SWITCH_REGKEY_SURPRESS_LINK_ERRORS_FOR_GPU_RESET_DISABLE);
//
// Debug use regkeys
@@ -505,9 +520,21 @@ _nvswitch_init_device_regkeys
NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL,
NV_SWITCH_REGKEY_I2C_ACCESS_CONTROL_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, force_kernel_i2c,
NV_SWITCH_REGKEY_FORCE_KERNEL_I2C,
NV_SWITCH_REGKEY_FORCE_KERNEL_I2C_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, link_recal_settings,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP);
NVSWITCH_INIT_REGKEY(_PRIVATE, lp_threshold,
NV_SWITCH_REGKEY_SET_LP_THRESHOLD,
NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT);
NVSWITCH_INIT_REGKEY(_PUBLIC, minion_intr,
NV_SWITCH_REGKEY_MINION_INTERRUPTS,
NV_SWITCH_REGKEY_MINION_INTERRUPTS_DEFAULT);
}
NvU64
nvswitch_lib_deferred_task_dispatcher
@@ -518,12 +545,14 @@ nvswitch_lib_deferred_task_dispatcher
NvU64 time_nsec;
NvU64 time_next_nsec = nvswitch_os_get_platform_time() + 100*NVSWITCH_INTERVAL_1MSEC_IN_NS;
NVSWITCH_TASK_TYPE *task;
NVSWITCH_TASK_TYPE *prev_task;
if (!NVSWITCH_IS_DEVICE_VALID(device))
{
return NV_U64_MAX;
}
prev_task = NULL;
task = device->tasks;
// Walk the task list, executing those whose next execution interval is at hand
@@ -541,13 +570,50 @@ nvswitch_lib_deferred_task_dispatcher
task->last_run_nsec = time_nsec;
// Run the task
if (NVSWITCH_IS_DEVICE_INITIALIZED(device) ||
(task->flags & NVSWITCH_TASK_TYPE_FLAGS_ALWAYS_RUN))
(*task->task_fn)(device);
(task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED))
{
if(task->flags & NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS)
(*task->task_fn_vdptr)(device, task->task_args); // run task with provided args
else
(*task->task_fn_devptr)(device);
}
}
// Determine its next run time
time_next_nsec = NV_MIN(task->last_run_nsec + task->period_nsec, time_next_nsec);
task = task->next;
// Advance pointer. If run once flag is set and task ran, remove task from list.
if((task->flags & NVSWITCH_TASK_TYPE_FLAGS_RUN_ONCE) &&
(task->last_run_nsec == time_nsec))
{
prev_task = task->prev;
// Removing from list head
if (prev_task == NULL)
{
device->tasks = task->next;
if (device->tasks != NULL)
{
device->tasks->prev = NULL;
}
nvswitch_os_free(task);
task = device->tasks;
}
else
{
prev_task->next = task->next;
if (prev_task->next != NULL)
{
prev_task->next->prev = prev_task;
}
nvswitch_os_free(task);
task = prev_task->next;
}
}
else
{
task = task->next;
}
}
time_nsec = nvswitch_os_get_platform_time();
@@ -568,6 +634,11 @@ _nvswitch_setup_hal
nvswitch_setup_hal_lr10(device);
return NVL_SUCCESS;
}
if (nvswitch_is_ls10_device_id(pci_device_id))
{
nvswitch_setup_hal_ls10(device);
return NVL_SUCCESS;
}
NVSWITCH_PRINT(device, ERROR,
"NVSwitch HAL setup failed - Unrecognized PCI Device ID\n");
return -NVL_ERR_NOT_SUPPORTED;
@@ -648,6 +719,7 @@ nvswitch_is_soe_supported
return device->hal.nvswitch_is_soe_supported(device);
}
NvlStatus
nvswitch_init_soe
(
@@ -744,12 +816,12 @@ _nvswitch_post_init_device_setup
}
static NvlStatus
_nvswitch_setup_link_system_registers
_nvswitch_setup_system_registers
(
nvswitch_device *device
)
{
return device->hal.nvswitch_setup_link_system_registers(device);
return device->hal.nvswitch_setup_system_registers(device);
}
static void
@@ -932,14 +1004,27 @@ nvswitch_ctrl_set_fm_driver_state(
NVSWITCH_SET_FM_DRIVER_STATE_PARAMS *p
)
{
NvU32 prev_fm_status;
if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
{
return -NVL_BAD_ARGS;
}
prev_fm_status = device->driver_fabric_state;
device->driver_fabric_state = p->driverState;
device->fabric_state_timestamp = nvswitch_os_get_platform_time();
if (prev_fm_status != p->driverState)
{
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_FABRIC_STATE) != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify event\n",
__FUNCTION__);
}
}
return NVL_SUCCESS;
}
@@ -1069,12 +1154,100 @@ _nvswitch_ctrl_unregister_events(
return NVL_SUCCESS;
}
/*
* @Brief : Sends NACK or drops given inband msg based on message type
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] linkId Link ID
* @param[in] msghdr Header to the message
*
*/
static void
nvswitch_send_nack_or_drop
(
nvswitch_device *device,
NvU32 linkId,
nvlink_inband_msg_header_t *msghdr
)
{
switch(msghdr->type)
{
case NVLINK_INBAND_MSG_TYPE_MC_TEAM_SETUP_REQ:
device->hal.nvswitch_send_inband_nack(device, (NvU32 *)msghdr, linkId);
NVSWITCH_PRINT(device, ERROR,
"Sending NACK for message (type 0x%x)\n", msghdr->type);
return;
default:
// TODO: Add SXid in future if needed.
NVSWITCH_PRINT(device, ERROR,
"Dropping message (type 0x%x)\n", msghdr->type);
return;
}
}
/*
* @Brief : Deletes all the entries in persistent or non-persistent lists.
* Send nacks if requested.
*
* @Description :
*
* @param[in] device NVSwitch device to contain this link
* @param[in] linkId Link number
* @param[in] bSendNack Send nacks if true
* @param[in] bNonPersistentOnly Clear only non-persistent list
*/
static void
_nvswitch_inband_clear_lists
(
nvswitch_device *device,
NvU32 linkId,
NvBool bSendNack,
NvBool bNonPersistentOnly
)
{
nvswitch_inband_data_list *curr = NULL;
nvswitch_inband_data_list *next = NULL;
nvlink_inband_msg_header_t *msghdr = NULL;
nvListForEachEntry_safe(curr, next,
&device->link[linkId].inbandData.nonpersistent_list, entry)
{
if (bSendNack)
{
msghdr = (nvlink_inband_msg_header_t *)curr->data;
nvswitch_send_nack_or_drop(device, linkId, msghdr);
}
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
if (bNonPersistentOnly)
return;
nvListForEachEntry_safe(curr, next,
&device->link[linkId].inbandData.persistent_list, entry)
{
if (bSendNack)
{
msghdr = (nvlink_inband_msg_header_t *)curr->data;
nvswitch_send_nack_or_drop(device, linkId, msghdr);
}
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
}
static void
nvswitch_fabric_state_heartbeat(
nvswitch_device *device
)
{
NvU64 age;
NvU32 linkId;
if (!NVSWITCH_IS_DEVICE_VALID(device))
return;
@@ -1086,6 +1259,18 @@ nvswitch_fabric_state_heartbeat(
age > (NvU64)device->fm_timeout * 1000ULL * 1000ULL)
device->driver_fabric_state = NVSWITCH_DRIVER_FABRIC_STATE_MANAGER_TIMEOUT;
//
// If FM is not running, clear pending non-persistent messages. Persistent
// messages can be processed by the FM when it restarts.
//
if (device->driver_fabric_state != NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
{
for (linkId = 0; linkId < nvswitch_get_num_links(device); linkId++)
_nvswitch_inband_clear_lists(device, linkId,
NV_TRUE /* Nack */,
NV_TRUE /* Non-persistent only */);
}
(void)device->hal.nvswitch_write_fabric_state(device);
}
@@ -1240,8 +1425,12 @@ nvswitch_lib_initialize_device
nvswitch_task_create(device, &nvswitch_fabric_state_heartbeat,
NVSWITCH_HEARTBEAT_INTERVAL_NS,
NVSWITCH_TASK_TYPE_FLAGS_ALWAYS_RUN);
NVSWITCH_TASK_TYPE_FLAGS_RUN_EVEN_IF_DEVICE_NOT_INITIALIZED);
//
// Blacklisted devices return successfully in order to preserve the fabric state heartbeat
// and ensure OOB utilities don't think the driver has died
//
if (device->device_blacklist_reason == NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_OUT_OF_BAND)
{
NVSWITCH_PRINT(device, SETUP,
@@ -1250,13 +1439,13 @@ nvswitch_lib_initialize_device
device->nvlink_device->pciInfo.bus,
device->nvlink_device->pciInfo.device,
device->nvlink_device->pciInfo.function);
return retval;
return NVL_SUCCESS;
}
if (is_blacklisted_by_os)
{
(void)nvswitch_lib_blacklist_device(device, NVSWITCH_DEVICE_BLACKLIST_REASON_MANUAL_IN_BAND);
return retval;
return NVL_SUCCESS;
}
for (link_num=0; link_num < nvswitch_get_num_links(device); link_num++)
@@ -1365,6 +1554,7 @@ nvswitch_initialize_inforom_fail:
nvswitch_initialize_device_state_fail:
_nvswitch_destruct_soe(device);
nvswitch_tasks_destroy(device);
return retval;
}
@@ -1426,7 +1616,7 @@ nvswitch_lib_post_init_device
__FUNCTION__);
}
retval = _nvswitch_setup_link_system_registers(device);
retval = _nvswitch_setup_system_registers(device);
if (retval != NVL_SUCCESS)
{
return retval;
@@ -1448,9 +1638,44 @@ nvswitch_lib_post_init_blacklist_device
_nvswitch_post_init_blacklist_device_setup(device);
}
void
_nvswitch_check_pending_data_and_notify
(
nvswitch_device *device,
NVSWITCH_CLIENT_EVENT *event
)
{
switch (event->eventId)
{
case NVSWITCH_DEVICE_EVENT_INBAND_DATA:
{
NvU32 i;
for (i = 0; i < nvswitch_get_num_links(device); i++)
{
if (!nvListIsEmpty(&device->link[i].inbandData.persistent_list) ||
!nvListIsEmpty(&device->link[i].inbandData.nonpersistent_list))
{
(void)nvswitch_os_notify_client_event(device->os_handle,
event->private_driver_data,
event->eventId);
}
}
break;
}
default:
return;
}
}
/*!
* @brief: Gets the client event associated with the file descriptor
* if it already exists in the Device's client event list.
*
* If found, and if there is pending data for the event,
* the event is triggered before returning to unblock the
* client right away.
*/
NvlStatus
nvswitch_lib_get_client_event
@@ -1474,6 +1699,7 @@ nvswitch_lib_get_client_event
if (curr->private_driver_data == osPrivate)
{
*ppClientEvent = curr;
_nvswitch_check_pending_data_and_notify(device, curr);
return NVL_SUCCESS;
}
}
@@ -1654,6 +1880,7 @@ nvswitch_lib_shutdown_device
nvswitch_device *device
)
{
NVSWITCH_INBAND_FLUSH_DATA_PARAMS p;
if (!NVSWITCH_IS_DEVICE_ACCESSIBLE(device))
{
@@ -1670,6 +1897,10 @@ nvswitch_lib_shutdown_device
nvswitch_hw_counter_shutdown(device);
// FLUSH any pending messages to avoid memory leaks
p.linkMask = nvswitch_get_enabled_link_mask(device);
_nvswitch_ctrl_inband_flush_data(device, &p);
_nvswitch_unregister_links(device);
nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
@@ -1760,7 +1991,11 @@ nvswitch_lib_get_bios_version
return -NVL_BAD_ARGS;
ret = device->hal.nvswitch_ctrl_get_bios_info(device, &p);
if (version != NULL)
{
*version = p.version;
}
return ret;
}
@@ -2250,7 +2485,7 @@ nvswitch_timeout_check
return (time->timeout_ns <= time_current);
}
void
NvlStatus
nvswitch_task_create
(
nvswitch_device *device,
@@ -2259,23 +2494,74 @@ nvswitch_task_create
NvU32 flags
)
{
NVSWITCH_TASK_TYPE *task = nvswitch_os_malloc(sizeof(*task));
NVSWITCH_TASK_TYPE *task;
task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
if (task == NULL)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Unable to allocate task.\n",
__FUNCTION__);
return -NVL_NO_MEM;
}
else
{
task->task_fn = task_fn;
task->task_fn_devptr = task_fn;
task->task_args = NULL;
task->period_nsec = period_nsec;
task->last_run_nsec = 0;
task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
task->flags = flags;
task->prev = NULL;
task->next = device->tasks;
if (device->tasks != NULL)
{
device->tasks->prev = task;
}
device->tasks = task;
}
return NVL_SUCCESS;
}
NvlStatus
nvswitch_task_create_args
(
nvswitch_device *device,
void *fn_args,
void (*task_fn)(nvswitch_device* device, void *fn_args),
NvU64 period_nsec,
NvU32 flags
)
{
NVSWITCH_TASK_TYPE *task;
task = nvswitch_os_malloc(sizeof(NVSWITCH_TASK_TYPE));
flags = flags | NVSWITCH_TASK_TYPE_FLAGS_VOID_PTR_ARGS; // ensure dispatcher always executes tasks passed through this function with args
if (task == NULL)
{
NVSWITCH_PRINT(device, ERROR,
"%s: Unable to allocate task.\n",
__FUNCTION__);
return -NVL_NO_MEM;
}
else
{
task->task_fn_vdptr = task_fn;
task->task_args = fn_args;
task->period_nsec = period_nsec;
task->last_run_nsec = nvswitch_os_get_platform_time(); // Prevent deferred tasks from being run immediately
task->flags = flags;
task->prev = NULL;
task->next = device->tasks;
if (device->tasks != NULL)
{
device->tasks->prev = task;
}
device->tasks = task;
}
return NVL_SUCCESS;
}
void
@@ -2544,7 +2830,7 @@ _nvswitch_ctrl_get_nvlipt_counters
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters
// nvswitch_ctrl_get_throughput_counters
//
return -NVL_ERR_NOT_SUPPORTED;
}
@@ -2559,7 +2845,7 @@ _nvswitch_ctrl_set_nvlipt_counter_config
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters_lr10
// nvswitch_ctrl_get_throughput_counters_lr10
//
// Setting counter config is not allowed on these
// non-configurable counters. These counters are
@@ -2578,7 +2864,7 @@ _nvswitch_ctrl_get_nvlipt_counter_config
//
// This control call is now deprecated.
// New control call to fetch throughput counters is:
// _nvswitch_ctrl_get_throughput_counters_lr10
// nvswitch_ctrl_get_throughput_counters_lr10
//
// Getting counter config is useful if counters are
// configurable. These counters are not configurable
@@ -2587,6 +2873,26 @@ _nvswitch_ctrl_get_nvlipt_counter_config
return -NVL_ERR_NOT_SUPPORTED;
}
static NvlStatus
_nvswitch_ctrl_register_read
(
nvswitch_device *device,
NVSWITCH_REGISTER_READ *p
)
{
return device->hal.nvswitch_ctrl_register_read(device, p);
}
static NvlStatus
_nvswitch_ctrl_register_write
(
nvswitch_device *device,
NVSWITCH_REGISTER_WRITE *p
)
{
return device->hal.nvswitch_ctrl_register_write(device, p);
}
NvU32
nvswitch_i2c_get_port_info
(
@@ -2627,6 +2933,16 @@ _nvswitch_ctrl_get_bios_info
return device->hal.nvswitch_ctrl_get_bios_info(device, p);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_version
(
nvswitch_device *device,
NVSWITCH_GET_INFOROM_VERSION_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_get_inforom_version(device, p);
}
NvlStatus
nvswitch_ctrl_set_latency_bins
(
@@ -2647,8 +2963,8 @@ _nvswitch_ctrl_get_ingress_reqlinkid
return device->hal.nvswitch_ctrl_get_ingress_reqlinkid(device, params);
}
static NvlStatus
_nvswitch_ctrl_get_throughput_counters
NvlStatus
nvswitch_ctrl_get_throughput_counters
(
nvswitch_device *device,
NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS *p
@@ -2724,6 +3040,26 @@ _nvswitch_ctrl_get_nvlink_ecc_errors
return device->hal.nvswitch_get_nvlink_ecc_errors(device, params);
}
static NvlStatus
_nvswitch_ctrl_set_mc_rid_table
(
nvswitch_device *device,
NVSWITCH_SET_MC_RID_TABLE_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_set_mc_rid_table(device, p);
}
static NvlStatus
_nvswitch_ctrl_get_mc_rid_table
(
nvswitch_device *device,
NVSWITCH_GET_MC_RID_TABLE_PARAMS *p
)
{
return device->hal.nvswitch_ctrl_get_mc_rid_table(device, p);
}
static NvlStatus
_nvswitch_ctrl_set_residency_bins
(
@@ -2794,38 +3130,6 @@ _nvswitch_ctrl_inband_read_data
return device->hal.nvswitch_ctrl_inband_read_data(device, p);
}
/*
* @Brief : Deletes all the entires in persistant or nonpersistant list
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] linkId link number of the link
*
*/
static void
_nvswitch_inband_clear_list
(
nvswitch_device *device,
NvU32 linkId
)
{
nvswitch_inband_data_list *curr = NULL;
nvswitch_inband_data_list *next = NULL;
nvListForEachEntry_safe(curr, next, &device->link[linkId].inbandData.persistent_list, entry)
{
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
nvListForEachEntry_safe(curr, next, &device->link[linkId].inbandData.nonpersistent_list, entry)
{
nvListDel(&curr->entry);
nvswitch_os_free(curr);
}
}
static NvlStatus
_nvswitch_ctrl_inband_flush_data
(
@@ -2847,9 +3151,16 @@ _nvswitch_ctrl_inband_flush_data
FOR_EACH_INDEX_IN_MASK(64, i, p->linkMask)
{
if (nvswitch_is_link_valid(device, i) &&
(enabledLinkMask & NVBIT(i)))
(enabledLinkMask & NVBIT64(i)))
{
_nvswitch_inband_clear_list(device, i);
//
// Flush is expected to clear both persistent and non-persistent
// list. FM does flush when it wants to drop (ignore) all pending
// messages w/o any NACKs.
//
_nvswitch_inband_clear_lists(device, i,
NV_FALSE /* Nack */,
NV_FALSE /* Non-persistent only */);
}
}
FOR_EACH_INDEX_IN_MASK_END;
@@ -2872,16 +3183,16 @@ _nvswitch_ctrl_inband_pending_data_stats
for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
{
if (nvswitch_is_link_valid(device, link_num) &&
(enabledLinkMask & NVBIT(link_num)))
(enabledLinkMask & NVBIT64(link_num)))
{
if (!nvListIsEmpty(&device->link[link_num].inbandData.persistent_list))
{
persistent_mask |= NVBIT(link_num);
persistent_mask |= NVBIT64(link_num);
}
if (!nvListIsEmpty(&device->link[link_num].inbandData.nonpersistent_list))
{
nonpersistent_mask |= NVBIT(link_num);
nonpersistent_mask |= NVBIT64(link_num);
}
}
}
@@ -3100,6 +3411,8 @@ nvswitch_inband_read_data
if (nvListIsEmpty(&device->link[linkId].inbandData.persistent_list) &&
nvListIsEmpty(&device->link[linkId].inbandData.nonpersistent_list))
{
NVSWITCH_PRINT(device, ERROR, "%s: LinkId %d doesnt have any data to send\n",
__FUNCTION__, linkId);
*dataSize = 0;
return -NVL_NOT_FOUND;
}
@@ -3120,6 +3433,34 @@ nvswitch_inband_read_data
return NVL_SUCCESS;
}
/*
* @Brief : Returns NV_TRUE if the given inband msg
* needs to go to persistant list
*
* @Description :
*
* @param[in] device NvSwitch device to contain this link
* @param[in] msghdr Header to the message
*
*/
static NvBool
nvswitch_is_message_persistent
(
nvswitch_device *device,
nvlink_inband_msg_header_t *msghdr
)
{
// We expect only one message per received data
switch(msghdr->type)
{
case NVLINK_INBAND_MSG_TYPE_MC_TEAM_RELEASE_REQ:
return NV_TRUE;
default:
return NV_FALSE;
}
}
/*
* @Brief : Moves the data into persistant or nonpersistant list
*
@@ -3136,6 +3477,60 @@ nvswitch_filter_messages
NvU32 linkId
)
{
NvlStatus status;
nvlink_inband_msg_header_t *msghdr = NULL;
nvswitch_inband_data_list *msg = device->link[linkId].inbandData.message;
NvU8 *buffer = device->link[linkId].inbandData.message->data;
NVSWITCH_DRIVER_FABRIC_STATE driver_fabric_state = 0;
NvBool bSendNackOrDrop = NV_FALSE;
NVSWITCH_ASSERT(nvswitch_lib_read_fabric_state(device, NULL, NULL,
&driver_fabric_state) == NVL_SUCCESS);
msghdr = (nvlink_inband_msg_header_t*)buffer;
if (nvswitch_is_message_persistent(device, msghdr))
{
if (nvListCount(&device->link[linkId].inbandData.persistent_list) <
device->hal.nvswitch_get_max_persistent_message_count(device))
{
nvListAdd(&msg->entry, &device->link[linkId].inbandData.persistent_list);
}
else
{
bSendNackOrDrop = NV_TRUE;
}
}
else
{
if (driver_fabric_state == NVSWITCH_DRIVER_FABRIC_STATE_CONFIGURED)
{
nvListAdd(&msg->entry,
&device->link[linkId].inbandData.nonpersistent_list);
}
else
{
bSendNackOrDrop = NV_TRUE;
}
}
if (bSendNackOrDrop)
{
nvswitch_send_nack_or_drop(device, linkId, msghdr);
nvswitch_os_free(msg);
}
else
{
status = nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_INBAND_DATA);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify INBAND_DATA event\n",
__FUNCTION__);
}
}
device->link[linkId].inbandData.message = NULL;
}
/*
@@ -3769,7 +4164,7 @@ nvswitch_lib_smbpbi_log_sxid
{
va_list arglist;
int msglen;
char string[80];
char string[RM_SOE_SMBPBI_CMD_LOG_MESSAGE_MAX_STRING];
va_start(arglist, pFormat);
msglen = nvswitch_os_vsnprintf(string, sizeof(string), pFormat, arglist);
@@ -3778,7 +4173,7 @@ nvswitch_lib_smbpbi_log_sxid
if (!(msglen < 0))
{
msglen = NV_MIN(msglen + 1, (int) sizeof(string));
nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string);
device->hal.nvswitch_smbpbi_log_message(device, sxid, msglen, (NvU8 *) string);
}
}
@@ -4191,10 +4586,51 @@ NvlStatus
nvswitch_launch_ALI_link_training
(
nvswitch_device *device,
nvlink_link *link,
NvBool bSync
)
{
return device->hal.nvswitch_launch_ALI_link_training(device, link, bSync);
}
static NvlStatus
_nvswitch_ctrl_get_err_info
(
nvswitch_device *device,
NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS *ret
)
{
return device->hal.nvswitch_ctrl_get_err_info(device, ret);
}
static NvlStatus
_nvswitch_ctrl_clear_counters
(
nvswitch_device *device,
NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS *ret
)
{
return device->hal.nvswitch_ctrl_clear_counters(device, ret);
}
void
nvswitch_setup_link_system_registers
(
nvswitch_device *device,
nvlink_link *link
)
{
return device->hal.nvswitch_launch_ALI_link_training(device, link);
device->hal.nvswitch_setup_link_system_registers(device, link);
}
void
nvswitch_load_link_disable_settings
(
nvswitch_device *device,
nvlink_link *link
)
{
device->hal.nvswitch_load_link_disable_settings(device, link);
}
NvlStatus
@@ -4242,7 +4678,7 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_therm_read_temperature,
NVSWITCH_CTRL_GET_TEMPERATURE_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_THROUGHPUT_COUNTERS,
_nvswitch_ctrl_get_throughput_counters,
nvswitch_ctrl_get_throughput_counters,
NVSWITCH_GET_THROUGHPUT_COUNTERS_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_FATAL_ERROR_SCOPE,
_nvswitch_ctrl_get_fatal_error_scope,
@@ -4351,6 +4787,9 @@ nvswitch_lib_ctrl
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_BIOS_INFO,
_nvswitch_ctrl_get_bios_info,
NVSWITCH_GET_BIOS_INFO_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_INFOROM_VERSION,
_nvswitch_ctrl_get_inforom_version,
NVSWITCH_GET_INFOROM_VERSION_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_BLACKLIST_DEVICE,
nvswitch_ctrl_blacklist_device,
@@ -4386,6 +4825,16 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_set_training_error_info,
NVSWITCH_SET_TRAINING_ERROR_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_SET_MC_RID_TABLE,
_nvswitch_ctrl_set_mc_rid_table,
NVSWITCH_SET_MC_RID_TABLE_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_MC_RID_TABLE,
_nvswitch_ctrl_get_mc_rid_table,
NVSWITCH_GET_MC_RID_TABLE_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_COUNTERS,
_nvswitch_ctrl_get_counters,
@@ -4413,6 +4862,12 @@ nvswitch_lib_ctrl
CTRL_NVSWITCH_RESERVED_4);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_5);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_8);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_9);
NVSWITCH_DEV_CMD_DISPATCH_RESERVED(
CTRL_NVSWITCH_RESERVED_10);
NVSWITCH_DEV_CMD_DISPATCH(
CTRL_NVSWITCH_GET_TEMPERATURE_LIMIT,
_nvswitch_ctrl_therm_get_temperature_limit,
@@ -4488,6 +4943,23 @@ nvswitch_lib_ctrl
_nvswitch_ctrl_get_sw_info,
NVSWITCH_GET_SW_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_READ,
_nvswitch_ctrl_register_read,
NVSWITCH_REGISTER_READ,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_REGISTER_WRITE,
_nvswitch_ctrl_register_write,
NVSWITCH_REGISTER_WRITE,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_GET_ERR_INFO,
_nvswitch_ctrl_get_err_info,
NVSWITCH_NVLINK_GET_ERR_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(CTRL_NVSWITCH_CLEAR_COUNTERS,
_nvswitch_ctrl_clear_counters,
NVSWITCH_NVLINK_CLEAR_COUNTERS_PARAMS,
osPrivate, flags);
default:
nvswitch_os_print(NVSWITCH_DBG_LEVEL_INFO, "unknown ioctl %x\n", cmd);
retval = -NVL_BAD_ARGS;

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2019-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -24,6 +24,7 @@
#include "common_nvswitch.h"
#include "error_nvswitch.h"
#include "pmgr_nvswitch.h"
#include "soe/soeifcore.h"
void
nvswitch_i2c_init
@@ -32,6 +33,12 @@ nvswitch_i2c_init
)
{
PNVSWITCH_OBJI2C pI2c = nvswitch_os_malloc(sizeof(struct NVSWITCH_OBJI2C));
if (pI2c == NULL)
{
device->pI2c = NULL;
return;
}
nvswitch_os_memset(pI2c, 0, sizeof(struct NVSWITCH_OBJI2C));
device->pI2c = pI2c;
}
@@ -43,7 +50,18 @@ nvswitch_i2c_destroy
)
{
if (device->pI2c == NULL)
{
return;
}
if (device->pI2c->soeI2CSupported)
{
nvswitch_os_unmap_dma_region(device->os_handle, device->pI2c->pCpuAddr, device->pI2c->dmaHandle,
SOE_I2C_DMA_BUF_SIZE, NVSWITCH_DMA_DIR_BIDIRECTIONAL);
nvswitch_os_free_contig_memory(device->os_handle, device->pI2c->pCpuAddr, SOE_I2C_DMA_BUF_SIZE);
device->pI2c->pCpuAddr = NULL;
device->pI2c->dmaHandle = 0;
}
nvswitch_os_free(device->pI2c);
device->pI2c = NULL;

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2020-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2020-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -32,47 +32,6 @@
#include "rmflcncmdif_nvswitch.h"
#define GET_PFIFO_FROM_DEVICE(dev) (&(dev)->pSmbpbi->sharedSurface->inforomObjects.DEM.object.v1)
#define DEM_FIFO_SIZE INFOROM_DEM_OBJECT_V1_00_FIFO_SIZE
#define DEM_FIFO_PTR(x) ((x) % DEM_FIFO_SIZE)
#define DEM_PTR_DIFF(cur, next) (((next) > (cur)) ? ((next) - (cur)) : \
(DEM_FIFO_SIZE - ((cur) - (next))))
#define DEM_BYTES_OCCUPIED(pf) DEM_PTR_DIFF((pf)->readOffset, (pf)->writeOffset)
//
// See how much space is available in the FIFO.
// Must leave 1 word free so the write pointer does not
// catch up with the read pointer. That would be indistinguishable
// from an empty FIFO.
//
#define DEM_BYTES_AVAILABLE(pf) (DEM_PTR_DIFF((pf)->writeOffset, (pf)->readOffset) - \
sizeof(NvU32))
#define DEM_RECORD_SIZE_MAX (sizeof(NV_MSGBOX_DEM_RECORD) \
+ NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
#define DEM_RECORD_SIZE_MIN (sizeof(NV_MSGBOX_DEM_RECORD) + 1)
#define FIFO_REC_LOOP_ITERATOR _curPtr
#define FIFO_REC_LOOP_REC_PTR _recPtr
#define FIFO_REC_LOOP_REC_SIZE _recSize
#define FIFO_REC_LOOP_START(pf, cond) \
{ \
NvU16 _nextPtr; \
for (FIFO_REC_LOOP_ITERATOR = (pf)->readOffset; cond; FIFO_REC_LOOP_ITERATOR = _nextPtr) \
{ \
NV_MSGBOX_DEM_RECORD *FIFO_REC_LOOP_REC_PTR = (NV_MSGBOX_DEM_RECORD *) \
((pf)->fifoBuffer + FIFO_REC_LOOP_ITERATOR); \
NvU16 FIFO_REC_LOOP_REC_SIZE = \
FIFO_REC_LOOP_REC_PTR->recordSize * sizeof(NvU32);
#define FIFO_REC_LOOP_END \
_nextPtr = DEM_FIFO_PTR(FIFO_REC_LOOP_ITERATOR + FIFO_REC_LOOP_REC_SIZE); \
} \
}
static void _smbpbiDemInit(nvswitch_device *device, struct smbpbi *pSmbpbi, struct INFOROM_DEM_OBJECT_V1_00 *pFifo);
static void _nvswitch_smbpbi_dem_flush(nvswitch_device *device);
NvlStatus
nvswitch_smbpbi_init
(
@@ -80,55 +39,36 @@ nvswitch_smbpbi_init
)
{
NV_STATUS status;
NvU64 dmaHandle;
void *cpuAddr;
if (!device->pSoe)
{
return -NVL_ERR_INVALID_STATE;
}
// Create DMA mapping for SMBPBI transactions
status = nvswitch_os_alloc_contig_memory(device->os_handle, &cpuAddr,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
(device->dma_addr_width == 32));
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Failed to allocate contig memory, rc:%d\n",
status);
return status;
}
nvswitch_os_memset(cpuAddr, 0, sizeof(SOE_SMBPBI_SHARED_SURFACE));
status = nvswitch_os_map_dma_region(device->os_handle, cpuAddr, &dmaHandle,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"Failed to map dma region for SMBPBI shared surface, rc:%d\n",
status);
goto os_map_dma_region_fail;
}
device->pSmbpbi = nvswitch_os_malloc(sizeof(struct smbpbi));
if (!device->pSmbpbi)
{
status = -NVL_NO_MEM;
goto smbpbi_init_fail;
}
nvswitch_os_memset(device->pSmbpbi, 0, sizeof(struct smbpbi));
device->pSmbpbi->sharedSurface = cpuAddr;
device->pSmbpbi->dmaHandle = dmaHandle;
status = device->hal.nvswitch_smbpbi_send_init_data(device);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"Failed to send SMBPBI init data, rc:%d\n",
status);
// Do not fail the init because of this.
}
return NVL_SUCCESS;
status = device->hal.nvswitch_smbpbi_alloc(device);
smbpbi_init_fail:
nvswitch_os_unmap_dma_region(device->os_handle, cpuAddr, dmaHandle,
sizeof(SOE_SMBPBI_SHARED_SURFACE), NVSWITCH_DMA_DIR_BIDIRECTIONAL);
os_map_dma_region_fail:
nvswitch_os_free_contig_memory(device->os_handle, cpuAddr, sizeof(SOE_SMBPBI_SHARED_SURFACE));
if (status != NVL_SUCCESS)
{
nvswitch_os_free(device->pSmbpbi);
}
return status;
}
@@ -139,94 +79,24 @@ nvswitch_smbpbi_post_init
nvswitch_device * device
)
{
struct smbpbi *pSmbpbi = device->pSmbpbi;
FLCN *pFlcn;
NvU64 dmaHandle;
RM_FLCN_CMD_SOE cmd;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
RM_SOE_SMBPBI_CMD_INIT *pInitCmd = &cmd.cmd.smbpbiCmd.init;
NvlStatus status;
NvlStatus status;
if (!device->pSmbpbi || !device->pInforom)
if (!device->pSmbpbi)
{
return -NVL_ERR_NOT_SUPPORTED;
}
// Populate shared surface with static InfoROM data
nvswitch_inforom_read_static_data(device, device->pInforom,
&device->pSmbpbi->sharedSurface->inforomObjects);
status = device->hal.nvswitch_smbpbi_post_init_hal(device);
pFlcn = device->pSoe->pFlcn;
dmaHandle = pSmbpbi->dmaHandle;
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, INIT);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_INIT;
RM_FLCN_U64_PACK(&pInitCmd->dmaHandle, &dmaHandle);
//
// Make the interval twice the heartbeat period to avoid
// skew between driver and soe threads
//
pInitCmd->driverPollingPeriodUs = (NVSWITCH_HEARTBEAT_INTERVAL_NS / 1000) * 2;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
if (status == NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI Init command failed. rc:%d\n",
__FUNCTION__, status);
return status;
nvswitch_lib_smbpbi_log_sxid(device, NVSWITCH_ERR_NO_ERROR,
"NVSWITCH SMBPBI server is online.");
NVSWITCH_PRINT(device, INFO, "%s: SMBPBI POST INIT completed\n", __FUNCTION__);
}
nvswitch_lib_smbpbi_log_sxid(device, NVSWITCH_ERR_NO_ERROR,
"NVSWITCH SMBPBI server is online.");
NVSWITCH_PRINT(device, INFO, "%s: SMBPBI POST INIT completed\n", __FUNCTION__);
return NVL_SUCCESS;
}
static void
_nvswitch_smbpbi_send_unload
(
nvswitch_device *device
)
{
FLCN *pFlcn;
RM_FLCN_CMD_SOE cmd;
NVSWITCH_TIMEOUT timeout;
NvU32 cmdSeqDesc;
NvlStatus status;
pFlcn = device->pSoe->pFlcn;
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SMBPBI;
cmd.hdr.size = RM_SOE_CMD_SIZE(SMBPBI, UNLOAD);
cmd.cmd.smbpbiCmd.cmdType = RM_SOE_SMBPBI_CMD_ID_UNLOAD;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1SEC_IN_NS, &timeout);
status = flcnQueueCmdPostBlocking(device, pFlcn,
(PRM_FLCN_CMD)&cmd,
NULL, // pMsg - not used for now
NULL, // pPayload - not used for now
SOE_RM_CMDQ_LOG_ID,
&cmdSeqDesc,
&timeout);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: SMBPBI unload command failed. rc:%d\n",
__FUNCTION__, status);
}
return status;
}
void
@@ -237,8 +107,8 @@ nvswitch_smbpbi_unload
{
if (device->pSmbpbi)
{
_nvswitch_smbpbi_send_unload(device);
_nvswitch_smbpbi_dem_flush(device);
device->hal.nvswitch_smbpbi_send_unload(device);
device->hal.nvswitch_smbpbi_dem_flush(device);
}
}
@@ -250,13 +120,7 @@ nvswitch_smbpbi_destroy
{
if (device->pSmbpbi)
{
nvswitch_os_unmap_dma_region(device->os_handle,
device->pSmbpbi->sharedSurface,
device->pSmbpbi->dmaHandle,
sizeof(SOE_SMBPBI_SHARED_SURFACE),
NVSWITCH_DMA_DIR_BIDIRECTIONAL);
nvswitch_os_free_contig_memory(device->os_handle, device->pSmbpbi->sharedSurface,
sizeof(SOE_SMBPBI_SHARED_SURFACE));
device->hal.nvswitch_smbpbi_destroy_hal(device);
nvswitch_os_free(device->pSmbpbi);
device->pSmbpbi = NULL;
}
@@ -293,391 +157,6 @@ nvswitch_smbpbi_refresh_ecc_counts
return NVL_SUCCESS;
}
NvlStatus
nvswitch_inforom_dem_load
(
nvswitch_device *device
)
{
NvlStatus status;
NvU8 version = 0;
NvU8 subversion = 0;
struct inforom *pInforom = device->pInforom;
NvU8 *pPackedObject = NULL;
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
if ((pInforom == NULL) || (device->pSmbpbi == NULL) ||
(device->pSmbpbi->sharedSurface == NULL))
{
return -NVL_ERR_NOT_SUPPORTED;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
status = nvswitch_inforom_get_object_version_info(device, "DEM", &version,
&subversion);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, INFO, "no DEM object found, rc:%d\n", status);
goto nvswitch_inforom_dem_load_fail;
}
if (!INFOROM_OBJECT_SUBVERSION_SUPPORTS_NVSWITCH(subversion))
{
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
version, subversion);
status = -NVL_ERR_NOT_SUPPORTED;
goto nvswitch_inforom_dem_load_fail;
}
NVSWITCH_PRINT(device, INFO, "DEM v%u.%u found\n", version, subversion);
if (version != 1)
{
NVSWITCH_PRINT(device, WARN, "DEM v%u.%u not supported\n",
version, subversion);
status = -NVL_ERR_NOT_SUPPORTED;
goto nvswitch_inforom_dem_load_fail;
}
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
if (pPackedObject == NULL)
{
status = -NVL_NO_MEM;
goto nvswitch_inforom_dem_load_fail;
}
status = nvswitch_inforom_load_object(device, pInforom, "DEM",
INFOROM_DEM_OBJECT_V1_00_FMT,
pPackedObject,
pFifo);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Failed to load DEM object, rc: %d\n",
status);
goto nvswitch_inforom_dem_load_fail;
}
nvswitch_inforom_dem_load_fail:
if (pPackedObject)
{
nvswitch_os_free(pPackedObject);
}
//
// Mark the cached DEM as usable for Xid logging, even if we were
// unable to find it in the InfoROM image.
//
device->pSmbpbi->sharedSurface->inforomObjects.DEM.bValid = NV_TRUE;
_smbpbiDemInit(device, device->pSmbpbi, pFifo);
return status;
}
/*!
* Validate/Initialize the Driver Event Message (SXid) FIFO buffer
*
* @param[in] device device object pointer
* @param[in] pSmbpbi SMBPBI object pointer
* @param[in,out] pFifo DEM object pointer
*
* @return void
*/
static void
_smbpbiDemInit
(
nvswitch_device *device,
struct smbpbi *pSmbpbi,
struct INFOROM_DEM_OBJECT_V1_00 *pFifo
)
{
NvU8 msgLeft;
unsigned recordsHeld = 0;
NvU16 FIFO_REC_LOOP_ITERATOR;
NvU16 bytesOccupied;
NvU16 bytesSeen;
NvBool status = NV_FALSE;
// validate the FIFO buffer
if ((DEM_FIFO_PTR(pFifo->writeOffset) != pFifo->writeOffset) ||
(DEM_FIFO_PTR(pFifo->readOffset) != pFifo->readOffset) ||
((pFifo->writeOffset % sizeof(NvU32)) != 0) ||
((pFifo->readOffset % sizeof(NvU32)) != 0))
{
goto smbpbiDemInit_exit;
}
if (pFifo->writeOffset == pFifo->readOffset)
{
// The FIFO is empty
status = NV_TRUE;
goto smbpbiDemInit_exit;
}
//
// This HAL extracts from a scratch register the count of DEM messages
// in the FIFO that has not yet been requested by the SMBPBI client.
// If the FIFO holds more messages than that, it means those in excess
// of this count have been delivered to the client by PreOS app.
//
if (device->hal.nvswitch_smbpbi_get_dem_num_messages(device, &msgLeft) != NVL_SUCCESS)
{
// assume the maximum
msgLeft = ~0;
}
if (msgLeft == 0)
{
// Nothing of value in the FIFO. Lets reset it explicitly.
status = NV_TRUE;
pFifo->writeOffset = 0;
pFifo->readOffset = 0;
goto smbpbiDemInit_exit;
}
//
// Count the messages in the FIFO, while also checking the structure
// for integrity. Reset the FIFO in case any corruption is found.
//
bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
bytesSeen = 0;
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
if ((_recSize > DEM_RECORD_SIZE_MAX) ||
(FIFO_REC_LOOP_REC_SIZE < DEM_RECORD_SIZE_MIN))
{
goto smbpbiDemInit_exit;
}
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
++recordsHeld;
FIFO_REC_LOOP_END
if ((bytesSeen != bytesOccupied) || (msgLeft > recordsHeld))
{
goto smbpbiDemInit_exit;
}
//
// Advance the FIFO read ptr in order to remove those messages that
// have already been delivered to the client.
//
FIFO_REC_LOOP_START(pFifo, recordsHeld > msgLeft)
--recordsHeld;
FIFO_REC_LOOP_END
pFifo->readOffset = FIFO_REC_LOOP_ITERATOR;
status = NV_TRUE;
smbpbiDemInit_exit:
if (!status)
{
// Reset the FIFO
pFifo->writeOffset = 0;
pFifo->readOffset = 0;
pFifo->seqNumber = 0;
}
}
static void
_nvswitch_smbpbi_dem_flush(nvswitch_device *device)
{
NvU8 *pPackedObject = NULL;
struct INFOROM_DEM_OBJECT_V1_00 *pFifo;
NvlStatus status = NVL_SUCCESS;
pPackedObject = nvswitch_os_malloc(INFOROM_DEM_OBJECT_V1_00_PACKED_SIZE);
if (pPackedObject == NULL)
{
status = -NVL_NO_MEM;
goto _nvswitch_smbpbi_dem_flush_exit;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
status = nvswitch_inforom_write_object(device, "DEM",
INFOROM_DEM_OBJECT_V1_00_FMT,
pFifo,
pPackedObject);
_nvswitch_smbpbi_dem_flush_exit:
nvswitch_os_free(pPackedObject);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "DEM object write failed, status=%d\n",
status);
}
}
/*!
* A helper to create a new DEM FIFO record
*
* @param[in,out] pFifo DEM object pointer
* @param[in] num Xid number
* @param[in] osErrorString text message to store
* @param[in] msglen message size
* @param[out] pRecSize new record size in bytes
*
* @return ptr to the new record
* @return NULL if there's no room in the FIFO
* or dynamic allocation error
*/
static NV_MSGBOX_DEM_RECORD *
_makeNewRecord
(
INFOROM_DEM_OBJECT_V1_00 *pFifo,
NvU32 num,
NvU8 *osErrorString,
NvU32 msglen,
NvU32 *pRecSize
)
{
NV_MSGBOX_DEM_RECORD *pNewRec;
*pRecSize = NV_MIN(sizeof(NV_MSGBOX_DEM_RECORD) + msglen,
DEM_RECORD_SIZE_MAX);
if ((*pRecSize > DEM_BYTES_AVAILABLE(pFifo)) ||
((pNewRec = nvswitch_os_malloc(*pRecSize)) == NULL))
{
return NULL;
}
// Fill the new record.
nvswitch_os_memset(pNewRec, 0, *pRecSize);
pNewRec->recordSize = NV_UNSIGNED_DIV_CEIL(*pRecSize, sizeof(NvU32));
pNewRec->xidId = num;
pNewRec->seqNumber = pFifo->seqNumber++;
pNewRec->timeStamp = nvswitch_os_get_platform_time() / NVSWITCH_NSEC_PER_SEC;
if (msglen > NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE)
{
// The text string is too long. Truncate and notify the client.
pNewRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
_TRUNC, _SET, pNewRec->flags);
msglen = NV_MSGBOX_MAX_DRIVER_EVENT_MSG_TXT_SIZE - 1;
}
nvswitch_os_memcpy(pNewRec->textMessage, osErrorString, msglen);
return pNewRec;
}
/*!
* A helper to add the new record to the DEM FIFO
*
* @param[in,out] pFifo DEM object pointer
* @param[in] pNewRec the new record
* @param[in] recSize new record size in bytes
*
* @return void
*/
static void
_addNewRecord
(
INFOROM_DEM_OBJECT_V1_00 *pFifo,
NV_MSGBOX_DEM_RECORD *pNewRec,
NvU32 recSize
)
{
NvU16 rem;
NvU16 curPtr;
NvU16 copySz;
NvU8 *srcPtr;
// Copy the new record into the FIFO, handling a possible wrap-around.
rem = recSize;
curPtr = pFifo->writeOffset;
srcPtr = (NvU8 *)pNewRec;
while (rem > 0)
{
copySz = NV_MIN(rem, DEM_FIFO_SIZE - curPtr);
nvswitch_os_memcpy(pFifo->fifoBuffer + curPtr, srcPtr, copySz);
rem -= copySz;
srcPtr += copySz;
curPtr = DEM_FIFO_PTR(curPtr + copySz);
}
// Advance the FIFO write ptr.
pFifo->writeOffset = DEM_FIFO_PTR(pFifo->writeOffset +
(pNewRec->recordSize * sizeof(NvU32)));
}
/*!
* Add a Driver Event Message (SXid) to the InfoROM DEM FIFO buffer
*
* @param[in] device device object pointer
* @param[in] num Xid number
* @param[in] msglen message size
* @param[in] osErrorString text message to store
*
* @return void
*/
void
nvswitch_smbpbi_log_message
(
nvswitch_device *device,
NvU32 num,
NvU32 msglen,
NvU8 *osErrorString
)
{
INFOROM_DEM_OBJECT_V1_00 *pFifo;
NvU32 recSize;
NvU16 FIFO_REC_LOOP_ITERATOR;
NV_MSGBOX_DEM_RECORD *pNewRec;
if ((device->pSmbpbi == NULL) ||
(device->pSmbpbi->sharedSurface == NULL))
{
return;
}
pFifo = GET_PFIFO_FROM_DEVICE(device);
pNewRec = _makeNewRecord(pFifo, num, osErrorString, msglen, &recSize);
if (pNewRec != NULL)
{
_addNewRecord(pFifo, pNewRec, recSize);
nvswitch_os_free(pNewRec);
}
else
{
//
// We are unable to log this message. Mark the latest record
// with a flag telling the client that message(s) were dropped.
//
NvU16 bytesOccupied = DEM_BYTES_OCCUPIED(pFifo);
NvU16 bytesSeen;
NV_MSGBOX_DEM_RECORD *pLastRec = NULL;
// Find the newest record
bytesSeen = 0;
FIFO_REC_LOOP_START(pFifo, bytesSeen < bytesOccupied)
pLastRec = FIFO_REC_LOOP_REC_PTR;
bytesSeen += FIFO_REC_LOOP_REC_SIZE;
FIFO_REC_LOOP_END
if (pLastRec != NULL)
{
pLastRec->flags = FLD_SET_DRF(_MSGBOX, _DEM_RECORD_FLAGS,
_OVFL, _SET, pLastRec->flags);
}
}
return;
}
NvlStatus
nvswitch_smbpbi_set_link_error_info
(

View File

@@ -375,3 +375,20 @@ soeWaitForInitAck_HAL
return pSoe->base.pHal->waitForInitAck(device, pSoe);
}
NvlStatus
soeI2CAccess_HAL
(
nvswitch_device *device,
NVSWITCH_CTRL_I2C_INDEXED_PARAMS *pParams
)
{
PSOE pSoe = (PSOE)device->pSoe;
if (pSoe->base.pHal->i2cAccess == NULL)
{
NVSWITCH_ASSERT(0);
return 0;
}
return pSoe->base.pHal->i2cAccess(device, pParams);
}

View File

@@ -179,6 +179,10 @@ soeSetupHal
{
soeSetupHal_LR10(pSoe);
}
else if (nvswitch_is_ls10_device_id(pci_device_id))
{
soeSetupHal_LS10(pSoe);
}
else
{
// we're on a device which doesn't support SOE

View File

@@ -48,7 +48,7 @@ nvswitch_spi_init
nvswitch_os_memset(&cmd, 0, sizeof(cmd));
cmd.hdr.unitId = RM_SOE_UNIT_SPI;
cmd.hdr.size = sizeof(cmd);
cmd.hdr.size = RM_FLCN_QUEUE_HDR_SIZE + sizeof(RM_SOE_SPI_CMD);
cmd.cmd.spi.cmdType = RM_SOE_SPI_INIT;
nvswitch_timeout_create(NVSWITCH_INTERVAL_1MSEC_IN_NS * 30, &timeout);