515.105.01

This commit is contained in:
Andy Ritger 2023-03-30 09:52:52 -07:00
parent c700e8f91c
commit 21c357a471
No known key found for this signature in database
GPG Key ID: 6D466BB75E006CFC
69 changed files with 8415 additions and 7397 deletions

View File

@ -2,6 +2,10 @@
## Release 515 Entries
### [515.105.01] 2023-03-30
- Fixed nvenc compatibility with usermode clients [#104](https://github.com/NVIDIA/open-gpu-kernel-modules/issues/104)
### [515.86.01] 2022-11-22
### [515.76] 2022-09-20

View File

@ -1,7 +1,7 @@
# NVIDIA Linux Open GPU Kernel Module Source
This is the source release of the NVIDIA Linux open GPU kernel modules,
version 515.86.01.
version 515.105.01.
## How to Build
@ -17,7 +17,7 @@ as root:
Note that the kernel modules built here must be used with gsp.bin
firmware and user-space NVIDIA GPU driver components from a corresponding
515.86.01 driver release. This can be achieved by installing
515.105.01 driver release. This can be achieved by installing
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
option. E.g.,
@ -167,7 +167,7 @@ for the target kernel.
## Compatible GPUs
The open-gpu-kernel-modules can be used on any Turing or later GPU
(see the table below). However, in the 515.86.01 release,
(see the table below). However, in the 515.105.01 release,
GeForce and Workstation support is still considered alpha-quality.
To enable use of the open kernel modules on GeForce and Workstation GPUs,
@ -175,7 +175,7 @@ set the "NVreg_OpenRmEnableUnsupportedGpus" nvidia.ko kernel module
parameter to 1. For more details, see the NVIDIA GPU driver end user
README here:
https://us.download.nvidia.com/XFree86/Linux-x86_64/515.86.01/README/kernel_open.html
https://us.download.nvidia.com/XFree86/Linux-x86_64/515.105.01/README/kernel_open.html
In the below table, if three IDs are listed, the first is the PCI Device
ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI
@ -645,8 +645,8 @@ Subsystem Device ID.
| NVIDIA A100-SXM4-80GB | 20B2 10DE 147F |
| NVIDIA A100-SXM4-80GB | 20B2 10DE 1622 |
| NVIDIA A100-SXM4-80GB | 20B2 10DE 1623 |
| NVIDIA PG506-242 | 20B3 10DE 14A7 |
| NVIDIA PG506-243 | 20B3 10DE 14A8 |
| NVIDIA A100-SXM-64GB | 20B3 10DE 14A7 |
| NVIDIA A100-SXM-64GB | 20B3 10DE 14A8 |
| NVIDIA A100 80GB PCIe | 20B5 10DE 1533 |
| NVIDIA A100 80GB PCIe | 20B5 10DE 1642 |
| NVIDIA PG506-232 | 20B6 10DE 1492 |
@ -662,7 +662,6 @@ Subsystem Device ID.
| NVIDIA A800-SXM4-80GB | 20F3 10DE 17A2 |
| NVIDIA A800 80GB PCIe | 20F5 10DE 1799 |
| NVIDIA A800 80GB PCIe LC | 20F5 10DE 179A |
| NVIDIA A800 40GB PCIe | 20F6 10DE 17A3 |
| NVIDIA GeForce GTX 1660 Ti | 2182 |
| NVIDIA GeForce GTX 1660 | 2184 |
| NVIDIA GeForce GTX 1650 SUPER | 2187 |
@ -771,6 +770,7 @@ Subsystem Device ID.
| NVIDIA RTX A2000 12GB | 2571 103C 1611 |
| NVIDIA RTX A2000 12GB | 2571 10DE 1611 |
| NVIDIA RTX A2000 12GB | 2571 17AA 1611 |
| NVIDIA GeForce RTX 3050 | 2582 |
| NVIDIA GeForce RTX 3050 Ti Laptop GPU | 25A0 |
| NVIDIA GeForce RTX 3050Ti Laptop GPU | 25A0 103C 8928 |
| NVIDIA GeForce RTX 3050Ti Laptop GPU | 25A0 103C 89F9 |
@ -783,6 +783,9 @@ Subsystem Device ID.
| NVIDIA GeForce RTX 2050 | 25A7 |
| NVIDIA GeForce RTX 2050 | 25A9 |
| NVIDIA GeForce MX570 A | 25AA |
| NVIDIA GeForce RTX 3050 4GB Laptop GPU | 25AB |
| NVIDIA GeForce RTX 3050 6GB Laptop GPU | 25AC |
| NVIDIA GeForce RTX 2050 | 25AD |
| NVIDIA A16 | 25B6 10DE 14A9 |
| NVIDIA A2 | 25B6 10DE 157E |
| NVIDIA RTX A2000 Laptop GPU | 25B8 |
@ -792,5 +795,8 @@ Subsystem Device ID.
| NVIDIA GeForce RTX 3050 Ti Laptop GPU | 25E0 |
| NVIDIA GeForce RTX 3050 Laptop GPU | 25E2 |
| NVIDIA GeForce RTX 3050 Laptop GPU | 25E5 |
| NVIDIA GeForce RTX 3050 6GB Laptop GPU | 25EC |
| NVIDIA GeForce RTX 2050 | 25ED |
| NVIDIA RTX A1000 Embedded GPU | 25F9 |
| NVIDIA RTX A2000 Embedded GPU | 25FA |
| NVIDIA RTX A500 Embedded GPU | 25FB |

View File

@ -72,7 +72,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc
EXTRA_CFLAGS += -I$(src)
EXTRA_CFLAGS += -Wall -MD $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args
EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"515.86.01\"
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"515.105.01\"
EXTRA_CFLAGS += -Wno-unused-function

View File

@ -5305,6 +5305,28 @@ compile_test() {
compile_check_conftest "$CODE" "NV_ACPI_VIDEO_BACKLIGHT_USE_NATIVE" "" "functions"
;;
drm_connector_has_override_edid)
#
# Determine if 'struct drm_connector' has an 'override_edid' member.
#
# Removed by commit 90b575f52c6ab ("drm/edid: detach debugfs EDID
# override from EDID property update") in linux-next, expected in
# v6.2-rc1.
#
CODE="
#if defined(NV_DRM_DRM_CRTC_H_PRESENT)
#include <drm/drm_crtc.h>
#endif
#if defined(NV_DRM_DRM_CONNECTOR_H_PRESENT)
#include <drm/drm_connector.h>
#endif
int conftest_drm_connector_has_override_edid(void) {
return offsetof(struct drm_connector, override_edid);
}"
compile_check_conftest "$CODE" "NV_DRM_CONNECTOR_HAS_OVERRIDE_EDID" "" "types"
;;
# When adding a new conftest entry, please use the correct format for
# specifying the relevant upstream Linux kernel commit.
#

View File

@ -42,6 +42,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
static void nv_drm_connector_destroy(struct drm_connector *connector)
{
@ -98,7 +99,11 @@ __nv_drm_detect_encoder(struct NvKmsKapiDynamicDisplayParams *pDetectParams,
break;
}
#if defined(NV_DRM_CONNECTOR_HAS_OVERRIDE_EDID)
if (connector->override_edid) {
#else
if (drm_edid_override_connector_update(connector) > 0) {
#endif
const struct drm_property_blob *edid = connector->edid_blob_ptr;
if (edid->length <= sizeof(pDetectParams->edid.buffer)) {

View File

@ -240,10 +240,6 @@ nv_drm_init_mode_config(struct nv_drm_device *nv_dev,
dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1;
/* Currently unused. Update when needed. */
dev->mode_config.fb_base = 0;
#if defined(NV_DRM_CRTC_STATE_HAS_ASYNC_FLIP) || \
defined(NV_DRM_CRTC_STATE_HAS_PAGEFLIP_FLAGS)
dev->mode_config.async_page_flip = true;

View File

@ -205,7 +205,7 @@ static struct sg_table *__nv_drm_gem_nvkms_memory_prime_get_sg_table(
nv_dev,
"Cannot create sg_table for NvKmsKapiMemory 0x%p",
nv_gem->pMemory);
return NULL;
return ERR_PTR(-ENOMEM);
}
sg_table = nv_drm_prime_pages_to_sg(nv_dev->dev,

View File

@ -134,16 +134,19 @@ static int __nv_drm_put_back_post_fence_fd(
const struct NvKmsKapiLayerReplyConfig *layer_reply_config)
{
int fd = layer_reply_config->postSyncptFd;
int ret = 0;
if ((fd >= 0) && (plane_state->fd_user_ptr != NULL)) {
if (put_user(fd, plane_state->fd_user_ptr)) {
return -EFAULT;
ret = copy_to_user(plane_state->fd_user_ptr, &fd, sizeof(fd));
if (ret != 0) {
return ret;
}
/*! set back to Null and let set_property specify it again */
plane_state->fd_user_ptr = NULL;
}
return 0;
return ret;
}
static int __nv_drm_get_syncpt_data(

View File

@ -118,3 +118,4 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_config_has_allow_fb_modifiers
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_resv_add_fence
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_resv_reserve_fences
NV_CONFTEST_TYPE_COMPILE_TESTS += reservation_object_reserve_shared_has_num_fences_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_has_override_edid

View File

@ -30,8 +30,18 @@ NVIDIA_PEERMEM_CFLAGS += -UDEBUG -U_DEBUG -DNDEBUG -DNV_BUILD_MODULE_INSTANCES=0
# MOFED's Module.symvers is needed for the build
# to find the additional ib_* symbols.
#
# Also, MOFED doesn't use kbuild ARCH names.
# So adapt OFA_ARCH to match MOFED's conventions.
#
ifeq ($(ARCH), arm64)
OFA_ARCH := aarch64
else ifeq ($(ARCH), powerpc)
OFA_ARCH := ppc64le
else
OFA_ARCH := $(ARCH)
endif
OFA_DIR := /usr/src/ofa_kernel
OFA_CANDIDATES = $(OFA_DIR)/$(ARCH)/$(KERNELRELEASE) $(OFA_DIR)/$(KERNELRELEASE) $(OFA_DIR)/default /var/lib/dkms/mlnx-ofed-kernel
OFA_CANDIDATES = $(OFA_DIR)/$(OFA_ARCH)/$(KERNELRELEASE) $(OFA_DIR)/$(KERNELRELEASE) $(OFA_DIR)/default /var/lib/dkms/mlnx-ofed-kernel
MLNX_OFED_KERNEL := $(shell for d in $(OFA_CANDIDATES); do \
if [ -d "$$d" ]; then \
echo "$$d"; \

View File

@ -169,7 +169,11 @@ NvBool nv_ats_supported = NVCPU_IS_PPC64LE
/* nvos_ functions.. do not take a state device parameter */
static int nvos_count_devices(void);
static nv_alloc_t *nvos_create_alloc(struct device *, int);
static nv_alloc_t *nvos_create_alloc(struct device *, NvU64);
static int nvos_free_alloc(nv_alloc_t *);
/***
@ -284,11 +288,20 @@ void nv_sev_init(
static
nv_alloc_t *nvos_create_alloc(
struct device *dev,
int num_pages
NvU64 num_pages
)
{
nv_alloc_t *at;
unsigned int pt_size, i;
nv_alloc_t *at;
NvU64 pt_size;
unsigned int i;
NV_KMALLOC(at, sizeof(nv_alloc_t));
if (at == NULL)
@ -300,7 +313,29 @@ nv_alloc_t *nvos_create_alloc(
memset(at, 0, sizeof(nv_alloc_t));
at->dev = dev;
pt_size = num_pages * sizeof(nvidia_pte_t *);
//
// Check for multiplication overflow and check whether num_pages value can fit in at->num_pages.
//
if ((num_pages != 0) && ((pt_size / num_pages) != sizeof(nvidia_pte_t*)))
{
nv_printf(NV_DBG_ERRORS, "NVRM: Invalid page table allocation - Number of pages exceeds max value.\n");
NV_KFREE(at, sizeof(nv_alloc_t));
return NULL;
}
at->num_pages = num_pages;
if (at->num_pages != num_pages)
{
nv_printf(NV_DBG_ERRORS, "NVRM: Invalid page table allocation - requested size overflows.\n");
NV_KFREE(at, sizeof(nv_alloc_t));
return NULL;
}
if (os_alloc_mem((void **)&at->page_table, pt_size) != NV_OK)
{
nv_printf(NV_DBG_ERRORS, "NVRM: failed to allocate page table\n");
@ -309,7 +344,9 @@ nv_alloc_t *nvos_create_alloc(
}
memset(at->page_table, 0, pt_size);
at->num_pages = num_pages;
NV_ATOMIC_SET(at->usage_count, 0);
for (i = 0; i < at->num_pages; i++)

View File

@ -1142,11 +1142,27 @@ void NV_API_CALL os_get_screen_info(
*pFbHeight = registered_fb[i]->var.yres;
*pFbDepth = registered_fb[i]->var.bits_per_pixel;
*pFbPitch = registered_fb[i]->fix.line_length;
break;
return;
}
}
}
#elif NV_IS_EXPORT_SYMBOL_PRESENT_screen_info
#endif
/*
* If the screen info is not found in the registered FBs then fallback
* to the screen_info structure.
*
* The SYSFB_SIMPLEFB option, if enabled, marks VGA/VBE/EFI framebuffers as
* generic framebuffers so the new generic system-framebuffer drivers can
* be used instead. DRM_SIMPLEDRM drives the generic system-framebuffers
* device created by SYSFB_SIMPLEFB.
*
* SYSFB_SIMPLEFB registers a dummy framebuffer which does not contain the
* information required by os_get_screen_info(), therefore you need to
* fall back onto the screen_info structure.
*/
#if NV_IS_EXPORT_SYMBOL_PRESENT_screen_info
/*
* If there is not a framebuffer console, return 0 size.
*

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -330,6 +330,12 @@ namespace DisplayPort
//
bool bDscCapBasedOnParent;
//
// MST device connnected to dock may issue IRQ for link lost.
// Send PowerDown path msg to suppress that.
//
bool bPowerDownPhyBeforeD3;
void sharedInit();
ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Connector::EventSink * sink);

View File

@ -384,6 +384,11 @@ namespace DisplayPort
void pbnRequired(const ModesetInfo & modesetInfo, unsigned & base_pbn, unsigned & slots, unsigned & slots_pbn)
{
base_pbn = pbnForMode(modesetInfo);
if (bEnableFEC)
{
// IF FEC is enabled, we need to consider 3% overhead as per DP1.4 spec.
base_pbn = (NvU32)(divide_ceil(base_pbn * 100, 97));
}
slots = slotsForPBN(base_pbn);
slots_pbn = PBNForSlots(slots);
}

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
@ -59,6 +59,9 @@
#define NV_DP_REGKEY_FORCE_EDP_ILR "DP_BYPASS_EDP_ILR_REV_CHECK"
// Message to power down video stream before power down link (set D3)
#define NV_DP_REGKEY_POWER_DOWN_PHY "DP_POWER_DOWN_PHY"
//
// DSC capability of downstream device should be decided based on device's own
// and its parent's DSC capability.
@ -110,6 +113,7 @@ struct DP_REGKEY_DATABASE
bool bDscOptimizeLTBug3534707;
bool bNoReplyTimerForBusyWaiting;
bool bDpcdProbingForBusyWaiting;
bool bPowerDownPhyBeforeD3;
};
#endif //INCLUDED_DP_REGKEYDATABASE_H

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -190,6 +190,7 @@ void ConnectorImpl::applyRegkeyOverrides(const DP_REGKEY_DATABASE& dpRegkeyDatab
this->bDscMstCapBug3143315 = dpRegkeyDatabase.bDscMstCapBug3143315;
this->bDscMstEnablePassThrough = dpRegkeyDatabase.bDscMstEnablePassThrough;
this->bDscOptimizeLTBug3534707 = dpRegkeyDatabase.bDscOptimizeLTBug3534707;
this->bPowerDownPhyBeforeD3 = dpRegkeyDatabase.bPowerDownPhyBeforeD3;
}
void ConnectorImpl::setPolicyModesetOrderMitigation(bool enabled)
@ -3179,6 +3180,22 @@ void ConnectorImpl::powerdownLink(bool bPowerdownPanel)
powerOff.lanes = 0;
// Inform Sink about Main Link Power Down.
if (linkUseMultistream() && bPowerDownPhyBeforeD3)
{
PowerDownPhyMessage powerDownPhyMsg;
NakData nack;
for (Device * i = enumDevices(0); i; i=enumDevices(i))
{
if (i->isPlugged() && i->isVideoSink())
{
Address devAddress = ((DeviceImpl*)i)->address;
powerDownPhyMsg.set(devAddress.parent(), devAddress.tail(), NV_TRUE);
this->messageManager->send(&powerDownPhyMsg, nack);
}
}
}
//
// 1> If it is eDP and the power is not on, we don't need to put it into D3 here
// 2> If FEC is enabled then we have to put panel in D3 after powering down mainlink

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -97,7 +97,8 @@ const struct
{NV_DP_DSC_MST_ENABLE_PASS_THROUGH, &dpRegkeyDatabase.bDscMstEnablePassThrough, DP_REG_VAL_BOOL},
{NV_DP_DSC_OPTIMIZE_LT_BUG_3534707, &dpRegkeyDatabase.bDscOptimizeLTBug3534707, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_NO_REPLY_TIMER_FOR_BUSY_WAITING, &dpRegkeyDatabase.bNoReplyTimerForBusyWaiting, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_DPCD_PROBING_FOR_BUSY_WAITING, &dpRegkeyDatabase.bDpcdProbingForBusyWaiting, DP_REG_VAL_BOOL}
{NV_DP_REGKEY_DPCD_PROBING_FOR_BUSY_WAITING, &dpRegkeyDatabase.bDpcdProbingForBusyWaiting, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_POWER_DOWN_PHY, &dpRegkeyDatabase.bPowerDownPhyBeforeD3, DP_REG_VAL_BOOL}
};
EvoMainLink::EvoMainLink(EvoInterface * provider, Timer * timer) :

View File

@ -852,21 +852,16 @@ bool DisplayPort::isModePossibleMSTWithFEC
unsigned DisplayPort::pbnForMode(const ModesetInfo & modesetInfo)
{
// When DSC is enabled consider depth will multiplied by 16
unsigned dsc_factor = modesetInfo.bEnableDsc ? 16 : 1;
//
// Calculate PBN in terms of 54/64 mbyte/sec
// round up by .6% for spread de-rate. Note: if we're not spreading our link
// this MUST still be counted. It's also to allow downstream links to be spread.
//
unsigned pbnForMode = (NvU32)(divide_ceil(modesetInfo.pixelClockHz * modesetInfo.depth * 1006 * 64 / 8,
(NvU64)54000000 *1000));
if(modesetInfo.bEnableDsc)
{
//
// When DSC is enabled consider depth will multiplied by 16 and also 3% FEC Overhead
// as per DP1.4 spec
pbnForMode = (NvU32)(divide_ceil(pbnForMode * 100, 97 * DSC_DEPTH_FACTOR));
}
(NvU64)54000000 * 1000 * dsc_factor));
return pbnForMode;
}

View File

@ -36,25 +36,25 @@
// and then checked back in. You cannot make changes to these sections without
// corresponding changes to the buildmeister script
#ifndef NV_BUILD_BRANCH
#define NV_BUILD_BRANCH r517_71
#define NV_BUILD_BRANCH r518_03
#endif
#ifndef NV_PUBLIC_BRANCH
#define NV_PUBLIC_BRANCH r517_71
#define NV_PUBLIC_BRANCH r518_03
#endif
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r515/r517_71-480"
#define NV_BUILD_CHANGELIST_NUM (31976733)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r515/r518_03-644"
#define NV_BUILD_CHANGELIST_NUM (32511701)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "rel/gpu_drv/r515/r517_71-480"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (31976733)
#define NV_BUILD_NAME "rel/gpu_drv/r515/r518_03-644"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (32511701)
#else /* Windows builds */
#define NV_BUILD_BRANCH_VERSION "r517_71-1"
#define NV_BUILD_CHANGELIST_NUM (31976733)
#define NV_BUILD_BRANCH_VERSION "r518_03-1"
#define NV_BUILD_CHANGELIST_NUM (32511701)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "517.72"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (31976733)
#define NV_BUILD_NAME "518.04"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (32511701)
#define NV_BUILD_BRANCH_BASE_VERSION R515
#endif
// End buildmeister python edited section

View File

@ -4,7 +4,7 @@
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1)
#define NV_VERSION_STRING "515.86.01"
#define NV_VERSION_STRING "515.105.01"
#else

View File

@ -3,7 +3,7 @@
#define NV_COMPANY_NAME_STRING_SHORT "NVIDIA"
#define NV_COMPANY_NAME_STRING_FULL "NVIDIA Corporation"
#define NV_COMPANY_NAME_STRING NV_COMPANY_NAME_STRING_FULL
#define NV_COPYRIGHT_YEAR "2022"
#define NV_COPYRIGHT_YEAR "2023"
#define NV_COPYRIGHT "(C) " NV_COPYRIGHT_YEAR " NVIDIA Corporation. All rights reserved." // Please do not use the non-ascii copyright symbol for (C).
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \

View File

@ -32,6 +32,8 @@
#include "edid.h"
PUSH_SEGMENTS
// Macro to declare a TIMING initializer for given parameters without border
@ -2084,8 +2086,8 @@ NvU32 NvTiming_EDIDValidationMask(NvU8 *pEdid, NvU32 length, NvBool bIsStrongVal
// validate DTD blocks
pDTD = (DETAILEDTIMINGDESCRIPTOR *)&pExt[((EIA861EXTENSION *)pExt)->offset];
while (pDTD->wDTPixelClock != 0 &&
(NvU8 *)pDTD - pExt < (int)sizeof(EIA861EXTENSION))
while ((pDTD->wDTPixelClock != 0) &&
(((NvU8 *)pDTD - pExt + sizeof(DETAILEDTIMINGDESCRIPTOR)) < ((NvU8)sizeof(EIA861EXTENSION) - 1)))
{
if (parseEdidDetailedTimingDescriptor((NvU8 *)pDTD, NULL) != NVT_STATUS_SUCCESS)
{

View File

@ -32,6 +32,8 @@
#include "edid.h"
PUSH_SEGMENTS
#define EIA_TIMING(hv,hfp,hsw,ht,hsp,vv,vfp,vsw,vt,vsp,rrx1k,ip,aspect,rep,format) \
@ -395,7 +397,7 @@ void parse861ExtDetailedTiming(NvU8 *pEdidExt,
// Get all detailed timings in CEA ext block
pDTD = (DETAILEDTIMINGDESCRIPTOR *)&pEdidExt[pEIA861->offset];
while((NvU8 *)pDTD < (pEdidExt + sizeof(EDIDV1STRUC)) && // Check that we're not going beyond this extension block.
while((NvU8 *)pDTD + sizeof(DETAILEDTIMINGDESCRIPTOR) < (pEdidExt + sizeof(EDIDV1STRUC) - 1) &&
pDTD->wDTPixelClock != 0)
{
NVMISC_MEMSET(&newTiming, 0, sizeof(newTiming));
@ -1213,6 +1215,11 @@ NVT_STATUS get861ExtInfo(NvU8 *p, NvU32 size, NVT_EDID_CEA861_INFO *p861info)
return NVT_STATUS_ERR;
}
// DTD offset sanity check
if (p[2] >= 1 && p[2] <= 3)
{
return NVT_STATUS_ERR;
}
// don't do anything further if p is NULL
if (p861info == NULL)
@ -1274,7 +1281,12 @@ NVT_STATUS parseCta861DataBlockInfo(NvU8 *p,
tag = NVT_CEA861_GET_SHORT_DESCRIPTOR_TAG(p[i]);
payload = NVT_CEA861_GET_SHORT_DESCRIPTOR_SIZE(p[i]);
// move the pointer to the payload section
/*don't allow data colleciton totally size larger than [127 - 5 (tag, revision, offset, describing native video format, checksum)]*/
if ((i + payload > size) || (i + payload > 122))
{
return NVT_STATUS_ERR;
}
// move the pointer to the payload section or extended Tag Code
i++;
// loop through all descriptors

View File

@ -90,7 +90,7 @@ typedef struct
typedef struct
{
NvU16 nodeId;
NvU32 linkIndex;
NvU16 linkIndex;
nvlink_pci_dev_info pciInfo;
} nvlink_endpoint;
@ -116,7 +116,7 @@ typedef struct
typedef struct
{
NvU16 nodeId;
NvU32 linkIndex;
NvU16 linkIndex;
nvlink_pci_dev_info pciInfo;
NvU8 devUuid[NVLINK_UUID_LEN];
NvU32 devType;
@ -188,9 +188,9 @@ typedef enum
/* link and sublink state of an nvlink endpoint */
typedef struct
{
NvU32 linkMode;
NvU32 txSubLinkMode;
NvU32 rxSubLinkMode;
NvU8 linkMode;
NvU8 txSubLinkMode;
NvU8 rxSubLinkMode;
} nvlink_link_state;
/*
@ -353,7 +353,7 @@ typedef struct
*/
typedef struct
{
NvU32 linkIndex;
NvU16 linkIndex;
NvBool initStatus;
} nvlink_link_init_status;
@ -502,7 +502,7 @@ typedef struct
*/
typedef struct
{
NvU32 linkIndex;
NvU16 linkIndex;
NV_DECLARE_ALIGNED(NvU64 tokenValue, 8);
} nvlink_token_info;
@ -1109,6 +1109,11 @@ typedef struct
NvU32 endStatesCount;
} nvlink_get_device_link_states;
/*
* Note: Verify that new parameter structs for IOCTLs satisfy
* sizing restrictions for all OSs they could be used in.
*/
#define CTRL_NVLINK_CHECK_VERSION 0x01
#define CTRL_NVLINK_SET_NODE_ID 0x02
#define CTRL_NVLINK_SET_TX_COMMON_MODE 0x03

View File

@ -254,6 +254,8 @@ typedef struct
NvU32 link_recal_settings;
NvU32 crc_bit_error_rate_short;
NvU32 crc_bit_error_rate_long;
NvU32 block_code_mode;
NvU32 reference_clock_mode;
} NVSWITCH_REGKEY_TYPE;
//

View File

@ -122,7 +122,9 @@
_op(NvlStatus, nvswitch_soe_prepare_for_reset, (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_get_nvlink_ecc_errors, (nvswitch_device *device, NVSWITCH_GET_NVLINK_ECC_ERRORS_PARAMS *p), _arch) \
_op(NvlStatus, nvswitch_inforom_ecc_log_error_event, (nvswitch_device *device, INFOROM_ECC_OBJECT *pEccGeneric, INFOROM_NVS_ECC_ERROR_EVENT *error_event), _arch) \
_op(void, nvswitch_oms_set_device_disable, (INFOROM_OMS_STATE *pOmsState, NvBool bForceDeviceDisable), _arch) \

View File

@ -649,5 +649,7 @@ NvlStatus nvswitch_service_nvldl_fatal_link_lr10(nvswitch_device *device, NvU32
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);
#endif //_LR10_H_

View File

@ -332,6 +332,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.
@ -545,4 +547,35 @@
#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_BLOCK_CODE_MODE - Indicates the Forward Error Correction Mode
*
* Forward Error Correction Mode (Pre-HS).
* DEFAULT = System Default
* OFF = 0x0
* ECC96_ENABLED = 0x1
* ECC88_ENABLED = 0x2
*/
#define NV_SWITCH_REGKEY_BLOCK_CODE_MODE "BlockCodeMode"
#define NV_SWITCH_REGKEY_BLOCK_CODE_MODE_DEFAULT 0x0
#define NV_SWITCH_REGKEY_BLOCK_CODE_MODE_OFF 0x0
#define NV_SWITCH_REGKEY_BLOCK_CODE_MODE_ECC96_ENABLED 0x1
#define NV_SWITCH_REGKEY_BLOCK_CODE_MODE_ECC88_ENABLED 0x2
/*
* NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE - Indicates the reference clock mode for
* the system w.r.t. this link.
*
* DEFAULT = System Default
* COMMON = Common reference clock. Spread Spectrum (SS) may or may not be enabled.
* NON_COMMON_NO_SS = Non-common reference clock without SS enabled.
* NON_COMMON_SS = Non-common reference clock with SS enabled.
*/
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE "ReferenceClockMode"
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT 0x0
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_COMMON 0x0
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_RESERVED 0x1
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_NON_COMMON_NO_SS 0x2
#define NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_NON_COMMON_SS 0x3
#endif //_REGKEY_NVSWITCH_H_

View File

@ -2015,6 +2015,314 @@ 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 = 0;
NvU32 fldval = 0;
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);
}
// REFERENCE_CLOCK_MODE SYSTEM register
if (device->regkeys.reference_clock_mode != NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CLK_CTRL,
_REFERENCE_CLOCK_MODE, device->regkeys.reference_clock_mode, regval);
NVSWITCH_PRINT(device, SETUP, "%s: REFERENCE_CLOCK_MODE = 0x%x requested by regkey\n",
__FUNCTION__, device->regkeys.reference_clock_mode);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CLK_CTRL, _REFERENCE_CLOCK_MODE,
DRF_VAL(_NVLINK_VBIOS,_PARAM3,_REFERENCE_CLOCK_MODE, vbios_link_entry->nvLinkparam3),
regval);
}
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);
}
// AC vs DC mode SYSTEM register
if (link->ac_coupled)
{
//
// In NVL3.0, ACMODE is handled by MINION in the INITPHASE1 command
// Here we just setup the register with the proper info
//
NVSWITCH_PRINT(device, SETUP, "%s: AC_DC_MODE = 0x%x\n",
__FUNCTION__, DRF_VAL(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL,
_AC_DC_MODE, regval));
regval = FLD_SET_DRF(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_AC_DC_MODE, _AC, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _AC_DC_MODE,
DRF_VAL(_NVLINK_VBIOS, _PARAM0, _ACDC_MODE, vbios_link_entry->nvLinkparam0),
regval);
}
if (device->regkeys.block_code_mode != NV_SWITCH_REGKEY_BLOCK_CODE_MODE_DEFAULT)
{
NVSWITCH_PRINT(device, SETUP, "%s: BLOCK_CODE_MODE = 0x%x requested by regkey\n",
__FUNCTION__, device->regkeys.block_code_mode);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_BLOCK_CODE_MODE, device->regkeys.block_code_mode, regval);
}
else if (vbios_link_entry != NULL)
{
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, _BLOCK_CODE_MODE,
DRF_VAL(_NVLINK_VBIOS, _PARAM3, _CLOCK_MODE_BLOCK_CODE, vbios_link_entry->nvLinkparam3),
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
(

View File

@ -255,202 +255,6 @@ _nvswitch_setup_chiplib_forced_config_lr10
FOR_EACH_INDEX_IN_MASK_END;
}
static NvU32
_nvswitch_get_nvlink_linerate
(
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;
}
static void
_nvswitch_setup_link_system_registers_lr10
(
nvswitch_device *device,
NVSWITCH_BIOS_NVLINK_CONFIG *bios_config,
nvlink_link *link
)
{
NvU32 regval, fldval;
NvU32 lineRate = 0;
NVLINK_CONFIG_DATA_LINKENTRY *vbios_link_entry = NULL;
//
// 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(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);
}
else
{
//
// Default working configuration for LR10
// This will be provided by VBIOS once support available (bug 2767390)
//
NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_MANTISSA = 0x5 forced by driver\n",
__FUNCTION__);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_MINIMUM_TRAIN_TIME_MANTISSA, 0x5, 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);
}
else
{
//
// Default working configuration for LR10
// This will be provided by VBIOS once support available (bug 2767390)
//
NVSWITCH_PRINT(device, SETUP, "%s: MINIMUM_TRAIN_TIME_EXPONENT = 0x4 forced by driver\n",
__FUNCTION__);
regval = FLD_SET_DRF_NUM(_NVLIPT_LNK_CTRL_SYSTEM_LINK, _CHANNEL_CTRL,
_TXTRAIN_MINIMUM_TRAIN_TIME_EXPONENT, 0x4, 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);
}
/*!
* @brief Parse packed little endian data and unpack into padded structure
*
@ -1261,69 +1065,6 @@ setup_link_vbios_overrides_done:
return status;
}
static void
_nvswitch_load_link_disable_settings_lr10
(
nvswitch_device *device,
NVSWITCH_BIOS_NVLINK_CONFIG *bios_config,
nvlink_link *link
)
{
NvU32 val;
NVLINK_CONFIG_DATA_LINKENTRY *vbios_link_entry = NULL;
// 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);
}
}
/*
* @Brief : Setting up system registers after device initialization
*
@ -1332,24 +1073,14 @@ _nvswitch_load_link_disable_settings_lr10
* @param[in] device a reference to the device to initialize
*/
NvlStatus
nvswitch_setup_link_system_registers_lr10
nvswitch_setup_system_registers_lr10
(
nvswitch_device *device
)
{
nvlink_link *link;
NvU8 i;
NvU32 val;
NvU64 enabledLinkMask;
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__);
}
enabledLinkMask = nvswitch_get_enabled_link_mask(device);
@ -1366,23 +1097,8 @@ nvswitch_setup_link_system_registers_lr10
continue;
}
// AC vs DC mode SYSTEM register
if (link->ac_coupled)
{
//
// In NVL3.0, ACMODE is handled by MINION in the INITPHASE1 command
// Here we just setup the register with the proper info
//
val = NVSWITCH_LINK_RD32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL);
val = FLD_SET_DRF(_NVLIPT_LNK,
_CTRL_SYSTEM_LINK_CHANNEL_CTRL, _AC_DC_MODE, _AC, val);
NVSWITCH_LINK_WR32_LR10(device, link->linkNumber, NVLIPT_LNK,
_NVLIPT_LNK, _CTRL_SYSTEM_LINK_CHANNEL_CTRL, val);
}
_nvswitch_setup_link_system_registers_lr10(device, bios_config, link);
_nvswitch_load_link_disable_settings_lr10(device, bios_config, link);
nvswitch_setup_link_system_registers(device, link);
nvswitch_load_link_disable_settings(device, link);
}
FOR_EACH_INDEX_IN_MASK_END;

View File

@ -479,6 +479,14 @@ _nvswitch_init_device_regkeys
NVSWITCH_INIT_REGKEY(_PRIVATE, link_recal_settings,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS,
NV_SWITCH_REGKEY_LINK_RECAL_SETTINGS_NOP);
NVSWITCH_INIT_REGKEY(_PRIVATE, block_code_mode,
NV_SWITCH_REGKEY_BLOCK_CODE_MODE,
NV_SWITCH_REGKEY_BLOCK_CODE_MODE_DEFAULT);
NVSWITCH_INIT_REGKEY(_PRIVATE, reference_clock_mode,
NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE,
NV_SWITCH_REGKEY_REFERENCE_CLOCK_MODE_DEFAULT);
}
NvU64
nvswitch_lib_deferred_task_dispatcher
@ -734,12 +742,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
@ -1406,7 +1414,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;
@ -3935,6 +3943,27 @@ nvswitch_apply_recal_settings
return device->hal.nvswitch_apply_recal_settings(device, link);
}
void
nvswitch_setup_link_system_registers
(
nvswitch_device *device,
nvlink_link *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
nvswitch_lib_ctrl
(

View File

@ -2033,8 +2033,6 @@ typedef struct NV2080_CTRL_GPU_GET_ALL_BRIDGES_UPSTREAM_OF_GPU_PARAMS {
NV2080_CTRL_GPU_BRIDGE_VERSION_PARAMS bridgeList[NV2080_CTRL_MAX_PHYSICAL_BRIDGE];
} NV2080_CTRL_GPU_GET_ALL_BRIDGES_UPSTREAM_OF_GPU_PARAMS;
/*
* NV2080_CTRL_CMD_GPU_QUERY_SCRUBBER_STATUS
*

View File

@ -79,4 +79,67 @@ typedef struct NVB0CC_CTRL_INTERNAL_PERMISSIONS_INIT_PARAMS {
NvBool bMemoryProfilingPermitted;
} NVB0CC_CTRL_INTERNAL_PERMISSIONS_INIT_PARAMS;
/*!
* NVB0CC_CTRL_CMD_INTERNAL_FREE_PMA_STREAM
*
* Internal logic for PMA Stream Free
*/
#define NVB0CC_CTRL_CMD_INTERNAL_FREE_PMA_STREAM (0xb0cc0206) /* finn: Evaluated from "(FINN_MAXWELL_PROFILER_INTERNAL_INTERFACE_ID << 8) | NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS_MESSAGE_ID" */
#define NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS_MESSAGE_ID (0x6U)
typedef struct NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS {
/*!
* [in] The PMA channel index associated with a given PMA stream.
*/
NvU32 pmaChannelIdx;
} NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS;
/*!
* NVB0CC_CTRL_CMD_INTERNAL_GET_MAX_PMAS
*
* Get the maximum number of PMA channels
*/
#define NVB0CC_CTRL_CMD_INTERNAL_GET_MAX_PMAS (0xb0cc0207) /* finn: Evaluated from "(FINN_MAXWELL_PROFILER_INTERNAL_INTERFACE_ID << 8) | NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS_MESSAGE_ID" */
#define NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS_MESSAGE_ID (0x7U)
typedef struct NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS {
/*!
* [out] Max number of PMA channels
*/
NvU32 maxPmaChannels;
} NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS;
/*!
* NVB0CC_CTRL_CMD_INTERNAL_BIND_PM_RESOURCES
*
* Internally bind PM resources.
*/
#define NVB0CC_CTRL_CMD_INTERNAL_BIND_PM_RESOURCES (0xb0cc0208) /* finn: Evaluated from "(FINN_MAXWELL_PROFILER_INTERNAL_INTERFACE_ID << 8) | 0x8" */
/*!
* NVB0CC_CTRL_CMD_INTERNAL_UNBIND_PM_RESOURCES
*
* Internally unbind PM resources.
*/
#define NVB0CC_CTRL_CMD_INTERNAL_UNBIND_PM_RESOURCES (0xb0cc0209) /* finn: Evaluated from "(FINN_MAXWELL_PROFILER_INTERNAL_INTERFACE_ID << 8) | 0x9" */
/*!
* NVB0CC_CTRL_CMD_INTERNAL_RESERVE_HWPM_LEGACY
*
* Reserve legacy HWPM resources
*/
#define NVB0CC_CTRL_CMD_INTERNAL_RESERVE_HWPM_LEGACY (0xb0cc020a) /* finn: Evaluated from "(FINN_MAXWELL_PROFILER_INTERNAL_INTERFACE_ID << 8) | NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS_MESSAGE_ID" */
#define NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS_MESSAGE_ID (0xaU)
typedef struct NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS {
/*!
* [in] Enable ctxsw for HWPM.
*/
NvBool ctxsw;
} NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS;
/* _ctrlb0ccinternal_h_ */

View File

@ -31,6 +31,9 @@ extern "C" {
#endif
void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo);
NVEvoPassiveDpDongleType nvDpyGetPassiveDpDongleType(
const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz);
void nvDpySetValidSyncsEvo(const NVDpyEvoRec *pDpyEvo,
struct NvKmsModeValidationValidSyncs *pValidSyncs);
NVDpyEvoPtr nvAllocDpyEvo(NVDispEvoPtr pDispEvo,

View File

@ -231,7 +231,6 @@ void nvSetColorSpaceAndRangeEvo(
NVEvoUpdateState *pUpdateState);
NvBool nvAssignSOREvo(NVConnectorEvoPtr pConnectorEvo, NvU32 sorExcludeMask);
void nvRestoreSORAssigmentsEvo(NVDevEvoRec *pDevEvo);
void nvSetSwapBarrierNotifyEvo(NVDispEvoPtr pDispEvo,
NvBool enable, NvBool isPre);
@ -290,6 +289,9 @@ void nvDPSerializerPostSetMode(NVDispEvoPtr pDispEvo,
NvBool nvFramelockSetControlUnsyncEvo(NVDispEvoPtr pDispEvo, const NvU32 headMask,
NvBool server);
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo);
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo);
#ifdef __cplusplus
};
#endif

View File

@ -60,6 +60,7 @@ NvBool nvInitHdmiLibrary(NVDevEvoRec *pDevEvo);
void nvTeardownHdmiLibrary(NVDevEvoRec *pDevEvo);
NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo);
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo);
NvBool nvHdmiFrlQueryConfig(const NVDpyEvoRec *pDpyEvo,
const NvModeTimings *pModeTimings,
NVHwModeTimingsEvo *pTimings,

View File

@ -51,9 +51,6 @@ static void DpyGetDynamicDfpProperties(
NVDpyEvoPtr pDpyEvo,
const NvBool disableACPIBrightnessHotkeys);
static NVEvoPassiveDpDongleType
DpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz);
static void
CreateParsedEdidFromNVT_TIMING(NVT_TIMING *pTimings,
NVParsedEdidEvoPtr pParsedEdid);
@ -643,53 +640,37 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
nvkms_memset(&pDpyEvo->hdmi.srcCaps, 0, sizeof(pDpyEvo->hdmi.srcCaps));
nvkms_memset(&pDpyEvo->hdmi.sinkCaps, 0, sizeof(pDpyEvo->hdmi.sinkCaps));
if (pDevEvo->hal->caps.supportsHDMIFRL) {
if (nvHdmiDpySupportsFrl(pDpyEvo)) {
/*
* This function is called multiple times for each pDpyEvo:
* - Once when the dpy is created
* - Once when the dpy is connected
* - Once when the dpy is disconnected
* In the first and third cases, we don't yet have an EDID so
* we don't know if the sink supports HDMI FRL. Assume it
* doesn't, since if we try to set a mode anyway there won't be
* a sink to do link training with.
* An SOR needs to be assigned temporarily to do FRL training.
*
* Since the only other SORs in use at the moment (if any) are
* those driving heads, we don't need to exclude RM from
* selecting any SOR, so an sorExcludeMask of 0 is appropriate.
*/
if (pDpyEvo->parsedEdid.valid &&
pDpyEvo->parsedEdid.info.hdmiForumInfo.max_FRL_Rate) {
if (nvAssignSOREvo(pConnectorEvo, 0) &&
nvHdmiFrlAssessLink(pDpyEvo)) {
/*
* An SOR needs to be assigned temporarily to do FRL
* training.
* Since the only other SORs in use at the moment (if any)
* are those driving heads, we don't need to exclude RM
* from selecting any SOR, so an sorExcludeMask of 0 is
* appropriate.
* Note that although we "assessed" the link above, the
* maximum pixel clock set here doesn't take that into
* account -- it's the maximum the GPU hardware is capable
* of on the most capable link, mostly for reporting
* purposes.
*
* The calculation for if a given mode can fit in the
* assessed FRL configuration is complex and depends on
* things like the amount of blanking, rather than a simple
* pclk cutoff. So, we query the hdmi library when
* validating each individual mode, when we know actual
* timings.
*/
if (nvAssignSOREvo(pConnectorEvo, 0)) {
if (nvHdmiFrlAssessLink(pDpyEvo)) {
/*
* Note that although we "assessed" the link above,
* the maximum pixel clock set here doesn't take
* that into account -- it's the maximum the GPU
* hardware is capable of on the most capable link,
* mostly for reporting purposes.
*
* The calculation for if a given mode can fit in
* the assessed FRL configuration is complex and
* depends on things like the amount of blanking,
* rather than a simple pclk cutoff. So, we query
* the hdmi library when validating each individual
* mode, when we know actual timings.
*/
pDpyEvo->maxPixelClockKHz =
/*
* This comes from the Windows display driver:
* (4 lanes * 12Gb per lane *
* FRL encoding i.e 16/18) / 1K
*/
((4 * 12 * 1000 * 1000 * 16) / 18);
}
}
/*
* This comes from the Windows display driver: (4 lanes *
* 12Gb per lane * FRL encoding i.e 16/18) / 1K
*/
pDpyEvo->maxPixelClockKHz =
((4 * 12 * 1000 * 1000 * 16) / 18);
}
}
} else {
@ -721,8 +702,8 @@ void nvDpyProbeMaxPixelClock(NVDpyEvoPtr pDpyEvo)
* restrictive than the one described above. Check whether one of
* these dongles is in use, and override the limit accordingly.
*/
passiveDpDongleType = DpyGetPassiveDpDongleType(pDpyEvo,
&passiveDpDongleMaxPclkKHz);
passiveDpDongleType =
nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz);
if (passiveDpDongleType != NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
pDpyEvo->maxPixelClockKHz = NV_MIN(passiveDpDongleMaxPclkKHz,
@ -799,9 +780,9 @@ static NvBool IsConnectorTMDS(NVConnectorEvoPtr pConnectorEvo)
* Query RM for the passive Displayport dongle type; this can influence
* the maximum pixel clock allowed on that display.
*/
static NVEvoPassiveDpDongleType
DpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
NVEvoPassiveDpDongleType
nvDpyGetPassiveDpDongleType(const NVDpyEvoRec *pDpyEvo,
NvU32 *passiveDpDongleMaxPclkKHz)
{
NV0073_CTRL_DFP_GET_DISPLAYPORT_DONGLE_INFO_PARAMS params = { 0 };
NvU32 ret;

View File

@ -3847,72 +3847,124 @@ NvBool nvAssignSOREvo(NVConnectorEvoPtr pConnectorEvo, NvU32 sorExcludeMask)
return TRUE;
}
void nvRestoreSORAssigmentsEvo(NVDevEvoRec *pDevEvo)
static void CacheSorAssignList(const NVDispEvoRec *pDispEvo,
const NVConnectorEvoRec *sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS])
{
const NVConnectorEvoRec *pConnectorEvo;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
NvU32 i;
if (pConnectorEvo->or.type != NV0073_CTRL_SPECIFIC_OR_TYPE_SOR) {
continue;
}
FOR_EACH_INDEX_IN_MASK(32, i, pConnectorEvo->or.mask) {
/*
* RM populates same sor index into more than one connectors if
* they are are DCC partners, this checks make sure SOR
* assignment happens only for a single connector. The sor
* assignment call before modeset/dp-link-training makes sure
* assignment happens for the correct connector.
*/
if (sorAssignList[i] != NULL) {
continue;
}
sorAssignList[i] = pConnectorEvo;
} FOR_EACH_INDEX_IN_MASK_END
}
}
static void RestoreSorAssignList(NVDispEvoRec *pDispEvo,
const NVConnectorEvoRec *sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS])
{
NVDevEvoRec *pDevEvo = pDispEvo->pDevEvo;
NvU32 sorIndex;
for (sorIndex = 0;
sorIndex < NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS; sorIndex++) {
if (sorAssignList[sorIndex] == NULL) {
continue;
}
NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS params = {
.subDeviceInstance = pDispEvo->displayOwner,
.displayId = nvDpyIdToNvU32(sorAssignList[sorIndex]->displayId),
.sorExcludeMask = ~NVBIT(sorIndex),
};
NvU32 ret;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_ASSIGN_SOR,
&params,
sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDispDebug(pDispEvo,
EVO_LOG_ERROR,
"Failed to restore SOR-%u -> %s assignment.",
sorIndex, sorAssignList[sorIndex]->name);
} else {
RefreshSORAssignments(pDispEvo, &params);
}
}
}
NvBool nvResumeDevEvo(NVDevEvoRec *pDevEvo)
{
struct {
const NVConnectorEvoRec *
sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS];
} disp[NVKMS_MAX_SUBDEVICES] = { };
NVDispEvoRec *pDispEvo;
NvU32 dispIndex;
if (!NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
if (NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
NV0073_CTRL_SYSTEM_CAPS_CROSS_BAR_SUPPORTED)) {
return;
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
const NVConnectorEvoRec *
sorAssignList[NV0073_CTRL_CMD_DFP_ASSIGN_SOR_MAX_SORS] = { };
const NVConnectorEvoRec *pConnectorEvo;
NvU32 sorIndex;
FOR_ALL_EVO_CONNECTORS(pConnectorEvo, pDispEvo) {
NvU32 i;
if (pConnectorEvo->or.type != NV0073_CTRL_SPECIFIC_OR_TYPE_SOR) {
continue;
}
FOR_EACH_INDEX_IN_MASK(32, i, pConnectorEvo->or.mask) {
/*
* RM populates same sor index into more than one connectors if
* they are are DCC partners, this checks make sure SOR
* assignment happens only for a single connector. The sor
* assignment call before modeset/dp-link-training makes sure
* assignment happens for the correct connector.
*/
if (sorAssignList[i] != NULL) {
continue;
}
sorAssignList[i] = pConnectorEvo;
} FOR_EACH_INDEX_IN_MASK_END
}
for (sorIndex = 0; sorIndex < ARRAY_LEN(sorAssignList); sorIndex++) {
if (sorAssignList[sorIndex] == NULL) {
continue;
}
NV0073_CTRL_DFP_ASSIGN_SOR_PARAMS params = {
.subDeviceInstance = pDispEvo->displayOwner,
.displayId = nvDpyIdToNvU32(sorAssignList[sorIndex]->displayId),
.sorExcludeMask = ~NVBIT(sorIndex),
};
NvU32 ret;
ret = nvRmApiControl(nvEvoGlobal.clientHandle,
pDevEvo->displayCommonHandle,
NV0073_CTRL_CMD_DFP_ASSIGN_SOR,
&params,
sizeof(params));
if (ret != NVOS_STATUS_SUCCESS) {
nvEvoLogDispDebug(pDispEvo,
EVO_LOG_ERROR,
"Failed to restore SOR-%u -> %s assigment.",
sorIndex, sorAssignList[sorIndex]->name);
} else {
RefreshSORAssignments(pDispEvo, &params);
}
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
CacheSorAssignList(pDispEvo, disp[dispIndex].sorAssignList);
}
}
if (!nvAllocCoreChannelEvo(pDevEvo)) {
return FALSE;
}
/*
* During the hibernate-resume cycle vbios or GOP driver programs
* the display engine to lit up the boot display. In
* hibernate-resume path, doing NV0073_CTRL_CMD_DFP_ASSIGN_SOR
* rm-control call before the core channel allocation causes display
* channel hang because at that stage RM is not aware of the boot
* display actived by vbios and it ends up unrouting active SOR
* assignments. Therefore restore the SOR assignment only after the
* core channel allocation.
*/
if (NV0073_CTRL_SYSTEM_GET_CAP(pDevEvo->commonCapsBits,
NV0073_CTRL_SYSTEM_CAPS_CROSS_BAR_SUPPORTED)) {
/*
* Shutdown all heads before restoring the SOR assignments because in
* case of hibernate-resume the SOR, for which NVKMS is trying to
* restore the assignment, might be in use by the boot display setup
* by vbios/gop driver.
*/
nvShutDownHeads(pDevEvo, NULL /* pTestFunc, shut down all heads */);
FOR_ALL_EVO_DISPLAYS(pDispEvo, dispIndex, pDevEvo) {
RestoreSorAssignList(pDispEvo, disp[dispIndex].sorAssignList);
}
}
return TRUE;
}
void nvSuspendDevEvo(NVDevEvoRec *pDevEvo)
{
nvFreeCoreChannelEvo(pDevEvo);
}
/*!

View File

@ -1898,6 +1898,8 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
NVHDMIPKT_RESULT ret;
const NvU32 displayId = nvDpyIdToNvU32(pDpyEvo->pConnectorEvo->displayId);
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/* HDMI dpys not dynamic dpy so its connector should have a dpyId. */
nvAssert(displayId != 0);
nvAssert(pDpyEvo->parsedEdid.valid);
@ -1916,33 +1918,54 @@ NvBool nvHdmiFrlAssessLink(NVDpyEvoPtr pDpyEvo)
return pDpyEvo->hdmi.sinkCaps.linkMaxFRLRate != HDMI_FRL_DATA_RATE_NONE;
}
/* Determine if HDMI FRL is needed to drive the given timings on the given dpy. */
static NvBool TimingsNeedFRL(const NVDpyEvoRec *pDpyEvo,
const NVHwModeTimingsEvo *pTimings)
/*
* Determine if the given HDMI dpy supports FRL.
*
* Returns TRUE if the dpy supports FRL, or FALSE otherwise.
*/
NvBool nvHdmiDpySupportsFrl(const NVDpyEvoRec *pDpyEvo)
{
NvU32 passiveDpDongleMaxPclkKHz;
const NVDevEvoRec *pDevEvo = pDpyEvo->pDispEvo->pDevEvo;
/* Can't use FRL if the display hardware doesn't support it */
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/* Can't use FRL if the display hardware doesn't support it. */
if (!pDevEvo->hal->caps.supportsHDMIFRL) {
return FALSE;
}
/* Can only use FRL for HDMI devices. */
if (!nvDpyIsHdmiEvo(pDpyEvo)) {
return FALSE;
}
/* Can only use FRL if the HDMI sink supports it. */
/* Can't use FRL if the HDMI sink doesn't support it. */
if (!pDpyEvo->parsedEdid.valid ||
!pDpyEvo->parsedEdid.info.hdmiForumInfo.max_FRL_Rate) {
return FALSE;
}
/* Can't use FRL if we are using a passive DP to HDMI dongle. */
if (nvDpyGetPassiveDpDongleType(pDpyEvo, &passiveDpDongleMaxPclkKHz) !=
NV_EVO_PASSIVE_DP_DONGLE_UNUSED) {
return FALSE;
}
return TRUE;
}
/*
* Determine if HDMI FRL is needed to drive timings with the given pixel clock
* on the given dpy.
*
* Returns TRUE if FRL is needed, or FALSE otherwise.
* */
static NvBool HdmiTimingsNeedFrl(const NVDpyEvoRec *pDpyEvo,
const NvU32 pixelClock)
{
nvAssert(nvDpyIsHdmiEvo(pDpyEvo));
/*
* For HDMI, maxSingleLinkPixelClockKHz is the maximum non-FRL rate.
* If the rate is higher than that, try to use FRL for the mode.
*/
return pTimings->pixelClock > pDpyEvo->maxSingleLinkPixelClockKHz;
return pixelClock > pDpyEvo->maxSingleLinkPixelClockKHz;
}
NvBool nvHdmiFrlQueryConfig(
@ -1959,10 +1982,15 @@ NvBool nvHdmiFrlQueryConfig(
NVT_TIMING nvtTiming = { };
NVHDMIPKT_RESULT ret;
if (!TimingsNeedFRL(pDpyEvo, pHwTimings)) {
if (!nvDpyIsHdmiEvo(pDpyEvo) ||
!HdmiTimingsNeedFrl(pDpyEvo, pHwTimings->pixelClock)) {
return TRUE;
}
if (!nvHdmiDpySupportsFrl(pDpyEvo)) {
return FALSE;
}
/* See if we can find an NVT_TIMING for this mode from the EDID. */
pNvtTiming = nvFindEdidNVT_TIMING(pDpyEvo, pModeTimings, pValidationParams);

View File

@ -934,14 +934,6 @@ static void RevokePermissionsInternal(
}
}
static void ReallocCoreChannel(NVDevEvoRec *pDevEvo)
{
if (nvAllocCoreChannelEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
}
static void RestoreConsole(NVDevEvoPtr pDevEvo)
{
pDevEvo->modesetOwnerChanged = TRUE;
@ -956,7 +948,10 @@ static void RestoreConsole(NVDevEvoPtr pDevEvo)
// Reallocate the core channel right after freeing it. This makes sure
// that it's allocated and ready right away if another NVKMS client is
// started.
ReallocCoreChannel(pDevEvo);
if (nvAllocCoreChannelEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
}
}
@ -4845,7 +4840,7 @@ void nvKmsSuspend(NvU32 gpuId)
FreeSurfaceCtxDmasForAllOpens(pDevEvo);
nvFreeCoreChannelEvo(pDevEvo);
nvSuspendDevEvo(pDevEvo);
}
}
@ -4862,9 +4857,10 @@ void nvKmsResume(NvU32 gpuId)
FOR_ALL_EVO_DEVS(pDevEvo) {
nvEvoLogDevDebug(pDevEvo, EVO_LOG_INFO, "Resuming");
nvRestoreSORAssigmentsEvo(pDevEvo);
ReallocCoreChannel(pDevEvo);
if (nvResumeDevEvo(pDevEvo)) {
nvDPSetAllowMultiStreaming(pDevEvo, TRUE /* allowMST */);
AllocSurfaceCtxDmasForAllOpens(pDevEvo);
}
if (pDevEvo->modesetOwner == NULL) {
// Hardware state was lost, so we need to force a console

View File

@ -466,6 +466,10 @@
#define ESC_4000_G4_DEVID 0xA1C1
#define ESC_4000_G4_SSDEVID 0x871E
// Lenovo Tomcat Workstation
#define LENOVO_TOMCAT_DEVID 0x1B81
#define LENOVO_TOMCAT_SSDEVID 0x104e
// NVIDIA C51
#define NVIDIA_C51_DEVICE_ID_MIN 0x2F0

View File

@ -911,16 +911,23 @@ NV_STATUS osAllocPagesInternal(
if (nv && (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_32BIT_ADDRESSABLE)))
nv->force_dma32_alloc = NV_TRUE;
status = nv_alloc_pages(
NV_GET_NV_STATE(pGpu),
NV_RM_PAGES_TO_OS_PAGES(pMemDesc->PageCount),
memdescGetContiguity(pMemDesc, AT_CPU),
memdescGetCpuCacheAttrib(pMemDesc),
pSys->getProperty(pSys,
PDB_PROP_SYS_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS),
unencrypted,
memdescGetPteArray(pMemDesc, AT_CPU),
&pMemData);
if (NV_RM_PAGES_TO_OS_PAGES(pMemDesc->PageCount) > NV_U32_MAX)
{
status = NV_ERR_INVALID_LIMIT;
}
else
{
status = nv_alloc_pages(
NV_GET_NV_STATE(pGpu),
NV_RM_PAGES_TO_OS_PAGES(pMemDesc->PageCount),
memdescGetContiguity(pMemDesc, AT_CPU),
memdescGetCpuCacheAttrib(pMemDesc),
pSys->getProperty(pSys,
PDB_PROP_SYS_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS),
unencrypted,
memdescGetPteArray(pMemDesc, AT_CPU),
&pMemData);
}
if (nv && nv->force_dma32_alloc)
nv->force_dma32_alloc = NV_FALSE;
@ -1204,12 +1211,11 @@ static void postEvent(
NvBool dataValid
)
{
nv_state_t *nv = nv_get_ctl_state();
portSyncSpinlockAcquire(nv->event_spinlock);
if (event->active)
nv_post_event(event, hEvent, notifyIndex,
info32, info16, dataValid);
portSyncSpinlockRelease(nv->event_spinlock);
if (osReferenceObjectCount(event) != NV_OK)
return;
nv_post_event(event, hEvent, notifyIndex,
info32, info16, dataValid);
osDereferenceObjectCount(event);
}
NvU32 osSetEvent
@ -1428,6 +1434,12 @@ NV_STATUS osReferenceObjectCount(void *pEvent)
nv_event_t *event = pEvent;
portSyncSpinlockAcquire(nv->event_spinlock);
// If event->active is false, don't allow any more reference
if (!event->active)
{
portSyncSpinlockRelease(nv->event_spinlock);
return NV_ERR_INVALID_EVENT;
}
++event->refcount;
portSyncSpinlockRelease(nv->event_spinlock);
return NV_OK;
@ -1440,11 +1452,10 @@ NV_STATUS osDereferenceObjectCount(void *pOSEvent)
portSyncSpinlockAcquire(nv->event_spinlock);
NV_ASSERT(event->refcount > 0);
--event->refcount;
// If event->refcount == 0 but event->active is true, the client
// has not yet freed the OS event. free_os_event will free its
// memory when they do, or else when the client itself is freed.
if (event->refcount == 0 && !event->active)
if (--event->refcount == 0 && !event->active)
portMemFree(event);
portSyncSpinlockRelease(nv->event_spinlock);

View File

@ -354,9 +354,7 @@ static void free_os_event_under_lock(nv_event_t *event)
// If refcount > 0, event will be freed by osDereferenceObjectCount
// when the last associated RM event is freed.
if (event->refcount == 0)
{
portMemFree(event);
}
}
static void free_os_events(

View File

@ -521,6 +521,11 @@ NV_STATUS engineNonStallIntrNotify(OBJGPU *, NvU32);
NV_STATUS notifyEvents(OBJGPU*, EVENTNOTIFICATION*, NvU32, NvU32, NvU32, NV_STATUS, NvU32);
NV_STATUS engineNonStallIntrNotifyEvent(OBJGPU *, NvU32, NvHandle);
typedef struct GpuEngineEventNotificationList GpuEngineEventNotificationList;
NV_STATUS gpuEngineEventNotificationListCreate(OBJGPU *, GpuEngineEventNotificationList **);
void gpuEngineEventNotificationListDestroy(OBJGPU *, GpuEngineEventNotificationList *);
#endif // _EVENT_H_
#ifdef __cplusplus

View File

@ -630,21 +630,6 @@ typedef struct // GPU specific data for core logic object, stored in GPU object
#define GPU_STATE_DEFAULT 0 // Default flags for destructive state loads
// and unloads
typedef struct engine_event_node
{
PEVENTNOTIFICATION pEventNotify;
struct Memory *pMemory;
struct engine_event_node *pNext;
} ENGINE_EVENT_NODE;
// Linked list of per engine non-stall event nodes
typedef struct
{
ENGINE_EVENT_NODE *pEventNode;
// lock to protect above list
PORT_SPINLOCK *pSpinlock;
} ENGINE_EVENT_LIST;
struct OBJHWBC;
typedef struct hwbc_list
{
@ -906,7 +891,7 @@ struct OBJGPU {
OS_RM_CAPS *pOsRmCaps;
NvU32 halImpl;
void *hPci;
ENGINE_EVENT_LIST engineNonstallIntr[52];
GpuEngineEventNotificationList *engineNonstallIntrEventNotifications[52];
NvBool bIsSOC;
NvU32 gpuInstance;
NvU32 gpuDisabled;

View File

@ -332,6 +332,9 @@ typedef struct MEMORY_DESCRIPTOR
// Serve as a head node in a list of submemdescs
MEMORY_DESCRIPTOR_LIST *pSubMemDescList;
// Reserved for RM exclusive use
NvBool bRmExclusiveUse;
// If strung in a intrusive linked list
ListNode node;
@ -631,6 +634,8 @@ PMEMORY_DESCRIPTOR memdescGetRootMemDesc(PMEMORY_DESCRIPTOR pMemDesc, NvU64 *pRo
void memdescSetCustomHeap(PMEMORY_DESCRIPTOR);
NvBool memdescGetCustomHeap(PMEMORY_DESCRIPTOR);
NvBool memdescAcquireRmExclusiveUse(MEMORY_DESCRIPTOR *pMemDesc);
/*!
* @brief Get PTE kind
*

View File

@ -808,8 +808,8 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x20B2, 0x147f, 0x10de, "NVIDIA A100-SXM4-80GB" },
{ 0x20B2, 0x1622, 0x10de, "NVIDIA A100-SXM4-80GB" },
{ 0x20B2, 0x1623, 0x10de, "NVIDIA A100-SXM4-80GB" },
{ 0x20B3, 0x14a7, 0x10de, "NVIDIA PG506-242" },
{ 0x20B3, 0x14a8, 0x10de, "NVIDIA PG506-243" },
{ 0x20B3, 0x14a7, 0x10de, "NVIDIA A100-SXM-64GB" },
{ 0x20B3, 0x14a8, 0x10de, "NVIDIA A100-SXM-64GB" },
{ 0x20B5, 0x1533, 0x10de, "NVIDIA A100 80GB PCIe" },
{ 0x20B5, 0x1642, 0x10de, "NVIDIA A100 80GB PCIe" },
{ 0x20B6, 0x1492, 0x10de, "NVIDIA PG506-232" },
@ -825,7 +825,6 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x20F3, 0x17a2, 0x10de, "NVIDIA A800-SXM4-80GB" },
{ 0x20F5, 0x1799, 0x10de, "NVIDIA A800 80GB PCIe" },
{ 0x20F5, 0x179a, 0x10de, "NVIDIA A800 80GB PCIe LC" },
{ 0x20F6, 0x17a3, 0x10de, "NVIDIA A800 40GB PCIe" },
{ 0x2182, 0x0000, 0x0000, "NVIDIA GeForce GTX 1660 Ti" },
{ 0x2184, 0x0000, 0x0000, "NVIDIA GeForce GTX 1660" },
{ 0x2187, 0x0000, 0x0000, "NVIDIA GeForce GTX 1650 SUPER" },
@ -935,6 +934,7 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x2571, 0x1611, 0x103c, "NVIDIA RTX A2000 12GB" },
{ 0x2571, 0x1611, 0x10de, "NVIDIA RTX A2000 12GB" },
{ 0x2571, 0x1611, 0x17aa, "NVIDIA RTX A2000 12GB" },
{ 0x2582, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050" },
{ 0x25A0, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 Ti Laptop GPU" },
{ 0x25A0, 0x8928, 0x103c, "NVIDIA GeForce RTX 3050Ti Laptop GPU" },
{ 0x25A0, 0x89f9, 0x103c, "NVIDIA GeForce RTX 3050Ti Laptop GPU" },
@ -947,6 +947,9 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x25A7, 0x0000, 0x0000, "NVIDIA GeForce RTX 2050" },
{ 0x25A9, 0x0000, 0x0000, "NVIDIA GeForce RTX 2050" },
{ 0x25AA, 0x0000, 0x0000, "NVIDIA GeForce MX570 A" },
{ 0x25AB, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 4GB Laptop GPU" },
{ 0x25AC, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 6GB Laptop GPU" },
{ 0x25AD, 0x0000, 0x0000, "NVIDIA GeForce RTX 2050" },
{ 0x25B6, 0x14a9, 0x10de, "NVIDIA A16" },
{ 0x25B6, 0x157e, 0x10de, "NVIDIA A2" },
{ 0x25B8, 0x0000, 0x0000, "NVIDIA RTX A2000 Laptop GPU" },
@ -956,8 +959,11 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x25E0, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 Ti Laptop GPU" },
{ 0x25E2, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 Laptop GPU" },
{ 0x25E5, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 Laptop GPU" },
{ 0x25EC, 0x0000, 0x0000, "NVIDIA GeForce RTX 3050 6GB Laptop GPU" },
{ 0x25ED, 0x0000, 0x0000, "NVIDIA GeForce RTX 2050" },
{ 0x25F9, 0x0000, 0x0000, "NVIDIA RTX A1000 Embedded GPU" },
{ 0x25FA, 0x0000, 0x0000, "NVIDIA RTX A2000 Embedded GPU" },
{ 0x25FB, 0x0000, 0x0000, "NVIDIA RTX A500 Embedded GPU" },
{ 0x13BD, 0x11cc, 0x10DE, "GRID M10-0B" },
{ 0x13BD, 0x11cd, 0x10DE, "GRID M10-1B" },
{ 0x13BD, 0x11ce, 0x10DE, "GRID M10-0Q" },

View File

@ -188,12 +188,12 @@ static NvBool __nvoc_thunk_RmResource_profilerBaseAccessCallback(struct Profiler
static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_ProfilerBase[] =
{
{ /* [0] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdReserveHwpmLegacy_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
/*flags=*/ 0x210u,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*flags=*/ 0x2010u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0101u,
/*paramSize=*/ sizeof(NVB0CC_CTRL_RESERVE_HWPM_LEGACY_PARAMS),
@ -263,12 +263,12 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
#endif
},
{ /* [5] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x10u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdFreePmaStream_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
/*flags=*/ 0x210u,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x10u)
/*flags=*/ 0x10u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0106u,
/*paramSize=*/ sizeof(NVB0CC_CTRL_FREE_PMA_STREAM_PARAMS),
@ -278,12 +278,12 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
#endif
},
{ /* [6] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdBindPmResources_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
/*flags=*/ 0x210u,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*flags=*/ 0x2010u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0107u,
/*paramSize=*/ 0,
@ -293,12 +293,12 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
#endif
},
{ /* [7] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdUnbindPmResources_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
/*flags=*/ 0x210u,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
/*flags=*/ 0x2010u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0108u,
/*paramSize=*/ 0,
@ -323,12 +323,12 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
#endif
},
{ /* [9] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x230u)
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2230u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdExecRegops_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x230u)
/*flags=*/ 0x230u,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2230u)
/*flags=*/ 0x2230u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc010au,
/*paramSize=*/ sizeof(NVB0CC_CTRL_EXEC_REG_OPS_PARAMS),
@ -440,6 +440,81 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalPermissionsInit"
#endif
},
{ /* [17] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdInternalFreePmaStream_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*flags=*/ 0x610u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0206u,
/*paramSize=*/ sizeof(NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS),
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalFreePmaStream"
#endif
},
{ /* [18] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdInternalGetMaxPmas_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*flags=*/ 0x610u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0207u,
/*paramSize=*/ sizeof(NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS),
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalGetMaxPmas"
#endif
},
{ /* [19] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdInternalBindPmResources_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*flags=*/ 0x610u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0208u,
/*paramSize=*/ 0,
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalBindPmResources"
#endif
},
{ /* [20] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdInternalUnbindPmResources_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*flags=*/ 0x610u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc0209u,
/*paramSize=*/ 0,
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalUnbindPmResources"
#endif
},
{ /* [21] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) profilerBaseCtrlCmdInternalReserveHwpmLegacy_IMPL,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
/*flags=*/ 0x610u,
/*accessRight=*/0x0u,
/*methodId=*/ 0xb0cc020au,
/*paramSize=*/ sizeof(NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS),
/*pClassInfo=*/ &(__nvoc_class_def_ProfilerBase.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "profilerBaseCtrlCmdInternalReserveHwpmLegacy"
#endif
},
@ -447,7 +522,7 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_Profiler
const struct NVOC_EXPORT_INFO __nvoc_export_info_ProfilerBase =
{
/*numEntries=*/ 17,
/*numEntries=*/ 22,
/*pExportEntries=*/ __nvoc_exported_method_def_ProfilerBase
};
@ -494,10 +569,14 @@ static void __nvoc_init_funcTable_ProfilerBase_1(ProfilerBase *pThis, RmHalspecO
PORT_UNREFERENCED_VARIABLE(rmVariantHal);
PORT_UNREFERENCED_VARIABLE(rmVariantHal_HalVarIdx);
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
pThis->__profilerBaseCtrlCmdReserveHwpmLegacy__ = &profilerBaseCtrlCmdReserveHwpmLegacy_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
pThis->__profilerBaseCtrlCmdInternalReserveHwpmLegacy__ = &profilerBaseCtrlCmdInternalReserveHwpmLegacy_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
pThis->__profilerBaseCtrlCmdReleaseHwpmLegacy__ = &profilerBaseCtrlCmdReleaseHwpmLegacy_IMPL;
#endif
@ -514,23 +593,39 @@ static void __nvoc_init_funcTable_ProfilerBase_1(ProfilerBase *pThis, RmHalspecO
pThis->__profilerBaseCtrlCmdAllocPmaStream__ = &profilerBaseCtrlCmdAllocPmaStream_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x10u)
pThis->__profilerBaseCtrlCmdFreePmaStream__ = &profilerBaseCtrlCmdFreePmaStream_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
pThis->__profilerBaseCtrlCmdInternalFreePmaStream__ = &profilerBaseCtrlCmdInternalFreePmaStream_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
pThis->__profilerBaseCtrlCmdInternalGetMaxPmas__ = &profilerBaseCtrlCmdInternalGetMaxPmas_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
pThis->__profilerBaseCtrlCmdBindPmResources__ = &profilerBaseCtrlCmdBindPmResources_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2010u)
pThis->__profilerBaseCtrlCmdUnbindPmResources__ = &profilerBaseCtrlCmdUnbindPmResources_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
pThis->__profilerBaseCtrlCmdInternalBindPmResources__ = &profilerBaseCtrlCmdInternalBindPmResources_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x610u)
pThis->__profilerBaseCtrlCmdInternalUnbindPmResources__ = &profilerBaseCtrlCmdInternalUnbindPmResources_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x210u)
pThis->__profilerBaseCtrlCmdPmaStreamUpdateGetPut__ = &profilerBaseCtrlCmdPmaStreamUpdateGetPut_IMPL;
#endif
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x230u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x2230u)
pThis->__profilerBaseCtrlCmdExecRegops__ = &profilerBaseCtrlCmdExecRegops_IMPL;
#endif

View File

@ -67,13 +67,18 @@ struct ProfilerBase {
struct GpuResource *__nvoc_pbase_GpuResource;
struct ProfilerBase *__nvoc_pbase_ProfilerBase;
NV_STATUS (*__profilerBaseCtrlCmdReserveHwpmLegacy__)(struct ProfilerBase *, NVB0CC_CTRL_RESERVE_HWPM_LEGACY_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdInternalReserveHwpmLegacy__)(struct ProfilerBase *, NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdReleaseHwpmLegacy__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdReservePmAreaSmpc__)(struct ProfilerBase *, NVB0CC_CTRL_RESERVE_PM_AREA_SMPC_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdReleasePmAreaSmpc__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdAllocPmaStream__)(struct ProfilerBase *, NVB0CC_CTRL_ALLOC_PMA_STREAM_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdFreePmaStream__)(struct ProfilerBase *, NVB0CC_CTRL_FREE_PMA_STREAM_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdInternalFreePmaStream__)(struct ProfilerBase *, NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdInternalGetMaxPmas__)(struct ProfilerBase *, NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdBindPmResources__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdUnbindPmResources__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdInternalBindPmResources__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdInternalUnbindPmResources__)(struct ProfilerBase *);
NV_STATUS (*__profilerBaseCtrlCmdPmaStreamUpdateGetPut__)(struct ProfilerBase *, NVB0CC_CTRL_PMA_STREAM_UPDATE_GET_PUT_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdExecRegops__)(struct ProfilerBase *, NVB0CC_CTRL_EXEC_REG_OPS_PARAMS *);
NV_STATUS (*__profilerBaseCtrlCmdInternalAllocPmaStream__)(struct ProfilerBase *, NVB0CC_CTRL_ALLOC_PMA_STREAM_PARAMS *);
@ -105,6 +110,13 @@ struct ProfilerBase {
NV_STATUS (*__profilerBaseControlLookup__)(struct ProfilerBase *, struct RS_RES_CONTROL_PARAMS_INTERNAL *, const struct NVOC_EXPORTED_METHOD_DEF **);
NV_STATUS (*__profilerBaseMap__)(struct ProfilerBase *, struct CALL_CONTEXT *, struct RS_CPU_MAP_PARAMS *, struct RsCpuMapping *);
NvBool (*__profilerBaseAccessCallback__)(struct ProfilerBase *, struct RsClient *, void *, RsAccessRight);
NvU32 maxPmaChannels;
NvU32 pmaVchIdx;
NvBool bLegacyHwpm;
struct RsResourceRef **ppBytesAvailable;
struct RsResourceRef **ppStreamBuffers;
struct RsResourceRef *pBoundCntBuf;
struct RsResourceRef *pBoundPmaBuf;
};
#ifndef __NVOC_CLASS_ProfilerBase_TYPEDEF__
@ -136,13 +148,18 @@ NV_STATUS __nvoc_objCreate_ProfilerBase(ProfilerBase**, Dynamic*, NvU32, struct
__nvoc_objCreate_ProfilerBase((ppNewObj), staticCast((pParent), Dynamic), (createFlags), arg_pCallContext, arg_pParams)
#define profilerBaseCtrlCmdReserveHwpmLegacy(pProfiler, pParams) profilerBaseCtrlCmdReserveHwpmLegacy_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdInternalReserveHwpmLegacy(pProfiler, pParams) profilerBaseCtrlCmdInternalReserveHwpmLegacy_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdReleaseHwpmLegacy(pProfiler) profilerBaseCtrlCmdReleaseHwpmLegacy_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdReservePmAreaSmpc(pProfiler, pParams) profilerBaseCtrlCmdReservePmAreaSmpc_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdReleasePmAreaSmpc(pProfiler) profilerBaseCtrlCmdReleasePmAreaSmpc_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdAllocPmaStream(pProfiler, pParams) profilerBaseCtrlCmdAllocPmaStream_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdFreePmaStream(pProfiler, pParams) profilerBaseCtrlCmdFreePmaStream_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdInternalFreePmaStream(pProfiler, pParams) profilerBaseCtrlCmdInternalFreePmaStream_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdInternalGetMaxPmas(pProfiler, pParams) profilerBaseCtrlCmdInternalGetMaxPmas_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdBindPmResources(pProfiler) profilerBaseCtrlCmdBindPmResources_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdUnbindPmResources(pProfiler) profilerBaseCtrlCmdUnbindPmResources_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdInternalBindPmResources(pProfiler) profilerBaseCtrlCmdInternalBindPmResources_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdInternalUnbindPmResources(pProfiler) profilerBaseCtrlCmdInternalUnbindPmResources_DISPATCH(pProfiler)
#define profilerBaseCtrlCmdPmaStreamUpdateGetPut(pProfiler, pParams) profilerBaseCtrlCmdPmaStreamUpdateGetPut_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdExecRegops(pProfiler, pParams) profilerBaseCtrlCmdExecRegops_DISPATCH(pProfiler, pParams)
#define profilerBaseCtrlCmdInternalAllocPmaStream(pProfiler, pParams) profilerBaseCtrlCmdInternalAllocPmaStream_DISPATCH(pProfiler, pParams)
@ -209,6 +226,12 @@ static inline NV_STATUS profilerBaseCtrlCmdReserveHwpmLegacy_DISPATCH(struct Pro
return pProfiler->__profilerBaseCtrlCmdReserveHwpmLegacy__(pProfiler, pParams);
}
NV_STATUS profilerBaseCtrlCmdInternalReserveHwpmLegacy_IMPL(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS *pParams);
static inline NV_STATUS profilerBaseCtrlCmdInternalReserveHwpmLegacy_DISPATCH(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_RESERVE_HWPM_LEGACY_PARAMS *pParams) {
return pProfiler->__profilerBaseCtrlCmdInternalReserveHwpmLegacy__(pProfiler, pParams);
}
NV_STATUS profilerBaseCtrlCmdReleaseHwpmLegacy_IMPL(struct ProfilerBase *pProfiler);
static inline NV_STATUS profilerBaseCtrlCmdReleaseHwpmLegacy_DISPATCH(struct ProfilerBase *pProfiler) {
@ -239,6 +262,18 @@ static inline NV_STATUS profilerBaseCtrlCmdFreePmaStream_DISPATCH(struct Profile
return pProfiler->__profilerBaseCtrlCmdFreePmaStream__(pProfiler, pParams);
}
NV_STATUS profilerBaseCtrlCmdInternalFreePmaStream_IMPL(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS *pParams);
static inline NV_STATUS profilerBaseCtrlCmdInternalFreePmaStream_DISPATCH(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS *pParams) {
return pProfiler->__profilerBaseCtrlCmdInternalFreePmaStream__(pProfiler, pParams);
}
NV_STATUS profilerBaseCtrlCmdInternalGetMaxPmas_IMPL(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS *pParams);
static inline NV_STATUS profilerBaseCtrlCmdInternalGetMaxPmas_DISPATCH(struct ProfilerBase *pProfiler, NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS *pParams) {
return pProfiler->__profilerBaseCtrlCmdInternalGetMaxPmas__(pProfiler, pParams);
}
NV_STATUS profilerBaseCtrlCmdBindPmResources_IMPL(struct ProfilerBase *pProfiler);
static inline NV_STATUS profilerBaseCtrlCmdBindPmResources_DISPATCH(struct ProfilerBase *pProfiler) {
@ -251,6 +286,18 @@ static inline NV_STATUS profilerBaseCtrlCmdUnbindPmResources_DISPATCH(struct Pro
return pProfiler->__profilerBaseCtrlCmdUnbindPmResources__(pProfiler);
}
NV_STATUS profilerBaseCtrlCmdInternalBindPmResources_IMPL(struct ProfilerBase *pProfiler);
static inline NV_STATUS profilerBaseCtrlCmdInternalBindPmResources_DISPATCH(struct ProfilerBase *pProfiler) {
return pProfiler->__profilerBaseCtrlCmdInternalBindPmResources__(pProfiler);
}
NV_STATUS profilerBaseCtrlCmdInternalUnbindPmResources_IMPL(struct ProfilerBase *pProfiler);
static inline NV_STATUS profilerBaseCtrlCmdInternalUnbindPmResources_DISPATCH(struct ProfilerBase *pProfiler) {
return pProfiler->__profilerBaseCtrlCmdInternalUnbindPmResources__(pProfiler);
}
NV_STATUS profilerBaseCtrlCmdPmaStreamUpdateGetPut_IMPL(struct ProfilerBase *pProfiler, NVB0CC_CTRL_PMA_STREAM_UPDATE_GET_PUT_PARAMS *pParams);
static inline NV_STATUS profilerBaseCtrlCmdPmaStreamUpdateGetPut_DISPATCH(struct ProfilerBase *pProfiler, NVB0CC_CTRL_PMA_STREAM_UPDATE_GET_PUT_PARAMS *pParams) {

View File

@ -267,9 +267,9 @@ static NV_STATUS _issueRpcLarge
//
// Copy the initial buffer
// Temporary black magic WAR for bug 3594082: reducing the size by 1
// Temporary black magic WAR for bug 3594082: reducing the size by 2
//
entryLength = NV_MIN(bufSize, pRpc->maxRpcSize - 1);
entryLength = NV_MIN(bufSize, pRpc->maxRpcSize - 2);
if ((NvU8 *)vgpu_rpc_message_header_v != pBuf8)
portMemCopy(vgpu_rpc_message_header_v, entryLength, pBuf8, entryLength);
@ -296,9 +296,9 @@ static NV_STATUS _issueRpcLarge
//
// Copy the remaining buffers
// Temporary black magic WAR for bug 3594082: reducing the size by 1
// Temporary black magic WAR for bug 3594082: reducing the size by 2
//
entryLength = pRpc->maxRpcSize - sizeof(rpc_message_header_v) - 1;
entryLength = pRpc->maxRpcSize - sizeof(rpc_message_header_v) - 2;
while (remainingSize != 0)
{
if (entryLength > remainingSize)
@ -357,7 +357,8 @@ static NV_STATUS _issueRpcLarge
pBuf8 = (NvU8 *)pBuffer;
remainingSize = bufSize;
entryLength = NV_MIN(bufSize, pRpc->maxRpcSize);
entryLength = NV_MIN(bufSize, vgpu_rpc_message_header_v->length);
NV_CHECK_OR_RETURN(LEVEL_ERROR, entryLength <= pRpc->maxRpcSize, NV_ERR_INVALID_STATE);
if (((NvU8 *)vgpu_rpc_message_header_v != pBuf8) && bBidirectional)
portMemCopy(pBuf8, entryLength, vgpu_rpc_message_header_v, entryLength);
@ -388,8 +389,11 @@ static NV_STATUS _issueRpcLarge
NV_ASSERT(0);
return nvStatus;
}
entryLength = vgpu_rpc_message_header_v->length - sizeof(rpc_message_header_v);
entryLength = vgpu_rpc_message_header_v->length;
NV_CHECK_OR_RETURN(LEVEL_ERROR, entryLength <= pRpc->maxRpcSize, NV_ERR_INVALID_STATE);
NV_CHECK_OR_RETURN(LEVEL_ERROR, entryLength >= sizeof(rpc_message_header_v), NV_ERR_INVALID_STATE);
entryLength -= sizeof(rpc_message_header_v);
if (entryLength > remainingSize)
entryLength = remainingSize;
@ -1635,9 +1639,9 @@ NV_STATUS rpcRmApiControl_GSP
if (status != NV_OK)
{
NV_PRINTF(LEVEL_WARNING,
"GspRmControl failed: hClient=0x%08x; hObject=0x%08x; cmd=0x%08x; paramsSize=0x%08x; paramsStatus=0x%08x; status=0x%08x\n",
hClient, hObject, cmd, paramsSize, rpc_params->status, status);
NV_PRINTF_COND((status == (NV_ERR_NOT_SUPPORTED || NV_ERR_OBJECT_NOT_FOUND)), LEVEL_INFO, LEVEL_WARNING,
"GspRmControl failed: hClient=0x%08x; hObject=0x%08x; cmd=0x%08x; paramsSize=0x%08x; paramsStatus=0x%08x; status=0x%08x\n",
hClient, hObject, cmd, paramsSize, rpc_params->status, status);
}
done:

View File

@ -555,12 +555,11 @@ _rmGpuLocksAcquire(NvU32 gpuMask, NvU32 flags, NvU32 module, void *ra, NvU32 *pG
// If we own a higher order lock than one of the needed ones, we are
// violating the locking order and need to do a conditional acquire
// clz32(0) == ctz(0) == 32:
// owned=0b00110000, needed=0b00001100: (4 < (32-28)), bCond=FALSE
// owned=0b00110010, needed=0b00001100: (1 < (32-28)), bCond=TRUE
// owned=0b00010000, needed=0b11000011: (4 < (32-24)), bCond=TRUE
// owned=0b00000000, needed=0b00001100: (32 < (32-28)), bCond=FALSE
// owned=0b00000001, needed=0b00000000: (0 < (32-32)), bCond=FALSE
if (portUtilCountTrailingZeros32(ownedMask) < (32-portUtilCountLeadingZeros32(gpuMask)))
// owned=0b00001100, needed=0b00110000: ((32-28) > 4), bCond=FALSE
// owned=0b00001100, needed=0b00110010: ((32-28) > 1), bCond=TRUE
// owned=0b11000011, needed=0b00010000: ((32-24) > 4), bCond=TRUE
// owned=0b00000000, needed=0b00000001: ((32-32) > 0), bCond=FALSE
if ((32-portUtilCountLeadingZeros32(ownedMask)) > portUtilCountTrailingZeros32(gpuMask))
{
bCondAcquireCheck = NV_TRUE;
}

View File

@ -362,8 +362,11 @@ kbusRemoveNvlinkPeerMapping_GP100
peerId, gpuGetInstance(pGpu0));
// Before removing the NVLink peer mapping in HSHUB flush both ends
kbusFlush_HAL(pGpu0, pKernelBus0, BUS_FLUSH_VIDEO_MEMORY);
kbusFlush_HAL(pGpu1, GPU_GET_KERNEL_BUS(pGpu1), BUS_FLUSH_VIDEO_MEMORY);
if (IsAMPEREorBetter(pGpu0))
{
kbusFlush_HAL(pGpu0, pKernelBus0, BUS_FLUSH_VIDEO_MEMORY | BUS_FLUSH_USE_PCIE_READ);
kbusFlush_HAL(pGpu1, GPU_GET_KERNEL_BUS(pGpu1), BUS_FLUSH_VIDEO_MEMORY | BUS_FLUSH_USE_PCIE_READ);
}
NV2080_CTRL_NVLINK_ENABLE_NVLINK_PEER_PARAMS params;
portMemSet(&params, 0, sizeof(params));

View File

@ -143,7 +143,9 @@ kflcnPreResetWait_GA10X
{
NvU32 hwcfg2;
RMTIMEOUT timeout;
NvU32 flags = GPU_TIMEOUT_FLAGS_DEFAULT | GPU_TIMEOUT_FLAGS_BYPASS_JOURNAL_LOG;
NvU32 flags = (GPU_TIMEOUT_FLAGS_TMR |
GPU_TIMEOUT_FLAGS_BYPASS_THREAD_STATE |
GPU_TIMEOUT_FLAGS_BYPASS_JOURNAL_LOG);
if (!IS_SILICON(pGpu) && !IS_EMULATION(pGpu))
{

View File

@ -3194,10 +3194,13 @@ NV_STATUS gpuConstructEngineTable_IMPL
// Initialize per-GPU per-engine list of non-stall interrupt event nodes.
for (engineId = 0; engineId < NV2080_ENGINE_TYPE_LAST; engineId++)
{
pGpu->engineNonstallIntr[engineId].pEventNode = NULL;
pGpu->engineNonstallIntr[engineId].pSpinlock = portSyncSpinlockCreate(portMemAllocatorGetGlobalNonPaged());
if (pGpu->engineNonstallIntr[engineId].pSpinlock == NULL)
return NV_ERR_INSUFFICIENT_RESOURCES;
NV_STATUS status = gpuEngineEventNotificationListCreate(pGpu,
&pGpu->engineNonstallIntrEventNotifications[engineId]);
if (status != NV_OK)
{
gpuDestroyEngineTable(pGpu);
return status;
}
}
return NV_OK;
@ -3251,7 +3254,9 @@ NV_STATUS gpuUpdateEngineTable_IMPL
}
void gpuDestroyEngineTable_IMPL(OBJGPU *pGpu)
{
NvU32 engineId = 0;
for (NvU32 engineId = 0; engineId < NV2080_ENGINE_TYPE_LAST; engineId++)
gpuEngineEventNotificationListDestroy(pGpu,
pGpu->engineNonstallIntrEventNotifications[engineId]);
if (pGpu->engineDB.pType)
{
@ -3260,16 +3265,6 @@ void gpuDestroyEngineTable_IMPL(OBJGPU *pGpu)
pGpu->engineDB.pType = NULL;
pGpu->engineDB.bValid = NV_FALSE;
}
for (engineId = 0; engineId < NV2080_ENGINE_TYPE_LAST; engineId++)
{
NV_ASSERT(pGpu->engineNonstallIntr[engineId].pEventNode == NULL);
if (pGpu->engineNonstallIntr[engineId].pSpinlock != NULL)
{
portSyncSpinlockDestroy(pGpu->engineNonstallIntr[engineId].pSpinlock);
}
}
}
NvBool gpuCheckEngineTable_IMPL

View File

@ -363,8 +363,11 @@ _checkTimeout
if (current >= pTimeout->timeout)
{
NV_PRINTF(LEVEL_ERROR, "ptmr elapsed %llx >= %llx\n",
current, pTimeout->timeout);
if (!(pTimeout->flags & GPU_TIMEOUT_FLAGS_BYPASS_JOURNAL_LOG))
{
NV_PRINTF(LEVEL_ERROR, "ptmr elapsed %llx >= %llx\n",
current, pTimeout->timeout);
}
status = NV_ERR_TIMEOUT;
}
}
@ -382,7 +385,10 @@ _checkTimeout
if (pTimeout->timeout == 0)
{
NV_PRINTF(LEVEL_INFO, "ptmr timeout == 0\n");
if (!(pTimeout->flags & GPU_TIMEOUT_FLAGS_BYPASS_JOURNAL_LOG))
{
NV_PRINTF(LEVEL_INFO, "ptmr timeout == 0\n");
}
status = NV_ERR_TIMEOUT;
}
}

View File

@ -2103,7 +2103,8 @@ deviceCtrlCmdKGrGetCaps_IMPL
)
{
OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice);
NvBool bCapsPopulated = NV_FALSE;
NvU8 *pGrCaps = NvP64_VALUE(pParams->capsTbl);
NvBool bCapsPopulated = NV_FALSE;
LOCK_ASSERT_AND_RETURN(rmApiLockIsOwner());
@ -2112,6 +2113,9 @@ deviceCtrlCmdKGrGetCaps_IMPL
return NV_ERR_NOT_SUPPORTED;
}
NV_CHECK_OR_RETURN(LEVEL_ERROR, pGrCaps != NULL, NV_ERR_INVALID_ARGUMENT);
NV_CHECK_OR_RETURN(LEVEL_ERROR, pParams->capsTblSize == NV0080_CTRL_GR_CAPS_TBL_SIZE, NV_ERR_INVALID_ARGUMENT);
SLI_LOOP_START(SLI_LOOP_FLAGS_BC_ONLY)
{
KernelGraphicsManager *pKernelGraphicsManager = GPU_GET_KERNEL_GRAPHICS_MANAGER(pGpu);
@ -2128,7 +2132,7 @@ deviceCtrlCmdKGrGetCaps_IMPL
if (!bCapsPopulated)
{
NV_CHECK_OK_OR_ELSE(status, LEVEL_ERROR,
kgraphicsGetCaps(pGpu, pKernelGraphics, pParams->capsTbl),
kgraphicsGetCaps(pGpu, pKernelGraphics, pGrCaps),
SLI_LOOP_RETURN(status););
bCapsPopulated = NV_TRUE;

View File

@ -835,9 +835,18 @@ _kgspRpcRecvPoll
NV_ASSERT(portSafeMulU32(GSP_SCALE_TIMEOUT_EMU_SIM, 1500000, &timeoutResult));
timeoutUs = timeoutResult;
}
else
{
// We should only ever timeout this when GSP is in really bad state, so if it just
// happens to timeout on default timeout it should be OK for us to give it a little
// more time - make this timeout 1.5 of the default to allow some leeway.
NvU32 defaultus = pGpu->timeoutData.defaultus;
timeoutUs = defaultus + defaultus / 2;
}
NV_ASSERT(rmDeviceGpuLockIsOwner(pGpu->gpuInstance));
gpuSetTimeout(pGpu, timeoutUs, &timeout, 0);
gpuSetTimeout(pGpu, timeoutUs, &timeout, GPU_TIMEOUT_FLAGS_BYPASS_THREAD_STATE);
for (;;)
{
@ -1461,6 +1470,13 @@ kgspUnloadRm_IMPL
// Dump GSP-RM logs and reset before invoking FWSEC-SB
kgspDumpGspLogs(pGpu, pKernelGsp, NV_FALSE);
//
// Avoid cascading timeouts when attempting to invoke the below ucodes if
// we are unloading due to a GSP-RM timeout.
//
threadStateResetTimeout(pGpu);
kflcnReset_HAL(pGpu, staticCast(pKernelGsp, KernelFalcon));
// Invoke FWSEC-SB to put back PreOsApps during driver unload

View File

@ -430,7 +430,7 @@ NV_STATUS GspMsgQueueSendCommand(MESSAGE_QUEUE_INFO *pMQI, OBJGPU *pGpu)
if ((uElementSize & 7) != 0)
portMemSet(pSrc + uElementSize, 0, 8 - (uElementSize & 7));
pCQE->seqNum = pMQI->txSeqNum++;
pCQE->seqNum = pMQI->txSeqNum;
pCQE->checkSum = 0;
pCQE->checkSum = _checkSum32(pSrc, uElementSize);
@ -489,6 +489,9 @@ NV_STATUS GspMsgQueueSendCommand(MESSAGE_QUEUE_INFO *pMQI, OBJGPU *pGpu)
goto done;
}
// Advance seq num only if we actually used it.
pMQI->txSeqNum++;
nvStatus = NV_OK;
done:

View File

@ -22,9 +22,185 @@
*/
#include "gpu/gpu.h"
#include "nvoc/prelude.h"
#include "nvstatuscodes.h"
#include "rmapi/rs_utils.h"
#include "gpu/hwpm/profiler_v2.h"
#include "ctrl/ctrlb0cc/ctrlb0ccinternal.h"
#include "mem_mgr/mem.h"
NV_STATUS
profilerBaseCtrlCmdFreePmaStream_IMPL
(
ProfilerBase *pProfiler,
NVB0CC_CTRL_FREE_PMA_STREAM_PARAMS *pParams
)
{
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(GPU_RES_GET_GPU(pProfiler));
NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS internalParams;
portMemSet(&internalParams, 0, sizeof(NVB0CC_CTRL_INTERNAL_FREE_PMA_STREAM_PARAMS));
internalParams.pmaChannelIdx = pParams->pmaChannelIdx;
{
RsResourceRef *pCountRef = NULL;
RsResourceRef *pBufferRef = NULL;
if (pProfiler->maxPmaChannels <= pParams->pmaChannelIdx)
{
goto err;
}
pCountRef = pProfiler->ppBytesAvailable[pParams->pmaChannelIdx];
pProfiler->ppBytesAvailable[pParams->pmaChannelIdx] = NULL;
pBufferRef = pProfiler->ppStreamBuffers[pParams->pmaChannelIdx];
pProfiler->ppStreamBuffers[pParams->pmaChannelIdx] = NULL;
if(pProfiler->pBoundCntBuf == pCountRef && pProfiler->pBoundPmaBuf == pBufferRef)
{
Memory *pCntMem = dynamicCast(pCountRef->pResource, Memory);
Memory *pBufMem = dynamicCast(pBufferRef->pResource, Memory);
pProfiler->pBoundCntBuf = NULL;
pProfiler->pBoundPmaBuf = NULL;
pCntMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
pBufMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
}
if (pCountRef != NULL)
{
refRemoveDependant(pCountRef, RES_GET_REF(pProfiler));
}
if (pBufferRef != NULL)
{
refRemoveDependant(pBufferRef, RES_GET_REF(pProfiler));
}
}
err:
return pRmApi->Control(pRmApi,
RES_GET_CLIENT_HANDLE(pProfiler),
RES_GET_HANDLE(pProfiler),
NVB0CC_CTRL_CMD_INTERNAL_FREE_PMA_STREAM,
&internalParams, sizeof(internalParams));
}
NV_STATUS
profilerBaseCtrlCmdBindPmResources_IMPL
(
ProfilerBase *pProfiler
)
{
OBJGPU *pGpu = GPU_RES_GET_GPU(pProfiler);
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NvHandle hClient = RES_GET_CLIENT_HANDLE(pProfiler);
NvHandle hObject = RES_GET_HANDLE(pProfiler);
NV_STATUS status = NV_OK;
RsResourceRef *pCntRef = NULL;
RsResourceRef *pBufRef = NULL;
Memory *pCntMem = NULL;
Memory *pBufMem = NULL;
NV_CHECK_OR_GOTO(LEVEL_INFO,
!pProfiler->bLegacyHwpm && pProfiler->maxPmaChannels != 0, physical_control);
if (pProfiler->maxPmaChannels <= pProfiler->pmaVchIdx)
{
return NV_ERR_INVALID_ARGUMENT;
}
pCntRef = pProfiler->ppBytesAvailable[pProfiler->pmaVchIdx];
pBufRef = pProfiler->ppStreamBuffers[pProfiler->pmaVchIdx];
NV_CHECK_OR_GOTO(LEVEL_INFO,
pCntRef != NULL && pBufRef != NULL, physical_control);
pCntMem = dynamicCast(pCntRef->pResource, Memory);
pBufMem = dynamicCast(pBufRef->pResource, Memory);
NV_ASSERT_OR_RETURN(pCntMem != NULL && pBufMem != NULL, NV_ERR_INVALID_STATE);
if (!memdescAcquireRmExclusiveUse(pCntMem->pMemDesc) ||
!memdescAcquireRmExclusiveUse(pBufMem->pMemDesc))
{
pCntMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
pBufMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
return NV_ERR_INVALID_ARGUMENT;
}
pProfiler->pBoundCntBuf = pCntRef;
pProfiler->pBoundPmaBuf = pBufRef;
physical_control:
status = pRmApi->Control(pRmApi, hClient, hObject,
NVB0CC_CTRL_CMD_INTERNAL_BIND_PM_RESOURCES,
NULL, 0);
if (status != NV_OK && pCntMem != NULL && pBufMem != NULL)
{
pCntMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
pBufMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
pProfiler->pBoundCntBuf = NULL;
pProfiler->pBoundPmaBuf = NULL;
}
return status;
}
NV_STATUS
profilerBaseCtrlCmdUnbindPmResources_IMPL
(
ProfilerBase *pProfiler
)
{
OBJGPU *pGpu = GPU_RES_GET_GPU(pProfiler);
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NvHandle hClient = RES_GET_CLIENT_HANDLE(pProfiler);
NvHandle hObject = RES_GET_HANDLE(pProfiler);
RsResourceRef *pCntRef = NULL;
RsResourceRef *pBufRef = NULL;
pCntRef = pProfiler->pBoundCntBuf;
pBufRef = pProfiler->pBoundPmaBuf;
if (pCntRef != NULL)
{
Memory *pCntMem = dynamicCast(pCntRef->pResource, Memory);
if (pCntMem != NULL)
{
pCntMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
}
pProfiler->pBoundCntBuf = NULL;
}
if (pBufRef != NULL)
{
Memory *pBufMem = dynamicCast(pBufRef->pResource, Memory);
if (pBufMem != NULL)
{
pBufMem->pMemDesc->bRmExclusiveUse = NV_FALSE;
}
pProfiler->pBoundPmaBuf = NULL;
}
return pRmApi->Control(pRmApi, hClient, hObject,
NVB0CC_CTRL_CMD_INTERNAL_UNBIND_PM_RESOURCES,
NULL, 0);
}
NV_STATUS
profilerBaseCtrlCmdReserveHwpmLegacy_IMPL
(
ProfilerBase *pProfiler,
NVB0CC_CTRL_RESERVE_HWPM_LEGACY_PARAMS *pParams
)
{
OBJGPU *pGpu = GPU_RES_GET_GPU(pProfiler);
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NvHandle hClient = RES_GET_CLIENT_HANDLE(pProfiler);
NvHandle hObject = RES_GET_HANDLE(pProfiler);
pProfiler->bLegacyHwpm = NV_TRUE;
return pRmApi->Control(pRmApi, hClient, hObject,
NVB0CC_CTRL_CMD_INTERNAL_RESERVE_HWPM_LEGACY,
pParams, sizeof(*pParams));
}
NV_STATUS
profilerBaseCtrlCmdAllocPmaStream_IMPL
@ -41,39 +217,57 @@ profilerBaseCtrlCmdAllocPmaStream_IMPL
NvHandle hObject = RES_GET_HANDLE(pProfiler);
NvBool bMemPmaBufferRegistered = NV_FALSE;
NvBool bMemPmaBytesAvailableRegistered = NV_FALSE;
RsResourceRef *pMemoryRef = NULL;
//
// REGISTER MEMDESCs TO GSP
// These are no-op with BareMetal/No GSP
//
status = memdescRegisterToGSP(pGpu, hClient, hParent, pParams->hMemPmaBuffer);
if (status != NV_OK)
{
goto fail;
}
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
memdescRegisterToGSP(pGpu, hClient, hParent, pParams->hMemPmaBuffer),
fail);
bMemPmaBufferRegistered = NV_TRUE;
status = memdescRegisterToGSP(pGpu, hClient, hParent, pParams->hMemPmaBytesAvailable);
if (status != NV_OK)
{
goto fail;
}
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
memdescRegisterToGSP(pGpu, hClient, hParent, pParams->hMemPmaBytesAvailable),
fail);
bMemPmaBytesAvailableRegistered = NV_TRUE;
//
// With BareMetal/No GSP: this control is a direct call to
// profilerBaseCtrlCmdInternalReleaseHwpmLegacy_IMPL
//
status = pRmApi->Control(pRmApi,
hClient,
hObject,
NVB0CC_CTRL_CMD_INTERNAL_ALLOC_PMA_STREAM,
pParams, sizeof(*pParams));
if (status != NV_OK)
{
goto fail;
}
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
pRmApi->Control(pRmApi,
hClient,
hObject,
NVB0CC_CTRL_CMD_INTERNAL_ALLOC_PMA_STREAM,
pParams, sizeof(*pParams)), fail);
if (pProfiler->ppBytesAvailable == NULL)
{
NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS maxPmaParams;
portMemSet(&maxPmaParams, 0, sizeof(NVB0CC_CTRL_INTERNAL_GET_MAX_PMAS_PARAMS));
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
pRmApi->Control(pRmApi, hClient, hObject,
NVB0CC_CTRL_CMD_INTERNAL_GET_MAX_PMAS,
&maxPmaParams, sizeof(maxPmaParams)), fail);
pProfiler->maxPmaChannels = maxPmaParams.maxPmaChannels;
pProfiler->ppBytesAvailable = (RsResourceRef**)portMemAllocNonPaged(maxPmaParams.maxPmaChannels * sizeof(RsResourceRef*));
pProfiler->ppStreamBuffers = (RsResourceRef**)portMemAllocNonPaged(maxPmaParams.maxPmaChannels * sizeof(RsResourceRef*));
}
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
serverutilGetResourceRef(hClient, pParams->hMemPmaBytesAvailable, &pMemoryRef), fail);
pProfiler->ppBytesAvailable[pParams->pmaChannelIdx] = pMemoryRef;
refAddDependant(pMemoryRef, RES_GET_REF(pProfiler));
NV_CHECK_OK_OR_GOTO(status, LEVEL_ERROR,
serverutilGetResourceRef(hClient, pParams->hMemPmaBuffer, &pMemoryRef), fail);
pProfiler->ppStreamBuffers[pParams->pmaChannelIdx] = pMemoryRef;
refAddDependant(pMemoryRef, RES_GET_REF(pProfiler));
// Copy output params to external struct.
pProfiler->pmaVchIdx = pParams->pmaChannelIdx;
pProfiler->bLegacyHwpm = NV_FALSE;
return status;
fail:

View File

@ -4723,8 +4723,11 @@ NV_STATUS heapResize_IMPL
if (resizeBy < 0) // Shrink the allocation
{
NvS64 newSize;
NV_ASSERT_OR_RETURN(pBlockLast->owner == NVOS32_BLOCK_TYPE_FREE, NV_ERR_NO_MEMORY);
NV_ASSERT_OR_RETURN((pBlockLast->end - pBlockLast->begin + resizeBy > 0), NV_ERR_INVALID_LIMIT);
NV_CHECK_OR_RETURN(LEVEL_ERROR, portSafeAddS64(pBlockLast->end - pBlockLast->begin, resizeBy, &newSize) &&
(newSize > 0), NV_ERR_INVALID_LIMIT);
pBlockLast->end += resizeBy;
}
else // Grow the allocation

View File

@ -944,7 +944,7 @@ memdescAlloc
// TO DO: Make this an error once existing allocations are cleaned up.
// After that pHeap selection can be moved to memdescAllocInternal()
//
NV_PRINTF(LEVEL_ERROR,
NV_PRINTF(LEVEL_WARNING,
"WARNING sysmem alloc on GSP firmware\n");
pMemDesc->_addressSpace = ADDR_FBMEM;
pMemDesc->pHeap = GPU_GET_HEAP(pGpu);
@ -2264,6 +2264,28 @@ memdescFillPages
}
}
/*!
* @brief Acquire exclusive use for memdesc for RM.
*
* @param[inout] pMemDesc Memory descriptor
*
* @returns Boolean indicating whether we successfully acquired the memdesc for exclusive use
*/
NvBool
memdescAcquireRmExclusiveUse
(
MEMORY_DESCRIPTOR *pMemDesc
)
{
NV_CHECK_OR_RETURN(LEVEL_ERROR, pMemDesc->_pParentDescriptor == NULL &&
!pMemDesc->bRmExclusiveUse &&
pMemDesc->DupCount == 1,
NV_FALSE);
pMemDesc->bRmExclusiveUse = NV_TRUE;
return NV_TRUE;
}
//
// SubMemory per subdevice chart: (MD - Memory Descriptor, SD - subdevice)
//
@ -2385,6 +2407,7 @@ memdescCreateSubMem
pMemDescNew->bUsingSuballocator = pMemDesc->bUsingSuballocator;
pMemDescNew->_pParentDescriptor = pMemDesc;
pMemDesc->childDescriptorCnt++;
pMemDescNew->bRmExclusiveUse = pMemDesc->bRmExclusiveUse;
pMemDescNew->subMemOffset = Offset;

View File

@ -38,6 +38,7 @@
#include "nvVer.h"
#include "gpu/bif/kernel_bif.h"
#include "gpu/bus/kern_bus.h"
#include "gpu/disp/kern_disp.h"
#include "gpu/mmu/kern_gmmu.h"
#include "kernel/gpu/intr/intr.h"
#include "kernel/gpu/mc/kernel_mc.h"
@ -278,6 +279,18 @@ getGpuInfos(Subdevice *pSubdevice, NV2080_CTRL_GPU_GET_INFO_V2_PARAMS *pParams,
}
break;
}
case NV2080_CTRL_GPU_INFO_INDEX_DISPLAY_ENABLED:
{
if (GPU_GET_KERNEL_DISPLAY(pGpu) != NULL)
{
data = NV2080_CTRL_GPU_INFO_DISPLAY_ENABLED_YES;
}
else
{
data = NV2080_CTRL_GPU_INFO_DISPLAY_ENABLED_NO;
}
break;
}
case NV2080_CTRL_GPU_INFO_INDEX_MOBILE_CONFIG_ENABLED:
{
if (IsMobile(pGpu))

View File

@ -722,24 +722,32 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
{
case NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_GPU_GET_NVENC_SW_SESSION_INFO_PARAMS*)pParams)->sessionInfoTbl = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_GPU_GET_ENGINES:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINES_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_GPU_GET_ENGINES_PARAMS*)pParams)->engineList = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_BUS_GET_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BUS_GET_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_BUS_GET_INFO_PARAMS*)pParams)->busInfoList = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_FB_GET_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_FB_GET_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_FB_GET_INFO_PARAMS*)pParams)->fbInfoList = paramCopies[0].pUserParams;
break;
@ -748,6 +756,9 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
case NV2080_CTRL_CMD_FB_GET_AMAP_CONF:
{
NV_STATUS status2;
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS);
NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS *pParamsUser =
(NV2080_CTRL_CMD_FB_GET_AMAP_CONF_PARAMS *) pParams;
@ -763,12 +774,16 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
#endif
case NV2080_CTRL_CMD_CE_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_CE_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_CE_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_FIFO_GET_CHANNELLIST:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS);
NV_STATUS handleListParamStatus = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_FIFO_GET_CHANNELLIST_PARAMS*)pParams)->pChannelHandleList = paramCopies[0].pUserParams;
@ -782,94 +797,126 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
}
case NV83DE_CTRL_CMD_DEBUG_READ_MEMORY:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS*)pRmCtrlParams->pParams)->buffer = paramCopies[0].pUserParams;
break;
}
case NV83DE_CTRL_CMD_DEBUG_WRITE_MEMORY:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV83DE_CTRL_DEBUG_WRITE_MEMORY_PARAMS*)pRmCtrlParams->pParams)->buffer = paramCopies[0].pUserParams;
break;
}
case NV83DE_CTRL_CMD_DEBUG_READ_BATCH_MEMORY:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pRmCtrlParams->pParams)->pData = paramCopies[0].pUserParams;
break;
}
case NV83DE_CTRL_CMD_DEBUG_WRITE_BATCH_MEMORY:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV83DE_CTRL_DEBUG_ACCESS_MEMORY_PARAMS*)pRmCtrlParams->pParams)->pData = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_HOST_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_HOST_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_HOST_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_MSENC_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_MSENC_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_MSENC_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_BIOS_GET_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_BIOS_GET_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_BIOS_GET_INFO_PARAMS*)pParams)->biosInfoList = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_GR_GET_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_FIFO_START_SELECTED_CHANNELS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_FIFO_START_SELECTED_CHANNELS_PARAMS*)pParams)->fifoStartChannelList = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_FIFO_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FIFO_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_FIFO_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV402C_CTRL_CMD_I2C_INDEXED:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_INDEXED_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV402C_CTRL_I2C_INDEXED_PARAMS*)pParams)->pMessage = paramCopies[0].pUserParams;
break;
}
case NV402C_CTRL_CMD_I2C_TRANSACTION:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV402C_CTRL_I2C_TRANSACTION_PARAMS);
return i2cTransactionCopyOut(paramCopies, pRmCtrlParams);
}
case NV2080_CTRL_CMD_GPU_EXEC_REG_OPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_GPU_EXEC_REG_OPS_PARAMS*)pParams)->regOps = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_NVD_GET_DUMP:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_NVD_GET_DUMP_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer = paramCopies[0].pUserParams;
break;
}
case NV0000_CTRL_CMD_NVD_GET_DUMP:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_NVD_GET_DUMP_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0000_CTRL_NVD_GET_DUMP_PARAMS*)pParams)->pBuffer = paramCopies[0].pUserParams;
break;
}
case NV0041_CTRL_CMD_GET_SURFACE_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0041_CTRL_GET_SURFACE_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0041_CTRL_GET_SURFACE_INFO_PARAMS*)pParams)->surfaceInfoList = paramCopies[0].pUserParams;
break;
@ -878,6 +925,8 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
// Not defined on all platforms
case NV0000_CTRL_CMD_OS_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_OS_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0000_CTRL_OS_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
@ -885,72 +934,96 @@ NV_STATUS embeddedParamCopyOut(RMAPI_PARAM_COPY *paramCopies, RmCtrlParams *pRmC
#endif
case NV0000_CTRL_CMD_SYSTEM_GET_P2P_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0000_CTRL_SYSTEM_GET_P2P_CAPS_PARAMS*)pParams)->busPeerIds = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_FB_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_FB_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_FB_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_GPU_GET_CLASSLIST:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_GPU_GET_CLASSLIST_PARAMS*)pParams)->classList = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_GPU_GET_ENGINE_CLASSLIST:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_GPU_GET_ENGINE_CLASSLIST_PARAMS*)pParams)->classList = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_GR_GET_CAPS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_GR_GET_CAPS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_GR_GET_CAPS_PARAMS*)pParams)->capsTbl = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_I2C_ACCESS:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_I2C_ACCESS_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_I2C_ACCESS_PARAMS*)pParams)->data = paramCopies[0].pUserParams;
break;
}
case NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0073_CTRL_CMD_DP_SET_MSA_PROPERTIES_PARAMS*)pParams)->pFeatureDebugValues = NvP64_VALUE(paramCopies[0].pUserParams);
break;
}
case NV2080_CTRL_CMD_GR_GET_INFO:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_GR_GET_INFO_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_GR_GET_INFO_PARAMS*)pParams)->grInfoList = paramCopies[0].pUserParams;
break;
}
case NVB06F_CTRL_CMD_MIGRATE_ENGINE_CTX_DATA:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NVB06F_CTRL_MIGRATE_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff = paramCopies[0].pUserParams;
break;
}
case NVB06F_CTRL_CMD_GET_ENGINE_CTX_DATA:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NVB06F_CTRL_GET_ENGINE_CTX_DATA_PARAMS*)pParams)->pEngineCtxBuff = paramCopies[0].pUserParams;
break;
}
case NV2080_CTRL_CMD_RC_READ_VIRTUAL_MEM:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV2080_CTRL_RC_READ_VIRTUAL_MEM_PARAMS*)pRmCtrlParams->pParams)->bufferPtr = paramCopies[0].pUserParams;
break;
}
case NV0080_CTRL_CMD_DMA_UPDATE_PDE_2:
{
CHECK_PARAMS_OR_RETURN(pRmCtrlParams, NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS);
status = rmapiParamsRelease(&paramCopies[0]);
((NV0080_CTRL_DMA_UPDATE_PDE_2_PARAMS*)pParams)->pPdeBuffer = paramCopies[0].pUserParams;

View File

@ -40,6 +40,41 @@
#include "kernel/gpu/mig_mgr/kernel_mig_manager.h"
typedef struct
{
EVENTNOTIFICATION *pEventNotify;
Memory *pMemory;
ListNode eventNotificationListNode;
ListNode pendingEventNotifyListNode;
} ENGINE_EVENT_NOTIFICATION;
//
// These lists are intrusive to avoid memory allocation during insertion while
// in a non-preemptible context (holding a spinlock/in an ISR).
//
MAKE_INTRUSIVE_LIST(EngineEventNotificationList, ENGINE_EVENT_NOTIFICATION,
eventNotificationListNode);
MAKE_INTRUSIVE_LIST(PendingEventNotifyList, ENGINE_EVENT_NOTIFICATION,
pendingEventNotifyListNode);
// Linked list of per engine non-stall event notifications
struct GpuEngineEventNotificationList
{
PORT_SPINLOCK *pSpinlock;
// List insertion and removal happens under pSpinlock
EngineEventNotificationList eventNotificationList;
// Filled while pSpinlock is held, drained outside of the lock in ISR
PendingEventNotifyList pendingEventNotifyList;
//
// Set to non-zero under pSpinlock, set to zero outside of the lock in ISR
// Insertions/removals on eventNotificationList are blocked while non-zero
//
volatile NvU32 pendingEventNotifyCount;
};
static NV_STATUS _insertEventNotification
(
PEVENTNOTIFICATION *ppEventNotification,
@ -67,159 +102,283 @@ static NV_STATUS _removeEventNotification
//
//---------------------------------------------------------------------------
static NV_STATUS engineNonStallEventOp
NV_STATUS gpuEngineEventNotificationListCreate
(
OBJGPU *pGpu,
NvU32 engineId,
PEVENTNOTIFICATION pEventNotify,
Memory *pMemory,
NvBool bInsert
GpuEngineEventNotificationList **ppEventNotificationList
)
{
ENGINE_EVENT_NODE *pTempNode;
NvBool bFound = NV_FALSE;
NV_STATUS status = NV_OK;
if (bInsert)
PORT_MEM_ALLOCATOR *pAllocator = portMemAllocatorGetGlobalNonPaged();
GpuEngineEventNotificationList *pEventNotificationList =
portMemAllocNonPaged(sizeof(*pEventNotificationList));
NV_ASSERT_OR_RETURN(pEventNotificationList != NULL, NV_ERR_NO_MEMORY);
portMemSet(pEventNotificationList, 0, sizeof(*pEventNotificationList));
pEventNotificationList->pSpinlock = portSyncSpinlockCreate(pAllocator);
NV_ASSERT_OR_ELSE(pEventNotificationList->pSpinlock != NULL,
{
pTempNode = portMemAllocNonPaged(sizeof(ENGINE_EVENT_NODE));
status = NV_ERR_INSUFFICIENT_RESOURCES;
goto exit;
});
if (pTempNode == NULL)
return NV_ERR_NO_MEMORY;
listInitIntrusive(&pEventNotificationList->eventNotificationList);
listInitIntrusive(&pEventNotificationList->pendingEventNotifyList);
// Acquire engine list spinlock before adding to engine event list
portSyncSpinlockAcquire(pGpu->engineNonstallIntr[engineId].pSpinlock);
pTempNode->pNext = pGpu->engineNonstallIntr[engineId].pEventNode;
pTempNode->pEventNotify = pEventNotify;
pTempNode->pMemory = pMemory;
portAtomicSetU32(&pEventNotificationList->pendingEventNotifyCount, 0);
pGpu->engineNonstallIntr[engineId].pEventNode = pTempNode;
*ppEventNotificationList = pEventNotificationList;
// Release engine list spinlock
portSyncSpinlockRelease(pGpu->engineNonstallIntr[engineId].pSpinlock);
}
else
exit:
if (status != NV_OK)
gpuEngineEventNotificationListDestroy(pGpu, pEventNotificationList);
return status;
}
void gpuEngineEventNotificationListDestroy
(
OBJGPU *pGpu,
GpuEngineEventNotificationList *pEventNotificationList
)
{
if (pEventNotificationList == NULL)
return;
NV_ASSERT(pEventNotificationList->pendingEventNotifyCount == 0);
NV_ASSERT(listCount(&pEventNotificationList->pendingEventNotifyList) == 0);
listDestroy(&pEventNotificationList->pendingEventNotifyList);
NV_ASSERT(listCount(&pEventNotificationList->eventNotificationList) == 0);
listDestroy(&pEventNotificationList->eventNotificationList);
if (pEventNotificationList->pSpinlock != NULL)
portSyncSpinlockDestroy(pEventNotificationList->pSpinlock);
portMemFree(pEventNotificationList);
}
static void _gpuEngineEventNotificationListLockPreemptible
(
GpuEngineEventNotificationList *pEventNotificationList
)
{
do
{
ENGINE_EVENT_NODE *pEngNode, *pPrevNode = NULL;
portSyncSpinlockAcquire(pEventNotificationList->pSpinlock);
// Acquire engine list spinlock before traversing engine event list
portSyncSpinlockAcquire(pGpu->engineNonstallIntr[engineId].pSpinlock);
//
// Only return with the lock held once there are no pending
// notifications to process. No more pending notifications can be queued
// while the spinlock is held, and we drop the lock to re-enable
// preemption, to guarantee that _gpuEngineEventNotificationListNotify()
// can make forward progress to drain the pending notifications list.
//
if (pEventNotificationList->pendingEventNotifyCount == 0)
return;
pEngNode = pGpu->engineNonstallIntr[engineId].pEventNode;
while (pEngNode)
{
if (pEngNode->pEventNotify == pEventNotify)
{
if (pPrevNode == NULL)
pGpu->engineNonstallIntr[engineId].pEventNode = pEngNode->pNext;
else
pPrevNode->pNext = pEngNode->pNext;
portSyncSpinlockRelease(pEventNotificationList->pSpinlock);
pTempNode = pEngNode;
bFound = NV_TRUE;
break;
}
else
{
pPrevNode = pEngNode;
}
pEngNode = pEngNode->pNext;
}
//
// Spin waiting for the pending notifications to drain.
// This can only be done in a preemptible context (i.e., add
// or remove notification in a thread context).
//
while (pEventNotificationList->pendingEventNotifyCount > 0)
osSpinLoop();
} while (NV_TRUE);
}
// Release engine list spinlock
portSyncSpinlockRelease(pGpu->engineNonstallIntr[engineId].pSpinlock);
static inline void _gpuEngineEventNotificationListUnlockPreemptible
(
GpuEngineEventNotificationList *pEventNotificationList
)
{
portSyncSpinlockRelease(pEventNotificationList->pSpinlock);
}
if (bFound)
{
portMemFree(pTempNode);
}
else
{
NV_ASSERT_FAILED("failed to find non-stall event!");
return NV_ERR_INVALID_STATE;
}
static NV_STATUS _gpuEngineEventNotificationInsert
(
GpuEngineEventNotificationList *pEventNotificationList,
EVENTNOTIFICATION *pEventNotify,
Memory *pMemory
)
{
NV_CHECK_OR_RETURN(LEVEL_ERROR, pEventNotify != NULL,
NV_ERR_INVALID_ARGUMENT);
// Allocate the new node outside of the spinlock
ENGINE_EVENT_NOTIFICATION *pEngineEventNotification =
portMemAllocNonPaged(sizeof(*pEngineEventNotification));
NV_CHECK_OR_RETURN(LEVEL_ERROR, pEngineEventNotification != NULL,
NV_ERR_NO_MEMORY);
portMemSet(pEngineEventNotification, 0, sizeof(*pEngineEventNotification));
pEngineEventNotification->pEventNotify = pEventNotify;
pEngineEventNotification->pMemory = pMemory;
// Take the lock to add the node to the list
_gpuEngineEventNotificationListLockPreemptible(pEventNotificationList);
{
listPrependExisting(&pEventNotificationList->eventNotificationList,
pEngineEventNotification);
}
_gpuEngineEventNotificationListUnlockPreemptible(pEventNotificationList);
return NV_OK;
}
static NV_STATUS _engineNonStallIntrNotifyImpl(OBJGPU *pGpu, NvU32 engineId, NvHandle hEvent)
static void _gpuEngineEventNotificationRemove
(
GpuEngineEventNotificationList *pEventNotificationList,
EVENTNOTIFICATION *pEventNotify
)
{
ENGINE_EVENT_NODE *pTempHead;
Memory *pSemMemory;
NvU32 semValue;
NvU32 *pTempKernelMapping = NULL;
NV_STATUS rmStatus = NV_OK;
ENGINE_EVENT_NOTIFICATION *pEngineEventNotification = NULL;
_gpuEngineEventNotificationListLockPreemptible(pEventNotificationList);
{
EngineEventNotificationListIter it =
listIterAll(&pEventNotificationList->eventNotificationList);
while (listIterNext(&it))
{
if (it.pValue->pEventNotify == pEventNotify)
{
pEngineEventNotification = it.pValue;
listRemove(&pEventNotificationList->eventNotificationList,
pEngineEventNotification);
break;
}
}
}
_gpuEngineEventNotificationListUnlockPreemptible(pEventNotificationList);
NV_ASSERT(pEngineEventNotification != NULL);
portMemFree(pEngineEventNotification);
}
static NV_STATUS _gpuEngineEventNotificationListNotify
(
OBJGPU *pGpu,
GpuEngineEventNotificationList *pEventNotificationList,
NvHandle hEvent
)
{
NV_STATUS status = NV_OK;
PendingEventNotifyList *pPending =
&pEventNotificationList->pendingEventNotifyList;
//
// Acquire engine list spinlock before traversing the list. Note that this
// is called without holding locks from ISR for Linux. This spinlock is used
// to protect per GPU per engine event node list.
// to protect the per GPU per engine event node list.
//
portSyncSpinlockAcquire(pGpu->engineNonstallIntr[engineId].pSpinlock);
pTempHead = pGpu->engineNonstallIntr[engineId].pEventNode;
while (pTempHead)
portSyncSpinlockAcquire(pEventNotificationList->pSpinlock);
{
if (!pTempHead->pEventNotify)
// We don't expect this to be called multiple times in parallel
NV_ASSERT_OR_ELSE(pEventNotificationList->pendingEventNotifyCount == 0,
{
rmStatus = NV_ERR_INVALID_STATE;
break;
}
portSyncSpinlockRelease(pEventNotificationList->pSpinlock);
return NV_ERR_INVALID_STATE;
});
if (hEvent && pTempHead->pEventNotify->hEvent != hEvent)
goto nextEvent;
pSemMemory = pTempHead->pMemory;
if (pSemMemory && pSemMemory->vgpuNsIntr.isSemaMemValidationEnabled &&
pSemMemory->pMemDesc && pSemMemory->pMemDesc->Allocated)
EngineEventNotificationListIter it =
listIterAll(&pEventNotificationList->eventNotificationList);
while (listIterNext(&it))
{
pTempKernelMapping = (NvU32 *)NvP64_VALUE(memdescGetKernelMapping(pSemMemory->pMemDesc));
if (pTempKernelMapping == NULL)
{
NV_PRINTF(LEVEL_WARNING, "Per-vGPU semaphore location mapping is NULL. Skipping the current node.\n");
pTempHead = pTempHead->pNext;
ENGINE_EVENT_NOTIFICATION *pEngineEventNotification = it.pValue;
if (hEvent &&
pEngineEventNotification->pEventNotify->hEvent != hEvent)
continue;
}
semValue = MEM_RD32(pTempKernelMapping + (pSemMemory->vgpuNsIntr.nsSemOffset / sizeof(NvU32)));
if (pSemMemory->vgpuNsIntr.nsSemValue == semValue)
Memory *pSemMemory = pEngineEventNotification->pMemory;
if (pSemMemory &&
pSemMemory->vgpuNsIntr.isSemaMemValidationEnabled &&
pSemMemory->pMemDesc && pSemMemory->pMemDesc->Allocated)
{
pTempHead = pTempHead->pNext;
continue;
NvU32 *pTempKernelMapping =
(NvU32 *)NvP64_VALUE(
memdescGetKernelMapping(pSemMemory->pMemDesc));
if (pTempKernelMapping == NULL)
{
NV_PRINTF(LEVEL_WARNING,
"Per-vGPU semaphore location mapping is NULL."
" Skipping the current node.\n");
continue;
}
NvU32 semValue = MEM_RD32(pTempKernelMapping +
(pSemMemory->vgpuNsIntr.nsSemOffset /
sizeof(NvU32)));
if (pSemMemory->vgpuNsIntr.nsSemValue == semValue)
continue;
pSemMemory->vgpuNsIntr.nsSemValue = semValue;
}
pSemMemory->vgpuNsIntr.nsSemValue = semValue;
//
// Queue up this event notification to be completed outside of the
// critical section, as the osNotifyEvent implementation may need
// to be preemptible.
//
listAppendExisting(pPending, pEngineEventNotification);
}
if (osNotifyEvent(pGpu, pTempHead->pEventNotify, 0, 0, NV_OK) != NV_OK)
{
NV_PRINTF(LEVEL_ERROR, "failed to notify event for engine 0x%x\n",
engineId);
NV_ASSERT(0);
rmStatus = NV_ERR_INVALID_STATE;
break;
}
portAtomicSetU32(&pEventNotificationList->pendingEventNotifyCount,
listCount(pPending));
}
portSyncSpinlockRelease(pEventNotificationList->pSpinlock);
nextEvent:
pTempHead = pTempHead->pNext;
//
// Iterate through the pending notifications and call the OS to send them.
// Note that osNotifyEvent may need to be preemptible, so this is done
// outside of the spinlock-protected critical section.
//
PendingEventNotifyListIter it = listIterAll(pPending);
while (listIterNext(&it))
{
NV_ASSERT_OK_OR_CAPTURE_FIRST_ERROR(status,
osNotifyEvent(pGpu, it.pValue->pEventNotify, 0, 0, NV_OK));
}
portSyncSpinlockRelease(pGpu->engineNonstallIntr[engineId].pSpinlock);
return rmStatus;
// Remove all entries from the pending event notify list
ENGINE_EVENT_NOTIFICATION *pIter, *pNext;
for (pIter = listHead(pPending); pIter != NULL; pIter = pNext)
{
pNext = listNext(pPending, pIter);
listRemove(pPending, pIter);
}
NV_ASSERT(listCount(pPending) == 0);
// Mark the event notifications as drained so preemptible code can continue
portAtomicSetU32(&pEventNotificationList->pendingEventNotifyCount, 0);
return status;
}
NV_STATUS
engineNonStallIntrNotify(OBJGPU *pGpu, NvU32 engineId)
{
return _engineNonStallIntrNotifyImpl(pGpu, engineId, 0);
NV_ASSERT_OR_RETURN(engineId < NV_ARRAY_ELEMENTS(pGpu->engineNonstallIntrEventNotifications),
NV_ERR_INVALID_ARGUMENT);
return _gpuEngineEventNotificationListNotify(pGpu,
pGpu->engineNonstallIntrEventNotifications[engineId], 0);
}
NV_STATUS
engineNonStallIntrNotifyEvent(OBJGPU *pGpu, NvU32 engineId, NvHandle hEvent)
{
return _engineNonStallIntrNotifyImpl(pGpu, engineId, hEvent);
NV_ASSERT_OR_RETURN(engineId < NV_ARRAY_ELEMENTS(pGpu->engineNonstallIntrEventNotifications),
NV_ERR_INVALID_ARGUMENT);
return _gpuEngineEventNotificationListNotify(pGpu,
pGpu->engineNonstallIntrEventNotifications[engineId], hEvent);
}
static NV_STATUS
@ -428,8 +587,9 @@ NV_STATUS registerEventNotification
free_entry);
}
rmStatus = engineNonStallEventOp(pGpu, engineId,
*ppEventNotification, pSemMemory, NV_TRUE);
rmStatus = _gpuEngineEventNotificationInsert(
pGpu->engineNonstallIntrEventNotifications[engineId],
*ppEventNotification, pSemMemory);
if (rmStatus != NV_OK)
goto free_entry;
@ -630,8 +790,9 @@ NV_STATUS unregisterEventNotificationWithData
engineId = globalEngineId;
}
rmStatus = engineNonStallEventOp(pGpu, engineId,
pTargetEvent, NULL, NV_FALSE);
_gpuEngineEventNotificationRemove(
pGpu->engineNonstallIntrEventNotifications[engineId],
pTargetEvent);
}
free_entry:

View File

@ -1,4 +1,4 @@
NVIDIA_VERSION = 515.86.01
NVIDIA_VERSION = 515.105.01
# This file.
VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))