Unverified Commit 98553501 authored by Andy Ritger's avatar Andy Ritger
Browse files

515.65.01

parent 1e2a1b5f
......@@ -2,6 +2,13 @@
## Release 515 Entries
### [515.65.01] 2022-08-02
#### Fixed
- Collection of minor fixes to issues, [#6](https://github.com/NVIDIA/open-gpu-kernel-modules/pull/61) by @Joshua-Ashton
- Remove unnecessary use of acpi_bus_get_device().
### [515.57] 2022-06-28
#### Fixed
......
# NVIDIA Linux Open GPU Kernel Module Source
This is the source release of the NVIDIA Linux open GPU kernel modules,
version 515.57.
version 515.65.01.
## How to Build
......@@ -17,7 +17,7 @@ as root:
Note that the kernel modules built here must be used with gsp.bin
firmware and user-space NVIDIA GPU driver components from a corresponding
515.57 driver release. This can be achieved by installing
515.65.01 driver release. This can be achieved by installing
the NVIDIA GPU driver from the .run file using the `--no-kernel-modules`
option. E.g.,
......@@ -167,7 +167,7 @@ for the target kernel.
## Compatible GPUs
The open-gpu-kernel-modules can be used on any Turing or later GPU
(see the table below). However, in the 515.57 release,
(see the table below). However, in the 515.65.01 release,
GeForce and Workstation support is still considered alpha-quality.
To enable use of the open kernel modules on GeForce and Workstation GPUs,
......@@ -175,7 +175,7 @@ set the "NVreg_OpenRmEnableUnsupportedGpus" nvidia.ko kernel module
parameter to 1. For more details, see the NVIDIA GPU driver end user
README here:
https://us.download.nvidia.com/XFree86/Linux-x86_64/515.57/README/kernel_open.html
https://us.download.nvidia.com/XFree86/Linux-x86_64/515.65.01/README/kernel_open.html
In the below table, if three IDs are listed, the first is the PCI Device
ID, the second is the PCI Subsystem Vendor ID, and the third is the PCI
......@@ -704,6 +704,8 @@ Subsystem Device ID.
| NVIDIA RTX A5500 | 2233 10DE 165A |
| NVIDIA RTX A5500 | 2233 17AA 165A |
| NVIDIA A40 | 2235 10DE 145A |
| NVIDIA A10 | 2236 10DE 1482 |
| NVIDIA A10G | 2237 10DE 152F |
| NVIDIA A10M | 2238 10DE 1677 |
| NVIDIA GeForce RTX 3060 Ti | 2414 |
| NVIDIA GeForce RTX 3080 Ti Laptop GPU | 2420 |
......
......@@ -72,7 +72,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc
EXTRA_CFLAGS += -I$(src)
EXTRA_CFLAGS += -Wall -MD $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error -Wno-format-extra-args
EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"515.57\"
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"515.65.01\"
EXTRA_CFLAGS += -Wno-unused-function
......
......@@ -989,6 +989,7 @@ NvBool NV_API_CALL rm_disable_iomap_wc(void);
void NV_API_CALL rm_init_dynamic_power_management(nvidia_stack_t *, nv_state_t *, NvBool);
void NV_API_CALL rm_cleanup_dynamic_power_management(nvidia_stack_t *, nv_state_t *);
void NV_API_CALL rm_enable_dynamic_power_management(nvidia_stack_t *, nv_state_t *);
NV_STATUS NV_API_CALL rm_ref_dynamic_power(nvidia_stack_t *, nv_state_t *, nv_dynamic_power_mode_t);
void NV_API_CALL rm_unref_dynamic_power(nvidia_stack_t *, nv_state_t *, nv_dynamic_power_mode_t);
NV_STATUS NV_API_CALL rm_transition_dynamic_power(nvidia_stack_t *, nv_state_t *, NvBool);
......
......@@ -5288,22 +5288,6 @@ compile_test() {
rm -f conftest$$.c
;;
acpi_bus_get_device)
#
# Determine if the acpi_bus_get_device() function is present
#
# acpi_bus_get_device() was removed by commit ac2a3feefad5
# ("ACPI: bus: Eliminate acpi_bus_get_device()") in
# v5.18-rc2 (2022-04-05).
#
CODE="
#include <linux/acpi.h>
int conftest_acpi_bus_get_device(void) {
return acpi_bus_get_device();
}"
compile_check_conftest "$CODE" "NV_ACPI_BUS_GET_DEVICE_PRESENT" "" "functions"
;;
dma_resv_add_fence)
#
# Determine if the dma_resv_add_fence() function is present.
......@@ -5365,6 +5349,23 @@ compile_test() {
compile_check_conftest "$CODE" "NV_RESERVATION_OBJECT_RESERVE_SHARED_HAS_NUM_FENCES_ARG" "" "types"
;;
get_task_ioprio)
#
# Determine if the __get_task_ioprio() function is present.
#
# __get_task_ioprio was added by commit 893e5d32d583
# ("block: Generalize get_current_ioprio() for any task") for
# v5.20 linux-next (2022-06-23).
#
CODE="
#include <linux/ioprio.h>
void conftest_get_task_ioprio(void) {
__get_task_ioprio();
}"
compile_check_conftest "$CODE" "NV_GET_TASK_IOPRIO_PRESENT" "" "functions"
;;
# When adding a new conftest entry, please use the correct format for
# specifying the relevant upstream Linux kernel commit.
#
......
......@@ -715,12 +715,11 @@ NV_STATUS NV_API_CALL nv_acpi_ddc_method(
)
{
acpi_status status;
struct acpi_device *device = NULL;
union acpi_object *ddc = NULL;
struct list_head *node, *next;
NvU32 i, largestEdidSize;
acpi_handle dev_handle = NULL;
acpi_handle lcd_dev_handle = NULL;
acpi_handle handle = NULL;
if (!nv_acpi_get_device_handle(nv, &dev_handle))
return NV_ERR_NOT_SUPPORTED;
......@@ -728,15 +727,6 @@ NV_STATUS NV_API_CALL nv_acpi_ddc_method(
if (!dev_handle)
return NV_ERR_INVALID_ARGUMENT;
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
status = acpi_bus_get_device(dev_handle, &device);
#else
return NV_ERR_NOT_SUPPORTED;
#endif
if (ACPI_FAILURE(status) || !device)
return NV_ERR_INVALID_ARGUMENT;
if (!NV_MAY_SLEEP())
{
#if defined(DEBUG)
......@@ -747,16 +737,16 @@ NV_STATUS NV_API_CALL nv_acpi_ddc_method(
return NV_ERR_NOT_SUPPORTED;
}
list_for_each_safe(node, next, &device->children)
while (lcd_dev_handle == NULL)
{
unsigned long long device_id = 0;
struct acpi_device *dev =
list_entry(node, struct acpi_device, node);
if (!dev)
continue;
status = acpi_get_next_object(ACPI_TYPE_DEVICE, dev_handle,
handle, &handle);
if (ACPI_FAILURE(status) || (handle == NULL))
break;
status = acpi_evaluate_integer(dev->handle, "_ADR", NULL, &device_id);
status = acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
if (ACPI_FAILURE(status))
/* Couldnt query device_id for this device */
continue;
......@@ -766,16 +756,13 @@ NV_STATUS NV_API_CALL nv_acpi_ddc_method(
case 0x0118:
case 0x0400:
case 0xA420:
lcd_dev_handle = dev->handle;
lcd_dev_handle = handle;
nv_printf(NV_DBG_INFO, "NVRM: %s Found LCD: %x\n",
__FUNCTION__, device_id);
break;
default:
break;
}
if (lcd_dev_handle != NULL)
break;
}
if (lcd_dev_handle == NULL)
......@@ -1125,15 +1112,14 @@ NV_STATUS NV_API_CALL nv_acpi_mux_method(
)
{
acpi_status status;
struct acpi_device *device = NULL;
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *mux = NULL;
union acpi_object mux_arg = { ACPI_TYPE_INTEGER };
struct acpi_object_list input = { 1, &mux_arg };
acpi_handle dev_handle = NULL;
acpi_handle mux_dev_handle = NULL;
acpi_handle handle = NULL;
unsigned long long device_id = 0;
struct list_head *node, *next;
if ((strcmp(pMethodName, "MXDS") != 0)
&& (strcmp(pMethodName, "MXDM") != 0))
......@@ -1154,16 +1140,6 @@ NV_STATUS NV_API_CALL nv_acpi_mux_method(
if (!dev_handle)
return NV_ERR_INVALID_ARGUMENT;
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
status = acpi_bus_get_device(dev_handle, &device);
#else
return NV_ERR_NOT_SUPPORTED;
#endif
if (ACPI_FAILURE(status) || !device)
return NV_ERR_INVALID_ARGUMENT;
if (!NV_MAY_SLEEP())
{
#if defined(DEBUG)
......@@ -1172,23 +1148,16 @@ NV_STATUS NV_API_CALL nv_acpi_mux_method(
return NV_ERR_NOT_SUPPORTED;
}
list_for_each_safe(node, next, &device->children)
while (mux_dev_handle == NULL)
{
struct acpi_device *dev = list_entry(node, struct acpi_device, node);
if (!dev)
continue;
status = acpi_evaluate_integer(dev->handle, "_ADR", NULL, &device_id);
if (ACPI_FAILURE(status))
/* Could not query device_id for this device */
continue;
if (device_id == muxAcpiId)
{
mux_dev_handle = dev->handle;
status = acpi_get_next_object(ACPI_TYPE_DEVICE, dev_handle,
handle, &handle);
if (ACPI_FAILURE(status) || (handle == NULL))
break;
}
status = acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
if (ACPI_SUCCESS(status) && (device_id == muxAcpiId))
mux_dev_handle = handle;
}
if (mux_dev_handle == NULL)
......
......@@ -797,12 +797,12 @@ nv_dma_buf_reuse(
}
if (buf->ops != &nv_dma_buf_ops)
{
nv_printf(NV_DBG_ERRORS, "NVRM: Invalid dma-buf fd\n");
status = NV_ERR_INVALID_ARGUMENT;
goto cleanup_dmabuf;
}
priv = buf->priv;
......
......@@ -608,6 +608,13 @@ next_bar:
dev_pm_set_driver_flags(nvl->dev, DPM_FLAG_NEVER_SKIP);
#endif
/*
* Dynamic power management should be enabled as the last step.
* Kernel runtime power management framework can put the device
* into the suspended state. Hardware register access should not be done
* after enabling dynamic power management.
*/
rm_enable_dynamic_power_management(sp, nv);
nv_kmem_cache_free_stack(sp);
return 0;
......@@ -683,8 +690,9 @@ nv_pci_remove(struct pci_dev *pci_dev)
if ((NV_ATOMIC_READ(nvl->usage_count) != 0) && !(nv->is_external_gpu))
{
nv_printf(NV_DBG_ERRORS,
"NVRM: Attempting to remove minor device %u with non-zero usage count!\n",
nvl->minor_num);
"NVRM: Attempting to remove device %04x:%02x:%02x.%x with non-zero usage count!\n",
NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev),
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
/*
* We can't return from this function without corrupting state, so we wait for
......@@ -708,9 +716,10 @@ nv_pci_remove(struct pci_dev *pci_dev)
if (!nvl)
{
/* The device was not found, which should not happen */
nv_printf(NV_DBG_ERRORS, "NVRM: Failed removal of minor device! %04x:%02x:%02x.%x\n",
nv_printf(NV_DBG_ERRORS,
"NVRM: Failed removal of device %04x:%02x:%02x.%x!\n",
NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev),
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
WARN_ON(1);
goto done;
}
......@@ -719,8 +728,9 @@ nv_pci_remove(struct pci_dev *pci_dev)
}
nv_printf(NV_DBG_ERRORS,
"NVRM: Continuing with GPU removal for minor device %u\n",
nvl->minor_num);
"NVRM: Continuing with GPU removal for device %04x:%02x:%02x.%x\n",
NV_PCI_DOMAIN_NUMBER(pci_dev), NV_PCI_BUS_NUMBER(pci_dev),
NV_PCI_SLOT_NUMBER(pci_dev), PCI_FUNC(pci_dev->devfn));
}
rm_check_for_gpu_surprise_removal(sp, nv);
......
......@@ -5443,7 +5443,19 @@ NvBool NV_API_CALL nv_s2idle_pm_configured(void)
return NV_FALSE;
}
/*
* init_sync_kiocb() internally uses GPL licensed __get_task_ioprio() from
* v5.20-rc1.
*/
#if defined(NV_GET_TASK_IOPRIO_PRESENT)
memset(&kiocb, 0, sizeof(kiocb));
kiocb.ki_filp = file;
kiocb.ki_flags = iocb_flags(file);
kiocb.ki_ioprio = IOPRIO_DEFAULT;
#else
init_sync_kiocb(&kiocb, file);
#endif
kiocb.ki_pos = 0;
iov_iter_kvec(&iter, READ, &iov, 1, sizeof(buf));
......
......@@ -199,7 +199,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_ops_has_map_atomic
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_has_dynamic_attachment
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_buf_attachment_has_peer2peer
NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_set_mask_and_coherent
NV_CONFTEST_FUNCTION_COMPILE_TESTS += acpi_bus_get_device
NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_task_ioprio
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_of_node_to_nid
NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_sme_active
......
......@@ -122,6 +122,8 @@ namespace DisplayPort
ConnectorType connectorType;
Address address;
GUID guid;
GUID guid2;
bool bVirtualPeerDevice;
NvU8 peerDevice;
NvU8 dpcdRevisionMajor;
NvU8 dpcdRevisionMinor;
......@@ -357,6 +359,29 @@ namespace DisplayPort
return hal->setIgnoreMSATimingParamters(msaTimingParamIgnoreEn);
}
bool isVirtualPeerDevice()
{
return bVirtualPeerDevice;
}
bool isBranchDevice()
{
return !isVideoSink() && !isAudioSink();
}
bool isAtLeastVersion(unsigned major, unsigned minor)
{
if (dpcdRevisionMajor > major)
return true;
if (dpcdRevisionMajor < major)
return false;
return dpcdRevisionMinor >= minor;
}
virtual void queryGUID2();
virtual bool getSDPExtnForColorimetrySupported();
virtual bool isPowerSuspended();
......@@ -447,6 +472,7 @@ namespace DisplayPort
unsigned getDscPeakThroughputModel();
unsigned getDscMaxSliceWidth();
unsigned getDscDecoderColorDepthSupportMask();
void setDscDecompressionDevice(bool bDscCapBasedOnParent);
};
class DeviceHDCPDetection : public Object, MessageManager::Message::MessageEventSink, Timer::TimerCallback
{
......
......@@ -624,132 +624,36 @@ create:
if (existingDev && existingDev->complianceDeviceEdidReadTest)
existingDev->lazyExitNow = true;
if(newDev->isBranchDevice() && newDev->isAtLeastVersion(1,4))
{
//
// GUID_2 will be non-zero for a virtual peer device and 0 for others.
// This will help identify if a device is virtual peer device or not.
//
newDev->queryGUID2();
}
// Read panel DSC support only if GPU supports DSC
bool bGpuDscSupported;
main->getDscCaps(&bGpuDscSupported);
if (bGpuDscSupported && newDev->getDSCSupport())
if (bGpuDscSupported)
{
// Read and parse DSC caps only if panel supports DSC
newDev->readAndParseDSCCaps();
// Read and Parse Branch Specific DSC Caps
if (!newDev->isVideoSink() && !newDev->isAudioSink())
if (newDev->getDSCSupport())
{
newDev->readAndParseBranchSpecificDSCCaps();
}
}
// Read and parse DSC caps only if panel supports DSC
newDev->readAndParseDSCCaps();
// Decide if DSC stream can be sent to new device
newDev->bDSCPossible = false;
newDev->devDoingDscDecompression = NULL;
if (bGpuDscSupported && !processedEdid.WARFlags.bIgnoreDscCap)
{
if (newDev->multistream)
{
if ((newDev->peerDevice == Dongle) &&
(newDev->dpcdRevisionMajor != 0) &&
!bDscCapBasedOnParent)
{
// For Peer Type 4 device with LAM DPCD rev != 0.0, check only the device's own DSC capability.
if (newDev->isDSCSupported())
{
newDev->bDSCPossible = true;
newDev->devDoingDscDecompression = newDev;
}
}
else
// Read and Parse Branch Specific DSC Caps
if (!newDev->isVideoSink() && !newDev->isAudioSink())
{
if (this->bDscMstEnablePassThrough)
{
//
// Check the device's own and its parent's DSC capability.
// - Sink device will do DSC cecompression when
// 1. Sink device is capable of DSC decompression and parent
// supports DSC pass through.
//
// - Sink device's parent will do DSC decompression
// 1. If sink device supports DSC decompression but it's parent does not support
// DSC Pass through, but supports DSC decompression.
// 2. If the device does not support DSC decompression, but parent supports it.
//
if (newDev->isDSCSupported())
{
if (newDev->videoSink && newDev->parent)
{
if (newDev->parent->isDSCPassThroughSupported())
{
//
// This condition takes care of DSC capable sink devices
// connected behind a DSC Pass through capable branch
//
newDev->devDoingDscDecompression = newDev;
newDev->bDSCPossible = true;
}
else if (newDev->parent->isDSCSupported())
{
//
// This condition takes care of DSC capable sink devices
// connected behind a branch device that is not capable
// of DSC pass through but can do DSC decompression.
//
newDev->bDSCPossible = true;
newDev->devDoingDscDecompression = newDev->parent;
}
}
else
{
// This condition takes care of branch device capable of DSC.
newDev->devDoingDscDecompression = newDev;
newDev->bDSCPossible = true;
}
}
else if (newDev->parent && newDev->parent->isDSCSupported())
{
//
// This condition takes care of sink devices not capable of DSC
// but parent is capable of DSC decompression.
//
newDev->bDSCPossible = true;
newDev->devDoingDscDecompression = newDev->parent;
}
}
else
{
//
// Revert to old code if DSC Pass through support is not requested.
// This code will be deleted once DSC Pass through support will be enabled
// by default which will be done when 2Head1OR MST (GR-133) will be in production.
//
// Check the device's own and its parent's DSC capability. Parent of the device can do
// DSC decompression and send uncompressed stream to downstream device
//
if (newDev->isDSCSupported() || (newDev->parent && newDev->parent->isDSCSupported()))
{
newDev->bDSCPossible = true;
}
// For multistream device, determine who will do the DSC decompression
if (newDev->bDSCPossible)
{
if(!newDev->isDSCSupported())
{
newDev->devDoingDscDecompression = newDev->parent;
}
else
{
newDev->devDoingDscDecompression = newDev;
}
}
}
newDev->readAndParseBranchSpecificDSCCaps();
}
}
else
if (!processedEdid.WARFlags.bIgnoreDscCap)
{
if (newDev->isDSCSupported())
{
newDev->bDSCPossible = true;
newDev->devDoingDscDecompression = newDev;
}
// Check if DSC is possible for the device and if so, set DSC Decompression device.
newDev->setDscDecompressionDevice(this->bDscCapBasedOnParent);
}
}
......@@ -1953,8 +1857,9 @@ void ConnectorImpl::fireEvents()
void ConnectorImpl::fireEventsInternal()
{
ListElement * next;
Address::StringBuffer sb;
Address::StringBuffer sb, sb1;
DP_USED(sb);
DP_USED(sb1);
for (ListElement * e = deviceList.begin(); e != deviceList.end(); e = next)
{
next = e->next;
......@@ -2096,7 +2001,7 @@ void ConnectorImpl::fireEventsInternal()
DP_LOG(("DPCONN> New device %s | Native DSC Capability - %s | DSC Decompression Device - %s",
dev->address.toString(sb),
(dev->isDSCSupported() ? "Capable" : "Not Capable"),
(dev->devDoingDscDecompression) ? dev->devDoingDscDecompression->address.toString(sb):"NA"));
(dev->devDoingDscDecompression) ? dev->devDoingDscDecompression->address.toString(sb1):"NA"));
}
else
{
......
......@@ -81,6 +81,7 @@ DeviceImpl::DeviceImpl(DPCDHAL * hal, ConnectorImpl * connector, DeviceImpl * pa
activeGroup(0),
connector(connector),
address(),
bVirtualPeerDevice(false),
plugged(false),
friendlyAux(this),
isHDCPCap(False),
......@@ -1445,6 +1446,8 @@ NvBool DeviceImpl::getDSCSupport()
NvU8 byte = 0;
unsigned size = 0;
unsigned nakReason = NakUndefined;
Address::StringBuffer sb;
DP_USED(sb);
dscCaps.bDSCSupported = false;
......@@ -1462,6 +1465,11 @@ NvBool DeviceImpl::getDSCSupport()
}
}
else
{
DP_LOG(("DP-DEV> DSC Support AUX READ failed for %s!", address.toString(sb)));
}
return dscCaps.bDSCSupported;
}
......@@ -1737,16 +1745,40 @@ bool DeviceImpl::readAndParseDSCCaps()
unsigned sizeCompleted = 0;
unsigned nakReason = NakUndefined;
Address::StringBuffer sb;
DP_USED(sb);