mirror of
https://github.com/NVIDIA/open-gpu-kernel-modules.git
synced 2026-01-30 21:19:49 +00:00
515.48.07
This commit is contained in:
@@ -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.43.04\"
|
||||
EXTRA_CFLAGS += -DNV_VERSION_STRING=\"515.48.07\"
|
||||
|
||||
EXTRA_CFLAGS += -Wno-unused-function
|
||||
|
||||
@@ -94,6 +94,7 @@ EXTRA_CFLAGS += -ffreestanding
|
||||
|
||||
ifeq ($(ARCH),arm64)
|
||||
EXTRA_CFLAGS += -mgeneral-regs-only -march=armv8-a
|
||||
EXTRA_CFLAGS += $(call cc-option,-mno-outline-atomics,)
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
|
||||
@@ -1647,23 +1647,12 @@ extern NvBool nv_ats_supported;
|
||||
* and any other baggage we want to carry along
|
||||
*
|
||||
*/
|
||||
#define NV_MAXNUM_DISPLAY_DEVICES 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
acpi_handle dev_handle;
|
||||
int dev_id;
|
||||
} nv_video_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nvidia_stack_t *sp;
|
||||
struct acpi_device *device;
|
||||
|
||||
nv_video_t pNvVideo[NV_MAXNUM_DISPLAY_DEVICES];
|
||||
|
||||
struct acpi_handle *handle;
|
||||
int notify_handler_installed;
|
||||
int default_display_mask;
|
||||
} nv_acpi_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,8 +35,6 @@ extern nvidia_module_t nv_fops;
|
||||
|
||||
void nv_acpi_register_notifier (nv_linux_state_t *);
|
||||
void nv_acpi_unregister_notifier (nv_linux_state_t *);
|
||||
int nv_acpi_init (void);
|
||||
int nv_acpi_uninit (void);
|
||||
|
||||
NvU8 nv_find_pci_capability (struct pci_dev *, NvU8);
|
||||
|
||||
|
||||
@@ -576,11 +576,9 @@ typedef enum
|
||||
((nv)->iso_iommu_present)
|
||||
|
||||
/*
|
||||
* NVIDIA ACPI event IDs to be passed into the core NVIDIA
|
||||
* driver for various events like display switch events,
|
||||
* AC/battery events, etc..
|
||||
* NVIDIA ACPI event ID to be passed into the core NVIDIA driver for
|
||||
* AC/DC event.
|
||||
*/
|
||||
#define NV_SYSTEM_ACPI_DISPLAY_SWITCH_EVENT 0x8001
|
||||
#define NV_SYSTEM_ACPI_BATTERY_POWER_EVENT 0x8002
|
||||
|
||||
/*
|
||||
@@ -589,14 +587,6 @@ typedef enum
|
||||
#define NV_SYSTEM_GPU_ADD_EVENT 0x9001
|
||||
#define NV_SYSTEM_GPU_REMOVE_EVENT 0x9002
|
||||
|
||||
/*
|
||||
* Status bit definitions for display switch hotkey events.
|
||||
*/
|
||||
#define NV_HOTKEY_STATUS_DISPLAY_ENABLE_LCD 0x01
|
||||
#define NV_HOTKEY_STATUS_DISPLAY_ENABLE_CRT 0x02
|
||||
#define NV_HOTKEY_STATUS_DISPLAY_ENABLE_TV 0x04
|
||||
#define NV_HOTKEY_STATUS_DISPLAY_ENABLE_DFP 0x08
|
||||
|
||||
/*
|
||||
* NVIDIA ACPI sub-event IDs (event types) to be passed into
|
||||
* to core NVIDIA driver for ACPI events.
|
||||
|
||||
@@ -1120,6 +1120,23 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_MDEV_SET_IOMMU_DEVICE_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
mdev_parent_ops_has_open_device)
|
||||
# Determine if 'mdev_parent_ops' structure has a 'open_device'
|
||||
# field.
|
||||
#
|
||||
# Added by commit 2fd585f4ed9d ("vfio: Provide better generic support
|
||||
# for open/release vfio_device_ops") in 5.15 (2021-08-05)
|
||||
#
|
||||
CODE="
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mdev.h>
|
||||
int conftest_mdev_parent_ops_has_open_device(void) {
|
||||
return offsetof(struct mdev_parent_ops, open_device);
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_MDEV_PARENT_OPS_HAS_OPEN_DEVICE" "" "types"
|
||||
;;
|
||||
|
||||
pci_irq_vector_helpers)
|
||||
#
|
||||
# Determine if pci_alloc_irq_vectors(), pci_free_irq_vectors()
|
||||
@@ -1154,23 +1171,6 @@ compile_test() {
|
||||
compile_check_conftest "$CODE" "NV_VFIO_DEVICE_GFX_PLANE_INFO_PRESENT" "" "types"
|
||||
;;
|
||||
|
||||
vfio_device_migration_info)
|
||||
#
|
||||
# determine if the 'struct vfio_device_migration_info' type is present.
|
||||
#
|
||||
# Proposed interface for vGPU Migration
|
||||
# ("[PATCH v3 0/5] Add migration support for VFIO device ")
|
||||
# https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg05176.html
|
||||
# Upstreamed commit a8a24f3f6e38 (vfio: UAPI for migration interface
|
||||
# for device state) in v5.8 (2020-05-29)
|
||||
#
|
||||
CODE="
|
||||
#include <linux/vfio.h>
|
||||
struct vfio_device_migration_info info;"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_VFIO_DEVICE_MIGRATION_INFO_PRESENT" "" "types"
|
||||
;;
|
||||
|
||||
vfio_device_migration_has_start_pfn)
|
||||
#
|
||||
# Determine if the 'vfio_device_migration_info' structure has
|
||||
@@ -5304,6 +5304,67 @@ compile_test() {
|
||||
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.
|
||||
#
|
||||
# dma_resv_add_excl_fence() and dma_resv_add_shared_fence() were
|
||||
# removed and replaced with dma_resv_add_fence() by commit
|
||||
# 73511edf8b19 ("dma-buf: specify usage while adding fences to
|
||||
# dma_resv obj v7") in linux-next, expected in v5.19-rc1.
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
#include <linux/dma-resv.h>
|
||||
#endif
|
||||
void conftest_dma_resv_add_fence(void) {
|
||||
dma_resv_add_fence();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DMA_RESV_ADD_FENCE_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
dma_resv_reserve_fences)
|
||||
#
|
||||
# Determine if the dma_resv_reserve_fences() function is present.
|
||||
#
|
||||
# dma_resv_reserve_shared() was removed and replaced with
|
||||
# dma_resv_reserve_fences() by commit c8d4c18bfbc4
|
||||
# ("dma-buf/drivers: make reserving a shared slot mandatory v4") in
|
||||
# linux-next, expected in v5.19-rc1.
|
||||
#
|
||||
CODE="
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
#include <linux/dma-resv.h>
|
||||
#endif
|
||||
void conftest_dma_resv_reserve_fences(void) {
|
||||
dma_resv_reserve_fences();
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_DMA_RESV_RESERVE_FENCES_PRESENT" "" "functions"
|
||||
;;
|
||||
|
||||
reservation_object_reserve_shared_has_num_fences_arg)
|
||||
#
|
||||
# Determine if reservation_object_reserve_shared() has 'num_fences'
|
||||
# argument.
|
||||
#
|
||||
# reservation_object_reserve_shared() function prototype was updated
|
||||
# to take 'num_fences' argument by commit ca05359f1e64 ("dma-buf:
|
||||
# allow reserving more than one shared fence slot") in v4.21-rc1
|
||||
# (2018-12-14).
|
||||
#
|
||||
CODE="
|
||||
#include <linux/reservation.h>
|
||||
void conftest_reservation_object_reserve_shared_has_num_fences_arg(
|
||||
struct reservation_object *obj,
|
||||
unsigned int num_fences) {
|
||||
(void) reservation_object_reserve_shared(obj, num_fences);
|
||||
}"
|
||||
|
||||
compile_check_conftest "$CODE" "NV_RESERVATION_OBJECT_RESERVE_SHARED_HAS_NUM_FENCES_ARG" "" "types"
|
||||
;;
|
||||
|
||||
# When adding a new conftest entry, please use the correct format for
|
||||
# specifying the relevant upstream Linux kernel commit.
|
||||
#
|
||||
|
||||
@@ -65,11 +65,57 @@ static inline void nv_dma_resv_fini(nv_dma_resv_t *obj)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void nv_dma_resv_lock(nv_dma_resv_t *obj,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
{
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
dma_resv_lock(obj, ctx);
|
||||
#else
|
||||
ww_mutex_lock(&obj->lock, ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void nv_dma_resv_unlock(nv_dma_resv_t *obj)
|
||||
{
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
dma_resv_unlock(obj);
|
||||
#else
|
||||
ww_mutex_unlock(&obj->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int nv_dma_resv_reserve_fences(nv_dma_resv_t *obj,
|
||||
unsigned int num_fences,
|
||||
NvBool shared)
|
||||
{
|
||||
#if defined(NV_DMA_RESV_RESERVE_FENCES_PRESENT)
|
||||
return dma_resv_reserve_fences(obj, num_fences);
|
||||
#else
|
||||
if (shared) {
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
return dma_resv_reserve_shared(obj, num_fences);
|
||||
#elif defined(NV_RESERVATION_OBJECT_RESERVE_SHARED_HAS_NUM_FENCES_ARG)
|
||||
return reservation_object_reserve_shared(obj, num_fences);
|
||||
#else
|
||||
unsigned int i;
|
||||
for (i = 0; i < num_fences; i++) {
|
||||
reservation_object_reserve_shared(obj);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void nv_dma_resv_add_excl_fence(nv_dma_resv_t *obj,
|
||||
nv_dma_fence_t *fence)
|
||||
{
|
||||
#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
|
||||
#if defined(NV_DMA_RESV_ADD_FENCE_PRESENT)
|
||||
dma_resv_add_fence(obj, fence, DMA_RESV_USAGE_WRITE);
|
||||
#else
|
||||
dma_resv_add_excl_fence(obj, fence);
|
||||
#endif
|
||||
#else
|
||||
reservation_object_add_excl_fence(obj, fence);
|
||||
#endif
|
||||
|
||||
@@ -499,9 +499,18 @@ int nv_drm_gem_fence_attach_ioctl(struct drm_device *dev,
|
||||
goto fence_context_create_fence_failed;
|
||||
}
|
||||
|
||||
nv_dma_resv_add_excl_fence(&nv_gem->resv, fence);
|
||||
nv_dma_resv_lock(&nv_gem->resv, NULL);
|
||||
|
||||
ret = 0;
|
||||
ret = nv_dma_resv_reserve_fences(&nv_gem->resv, 1, false);
|
||||
if (ret == 0) {
|
||||
nv_dma_resv_add_excl_fence(&nv_gem->resv, fence);
|
||||
} else {
|
||||
NV_DRM_DEV_LOG_ERR(
|
||||
nv_dev,
|
||||
"Failed to reserve fence. Error code: %d", ret);
|
||||
}
|
||||
|
||||
nv_dma_resv_unlock(&nv_gem->resv);
|
||||
|
||||
fence_context_create_fence_failed:
|
||||
nv_drm_gem_object_unreference_unlocked(&nv_gem_fence_context->base);
|
||||
|
||||
@@ -115,3 +115,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_plane_atomic_check_has_atomic_state_arg
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_device_has_pdev
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_state_has_no_vblank
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_config_has_allow_fb_modifiers
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_resv_add_fence
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += dma_resv_reserve_fences
|
||||
NV_CONFTEST_TYPE_COMPILE_TESTS += reservation_object_reserve_shared_has_num_fences_arg
|
||||
|
||||
@@ -976,6 +976,7 @@ NvBool nvkms_allow_write_combining(void)
|
||||
return __rm_ops.system_info.allow_write_combining;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
|
||||
/*************************************************************************
|
||||
* Implementation of sysfs interface to control backlight
|
||||
*************************************************************************/
|
||||
@@ -1034,11 +1035,13 @@ static const struct backlight_ops nvkms_backlight_ops = {
|
||||
.update_status = nvkms_update_backlight_status,
|
||||
.get_brightness = nvkms_get_backlight_brightness,
|
||||
};
|
||||
#endif /* IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) */
|
||||
|
||||
struct nvkms_backlight_device*
|
||||
nvkms_register_backlight(NvU32 gpu_id, NvU32 display_id, void *drv_priv,
|
||||
NvU32 current_brightness)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
|
||||
char name[18];
|
||||
struct backlight_properties props = {
|
||||
.brightness = current_brightness,
|
||||
@@ -1093,15 +1096,20 @@ done:
|
||||
nvkms_free(gpu_info, NV_MAX_GPUS * sizeof(*gpu_info));
|
||||
|
||||
return nvkms_bd;
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) */
|
||||
}
|
||||
|
||||
void nvkms_unregister_backlight(struct nvkms_backlight_device *nvkms_bd)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
|
||||
if (nvkms_bd->dev) {
|
||||
backlight_device_unregister(nvkms_bd->dev);
|
||||
}
|
||||
|
||||
nvkms_free(nvkms_bd, sizeof(*nvkms_bd));
|
||||
#endif /* IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
||||
@@ -232,7 +232,7 @@ static inline const struct cpumask *uvm_cpumask_of_node(int node)
|
||||
#define __GFP_NORETRY 0
|
||||
#endif
|
||||
|
||||
#define NV_UVM_GFP_FLAGS (GFP_KERNEL | __GFP_NORETRY)
|
||||
#define NV_UVM_GFP_FLAGS (GFP_KERNEL)
|
||||
|
||||
#if !defined(NV_ADDRESS_SPACE_INIT_ONCE_PRESENT)
|
||||
void address_space_init_once(struct address_space *mapping);
|
||||
|
||||
@@ -151,7 +151,7 @@ static void maxwell_membar_after_transfer(uvm_push_t *push)
|
||||
|
||||
// Flush on transfers only works when paired with a semaphore release. Use a
|
||||
// host WFI + MEMBAR.
|
||||
// http://nvbugs/1709888
|
||||
// Bug 1709888
|
||||
gpu->parent->host_hal->wait_for_idle(push);
|
||||
|
||||
if (uvm_push_get_and_reset_flag(push, UVM_PUSH_FLAG_NEXT_MEMBAR_GPU))
|
||||
|
||||
@@ -1805,12 +1805,12 @@ nvswitch_exit
|
||||
return;
|
||||
}
|
||||
|
||||
nvswitch_procfs_exit();
|
||||
|
||||
nvswitch_ctl_exit();
|
||||
|
||||
pci_unregister_driver(&nvswitch_pci_driver);
|
||||
|
||||
nvswitch_procfs_exit();
|
||||
|
||||
cdev_del(&nvswitch.cdev);
|
||||
|
||||
unregister_chrdev_region(nvswitch.devno, NVSWITCH_MINOR_COUNT);
|
||||
|
||||
@@ -35,29 +35,13 @@ static NV_STATUS nv_acpi_extract_buffer (const union acpi_object *, void *, N
|
||||
static NV_STATUS nv_acpi_extract_package (const union acpi_object *, void *, NvU32, NvU32 *);
|
||||
static NV_STATUS nv_acpi_extract_object (const union acpi_object *, void *, NvU32, NvU32 *);
|
||||
|
||||
static int nv_acpi_add (struct acpi_device *);
|
||||
static int nv_acpi_remove (struct acpi_device *device);
|
||||
static void nv_acpi_event (acpi_handle, u32, void *);
|
||||
static void nv_acpi_powersource_hotplug_event(acpi_handle, u32, void *);
|
||||
static acpi_status nv_acpi_find_methods (acpi_handle, u32, void *, void **);
|
||||
static NV_STATUS nv_acpi_nvif_method (NvU32, NvU32, void *, NvU16, NvU32 *, void *, NvU16 *);
|
||||
|
||||
static NV_STATUS nv_acpi_wmmx_method (NvU32, NvU8 *, NvU16 *);
|
||||
|
||||
static const struct acpi_device_id nv_video_device_ids[] = {
|
||||
{
|
||||
.id = ACPI_VIDEO_HID,
|
||||
.driver_data = 0,
|
||||
},
|
||||
{
|
||||
.id = "",
|
||||
.driver_data = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct acpi_driver *nv_acpi_driver;
|
||||
static acpi_handle nvif_handle = NULL;
|
||||
static acpi_handle nvif_parent_gpu_handle = NULL;
|
||||
static acpi_handle wmmx_handle = NULL;
|
||||
|
||||
// Used for AC Power Source Hotplug Handling
|
||||
@@ -81,16 +65,6 @@ static NvBool battery_present = NV_FALSE;
|
||||
#define ACPI_VIDEO_CLASS "video"
|
||||
#endif
|
||||
|
||||
static const struct acpi_driver nv_acpi_driver_template = {
|
||||
.name = "NVIDIA ACPI Video Driver",
|
||||
.class = ACPI_VIDEO_CLASS,
|
||||
.ids = nv_video_device_ids,
|
||||
.ops = {
|
||||
.add = nv_acpi_add,
|
||||
.remove = nv_acpi_remove,
|
||||
},
|
||||
};
|
||||
|
||||
static int nv_acpi_get_device_handle(nv_state_t *nv, acpi_handle *dev_handle)
|
||||
{
|
||||
nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
|
||||
@@ -151,351 +125,6 @@ void nv_acpi_unregister_notifier(nv_linux_state_t *nvl)
|
||||
unregister_acpi_notifier(&nvl->acpi_nb);
|
||||
}
|
||||
|
||||
int nv_acpi_init(void)
|
||||
{
|
||||
/*
|
||||
* This function will register the RM with the Linux
|
||||
* ACPI subsystem.
|
||||
*/
|
||||
int status;
|
||||
nvidia_stack_t *sp = NULL;
|
||||
NvU32 acpi_event_config = 0;
|
||||
NV_STATUS rmStatus;
|
||||
|
||||
status = nv_kmem_cache_alloc_stack(&sp);
|
||||
if (status != 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
rmStatus = rm_read_registry_dword(sp, NULL,
|
||||
NV_REG_REGISTER_FOR_ACPI_EVENTS, &acpi_event_config);
|
||||
nv_kmem_cache_free_stack(sp);
|
||||
|
||||
if ((rmStatus == NV_OK) && (acpi_event_config == 0))
|
||||
return 0;
|
||||
|
||||
if (nv_acpi_driver != NULL)
|
||||
return -EBUSY;
|
||||
|
||||
rmStatus = os_alloc_mem((void **)&nv_acpi_driver,
|
||||
sizeof(struct acpi_driver));
|
||||
if (rmStatus != NV_OK)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy((void *)nv_acpi_driver, (void *)&nv_acpi_driver_template,
|
||||
sizeof(struct acpi_driver));
|
||||
|
||||
status = acpi_bus_register_driver(nv_acpi_driver);
|
||||
if (status < 0)
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_init: acpi_bus_register_driver() failed (%d)!\n", status);
|
||||
os_free_mem(nv_acpi_driver);
|
||||
nv_acpi_driver = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int nv_acpi_uninit(void)
|
||||
{
|
||||
nvidia_stack_t *sp = NULL;
|
||||
NvU32 acpi_event_config = 0;
|
||||
NV_STATUS rmStatus;
|
||||
int rc;
|
||||
|
||||
rc = nv_kmem_cache_alloc_stack(&sp);
|
||||
if (rc != 0)
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
rmStatus = rm_read_registry_dword(sp, NULL,
|
||||
NV_REG_REGISTER_FOR_ACPI_EVENTS, &acpi_event_config);
|
||||
nv_kmem_cache_free_stack(sp);
|
||||
|
||||
if ((rmStatus == NV_OK) && (acpi_event_config == 0))
|
||||
return 0;
|
||||
|
||||
if (nv_acpi_driver == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
acpi_bus_unregister_driver(nv_acpi_driver);
|
||||
os_free_mem(nv_acpi_driver);
|
||||
|
||||
nv_acpi_driver = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_acpi_add(struct acpi_device *device)
|
||||
{
|
||||
/*
|
||||
* This function will cause RM to initialize the things it needs for acpi interaction
|
||||
* on the display device.
|
||||
*/
|
||||
int status = -1;
|
||||
NV_STATUS rmStatus = NV_ERR_GENERIC;
|
||||
nv_acpi_t *pNvAcpiObject = NULL;
|
||||
union acpi_object control_argument_0 = { ACPI_TYPE_INTEGER };
|
||||
struct acpi_object_list control_argument_list = { 0, NULL };
|
||||
nvidia_stack_t *sp = NULL;
|
||||
struct list_head *node, *next;
|
||||
unsigned long long device_id = 0;
|
||||
int device_counter = 0;
|
||||
|
||||
status = nv_kmem_cache_alloc_stack(&sp);
|
||||
if (status != 0)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
// allocate data structure we need
|
||||
rmStatus = os_alloc_mem((void **) &pNvAcpiObject, sizeof(nv_acpi_t));
|
||||
if (rmStatus != NV_OK)
|
||||
{
|
||||
nv_kmem_cache_free_stack(sp);
|
||||
nv_printf(NV_DBG_ERRORS,
|
||||
"NVRM: nv_acpi_add: failed to allocate ACPI device management data!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
os_mem_set((void *)pNvAcpiObject, 0, sizeof(nv_acpi_t));
|
||||
|
||||
device->driver_data = pNvAcpiObject;
|
||||
pNvAcpiObject->device = device;
|
||||
|
||||
pNvAcpiObject->sp = sp;
|
||||
|
||||
// grab handles to all the important nodes representing devices
|
||||
|
||||
list_for_each_safe(node, next, &device->children)
|
||||
{
|
||||
struct acpi_device *dev =
|
||||
list_entry(node, struct acpi_device, node);
|
||||
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
if (device_counter == NV_MAXNUM_DISPLAY_DEVICES)
|
||||
{
|
||||
nv_printf(NV_DBG_ERRORS,
|
||||
"NVRM: nv_acpi_add: Total number of devices cannot exceed %d\n",
|
||||
NV_MAXNUM_DISPLAY_DEVICES);
|
||||
break;
|
||||
}
|
||||
|
||||
status =
|
||||
acpi_evaluate_integer(dev->handle, "_ADR", NULL, &device_id);
|
||||
if (ACPI_FAILURE(status))
|
||||
/* Couldnt query device_id for this device */
|
||||
continue;
|
||||
|
||||
device_id = (device_id & 0xffff);
|
||||
|
||||
if ((device_id != 0x100) && /* Not a known CRT device-id */
|
||||
(device_id != 0x200) && /* Not a known TV device-id */
|
||||
(device_id != 0x0110) && (device_id != 0x0118) && (device_id != 0x0400) && /* Not an LCD*/
|
||||
(device_id != 0x0111) && (device_id != 0x0120) && (device_id != 0x0300)) /* Not a known DVI device-id */
|
||||
{
|
||||
/* This isnt a known device Id.
|
||||
Do default switching on this system. */
|
||||
pNvAcpiObject->default_display_mask = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pNvAcpiObject->pNvVideo[device_counter].dev_id = device_id;
|
||||
pNvAcpiObject->pNvVideo[device_counter].dev_handle = dev->handle;
|
||||
|
||||
device_counter++;
|
||||
|
||||
}
|
||||
|
||||
// arg 0, bits 1:0, 0 = enable events
|
||||
control_argument_0.integer.type = ACPI_TYPE_INTEGER;
|
||||
control_argument_0.integer.value = 0x0;
|
||||
|
||||
// listify it
|
||||
control_argument_list.count = 1;
|
||||
control_argument_list.pointer = &control_argument_0;
|
||||
|
||||
// _DOS method takes 1 argument and returns nothing
|
||||
status = acpi_evaluate_object(device->handle, "_DOS", &control_argument_list, NULL);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_add: failed to enable display switch events (%d)!\n", status);
|
||||
}
|
||||
|
||||
status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
|
||||
nv_acpi_event, pNvAcpiObject);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_add: failed to install event notification handler (%d)!\n", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
try_module_get(THIS_MODULE);
|
||||
pNvAcpiObject->notify_handler_installed = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nv_acpi_remove(struct acpi_device *device)
|
||||
{
|
||||
/*
|
||||
* This function will cause RM to relinquish control of the VGA ACPI device.
|
||||
*/
|
||||
acpi_status status;
|
||||
union acpi_object control_argument_0 = { ACPI_TYPE_INTEGER };
|
||||
struct acpi_object_list control_argument_list = { 0, NULL };
|
||||
nv_acpi_t *pNvAcpiObject = device->driver_data;
|
||||
|
||||
|
||||
pNvAcpiObject->default_display_mask = 0;
|
||||
|
||||
// arg 0, bits 1:0, 1 = disable events
|
||||
control_argument_0.integer.type = ACPI_TYPE_INTEGER;
|
||||
control_argument_0.integer.value = 0x1;
|
||||
|
||||
// listify it
|
||||
control_argument_list.count = 1;
|
||||
control_argument_list.pointer = &control_argument_0;
|
||||
|
||||
// _DOS method takes 1 argument and returns nothing
|
||||
status = acpi_evaluate_object(device->handle, "_DOS", &control_argument_list, NULL);
|
||||
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_remove: failed to disable display switch events (%d)!\n", status);
|
||||
}
|
||||
|
||||
if (pNvAcpiObject->notify_handler_installed)
|
||||
{
|
||||
// remove event notifier
|
||||
status = acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, nv_acpi_event);
|
||||
}
|
||||
|
||||
if (pNvAcpiObject->notify_handler_installed &&
|
||||
ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_remove: failed to remove event notification handler (%d)!\n", status);
|
||||
}
|
||||
else
|
||||
{
|
||||
nv_kmem_cache_free_stack(pNvAcpiObject->sp);
|
||||
os_free_mem((void *)pNvAcpiObject);
|
||||
module_put(THIS_MODULE);
|
||||
device->driver_data = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* The ACPI specification defines IDs for various ACPI video
|
||||
* extension events like display switch events, AC/battery
|
||||
* events, docking events, etc..
|
||||
* Whenever an ACPI event is received by the corresponding
|
||||
* event handler installed within the core NVIDIA driver, the
|
||||
* code can verify the event ID before processing it.
|
||||
*/
|
||||
#define ACPI_DISPLAY_DEVICE_CHANGE_EVENT 0x80
|
||||
#define NVIF_NOTIFY_DISPLAY_DETECT 0xCB
|
||||
#define NVIF_DISPLAY_DEVICE_CHANGE_EVENT NVIF_NOTIFY_DISPLAY_DETECT
|
||||
static void nv_acpi_event(acpi_handle handle, u32 event_type, void *data)
|
||||
{
|
||||
/*
|
||||
* This function will handle acpi events from the linux kernel, used
|
||||
* to detect notifications from the VGA device.
|
||||
*/
|
||||
nv_acpi_t *pNvAcpiObject = data;
|
||||
u32 event_val = 0;
|
||||
unsigned long long state;
|
||||
int status = 0;
|
||||
int device_counter = 0;
|
||||
|
||||
if (event_type == NVIF_DISPLAY_DEVICE_CHANGE_EVENT)
|
||||
{
|
||||
/* We are getting NVIF events on this machine. We arent putting a very
|
||||
extensive handling in-place to communicate back with SBIOS, know
|
||||
the next enabled devices, and then do the switch. We just
|
||||
pass a default display switch event, so that X-driver decides
|
||||
the switching policy itself. */
|
||||
rm_system_event(pNvAcpiObject->sp, NV_SYSTEM_ACPI_DISPLAY_SWITCH_EVENT, 0);
|
||||
}
|
||||
if (event_type == ACPI_DISPLAY_DEVICE_CHANGE_EVENT)
|
||||
{
|
||||
if (pNvAcpiObject->default_display_mask != 1)
|
||||
{
|
||||
while ((device_counter < NV_MAXNUM_DISPLAY_DEVICES) &&
|
||||
(pNvAcpiObject->pNvVideo[device_counter].dev_handle))
|
||||
{
|
||||
acpi_handle dev_handle = pNvAcpiObject->pNvVideo[device_counter].dev_handle;
|
||||
int dev_id = pNvAcpiObject->pNvVideo[device_counter].dev_id;
|
||||
|
||||
status = acpi_evaluate_integer(dev_handle,
|
||||
"_DGS",
|
||||
NULL,
|
||||
&state);
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_event: failed to query _DGS method for display device 0x%x\n",
|
||||
dev_id);
|
||||
}
|
||||
else if (state)
|
||||
{
|
||||
/* Check if the device is a CRT ...*/
|
||||
if (dev_id == 0x0100)
|
||||
{
|
||||
event_val |= NV_HOTKEY_STATUS_DISPLAY_ENABLE_CRT;
|
||||
}
|
||||
/* device-id for a TV */
|
||||
else if (dev_id == 0x0200)
|
||||
{
|
||||
event_val |= NV_HOTKEY_STATUS_DISPLAY_ENABLE_TV;
|
||||
}
|
||||
else if ((dev_id == 0x0110) || /* device id for internal LCD */
|
||||
(dev_id == 0x0118) || /* alternate ACPI ID for the
|
||||
internal LCD */
|
||||
(dev_id == 0x0400)) /* ACPI spec 3.0 specified
|
||||
device id for a internal LCD*/
|
||||
{
|
||||
event_val |= NV_HOTKEY_STATUS_DISPLAY_ENABLE_LCD;
|
||||
}
|
||||
else if ((dev_id == 0x0111) || /* the set
|
||||
of possible device-ids for a DFP */
|
||||
(dev_id == 0x0120) ||
|
||||
(dev_id == 0x0300)) /* ACPI spec 3.0 specified
|
||||
device id for non-LVDS DFP */
|
||||
{
|
||||
event_val |= NV_HOTKEY_STATUS_DISPLAY_ENABLE_DFP;
|
||||
}
|
||||
}
|
||||
device_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
nv_printf(NV_DBG_INFO,
|
||||
"NVRM: nv_acpi_event: Event-type 0x%x, Event-val 0x%x\n",
|
||||
event_type, event_val);
|
||||
|
||||
rm_system_event(pNvAcpiObject->sp, NV_SYSTEM_ACPI_DISPLAY_SWITCH_EVENT, event_val);
|
||||
}
|
||||
|
||||
// no unsubscription or re-enable necessary. Once DOD has been set, we are go.
|
||||
// once we are subscribed to ACPI events, we don't have to re-subscribe unless
|
||||
// unsubscribe.
|
||||
}
|
||||
|
||||
NV_STATUS NV_API_CALL nv_acpi_get_powersource(NvU32 *ac_plugged)
|
||||
{
|
||||
unsigned long long val;
|
||||
@@ -543,14 +172,14 @@ static void nv_acpi_powersource_hotplug_event(acpi_handle handle, u32 event_type
|
||||
*/
|
||||
|
||||
/* Do the necessary allocations and install notifier "handler" on the device-node "device" */
|
||||
static nv_acpi_t* nv_install_notifier(struct acpi_device *device, acpi_notify_handler handler)
|
||||
static nv_acpi_t* nv_install_notifier(struct acpi_handle *handle, acpi_notify_handler handler)
|
||||
{
|
||||
nvidia_stack_t *sp = NULL;
|
||||
nv_acpi_t *pNvAcpiObject = NULL;
|
||||
NV_STATUS rmStatus = NV_ERR_GENERIC;
|
||||
acpi_status status = -1;
|
||||
|
||||
if (!device)
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
if (nv_kmem_cache_alloc_stack(&sp) != 0)
|
||||
@@ -564,11 +193,11 @@ static nv_acpi_t* nv_install_notifier(struct acpi_device *device, acpi_notify_ha
|
||||
|
||||
os_mem_set((void *)pNvAcpiObject, 0, sizeof(nv_acpi_t));
|
||||
|
||||
// store a device reference in our object
|
||||
pNvAcpiObject->device = device;
|
||||
// store a handle reference in our object
|
||||
pNvAcpiObject->handle = handle;
|
||||
pNvAcpiObject->sp = sp;
|
||||
|
||||
status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
|
||||
status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY,
|
||||
handler, pNvAcpiObject);
|
||||
if (!ACPI_FAILURE(status))
|
||||
{
|
||||
@@ -592,7 +221,7 @@ static void nv_uninstall_notifier(nv_acpi_t *pNvAcpiObject, acpi_notify_handler
|
||||
|
||||
if (pNvAcpiObject && pNvAcpiObject->notify_handler_installed)
|
||||
{
|
||||
status = acpi_remove_notify_handler(pNvAcpiObject->device->handle, ACPI_DEVICE_NOTIFY, handler);
|
||||
status = acpi_remove_notify_handler(pNvAcpiObject->handle, ACPI_DEVICE_NOTIFY, handler);
|
||||
if (ACPI_FAILURE(status))
|
||||
{
|
||||
nv_printf(NV_DBG_INFO,
|
||||
@@ -616,56 +245,22 @@ static void nv_uninstall_notifier(nv_acpi_t *pNvAcpiObject, acpi_notify_handler
|
||||
|
||||
void NV_API_CALL nv_acpi_methods_init(NvU32 *handlesPresent)
|
||||
{
|
||||
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
|
||||
struct acpi_device *device = NULL;
|
||||
int retVal = -1;
|
||||
#endif
|
||||
|
||||
|
||||
if (!handlesPresent) // Caller passed us invalid pointer.
|
||||
return;
|
||||
|
||||
|
||||
*handlesPresent = 0;
|
||||
|
||||
NV_ACPI_WALK_NAMESPACE(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX, nv_acpi_find_methods, NULL, NULL);
|
||||
|
||||
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
|
||||
if (nvif_handle)
|
||||
{
|
||||
*handlesPresent = NV_ACPI_NVIF_HANDLE_PRESENT;
|
||||
do
|
||||
{
|
||||
if (!nvif_parent_gpu_handle) /* unknown error */
|
||||
break;
|
||||
|
||||
retVal = acpi_bus_get_device(nvif_parent_gpu_handle, &device);
|
||||
|
||||
if (ACPI_FAILURE(retVal) || !device)
|
||||
break;
|
||||
|
||||
if (device->driver_data)
|
||||
{
|
||||
nvif_parent_gpu_handle = NULL;
|
||||
break; /* Someone else has already populated this device
|
||||
nodes' structures. So nothing more to be done */
|
||||
}
|
||||
|
||||
device->driver_data = nv_install_notifier(device, nv_acpi_event);
|
||||
|
||||
|
||||
if (!device->driver_data)
|
||||
nvif_parent_gpu_handle = NULL;
|
||||
|
||||
} while (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wmmx_handle)
|
||||
*handlesPresent = *handlesPresent | NV_ACPI_WMMX_HANDLE_PRESENT;
|
||||
|
||||
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
|
||||
if (psr_handle)
|
||||
{
|
||||
// Since _PSR is not a per-GPU construct we only need to register a
|
||||
@@ -673,15 +268,9 @@ void NV_API_CALL nv_acpi_methods_init(NvU32 *handlesPresent)
|
||||
// devices
|
||||
if (psr_nv_acpi_object == NULL)
|
||||
{
|
||||
retVal = acpi_bus_get_device(psr_device_handle, &device);
|
||||
|
||||
if (!(ACPI_FAILURE(retVal) || !device))
|
||||
{
|
||||
psr_nv_acpi_object = nv_install_notifier(device, nv_acpi_powersource_hotplug_event);
|
||||
}
|
||||
psr_nv_acpi_object = nv_install_notifier(psr_device_handle, nv_acpi_powersource_hotplug_event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -698,7 +287,6 @@ acpi_status nv_acpi_find_methods(
|
||||
if (!acpi_get_handle(handle, "NVIF", &method_handle))
|
||||
{
|
||||
nvif_handle = method_handle;
|
||||
nvif_parent_gpu_handle = handle;
|
||||
}
|
||||
|
||||
if (!acpi_get_handle(handle, "WMMX", &method_handle))
|
||||
@@ -717,8 +305,6 @@ acpi_status nv_acpi_find_methods(
|
||||
|
||||
void NV_API_CALL nv_acpi_methods_uninit(void)
|
||||
{
|
||||
struct acpi_device *device = NULL;
|
||||
|
||||
nvif_handle = NULL;
|
||||
wmmx_handle = NULL;
|
||||
|
||||
@@ -730,20 +316,6 @@ void NV_API_CALL nv_acpi_methods_uninit(void)
|
||||
psr_device_handle = NULL;
|
||||
psr_nv_acpi_object = NULL;
|
||||
}
|
||||
|
||||
if (nvif_parent_gpu_handle == NULL)
|
||||
return;
|
||||
|
||||
#if defined(NV_ACPI_BUS_GET_DEVICE_PRESENT)
|
||||
acpi_bus_get_device(nvif_parent_gpu_handle, &device);
|
||||
|
||||
nv_uninstall_notifier(device->driver_data, nv_acpi_event);
|
||||
#endif
|
||||
|
||||
device->driver_data = NULL;
|
||||
nvif_parent_gpu_handle = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static NV_STATUS nv_acpi_extract_integer(
|
||||
@@ -1763,16 +1335,6 @@ NvBool NV_API_CALL nv_acpi_is_battery_present(void)
|
||||
|
||||
#else // NV_LINUX_ACPI_EVENTS_SUPPORTED
|
||||
|
||||
int nv_acpi_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nv_acpi_uninit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NV_API_CALL nv_acpi_methods_init(NvU32 *handlePresent)
|
||||
{
|
||||
*handlePresent = 0;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "os-interface.h"
|
||||
#include "nv-linux.h"
|
||||
#include "nv-reg.h"
|
||||
|
||||
#define NV_DMA_DEV_PRINTF(debuglevel, dma_dev, format, ... ) \
|
||||
nv_printf(debuglevel, "NVRM: %s: " format, \
|
||||
@@ -32,6 +33,8 @@
|
||||
NULL), \
|
||||
## __VA_ARGS__)
|
||||
|
||||
NvU32 nv_dma_remap_peer_mmio = NV_DMA_REMAP_PEER_MMIO_ENABLE;
|
||||
|
||||
NV_STATUS nv_create_dma_map_scatterlist (nv_dma_map_t *dma_map);
|
||||
void nv_destroy_dma_map_scatterlist(nv_dma_map_t *dma_map);
|
||||
NV_STATUS nv_map_dma_map_scatterlist (nv_dma_map_t *dma_map);
|
||||
@@ -766,11 +769,16 @@ NV_STATUS NV_API_CALL nv_dma_unmap_alloc
|
||||
return status;
|
||||
}
|
||||
|
||||
static NvBool nv_dma_is_map_resource_implemented
|
||||
static NvBool nv_dma_use_map_resource
|
||||
(
|
||||
nv_dma_device_t *dma_dev
|
||||
)
|
||||
{
|
||||
if (nv_dma_remap_peer_mmio == NV_DMA_REMAP_PEER_MMIO_DISABLE)
|
||||
{
|
||||
return NV_FALSE;
|
||||
}
|
||||
|
||||
#if defined(NV_DMA_MAP_RESOURCE_PRESENT)
|
||||
const struct dma_map_ops *ops = get_dma_ops(dma_dev->dev);
|
||||
|
||||
@@ -833,7 +841,7 @@ NV_STATUS NV_API_CALL nv_dma_map_peer
|
||||
return NV_ERR_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
if (nv_dma_is_map_resource_implemented(dma_dev))
|
||||
if (nv_dma_use_map_resource(dma_dev))
|
||||
{
|
||||
status = nv_dma_map_mmio(dma_dev, page_count, va);
|
||||
}
|
||||
@@ -858,7 +866,7 @@ void NV_API_CALL nv_dma_unmap_peer
|
||||
NvU64 va
|
||||
)
|
||||
{
|
||||
if (nv_dma_is_map_resource_implemented(dma_dev))
|
||||
if (nv_dma_use_map_resource(dma_dev))
|
||||
{
|
||||
nv_dma_unmap_mmio(dma_dev, page_count, va);
|
||||
}
|
||||
@@ -873,29 +881,28 @@ NV_STATUS NV_API_CALL nv_dma_map_mmio
|
||||
)
|
||||
{
|
||||
#if defined(NV_DMA_MAP_RESOURCE_PRESENT)
|
||||
NvU64 mmio_addr;
|
||||
|
||||
BUG_ON(!va);
|
||||
|
||||
mmio_addr = *va;
|
||||
|
||||
*va = dma_map_resource(dma_dev->dev, mmio_addr, page_count * PAGE_SIZE,
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
if (dma_mapping_error(dma_dev->dev, *va))
|
||||
if (nv_dma_use_map_resource(dma_dev))
|
||||
{
|
||||
NV_DMA_DEV_PRINTF(NV_DBG_ERRORS, dma_dev,
|
||||
"Failed to DMA map MMIO range [0x%llx-0x%llx]\n",
|
||||
mmio_addr, mmio_addr + page_count * PAGE_SIZE - 1);
|
||||
return NV_ERR_OPERATING_SYSTEM;
|
||||
NvU64 mmio_addr = *va;
|
||||
*va = dma_map_resource(dma_dev->dev, mmio_addr, page_count * PAGE_SIZE,
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
if (dma_mapping_error(dma_dev->dev, *va))
|
||||
{
|
||||
NV_DMA_DEV_PRINTF(NV_DBG_ERRORS, dma_dev,
|
||||
"Failed to DMA map MMIO range [0x%llx-0x%llx]\n",
|
||||
mmio_addr, mmio_addr + page_count * PAGE_SIZE - 1);
|
||||
return NV_ERR_OPERATING_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The default implementation passes through the source address
|
||||
* without failing. Adjust it using the DMA start address to keep RM's
|
||||
* validation schemes happy.
|
||||
*/
|
||||
if (!nv_dma_is_map_resource_implemented(dma_dev))
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If dma_map_resource is not available, pass through the source address
|
||||
* without failing. Further, adjust it using the DMA start address to
|
||||
* keep RM's validation schemes happy.
|
||||
*/
|
||||
*va = *va + dma_dev->addressable_range.start;
|
||||
}
|
||||
|
||||
@@ -915,15 +922,13 @@ void NV_API_CALL nv_dma_unmap_mmio
|
||||
)
|
||||
{
|
||||
#if defined(NV_DMA_MAP_RESOURCE_PRESENT)
|
||||
if (!nv_dma_is_map_resource_implemented(dma_dev))
|
||||
{
|
||||
va = va - dma_dev->addressable_range.start;
|
||||
}
|
||||
|
||||
nv_dma_nvlink_addr_decompress(dma_dev, &va, page_count, NV_TRUE);
|
||||
|
||||
dma_unmap_resource(dma_dev->dev, va, page_count * PAGE_SIZE,
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
if (nv_dma_use_map_resource(dma_dev))
|
||||
{
|
||||
dma_unmap_resource(dma_dev->dev, va, page_count * PAGE_SIZE,
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef struct nv_dma_buf_file_private
|
||||
nv_dma_buf_mem_handle_t *handles;
|
||||
NvU64 bar1_va_ref_count;
|
||||
void *mig_info;
|
||||
NvBool can_mmap;
|
||||
} nv_dma_buf_file_private_t;
|
||||
|
||||
static void
|
||||
@@ -562,6 +563,8 @@ nv_dma_buf_mmap(
|
||||
struct vm_area_struct *vma
|
||||
)
|
||||
{
|
||||
// TODO: Check can_mmap flag
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
@@ -674,6 +677,7 @@ nv_dma_buf_create(
|
||||
priv->total_objects = params->totalObjects;
|
||||
priv->total_size = params->totalSize;
|
||||
priv->nv = nv;
|
||||
priv->can_mmap = NV_FALSE;
|
||||
|
||||
rc = nv_kmem_cache_alloc_stack(&sp);
|
||||
if (rc != 0)
|
||||
@@ -792,6 +796,15 @@ nv_dma_buf_reuse(
|
||||
return NV_ERR_OPERATING_SYSTEM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
priv = buf->priv;
|
||||
|
||||
if (priv == NULL)
|
||||
|
||||
@@ -301,23 +301,6 @@
|
||||
#define __NV_ENABLE_MSI EnableMSI
|
||||
#define NV_REG_ENABLE_MSI NV_REG_STRING(__NV_ENABLE_MSI)
|
||||
|
||||
/*
|
||||
* Option: RegisterForACPIEvents
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* When this option is enabled, the NVIDIA driver will register with the
|
||||
* ACPI subsystem to receive notification of ACPI events.
|
||||
*
|
||||
* Possible values:
|
||||
*
|
||||
* 1 - register for ACPI events (default)
|
||||
* 0 - do not register for ACPI events
|
||||
*/
|
||||
|
||||
#define __NV_REGISTER_FOR_ACPI_EVENTS RegisterForACPIEvents
|
||||
#define NV_REG_REGISTER_FOR_ACPI_EVENTS NV_REG_STRING(__NV_REGISTER_FOR_ACPI_EVENTS)
|
||||
|
||||
/*
|
||||
* Option: EnablePCIeGen3
|
||||
*
|
||||
@@ -819,6 +802,30 @@
|
||||
#define NV_REG_OPENRM_ENABLE_UNSUPPORTED_GPUS_ENABLE 0x00000001
|
||||
#define NV_REG_OPENRM_ENABLE_UNSUPPORTED_GPUS_DEFAULT NV_REG_OPENRM_ENABLE_UNSUPPORTED_GPUS_DISABLE
|
||||
|
||||
/*
|
||||
* Option: NVreg_DmaRemapPeerMmio
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* When this option is enabled, the NVIDIA driver will use device driver
|
||||
* APIs provided by the Linux kernel for DMA-remapping part of a device's
|
||||
* MMIO region to another device, creating e.g., IOMMU mappings as necessary.
|
||||
* When this option is disabled, the NVIDIA driver will instead only apply a
|
||||
* fixed offset, which may be zero, to CPU physical addresses to produce the
|
||||
* DMA address for the peer's MMIO region, and no IOMMU mappings will be
|
||||
* created.
|
||||
*
|
||||
* This option only affects peer MMIO DMA mappings, and not system memory
|
||||
* mappings.
|
||||
*
|
||||
* Possible Values:
|
||||
* 0 = disable dynamic DMA remapping of peer MMIO regions
|
||||
* 1 = enable dynamic DMA remapping of peer MMIO regions (default)
|
||||
*/
|
||||
#define __NV_DMA_REMAP_PEER_MMIO DmaRemapPeerMmio
|
||||
#define NV_DMA_REMAP_PEER_MMIO NV_REG_STRING(__NV_DMA_REMAP_PEER_MMIO)
|
||||
#define NV_DMA_REMAP_PEER_MMIO_DISABLE 0x00000000
|
||||
#define NV_DMA_REMAP_PEER_MMIO_ENABLE 0x00000001
|
||||
|
||||
#if defined(NV_DEFINE_REGISTRY_KEY_TABLE)
|
||||
|
||||
@@ -834,7 +841,6 @@ NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_GID, 0);
|
||||
NV_DEFINE_REG_ENTRY(__NV_DEVICE_FILE_MODE, 0666);
|
||||
NV_DEFINE_REG_ENTRY(__NV_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS, 1);
|
||||
NV_DEFINE_REG_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE, ~0);
|
||||
NV_DEFINE_REG_ENTRY(__NV_REGISTER_FOR_ACPI_EVENTS, 1);
|
||||
NV_DEFINE_REG_ENTRY(__NV_ENABLE_PCIE_GEN3, 0);
|
||||
NV_DEFINE_REG_ENTRY(__NV_ENABLE_MSI, 1);
|
||||
NV_DEFINE_REG_ENTRY(__NV_TCE_BYPASS_MODE, NV_TCE_BYPASS_MODE_DEFAULT);
|
||||
@@ -871,6 +877,7 @@ NV_DEFINE_REG_STRING_ENTRY(__NV_RM_MSG, NULL);
|
||||
NV_DEFINE_REG_STRING_ENTRY(__NV_GPU_BLACKLIST, NULL);
|
||||
NV_DEFINE_REG_STRING_ENTRY(__NV_TEMPORARY_FILE_PATH, NULL);
|
||||
NV_DEFINE_REG_STRING_ENTRY(__NV_EXCLUDED_GPUS, NULL);
|
||||
NV_DEFINE_REG_ENTRY(__NV_DMA_REMAP_PEER_MMIO, NV_DMA_REMAP_PEER_MMIO_ENABLE);
|
||||
|
||||
/*
|
||||
*----------------registry database definition----------------------
|
||||
@@ -893,7 +900,6 @@ nv_parm_t nv_parms[] = {
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_INITIALIZE_SYSTEM_MEMORY_ALLOCATIONS),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_USE_PAGE_ATTRIBUTE_TABLE),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_MSI),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_REGISTER_FOR_ACPI_EVENTS),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_PCIE_GEN3),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_MEMORY_POOL_SIZE),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_KMALLOC_HEAP_MAX_SIZE),
|
||||
@@ -918,6 +924,7 @@ nv_parm_t nv_parms[] = {
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_GPU_FIRMWARE_LOGS),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_ENABLE_DBG_BREAKPOINT),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_OPENRM_ENABLE_UNSUPPORTED_GPUS),
|
||||
NV_DEFINE_PARAMS_TABLE_ENTRY(__NV_DMA_REMAP_PEER_MMIO),
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ nv_linux_state_t *nv_linux_devices;
|
||||
* And one for the control device
|
||||
*/
|
||||
nv_linux_state_t nv_ctl_device = { { 0 } };
|
||||
extern NvU32 nv_dma_remap_peer_mmio;
|
||||
|
||||
nv_kthread_q_t nv_kthread_q;
|
||||
nv_kthread_q_t nv_deferred_close_kthread_q;
|
||||
@@ -571,6 +572,12 @@ nv_registry_keys_init(nv_stack_t *sp)
|
||||
WARN_ON(status != NV_OK);
|
||||
}
|
||||
}
|
||||
|
||||
status = rm_read_registry_dword(sp, nv, NV_DMA_REMAP_PEER_MMIO, &data);
|
||||
if (status == NV_OK)
|
||||
{
|
||||
nv_dma_remap_peer_mmio = data;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init
|
||||
@@ -2660,7 +2667,6 @@ nvidia_ctl_open(
|
||||
nv_linux_state_t *nvl = &nv_ctl_device;
|
||||
nv_state_t *nv = NV_STATE_PTR(nvl);
|
||||
nv_linux_file_private_t *nvlfp = NV_GET_LINUX_FILE_PRIVATE(file);
|
||||
static int count = 0;
|
||||
|
||||
nv_printf(NV_DBG_INFO, "NVRM: nvidia_ctl_open\n");
|
||||
|
||||
@@ -2672,13 +2678,6 @@ nvidia_ctl_open(
|
||||
if (NV_ATOMIC_READ(nvl->usage_count) == 0)
|
||||
{
|
||||
nv->flags |= (NV_FLAG_OPEN | NV_FLAG_CONTROL);
|
||||
|
||||
if ((nv_acpi_init() < 0) &&
|
||||
(count++ < NV_MAX_RECURRING_WARNING_MESSAGES))
|
||||
{
|
||||
nv_printf(NV_DBG_ERRORS,
|
||||
"NVRM: failed to register with the ACPI subsystem!\n");
|
||||
}
|
||||
}
|
||||
|
||||
NV_ATOMIC_INC(nvl->usage_count);
|
||||
@@ -2702,7 +2701,6 @@ nvidia_ctl_close(
|
||||
nv_state_t *nv = NV_STATE_PTR(nvl);
|
||||
nv_linux_file_private_t *nvlfp = NV_GET_LINUX_FILE_PRIVATE(file);
|
||||
nvidia_stack_t *sp = nvlfp->sp;
|
||||
static int count = 0;
|
||||
unsigned int i;
|
||||
|
||||
nv_printf(NV_DBG_INFO, "NVRM: nvidia_ctl_close\n");
|
||||
@@ -2711,13 +2709,6 @@ nvidia_ctl_close(
|
||||
if (NV_ATOMIC_DEC_AND_TEST(nvl->usage_count))
|
||||
{
|
||||
nv->flags &= ~NV_FLAG_OPEN;
|
||||
|
||||
if ((nv_acpi_uninit() < 0) &&
|
||||
(count++ < NV_MAX_RECURRING_WARNING_MESSAGES))
|
||||
{
|
||||
nv_printf(NV_DBG_ERRORS,
|
||||
"NVRM: failed to unregister from the ACPI subsystem!\n");
|
||||
}
|
||||
}
|
||||
up(&nvl->ldata_lock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user