545.23.06

This commit is contained in:
Andy Ritger
2023-10-17 09:25:29 -07:00
parent f59818b751
commit b5bf85a8e3
917 changed files with 132480 additions and 110015 deletions

View File

@@ -94,12 +94,12 @@ static NV_INLINE void nvswitch_clear_flags(NvU32 *val, NvU32 flags)
#endif
#define NV_ARRAY_ELEMENTS(x) ((sizeof(x)/sizeof((x)[0])))
#define NVSWITCH_DBG_LEVEL NVSWITCH_DBG_LEVEL_INFO
#define NVSWITCH_DBG_LEVEL(_d) (_d == NULL ? NVSWITCH_DBG_LEVEL_INFO : ((nvswitch_device *)_d)->regkeys.debug_level)
#if defined(DEVELOP) || defined(DEBUG) || defined(NV_MODS)
#define NVSWITCH_PRINT(_d, _lvl, _fmt, ...) \
((NVSWITCH_DBG_LEVEL <= NVSWITCH_DBG_LEVEL_ ## _lvl) ? \
((NVSWITCH_DBG_LEVEL(_d) <= NVSWITCH_DBG_LEVEL_ ## _lvl) ? \
nvswitch_os_print(NVSWITCH_DBG_LEVEL_ ## _lvl, \
"%s[%-5s]: " _fmt, \
((_d == NULL) ? \
@@ -271,6 +271,7 @@ typedef struct
NvU32 surpress_link_errors_for_gpu_reset;
NvU32 block_code_mode;
NvU32 reference_clock_mode;
NvU32 debug_level;
} NVSWITCH_REGKEY_TYPE;
//
@@ -341,6 +342,30 @@ struct NVSWITCH_CLIENT_EVENT
void *private_driver_data;
};
typedef struct
{
NvU8 port_event_type; // 0 = port up, 1 = port down, 2 = error invalid entry
NvU64 local_port_event_num; // Count of preceding port events (local port event log)
NvU64 global_port_event_num; // Count of preceding port events (globally)
NvU32 link_id; // Link that event occured on
NvU64 time; // Platform time, in ns
} NVSWITCH_PORT_EVENT_TYPE;
#define NVSWITCH_PORT_EVENT_LOG_SIZE 1024
typedef struct
{
NvU32 port_event_start; // Start index within CB (circular buffer)
NvU32 port_event_count; // Count of current port events in CB
NvU64 port_event_total; // Count of total port events logged
NvU32 port_event_log_size; // CB size
NVSWITCH_PORT_EVENT_TYPE *port_event_log;
NvBool overwritable; // Old entries can be overwritten
NvBool bOverflow; // True when log has been overflowed and no
// longer contains all port events that occurred
} NVSWITCH_PORT_EVENT_LOG_TYPE;
//
// common device information
//
@@ -369,6 +394,9 @@ struct nvswitch_device
NVSWITCH_ERROR_LOG_TYPE log_FATAL_ERRORS;
NVSWITCH_ERROR_LOG_TYPE log_NONFATAL_ERRORS;
// Port Events
NVSWITCH_PORT_EVENT_LOG_TYPE log_PORT_EVENTS;
NVSWITCH_FIRMWARE firmware;
// HAL connectivity
@@ -582,4 +610,7 @@ void nvswitch_apply_recal_settings(nvswitch_device *device, nvlink_link *li
void nvswitch_init_buffer_ready(nvswitch_device *device, nvlink_link *link, NvBool bNportBufferReady);
NvBool nvswitch_does_link_need_termination_enabled(nvswitch_device *device, nvlink_link *link);
NvlStatus nvswitch_link_termination_setup(nvswitch_device *device, nvlink_link* link);
void nvswitch_record_port_event(nvswitch_device *device, NVSWITCH_PORT_EVENT_LOG_TYPE *port_events, NvU32 link_id, NvU8 port_event_type);
NvlStatus nvswitch_ctrl_get_port_events(nvswitch_device *device, NVSWITCH_GET_PORT_EVENTS_PARAMS *p);
#endif //_COMMON_NVSWITCH_H_

View File

@@ -158,6 +158,7 @@
_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_bbx_get_data, (nvswitch_device *device, NvU8 dataType, void * 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) \
@@ -213,7 +214,6 @@
_op(void, nvswitch_reset_persistent_link_hw_state, (nvswitch_device *device, NvU32 linkNumber), _arch)\
_op(void, nvswitch_store_topology_information, (nvswitch_device *device, nvlink_link *link), _arch) \
_op(void, nvswitch_init_lpwr_regs, (nvlink_link *link), _arch) \
_op(void, nvswitch_program_l1_scratch_reg, (nvswitch_device *device, NvU32 linkNumber), _arch) \
_op(NvlStatus, nvswitch_set_training_mode, (nvswitch_device *device), _arch) \
_op(NvU32, nvswitch_get_sublink_width, (nvswitch_device *device, NvU32 linkNumber), _arch) \
_op(NvBool, nvswitch_i2c_is_device_access_allowed, (nvswitch_device *device, NvU32 port, NvU8 addr, NvBool bIsRead), _arch) \

View File

@@ -184,6 +184,7 @@ NvlStatus nvswitch_inforom_bbx_add_sxid(nvswitch_device *device,
NvU32 data1, NvU32 data2);
NvlStatus nvswitch_inforom_bbx_get_sxid(nvswitch_device *device,
NVSWITCH_GET_SXIDS_PARAMS *params);
NvlStatus nvswitch_inforom_bbx_get_data(nvswitch_device *device, NvU8 dataType, void *params);
// InfoROM DEM APIs
NvlStatus nvswitch_inforom_dem_load(nvswitch_device *device);

View File

@@ -169,4 +169,12 @@ nvswitch_bbx_get_sxid_lr10
NVSWITCH_GET_SXIDS_PARAMS * params
);
NvlStatus
nvswitch_bbx_get_data_lr10
(
nvswitch_device *device,
NvU8 dataType,
void *params
);
#endif //_INFOROM_LR10_H_

View File

@@ -652,7 +652,6 @@ void nvswitch_setup_link_loopback_mode_lr10(nvswitch_device *device, NvU32
void nvswitch_reset_persistent_link_hw_state_lr10(nvswitch_device *device, NvU32 linkNumber);
void nvswitch_store_topology_information_lr10(nvswitch_device *device, nvlink_link *link);
void nvswitch_init_lpwr_regs_lr10(nvlink_link *link);
void nvswitch_program_l1_scratch_reg_lr10(nvswitch_device *device, NvU32 linkNumber);
NvlStatus nvswitch_set_training_mode_lr10(nvswitch_device *device);
NvBool nvswitch_i2c_is_device_access_allowed_lr10(nvswitch_device *device, NvU32 port, NvU8 addr, NvBool bIsRead);
NvU32 nvswitch_get_sublink_width_lr10(nvswitch_device *device,NvU32 linkNumber);

View File

@@ -154,4 +154,11 @@ nvswitch_bbx_get_sxid_ls10
NVSWITCH_GET_SXIDS_PARAMS * params
);
NvlStatus
nvswitch_bbx_get_data_ls10
(
nvswitch_device *device,
NvU8 dataType,
void *params
);
#endif //_INFOROM_LS10_H_

View File

@@ -938,7 +938,6 @@ void nvswitch_corelib_clear_link_state_lr10(nvlink_link *link);
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);
void nvswitch_program_l1_scratch_reg_ls10(nvswitch_device *device, NvU32 linkNumber);
NvlStatus nvswitch_minion_service_falcon_interrupts_ls10(nvswitch_device *device, NvU32 instance);

View File

@@ -620,4 +620,21 @@
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_NON_COMMON_NO_SS 0x2
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_NON_COMMON_SS 0x3
/*
* NV_SWITCH_REGKEY_DBG_LEVEL - Adjusts the amount of debug prints that will be generated
*
* Prints will be generated at the specified level and above. Eg. Debug level 0 will
* enable all prints
*
* Private: Debug use only
*/
#define NV_SWITCH_REGKEY_DBG_LEVEL "DebugLevel"
#define NV_SWITCH_REGKEY_DBG_LEVEL_DEFAULT NV_SWITCH_REGKEY_DBG_LEVEL_INFO
#define NV_SWITCH_REGKEY_DBG_LEVEL_MMIO 0x0
#define NV_SWITCH_REGKEY_DBG_LEVEL_NOISY 0x1
#define NV_SWITCH_REGKEY_DBG_LEVEL_INFO 0x2
#define NV_SWITCH_REGKEY_DBG_LEVEL_SETUP 0x3
#define NV_SWITCH_REGKEY_DBG_LEVEL_WARN 0x4
#define NV_SWITCH_REGKEY_DBG_LEVEL_ERROR 0x5
#endif //_REGKEY_NVSWITCH_H_

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -130,3 +130,21 @@ nvswitch_inforom_bbx_get_sxid
return status;
}
NvlStatus
nvswitch_inforom_bbx_get_data
(
nvswitch_device *device,
NvU8 dataType,
void *params
)
{
NvlStatus status;
status = device->hal.nvswitch_bbx_get_data(device, dataType, params);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: (type=%d) failed, status=%d\n", __FUNCTION__, dataType, status);
}
return status;
}

View File

@@ -32,6 +32,7 @@
#include "nvVer.h"
#include "regkey_nvswitch.h"
#include "inforom/inforom_nvl_v3_nvswitch.h"
#include "soe/soeififr.h"
//
// TODO: Split individual object hals to their own respective files
@@ -1280,3 +1281,14 @@ nvswitch_bbx_get_sxid_lr10
return -NVL_ERR_NOT_SUPPORTED;
}
NvlStatus
nvswitch_bbx_get_data_lr10
(
nvswitch_device *device,
NvU8 dataType,
void *params
)
{
return -NVL_ERR_NOT_SUPPORTED;
}

View File

@@ -566,6 +566,11 @@ nvswitch_init_lpwr_regs_lr10
NvU8 softwareDesired, hardwareDisable;
NvBool bLpEnable;
if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
{
return;
}
if (device->regkeys.enable_pm == NV_SWITCH_REGKEY_ENABLE_PM_NO)
{
return;
@@ -681,15 +686,6 @@ nvswitch_init_lpwr_regs_lr10
tempRegVal);
}
void
nvswitch_program_l1_scratch_reg_lr10
(
nvswitch_device *device,
NvU32 linkNumber
)
{
// Not Implemented for LR10
}
void
nvswitch_init_buffer_ready_lr10
@@ -1020,6 +1016,7 @@ nvswitch_corelib_set_dl_link_mode_lr10
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_DOWN event\n",
__FUNCTION__);
}
nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link->linkNumber, NVSWITCH_PORT_EVENT_TYPE_DOWN);
break;
}
@@ -2006,6 +2003,7 @@ nvswitch_corelib_training_complete_lr10
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_UP event\n",
__FUNCTION__);
}
nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link->linkNumber, NVSWITCH_PORT_EVENT_TYPE_UP);
}

View File

@@ -837,23 +837,23 @@ nvswitch_read_vbios_link_entries_lr10
link_entries[i].nvLinkparam6 = (NvU8)vbios_link_entry.nvLinkparam6;
tblPtr += (sizeof(NVLINK_VBIOS_CONFIG_DATA_LINKENTRY_20)/sizeof(NvU32));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink ID 0x%x ---->>>\n", i);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 0 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam0, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam0));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 1 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam1, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam1));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 2 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam2, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam2));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 3 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam3, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam3));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 4 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam4, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam4));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 5 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam5, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam5));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 6 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam6, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam6));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink ID 0x%x ---->>>\n\n", i);
}
*identified_link_entriesCount = i;
@@ -914,23 +914,23 @@ _nvswitch_vbios_fetch_nvlink_entries
goto vbios_fetch_nvlink_entries_done;
}
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink Header ---->>>\n\n");
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Version \t\t 0x%x\n", header.ver_20.Version);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Header Size \t0x%x\n", header.ver_20.HeaderSize);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Base Entry Size \t0x%x\n", header.ver_20.BaseEntrySize);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Base Entry count \t0x%x\n", header.ver_20.BaseEntryCount);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Link Entry Size \t0x%x\n", header.ver_20.LinkEntrySize);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Link Entry Count \t0x%x\n", header.ver_20.LinkEntryCount);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"Reserved \t0x%x\n", header.ver_20.Reserved);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink Header ---->>>\n");
if (header.ver_20.Version == NVLINK_CONFIG_DATA_HEADER_VER_20)
{
@@ -6668,6 +6668,12 @@ nvswitch_is_soe_supported_lr10
nvswitch_device *device
)
{
if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES)
{
NVSWITCH_PRINT(device, INFO, "SOE is disabled via regkey.\n");
return NV_FALSE;
}
return NV_TRUE;
}

View File

@@ -32,7 +32,7 @@
#include <stddef.h>
#define VERBOSE_MMIO_DISCOVERY 1
#define VERBOSE_MMIO_DISCOVERY 0
#define MAKE_DISCOVERY_LS10(_engine) \
{ \

View File

@@ -863,3 +863,174 @@ nvswitch_bbx_get_sxid_ls10_free_and_exit:
return status;
}
NvlStatus
nvswitch_bbx_get_data_ls10
(
nvswitch_device *device,
NvU8 dataType,
void *params
)
{
NvlStatus status;
void *pDmaBuf;
NvU64 dmaHandle;
FLCN *pFlcn;
RM_FLCN_CMD_SOE bbxCmd;
NvU32 cmdSeqDesc;
NVSWITCH_TIMEOUT timeout;
NvU32 transferSize;
if (!nvswitch_is_inforom_supported_ls10(device))
{
NVSWITCH_PRINT(device, ERROR, "%s: InfoROM is not supported\n", __FUNCTION__);
return -NVL_ERR_NOT_SUPPORTED;
}
if (params == NULL)
{
NVSWITCH_PRINT(device, ERROR, "%s: params is NULL\n", __FUNCTION__);
return -NVL_BAD_ARGS;
}
switch (dataType)
{
case RM_SOE_IFR_BBX_GET_SYS_INFO:
transferSize = sizeof(NVSWITCH_GET_SYS_INFO_PARAMS);
break;
case RM_SOE_IFR_BBX_GET_TIME_INFO:
transferSize = sizeof(NVSWITCH_GET_TIME_INFO_PARAMS);
break;
case RM_SOE_IFR_BBX_GET_TEMP_DATA:
transferSize = sizeof(NVSWITCH_GET_TEMP_DATA_PARAMS);
break;
case RM_SOE_IFR_BBX_GET_TEMP_SAMPLES:
transferSize = sizeof(NVSWITCH_GET_TEMP_SAMPLES_PARAMS);
break;
default:
NVSWITCH_PRINT(device, ERROR, "Unknown dataType %d", dataType);
return -NVL_BAD_ARGS;
break;
}
status = nvswitch_os_alloc_contig_memory(device->os_handle, &pDmaBuf, transferSize,
(device->dma_addr_width == 32));
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to allocate contig memory. rc:%d\n", __FUNCTION__, status);
return status;
}
status = nvswitch_os_map_dma_region(device->os_handle, pDmaBuf, &dmaHandle,
transferSize, NVSWITCH_DMA_DIR_TO_SYSMEM);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to map DMA region. rc:%d\n", __FUNCTION__, status);
goto nvswitch_bbx_get_data_ls10_free_and_exit;
}
nvswitch_os_memset(pDmaBuf, 0, transferSize);
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_DATA_GET;
bbxCmd.cmd.ifr.bbxDataGet.sizeInBytes = transferSize;
bbxCmd.cmd.ifr.bbxDataGet.dataType = dataType;
RM_FLCN_U64_PACK(&bbxCmd.cmd.ifr.bbxDataGet.dmaHandle, &dmaHandle);
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: BX_GET_DATA type=%d failed. rc:%d\n",
__FUNCTION__, dataType, status);
goto nvswitch_bbx_get_data_ls10_unmap_and_exit;
}
status = nvswitch_os_sync_dma_region_for_cpu(device->os_handle, dmaHandle,
transferSize,
NVSWITCH_DMA_DIR_TO_SYSMEM);
if (status != NV_OK)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to sync DMA region. rc:%d\n", __FUNCTION__, status);
goto nvswitch_bbx_get_data_ls10_unmap_and_exit;
}
if (dataType == RM_SOE_IFR_BBX_GET_SYS_INFO)
{
NVSWITCH_GET_SYS_INFO_PARAMS bbxSysInfoData = {0};
nvswitch_os_memcpy((NvU8 *)&bbxSysInfoData, (NvU8 *)pDmaBuf, sizeof(NVSWITCH_GET_SYS_INFO_PARAMS));
nvswitch_os_memcpy((NvU8 *)params, (NvU8 *)&bbxSysInfoData, sizeof(NVSWITCH_GET_SYS_INFO_PARAMS));
}
else if (dataType == RM_SOE_IFR_BBX_GET_TIME_INFO)
{
NVSWITCH_GET_TIME_INFO_PARAMS bbxTimeInfoData = {0};
nvswitch_os_memcpy((NvU8 *)&bbxTimeInfoData, (NvU8 *)pDmaBuf, sizeof(NVSWITCH_GET_TIME_INFO_PARAMS));
nvswitch_os_memcpy((NvU8 *)params, (NvU8 *)&bbxTimeInfoData, sizeof(NVSWITCH_GET_TIME_INFO_PARAMS));
}
else if (dataType == RM_SOE_IFR_BBX_GET_TEMP_DATA)
{
NVSWITCH_GET_TEMP_DATA_PARAMS *pBbxTempData = NULL;
pBbxTempData = nvswitch_os_malloc(sizeof(NVSWITCH_GET_TEMP_DATA_PARAMS));
if (pBbxTempData == NULL)
{
NVSWITCH_PRINT(device, ERROR, "Out of memory: dataType %d", dataType);
status = -NVL_NO_MEM;
goto nvswitch_bbx_get_data_ls10_unmap_and_exit;
}
nvswitch_os_memset(pBbxTempData, 0, sizeof(NVSWITCH_GET_TEMP_DATA_PARAMS));
nvswitch_os_memcpy((NvU8 *)pBbxTempData, (NvU8 *)pDmaBuf, sizeof(NVSWITCH_GET_TEMP_DATA_PARAMS));
nvswitch_os_memcpy((NvU8 *)params, (NvU8 *)pBbxTempData, sizeof(NVSWITCH_GET_TEMP_DATA_PARAMS));
nvswitch_os_free(pBbxTempData);
}
else if (dataType == RM_SOE_IFR_BBX_GET_TEMP_SAMPLES)
{
NVSWITCH_GET_TEMP_SAMPLES_PARAMS *pBbxTempSamples = NULL;
pBbxTempSamples = nvswitch_os_malloc(sizeof(NVSWITCH_GET_TEMP_SAMPLES_PARAMS));
if (pBbxTempSamples == NULL)
{
NVSWITCH_PRINT(device, ERROR, "Out of memory: dataType %d", dataType);
status = -NVL_NO_MEM;
goto nvswitch_bbx_get_data_ls10_unmap_and_exit;
}
nvswitch_os_memset(pBbxTempSamples, 0, sizeof(NVSWITCH_GET_TEMP_SAMPLES_PARAMS));
nvswitch_os_memcpy((NvU8 *)pBbxTempSamples, (NvU8 *)pDmaBuf, sizeof(NVSWITCH_GET_TEMP_SAMPLES_PARAMS));
nvswitch_os_memcpy((NvU8 *)params, (NvU8 *)pBbxTempSamples, sizeof(NVSWITCH_GET_TEMP_SAMPLES_PARAMS));
nvswitch_os_free(pBbxTempSamples);
}
else
{
NVSWITCH_PRINT(device, ERROR, "Unknown dataType %d", dataType);
goto nvswitch_bbx_get_data_ls10_unmap_and_exit;
}
nvswitch_bbx_get_data_ls10_unmap_and_exit:
nvswitch_os_unmap_dma_region(device->os_handle, pDmaBuf, dmaHandle,
transferSize, NVSWITCH_DMA_DIR_FROM_SYSMEM);
nvswitch_bbx_get_data_ls10_free_and_exit:
nvswitch_os_free_contig_memory(device->os_handle, pDmaBuf, transferSize);
return status;
}

View File

@@ -5545,8 +5545,6 @@ _nvswitch_emit_link_errors_nvldl_fatal_link_ls10
if (nvswitch_test_flags(pending, bit))
{
NVSWITCH_REPORT_FATAL(_HW_DLPL_LTSSM_FAULT_DOWN, "LTSSM Fault Down", NV_FALSE);
error_event.error = INFOROM_NVLINK_DL_LTSSM_FAULT_DOWN_FATAL;
nvswitch_inforom_nvlink_log_error_event(device, &error_event);
}
}
@@ -5827,17 +5825,18 @@ _nvswitch_deferred_link_state_check_ls10
NvU64 lastLinkUpTime;
NvU64 lastRetrainTime;
NvU64 current_time = nvswitch_os_get_platform_time();
NvBool bRedeferLinkStateCheck;
chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
lastLinkUpTime = chip_device->deferredLinkErrors[link].state.lastLinkUpTime;
lastRetrainTime = chip_device->deferredLinkErrors[link].state.lastRetrainTime;
// Sanity Check
NVSWITCH_ASSERT(nvswitch_is_link_valid(device, link));
nvswitch_os_free(pErrorReportParams);
pErrorReportParams = NULL;
chip_device->deferredLinkErrors[link].state.bLinkStateCallBackEnabled = NV_FALSE;
bRedeferLinkStateCheck = NV_FALSE;
// Link came up after last retrain
if (lastLinkUpTime >= lastRetrainTime)
@@ -5854,16 +5853,21 @@ _nvswitch_deferred_link_state_check_ls10
{
if ((current_time - lastRetrainTime) < NVSWITCH_DEFERRED_LINK_STATE_CHECK_INTERVAL_NS)
{
nvswitch_create_deferred_link_state_check_task_ls10(device, nvlipt_instance, link);
return;
bRedeferLinkStateCheck = NV_TRUE;
}
}
if (bRedeferLinkStateCheck)
{
nvswitch_create_deferred_link_state_check_task_ls10(device, nvlipt_instance, link);
return;
}
//
// Otherwise, the link hasn't retrained within the timeout so emit the
// deferred errors.
//
_nvswitch_emit_deferred_link_errors_ls10(device, nvlipt_instance, link);
_nvswitch_emit_deferred_link_errors_ls10(device, nvlipt_instance, link);
_nvswitch_clear_deferred_link_errors_ls10(device, link);
}
@@ -5948,9 +5952,9 @@ _nvswitch_deferred_link_errors_check_ls10
// It is assumed that this callback runs long before a link could have been
// retrained and hit errors again.
//
_nvswitch_emit_deferred_link_errors_ls10(device, nvlipt_instance, link);
_nvswitch_clear_deferred_link_errors_ls10(device, link);
}
_nvswitch_emit_deferred_link_errors_ls10(device, nvlipt_instance, link);
_nvswitch_clear_deferred_link_errors_ls10(device, link);
}
static void
_nvswitch_create_deferred_link_errors_task_ls10
@@ -6645,6 +6649,12 @@ _nvswitch_service_nvlipt_lnk_status_ls10
link = nvswitch_get_link(device, link_id);
chip_device = NVSWITCH_GET_CHIP_DEVICE_LS10(device);
if (link == NULL)
{
return -NVL_BAD_ARGS;
}
pending = NVSWITCH_LINK_RD32(device, link_id, NVLIPT_LNK, _NVLIPT_LNK, _INTR_STATUS);
enabled = NVSWITCH_LINK_RD32(device, link_id, NVLIPT_LNK, _NVLIPT_LNK, _INTR_INT1_EN);
pending &= enabled;
@@ -6670,12 +6680,6 @@ _nvswitch_service_nvlipt_lnk_status_ls10
{
NVSWITCH_PRINT(device, INFO, "%s: nvlipt_lnk_status: Link is up!. LinkId %d\n",
__FUNCTION__, link_id);
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_PORT_UP) != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_UP event. LinkId %d\n",
__FUNCTION__, link_id);
}
//
// When a link comes up ensure that we finish off the post-training tasks:
@@ -6684,7 +6688,7 @@ _nvswitch_service_nvlipt_lnk_status_ls10
//
nvswitch_corelib_training_complete_ls10(link);
nvswitch_init_buffer_ready(device, link, NV_TRUE);
link->bRxDetected = NV_TRUE;
link->bRxDetected = NV_TRUE;
//
// Clear out any cached interrupts for the link and update the last link up timestamp
@@ -7754,38 +7758,51 @@ nvswitch_service_nvldl_fatal_link_ls10
// pending DL interrupts. In order to log all error before wiping that state,
// service all other interrupts before this one
//
bit = DRF_NUM(_NVLDL_TOP, _INTR, _LTSSM_FAULT_DOWN, 1);
if (nvswitch_test_flags(pending, bit))
{
nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link, NVSWITCH_PORT_EVENT_TYPE_DOWN);
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_PORT_DOWN) != NVL_SUCCESS)
{
dlDeferredIntrLinkMask |= bit;
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_DOWN event\n",
__FUNCTION__);
}
dlDeferredIntrLinkMask |= bit;
//
// Since reset and drain will reset the link, including clearing
// pending interrupts, skip the clear write below. There are cases
// where link clocks will not be on after reset and drain so there
// maybe PRI errors on writing to the register
//
bRequireResetAndDrain = NV_TRUE;
}
//
// Since reset and drain will reset the link, including clearing
// pending interrupts, skip the clear write below. There are cases
// where link clocks will not be on after reset and drain so there
// maybe PRI errors on writing to the register
//
{
bRequireResetAndDrain = NV_TRUE;
}
nvswitch_clear_flags(&unhandled, bit);
}
bit = DRF_NUM(_NVLDL_TOP, _INTR, _LTSSM_FAULT_UP, 1);
if (nvswitch_test_flags(pending, bit))
{
nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link, NVSWITCH_PORT_EVENT_TYPE_DOWN);
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_PORT_DOWN) != NVL_SUCCESS)
{
dlDeferredIntrLinkMask |= bit;
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_DOWN event\n",
__FUNCTION__);
}
dlDeferredIntrLinkMask |= bit;
//
// Since reset and drain will reset the link, including clearing
// pending interrupts, skip the clear write below. There are cases
// where link clocks will not be on after reset and drain so there
// maybe PRI errors on writing to the register
//
bRequireResetAndDrain = NV_TRUE;
}
//
// Since reset and drain will reset the link, including clearing
// pending interrupts, skip the clear write below. There are cases
// where link clocks will not be on after reset and drain so there
// maybe PRI errors on writing to the register
//
{
bRequireResetAndDrain = NV_TRUE;
}
nvswitch_clear_flags(&unhandled, bit);
}

View File

@@ -98,30 +98,6 @@ _nvswitch_configure_reserved_throughput_counters
DRF_DEF(_NVLTLC_TX_LNK, _DEBUG_TP_CNTR_CTRL_0, _ENABLE, _ENABLE));
}
void
nvswitch_program_l1_scratch_reg_ls10
(
nvswitch_device *device,
NvU32 linkNumber
)
{
NvU32 scrRegVal;
NvU32 tempRegVal;
// Read L1 register and store initial/VBIOS L1 Threshold Value in Scratch register
tempRegVal = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_L1_ENTER_THRESHOLD);
scrRegVal = NVSWITCH_LINK_RD32_LS10(device, linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _SCRATCH_WARM);
// Update the scratch register value only if it has not been written to before
if (scrRegVal == NV_NVLIPT_LNK_SCRATCH_WARM_DATA_INIT)
{
NVSWITCH_LINK_WR32_LS10(device, linkNumber, NVLIPT_LNK, _NVLIPT_LNK, _SCRATCH_WARM, tempRegVal);
}
}
#define BUG_3797211_LS10_VBIOS_VERSION 0x9610410000
void
nvswitch_init_lpwr_regs_ls10
(
@@ -134,55 +110,33 @@ nvswitch_init_lpwr_regs_ls10
NvU32 tempRegVal, lpEntryThreshold;
NvU8 softwareDesired;
NvBool bLpEnable;
NvU64 biosVersion;
if (IS_RTLSIM(device) || IS_EMULATION(device) || IS_FMODEL(device))
{
return;
}
if (device->regkeys.enable_pm == NV_SWITCH_REGKEY_ENABLE_PM_NO)
{
return;
}
if (nvswitch_lib_get_bios_version(device, &biosVersion) != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, WARN, "%s Get VBIOS version failed.\n",
__FUNCTION__);
biosVersion = 0;
}
// bios_config = nvswitch_get_bios_nvlink_config(device);
if (biosVersion >= BUG_3797211_LS10_VBIOS_VERSION)
// IC Enter Threshold
if (device->regkeys.lp_threshold == NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT)
{
// IC Enter Threshold
if (device->regkeys.lp_threshold == NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT)
{
//
// Do nothing since VBIOS (version 96.10.41.00.00 and above)
// sets the default L1 threshold.
// Refer Bug 3797211 for more info.
//
}
else
{
lpEntryThreshold = device->regkeys.lp_threshold;
tempRegVal = 0;
tempRegVal = FLD_SET_DRF_NUM(_NVLIPT, _LNK_PWRM_L1_ENTER_THRESHOLD, _THRESHOLD, lpEntryThreshold, tempRegVal);
NVSWITCH_LINK_WR32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_L1_ENTER_THRESHOLD, tempRegVal);
}
//
// Do nothing since VBIOS sets the default L1 threshold.
// Refer Bug 3797211 for more info.
//
}
else
{
// IC Enter Threshold
if (device->regkeys.lp_threshold == NV_SWITCH_REGKEY_SET_LP_THRESHOLD_DEFAULT)
{
lpEntryThreshold = 1;
}
else
{
lpEntryThreshold = device->regkeys.lp_threshold;
}
tempRegVal = 0;
tempRegVal = FLD_SET_DRF_NUM(_NVLIPT, _LNK_PWRM_L1_ENTER_THRESHOLD, _THRESHOLD, lpEntryThreshold, tempRegVal);
NVSWITCH_LINK_WR32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_L1_ENTER_THRESHOLD, tempRegVal);
lpEntryThreshold = device->regkeys.lp_threshold;
tempRegVal = 0;
tempRegVal = FLD_SET_DRF_NUM(_NVLIPT, _LNK_PWRM_L1_ENTER_THRESHOLD, _THRESHOLD, lpEntryThreshold, tempRegVal);
NVSWITCH_LINK_WR32_LS10(device, linkNum, NVLIPT_LNK, _NVLIPT_LNK, _PWRM_L1_ENTER_THRESHOLD, tempRegVal);
}
//LP Entry Enable
@@ -211,6 +165,7 @@ nvswitch_corelib_training_complete_ls10
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_UP event\n",
__FUNCTION__);
}
nvswitch_record_port_event(device, &(device->log_PORT_EVENTS), link->linkNumber, NVSWITCH_PORT_EVENT_TYPE_UP);
return;
}
@@ -1470,7 +1425,7 @@ nvswitch_load_link_disable_settings_ls10
nvswitch_device *device,
nvlink_link *link
)
{
{
NvU32 regVal;
// Read state from NVLIPT HW
@@ -1479,7 +1434,7 @@ nvswitch_load_link_disable_settings_ls10
if (FLD_TEST_DRF(_NVLIPT_LNK, _CTRL_LINK_STATE_STATUS, _CURRENTLINKSTATE, _DISABLE, regVal))
{
// Set link to invalid and unregister from corelib
device->link[link->linkNumber].valid = NV_FALSE;
nvlink_lib_unregister_link(link);
@@ -1619,7 +1574,7 @@ nvswitch_reset_and_train_link_ls10
link_intr_subcode = DRF_VAL(_NVLSTAT, _MN00, _LINK_INTR_SUBCODE, stat_data);
if ((link_state == NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_STATUS_MINION_REQUEST_FAIL) &&
(link_intr_subcode == MINION_ALARM_BUSY))
(link_intr_subcode == MINION_ALARM_BUSY))
{
status = nvswitch_request_tl_link_state_ls10(link,

View File

@@ -1353,7 +1353,7 @@ nvswitch_init_warm_reset_ls10
)
{
NVSWITCH_PRINT(device, WARN, "%s: Function not implemented\n", __FUNCTION__);
}
}
//
// Helper funcction to query MINION to see if DL clocks are on
@@ -1401,11 +1401,8 @@ _nvswitch_are_dl_clocks_on
return NV_TRUE;
}
//
// Implement reset and drain sequence for ls10
//
NvlStatus
nvswitch_reset_and_drain_links_ls10
static NvlStatus
_nvswitch_reset_and_drain_links_ls10
(
nvswitch_device *device,
NvU64 link_mask
@@ -1425,7 +1422,6 @@ nvswitch_reset_and_drain_links_ls10
NvBool bAreDlClocksOn;
NVSWITCH_TIMEOUT timeout;
if (link_mask == 0)
{
NVSWITCH_PRINT(device, ERROR, "%s: Invalid link_mask 0\n",
@@ -1538,6 +1534,14 @@ nvswitch_reset_and_drain_links_ls10
NVSWITCH_PRINT(device, ERROR,
"%s: link %d failed to enter emergency shutdown\n",
__FUNCTION__, link);
// Re-register links.
status = nvlink_lib_register_link(device->nvlink_device, link_info);
if (status != NVL_SUCCESS)
{
nvswitch_destroy_link(link_info);
}
continue;
}
@@ -1632,10 +1636,10 @@ nvswitch_reset_and_drain_links_ls10
nvswitch_soe_restore_nport_state_ls10(device, link);
// Step 7.0 : Re-program the routing table for DBEs
// Step 8.0 : Reset NVLW and NPORT interrupt state
_nvswitch_link_reset_interrupts_ls10(device, link);
// Re-register links.
status = nvlink_lib_register_link(device->nvlink_device, link_info);
if (status != NVL_SUCCESS)
@@ -1654,16 +1658,18 @@ nvswitch_reset_and_drain_links_ls10
// Request active, but don't block. FM will come back and check
// active link status by blocking on this TLREQ's completion
//
status = nvswitch_request_tl_link_state_ls10(link_info,
NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_ACTIVE,
NV_FALSE);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: TL link state request to active for ALI failed for link: 0x%x\n",
__FUNCTION__, link);
continue;
status = nvswitch_request_tl_link_state_ls10(link_info,
NV_NVLIPT_LNK_CTRL_LINK_STATE_REQUEST_REQUEST_ACTIVE,
NV_FALSE);
if (status != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR,
"%s: TL link state request to active for ALI failed for link: 0x%x\n",
__FUNCTION__, link);
continue;
}
}
bAreDlClocksOn = NV_FALSE;
@@ -1692,7 +1698,26 @@ nvswitch_reset_and_drain_links_ls10
}
FOR_EACH_INDEX_IN_MASK_END;
// TODO: CCI Links Support: Reset the CCI links
return NVL_SUCCESS;
}
//
// Implement reset and drain sequence for ls10
//
NvlStatus
nvswitch_reset_and_drain_links_ls10
(
nvswitch_device *device,
NvU64 link_mask
)
{
NvlStatus status = NVL_SUCCESS;
status = _nvswitch_reset_and_drain_links_ls10(device, link_mask);
if (status != NVL_SUCCESS)
{
return status;
}
return NVL_SUCCESS;
}
@@ -2841,17 +2866,6 @@ nvswitch_set_fatal_error_ls10
NVSWITCH_ASSERT(link_id < nvswitch_get_num_links(device));
// On first fatal error, notify PORT_DOWN
if (!device->link[link_id].fatal_error_occurred)
{
if (nvswitch_lib_notify_client_events(device,
NVSWITCH_DEVICE_EVENT_PORT_DOWN) != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "%s: Failed to notify PORT_DOWN event\n",
__FUNCTION__);
}
}
device->link[link_id].fatal_error_occurred = NV_TRUE;
if (device_fatal)
@@ -2927,6 +2941,11 @@ nvswitch_is_soe_supported_ls10
return NV_FALSE;
}
if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES)
{
NVSWITCH_PRINT(device, WARN, "SOE can not be disabled via regkey.\n");
}
return NV_TRUE;
}
@@ -5896,29 +5915,29 @@ nvswitch_read_vbios_link_entries_ls10
tblPtr += (sizeof(NVLINK_VBIOS_CONFIG_DATA_LINKENTRY_20)/sizeof(NvU32));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink ID 0x%x ---->>>\n", i);
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 0 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam0, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam0));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 1 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam1, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam1));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 2 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam2, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam2));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 3 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam3, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam3));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 4 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam4, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam4));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 5 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam5, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam5));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 6 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam6, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam6));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 7 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam7, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam7));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 8 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam8, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam8));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"NVLink Params 9 \t0x%x \tBinary:"BYTE_TO_BINARY_PATTERN"\n", vbios_link_entry.nvLinkparam9, BYTE_TO_BINARY(vbios_link_entry.nvLinkparam9));
NVSWITCH_PRINT(device, SETUP,
NVSWITCH_PRINT(device, NOISY,
"<<<---- NvLink ID 0x%x ---->>>\n\n", i);
}
*identified_link_entriesCount = i;

View File

@@ -515,7 +515,7 @@ nvswitch_soe_disable_nport_fatal_interrupts_ls10
NvlStatus stat;
stat = device->hal.nvswitch_ctrl_get_bios_info(device, &p);
if ((stat != NVL_SUCCESS) || ((p.version & SOE_VBIOS_VERSION_MASK) <
if ((stat != NVL_SUCCESS) || ((p.version & SOE_VBIOS_VERSION_MASK) <
SOE_VBIOS_REVLOCK_DISABLE_NPORT_FATAL_INTR))
{
NVSWITCH_PRINT(device, ERROR,

View File

@@ -30,6 +30,7 @@
#include "flcn/haldefs_flcnable_nvswitch.h"
#include "flcn/flcn_nvswitch.h"
#include "soe/soe_nvswitch.h"
#include "soe/soeififr.h"
#include "nvVer.h"
#include "nvlink_inband_msg.h"
@@ -543,7 +544,19 @@ _nvswitch_init_device_regkeys
NVSWITCH_INIT_REGKEY(_PRIVATE, reference_clock_mode,
NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE,
NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, debug_level,
NV_SWITCH_REGKEY_DBG_LEVEL,
NV_SWITCH_REGKEY_DBG_LEVEL_DEFAULT);
}
ct_assert(NVSWITCH_DBG_LEVEL_MMIO == NV_SWITCH_REGKEY_DBG_LEVEL_MMIO);
ct_assert(NVSWITCH_DBG_LEVEL_NOISY == NV_SWITCH_REGKEY_DBG_LEVEL_NOISY);
ct_assert(NVSWITCH_DBG_LEVEL_SETUP == NV_SWITCH_REGKEY_DBG_LEVEL_SETUP);
ct_assert(NVSWITCH_DBG_LEVEL_INFO == NV_SWITCH_REGKEY_DBG_LEVEL_INFO);
ct_assert(NVSWITCH_DBG_LEVEL_WARN == NV_SWITCH_REGKEY_DBG_LEVEL_WARN);
ct_assert(NVSWITCH_DBG_LEVEL_ERROR == NV_SWITCH_REGKEY_DBG_LEVEL_ERROR);
NvU64
nvswitch_lib_deferred_task_dispatcher
(
@@ -727,12 +740,6 @@ nvswitch_is_soe_supported
nvswitch_device *device
)
{
if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES)
{
NVSWITCH_PRINT(device, INFO, "SOE is disabled via regkey.\n");
return NV_FALSE;
}
return device->hal.nvswitch_is_soe_supported(device);
}
@@ -743,12 +750,6 @@ nvswitch_init_soe
nvswitch_device *device
)
{
if (device->regkeys.soe_disable == NV_SWITCH_REGKEY_SOE_DISABLE_YES)
{
NVSWITCH_PRINT(device, INFO, "SOE is disabled via regkey.\n");
return NV_FALSE;
}
return device->hal.nvswitch_init_soe(device);
}
@@ -1335,6 +1336,75 @@ _nvswitch_ctrl_therm_get_temperature_limit
return device->hal.nvswitch_ctrl_therm_get_temperature_limit(device, pParams);
}
//
// Construct an port event log
//
// If port_event_log_size > 0 a circular buffer is created to record port events
//
NvlStatus
_nvswitch_construct_port_event_log
(
NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
NvU32 port_event_log_size,
NvBool overwritable
)
{
NvlStatus retval = NVL_SUCCESS;
NVSWITCH_ASSERT(port_events != NULL);
port_events->port_event_start = 0;
port_events->port_event_count = 0;
port_events->port_event_total = 0;
port_events->port_event_log_size = 0;
port_events->port_event_log = NULL;
port_events->overwritable = overwritable;
port_events->bOverflow = NV_FALSE;
if (port_event_log_size > 0)
{
port_events->port_event_log = nvswitch_os_malloc(port_event_log_size * sizeof(NVSWITCH_PORT_EVENT_TYPE));
}
if (port_events->port_event_log != NULL)
{
port_events->port_event_log_size = port_event_log_size;
nvswitch_os_memset(port_events->port_event_log, 0, port_events->port_event_log_size * sizeof(NVSWITCH_PORT_EVENT_TYPE));
}
if (port_event_log_size != port_events->port_event_log_size)
{
retval = -NVL_NO_MEM;
}
return retval;
}
//
// Destroy an error log
//
void
_nvswitch_destroy_port_event_log
(
nvswitch_device *device,
NVSWITCH_PORT_EVENT_LOG_TYPE *port_events
)
{
if (port_events == NULL)
return;
port_events->port_event_start = 0;
port_events->port_event_count = 0;
port_events->port_event_log_size = 0;
port_events->bOverflow = NV_FALSE;
if (port_events->port_event_log != NULL)
{
nvswitch_os_free(port_events->port_event_log);
port_events->port_event_log = NULL;
}
}
NvlStatus
nvswitch_lib_initialize_device
(
@@ -1507,17 +1577,10 @@ nvswitch_lib_initialize_device
nvswitch_reset_persistent_link_hw_state(device, link_num);
//
// During Nvswitch initialization, the default L1 thresholds are programmed by the
// BIOS from the BIOS tables. Save these L1 Threshold Values in scratch registers
// for use when resetting the thresholds to default.
//
nvswitch_program_l1_scratch_reg(device, link_num);
//
// WAR : Initializing the L1 threshold registers at this point as a WAR for
// Bug 3963639 where it was discussed that the L1 threshold register should have
// the default value for all available links and not just for active links.
// Bug 3963639 where is it was discussed that the L1 threshold register should have
// value the default value for all available links and not just for active links.
//
nvswitch_init_lpwr_regs(link);
}
@@ -1546,6 +1609,13 @@ nvswitch_lib_initialize_device
goto nvswitch_construct_error_log_fail;
}
retval = _nvswitch_construct_port_event_log(&device->log_PORT_EVENTS, NVSWITCH_PORT_EVENT_LOG_SIZE, NV_TRUE);
if (retval != NVL_SUCCESS)
{
NVSWITCH_PRINT(device, ERROR, "Failed to construct log_PORT_EVENTS! rc: %d\n", retval);
goto nvswitch_construct_port_event_log_fail;
}
if (device->regkeys.latency_counter == NV_SWITCH_REGKEY_LATENCY_COUNTER_LOGGING_ENABLE)
{
nvswitch_task_create(device, &nvswitch_internal_latency_bin_log,
@@ -1576,6 +1646,10 @@ nvswitch_construct_error_log_fail:
nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS);
nvswitch_construct_port_event_log_fail:
//free allocated memory to avoid leaking
_nvswitch_destroy_port_event_log(device, &device->log_PORT_EVENTS);
nvswitch_link_fail:
// Track down all links that successfully registered.
for (link_num = 0; link_num < nvswitch_get_num_links(device); link_num++)
@@ -1675,7 +1749,7 @@ nvswitch_lib_post_init_device
}
//
// There is an edge case where a hypervisor may not send same number
// There is an edge case where a hyperisor may not send same number
// of reset to switch and GPUs, so try to re-train links in fault
// if possible
//
@@ -1928,6 +2002,158 @@ nvswitch_lib_notify_client_events
return NVL_SUCCESS;
}
void
nvswitch_record_port_event
(
nvswitch_device *device,
NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
NvU32 link_id,
NvU8 port_event_type
)
{
NvU32 idx;
NVSWITCH_ASSERT(port_events != NULL);
// If no port events log has been created, then don't log it.
if ((port_events->port_event_log_size != 0) &&
(port_events->port_event_log != NULL))
{
idx = (port_events->port_event_start + port_events->port_event_count)
% port_events->port_event_log_size;
if (port_events->port_event_count == port_events->port_event_log_size)
{
// Error: ring buffer is already full/
if (port_events->overwritable)
{
port_events->port_event_start = (port_events->port_event_start + 1)
% port_events->port_event_log_size;
port_events->bOverflow = NV_TRUE;
}
else
{
// No logging, ring buffer is full
return;
}
}
else
{
port_events->port_event_count++;
}
// Log port event info
port_events->port_event_log[idx].link_id = link_id;
port_events->port_event_log[idx].port_event_type = port_event_type;
// Log tracking info
port_events->port_event_log[idx].time = nvswitch_os_get_platform_time();
port_events->port_event_log[idx].local_port_event_num = port_events->port_event_total;
}
port_events->port_event_total++;
}
/*
* @Brief : Retrives a port event entry by index.
*
* @Description : Retrieves the port_event at index port_event_idx. If index is out
* of range, returns an empty port event entry with port_event_type = 2
*
* @param[in] device NVSwitch device to contain this link
* @param[in] port_events Log of all port events with metadata
* @param[in] port_event_idx Index of entry to retrieve (0 = oldest port event)
* @param[out] port_event_count Clear only non-persistent list
*/
void
nvswitch_get_port_event
(
nvswitch_device *device,
NVSWITCH_PORT_EVENT_LOG_TYPE *port_events,
NVSWITCH_PORT_EVENT_TYPE *port_event_entry,
NvU32 port_event_idx,
NvU32 *port_event_count
)
{
NvU32 idx;
NVSWITCH_ASSERT(port_events != NULL);
if (port_event_entry != NULL)
{
// Index is out of range
if (port_event_idx >= port_events->port_event_count)
{
nvswitch_os_memset(port_event_entry, 0, sizeof(*port_event_entry));
port_event_entry->port_event_type = NVSWITCH_PORT_EVENT_TYPE_INVALID;
port_event_entry->time = nvswitch_os_get_platform_time();
}
else
{
idx = (port_events->port_event_start + port_event_idx) % port_events->port_event_log_size;
*port_event_entry = port_events->port_event_log[idx];
}
}
if (port_event_count)
{
*port_event_count = port_events->port_event_count;
}
}
NvlStatus
nvswitch_ctrl_get_port_events
(
nvswitch_device *device,
NVSWITCH_GET_PORT_EVENTS_PARAMS *p
)
{
NvU32 index = 0;
NvU32 count = 0;
NVSWITCH_PORT_EVENT_LOG_TYPE *port_events = &device->log_PORT_EVENTS;
NVSWITCH_PORT_EVENT_TYPE port_event;
nvswitch_os_memset(p->portEvent, 0, sizeof(NVSWITCH_PORT_EVENT)
*NVSWITCH_PORT_EVENT_COUNT_SIZE);
p->nextPortEventIndex = port_events->port_event_total;
p->portEventCount = 0;
p->bOverflow = port_events->bOverflow;
// Return if there are no more port events to get
nvswitch_get_port_event(device, port_events, &port_event, index, &count);
if (count == 0)
{
return NVL_SUCCESS;
}
// If port event's local_port_Event_num is smaller than the portEventIndex
// passed in by the client, fast-forward index by the difference.
// This will skip over port events that were previously read by the client.
if (port_event.local_port_event_num < p->portEventIndex)
{
index = (NvU32) (p->portEventIndex - port_event.local_port_event_num);
}
// Return if there are no more events after fast-forwarding.
if (index >= count)
{
return NVL_SUCCESS;
}
while ((p->portEventCount < NVSWITCH_PORT_EVENT_COUNT_SIZE) && (index < count))
{
nvswitch_get_port_event(device, port_events, &port_event, index, NULL);
p->portEvent[p->portEventCount].port_event_type = port_event.port_event_type;
p->portEvent[p->portEventCount].link_id = port_event.link_id;
p->portEvent[p->portEventCount].time = port_event.time;
p->portEventCount++;
index++;
}
p->portEventIndex = port_event.local_port_event_num + 1;
return NVL_SUCCESS;
}
/*!
@brief: Release ROM image from memory.
*/
@@ -1989,6 +2215,8 @@ nvswitch_lib_shutdown_device
nvswitch_destroy_error_log(device, &device->log_FATAL_ERRORS);
nvswitch_destroy_error_log(device, &device->log_NONFATAL_ERRORS);
_nvswitch_destroy_port_event_log(device, &device->log_PORT_EVENTS);
nvswitch_smbpbi_unload(device);
_nvswitch_destroy_event_list(device);
@@ -2012,17 +2240,18 @@ NvlStatus
nvswitch_lib_get_log_count
(
nvswitch_device *device,
NvU32 *fatal, NvU32 *nonfatal
NvU32 *fatal, NvU32 *nonfatal, NvU32 *portEvent
)
{
if (!NVSWITCH_IS_DEVICE_INITIALIZED(device) ||
fatal == NULL || nonfatal == NULL)
fatal == NULL || nonfatal == NULL || portEvent == NULL)
{
return -NVL_BAD_ARGS;
}
*fatal = device->log_FATAL_ERRORS.error_count;
*nonfatal = device->log_NONFATAL_ERRORS.error_count;
*portEvent = device->log_PORT_EVENTS.port_event_count;
// No report of log_INFO currently
return NVL_SUCCESS;
@@ -3475,6 +3704,46 @@ _nvswitch_ctrl_get_inforom_bbx_sxid
return nvswitch_inforom_bbx_get_sxid(device, params);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_sys_info
(
nvswitch_device *device,
NVSWITCH_GET_SYS_INFO_PARAMS *params
)
{
return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_SYS_INFO, (void *)params);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_time_info
(
nvswitch_device *device,
NVSWITCH_GET_TIME_INFO_PARAMS *params
)
{
return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TIME_INFO, (void *)params);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_temp_data
(
nvswitch_device *device,
NVSWITCH_GET_TEMP_DATA_PARAMS *params
)
{
return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TEMP_DATA, (void *)params);
}
static NvlStatus
_nvswitch_ctrl_get_inforom_bbx_temp_samples
(
nvswitch_device *device,
NVSWITCH_GET_TEMP_SAMPLES_PARAMS *params
)
{
return nvswitch_inforom_bbx_get_data(device, RM_SOE_IFR_BBX_GET_TEMP_SAMPLES, (void *)params);
}
static NvlStatus
_nvswitch_ctrl_get_nvlink_lp_counters
(
@@ -4656,16 +4925,6 @@ nvswitch_init_lpwr_regs
device->hal.nvswitch_init_lpwr_regs(link);
}
void
nvswitch_program_l1_scratch_reg
(
nvswitch_device *device,
NvU32 linkNumber
)
{
device->hal.nvswitch_program_l1_scratch_reg(device, linkNumber);
}
NvlStatus
nvswitch_launch_ALI
(
@@ -4870,6 +5129,9 @@ nvswitch_lib_ctrl
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_ERRORS,
nvswitch_ctrl_get_errors,
NVSWITCH_GET_ERRORS_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_PORT_EVENTS,
nvswitch_ctrl_get_port_events,
NVSWITCH_GET_PORT_EVENTS_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_NVLINK_STATUS,
_nvswitch_ctrl_get_nvlink_status,
NVSWITCH_GET_NVLINK_STATUS_PARAMS);
@@ -5181,6 +5443,26 @@ nvswitch_lib_ctrl
NVSWITCH_DEV_CMD_DISPATCH(CTRL_NVSWITCH_GET_POWER,
_nvswitch_ctrl_therm_read_power,
NVSWITCH_GET_POWER_PARAMS);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_SYS_INFO,
_nvswitch_ctrl_get_inforom_bbx_sys_info,
NVSWITCH_GET_SYS_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_TIME_INFO,
_nvswitch_ctrl_get_inforom_bbx_time_info,
NVSWITCH_GET_TIME_INFO_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_TEMP_DATA,
_nvswitch_ctrl_get_inforom_bbx_temp_data,
NVSWITCH_GET_TEMP_DATA_PARAMS,
osPrivate, flags);
NVSWITCH_DEV_CMD_DISPATCH_PRIVILEGED(
CTRL_NVSWITCH_GET_TEMP_SAMPLES,
_nvswitch_ctrl_get_inforom_bbx_temp_samples,
NVSWITCH_GET_TEMP_SAMPLES_PARAMS,
osPrivate, flags);
default:
nvswitch_os_print(NVSWITCH_DBG_LEVEL_INFO, "unknown ioctl %x\n", cmd);