615.78.08

This commit is contained in:
Maneet Singh
2026-10-07 09:29:01 -07:00
parent 61dcc93722
commit ca2d03e6fa
83 changed files with 197790 additions and 195633 deletions
+4 -3
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 615.71.09.
version 615.78.08.
## How to Build
@@ -17,7 +17,7 @@ as root:
Note that the kernel modules built here must be used with GSP
firmware and user-space NVIDIA GPU driver components from a corresponding
615.71.09 driver release. This can be achieved by installing
615.78.08 driver release. This can be achieved by installing
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
option. E.g.,
@@ -186,7 +186,7 @@ table below).
For details on feature support and limitations, see the NVIDIA GPU driver
end user README here:
https://us.download.nvidia.com/XFree86/Linux-x86_64/615.71.09/README/kernel_open.html
https://us.download.nvidia.com/XFree86/Linux-x86_64/615.78.08/README/kernel_open.html
For vGPU support, please refer to the README.vgpu packaged in the vGPU Host
Package for more details.
@@ -1030,3 +1030,4 @@ Subsystem Device ID.
| NVIDIA B300 SXM6 AC | 3182 10DE 20E6 |
| NVIDIA GB300 | 31C2 10DE 21F1 |
| NVIDIA GB300 | 31C3 10DE 22F8 |
| NVIDIA GB300-252 | 31C3 10DE 23AB |
+1 -1
View File
@@ -106,7 +106,7 @@ ccflags-y += -I$(src)/common/inc
ccflags-y += -I$(src)
ccflags-y += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-format-extra-args
ccflags-y += -D__KERNEL__ -DMODULE -DNVRM
ccflags-y += -DNV_VERSION_STRING=\"615.71.09\"
ccflags-y += -DNV_VERSION_STRING=\"615.78.08\"
# Include and link Tegra out-of-tree modules.
ifneq ($(wildcard /usr/src/nvidia/nvidia-public),)
+131 -1
View File
@@ -5367,7 +5367,7 @@ compile_test() {
CODE="
#include <asm/page.h>
int conftest_pfn_is_map_memory(void) {
return pfn_is_map_memory();
return pfn_is_map_memory(0);
}"
compile_check_conftest "$CODE" "NV_PFN_IS_MAP_MEMORY_PRESENT" "" "functions"
;;
@@ -5387,6 +5387,33 @@ compile_test() {
compile_check_conftest "$CODE" "NV_DMEM_CGROUP_PRESENT" "" "types"
;;
dmem_cgroup_register_region_has_init_arg)
#
# Determine if dmem_cgroup_register_region() takes a
# 'const struct dmem_cgroup_init *' argument.
#
# Commit e11640b9cea4 ("cgroup/dmem: Introduce struct
# dmem_cgroup_init for region initialization") changed the first
# argument from 'u64 size' to 'const struct dmem_cgroup_init *'
# in Linux 7.3.
#
CODE="
#include <linux/cgroup_dmem.h>
typeof(dmem_cgroup_register_region)
conftest_dmem_cgroup_register_region_has_init_arg;
struct dmem_cgroup_region *
conftest_dmem_cgroup_register_region_has_init_arg(
const struct dmem_cgroup_init *init,
const char *name_fmt, ...)
{
return NULL;
}"
compile_check_conftest "$CODE" "NV_DMEM_CGROUP_REGISTER_REGION_HAS_INIT_ARG" "" "types"
;;
misc_cgrp_id)
#
# Check to see if the misc cgroup type is available
@@ -5462,6 +5489,7 @@ compile_test() {
# calls for common alloc/free page calls") in 6.12
#
CODE="
#include <linux/dma-mapping.h>
#if defined(NV_LINUX_IOMMU_DMA_H_PRESENT)
#include <linux/iommu-dma.h>
#endif
@@ -5529,6 +5557,108 @@ compile_test() {
compile_check_conftest "$CODE" "NV_SG_ALLOC_TABLE_FROM_PAGES_SEGMENT_PRESENT" "" "functions"
;;
drm_atomic_helper_connector_state_init)
#
# Determine if __drm_atomic_helper_connector_state_init is present.
#
# Added by commit b74940afe5bc ("drm/atomic-state-helper: Rename
# __drm_atomic_helper_connector_state_reset()") in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
void conftest_drm_atomic_helper_connector_state_init() {
__drm_atomic_helper_connector_state_init();
}"
compile_check_conftest "$CODE" "NV_DRM_ATOMIC_HELPER_CONNECTOR_STATE_INIT" "" "functions"
;;
drm_atomic_helper_crtc_state_init)
#
# Determine if __drm_atomic_helper_crtc_state_init is present.
#
# Added by commit 915fdd2c7e87 ("drm/atomic-state-helper: Rename
# __drm_atomic_helper_crtc_state_reset()") in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
void conftest_drm_atomic_helper_crtc_state_init() {
__drm_atomic_helper_crtc_state_init();
}"
compile_check_conftest "$CODE" "NV_DRM_ATOMIC_HELPER_CRTC_STATE_INIT" "" "functions"
;;
drm_atomic_helper_plane_state_init)
#
# Determine if __drm_atomic_helper_plane_state_init is present.
#
# Added by commit 3e5656ea5e73 ("drm/atomic-state-helper: Rename
# __drm_atomic_helper_plane_state_reset()") in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
void conftest_drm_atomic_helper_plane_state_init() {
__drm_atomic_helper_plane_state_init();
}"
compile_check_conftest "$CODE" "NV_DRM_ATOMIC_HELPER_PLANE_STATE_INIT" "" "functions"
;;
drm_connector_funcs_has_atomic_create_state)
#
# Determine if drm_connector_funcs has a 'atomic_create_state' function pointer.
#
# Added by commit 6db0e11f4806 ("drm/connector: Add new atomic_create_state callback")
# in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
int conftest_drm_connector_funcs_has_atomic_create_state(void) {
return offsetof(struct drm_connector_funcs, atomic_create_state);
}"
compile_check_conftest "$CODE" "NV_DRM_CONNECTOR_FUNCS_HAS_ATOMIC_CREATE_STATE" "" "types"
;;
drm_crtc_funcs_has_atomic_create_state)
#
# Determine if drm_crtc_funcs has a 'atomic_create_state' function pointer.
#
# Added by commit 58d426b5ed0d ("drm/crtc: Add new atomic_create_state callback")
# in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
int conftest_drm_crtc_funcs_has_atomic_create_state(void) {
return offsetof(struct drm_crtc_funcs, atomic_create_state);
}"
compile_check_conftest "$CODE" "NV_DRM_CRTC_FUNCS_HAS_ATOMIC_CREATE_STATE" "" "types"
;;
drm_plane_funcs_has_atomic_create_state)
#
# Determine if drm_plane_funcs has a 'atomic_create_state' function pointer.
#
# Added by commit 1a185ddecaf9 ("drm/plane: Add new atomic_create_state callback")
# in v7.3-rc1.
#
CODE="
#include <drm/drm_atomic_helper.h>
int conftest_drm_plane_funcs_has_atomic_create_state(void) {
return offsetof(struct drm_plane_funcs, atomic_create_state);
}"
compile_check_conftest "$CODE" "NV_DRM_PLANE_FUNCS_HAS_ATOMIC_CREATE_STATE" "" "types"
;;
# When adding a new conftest entry, please use the correct format for
# specifying the relevant upstream Linux kernel commit. Please
# avoid specifying -rc kernels, and only use SHAs that actually exist
@@ -266,6 +266,32 @@ done:
return status;
}
#if defined(NV_DRM_CONNECTOR_FUNCS_HAS_ATOMIC_CREATE_STATE)
/**
* nv_drm_connector_atomic_create_state - connector state creation hook
* @crtc: DRM connector
*
* Allocate an empty DRM connector state.
*/
static struct drm_connector_state *
nv_drm_connector_atomic_create_state(struct drm_connector *connector)
{
struct nv_drm_connector_state *nv_connector_state =
nv_drm_calloc(1, sizeof(*nv_connector_state));
if (!nv_connector_state) {
return ERR_PTR(-ENOMEM);
}
#if defined(NV_DRM_ATOMIC_HELPER_CONNECTOR_STATE_INIT)
__drm_atomic_helper_connector_state_init(&nv_connector_state->base, connector);
#else
__drm_atomic_helper_connector_state_reset(&nv_connector_state->base, connector);
#endif
return &nv_connector_state->base;
}
#else
static void nv_drm_connector_reset(struct drm_connector *connector)
{
struct nv_drm_connector_state * nv_connector_state =
@@ -285,6 +311,7 @@ static void nv_drm_connector_reset(struct drm_connector *connector)
__drm_atomic_helper_connector_reset(connector, &nv_connector_state->base);
}
#endif
static struct drm_connector_state* nv_drm_connector_atomic_duplicate_state(struct drm_connector *connector)
{
@@ -406,7 +433,11 @@ static int nv_drm_connector_atomic_get_property(
static struct drm_connector_funcs nv_connector_funcs = {
.destroy = nv_drm_connector_destroy,
#if defined(NV_DRM_CONNECTOR_FUNCS_HAS_ATOMIC_CREATE_STATE)
.atomic_create_state = nv_drm_connector_atomic_create_state,
#else
.reset = nv_drm_connector_reset,
#endif
.force = __nv_drm_connector_force,
.detect = nv_drm_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
+58
View File
@@ -2193,6 +2193,31 @@ static inline struct nv_drm_plane_state *nv_drm_plane_state_alloc(void)
return nv_plane_state;
}
#if defined(NV_DRM_PLANE_FUNCS_HAS_ATOMIC_CREATE_STATE)
/**
* nv_drm_plane_atomic_create_state - plane state creation hook
* @plane: DRM plane
*
* Allocate an empty DRM plane state.
*/
static struct drm_plane_state *nv_drm_plane_atomic_create_state(struct drm_plane *plane)
{
struct nv_drm_plane_state *nv_plane_state =
nv_drm_plane_state_alloc();
if (!nv_plane_state) {
return ERR_PTR(-ENOMEM);
}
#if defined(NV_DRM_ATOMIC_HELPER_PLANE_STATE_INIT)
__drm_atomic_helper_plane_state_init(&nv_plane_state->base, plane);
#else
__drm_atomic_helper_plane_state_reset(&nv_plane_state->base, plane);
#endif
return &nv_plane_state->base;
}
#else
/**
* nv_drm_plane_atomic_reset - plane state reset hook
* @plane: DRM plane
@@ -2223,6 +2248,7 @@ static void nv_drm_plane_atomic_reset(struct drm_plane *plane)
kfree(nv_plane_state);
}
}
#endif
static struct drm_plane_state *
@@ -2344,7 +2370,11 @@ static const struct drm_plane_funcs nv_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
.destroy = nv_drm_plane_destroy,
#if defined(NV_DRM_PLANE_FUNCS_HAS_ATOMIC_CREATE_STATE)
.atomic_create_state = nv_drm_plane_atomic_create_state,
#else
.reset = nv_drm_plane_atomic_reset,
#endif
.atomic_get_property = nv_drm_plane_atomic_get_property,
.atomic_set_property = nv_drm_plane_atomic_set_property,
.atomic_duplicate_state = nv_drm_plane_atomic_duplicate_state,
@@ -2408,7 +2438,30 @@ static inline struct nv_drm_crtc_state *nv_drm_crtc_state_alloc(void)
return nv_state;
}
#if defined(NV_DRM_CRTC_FUNCS_HAS_ATOMIC_CREATE_STATE)
/**
* nv_drm_atomic_crtc_atomic_create_state - crtc state creation hook
* @crtc: DRM crtc
*
* Allocate an empty DRM crtc state.
*/
static struct drm_crtc_state *nv_drm_atomic_crtc_atomic_create_state(struct drm_crtc *crtc)
{
struct nv_drm_crtc_state *nv_state = nv_drm_crtc_state_alloc();
if (!nv_state) {
return ERR_PTR(-ENOMEM);
}
#if defined(NV_DRM_ATOMIC_HELPER_CRTC_STATE_INIT)
__drm_atomic_helper_crtc_state_init(&nv_state->base, crtc);
#else
__drm_atomic_helper_crtc_state_reset(&nv_state->base, crtc);
#endif
return &nv_state->base;
}
#else
/**
* nv_drm_atomic_crtc_reset - crtc state reset hook
* @crtc: DRM crtc
@@ -2438,6 +2491,7 @@ static void nv_drm_atomic_crtc_reset(struct drm_crtc *crtc)
kfree(nv_state);
}
}
#endif
/**
* nv_drm_atomic_crtc_duplicate_state - crtc state duplicate hook
@@ -2585,7 +2639,11 @@ static bool nv_drm_crtc_get_vblank_timestamp(
static struct drm_crtc_funcs nv_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
#if defined(NV_DRM_CRTC_FUNCS_HAS_ATOMIC_CREATE_STATE)
.atomic_create_state = nv_drm_atomic_crtc_atomic_create_state,
#else
.reset = nv_drm_atomic_crtc_reset,
#endif
.destroy = nv_drm_crtc_destroy,
.atomic_get_property = nv_drm_atomic_crtc_get_property,
.atomic_set_property = nv_drm_atomic_crtc_set_property,
@@ -118,3 +118,9 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_funcs_has_get_vblank_timestamp
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_color_lut32_present
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_colorop_has_funcs
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_commit_struct_present
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_helper_connector_state_init
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_helper_crtc_state_init
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_helper_plane_state_init
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_funcs_has_atomic_create_state
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_funcs_has_atomic_create_state
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_plane_funcs_has_atomic_create_state
+3
View File
@@ -159,6 +159,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += hv_get_isolation_type
NV_CONFTEST_FUNCTION_COMPILE_TESTS += seq_read_iter
NV_CONFTEST_FUNCTION_COMPILE_TESTS += follow_pfn
NV_CONFTEST_FUNCTION_COMPILE_TESTS += ptep_get
NV_CONFTEST_FUNCTION_COMPILE_TESTS += pfn_is_map_memory
NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_gem_object_put_unlocked
NV_CONFTEST_FUNCTION_COMPILE_TESTS += add_memory_driver_managed
NV_CONFTEST_FUNCTION_COMPILE_TESTS += of_dma_configure
@@ -235,6 +236,7 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_lockdep_register_ke
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_pci_find_dvsec_capability
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_wait_for_device_probe
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_dma_iova_try_alloc
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_shmem_kernel_file_setup
NV_CONFTEST_TYPE_COMPILE_TESTS += vmf_insert_pfn_prot
NV_CONFTEST_TYPE_COMPILE_TESTS += sysfs_slab_unlink
@@ -264,6 +266,7 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += register_shrinker_has_format_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += nr_kernel_misc_reclaimable
NV_CONFTEST_TYPE_COMPILE_TESTS += pci_resize_resource_has_exclude_bars_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += dmem_cgrp_id
NV_CONFTEST_TYPE_COMPILE_TESTS += dmem_cgroup_register_region_has_init_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += misc_cgrp_id
NV_CONFTEST_TYPE_COMPILE_TESTS += is_vma_write_locked_has_mm_lock_seq_arg
NV_CONFTEST_TYPE_COMPILE_TESTS += percpu_mm_counter
+31 -4
View File
@@ -1977,6 +1977,13 @@ NV_STATUS NV_API_CALL os_numa_memblock_size
return NV_OK;
}
/*
* Allocates an anonymous file to be used only within the kernel.
*
* This file may bypass LSM checks such as SELinux, so it is important that this
* file never be mapped, linked into the filesystem, or assigned a file
* descriptor unless access control is checked by the caller.
*/
NV_STATUS NV_API_CALL os_allocate_temporary_file
(
void **ppFile,
@@ -1992,9 +1999,15 @@ NV_STATUS NV_API_CALL os_allocate_temporary_file
if (!path)
{
#if defined(mk_vma_flags)
file = shmem_file_setup("nvidia-tmp", 0, mk_vma_flags(VMA_NORESERVE_BIT));
#define NV_VMA_NORESERVE mk_vma_flags(VMA_NORESERVE_BIT)
#else
file = shmem_file_setup("nvidia-tmp", 0, VM_NORESERVE);
#define NV_VMA_NORESERVE VM_NORESERVE
#endif
#if NV_IS_EXPORT_SYMBOL_PRESENT_shmem_kernel_file_setup
file = shmem_kernel_file_setup("nvidia-tmp", 0, NV_VMA_NORESERVE);
#else
file = shmem_file_setup("nvidia-tmp", 0, NV_VMA_NORESERVE);
#endif
if (!IS_ERR(file))
{
@@ -2979,6 +2992,9 @@ NvU32 NV_API_CALL os_cgroup_implementation(void)
void* NV_API_CALL os_cgroup_for_pid(int pid, void *pidInfo, int impl)
{
void *cgrp = NULL;
#if defined(NV_DMEM_CGROUP_PRESENT) || defined(NV_MISC_CGROUP_PRESENT)
struct task_struct *task;
struct pid *p;
int subsys_id;
@@ -3010,7 +3026,9 @@ void* NV_API_CALL os_cgroup_for_pid(int pid, void *pidInfo, int impl)
default:
return NULL;
}
return task_cgroup(task, subsys_id);
cgrp = task_cgroup(task, subsys_id);
#endif
return cgrp;
}
#if defined(NV_DMEM_CGROUP_PRESENT) || defined(NV_MISC_CGROUP_PRESENT)
@@ -3028,7 +3046,16 @@ void* NV_API_CALL os_cgroup_parent(void *cgroup) { return NULL; }
#if defined(NV_DMEM_CGROUP_PRESENT)
void* NV_API_CALL os_dmem_cgroup_register_region(const char *name, NvU64 size, NvU64 precharge, void **prechargePool)
{
void *region = dmem_cgroup_register_region(size, name);
void *region;
#if defined(NV_DMEM_CGROUP_REGISTER_REGION_HAS_INIT_ARG)
const struct dmem_cgroup_init init =
{
.size = size,
};
region = dmem_cgroup_register_region(&init, name);
#else
region = dmem_cgroup_register_region(size, name);
#endif
if (IS_ERR(region))
{
return NULL;
+3
View File
@@ -72,6 +72,9 @@ namespace DisplayPort
{
return 0;
}
virtual NvU32 getDpTunnelingDownstreamDpcdRev() { return 0; }
virtual void setDevicePlugged(bool) {}
virtual bool isDevicePlugged()
{
+9 -1
View File
@@ -576,6 +576,7 @@ namespace DisplayPort
virtual void setIgnoreDiaNonLttprCrDoneStatus() = 0;
virtual void setOverrideExtendedWakeCapsForDpTunneling() = 0;
virtual void setChunkedLttprCapsReadForDpTunneling() = 0;
virtual void setOverrideDpcdRevFromDia() = 0;
virtual AuxRetry::status notifySDPErrDetectionCapability() = 0;
virtual bool isDp2xChannelCodingCapable() = 0;
@@ -721,6 +722,7 @@ namespace DisplayPort
bool bIsIgnoreDiaNonLttprCrDoneStatus;
bool bOverrideExtendedWakeCapsForDpTunneling;
bool bChunkedLttprCapsReadForDpTunneling;
bool bOverrideDpcdRevFromDia;
struct
{
@@ -811,7 +813,8 @@ namespace DisplayPort
bIsIgnoreDiaLttprInterlaneAlignStatus(false),
bIsIgnoreDiaNonLttprCrDoneStatus(false),
bOverrideExtendedWakeCapsForDpTunneling(false),
bChunkedLttprCapsReadForDpTunneling(false)
bChunkedLttprCapsReadForDpTunneling(false),
bOverrideDpcdRevFromDia(false)
{
// start with default caps.
dpcdOffline = true;
@@ -1555,6 +1558,11 @@ namespace DisplayPort
bChunkedLttprCapsReadForDpTunneling = true;
}
virtual void setOverrideDpcdRevFromDia()
{
bOverrideDpcdRevFromDia = true;
}
bool getDpTunnelEstimatedBw(NvU8 &estimatedBw);
bool hasDpTunnelEstimatedBwChanged();
bool hasDpTunnelBwAllocationCapabilityChanged();
@@ -124,7 +124,9 @@ namespace DisplayPort
bool isDP12AuthCap; // To tell whether this DP1.2 connector/ upmost device has the authentication Cap.
bool isHDCPAuthOn; // To tell whether this connector has the authentication on.
bool isHDCPReAuthPending; // To tell whether HDCP Auth is pending (at every stream addition and cleared at handler).
bool isHDCPAuthTriggered; // To tell whether HDCP Auth is triggered and only cleared at unplug/device detach for MST.
bool isHDCPAuthTriggered; // To tell whether HDCP Auth is triggered. Only cleared at last-group detach (activeGroups
// isEmpty()); deliberately NOT cleared at HPD high/low or in cancelHdcpCallbacks(), so it
// is kept true as long as possible to avoid racing a real in-flight reAuth's CP_IRQ.
bool isHopLimitExceeded; // To tell the current topology is over limitation.
bool bIsDiscoveryDetectActive; // To tell device discovery is active ( isDiscoveryDetectComplete is also used as DD notify and not want to impacts that. )
bool bNotifyDetectCompletePending; // To tell if we are pending to notify detect complete to client.
@@ -642,8 +644,7 @@ namespace DisplayPort
unsigned headIndex,
ModesetInfo modesetInfo);
virtual bool avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc,
bool bSameTimings);
virtual bool avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc);
virtual bool isLinkTrainingNeededForModeset(ModesetInfo modesetInfo);
@@ -91,8 +91,7 @@ namespace DisplayPort
virtual void handleEdidWARs(Edid &edid, DiscoveryManager::Device &device);
virtual void applyTimeslotWAR(unsigned &slot_count);
virtual bool avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc,
bool bSameTimings);
virtual bool avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc);
bool bSupportUHBR2_50; // Support UHBR2.5 for internal testing.
bool bSupportUHBR2_70; // Support UHBR2.7 for internal testing.
@@ -49,6 +49,25 @@ namespace DisplayPort
#define DEVICE_OUI_SIZE 3
#define DSC_CAPS_SIZE 16
#define PCLK_MHZ_TO_HZ 1000000U
#define HDMI2_MAX_TMDS_CLK_RATE_HZ 600000000ULL
#define CTA861_EXT_TAG 0x02
#define CTA861_EXT_TAG_OFFSET 0x00
#define CTA861_EXT_REVISION_OFFSET 0x01
#define CTA861_EXT_MIN_REVISION 0x03
#define CTA861_EXT_DTD_START_OFFSET 0x02
#define CTA861_DATA_BLOCK_START 0x04
#define CTA861_DATA_BLOCK_TAG_SHIFT 5
#define CTA861_DATA_BLOCK_LEN_MASK 0x1FU
#define CTA861_DATA_BLOCK_TAG_VENDOR 0x03
#define CTA861_VSDB_OUI_SIZE 3
#define CTA861_VSDB_OUI_HDMI_FORUM 0xC45DD8U
#define CTA861_VSDB_OUI_HDMI_LLC 0x000C03U
#define HF_VSDB_MAX_TMDS_RATE_OFFSET 4
#define HF_VSDB_MIN_PAYLOAD_SIZE 5
#define HDMI_VSDB_MAX_TMDS_CLK_OFFSET 6
#define HDMI_VSDB_MIN_PAYLOAD_SIZE 7
#define EDID_TMDS_RATE_UNIT_HZ 5000000ULL
struct GroupImpl;
struct ConnectorImpl;
class DeviceHDCPDetection;
@@ -130,6 +130,8 @@ namespace DisplayPort
return gpuSupportedDpVersions;
}
virtual NvU32 getDpTunnelingDownstreamDpcdRev();
virtual void setDevicePlugged(bool);
virtual bool isDevicePlugged()
{
@@ -149,6 +149,16 @@
// Enable per-device caching of panel FW checksum (DPCD 0x040A/0x040B) via regkey
#define NV_DP_REGKEY_ENABLE_PANEL_FW_REVISION_CACHE "DP_ENABLE_PANEL_FW_REVISION_CACHE"
// Disable adopting the DIA aggregated downstream DPCD rev as the policy rev on
// internal DP tunneling links.
#define NV_DP_REGKEY_DISABLE_DP_TUN_DIA_DPCD_REV_WAR "DISABLE_DP_TUN_DIA_DPCD_REV_WAR"
//
// Widen the DP tunneling DIA SW auto-read WAR to sinks of any OUI.
// This does not bypass the DP tunneling and RM capability checks.
//
#define NV_DP_REGKEY_ENABLE_DP_TUN_SW_AUTO_READ_WAR_ALL_SINKS "ENABLE_DP_TUN_SW_AUTO_READ_WAR_ALL_SINKS"
//
// Data Base used to store all the regkey values.
// The actual data base is declared statically in dp_evoadapter.cpp.
@@ -208,6 +218,8 @@ struct DP_REGKEY_DATABASE
bool bDisableDpTunLttprCapsChunkRead;
bool bDisableFecOnEdp;
bool bEnablePanelFwRevisionCache;
bool bDisableDpTunDiaDpcdRevWar;
bool bEnableDpTunSwAutoReadWarAllSinks;
};
extern struct DP_REGKEY_DATABASE dpRegkeyDatabase;
@@ -235,6 +235,24 @@ void DPCDHALImpl::parseAndReadCaps()
{
caps.revisionMajor = DRF_VAL(_DPCD, _REV, _MAJOR, buffer[0]);
caps.revisionMinor = DRF_VAL(_DPCD, _REV, _MINOR, buffer[0]);
if (isDpInTunnelingSupported() && bOverrideDpcdRevFromDia)
{
NvU32 diaDpcdRev = bus.getDirect()->getDpTunnelingDownstreamDpcdRev();
if ((DRF_VAL(_DPCD, _REV, _MAJOR, diaDpcdRev) == NV_DPCD_REV_MAJOR_1) &&
(DRF_VAL(_DPCD, _REV, _MINOR, diaDpcdRev) == NV_DPCD_REV_MINOR_1))
{
DP_PRINTF(DP_NOTICE,
"DPHAL> DP Tunneling DIA reports DPCD 1.1 sink, AUX reply was %d.%d. "
"Using 1.1 as policy rev.",
caps.revisionMajor, caps.revisionMinor);
caps.revisionMajor = NV_DPCD_REV_MAJOR_1;
caps.revisionMinor = NV_DPCD_REV_MINOR_1;
}
}
if (isAtLeastVersion(1, 2))
{
//
+322 -44
View File
@@ -190,6 +190,12 @@ ConnectorImpl::ConnectorImpl(MainLink * main, AuxBus * auxBus, Timer * timer, Co
}
}
if (main->isInternalDpTunnelingSupported() &&
!dpRegkeyDatabase.bDisableDpTunDiaDpcdRevWar)
{
hal->setOverrideDpcdRevFromDia();
}
hal->setConnectorTypeC(main->isConnectorUSBTypeC());
highestAssessedLC = initMaxLinkConfig();
@@ -465,6 +471,35 @@ void ConnectorImpl::discoveryNewDevice(const DiscoveryManager::Device & device)
}
}
//
// True when the device has a non-DisplayPort downstream port with detailed
// capabilities, i.e. a protocol converter. Bug 6546550.
//
static bool hasLegacyDownstreamPort(DeviceImpl * dev)
{
NvU8 byte = 0;
unsigned sizeCompleted = 0;
if (dev == NULL)
{
return false;
}
if (dev->getDpcdData(NV_DPCD_DOWNSTREAMPORT, &byte, sizeof(byte),
&sizeCompleted) != AuxBus::success)
{
return false;
}
if (FLD_TEST_DRF(_DPCD, _DOWNSTREAMPORT, _PRESENT, _NO, byte) ||
FLD_TEST_DRF(_DPCD, _DOWNSTREAMPORT, _DETAILED_CAP_INFO_AVAILABLE, _NO, byte))
{
return false;
}
return !FLD_TEST_DRF(_DPCD, _DOWNSTREAMPORT, _TYPE, _DISPLAYPORT, byte);
}
void ConnectorImpl::processNewDevice(const ProcessNewDeviceParams &params)
{
const DiscoveryManager::Device &device = params.device;
@@ -862,6 +897,14 @@ create:
}
}
}
//
// Catch a protocol converter not enumerated as peer device type 4 above.
// No-op on a real sink. Bug 6546550.
//
else if (newDev->isAtLeastVersion(1,4) && hasLegacyDownstreamPort(newDev))
{
newDev->getPCONCaps(&(newDev->pconCaps));
}
// Read panel replay capabilities
newDev->getPanelReplayCaps();
@@ -1555,6 +1598,184 @@ reRunCompoundQuery:
return bResult;
}
//
// Highest TMDS character rate, in Hz, the HDMI sink accepts on its input,
// from its EDID. 0 when unstated. Bug 6546550.
//
static NvU64 edidMaxTmdsCharRate(const Edid &edid)
{
const NvU8 *pData = edid.getBuffer()->getData();
unsigned length = edid.getBuffer()->getLength();
NvU64 hfVsdbRate = 0;
NvU64 vsdbRate = 0;
unsigned block;
if ((pData == NULL) || (length < (2 * EDID_BLOCK_SIZE)))
{
return 0;
}
for (block = EDID_BLOCK_SIZE; (block + EDID_BLOCK_SIZE) <= length;
block += EDID_BLOCK_SIZE)
{
const NvU8 *pExt = &pData[block];
unsigned dtdOffset;
unsigned i;
if ((pExt[CTA861_EXT_TAG_OFFSET] != CTA861_EXT_TAG) ||
(pExt[CTA861_EXT_REVISION_OFFSET] < CTA861_EXT_MIN_REVISION))
{
continue;
}
dtdOffset = pExt[CTA861_EXT_DTD_START_OFFSET];
if ((dtdOffset <= CTA861_DATA_BLOCK_START) || (dtdOffset > EDID_BLOCK_SIZE))
{
continue;
}
i = CTA861_DATA_BLOCK_START;
while (i < dtdOffset)
{
unsigned blockTag = pExt[i] >> CTA861_DATA_BLOCK_TAG_SHIFT;
unsigned payloadLen = pExt[i] & CTA861_DATA_BLOCK_LEN_MASK;
const NvU8 *pPayload = &pExt[i + 1U];
unsigned oui;
if ((i + 1U + payloadLen) > dtdOffset)
{
// Malformed collection - stop rather than read past it.
break;
}
i += 1U + payloadLen;
if ((blockTag != CTA861_DATA_BLOCK_TAG_VENDOR) ||
(payloadLen < CTA861_VSDB_OUI_SIZE))
{
continue;
}
oui = (unsigned)pPayload[0] | ((unsigned)pPayload[1] << 8) |
((unsigned)pPayload[2] << 16);
if ((oui == CTA861_VSDB_OUI_HDMI_FORUM) &&
(payloadLen >= HF_VSDB_MIN_PAYLOAD_SIZE))
{
hfVsdbRate = (NvU64)pPayload[HF_VSDB_MAX_TMDS_RATE_OFFSET] *
EDID_TMDS_RATE_UNIT_HZ;
}
else if ((oui == CTA861_VSDB_OUI_HDMI_LLC) &&
(payloadLen >= HDMI_VSDB_MIN_PAYLOAD_SIZE))
{
vsdbRate = (NvU64)pPayload[HDMI_VSDB_MAX_TMDS_CLK_OFFSET] *
EDID_TMDS_RATE_UNIT_HZ;
}
}
}
return (hfVsdbRate != 0) ? hfVsdbRate : vsdbRate;
}
//
// Upper bound, in Hz, on the TMDS character rate a DP to HDMI protocol
// converter can emit downstream. Returns 0 when no limit applies or none can
// be established, which callers must treat as unconstrained.
//
static NvU64 pconMaxTmdsCharRate(const DeviceImpl * dev)
{
NvU64 edidCharRate;
// connectorHDMI is the scope test: an HDMI connector type always means a
// protocol converter, regardless of how it was enumerated.
if ((dev == NULL) || (dev->connectorType != connectorHDMI))
{
return 0;
}
if (dev->pconCaps.maxHdmiLinkBandwidthGbps != 0)
{
return 0;
}
// Prefer what the converter advertised in its detailed port capabilities.
if (dev->pconCaps.maxTmdsClkRate != 0)
{
return (NvU64)dev->pconCaps.maxTmdsClkRate;
}
// No rate from the converter: a TMDS link is bounded at both ends, so
// fall back on what the sink's own EDID accepts.
edidCharRate = edidMaxTmdsCharRate(dev->rawEDID);
if (edidCharRate != 0)
{
return DP_MIN(edidCharRate, HDMI2_MAX_TMDS_CLK_RATE_HZ);
}
// Neither end published a rate: unknown, not unlimited. Don't reject on
// an assumption.
return 0;
}
//
// TMDS character rate, in Hz, the HDMI side of a converter has to run at to
// carry this mode. Mirrors the per format cases in compoundQueryAttachSST().
//
// TODO: move compoundQueryAttachSST() onto this function so the two copies
// cannot drift apart again.
//
static NvU64 tmdsCharRateForMode(const DpModesetParams &modesetParams)
{
NvU64 pixelClockHz = (NvU64)modesetParams.modesetInfo.pixelClockHz;
if ((modesetParams.colorFormat == dpColorFormat_YCbCr422) ||
(modesetParams.colorFormat == dpColorFormat_YCbCr422_Native))
{
return pixelClockHz;
}
// A converter emits uncompressed pixels, so a compressed depth is unusable.
if (modesetParams.modesetInfo.bEnableDsc || (modesetParams.modesetInfo.depth == 0))
{
return 0;
}
if (modesetParams.colorFormat == dpColorFormat_YCbCr420)
{
return ((pixelClockHz * modesetParams.modesetInfo.depth) / 24U) / 2U;
}
return (pixelClockHz * modesetParams.modesetInfo.depth) / 24U;
}
//
// Reject modes that overrun what a DP to HDMI protocol converter can emit
// downstream. 0 on either side means unknown - do not guess. Bug 6546550.
//
static bool isModeWithinPconLimits(const DeviceImpl * dev,
const DpModesetParams &modesetParams,
DP_IMP_ERROR *pErrorCode)
{
NvU64 maxCharRate = pconMaxTmdsCharRate(dev);
NvU64 requiredCharRate;
if (maxCharRate == 0)
{
return true;
}
requiredCharRate = tmdsCharRateForMode(modesetParams);
if ((requiredCharRate != 0) && (requiredCharRate > maxCharRate))
{
DP_PRINTF(DP_INFO,
"DPCONN> Mode needs %" NvU64_fmtu " Hz TMDS character rate, PCON limit is %" NvU64_fmtu " Hz",
requiredCharRate, maxCharRate);
SET_DP_IMP_ERROR(pErrorCode, DP_IMP_ERROR_DSC_PCON_HDMI2_BANDWIDTH)
return false;
}
return true;
}
bool ConnectorImpl::compoundQueryAttachMST(Group * target,
const DpModesetParams &modesetParams, // Modeset info
DscParams *pDscParams, // DSC parameters
@@ -1571,6 +1792,16 @@ bool ConnectorImpl::compoundQueryAttachMST(Group * target,
return false;
}
// Reject a mode the downstream HDMI port cannot clock out. Nothing is
// accumulated yet, so this needs no rollback. Bug 6546550.
for (Device * d = target->enumDevices(0); d; d = target->enumDevices(d))
{
if (!isModeWithinPconLimits((DeviceImpl *)d, modesetParams, pErrorCode))
{
return false;
}
}
localInfo.localModesetInfo = modesetParams.modesetInfo;
//
// compoundQueryAttachMSTGeneric scales localModesetInfo.depth in place,
@@ -1939,31 +2170,13 @@ bool ConnectorImpl::compoundQueryAttachMSTDsc(Group * target,
}
}
//
// If DP2HDMI PCON does not support FRL, but advertises TMDS
// Character clock rate on detailed caps, we need to honor that.
// No FRL, so the HDMI side is TMDS character rate limited.
// Bug 6546550.
//
else if (dev->pconCaps.maxTmdsClkRate != 0)
else if (!isModeWithinPconLimits(dev, modesetParams, pErrorCode))
{
NvU64 maxTmdsClkRateU64 = (NvU64)(dev->pconCaps.maxTmdsClkRate);
NvU64 requiredBw = (NvU64)(modesetParams.modesetInfo.pixelClockHz * modesetParams.modesetInfo.depth);
if (modesetParams.colorFormat == dpColorFormat_YCbCr420)
{
if (maxTmdsClkRateU64 < ((requiredBw/24)/2))
{
compoundQueryResult = false;
SET_DP_IMP_ERROR(pErrorCode, DP_IMP_ERROR_DSC_PCON_HDMI2_BANDWIDTH)
return false;
}
}
else
{
if (maxTmdsClkRateU64 < (requiredBw/24))
{
compoundQueryResult = false;
SET_DP_IMP_ERROR(pErrorCode, DP_IMP_ERROR_DSC_PCON_HDMI2_BANDWIDTH)
return false;
}
}
compoundQueryResult = false;
return false;
}
}
else if (dev->devDoingDscDecompression != dev)
@@ -3336,7 +3549,7 @@ void ConnectorImpl::fireEventsInternal()
//
// Setting isDiscoveryDetectComplete to true, now DPLIB can proceed and handle the cleint requests.
// Setting bNotifyDetectCompletePending to false, to indicate that the detect complete notification has been sent.
//
//
isDiscoveryDetectComplete = true;
bNotifyDetectCompletePending = false;
DP_PRINTF(DP_NOTICE, "DP-CONN> NotifyDetectComplete");
@@ -3496,17 +3709,7 @@ bool ConnectorImpl::isHeadShutDownNeeded(Group * target, // Group
//
else
{
// For the "same timings" check we only care about the fields that drive PCLK
// and raster programming -- pixel clock, raster size, and blanking.
const ModesetInfo &lastMs = targetImpl->lastModesetInfo;
const bool bSameTimings =
modesetInfo.pixelClockHz == lastMs.pixelClockHz &&
modesetInfo.rasterWidth == lastMs.rasterWidth &&
modesetInfo.rasterHeight == lastMs.rasterHeight &&
modesetInfo.rasterBlankStartX == lastMs.rasterBlankStartX &&
modesetInfo.rasterBlankEndX == lastMs.rasterBlankEndX;
if (avoidHeadShutdownForLinkConfig(lowestSelected, bSameTimings))
if (avoidHeadShutdownForLinkConfig(lowestSelected))
{
bHeadShutdownNeeded = false;
}
@@ -3525,8 +3728,7 @@ bool ConnectorImpl::isHeadShutDownNeeded(Group * target, // Group
return bHeadShutdownNeeded;
}
bool ConnectorImpl::avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc,
bool /*bSameTimings*/)
bool ConnectorImpl::avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc)
{
// DP1.x: keep legacy data-rate >= behavior; not affected by the UHBR TU window.
bool bAvoidShutdown = (targetLc.getTotalDataRate() >= activeLinkConfig.getTotalDataRate());
@@ -3861,14 +4063,52 @@ void ConnectorImpl::dpPreModeset(const DpPreModesetParams &params)
return;
}
// Skip gating modeset on HPD for DDS panels
if(!previousPlugged && !bClientForcedConnected && !main->isInternalPanelDynamicMuxCapable())
//
// NVKMS funnels both attach and detach through this entry point. A detach
// that arrives after HPD de-assert has to be let through, otherwise DPLib
// stream state is left stale while the client clears its head mask. Attach
// stays gated on plug state; DDS panels are never gated on HPD.
//
bool bAttachAllowed = previousPlugged || bClientForcedConnected ||
main->isInternalPanelDynamicMuxCapable();
NvU32 attachHeadMask = 0x0;
NvU32 detachHeadMask = 0x0;
for (NvU32 i = 0; i < NV_MAX_HEADS; i++)
{
DP_ASSERT(0 && "DPCONN> dpPreModeset called when Plugged State is false!");
return;
if ((params.headMask & NVBIT(i)) == 0x0)
continue;
if (params.head[i].pTarget != NULL)
attachHeadMask |= NVBIT(i);
else
detachHeadMask |= NVBIT(i);
}
this->bFECEnable |= this->needToEnableFEC(params);
if (!bAttachAllowed)
{
if (detachHeadMask == 0x0)
{
DP_ASSERT(0 && "DPCONN> dpPreModeset called when Plugged State is false!");
return;
}
if (attachHeadMask != 0x0)
{
//
// notifyAttachBegin/notifyAttachEnd reject these anyway. Dropping them
// here too keeps bFECEnable, inTransitionHeadMask and
// perHeadAttachedGroup from recording an attach that DPLib never
// completed, which a later detach would otherwise act on.
//
DP_PRINTF(DP_ERROR, "DPCONN> dpPreModeset skipping attach on headMask 0x%x, Plugged State is false!",
attachHeadMask);
}
}
else
{
this->bFECEnable |= this->needToEnableFEC(params);
}
DP_ASSERT(this->inTransitionHeadMask == 0x0);
this->inTransitionHeadMask = 0x0;
@@ -3878,6 +4118,9 @@ void ConnectorImpl::dpPreModeset(const DpPreModesetParams &params)
if ((params.headMask & NVBIT(i)) == 0x0)
continue;
if (!bAttachAllowed && ((attachHeadMask & NVBIT(i)) != 0x0))
continue;
this->inTransitionHeadMask |= NVBIT(i);
if (params.head[i].pTarget != NULL)
@@ -4550,6 +4793,9 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive, bool bKeepLinkOn)
{
cancelHdcpCallbacks();
// Only clear no more auth triggered when empty group.
isHDCPAuthTriggered = false;
// We disconnected a panel, try to clear the transition
if (linkAwaitingTransition)
{
@@ -4621,9 +4867,12 @@ void ConnectorImpl::notifyDetachEnd(bool bKeepOdAlive, bool bKeepLinkOn)
{
if (hdcpState.HDCP_State_22_Capable)
{
// No need forceClear.
main->configureAndTriggerECF(0x0);
authRetries = 0;
isHDCPAuthOn = false;
// Group not empty, trigger authentication with flag set.
isHDCPAuthTriggered = true;
// numOfStream changed, AKE_Init needed to change dpTypeMask
main->configureHDCPRenegotiate();
// ReAuth, so schedule callback to check state later.
@@ -5595,6 +5844,16 @@ bool ConnectorImpl::handleCPIRQ()
// CP_Irq event since Auth never started after HPD high or
// LinkTraining start.
//
// isHDCPAuthTriggered is only cleared at last-group detach
// (activeGroups.isEmpty()), not at HPD high/low or in
// cancelHdcpCallbacks(). This is deliberate: clearing it more
// eagerly would reduce the (mild, self-recovering) risk of
// honoring a stale post-plug IRQ here, but would raise the
// risk of racing a real in-flight reAuth and dropping its
// legitimate CP_IRQ, which is the more severe failure (sink
// stuck). So the flag is kept true as long as possible and
// only reset where doing so is unambiguously safe.
//
if (isHDCPAuthTriggered)
{
bReAuthReq = NV_TRUE;
@@ -5666,6 +5925,7 @@ bool ConnectorImpl::handleCPIRQ()
//
if (bReAuthReq)
{
// No need forceClear.
main->configureAndTriggerECF(0x0);
}
@@ -6799,8 +7059,14 @@ bool ConnectorImpl::train(const LinkConfiguration & lConfig, bool force,
//
// Cancel pending HDCP authentication callbacks if have or may interrupt
// active link training that violates spec.
// active link training that violates spec. Snapshot the pending state
// first so it can be restored below once training is done -- callers
// like notifyShortPulse()'s link-loss retrain invoke train() with no
// later notifyAttachEnd to re-arm HDCP, so a bare cancel here would
// permanently drop any HDCP re-authentication that was already queued.
//
bool bHDCPAuthTriggered = this->isHDCPAuthTriggered;
bool bHDCPReAuthPending = this->isHDCPReAuthPending;
cancelHdcpCallbacks();
if (!lConfig.multistream)
@@ -6932,6 +7198,19 @@ bool ConnectorImpl::train(const LinkConfiguration & lConfig, bool force,
this->psrLinkConfig = activeLinkConfig;
}
//
// Re-arm HDCP re-authentication that was cancelled above, but only if the
// link came back up -- if training failed or the link was powered down
// (lanes == 0), there's nothing to re-authenticate against.
//
if ((bHDCPAuthTriggered || bHDCPReAuthPending) && result && (activeLinkConfig.lanes != 0))
{
this->isHDCPAuthTriggered = bHDCPAuthTriggered;
this->isHDCPReAuthPending = bHDCPReAuthPending;
timer->queueCallback(this, &tagHDCPReauthentication, HDCP_AUTHENTICATION_COOLDOWN,
false /* not allowed in sleep */);
}
return result;
}
@@ -9013,7 +9292,6 @@ bool ConnectorImpl::hdcpValidateKsv(const NvU8 *ksv, NvU32 Size)
void ConnectorImpl::cancelHdcpCallbacks()
{
this->isHDCPReAuthPending = false;
this->isHDCPAuthTriggered = false;
this->authRetries = 0;
timer->cancelCallback(this, &tagHDCPReauthentication); // Cancel any queue the auth callback.
@@ -1668,6 +1668,9 @@ void ConnectorImpl2x::notifyDetachEnd(bool bKeepOdAlive, bool bKeepLinkOn)
{
cancelHdcpCallbacks();
// Only clear no more auth triggered when empty group.
isHDCPAuthTriggered = false;
// We disconnected a panel, try to clear the transition
if (linkAwaitingTransition)
{
@@ -2256,24 +2259,27 @@ void ConnectorImpl2x::handleEdidWARs(Edid & edid, DiscoveryManager::Device & dev
}
}
bool ConnectorImpl2x::avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc,
bool bSameTimings)
bool ConnectorImpl2x::avoidHeadShutdownForLinkConfig(const LinkConfiguration &targetLc)
{
bool bAvoidShutdown = false;
if (bUseLegacyHeadShutdownPolicy)
{
// Regkey override: fall back to the DP1.x-style data-rate >= policy.
return ConnectorImpl::avoidHeadShutdownForLinkConfig(targetLc, bSameTimings);
return ConnectorImpl::avoidHeadShutdownForLinkConfig(targetLc);
}
//
// T25x: scope bSameTimings requirement to N1x + DP tunneling only (bug 6054761).
// isDpInTunnelingSupported() — runtime: DP tunnel topology detected
// isDpTunnelingHwBugWarEnabled() — set by RM only on T25x/N1x platforms
// Force head shutdown on platform where internal DP tunneling is supported and DP tunnel topology is detected.
// isDpInTunnelingSupported() - runtime: DP tunneling detected
// isInternalDpTunnelingSupported() - set by RM only on T25x/N1x+ platforms where internal DP tunneling is supported on SoC
//
bool bN1xTunneling = hal->isDpInTunnelingSupported() && main->isDpTunnelingHwBugWarEnabled();
bool bAvoidShutdown = (targetLc == activeLinkConfig) && (!bN1xTunneling || bSameTimings);
DP_PRINTF(DP_NOTICE, "DP2.x avoidHeadShutdown: target=%llu active=%llu sameTimings=%d bN1xTunneling=%d result=%d",
bool bInternalDpTunneling = main->isInternalDpTunnelingSupported() && hal->isDpInTunnelingSupported();
if (!bInternalDpTunneling)
{
bAvoidShutdown = (targetLc == activeLinkConfig);
}
DP_PRINTF(DP_NOTICE, "DP2.x avoidHeadShutdown: target=%llu active=%llu bInternalDpTunneling=%d result=%d",
targetLc.getTotalDataRate(), activeLinkConfig.getTotalDataRate(),
bSameTimings, bN1xTunneling, bAvoidShutdown);
bInternalDpTunneling, bAvoidShutdown);
return bAvoidShutdown;
}
+36 -6
View File
@@ -124,7 +124,9 @@ const struct
{NV_DP_REGKEY_ENABLE_SST_EDID_RECOVERY_FIX, &dpRegkeyDatabase.bEnableSstEdidRecoveryFix, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_DISABLE_DP_TUN_LTTPR_CAPS_CHUNK_READ_WAR, &dpRegkeyDatabase.bDisableDpTunLttprCapsChunkRead, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_DISABLE_FEC_ON_EDP, &dpRegkeyDatabase.bDisableFecOnEdp, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_ENABLE_PANEL_FW_REVISION_CACHE, &dpRegkeyDatabase.bEnablePanelFwRevisionCache, DP_REG_VAL_BOOL}
{NV_DP_REGKEY_ENABLE_PANEL_FW_REVISION_CACHE, &dpRegkeyDatabase.bEnablePanelFwRevisionCache, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_DISABLE_DP_TUN_DIA_DPCD_REV_WAR, &dpRegkeyDatabase.bDisableDpTunDiaDpcdRevWar, DP_REG_VAL_BOOL},
{NV_DP_REGKEY_ENABLE_DP_TUN_SW_AUTO_READ_WAR_ALL_SINKS, &dpRegkeyDatabase.bEnableDpTunSwAutoReadWarAllSinks, DP_REG_VAL_BOOL}
};
EvoMainLink::EvoMainLink(EvoInterface * provider, Timer * timer) :
@@ -361,9 +363,16 @@ void EvoMainLink::setDpWarFlag(NvU32 warId, bool bEnable)
params.bEnable = bEnable ? NV_TRUE : NV_FALSE;
NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_SET_WAR_FLAGS, &params, sizeof params);
if (ret != NVOS_STATUS_SUCCESS)
//
// RM implements this control only where RMCFG_FEATURE_DP_TUNNELING is
// enabled. The clear runs on every plug and unplug, so ignore ERROR_NOT_SUPPORTED instead of
// logging it on every hotplug on GPUs that cannot have the WAR at all.
//
if (ret != NVOS_STATUS_SUCCESS && ret != NVOS_STATUS_ERROR_NOT_SUPPORTED)
{
DP_PRINTF(DP_ERROR, "setDpWarFlag failed!");
DP_PRINTF(DP_WARNING, "setDpWarFlag failed (warId: 0x%x, bEnable: %d, status: 0x%x)",
warId, bEnable, ret);
}
}
@@ -377,9 +386,10 @@ void EvoMainLink::configureAndTriggerECF(NvU64 ecf, NvBool bForceClearEcf, NvBoo
// ForceClearECF will delete DP MST Time slots along with ECF from GA10X and Later
// if ADD Stream Back is set then it will add back same time slots after clearing ECF
// bForceClear = TRUE should be set to have significance for bAddStreamBack
// bForceClear will be only set in case of Detach Stream/Flush mode
// bAddStream will also be set only in case of QSES error scenario
// In all other cases these are set to FALSE
// bForceClear will be set in case of Detach Stream/Flush mode, QSES error scenario,
// or MST HDCP content-type reAuth (GroupImpl::hdcpSetEncrypted, bNeedReNegotiate) —
// the latter deletes/re-adds time slots for the whole SOR, not just the group whose
// type changed. In all other cases these are set to FALSE.
//
params.bForceClearEcf = bForceClearEcf;
params.bAddStreamBack = bAddStreamBack;
@@ -1203,6 +1213,26 @@ void EvoAuxBus::setGpuDPSupportedVersions(NvU32 dpVersionsSupported)
gpuSupportedDpVersions = dpVersionsSupported;
}
NvU32 EvoAuxBus::getDpTunnelingDownstreamDpcdRev()
{
NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS params = {0};
params.subDeviceInstance = this->subdeviceIndex;
params.displayId = this->displayId;
params.warId = NV0073_CTRL_DP_WAR_DATA_DIA_DPCD_REV;
NvU32 ret = provider->rmControl0073(NV0073_CTRL_CMD_DP_GET_WAR_DATA,
&params, sizeof params);
if (ret != NVOS_STATUS_SUCCESS)
{
DP_PRINTF(DP_WARNING,
"DP> Failed to read DIA aggregated DPCD rev, status 0x%08x", ret);
return 0;
}
// Zero when the display is not on a DP IN adapter.
return params.data;
}
void EvoMainLink::preLinkTraining(NvU32 head)
{
provider->preLinkTraining(head);
@@ -426,8 +426,67 @@ bool GroupImpl::hdcpSetEncrypted(bool encrypted, NvU8 streamType, NvBool bForce
if(!parent->isHDCPAuthOn || bNeedReNegotiate)
{
//
// Bug 6472337: Renegotiate for MST needs to disable ECF ( uproc would disable HW encryption ).
// Here need to forceClear and addStreamBack or cannot clear under encrypted state.
//
// Bug 6755367: It would see transient blank with forceClear, wait add streams back.
// Repro is on the same legacy 8b/10b MST config as bug 6472337, so narrow this to
// N1X (GLOBAL_FEATURE_DP_TUNNELING_T25X) only, which is what bug 6472337's stuck
// state actually depends on. 128b132b is additionally excluded (on chips that also
// have GR1686_DISPLAYPORT_BLACKWELL) since the issue this force-clear protects
// against is 8b/10b-only regardless of tunneling. 2Head1OR (DSC_DUAL/DSC_DROP) is
// also excluded, since it doesn't reproduce bug 6472337's stuck state without this
// force-clear, so excluding it avoids the unneeded transient blank. The build-time
// config check above only reflects chip capability; also require both source
// (main->isInternalDpTunnelingSupported) and sink (parent->isDpInTunnelingSupported)
// to confirm the active link is actually a DP tunneling connection at runtime.
//
if (bNeedReNegotiate
&& !linkConfig.bIs128b132bChannelCoding
&& (this->lastModesetInfo.mode != DSC_DUAL)
&& (this->lastModesetInfo.mode != DSC_DROP)
&& parent->linkUseMultistream()
&& parent->main->isInternalDpTunnelingSupported()
&& parent->isDpInTunnelingSupported())
{
//
// Compute ECF with only this group's timeslot bits cleared, leaving every
// other currently-encrypted group's bits untouched — same mask math the
// disable branch below uses. Passing plain 0x0 here would force-clear
// every encrypted head on this SOR, not just this group (uproc iterates
// headOwnerMask and force-clears any head whose requested bits differ
// from current, see hdcp22wired_hdcp22wired0401.c).
//
NvU64 ecf = 0x0;
NvU64 countOnes, mask;
for (ListElement * i = parent->activeGroups.begin(); i != parent->activeGroups.end(); i = i->next)
{
GroupImpl * group = (GroupImpl *)i;
if (group->hdcpEnabled)
{
// Note: no 128b/132b 64-timeslot special-case here (unlike the disable
// branch below) — this block only runs when !bIs128b132bChannelCoding.
countOnes = (((NvU64)1) << group->timeslot.count) - 1;
mask = countOnes << group->timeslot.begin;
ecf |= mask;
}
}
countOnes = (((NvU64)1) << this->timeslot.count) - 1;
mask = countOnes << this->timeslot.begin;
ecf &= ~mask;
parent->main->configureAndTriggerECF(ecf, NV_TRUE, NV_TRUE);
// Force clear just zeroed HW encryption for this group; don't let
// hdcpGetEncrypted() report it as protected until renegotiate below
// resolves the real state.
this->hdcpEnabled = false;
}
cancelHdcpCallbacks();
parent->isHDCPAuthTriggered = true;
parent->main->configureHDCPRenegotiate();
parent->main->configureHDCPGetHDCPState(hdcpState);
if (hdcpState.HDCP_State_Encryption)
+15 -9
View File
@@ -96,6 +96,12 @@ void ConnectorImpl::applyOuiWARs()
void ConnectorImpl2x::applyOuiWARs()
{
//
// The regkey only extends the SW auto-read WAR to any OUI.
// It does not bypass the DP tunneling or RM capability checks.
//
bool bSwAutoReadWarNeeded = main->getRegkeyDatabase().bEnableDpTunSwAutoReadWarAllSinks;
switch (ouiId)
{
// Novatek Microelectronics Corp.
@@ -127,19 +133,19 @@ void ConnectorImpl2x::applyOuiWARs()
break;
//
// Realtek DP sink (OUI 00:E0:4C, ouiId 0x4CE000, device "Dp1.4").
// Realtek DP sink (OUI 00:E0:4C), any model.
//
case 0x4CE000:
if ((modelName[0] == 'D') && (modelName[1] == 'p') && (modelName[2] == '1') &&
(modelName[3] == '.') && (modelName[4] == '4') &&
hal->isDpInTunnelingSupported() &&
main->isDpTunnelingHwBugWarEnabled())
{
main->setDpWarFlag(NV0073_CTRL_DP_WAR_SW_AUTO_READ_ENABLE, true);
this->bSwAutoReadWarActive = true;
}
bSwAutoReadWarNeeded = true;
break;
}
if (bSwAutoReadWarNeeded &&
hal->isDpInTunnelingSupported() &&
main->isDpTunnelingHwBugWarEnabled())
{
main->setDpWarFlag(NV0073_CTRL_DP_WAR_SW_AUTO_READ_ENABLE, true);
this->bSwAutoReadWarActive = true;
}
}
+10 -10
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 r616_69
#define NV_BUILD_BRANCH r617_07
#endif
#ifndef NV_PUBLIC_BRANCH
#define NV_PUBLIC_BRANCH r616_69
#define NV_PUBLIC_BRANCH r617_07
#endif
#if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r615/r616_69-202"
#define NV_BUILD_CHANGELIST_NUM (38888698)
#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r615/r617_07-228"
#define NV_BUILD_CHANGELIST_NUM (39079891)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "rel/gpu_drv/r615/r616_69-202"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (38888698)
#define NV_BUILD_NAME "rel/gpu_drv/r615/r617_07-228"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (39079891)
#else /* Windows builds */
#define NV_BUILD_BRANCH_VERSION "r616_69-12"
#define NV_BUILD_CHANGELIST_NUM (38888698)
#define NV_BUILD_BRANCH_VERSION "r617_07-31"
#define NV_BUILD_CHANGELIST_NUM (39077980)
#define NV_BUILD_TYPE "Official"
#define NV_BUILD_NAME "616.92"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (38888698)
#define NV_BUILD_NAME "617.52"
#define NV_LAST_OFFICIAL_CHANGELIST_NUM (39077980)
#define NV_BUILD_BRANCH_BASE_VERSION R615
#endif
// End buildmeister python edited section
+1 -1
View File
@@ -5,7 +5,7 @@
(defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1) || \
defined(NV_DCECORE)
#define NV_VERSION_STRING "615.71.09"
#define NV_VERSION_STRING "615.78.08"
#else
+25 -5
View File
@@ -516,9 +516,16 @@ static void populateDscCaps(HDMI_SRC_CAPS const * const pSrcCaps,
NvU32 sliceCountMask = 0;
NvU32 maxNumHztSlices = pSinkCaps->pHdmiForumInfo->dsc_MaxSlices;
NvU32 peakThroughput = (pSinkCaps->pHdmiForumInfo->dsc_MaxPclkPerSliceMHz == 400) ?
DSC_DECODER_PEAK_THROUGHPUT_MODE0_400 :
DSC_DECODER_PEAK_THROUGHPUT_MODE0_340;
NvU32 peakThroughput;
// HDMI 2.1b and HDMI 2.2 add 600 MHz and 900 MHz per-slice throughput caps.
switch (pSinkCaps->pHdmiForumInfo->dsc_MaxPclkPerSliceMHz)
{
case 900: peakThroughput = DSC_DECODER_PEAK_THROUGHPUT_MODE0_900; break;
case 600: peakThroughput = DSC_DECODER_PEAK_THROUGHPUT_MODE0_600; break;
case 400: peakThroughput = DSC_DECODER_PEAK_THROUGHPUT_MODE0_400; break;
default: peakThroughput = DSC_DECODER_PEAK_THROUGHPUT_MODE0_340; break;
}
switch(pSinkCaps->pHdmiForumInfo->dsc_MaxSlices)
{
@@ -548,8 +555,21 @@ static void populateDscCaps(HDMI_SRC_CAPS const * const pSrcCaps,
// Per DSC v1.2 spec, native 422/420 per-slice peak throughput is approximately twice of RGB/444 peak throughput
// HDMI has only one throughput cap reporting, no separate 422/420 throughput cap unlike for DP, so just double 444's value here.
pDscInfo->sinkCaps.peakThroughputMode1 = (peakThroughput == DSC_DECODER_PEAK_THROUGHPUT_MODE0_340) ?
DSC_DECODER_PEAK_THROUGHPUT_MODE1_680 : DSC_DECODER_PEAK_THROUGHPUT_MODE1_800;
switch (peakThroughput)
{
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_900:
pDscInfo->sinkCaps.peakThroughputMode1 = DSC_DECODER_PEAK_THROUGHPUT_MODE1_1800;
break;
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_600:
pDscInfo->sinkCaps.peakThroughputMode1 = DSC_DECODER_PEAK_THROUGHPUT_MODE1_1200;
break;
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_400:
pDscInfo->sinkCaps.peakThroughputMode1 = DSC_DECODER_PEAK_THROUGHPUT_MODE1_800;
break;
default:
pDscInfo->sinkCaps.peakThroughputMode1 = DSC_DECODER_PEAK_THROUGHPUT_MODE1_680;
break;
}
}
// Fill in mode related info for DSC lib
+6
View File
@@ -1357,6 +1357,12 @@ DSC_GetPeakThroughputMps(NvU32 peak_throughput)
case DSC_DECODER_PEAK_THROUGHPUT_MODE0_680:
peak_throughput_mps = 680;
break;
case DSC_DECODER_PEAK_THROUGHPUT_MODE1_1200:
peak_throughput_mps = 1200;
break;
case DSC_DECODER_PEAK_THROUGHPUT_MODE1_1800:
peak_throughput_mps = 1800;
break;
default:
peak_throughput_mps = 0;
}
+4 -2
View File
@@ -166,9 +166,11 @@ typedef struct
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_950 (0x0000000D)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_1000 (0x0000000E)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_170 (0x0000000F)
// Custom definition of peak throughput for HDMI YUV modes since those are not defined in spec
// Starting with 0x100 to provide headroom for DSC spec definitions in future
// Custom HDMI YUV throughput values that are not defined by the DSC specification.
// Use 0x100 increments to avoid overlapping the specification-defined values.
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_680 (0x00000100)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_1200 (0x00000200)
#define DSC_DECODER_PEAK_THROUGHPUT_MODE1_1800 (0x00000300)
// Maximum bits_per_pixel supported by the DSC decompressor multiplied by 16
NvU32 maxBitsPerPixelX16;
@@ -1700,7 +1700,7 @@ typedef struct NV0073_CTRL_CMD_DP_SEND_ACT_PARAMS {
* bAvoidHBR3
* Returns NV_TRUE if we need to avoid HBR3 as much as possible
* bPollingEnabledForDpMstDetection
* Returns NV_TRUE if polling is enabled for DP MST Detection
* Returns NV_TRUE if polling is enabled for DP MST Detection.
* - The Post-based approach introduced a delay in processing LAM and EDID events
* - This never introduced any delay. There is some delay from an unknown source which needs to be debugged
* bIsDpTunnelingHwBugWarEnabled
@@ -3772,4 +3772,50 @@ typedef struct NV0073_CTRL_CMD_DP_SET_WAR_FLAGS_PARAMS {
#define NV0073_CTRL_CMD_DP_SET_WAR_FLAGS (0x731391U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_SET_WAR_FLAGS_PARAMS_MESSAGE_ID" */
/*
* NV0073_CTRL_CMD_DP_GET_WAR_DATA
*
* This command lets dplib read a value that a DisplayPort software
* workaround needs, from the root-port displayId. Each value is identified
* by a simple enumerated warId; the command carries one enumerated WAR per
* call. The value is served from GPU state and issues no AUX traffic, so it
* is safe to call from the capability parsing path.
*
* subDeviceInstance
* This parameter specifies the subdevice instance within the
* NV04_DISPLAY_COMMON parent device to which the operation should be
* directed. This parameter must specify a value between zero and the
* total number of subdevices within the parent device. This parameter
* should be set to zero for default behavior.
* displayId
* Specifies the root port displayId the workaround applies to.
* warId
* Which workaround value to read. Valid values:
* NV0073_CTRL_DP_WAR_DATA_DIA_DPCD_REV - aggregated downstream DPCD rev
* from the DP IN adapter, that is min(downstream DPRX response,
* DP_COMMON_CAP.Maximal DPCD Rev), in DPCD 00000h encoding
* (0x11 = DP 1.1, 0x12 = DP 1.2, ...).
* data
* Value read for warId. Zero when the value could not be determined,
* which includes a display that is not on a DP IN adapter.
*
* Possible status values returned are:
* NV_OK
* NV_ERR_INVALID_ARGUMENT
* NV_ERR_NOT_SUPPORTED
*
*/
#define NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS_MESSAGE_ID (0x92U)
typedef struct NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS {
NvU32 subDeviceInstance;
NvU32 displayId;
NvU32 warId;
NvU32 data;
} NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS;
#define NV0073_CTRL_DP_WAR_DATA_DIA_DPCD_REV 1U
#define NV0073_CTRL_CMD_DP_GET_WAR_DATA (0x731392U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS_MESSAGE_ID" */
/* _ctrl0073dp_h_ */
@@ -2935,8 +2935,7 @@ typedef struct NV2080_CTRL_FB_GET_MEMORY_BOOT_TRAINING_FLAGS_PARAMS {
typedef enum NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE {
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_DISPLAY_FRM = 0,
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_DISPLAY_FRM_RESERVED = 1,
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_UEFI = 2,
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_UEFI = 1,
} NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE;
typedef struct NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO {
@@ -836,4 +836,26 @@ typedef struct NV208F_CTRL_FB_SET_ROW_REMAP_FAILURE_FLAG_PARAMS {
NvBool value;
} NV208F_CTRL_FB_SET_ROW_REMAP_FAILURE_FLAG_PARAMS;
/*
* NV208F_CTRL_CMD_FB_SET_XID92_THRESHOLD_ENABLEMENT
*
* This command enables or disables XID 92 threshold enforcement for FBPA SEC
* interrupt storms.
*
* bEnable
* When true, the threshold emits XID 92 and disables FBPA SEC interrupts.
* When false, threshold-triggered XID 92 and interrupt disable actions are
* skipped.
*
* Possible status values returned are:
* NV_OK
*/
#define NV208F_CTRL_CMD_FB_SET_XID92_THRESHOLD_ENABLEMENT (0x208f051dU) /* finn: Evaluated from "(FINN_NV20_SUBDEVICE_DIAG_FB_INTERFACE_ID << 8) | NV208F_CTRL_FB_SET_XID92_THRESHOLD_ENABLEMENT_PARAMS_MESSAGE_ID" */
#define NV208F_CTRL_FB_SET_XID92_THRESHOLD_ENABLEMENT_PARAMS_MESSAGE_ID (0x1dU)
typedef struct NV208F_CTRL_FB_SET_XID92_THRESHOLD_ENABLEMENT_PARAMS {
NvBool bEnable;
} NV208F_CTRL_FB_SET_XID92_THRESHOLD_ENABLEMENT_PARAMS;
/* _ctrl208ffb_h_ */
@@ -117,6 +117,7 @@ typedef struct NVB0CC_CTRL_RESERVE_PM_AREA_SMPC_PARAMS {
*/
#define NVB0CC_PMA_BUFFER_SIZE_MAX (0xffe00000ULL) /* finn: Evaluated from "(4 * 1024 * 1024 * 1024 - 2 * 1024 * 1024)" */
#define NVB0CC_PMA_BYTES_AVAILABLE_SIZE (0x1000) /* finn: Evaluated from "(4 * 1024)" */
#define NVB0CC_PMA_INSTANCE_BLOCK_SIZE (0x1000) /* finn: Evaluated from "(4 * 1024)" */
#define NVB0CC_CTRL_ALLOC_PMA_STREAM_PARAMS_MESSAGE_ID (0x5U)
+8 -6
View File
@@ -691,8 +691,8 @@ done:
}
static NV_STATUS free_os_event(
NvHandle hParent,
NvU32 fd
NvHandle hParent,
NvU32 fd
)
{
nv_state_t *nv = nv_get_ctl_state();
@@ -703,7 +703,8 @@ static NV_STATUS free_os_event(
tmp = event = nv->event_list;
while (event)
{
if ((event->fd == fd) && (event->hParent == hParent))
if ((event->fd == fd) && (event->hParent == hParent)
)
{
if (event == nv->event_list)
nv->event_list = event->next;
@@ -3043,7 +3044,8 @@ NV_STATUS NV_API_CALL rm_ioctl(
break;
}
pApi->Status = free_os_event(pApi->hClient, pApi->fd);
pApi->Status = free_os_event(
pApi->hClient, pApi->fd);
break;
}
case NV_ESC_RM_GET_EVENT_DATA:
@@ -4636,9 +4638,9 @@ void NV_API_CALL rm_power_source_change_event(
}
os_unref_dynamic_power(nv, NV_DYNAMIC_PM_FINE);
}
// UNLOCK: release API lock
rmapiLockRelease();
}
// UNLOCK: release API lock
rmapiLockRelease();
}
if (rmStatus != NV_OK)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+22 -1
View File
@@ -3205,6 +3205,12 @@ static NV_STATUS dispcmnCtrlCmdDpSetWarFlags__EXPORT(void *pDispCommon, void *pP
}
#endif // !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x00000044u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x00000044u)
static NV_STATUS dispcmnCtrlCmdDpGetWarData__EXPORT(void *pDispCommon, void *pParams) {
return dispcmnCtrlCmdDpGetWarData_IMPL(pDispCommon, pParams);
}
#endif // !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x00000044u)
#if !NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x00000044u)
static NV_STATUS dispcmnCtrlCmdDpGetTestpattern__EXPORT(void *pDispCommon, void *pParams) {
return dispcmnCtrlCmdDpGetTestpattern_IMPL(pDispCommon, pParams);
@@ -5821,6 +5827,21 @@ static const struct NVOC_EXPORTED_METHOD_DEF __nvoc_exported_method_def_DispComm
{ /* [158] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x44u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) &dispcmnCtrlCmdDpGetWarData__EXPORT,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x44u)
/*flags=*/ 0x44u,
/*accessRight=*/0x0u,
/*methodId=*/ 0x731392u,
/*paramSize=*/ sizeof(NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS),
/*pClassInfo=*/ &(__nvoc_class_def_DispCommon.classInfo),
#if NV_PRINTF_STRINGS_ALLOWED
/*func=*/ "dispcmnCtrlCmdDpGetWarData"
#endif
},
{ /* [159] */
#if NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x44u)
/*pFunc=*/ (void (*)(void)) NULL,
#else
/*pFunc=*/ (void (*)(void)) &dispcmnCtrlCmdPsrGetSrPanelInfo__EXPORT,
#endif // NVOC_EXPORTED_METHOD_DISABLED_BY_FLAG(0x44u)
@@ -6117,7 +6138,7 @@ NV_STATUS __nvoc_up_thunk_Notifier_dispcmnGetOrAllocNotifShare(struct DispCommon
const struct NVOC_EXPORT_INFO __nvoc_export_info__DispCommon =
{
.numEntries= 159,
.numEntries= 160,
.pExportEntries= __nvoc_exported_method_def_DispCommon
};
+12
View File
@@ -2690,6 +2690,16 @@ static inline NV_STATUS dispcmnCtrlCmdDpSetWarFlags(struct DispCommon *pDispComm
#define dispcmnCtrlCmdDpSetWarFlags(pDispCommon, pParams) dispcmnCtrlCmdDpSetWarFlags_IMPL(pDispCommon, pParams)
#endif // __nvoc_disp_objs_h_disabled
NV_STATUS dispcmnCtrlCmdDpGetWarData_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS *pParams);
#ifdef __nvoc_disp_objs_h_disabled
static inline NV_STATUS dispcmnCtrlCmdDpGetWarData(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS *pParams) {
NV_ASSERT_FAILED_PRECOMP("DispCommon was disabled!");
return NV_ERR_NOT_SUPPORTED;
}
#else // __nvoc_disp_objs_h_disabled
#define dispcmnCtrlCmdDpGetWarData(pDispCommon, pParams) dispcmnCtrlCmdDpGetWarData_IMPL(pDispCommon, pParams)
#endif // __nvoc_disp_objs_h_disabled
NV_STATUS dispcmnCtrlCmdDpGetTestpattern_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_DP_GET_TESTPATTERN_PARAMS *pParams);
#ifdef __nvoc_disp_objs_h_disabled
static inline NV_STATUS dispcmnCtrlCmdDpGetTestpattern(struct DispCommon *pDispCommon, NV0073_CTRL_DP_GET_TESTPATTERN_PARAMS *pParams) {
@@ -3490,6 +3500,8 @@ NV_STATUS dispcmnCtrlCmdDpSetLaneData_IMPL(struct DispCommon *pDispCommon, NV007
NV_STATUS dispcmnCtrlCmdDpSetWarFlags_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_SET_WAR_FLAGS_PARAMS *pParams);
NV_STATUS dispcmnCtrlCmdDpGetWarData_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_CMD_DP_GET_WAR_DATA_PARAMS *pParams);
NV_STATUS dispcmnCtrlCmdDpGetTestpattern_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_DP_GET_TESTPATTERN_PARAMS *pParams);
NV_STATUS dispcmnCtrlCmdDpSetTestpattern_IMPL(struct DispCommon *pDispCommon, NV0073_CTRL_DP_SET_TESTPATTERN_PARAMS *pParams);
-11
View File
@@ -212,17 +212,6 @@ void __nvoc_init_dataField_OBJGPU(OBJGPU *pThis) {
pThis->setProperty(pThis, PDB_PROP_GPU_BUG_5395859_DFS_SCAN_PCIE_BUS, NV_FALSE);
}
// NVOC Property Hal field -- PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME
if (( ((chipHal_HalVarIdx >> 5) == 2UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x000000c0UL) )) /* ChipHal: GB20B | GB20C */
{
pThis->setProperty(pThis, PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME, NV_FALSE);
}
// default
else
{
pThis->setProperty(pThis, PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME, NV_FALSE);
}
// NVOC Property Hal field -- PDB_PROP_GPU_KEEP_WPR_ACROSS_GC6_SUPPORTED
if (( ((chipHal_HalVarIdx >> 5) == 2UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x000030feUL) )) /* ChipHal: GB202 | GB203 | GB205 | GB206 | GB207 | GB20B | GB20C | GR100 | GR102 */
{
+1 -4
View File
@@ -1190,7 +1190,7 @@ struct OBJGPU {
NvU32 (*__gpuGetXtlBaseAddr__)(struct OBJGPU * /*this*/); // halified (3 hals) body
NvU32 (*__gpuGetPrimaryFuseBaseAddr__)(struct OBJGPU * /*this*/); // halified (2 hals) body
// 133 PDB properties
// 132 PDB properties
NvBool PDB_PROP_GPU_HIGH_SPEED_BRIDGE_CONNECTED;
NvBool PDB_PROP_GPU_IN_STANDBY;
NvBool PDB_PROP_GPU_IN_HIBERNATE;
@@ -1207,7 +1207,6 @@ struct OBJGPU {
NvBool PDB_PROP_GPU_IS_CONNECTED;
NvBool PDB_PROP_GPU_BROKEN_FB;
NvBool PDB_PROP_GPU_BUG_5395859_DFS_SCAN_PCIE_BUS;
NvBool PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME;
NvBool PDB_PROP_GPU_IN_FULLCHIP_RESET;
NvBool PDB_PROP_GPU_IN_SECONDARY_BUS_RESET;
NvBool PDB_PROP_GPU_IN_GC6_RESET;
@@ -1612,8 +1611,6 @@ extern const struct NVOC_CLASS_DEF __nvoc_class_def_OBJGPU;
#define PDB_PROP_GPU_BROKEN_FB_BASE_NAME PDB_PROP_GPU_BROKEN_FB
#define PDB_PROP_GPU_BUG_5395859_DFS_SCAN_PCIE_BUS_BASE_CAST
#define PDB_PROP_GPU_BUG_5395859_DFS_SCAN_PCIE_BUS_BASE_NAME PDB_PROP_GPU_BUG_5395859_DFS_SCAN_PCIE_BUS
#define PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME_BASE_CAST
#define PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME_BASE_NAME PDB_PROP_GPU_SOC_FRM_RESTORE_HIBERNATE_RESUME
#define PDB_PROP_GPU_IN_FULLCHIP_RESET_BASE_CAST
#define PDB_PROP_GPU_IN_FULLCHIP_RESET_BASE_NAME PDB_PROP_GPU_IN_FULLCHIP_RESET
#define PDB_PROP_GPU_IN_SECONDARY_BUS_RESET_BASE_CAST
+1
View File
@@ -161,6 +161,7 @@ struct KernelOob {
// NvBool PDB_PROP_KOOB_IS_MISSING inherited from OBJENGSTATE
// Data members
NvBool bLoaded;
NvU32 registryOverride;
NvBool bSupported;
struct IoAperture mboxAperture;
-28
View File
@@ -1608,24 +1608,6 @@ static inline NV_STATUS memmgrCalculateHeapOffsetWithGSP(OBJGPU *pGpu, struct Me
#define memmgrCalculateHeapOffsetWithGSP(pGpu, pMemoryManager, offset) memmgrCalculateHeapOffsetWithGSP_395e98(pGpu, pMemoryManager, offset)
#endif // __nvoc_mem_mgr_h_disabled
#ifdef __nvoc_mem_mgr_h_disabled
static inline NV_STATUS memmgrSaveDisplayFrmReservedRegion(OBJGPU *pGpu, struct MemoryManager *pMemoryManager) {
NV_ASSERT_FAILED_PRECOMP("MemoryManager was disabled!");
return NV_ERR_NOT_SUPPORTED;
}
#else // __nvoc_mem_mgr_h_disabled
#define memmgrSaveDisplayFrmReservedRegion(pGpu, pMemoryManager) memmgrSaveDisplayFrmReservedRegion_395e98(pGpu, pMemoryManager)
#endif // __nvoc_mem_mgr_h_disabled
#ifdef __nvoc_mem_mgr_h_disabled
static inline NV_STATUS memmgrRestoreDisplayFrmReservedRegion(OBJGPU *pGpu, struct MemoryManager *pMemoryManager) {
NV_ASSERT_FAILED_PRECOMP("MemoryManager was disabled!");
return NV_ERR_NOT_SUPPORTED;
}
#else // __nvoc_mem_mgr_h_disabled
#define memmgrRestoreDisplayFrmReservedRegion(pGpu, pMemoryManager) memmgrRestoreDisplayFrmReservedRegion_395e98(pGpu, pMemoryManager)
#endif // __nvoc_mem_mgr_h_disabled
#ifdef __nvoc_mem_mgr_h_disabled
static inline NV_STATUS memmgrGetCarveoutRegionInfo(POBJGPU pGpu, struct MemoryManager *pMemoryManager, NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS *pParams) {
NV_ASSERT_FAILED_PRECOMP("MemoryManager was disabled!");
@@ -1921,8 +1903,6 @@ static inline NV_STATUS memmgrGetCarveoutRegionInfo(POBJGPU pGpu, struct MemoryM
#define memmgrDuplicateFromScanoutCarveoutRegion_FNPTR(pMemoryManager) pMemoryManager->__memmgrDuplicateFromScanoutCarveoutRegion__
#define memmgrDuplicateFromScanoutCarveoutRegion(pGpu, pMemoryManager, pMemDesc) memmgrDuplicateFromScanoutCarveoutRegion_DISPATCH(pGpu, pMemoryManager, pMemDesc)
#define memmgrDuplicateFromScanoutCarveoutRegion_HAL(pGpu, pMemoryManager, pMemDesc) memmgrDuplicateFromScanoutCarveoutRegion_DISPATCH(pGpu, pMemoryManager, pMemDesc)
#define memmgrSaveDisplayFrmReservedRegion_HAL(pGpu, pMemoryManager) memmgrSaveDisplayFrmReservedRegion(pGpu, pMemoryManager)
#define memmgrRestoreDisplayFrmReservedRegion_HAL(pGpu, pMemoryManager) memmgrRestoreDisplayFrmReservedRegion(pGpu, pMemoryManager)
#define memmgrGetCarveoutRegionInfo_HAL(pGpu, pMemoryManager, pParams) memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, pParams)
#define memmgrIsMemoryIoCoherent_FNPTR(pMemoryManager) pMemoryManager->__memmgrIsMemoryIoCoherent__
#define memmgrIsMemoryIoCoherent(pGpu, pMemoryManager, pAllocData) memmgrIsMemoryIoCoherent_DISPATCH(pGpu, pMemoryManager, pAllocData)
@@ -3069,14 +3049,6 @@ static inline NV_STATUS memmgrDuplicateFromScanoutCarveoutRegion_395e98(POBJGPU
return NV_ERR_NOT_SUPPORTED;
}
static inline NV_STATUS memmgrSaveDisplayFrmReservedRegion_395e98(OBJGPU *pGpu, struct MemoryManager *pMemoryManager){
return NV_ERR_NOT_SUPPORTED;
}
static inline NV_STATUS memmgrRestoreDisplayFrmReservedRegion_395e98(OBJGPU *pGpu, struct MemoryManager *pMemoryManager){
return NV_ERR_NOT_SUPPORTED;
}
static inline NV_STATUS memmgrGetCarveoutRegionInfo_ac1694(POBJGPU pGpu, struct MemoryManager *pMemoryManager, NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS *pParams){
return NV_OK;
}
@@ -865,6 +865,7 @@ static const CHIPS_RELEASED sChipsReleased[] = {
{ 0x3182, 0x20e6, 0x10de, "NVIDIA B300 SXM6 AC" },
{ 0x31C2, 0x21f1, 0x10de, "NVIDIA GB300" },
{ 0x31C3, 0x22f8, 0x10de, "NVIDIA GB300" },
{ 0x31C3, 0x23ab, 0x10de, "NVIDIA GB300-252" },
{ 0x1E37, 0x1347, 0x10DE, "GeForce RTX T10x-8" },
{ 0x1E37, 0x1348, 0x10DE, "GeForce RTX T10x-4" },
{ 0x1E37, 0x1349, 0x10DE, "GeForce RTX T10x-2" },
+5 -1
View File
@@ -21,6 +21,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "kernel/gpu/deferred_api.h"
#include "kernel/core/locks.h"
@@ -374,6 +375,10 @@ defapiCtrlCmdDeferredApiV2_IMPL
break;
}
case NV2080_CTRL_CMD_DMA_INVALIDATE_TLB:
{
break;
}
default:
// Nothing to do in kernel RM; just forward to physical RM.
break;
@@ -716,4 +721,3 @@ NvBool defapiIsSwMethodStalling_IMPL
return NV_TRUE;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -383,8 +383,10 @@ kflcnDumpTracepc_GA102
NvU64 pc;
NvU32 ctl;
NvU32 r, w, size;
NvU32 capacity;
NvU32 entry;
NvU32 count;
NvBool bFull = NV_FALSE;
r = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_RDIDX);
w = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_WTIDX);
@@ -398,29 +400,47 @@ kflcnDumpTracepc_GA102
size = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _MAXIDX, r);
if (size > __RISCV_MAX_TRACE_ENTRIES)
// __RISCV_MAX_TRACE_ENTRIES is 64, this is the entry count allocated for pCore->tracePC[]
if (size > (__RISCV_MAX_TRACE_ENTRIES - 1))
{
NV_PRINTF(LEVEL_ERROR, "Trace buffer larger than expected. Bailing!\n");
return;
}
r = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _RDIDX, r);
if (r > size)
{
return;
}
w = DRF_VAL(_PRISCV_RISCV, _TRACE_WTIDX, _WTIDX, w);
ctl = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACECTL);
if ((w == r) && (DRF_VAL(_PRISCV_RISCV, _TRACECTL, _FULL, ctl) == 0))
if (w > size)
{
count = 0;
return;
}
ctl = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACECTL);
capacity = size + 1U;
if (DRF_VAL(_PRISCV_RISCV, _TRACECTL, _FULL, ctl))
{
bFull = NV_TRUE;
}
if (bFull)
{
//
// FULL indicates that the ring has wrapped at least once. All slots
// therefore contain valid trace entries, regardless of the indices.
//
count = capacity;
}
else
{
//
// The number of entries in trace buffer is how far the w (put) pointer
// is ahead of the r (get) pointer. If this value is negative, add
// the size of the circular buffer to bring the element count back into range.
//
count = w > r ? w - r : w - r + size;
// WTIDX is the next write position; valid entries are [RDIDX, WTIDX).
count = (w + capacity - r) % capacity;
}
pCore->tracePCEntries = count;
@@ -429,9 +449,11 @@ kflcnDumpTracepc_GA102
{
for (entry = 0; entry < count; ++entry)
{
if (entry > w)
w += size;
kflcnRiscvRegWrite_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_RDIDX, w - entry);
// The stored trace is newest-to-oldest ordering
NvU32 index = (w + capacity - 1U - entry) % capacity;
kflcnRiscvRegWrite_HAL(pGpu, pKernelFlcn,
NV_PRISCV_RISCV_TRACE_RDIDX, index);
pc = ((NvU64)kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACEPC_HI) << 32ull) |
kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACEPC_LO);
@@ -446,7 +468,7 @@ kflcnDumpTracepc_GA102
NV_STATUS kflcnCoreDumpPc_GA102(OBJGPU *pGpu, KernelFalcon *pKernelFlcn, NvU64 *pc)
{
//
//
// This code originally handled 0xbadfxxxx values and returned failure,
// however we may want to see badf values so it is now wired to return the read
// register always. We want to also ensure any automated processing will know to
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2017-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2017-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -845,37 +845,57 @@ kflcnDumpTracepc_TU102
NvU64 pc;
NvU32 ctl;
NvU32 r, w, size;
NvU32 capacity;
NvU32 entry;
NvU32 count;
NvBool bFull = NV_FALSE;
r = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_RDIDX);
w = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_WTIDX);
size = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _MAXIDX, r);
if (size > __RISCV_MAX_TRACE_ENTRIES)
// __RISCV_MAX_TRACE_ENTRIES is 64, this is the entry count allocated for pCore->tracePC[]
if (size > (__RISCV_MAX_TRACE_ENTRIES - 1))
{
NV_PRINTF(LEVEL_ERROR, "Trace buffer larger than expected. Bailing!\n");
return;
}
r = DRF_VAL(_PRISCV_RISCV, _TRACE_RDIDX, _RDIDX, r);
if (r > size)
{
return;
}
w = DRF_VAL(_PRISCV_RISCV, _TRACE_WTIDX, _WTIDX, w);
ctl = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACECTL);
if ((w == r) && (DRF_VAL(_PRISCV_RISCV, _TRACECTL, _FULL, ctl) == 0))
if (w > size)
{
count = 0;
return;
}
ctl = kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACECTL);
capacity = size + 1U;
if (DRF_VAL(_PRISCV_RISCV, _TRACECTL, _FULL, ctl))
{
bFull = NV_TRUE;
}
if (bFull)
{
//
// FULL indicates that the ring has wrapped at least once. All slots
// therefore contain valid trace entries, regardless of the indices.
//
count = capacity;
}
else
{
//
// The number of entries in trace buffer is how far the w (put) pointer
// is ahead of the r (get) pointer. If this value is negative, add
// the size of the circular buffer to bring the element count back into range.
//
count = w > r ? w - r : w - r + size;
// WTIDX is the next write position; valid entries are [RDIDX, WTIDX).
count = (w + capacity - r) % capacity;
}
pCore->tracePCEntries = count;
@@ -884,9 +904,11 @@ kflcnDumpTracepc_TU102
{
for (entry = 0; entry < count; ++entry)
{
if (entry > w)
w += size;
kflcnRiscvRegWrite_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACE_RDIDX, w - entry);
NvU32 index = (w + capacity - 1U - entry) % capacity;
// The stored trace is newest-to-oldest ordering
kflcnRiscvRegWrite_HAL(pGpu, pKernelFlcn,
NV_PRISCV_RISCV_TRACE_RDIDX, index);
pc = ((NvU64)kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACEPC_HI) << 32ull) |
kflcnRiscvRegRead_HAL(pGpu, pKernelFlcn, NV_PRISCV_RISCV_TRACEPC_LO);
+1 -1
View File
@@ -32,6 +32,7 @@
#include "platform/platform.h"
#include "platform/chipset/chipset.h"
#include "gpu/bif/kernel_bif.h"
#include "gpu/bus/kern_bus.h"
#include "gpu/mem_mgr/mem_mgr.h"
#include "gpu/mem_mgr/fbsr.h"
#include "gpu/gsp/gsp_init_args.h"
@@ -575,7 +576,6 @@ gpuEnterStandby_IMPL(OBJGPU *pGpu)
pGpu->setProperty(pGpu, PDB_PROP_GPU_IN_PM_CODEPATH, NV_TRUE);
gpuNotifySubDeviceEvent(pGpu, NV2080_NOTIFIERS_POWER_SUSPEND, NULL, 0, 0, 0);
suspendStatus = gpuPowerManagementEnter(pGpu, NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3, GPU_STATE_FLAGS_PM_SUSPEND);
pGpu->setProperty(pGpu, PDB_PROP_GPU_IN_STANDBY, NV_TRUE);
@@ -114,6 +114,7 @@ gpushareddataConstruct_IMPL
OBJGPU *pGpu = pMemory->pGpu; // pGpu is initialized in the Memory class constructor
MEMORY_DESCRIPTOR **ppMemDesc = &(pGpu->userSharedData.pMemDesc);
NV00DE_ALLOC_PARAMETERS *pAllocParams = (NV00DE_ALLOC_PARAMETERS*)(pParams->pAllocParams);
NvU32 attr2 = 0;
NV_ASSERT_OR_RETURN(!RMCFG_FEATURE_PLATFORM_GSP, NV_ERR_NOT_SUPPORTED);
@@ -140,7 +141,7 @@ gpushareddataConstruct_IMPL
}
NV_ASSERT_OK_OR_RETURN(memConstructCommon(pMemory,
NV01_MEMORY_SYSTEM, 0, *ppMemDesc, 0, NULL, 0, 0, 0, 0,
NV01_MEMORY_SYSTEM, 0, *ppMemDesc, 0, NULL, 0, attr2, 0, 0,
NVOS32_MEM_TAG_NONE, NULL));
memdescAddRef(pGpu->userSharedData.pMemDesc);
@@ -23,6 +23,7 @@
#define NVOC_KERNEL_SM_DEBUGGER_SESSION_H_PRIVATE_ACCESS_ALLOWED
#include "kernel/os/os.h"
#include "kernel/core/locks.h"
#include "kernel/gpu/gr/kernel_sm_debugger_session.h"
@@ -55,6 +56,7 @@
} while (0);
static NV_STATUS _ShareDebugger(KernelSMDebuggerSession *, RsResourceRef *, RsResourceRef *);
static void _ksmdbgssnCleanup(KernelSMDebuggerSession *, OBJGPU *, NvBool);
void
dbgSessionRemoveDependant_IMPL
@@ -209,6 +211,33 @@ failed:
return status;
}
static void
_ksmdbgssnCleanup
(
KernelSMDebuggerSession *pKernelSMDebuggerSession,
OBJGPU *pGpu,
NvBool bRegistered
)
{
RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
if (bRegistered ||
(pKernelSMDebuggerSession->hInternalClient != NV01_NULL_OBJECT))
{
pRmApi->Free(pRmApi,
pKernelSMDebuggerSession->hInternalClient,
pKernelSMDebuggerSession->hInternalClient);
}
if (bRegistered)
{
kgrctxDeregisterKernelSMDebuggerSession(pGpu,
kgrobjGetKernelGraphicsContext(pGpu, pKernelSMDebuggerSession->pObject),
pKernelSMDebuggerSession);
}
}
NV_STATUS
ksmdbgssnConstruct_IMPL
(
@@ -350,6 +379,7 @@ ksmdbgssnConstruct_IMPL
_ShareDebugger(pKernelSMDebuggerSession, pCallContext->pResourceRef, pGrResourceRef));
return status;
}
/**
@@ -444,15 +474,9 @@ ksmdbgssnFreeCallback_IMPL
KernelSMDebuggerSession *pKernelSMDebuggerSession
)
{
RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
OBJGPU *pGpu = GPU_RES_GET_GPU(pKernelSMDebuggerSession);
// This should free the entire hierarchy of objects.
pRmApi->Free(pRmApi, pKernelSMDebuggerSession->hInternalClient, pKernelSMDebuggerSession->hInternalClient);
// Remove it from the pObject debugger list
kgrctxDeregisterKernelSMDebuggerSession(pGpu, kgrobjGetKernelGraphicsContext(pGpu, pKernelSMDebuggerSession->pObject), pKernelSMDebuggerSession);
_ksmdbgssnCleanup(pKernelSMDebuggerSession, pGpu, NV_TRUE);
}
NV_STATUS
@@ -112,7 +112,7 @@ intrGetIntrTopNonStallMask_GH100
Intr *pIntr
)
{
// TODO Bug 3823562 Remove all these asserts
// TODO Bug 3823562: Remove all these asserts
// Compile-time assert against the highest set bit that will be returned
#define NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_SUBTREE(5)
@@ -120,6 +120,8 @@ intrGetIntrTopNonStallMask_GH100
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_SET__SIZE_1);
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_CLEAR__SIZE_1);
// Guarantee that there is only one INTR_TOP for intrGetPendingNonStall_TU102
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < 32);
NvU64 mask = 0;
mask |= intrGetIntrTopCategoryMask(pIntr,
@@ -204,6 +204,7 @@ intrGetPendingNonStall_TU102
NvU32 i, j;
NvU32 pending;
NvU32 intrVector;
NvU64 topNonStallMask;
NV_ASSERT_OR_RETURN(pEngines != NULL, NV_ERR_INVALID_ARGUMENT);
@@ -226,11 +227,15 @@ intrGetPendingNonStall_TU102
NV_ASSERT_OK_OR_RETURN(intrGetInterruptTable_HAL(pGpu, pIntr, &pIntrTable));
FOR_EACH_INDEX_IN_MASK(64, i, intrGetIntrTopNonStallMask_HAL(pGpu, pIntr))
topNonStallMask = intrGetIntrTopNonStallMask_HAL(pGpu, pIntr);
// Only INTR_TOP_0 is ever read
// guaranteed by ct_asserts in intrGetIntrTopNonStallMask*
pending = intrReadRegTop_HAL(pGpu, pIntr, 0, pThreadState);
FOR_EACH_INDEX_IN_MASK(64, i, topNonStallMask)
{
j = NV_CTRL_INTR_SUBTREE_TO_TOP_IDX(i);
// TODO Bug 3823562: optimize this and don't read on every loop
pending = intrReadRegTop_HAL(pGpu, pIntr, j, pThreadState);
// i is never greater than 32 - see above
if ((pending & (NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_TOP_SUBTREE_INTR_PENDING << NV_CTRL_INTR_SUBTREE_TO_TOP_BIT(i))) == 0)
{
@@ -719,7 +719,7 @@ intrIsPending_TU102
* for a generic interface that works across generations and doesn't expose the
* intrVector to the module. Extenuating circumstances, such as the interrupt
* table not being initialized, can still use this.
*
*
*
* @param[in] pGpu OBJGPU pointer
* @param[in] pIntr Intr pointer
@@ -843,11 +843,19 @@ _intrGetLeafStatus_TU102
{
NvU32 subtreeIndex;
NvU32 leafIndex;
NvU32 lastLeafIndex;
FOR_EACH_INDEX_IN_MASK(64, subtreeIndex,
intrGetIntrTopLegacyStallMask_HAL(pIntr))
{
//
// The leafIndex and lastLeafIndex is computed from legacy stall tree.
// RM ensure that these two numbers are less than NV_MAX_INTR_LEAVES before.
// calling into this function.
//
leafIndex = NV_CTRL_INTR_SUBTREE_TO_LEAF_IDX_START(subtreeIndex);
lastLeafIndex = NV_CTRL_INTR_SUBTREE_TO_LEAF_IDX_END(subtreeIndex);
if (pIntr->getProperty(pIntr, PDB_PROP_INTR_READ_ONLY_EVEN_NUMBERED_INTR_LEAF_REGS))
{
//
@@ -865,7 +873,7 @@ _intrGetLeafStatus_TU102
}
else
{
for (; leafIndex <= NV_CTRL_INTR_SUBTREE_TO_LEAF_IDX_END(subtreeIndex); leafIndex++)
for (; leafIndex <= lastLeafIndex; leafIndex++)
{
if ((leafIndex == 4) && bUseCachedRegVal)
{
@@ -924,7 +932,12 @@ intrGetPendingStallEngines_TU102
return NV_OK;
}
NV_ASSERT_OK_OR_RETURN(_intrGetLeafStatus_TU102(pGpu, pIntr, bUseCachedRegVal, cachedStaticRegVal, intrLeafValues, pThreadState));
NV_ASSERT_OK_OR_RETURN(_intrGetLeafStatus_TU102(pGpu,
pIntr,
bUseCachedRegVal,
cachedStaticRegVal,
intrLeafValues,
pThreadState));
NV_ASSERT_OK_OR_RETURN(intrGetInterruptTable_HAL(pGpu, pIntr, &pIntrTable));
for (iter = vectIterAll(pIntrTable); vectIterNext(&iter);)
@@ -1507,6 +1520,9 @@ intrGetIntrTopNonStallMask_TU102
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_SET__SIZE_1);
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < NV_VIRTUAL_FUNCTION_PRIV_CPU_INTR_LEAF_EN_CLEAR__SIZE_1);
// Guarantee that there is only one INTR_TOP for intrGetPendingNonStall_TU102
ct_assert(NV_CPU_INTR_NOSTALL_SUBTREE_HIGHEST < 32);
NvU64 mask = intrGetIntrTopCategoryMask(pIntr,
NV2080_INTR_CATEGORY_ESCHED_DRIVEN_ENGINE_NOTIFICATION);
+66 -2
View File
@@ -280,7 +280,7 @@ subdeviceCtrlCmdMcServiceInterrupts_IMPL
}
intrServiceStallList_HAL(pGpu, pIntr, &engines, NV_TRUE);
return NV_OK;
}
@@ -1015,6 +1015,66 @@ intrSaveIntrEn0FromHw_IMPL
pIntr->saveIntrEn0 = intrGetIntrEnFromHw_HAL(pGpu, pIntr, NULL /* threadState */);
}
/*!
* @brief Validate a GSP-provided interrupt category-to-subtree mapping.
*
* Each interrupt subtree maps to two leaf registers. This function derives
* the number of complete subtrees from the total CPU interrupt leaf capacity
* and rejects any category mask that would select an unimplemented leaf.
*
* @param[in] pGpu GPU object pointer.
* @param[in] pIntr Interrupt object pointer.
* @param[in] pSubtreeMap Category-to-subtree mapping received from GSP-RM.
*
* @return NV_OK if every subtree mask is within the supported range.
* @return NV_ERR_OUT_OF_RANGE if the leaf count or any subtree mask is invalid.
*/
static NV_STATUS
_intrValidateKernelSubtreeMap
(
OBJGPU *pGpu,
Intr *pIntr,
const NV2080_INTR_CATEGORY_SUBTREE_MAP *pSubtreeMap
)
{
NvU32 numLeavesCapacity = intrGetLeafSize_HAL(pGpu, pIntr);
NvU32 numIntrLeaves = intrGetNumLeaves_HAL(pGpu, pIntr);
NvU32 numSubtrees;
NvU64 validSubtreeMask;
NvU32 category;
NV_ASSERT_OR_RETURN(
(numLeavesCapacity != 0) && (numIntrLeaves != 0) &&
(numIntrLeaves <= numLeavesCapacity) && (numLeavesCapacity <= NV_MAX_INTR_LEAVES),
NV_ERR_OUT_OF_RANGE);
//
// Each complete subtree maps to two leaf registers. Do not accept a
// subtree unless both of its leaves fit in the CPU-side destination.
//
numSubtrees = NV_CTRL_INTR_LEAF_IDX_TO_SUBTREE(numLeavesCapacity);
validSubtreeMask = NVBIT64(numSubtrees) - 1U;
for (category = 0;
category < NV2080_INTR_CATEGORY_ENUM_COUNT;
category++)
{
NvU64 subtreeMask = pSubtreeMap[category].subtreeMask;
if ((subtreeMask & ~validSubtreeMask) != 0U)
{
NV_PRINTF(LEVEL_ERROR,
"Invalid interrupt subtree map: category %u, "
"mask 0x%llx, valid mask 0x%llx\n",
category, subtreeMask, validSubtreeMask);
return NV_ERR_OUT_OF_RANGE;
}
}
return NV_OK;
}
NV_STATUS
intrInitInterruptTable_KERNEL
(
@@ -1051,6 +1111,10 @@ intrInitInterruptTable_KERNEL
NV_ERR_OUT_OF_RANGE,
exit);
NV_ASSERT_OK_OR_GOTO(status,
_intrValidateKernelSubtreeMap(pGpu, pIntr, pParams->subtreeMap),
exit);
NV_ASSERT_OK_OR_GOTO(status,
vectReserve(&pIntr->intrTable, pParams->tableLen),
exit);
@@ -1319,7 +1383,7 @@ void intrProcessDPCQueue_IMPL
do
{
NvU64 startTime, endTime;
NvU64 startTime, endTime;
osGetPerformanceCounter(&startTime);
bitVectorClrAll(&pendingEngines);
if (!intrIsDpcQueueEmpty(pGpu, pIntr, pDPCQueue))
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -29,42 +29,6 @@
#include "containers/eheap_old.h"
static NV_STATUS _memmgrSocGetScanoutCarveout
(
OBJGPU *pGpu,
NvU64 *pBase,
NvU64 *pSize
)
{
MemoryManager *pMemoryManager = GPU_GET_MEMORY_MANAGER(pGpu);
NV_STATUS status;
NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS params;
NvU32 i;
portMemSet(&params, 0x0, sizeof(params));
status = memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, &params);
if (status != NV_OK)
{
return status;
}
*pBase = *pSize = 0;
for (i = 0; i < params.numCarveoutRegions; i++)
{
// On Linux, the complete display FRM will be managed by RM carveout code.
if (params.carveoutRegion[i].carveoutType ==
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_DISPLAY_FRM)
{
*pBase = params.carveoutRegion[i].base;
*pSize = params.carveoutRegion[i].size;
break;
}
}
return NV_OK;
}
/**
* @brief Initializes FB regions
*
@@ -127,9 +91,30 @@ memmgrCreateScanoutCarveoutHeap_GB10B
MemoryManager *pMemoryManager
)
{
NvU64 base, size;
NV2080_CTRL_FB_GET_CARVEOUT_REGION_INFO_PARAMS params;
NvU64 base = 0, size = 0;
NvU32 i;
if (_memmgrSocGetScanoutCarveout(pGpu, &base, &size) != NV_OK) {
portMemSet(&params, 0x0, sizeof(params));
if (memmgrGetCarveoutRegionInfo(pGpu, pMemoryManager, &params) != NV_OK)
{
pGpu->setProperty(pGpu, PDB_PROP_GPU_ALLOC_ISO_SYS_MEM_FROM_CARVEOUT, NV_FALSE);
return NV_OK;
}
for (i = 0; i < params.numCarveoutRegions; i++)
{
if (params.carveoutRegion[i].carveoutType ==
NV2080_CTRL_FB_GET_CARVEOUT_REGION_CARVEOUT_TYPE_DISPLAY_FRM)
{
base = params.carveoutRegion[i].base;
size = params.carveoutRegion[i].size;
break;
}
}
if (size == 0)
{
pGpu->setProperty(pGpu, PDB_PROP_GPU_ALLOC_ISO_SYS_MEM_FROM_CARVEOUT, NV_FALSE);
return NV_OK;
}
@@ -154,7 +139,6 @@ memmgrDestroyScanoutCarveoutHeap_GB10B
MemoryManager *pMemoryManager
)
{
if (pMemoryManager->pScanoutHeap)
{
pMemoryManager->pScanoutHeap->eheapDestruct(pMemoryManager->pScanoutHeap);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 1993-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -52,7 +52,6 @@ memmgrSavePowerMgmtState_KERNEL
OBJFBSR *pFbsr;
NV_STATUS rmStatus = NV_OK;
if (pGpu->pGpuArch->bGpuArchIsZeroFb ||
pGpu->getProperty(pGpu, PDB_PROP_GPU_BROKEN_FB))
{
@@ -239,7 +238,6 @@ memmgrRestorePowerMgmtState_KERNEL
NvBool bIsGpuLost = NV_FALSE;
RM_API *pRmApi = rmapiGetInterface(RMAPI_GPU_LOCK_INTERNAL);
if (pGpu->pGpuArch->bGpuArchIsZeroFb ||
pGpu->getProperty(pGpu, PDB_PROP_GPU_BROKEN_FB))
{
@@ -1316,7 +1316,7 @@ static NvS64 _scanContiguousSearchLoopReverse
)
{
NvU64 realAlign = (frameAlignmentPadding + numFrames) & (frameAlignment - 1ll);
NvU64 frameBaseIdx = alignDownToMod(localEnd + 1llu, frameAlignment, realAlign);
NvU64 frameBaseIdx;
NvU64 localizedFrameBase = pRegmap->localizedFrameBase;
NvU64 localizedFrameCount = pRegmap->localizedFrameCount;
@@ -1328,6 +1328,8 @@ static NvS64 _scanContiguousSearchLoopReverse
//
NvU64 latestFree[PMA_BITS_PER_PAGE];
NvU64 i;
frameBaseIdx = alignDownToMod(localEnd + 1ULL, frameAlignment, realAlign);
for (i = 0; i < PMA_BITS_PER_PAGE; i++)
{
latestFree[i] = frameBaseIdx;
@@ -1723,7 +1725,7 @@ _scanDiscontiguousSearchLoopReverse
)
{
NvU64 realAlign = (frameAlignmentPadding + framesPerPage) & (frameAlignment - 1ll);
NvU64 frameBaseIdx = alignDownToMod(localEnd+1llu, frameAlignment, realAlign);
NvU64 frameBaseIdx;
NvU64 localizedFrameBase = pRegmap->localizedFrameBase;
NvU64 localizedFrameCount = pRegmap->localizedFrameCount;
@@ -1740,6 +1742,8 @@ _scanDiscontiguousSearchLoopReverse
NvBool bEvictablePage = NV_FALSE;
NvU64 i;
frameBaseIdx = alignDownToMod(localEnd + 1ULL, frameAlignment, realAlign);
for (i = 0; i < PMA_BITS_PER_PAGE; i++)
{
latestFree[i] = frameBaseIdx;
@@ -323,32 +323,27 @@ kmemsysStatePostLoad_IMPL
}
//
// GB20Y iGPU family (GB20B...): After the ACR HW scrubber zeros the CBC
// backing store in DRAM, invalidate the L2 cache (including the CBC
// comptag cache) so the LTC discards any stale entries and re-reads
// from the clean backing store on first access.
// Bug 5947582 / Bug 6760855: SOC SDM iGPUs (GB10B/GB20B/GB20C and
// future) — invalidate the L2 cache (including the CBC comptag cache)
// on every StatePostLoad so the LTC discards stale entries and re-reads
// from the CBC SR backing store in DRAM.
//
// gpuRequiresCbcSrScrub_HAL returns NV_TRUE for GB20Y... chips on
// coldboot, FLR, hibernate-resume, and driver reload — exactly the
// scenarios where ACR scrubs the CBC SR region. It returns NV_FALSE
// for sleep resume and GC6 exit (state preserved) and for all other
// chip families (default HAL returns NV_FALSE).
// This covers coldboot, FLR, hibernate-resume, driver reload, AND sleep
// resume. HW DRIPS power-gates the LTC SRAM during sleep, destroying
// CBC content, so the invalidation is needed on every resume path.
//
// Pure invalidate (FLAGS_ALL without FLAGS_CLEAN) so we discard L2
// entries rather than writing potentially stale data back to DRAM.
//
if (pGpu->getProperty(pGpu, PDB_PROP_GPU_IS_SOC_SDM))
{
NvBool bCbcScrub = gpuRequiresCbcSrScrub_HAL(pGpu);
if (bCbcScrub)
NV_STATUS l2Status;
l2Status = kmemsysSendL2InvalidateEvict(pGpu, pKernelMemorySystem,
NV2080_CTRL_INTERNAL_MEMSYS_L2_INVALIDATE_EVICT_FLAGS_ALL);
if (l2Status != NV_OK)
{
NV_STATUS l2Status;
l2Status = kmemsysSendL2InvalidateEvict(pGpu, pKernelMemorySystem,
NV2080_CTRL_INTERNAL_MEMSYS_L2_INVALIDATE_EVICT_FLAGS_ALL);
if (l2Status != NV_OK)
{
NV_PRINTF(LEVEL_WARNING,
"L2 CBC cache invalidate failed: 0x%x\n", l2Status);
}
NV_PRINTF(LEVEL_WARNING,
"L2 CBC cache invalidate failed: 0x%x\n", l2Status);
}
}
@@ -54,7 +54,6 @@ cisubscriptionConstruct_IMPL
)
{
NVC638_ALLOCATION_PARAMETERS *pUserParams = pRmAllocParams->pAllocParams;
RsClient *pRsClient = pCallContext->pClient;
RsResourceRef *pResourceRef = pCallContext->pResourceRef;
RsResourceRef *pParentRef = pResourceRef->pParentRef;
GPUInstanceSubscription *pGPUInstanceSubscription = dynamicCast(pParentRef->pResource, GPUInstanceSubscription);
@@ -82,21 +81,27 @@ cisubscriptionConstruct_IMPL
pMIGComputeInstance = &gisubscriptionGetMIGGPUInstance(pGPUInstanceSubscription)->MIGComputeInstance[pUserParams->execPartitionId];
NV_CHECK_OR_RETURN(LEVEL_SILENT, pMIGComputeInstance->bValid, NV_ERR_INVALID_ARGUMENT);
//
// For now skip kernel clients, such as UVM, until Bug 2729768 is fixed.
//
if (pRsClient->type == CLIENT_TYPE_USER)
{
status = osRmCapAcquire(pMIGComputeInstance->pOsRmCaps,
NV_RM_CAP_SMC_EXEC_PARTITION_ACCESS,
pUserParams->capDescriptor,
&pComputeInstanceSubscription->dupedCapDescriptor);
if ((status != NV_ERR_NOT_SUPPORTED) && (status != NV_OK))
RsClient *pRsClient = pCallContext->pClient;
//
// Capability descriptors are validated in Client/CPU-RM before the
// subscription request is forwarded to physical GSP-RM.
// For now skip kernel clients, such as UVM, until Bug 2729768 is fixed.
//
if (pRsClient->type == CLIENT_TYPE_USER)
{
NV_PRINTF(LEVEL_ERROR,
"Capability validation failed: ID 0x%08x!\n",
pUserParams->execPartitionId);
return status;
status = osRmCapAcquire(pMIGComputeInstance->pOsRmCaps,
NV_RM_CAP_SMC_EXEC_PARTITION_ACCESS,
pUserParams->capDescriptor,
&pComputeInstanceSubscription->dupedCapDescriptor);
if ((status != NV_ERR_NOT_SUPPORTED) && (status != NV_OK))
{
NV_PRINTF(LEVEL_ERROR,
"Capability validation failed: ID 0x%08x!\n",
pUserParams->execPartitionId);
return status;
}
}
}
@@ -210,7 +210,11 @@ gisubscriptionConstruct_IMPL
kmigmgrGetGPUInstanceInfo(pGpu, pKernelMIGManager, swizzId,
&pGPUInstanceSubscription->pKernelMIGGpuInstance));
//
// Capability descriptors are validated in Client/CPU-RM before the
// subscription request is forwarded to physical GSP-RM.
// For now skip kernel clients, such as UVM, until Bug 2729768 is fixed.
//
if (pRsClient->type == CLIENT_TYPE_USER)
{
status = osRmCapAcquire(pGPUInstanceSubscription->pKernelMIGGpuInstance->pOsRmCaps,
@@ -73,8 +73,11 @@ _mnocBufferPoolDestruct
KoobMnocBufferPool *pPool
)
{
portSyncSpinlockDestroy(pPool->pBufSpinLock);
pPool->pBufSpinLock = NULL;
if (pPool->pBufSpinLock != NULL)
{
portSyncSpinlockDestroy(pPool->pBufSpinLock);
pPool->pBufSpinLock = NULL;
}
}
NV_STATUS
@@ -87,6 +90,8 @@ koobStateLoad_GB100
{
NV_ASSERT_OK_OR_RETURN(_mnocBufferPoolConstruct(&pKernelOob->mnocBufferPool));
koobDriverStartupNotify(pGpu, pKernelOob);
pKernelOob->bLoaded = NV_TRUE;
return NV_OK;
}
@@ -98,8 +103,13 @@ koobStateUnload_GB100
NvU32 flags
)
{
koobDriverShutdownNotify(pGpu, pKernelOob);
_mnocBufferPoolDestruct(&pKernelOob->mnocBufferPool);
if (pKernelOob->bLoaded)
{
koobDriverShutdownNotify(pGpu, pKernelOob);
_mnocBufferPoolDestruct(&pKernelOob->mnocBufferPool);
pKernelOob->bLoaded = NV_FALSE;
}
return NV_OK;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -24,6 +24,7 @@
/* ------------------------ Includes --------------------------------------- */
#include "ctrl/ctrl2080/ctrl2080clk.h"
#include "ctrl/ctrl2080/ctrl2080perf.h"
#include "os/os.h"
#include "gpu/subdevice/subdevice.h"
#include "rmapi/rmapi.h"
@@ -101,7 +102,8 @@ subdeviceCtrlCmdPerfGetGpumonPerfmonUtilSamplesV2_KERNEL
OBJGPU *pGpu = GPU_RES_GET_GPU(pSubdevice);
RM_API *pRmApi = GPU_GET_PHYSICAL_RMAPI(pGpu);
NV2080_CTRL_PERF_GPUMON_PERFMON_UTIL_SAMPLE *pSample;
NvU32 numEntries, index, nsPid;
NvU32 numEntries, index;
NvU32 nsPid;
if (pGpu->getProperty(pGpu, PDB_PROP_GPU_CLKS_IN_TEGRA_SOC))
{
@@ -116,7 +118,7 @@ subdeviceCtrlCmdPerfGetGpumonPerfmonUtilSamplesV2_KERNEL
pParams,
sizeof(*pParams)));
// Skip translation if the request from root namespace.
// Skip translation if the request is from the root namespace.
if (osIsInitNs())
return NV_OK;
@@ -23,6 +23,7 @@
/* ------------------------ Includes --------------------------------------- */
#include "os/os.h"
#include "gpu/subdevice/subdevice.h"
#include "rmapi/rmapi.h"
#include "rmapi/rs_utils.h"
@@ -36,6 +37,7 @@
/* ------------------------ Static Function Prototypes --------------------- */
/* ------------------------ Macros ----------------------------------------- */
/* ------------------------ Public Functions ------------------------------- */
/*!
* @brief Retrieving the current requested RATED_TDP action corresponding
* to the specified client.
+2
View File
@@ -487,7 +487,9 @@ memConstructCommon_IMPL
{
status = memRegisterWithGsp(pGpu, RES_GET_CLIENT(pMemory), hParent, hMemory);
if (status != NV_OK)
{
goto done;
}
}
// Initialize the circular list item for tracking dup/sharing of pMemDesc
-1
View File
@@ -510,7 +510,6 @@ continue_alloc_object:
}
pPteArray = memdescGetPteArray(pMemDesc, AT_GPU);
// copy in the pages
// copy in the pages
status = rmapiParamsCopyIn(NULL,
pPteArray,
pAllocParams->pageNumberList,
@@ -41,6 +41,35 @@
#include "class/cl003e.h" // NV01_MEMORY_SYSTEM
static NV_STATUS
_sysmemScrubScanoutCarveout
(
MEMORY_DESCRIPTOR *pMemDesc
)
{
void *pMap;
NV_ASSERT_OR_RETURN(memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT),
NV_ERR_INVALID_ARGUMENT);
NV_ASSERT_OR_RETURN(memdescGetContiguity(pMemDesc, AT_CPU), NV_ERR_INVALID_STATE);
pMap = osMapKernelSpace(memdescGetPhysAddr(pMemDesc, AT_CPU, 0),
pMemDesc->Size,
memdescGetCpuCacheAttrib(pMemDesc),
NV_PROTECT_READ_WRITE);
if (pMap == NULL)
{
NV_PRINTF(LEVEL_ERROR,
"Failed to map scanout carveout allocation for CPU scrub\n");
return NV_ERR_INVALID_STATE;
}
portMemSet(pMap, 0, pMemDesc->Size);
osUnmapKernelSpace(pMap, pMemDesc->Size);
return NV_OK;
}
static NvU64
_sysmemGetNextSmallestPageSize
(
@@ -389,6 +418,9 @@ sysmemConstruct_IMPL
NV_CHECK_OK_OR_GOTO(rmStatus, LEVEL_ERROR, rmStatus, failed_destroy_memdesc);
rmStatus = _sysmemScrubScanoutCarveout(pMemDesc);
NV_CHECK_OK_OR_GOTO(rmStatus, LEVEL_ERROR, rmStatus, failed_free_scanout_carveout);
sizeOut = pMemDesc->Size;
pAllocData->limit = sizeOut - 1;
}
@@ -584,6 +616,7 @@ sysmemConstruct_IMPL
{
// UNLOCK: release GPUs lock
rmDeviceGpuLocksRelease(pGpu, GPUS_LOCK_FLAGS_NONE, NULL);
bLockAcquired = NV_FALSE;
}
return rmStatus;
@@ -596,10 +629,17 @@ failed_free_memdesc:
{
// UNLOCK: release GPUs lock
rmDeviceGpuLocksRelease(pGpu, GPUS_LOCK_FLAGS_NONE, NULL);
bLockAcquired = NV_FALSE;
}
memdescFree(pMemDesc);
failed_free_scanout_carveout:
if (bLockAcquired)
{
// UNLOCK: release GPUs lock
rmDeviceGpuLocksRelease(pGpu, GPUS_LOCK_FLAGS_NONE, NULL);
bLockAcquired = NV_FALSE;
}
if (memdescGetFlag(pMemDesc, MEMDESC_FLAGS_ALLOC_FROM_SCANOUT_CARVEOUT)) {
memmgrFreeScanoutCarveoutRegionResources(GPU_GET_MEMORY_MANAGER(pGpu),
memdescGetPte(pMemDesc, AT_CPU, 0));
+1
View File
@@ -378,6 +378,7 @@ eventapiInit_IMPL
rmStatus = serverGetClientUnderLock(&g_resServ, hNotifierClient, &pNotifierClient);
if (rmStatus != NV_OK)
return rmStatus;
}
else
{
+1
View File
@@ -11275,6 +11275,7 @@ NV_STATUS rpcCtrlCmdNvlinkInbandSendData_v26_05
rpc_params->dataSize = pParams->dataSize;
portMemCopy(rpc_params->buffer, rpc_params->dataSize, pParams->buffer, pParams->dataSize);
status = _issueRpcAndWait(pGpu, pRpc);
return status;
@@ -788,7 +788,9 @@ refAddDependant
if (status != NV_OK)
return status;
return indexAdd(&pResourceRef->depRefMap, pDependantRef->internalClassId, pDependantRef);
status = indexAdd(&pResourceRef->depRefMap, pDependantRef->internalClassId, pDependantRef);
return status;
}
void
@@ -48,6 +48,9 @@ enum CLIENT_LIST_LOCK_STATE
CLIENT_LIST_LOCK_UNLOCKED,
};
#if RS_STANDALONE_TEST
#endif // RS_STANDALONE_TEST
/**
* Get the RsClient from a client handle without taking locks
* @param[in] pServer
@@ -1255,6 +1258,8 @@ serverFreeResourceTree
pClientEntry = NULL;
serverTopLock_Epilogue(pServer, firstTopLockAccess, pLockInfo, &releaseFlags);
#if RS_STANDALONE_TEST
#endif // RS_STANDALONE_TEST
status = serverFreeResourceTreeLockAndFindResource(pServer, pParams, topLockAccess,
&releaseFlags, &pClientEntry, &pResourceRef);
if ((status != NV_OK) || (pResourceRef == NULL))
+2 -2
View File
@@ -1,5 +1,5 @@
NVIDIA_VERSION = 615.71.09
NVIDIA_NVID_VERSION = 615.71.09
NVIDIA_VERSION = 615.78.08
NVIDIA_NVID_VERSION = 615.78.08
NVIDIA_NVID_EXTRA =
# This file.