diff --git a/.manifest b/.manifest
index c381a3f..471e477 100644
--- a/.manifest
+++ b/.manifest
@@ -408,10 +408,11 @@ kernel/common/inc/nvkms-api-types.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1
 kernel/common/inc/nvkms-kapi.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvkms
 kernel/nvidia-drm/nvidia-drm.c 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-helper.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-dma-fence-helper.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
+kernel/nvidia-drm/nvidia-dma-resv-helper.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-priv.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-connector.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-crtc.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-drv.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
 kernel/nvidia-drm/nvidia-drm-encoder.h 0644 KERNEL_MODULE_SRC INHERIT_PATH_DEPTH:1 MODULE:nvidia_drm
diff --git a/kernel/conftest.sh b/kernel/conftest.sh
index 40c54f6..5b1e3f8 100755
--- a/kernel/conftest.sh
+++ b/kernel/conftest.sh
@@ -96,10 +96,16 @@ test_headers() {
     FILES="$FILES drm/drm_atomic_uapi.h"
     FILES="$FILES drm/drm_drv.h"
     FILES="$FILES drm/drm_framebuffer.h"
     FILES="$FILES drm/drm_connector.h"
     FILES="$FILES drm/drm_probe_helper.h"
+    FILES="$FILES drm/drm_prime.h"
+    FILES="$FILES drm/drm_plane.h"
+    FILES="$FILES drm/drm_vblank.h"
+    FILES="$FILES drm/drm_file.h"
+    FILES="$FILES drm/drm_ioctl.h"
+    FILES="$FILES drm/drm_device.h"
     FILES="$FILES generated/autoconf.h"
     FILES="$FILES generated/compile.h"
     FILES="$FILES generated/utsrelease.h"
     FILES="$FILES linux/efi.h"
     FILES="$FILES linux/kconfig.h"
@@ -116,10 +122,11 @@ test_headers() {
     FILES="$FILES linux/sched/task_stack.h"
     FILES="$FILES xen/ioemu.h"
     FILES="$FILES linux/fence.h"
     FILES="$FILES soc/tegra/chip-id.h"
     FILES="$FILES video/nv_internal.h"
+    FILES="$FILES linux/dma-resv.h"
 
     # Arch specific headers which need testing
     FILES_ARCH="asm/book3s/64/hash-64k.h"
     FILES_ARCH="$FILES_ARCH asm/set_memory.h"
     FILES_ARCH="$FILES_ARCH asm/prom.h"
@@ -1019,13 +1026,23 @@ compile_test() {
             # Determine if the DRM subsystem is usable
             CODE="
             #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
             #endif
+
+            #if defined(NV_DRM_DRM_DRV_H_PRESENT)
+            #include <drm/drm_drv.h>
+            #endif
+
+            #if defined(NV_DRM_DRM_PRIME_H_PRESENT)
+            #include <drm/drm_prime.h>
+            #endif
+
             #if !defined(CONFIG_DRM) && !defined(CONFIG_DRM_MODULE)
             #error DRM not enabled
             #endif
+
             void conftest_drm_available(void) {
                 struct drm_driver drv;
 
                 /* 2013-01-15 89177644a7b6306e6084a89eab7e290f4bfef397 */
                 drv.gem_prime_pin = 0;
@@ -1703,11 +1720,14 @@ compile_test() {
             #
             # Removed by commit c5786fe5f1c5 ("drm: Goody bye, drm_bus!")
             # in v3.18 (2014-08-29)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             void conftest_drm_bus_present(void) {
                 struct drm_bus bus;
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_BUS_PRESENT" "" "types"
@@ -1722,11 +1742,14 @@ compile_test() {
             #
             # Removed by commit 42b21049fc26 ("drm: kill drm_bus->bus_type")
             # in v3.16 (2013-11-03)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             int conftest_drm_bus_has_bus_type(void) {
                 return offsetof(struct drm_bus, bus_type);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_BUS_HAS_BUS_TYPE" "" "types"
@@ -1741,11 +1764,14 @@ compile_test() {
             #
             # Removed by commit b2a21aa25a39 ("drm: remove bus->get_irq
             # implementations") in v3.16 (2013-11-03)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             int conftest_drm_bus_has_get_irq(void) {
                 return offsetof(struct drm_bus, get_irq);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_BUS_HAS_GET_IRQ" "" "types"
@@ -1760,11 +1786,14 @@ compile_test() {
             #
             # removed by commit 9de1b51f1fae ("drm: remove drm_bus->get_name")
             # in v3.16 (2013-11-03)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             int conftest_drm_bus_has_get_name(void) {
                 return offsetof(struct drm_bus, get_name);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_BUS_HAS_GET_NAME" "" "types"
@@ -1777,11 +1806,18 @@ compile_test() {
             # Renamed from device_list to legacy_device_list by commit
             # b3f2333de8e8 ("drm: restrict the device list for shadow
             # attached drivers") in v3.14 (2013-12-11)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
+            #if defined(NV_DRM_DRM_DRV_H_PRESENT)
+            #include <drm/drm_drv.h>
+            #endif
+
             int conftest_drm_driver_has_legacy_dev_list(void) {
                 return offsetof(struct drm_driver, legacy_dev_list);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_LEGACY_DEV_LIST" "" "types"
@@ -1801,11 +1837,17 @@ compile_test() {
             # Additionally determine whether drm_universal_plane_init() has a
             # 'format_modifiers' argument, which was added by:
             #   2017-07-23  e6fc3b68558e4c6d8d160b5daf2511b99afa8814
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
+            #if defined(NV_DRM_DRM_CRTC_H_PRESENT)
+            #include <drm/drm_crtc.h>
+            #endif
 
             int conftest_drm_crtc_init_with_planes_has_name_arg(void) {
                 return
                     drm_crtc_init_with_planes(
                             NULL,  /* struct drm_device *dev */
@@ -1817,11 +1859,17 @@ compile_test() {
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_CRTC_INIT_WITH_PLANES_HAS_NAME_ARG" "" "types"
 
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
+            #if defined(NV_DRM_DRM_ENCODER_H_PRESENT)
+            #include <drm/drm_encoder.h>
+            #endif
 
             int conftest_drm_encoder_init_has_name_arg(void) {
                 return
                     drm_encoder_init(
                             NULL,  /* struct drm_device *dev */
@@ -1832,11 +1880,17 @@ compile_test() {
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_ENCODER_INIT_HAS_NAME_ARG" "" "types"
 
             echo "$CONFTEST_PREAMBLE
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
+            #if defined(NV_DRM_DRM_PLANE_H_PRESENT)
+            #include <drm/drm_plane.h>
+            #endif
 
             int conftest_drm_universal_plane_init_has_format_modifiers_arg(void) {
                 return
                     drm_universal_plane_init(
                             NULL,  /* struct drm_device *dev */
@@ -1859,11 +1913,17 @@ compile_test() {
                 echo "#define NV_DRM_UNIVERSAL_PLANE_INIT_HAS_NAME_ARG" | append_conftest "types"
             else
                 echo "#undef NV_DRM_UNIVERSAL_PLANE_INIT_HAS_FORMAT_MODIFIERS_ARG" | append_conftest "types"
 
                 echo "$CONFTEST_PREAMBLE
+                #if defined(NV_DRM_DRMP_H_PRESENT)
                 #include <drm/drmP.h>
+                #endif
+
+                #if defined(NV_DRM_DRM_PLANE_H_PRESENT)
+                #include <drm/drm_plane.h>
+                #endif
 
                 int conftest_drm_universal_plane_init_has_name_arg(void) {
                     return
                         drm_universal_plane_init(
                                 NULL,  /* struct drm_device *dev */
@@ -1912,11 +1972,14 @@ compile_test() {
             #
             # Added by commit 915b4d11b8b9 ("drm: add driver->set_busid()
             # callback") in v3.18 (2014-08-29)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             int conftest_drm_driver_has_set_busid(void) {
                 return offsetof(struct drm_driver, set_busid);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_SET_BUSID" "" "types"
@@ -1929,11 +1992,13 @@ compile_test() {
             #
             # Added by commit 3aac4502fd3f ("dma-buf: use reservation
             # objects") in v3.17 (2014-07-01)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
             int conftest_drm_driver_has_gem_prime_res_obj(void) {
                 return offsetof(struct drm_driver, gem_prime_res_obj);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ" "" "types"
@@ -2422,11 +2487,14 @@ compile_test() {
             # Last argument 'bool from_release' has been removed by commit
             # d6ed682eba54 ("drm: Refactor drop/set master code a bit")
             # in v4.8 (2016-06-21)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             void conftest_drm_master_drop_has_from_release_arg(struct drm_driver *drv) {
                 drv->master_drop(NULL, NULL, false);
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_MASTER_DROP_HAS_FROM_RELEASE_ARG" "" "types"
@@ -2556,11 +2624,13 @@ compile_test() {
             #
             # Changed to void by commit 11b3c20bdd15 ("drm: Change the return
             # type of the unload hook to void") in v4.11 (2017-01-06)
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
 
             int conftest_drm_driver_unload_has_int_return_type(struct drm_driver *drv) {
                 return drv->unload(NULL /* dev */);
             }"
 
@@ -2938,14 +3008,18 @@ compile_test() {
             #
             # Added by commit a4a69da06bc1 ("drm: Introduce
             # drm_framebuffer_{get,put}()") in v4.12 (2017-02-28).
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             #if defined(NV_DRM_DRM_FRAMEBUFFER_H_PRESENT)
             #include <drm/drm_framebuffer.h>
             #endif
+
             void conftest_drm_framebuffer_get(void) {
                 drm_framebuffer_get();
             }"
 
             compile_check_conftest "$CODE" "NV_DRM_FRAMEBUFFER_GET_PRESENT" "" "functions"
@@ -2957,11 +3031,14 @@ compile_test() {
             #
             # Added by commit e6b62714e87c ("drm: Introduce
             # drm_gem_object_{get,put}()") in v4.12 (2017-02-28).
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             #if defined(NV_DRM_DRM_GEM_H_PRESENT)
             #include <drm/drm_gem.h>
             #endif
             void conftest_drm_gem_object_get(void) {
                 drm_gem_object_get();
@@ -2976,11 +3053,14 @@ compile_test() {
             #
             # Added by commit 9a96f55034e4 ("drm: introduce drm_dev_{get/put}
             # functions") in v4.15 (2017-09-26).
             #
             CODE="
+            #if defined(NV_DRM_DRMP_H_PRESENT)
             #include <drm/drmP.h>
+            #endif
+
             #if defined(NV_DRM_DRM_DRV_H_PRESENT)
             #include <drm/drm_drv.h>
             #endif
             void conftest_drm_dev_put(void) {
                 drm_dev_put();
@@ -3212,10 +3292,72 @@ compile_test() {
         # specifying the relevant upstream Linux kernel commit.
         #
         # <function> was added|removed|etc by commit <sha> ("<commit message")
         # in <kernel-version> (<commit date>).
 
+        drm_connector_for_each_possible_encoder)
+            #
+            # Determine the number of arguments of the
+            # drm_connector_for_each_possible_encoder() macro.
+            #
+            # drm_connector_for_each_possible_encoder() is added by commit
+            # 83aefbb887b5 (drm: Add drm_connector_for_each_possible_encoder())
+            # in v4.19. The definition and prorotype is changed to take only
+            # two arguments connector and encoder, by commit 62afb4ad425a
+            # (drm/connector: Allow max possible encoders to attach to a
+            # connector) in v5.5rc1.
+            #
+            echo "$CONFTEST_PREAMBLE
+            #if defined(NV_DRM_DRMP_H_PRESENT)
+            #include <drm/drmP.h>
+            #endif
+
+            #if defined(NV_DRM_CONNECTOR_H_PRESENT)
+            #include <drm/drm_connector.h>
+            #endif
+
+            void conftest_drm_connector_for_each_possible_encoder(
+                struct drm_connector *connector,
+                struct drm_encoder *encoder,
+                int i) {
+
+                drm_connector_for_each_possible_encoder(connector, encoder, i) {
+                }
+            }" > conftest$$.c
+
+            $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
+            rm -f conftest$$.c
+
+            if [ -f conftest$$.o ]; then
+                echo "#define NV_DRM_CONNECTOR_FOR_EACH_POSSIBLE_ENCODER_ARGUMENT_COUNT 3" | append_conftest "functions"
+                rm -f conftest$$.o
+                return
+            else
+                echo "#define NV_DRM_CONNECTOR_FOR_EACH_POSSIBLE_ENCODER_ARGUMENT_COUNT 2" | append_conftest "functions"
+            fi
+        ;;
+
+        drm_gem_object_has_resv)
+            #
+            # Determine if the 'drm_gem_object' structure has a 'resv' field.
+            #
+            # A 'resv' filed in the 'drm_gem_object' structure, is added by
+            # commit 1ba627148ef5 (drm: Add reservation_object to
+            # drm_gem_object) in v5.2.
+            #
+            CODE="$CONFTEST_PREAMBLE
+            #if defined(NV_DRM_DRM_GEM_H_PRESENT)
+            #include <drm/drm_gem.h>
+            #endif
+
+            int conftest_drm_gem_object_has_resv(void) {
+                return offsetof(struct drm_gem_object, resv);
+            }"
+
+            compile_check_conftest "$CODE" "NV_DRM_GEM_OBJECT_HAS_RESV" "" "types"
+        ;;
+
         *)
             # Unknown test name given
             echo "Error: unknown conftest '$1' requested" >&2
             exit 1
         ;;
diff --git a/kernel/nvidia-drm/nvidia-dma-fence-helper.h b/kernel/nvidia-drm/nvidia-dma-fence-helper.h
index 0aa5a4f..a09ab76 100644
--- a/kernel/nvidia-drm/nvidia-dma-fence-helper.h
+++ b/kernel/nvidia-drm/nvidia-dma-fence-helper.h
@@ -23,11 +23,11 @@
 #ifndef __NVIDIA_DMA_FENCE_HELPER_H__
 #define __NVIDIA_DMA_FENCE_HELPER_H__
 
 #include "nvidia-drm-conftest.h"
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
+#if defined(NV_DRM_FENCE_AVAILABLE)
 
 /*
  * Fence headers are moved to file dma-fence.h and struct fence has
  * been renamed to dma_fence by commit -
  *
@@ -38,12 +38,10 @@
 #include <linux/fence.h>
 #else
 #include <linux/dma-fence.h>
 #endif
 
-#include <linux/reservation.h>
-
 #if defined(NV_LINUX_FENCE_H_PRESENT)
 typedef struct fence nv_dma_fence_t;
 typedef struct fence_ops nv_dma_fence_ops_t;
 #else
 typedef struct dma_fence nv_dma_fence_t;
@@ -116,8 +114,8 @@ nv_dma_fence_init(nv_dma_fence_t *fence,
 #else
     dma_fence_init(fence, ops, lock, context, seqno);
 #endif
 }
 
-#endif /* defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ) */
+#endif /* defined(NV_DRM_FENCE_AVAILABLE) */
 
 #endif /* __NVIDIA_DMA_FENCE_HELPER_H__ */
diff --git a/kernel/nvidia-drm/nvidia-dma-resv-helper.h b/kernel/nvidia-drm/nvidia-dma-resv-helper.h
new file mode 100644
index 0000000..ad8800d
--- /dev/null
+++ b/kernel/nvidia-drm/nvidia-dma-resv-helper.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __NVIDIA_DMA_RESV_HELPER_H__
+#define __NVIDIA_DMA_RESV_HELPER_H__
+
+#include "nvidia-drm-conftest.h"
+
+#if defined(NV_DRM_FENCE_AVAILABLE)
+
+/*
+ * linux/reservation.h is renamed to linux/dma-resv.h, by commit
+ * 52791eeec1d9 (dma-buf: rename reservation_object to dma_resv)
+ * in v5.4.
+ */
+
+#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
+#include <linux/dma-resv.h>
+#else
+#include <linux/reservation.h>
+#endif
+
+#include <nvidia-dma-fence-helper.h>
+
+#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
+typedef struct dma_resv nv_dma_resv_t;
+#else
+typedef struct reservation_object nv_dma_resv_t;
+#endif
+
+static inline void nv_dma_resv_init(nv_dma_resv_t *obj)
+{
+#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
+    dma_resv_init(obj);
+#else
+    reservation_object_init(obj);
+#endif
+}
+
+static inline void nv_dma_resv_fini(nv_dma_resv_t *obj)
+{
+#if defined(NV_LINUX_DMA_RESV_H_PRESENT)
+    dma_resv_fini(obj);
+#else
+    reservation_object_init(obj);
+#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)
+    dma_resv_add_excl_fence(obj, fence);
+#else
+    reservation_object_add_excl_fence(obj, fence);
+#endif
+}
+
+#endif /* defined(NV_DRM_FENCE_AVAILABLE) */
+
+#endif /* __NVIDIA_DMA_RESV_HELPER_H__ */
diff --git a/kernel/nvidia-drm/nvidia-drm-conftest.h b/kernel/nvidia-drm/nvidia-drm-conftest.h
index 7775ed2..bed8d81 100644
--- a/kernel/nvidia-drm/nvidia-drm-conftest.h
+++ b/kernel/nvidia-drm/nvidia-drm-conftest.h
@@ -52,7 +52,13 @@
 
 #define refcount_dec_and_test(__ptr) atomic_dec_and_test(&(__ptr)->refs)
 
 #endif
 
+#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ) || \
+    defined(NV_DRM_GEM_OBJECT_HAS_RESV)
+#define NV_DRM_FENCE_AVAILABLE
+#else
+#undef NV_DRM_FENCE_AVAILABLE
+#endif
 
 #endif /* defined(__NVIDIA_DRM_CONFTEST_H__) */
diff --git a/kernel/nvidia-drm/nvidia-drm-connector.c b/kernel/nvidia-drm/nvidia-drm-connector.c
index 1553ebc..6fbcd63 100644
--- a/kernel/nvidia-drm/nvidia-drm-connector.c
+++ b/kernel/nvidia-drm/nvidia-drm-connector.c
@@ -56,24 +56,104 @@ static void nv_drm_connector_destroy(struct drm_connector *connector)
     }
 
     nv_drm_free(nv_connector);
 }
 
+static bool
+__nv_drm_detect_encoder(struct NvKmsKapiDynamicDisplayParams *pDetectParams,
+                        struct drm_connector *connector,
+                        struct drm_encoder *encoder)
+{
+    struct nv_drm_connector *nv_connector = to_nv_connector(connector);
+    struct drm_device *dev = connector->dev;
+    struct nv_drm_device *nv_dev = to_nv_device(dev);
+    struct nv_drm_encoder *nv_encoder;
+
+    /*
+     * DVI-I connectors can drive both digital and analog
+     * encoders.  If a digital connection has been forced then
+     * skip analog encoders.
+     */
+
+    if (connector->connector_type == DRM_MODE_CONNECTOR_DVII &&
+        connector->force == DRM_FORCE_ON_DIGITAL &&
+        encoder->encoder_type == DRM_MODE_ENCODER_DAC) {
+        return false;
+    }
+
+    nv_encoder = to_nv_encoder(encoder);
+
+    memset(pDetectParams, 0, sizeof(*pDetectParams));
+
+    pDetectParams->handle = nv_encoder->hDisplay;
+
+    switch (connector->force) {
+        case DRM_FORCE_ON:
+        case DRM_FORCE_ON_DIGITAL:
+            pDetectParams->forceConnected = NV_TRUE;
+            break;
+        case DRM_FORCE_OFF:
+            pDetectParams->forceDisconnected = NV_TRUE;
+            break;
+        case DRM_FORCE_UNSPECIFIED:
+            break;
+    }
+
+    if (connector->override_edid) {
+        const struct drm_property_blob *edid = connector->edid_blob_ptr;
+
+        if (edid->length <= sizeof(pDetectParams->edid.buffer)) {
+            memcpy(pDetectParams->edid.buffer, edid->data, edid->length);
+            pDetectParams->edid.bufferSize = edid->length;
+            pDetectParams->overrideEdid = NV_TRUE;
+        } else {
+            WARN_ON(edid->length >
+                    sizeof(pDetectParams->edid.buffer));
+        }
+    }
+
+    if (!nvKms->getDynamicDisplayInfo(nv_dev->pDevice, pDetectParams)) {
+        NV_DRM_DEV_LOG_ERR(
+            nv_dev,
+            "Failed to detect display state");
+        return false;
+    }
+
+    if (pDetectParams->connected) {
+        if (!pDetectParams->overrideEdid && pDetectParams->edid.bufferSize) {
+
+            if ((nv_connector->edid = nv_drm_calloc(
+                        1,
+                        pDetectParams->edid.bufferSize)) != NULL) {
+
+                memcpy(nv_connector->edid,
+                       pDetectParams->edid.buffer,
+                       pDetectParams->edid.bufferSize);
+            } else {
+                NV_DRM_LOG_ERR("Out of Memory");
+            }
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
 static enum drm_connector_status __nv_drm_connector_detect_internal(
     struct drm_connector *connector)
 {
     struct drm_device *dev = connector->dev;
-    struct nv_drm_device *nv_dev = to_nv_device(dev);
     struct nv_drm_connector *nv_connector = to_nv_connector(connector);
 
     enum drm_connector_status status = connector_status_disconnected;
 
     struct drm_encoder *detected_encoder = NULL;
     struct nv_drm_encoder *nv_detected_encoder = NULL;
+    struct drm_encoder *encoder;
 
     struct NvKmsKapiDynamicDisplayParams *pDetectParams = NULL;
-    unsigned int i;
 
     BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
 
     if (nv_connector->edid != NULL) {
         nv_drm_free(nv_connector->edid);
@@ -85,94 +165,16 @@ static enum drm_connector_status __nv_drm_connector_detect_internal(
                 sizeof(*pDetectParams))) == NULL) {
         WARN_ON(pDetectParams == NULL);
         goto done;
     }
 
-    for (i = 0;
-         i < DRM_CONNECTOR_MAX_ENCODER && detected_encoder == NULL; i++) {
-        struct drm_encoder *encoder;
-        struct nv_drm_encoder *nv_encoder;
-
-        if (connector->encoder_ids[i] == 0) {
-            break;
-        }
-
-        encoder = nv_drm_encoder_find(dev, connector->encoder_ids[i]);
-
-        if (encoder == NULL) {
-            BUG_ON(encoder != NULL);
-            continue;
-        }
-
-        /*
-         * DVI-I connectors can drive both digital and analog
-         * encoders.  If a digital connection has been forced then
-         * skip analog encoders.
-         */
-
-        if (connector->connector_type == DRM_MODE_CONNECTOR_DVII &&
-            connector->force == DRM_FORCE_ON_DIGITAL &&
-            encoder->encoder_type == DRM_MODE_ENCODER_DAC) {
-            continue;
-        }
-
-        nv_encoder = to_nv_encoder(encoder);
-
-        memset(pDetectParams, 0, sizeof(*pDetectParams));
-
-        pDetectParams->handle = nv_encoder->hDisplay;
-
-        switch (connector->force) {
-            case DRM_FORCE_ON:
-            case DRM_FORCE_ON_DIGITAL:
-                pDetectParams->forceConnected = NV_TRUE;
-                break;
-            case DRM_FORCE_OFF:
-                pDetectParams->forceDisconnected = NV_TRUE;
-                break;
-            case DRM_FORCE_UNSPECIFIED:
-                break;
-        }
-
-        if (connector->override_edid) {
-            const struct drm_property_blob *edid = connector->edid_blob_ptr;
-
-            if (edid->length <= sizeof(pDetectParams->edid.buffer)) {
-                memcpy(pDetectParams->edid.buffer, edid->data, edid->length);
-                pDetectParams->edid.bufferSize = edid->length;
-                pDetectParams->overrideEdid = NV_TRUE;
-            } else {
-                WARN_ON(edid->length >
-                        sizeof(pDetectParams->edid.buffer));
-            }
-        }
-
-        if (!nvKms->getDynamicDisplayInfo(nv_dev->pDevice, pDetectParams)) {
-            NV_DRM_DEV_LOG_ERR(
-                nv_dev,
-                "Failed to detect display state");
-            continue;
-        }
-
-        if (pDetectParams->connected) {
-            if (!pDetectParams->overrideEdid && pDetectParams->edid.bufferSize) {
-
-                if ((nv_connector->edid = nv_drm_calloc(
-                            1,
-                            pDetectParams->edid.bufferSize)) != NULL) {
-
-                    memcpy(nv_connector->edid,
-                           pDetectParams->edid.buffer,
-                           pDetectParams->edid.bufferSize);
-                } else {
-                    NV_DRM_LOG_ERR("Out of Memory");
-                }
-            }
-
+    nv_drm_connector_for_each_possible_encoder(connector, encoder) {
+        if (__nv_drm_detect_encoder(pDetectParams, connector, encoder)) {
             detected_encoder = encoder;
+            break;
         }
-    }
+    } nv_drm_connector_for_each_possible_encoder_end;
 
     if (detected_encoder == NULL) {
         goto done;
     }
 
diff --git a/kernel/nvidia-drm/nvidia-drm-connector.h b/kernel/nvidia-drm/nvidia-drm-connector.h
index f74e22c..fd83d7a 100644
--- a/kernel/nvidia-drm/nvidia-drm-connector.h
+++ b/kernel/nvidia-drm/nvidia-drm-connector.h
@@ -25,11 +25,17 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_CONNECTOR_H_PRESENT)
+#include <drm/drm_connector.h>
+#endif
 
 #include "nvtypes.h"
 #include "nvkms-api-types.h"
 
 struct nv_drm_connector {
diff --git a/kernel/nvidia-drm/nvidia-drm-crtc.h b/kernel/nvidia-drm/nvidia-drm-crtc.h
index 0a70f2f..410a6f4 100644
--- a/kernel/nvidia-drm/nvidia-drm-crtc.h
+++ b/kernel/nvidia-drm/nvidia-drm-crtc.h
@@ -27,11 +27,16 @@
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
 #include "nvidia-drm-helper.h"
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#include <drm/drm_crtc.h>
+
 #include "nvtypes.h"
 #include "nvkms-kapi.h"
 
 struct nv_drm_crtc {
     NvU32 head;
diff --git a/kernel/nvidia-drm/nvidia-drm-drv.c b/kernel/nvidia-drm/nvidia-drm-drv.c
index 7eefe95..57ab47e 100644
--- a/kernel/nvidia-drm/nvidia-drm-drv.c
+++ b/kernel/nvidia-drm/nvidia-drm-drv.c
@@ -37,11 +37,31 @@
 
 #if defined(NV_DRM_AVAILABLE)
 
 #include "nvidia-drm-ioctl.h"
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_VBLANK_H_PRESENT)
+#include <drm/drm_vblank.h>
+#endif
+
+#if defined(NV_DRM_DRM_FILE_H_PRESENT)
+#include <drm/drm_file.h>
+#endif
+
+#if defined(NV_DRM_DRM_PRIME_H_PRESENT)
+#include <drm/drm_prime.h>
+#endif
+
+#if defined(NV_DRM_DRM_IOCTL_H_PRESENT)
+#include <drm/drm_ioctl.h>
+#endif
+
+#include <linux/pci.h>
 #include <linux/version.h>
 
 /*
  * Commit fcd70cd36b9b ("drm: Split out drm_probe_helper.h")
  * moves a number of helper function definitions from
@@ -631,11 +651,11 @@ static const struct drm_ioctl_desc nv_drm_ioctls[] = {
                       DRM_RENDER_ALLOW|DRM_UNLOCKED),
     DRM_IOCTL_DEF_DRV(NVIDIA_GET_DEV_INFO,
                       nv_drm_get_dev_info_ioctl,
                       DRM_RENDER_ALLOW|DRM_UNLOCKED),
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
+#if defined(NV_DRM_FENCE_AVAILABLE)
     DRM_IOCTL_DEF_DRV(NVIDIA_FENCE_SUPPORTED,
                       nv_drm_fence_supported_ioctl,
                       DRM_RENDER_ALLOW|DRM_UNLOCKED),
     DRM_IOCTL_DEF_DRV(NVIDIA_FENCE_CONTEXT_CREATE,
                       nv_drm_fence_context_create_ioctl,
diff --git a/kernel/nvidia-drm/nvidia-drm-fb.h b/kernel/nvidia-drm/nvidia-drm-fb.h
index 7f292ce..bfa93fd 100644
--- a/kernel/nvidia-drm/nvidia-drm-fb.h
+++ b/kernel/nvidia-drm/nvidia-drm-fb.h
@@ -25,11 +25,18 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_FRAMEBUFFER_H_PRESENT)
+#include <drm/drm_framebuffer.h>
+#endif
+
 #include "nvidia-drm-gem-nvkms-memory.h"
 #include "nvkms-kapi.h"
 
 struct nv_drm_framebuffer {
     struct NvKmsKapiSurface *pSurface;
diff --git a/kernel/nvidia-drm/nvidia-drm-gem-nvkms-memory.c b/kernel/nvidia-drm/nvidia-drm-gem-nvkms-memory.c
index c22edc5..0268d25 100644
--- a/kernel/nvidia-drm/nvidia-drm-gem-nvkms-memory.c
+++ b/kernel/nvidia-drm/nvidia-drm-gem-nvkms-memory.c
@@ -26,10 +26,16 @@
 
 #include "nv-linux.h"
 #include "nvidia-drm-gem-nvkms-memory.h"
 #include "nvidia-drm-ioctl.h"
 
+#if defined(NV_DRM_DRM_DRV_H_PRESENT)
+#include <drm/drm_drv.h>
+#endif
+
+#include <linux/io.h>
+
 #include "nv-mm.h"
 
 static void __nv_drm_gem_nvkms_memory_free(struct nv_drm_gem_object *nv_gem)
 {
     struct nv_drm_device *nv_dev = nv_gem->nv_dev;
diff --git a/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c b/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
index 5923173..5109767 100644
--- a/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
+++ b/kernel/nvidia-drm/nvidia-drm-gem-user-memory.c
@@ -22,10 +22,14 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
+#if defined(NV_DRM_DRM_PRIME_H_PRESENT)
+#include <drm/drm_prime.h>
+#endif
+
 #include "nvidia-drm-gem-user-memory.h"
 #include "nvidia-drm-ioctl.h"
 
 static inline
 void __nv_drm_gem_user_memory_free(struct nv_drm_gem_object *nv_gem)
diff --git a/kernel/nvidia-drm/nvidia-drm-gem.c b/kernel/nvidia-drm/nvidia-drm-gem.c
index 7201ade..c993d0e 100644
--- a/kernel/nvidia-drm/nvidia-drm-gem.c
+++ b/kernel/nvidia-drm/nvidia-drm-gem.c
@@ -27,15 +27,24 @@
 #include "nvidia-drm-priv.h"
 #include "nvidia-drm-ioctl.h"
 #include "nvidia-drm-prime-fence.h"
 #include "nvidia-drm-gem.h"
 #include "nvidia-drm-gem-nvkms-memory.h"
+#include "nvidia-dma-resv-helper.h"
 
 #if defined(NV_DMA_BUF_OWNER_PRESENT)
 #include "linux/dma-buf.h" /* To inspect dma_buf->owner during prime import */
 #endif
 
+#if defined(NV_DRM_DRM_DRV_H_PRESENT)
+#include <drm/drm_drv.h>
+#endif
+
+#if defined(NV_DRM_DRM_PRIME_H_PRESENT)
+#include <drm/drm_prime.h>
+#endif
+
 void nv_drm_gem_free(struct drm_gem_object *gem)
 {
     struct drm_device *dev = gem->dev;
     struct nv_drm_gem_object *nv_gem = to_nv_gem_object(gem);
 
@@ -43,12 +52,12 @@ void nv_drm_gem_free(struct drm_gem_object *gem)
 
     /* Cleanup core gem object */
 
     drm_gem_object_release(&nv_gem->base);
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
-    reservation_object_fini(&nv_gem->resv);
+#if defined(NV_DRM_FENCE_AVAILABLE) && !defined(NV_DRM_GEM_OBJECT_HAS_RESV)
+    nv_dma_resv_fini(&nv_gem->resv);
 #endif
 
     nv_gem->ops->free(nv_gem);
 }
 
@@ -111,11 +120,11 @@ void nv_drm_gem_prime_vunmap(struct drm_gem_object *gem, void *address)
         nv_gem->ops->prime_vunmap(nv_gem, address);
     }
 }
 
 #if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
-struct reservation_object* nv_drm_gem_prime_res_obj(struct drm_gem_object *obj)
+nv_dma_resv_t* nv_drm_gem_prime_res_obj(struct drm_gem_object *obj)
 {
     struct nv_drm_gem_object *nv_gem = to_nv_gem_object(obj);
 
     return &nv_gem->resv;
 }
diff --git a/kernel/nvidia-drm/nvidia-drm-gem.h b/kernel/nvidia-drm/nvidia-drm-gem.h
index b621969..222c385 100644
--- a/kernel/nvidia-drm/nvidia-drm-gem.h
+++ b/kernel/nvidia-drm/nvidia-drm-gem.h
@@ -27,17 +27,23 @@
 
 #if defined(NV_DRM_AVAILABLE)
 
 #include "nvidia-drm-priv.h"
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
-#include "nvkms-kapi.h"
+#endif
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
+#if defined(NV_DRM_DRM_GEM_H_PRESENT)
+#include <drm/drm_gem.h>
+#endif
 
-#include "nvidia-dma-fence-helper.h"
+#include "nvkms-kapi.h"
 
+#if defined(NV_DRM_FENCE_AVAILABLE)
+#include "nvidia-dma-fence-helper.h"
+#include "nvidia-dma-resv-helper.h"
 #endif
 
 struct nv_drm_gem_object;
 
 struct nv_drm_gem_object_funcs {
@@ -53,12 +59,12 @@ struct nv_drm_gem_object {
     struct drm_gem_object base;
 
     struct nv_drm_device *nv_dev;
     const struct nv_drm_gem_object_funcs *ops;
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
-    struct reservation_object resv;
+#if defined(NV_DRM_FENCE_AVAILABLE)
+    nv_dma_resv_t  resv;
 #endif
 };
 
 static inline struct nv_drm_gem_object *to_nv_gem_object(
     struct drm_gem_object *gem)
@@ -122,15 +128,20 @@ void nv_drm_gem_object_init(struct nv_drm_device *nv_dev,
     nv_gem->nv_dev = nv_dev;
     nv_gem->ops = ops;
 
     /* Initialize the gem object */
 
-    drm_gem_private_object_init(dev, &nv_gem->base, size);
+#if defined(NV_DRM_FENCE_AVAILABLE)
+    nv_dma_resv_init(&nv_gem->resv);
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
-    reservation_object_init(&nv_gem->resv);
+#if defined(NV_DRM_GEM_OBJECT_HAS_RESV)
+    nv_gem->base.resv = &nv_gem->resv;
 #endif
+
+#endif
+
+    drm_gem_private_object_init(dev, &nv_gem->base, size);
 }
 
 static inline int nv_drm_gem_create_mmap_offset(
     struct nv_drm_gem_object *nv_gem,
     uint64_t *offset)
@@ -183,11 +194,11 @@ struct sg_table *nv_drm_gem_prime_get_sg_table(struct drm_gem_object *gem);
 void *nv_drm_gem_prime_vmap(struct drm_gem_object *gem);
 
 void nv_drm_gem_prime_vunmap(struct drm_gem_object *gem, void *address);
 
 #if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
-struct reservation_object* nv_drm_gem_prime_res_obj(struct drm_gem_object *obj);
+nv_dma_resv_t* nv_drm_gem_prime_res_obj(struct drm_gem_object *obj);
 #endif
 
 #endif /* NV_DRM_AVAILABLE */
 
 #endif /* __NVIDIA_DRM_GEM_H__ */
diff --git a/kernel/nvidia-drm/nvidia-drm-helper.c b/kernel/nvidia-drm/nvidia-drm-helper.c
index da602ac..601a9c3 100644
--- a/kernel/nvidia-drm/nvidia-drm-helper.c
+++ b/kernel/nvidia-drm/nvidia-drm-helper.c
@@ -29,11 +29,14 @@
 
 #include "nvidia-drm-helper.h"
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
 #if defined(NV_DRM_DRM_ATOMIC_UAPI_H_PRESENT)
 #include <drm/drm_atomic_uapi.h>
 #endif
 
 static void __nv_drm_framebuffer_put(struct drm_framebuffer *fb)
diff --git a/kernel/nvidia-drm/nvidia-drm-helper.h b/kernel/nvidia-drm/nvidia-drm-helper.h
index 8f050d8..2489924 100644
--- a/kernel/nvidia-drm/nvidia-drm-helper.h
+++ b/kernel/nvidia-drm/nvidia-drm-helper.h
@@ -25,11 +25,17 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_DRV_H_PRESENT)
+#include <drm/drm_drv.h>
+#endif
 
 /*
  * drm_dev_put() is added by commit 9a96f55034e41b4e002b767e9218d55f03bdff7d
  * (2017-09-26) and drm_dev_unref() is removed by
  * ba1d345401476a5f7fbad622607c5a1f95e59b31 (2018-11-15).
@@ -274,10 +280,100 @@ static inline struct drm_encoder *nv_drm_encoder_find(struct drm_device *dev,
 #else
     return drm_encoder_find(dev, id);
 #endif
 }
 
+/*
+ * drm_connector_for_each_possible_encoder() is added by commit
+ * 83aefbb887b59df0b3520965c3701e01deacfc52 which was Signed-off-by:
+ *     Ville Syrjälä <ville.syrjala@linux.intel.com>
+ *
+ * drm_connector_for_each_possible_encoder() is copied from
+ * include/drm/drm_connector.h and modified to use nv_drm_encoder_find()
+ * instead of drm_encoder_find().
+ *
+ * drm_connector_for_each_possible_encoder() is copied from
+ *      include/drm/drm_connector.h @
+ *      83aefbb887b59df0b3520965c3701e01deacfc52
+ * which has the following copyright and license information:
+ *
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#if defined(NV_DRM_DRM_CONNECTOR_H_PRESENT)
+#include <drm/drm_connector.h>
+#endif
+
+/**
+ * nv_drm_connector_for_each_possible_encoder - iterate connector's possible
+ * encoders
+ * @connector: &struct drm_connector pointer
+ * @encoder: &struct drm_encoder pointer used as cursor
+ * @__i: int iteration cursor, for macro-internal use
+ */
+#if !defined(drm_connector_for_each_possible_encoder)
+
+#if !defined(for_each_if)
+#define for_each_if(condition) if (!(condition)) {} else
+#endif
+
+#define __nv_drm_connector_for_each_possible_encoder(connector, encoder, __i) \
+       for ((__i) = 0; (__i) < ARRAY_SIZE((connector)->encoder_ids) &&        \
+                    (connector)->encoder_ids[(__i)] != 0; (__i)++)            \
+               for_each_if((encoder) =                                        \
+                           nv_drm_encoder_find((connector)->dev,              \
+                                               (connector)->encoder_ids[(__i)]))
+
+#define nv_drm_connector_for_each_possible_encoder(connector, encoder) \
+    {                                                                  \
+        unsigned int __i;                                              \
+        __nv_drm_connector_for_each_possible_encoder(connector, encoder, __i)
+
+#define nv_drm_connector_for_each_possible_encoder_end \
+    }
+
+#else
+
+#if NV_DRM_CONNECTOR_FOR_EACH_POSSIBLE_ENCODER_ARGUMENT_COUNT == 3
+
+#define nv_drm_connector_for_each_possible_encoder(connector, encoder) \
+    {                                                                  \
+        unsigned int __i;                                              \
+        drm_connector_for_each_possible_encoder(connector, encoder, __i)
+
+#define nv_drm_connector_for_each_possible_encoder_end \
+    }
+
+#else
+
+#define nv_drm_connector_for_each_possible_encoder(connector, encoder) \
+    drm_connector_for_each_possible_encoder(connector, encoder)
+
+#define nv_drm_connector_for_each_possible_encoder_end
+
+#endif
+
+#endif
+
 static inline int
 nv_drm_connector_attach_encoder(struct drm_connector *connector,
                                 struct drm_encoder *encoder)
 {
 #if defined(NV_DRM_CONNECTOR_FUNCS_HAVE_MODE_IN_NAME)
diff --git a/kernel/nvidia-drm/nvidia-drm-linux.c b/kernel/nvidia-drm/nvidia-drm-linux.c
index b60304b..1d3e658 100644
--- a/kernel/nvidia-drm/nvidia-drm-linux.c
+++ b/kernel/nvidia-drm/nvidia-drm-linux.c
@@ -29,10 +29,16 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
+#include <drm/drmP.h>
+#endif
+
+#include <linux/vmalloc.h>
+
 #include "nv-mm.h"
 
 MODULE_PARM_DESC(
     modeset,
     "Enable atomic kernel modesetting (1 = enable, 0 = disable (default))");
diff --git a/kernel/nvidia-drm/nvidia-drm-modeset.c b/kernel/nvidia-drm/nvidia-drm-modeset.c
index 0d80def..4a1d672 100644
--- a/kernel/nvidia-drm/nvidia-drm-modeset.c
+++ b/kernel/nvidia-drm/nvidia-drm-modeset.c
@@ -28,10 +28,18 @@
 #include "nvidia-drm-modeset.h"
 #include "nvidia-drm-crtc.h"
 #include "nvidia-drm-os-interface.h"
 #include "nvidia-drm-helper.h"
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
+#include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_VBLANK_H_PRESENT)
+#include <drm/drm_vblank.h>
+#endif
+
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 
 struct nv_drm_atomic_state {
diff --git a/kernel/nvidia-drm/nvidia-drm-modeset.h b/kernel/nvidia-drm/nvidia-drm-modeset.h
index e2cb5c3..effb990 100644
--- a/kernel/nvidia-drm/nvidia-drm-modeset.h
+++ b/kernel/nvidia-drm/nvidia-drm-modeset.h
@@ -25,11 +25,14 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
-#include <drm/drmP.h>
+#include "nvkms-kapi.h"
+
+struct drm_device;
+struct drm_atomic_state;
 
 struct drm_atomic_state *nv_drm_atomic_state_alloc(struct drm_device *dev);
 void nv_drm_atomic_state_clear(struct drm_atomic_state *state);
 void nv_drm_atomic_state_free(struct drm_atomic_state *state);
 
diff --git a/kernel/nvidia-drm/nvidia-drm-os-interface.h b/kernel/nvidia-drm/nvidia-drm-os-interface.h
index f43f851..ac52752 100644
--- a/kernel/nvidia-drm/nvidia-drm-os-interface.h
+++ b/kernel/nvidia-drm/nvidia-drm-os-interface.h
@@ -27,11 +27,11 @@
 
 #include "nvtypes.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
-#include <drm/drmP.h>
+struct page;
 
 /* Set to true when the atomic modeset feature is enabled. */
 extern bool nv_drm_modeset_module_param;
 
 void *nv_drm_calloc(size_t nmemb, size_t size);
diff --git a/kernel/nvidia-drm/nvidia-drm-prime-fence.c b/kernel/nvidia-drm/nvidia-drm-prime-fence.c
index 1f10940..ee53060 100644
--- a/kernel/nvidia-drm/nvidia-drm-prime-fence.c
+++ b/kernel/nvidia-drm/nvidia-drm-prime-fence.c
@@ -22,16 +22,21 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
+#include <drm/drmP.h>
+#endif
+
 #include "nvidia-drm-priv.h"
 #include "nvidia-drm-ioctl.h"
 #include "nvidia-drm-gem.h"
 #include "nvidia-drm-prime-fence.h"
+#include "nvidia-dma-resv-helper.h"
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
+#if defined(NV_DRM_FENCE_AVAILABLE)
 
 #include "nvidia-dma-fence-helper.h"
 
 struct nv_drm_fence_context {
     struct nv_drm_device *nv_dev;
@@ -516,11 +521,11 @@ int nv_drm_gem_fence_attach_ioctl(struct drm_device *dev,
             "Failed to allocate fence: 0x%08x", p->handle);
 
         goto fence_context_create_fence_failed;
     }
 
-    reservation_object_add_excl_fence(&nv_gem->resv, fence);
+    nv_dma_resv_add_excl_fence(&nv_gem->resv, fence);
 
     ret = 0;
 
 fence_context_create_fence_failed:
     nv_drm_gem_object_unreference_unlocked(&nv_gem_fence_context->base);
@@ -530,8 +535,8 @@ fence_context_lookup_failed:
 
 done:
     return ret;
 }
 
-#endif /* NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ */
+#endif /* NV_DRM_FENCE_AVAILABLE */
 
 #endif /* NV_DRM_AVAILABLE */
diff --git a/kernel/nvidia-drm/nvidia-drm-prime-fence.h b/kernel/nvidia-drm/nvidia-drm-prime-fence.h
index 20da923..5afa2ae 100644
--- a/kernel/nvidia-drm/nvidia-drm-prime-fence.h
+++ b/kernel/nvidia-drm/nvidia-drm-prime-fence.h
@@ -25,23 +25,24 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_AVAILABLE)
 
-#include <drm/drmP.h>
+struct drm_file;
+struct drm_device;
 
-#if defined(NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ)
+#if defined(NV_DRM_FENCE_AVAILABLE)
 
 int nv_drm_fence_supported_ioctl(struct drm_device *dev,
                                  void *data, struct drm_file *filep);
 
 int nv_drm_fence_context_create_ioctl(struct drm_device *dev,
                                       void *data, struct drm_file *filep);
 
 int nv_drm_gem_fence_attach_ioctl(struct drm_device *dev,
                                   void *data, struct drm_file *filep);
 
-#endif /* NV_DRM_DRIVER_HAS_GEM_PRIME_RES_OBJ */
+#endif /* NV_DRM_FENCE_AVAILABLE */
 
 #endif /* NV_DRM_AVAILABLE */
 
 #endif /* __NVIDIA_DRM_PRIME_FENCE_H__ */
diff --git a/kernel/nvidia-drm/nvidia-drm-priv.h b/kernel/nvidia-drm/nvidia-drm-priv.h
index 9076835..fce7153 100644
--- a/kernel/nvidia-drm/nvidia-drm-priv.h
+++ b/kernel/nvidia-drm/nvidia-drm-priv.h
@@ -25,11 +25,17 @@
 
 #include "nvidia-drm-conftest.h" /* NV_DRM_AVAILABLE */
 
 #if defined(NV_DRM_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
 #include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_DEVICE_H_PRESENT)
+#include <drm/drm_device.h>
+#endif
 
 #if defined(NV_DRM_DRM_GEM_H_PRESENT)
 #include <drm/drm_gem.h>
 #endif
 
diff --git a/kernel/nvidia-drm/nvidia-drm-utils.c b/kernel/nvidia-drm/nvidia-drm-utils.c
index ac1097e..8cb2d5e 100644
--- a/kernel/nvidia-drm/nvidia-drm-utils.c
+++ b/kernel/nvidia-drm/nvidia-drm-utils.c
@@ -22,10 +22,21 @@
 
 #include "nvidia-drm-conftest.h" /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
+#if defined(NV_DRM_DRMP_H_PRESENT)
+#include <drm/drmP.h>
+#endif
+
+#if defined(NV_DRM_DRM_PLANE_H_PRESENT)
+#include <drm/drm_plane.h>
+#endif
+
+#include <drm/drm_modes.h>
+#include <uapi/drm/drm_fourcc.h>
+
 #include "nvidia-drm-priv.h"
 #include "nvidia-drm-utils.h"
 
 struct NvKmsKapiConnectorInfo*
 nvkms_get_connector_info(struct NvKmsKapiDevice *pDevice,
diff --git a/kernel/nvidia-drm/nvidia-drm-utils.h b/kernel/nvidia-drm/nvidia-drm-utils.h
index 33bf60c..4801b5e 100644
--- a/kernel/nvidia-drm/nvidia-drm-utils.h
+++ b/kernel/nvidia-drm/nvidia-drm-utils.h
@@ -25,13 +25,15 @@
 
 #include "nvidia-drm-conftest.h"
 
 #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE)
 
-#include <drm/drmP.h>
 #include "nvkms-kapi.h"
 
+enum drm_plane_type;
+struct drm_display_mode;
+
 struct NvKmsKapiConnectorInfo*
 nvkms_get_connector_info(struct NvKmsKapiDevice *pDevice,
                          NvKmsKapiConnector hConnector);
 
 int nvkms_connector_signal_to_drm_encoder_signal(
diff --git a/kernel/nvidia-drm/nvidia-drm.Kbuild b/kernel/nvidia-drm/nvidia-drm.Kbuild
index 921deea..f4ef5f0 100644
--- a/kernel/nvidia-drm/nvidia-drm.Kbuild
+++ b/kernel/nvidia-drm/nvidia-drm.Kbuild
@@ -63,10 +63,11 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_atomic_helper_connector_dpms
 NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_funcs_have_mode_in_name
 NV_CONFTEST_FUNCTION_COMPILE_TESTS += vmf_insert_pfn
 NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_framebuffer_get
 NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_gem_object_get
 NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_dev_put
+NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_for_each_possible_encoder
 
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_present
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_has_bus_type
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_has_get_irq
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_bus_has_get_name
@@ -83,5 +84,6 @@ NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_helper_crtc_destroy_state_has_crtc_
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_crtc_helper_funcs_has_atomic_enable
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_mode_object_find_has_file_priv_arg
 NV_CONFTEST_TYPE_COMPILE_TESTS += dma_buf_owner
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_connector_list_iter
 NV_CONFTEST_TYPE_COMPILE_TESTS += drm_atomic_helper_swap_state_has_stall_arg
+NV_CONFTEST_TYPE_COMPILE_TESTS += drm_gem_object_has_resv
diff --git a/kernel/nvidia/nv-vm.c b/kernel/nvidia/nv-vm.c
index 09cd39b..2fca12a 100644
--- a/kernel/nvidia/nv-vm.c
+++ b/kernel/nvidia/nv-vm.c
@@ -233,11 +233,13 @@ static unsigned int nv_compute_gfp_mask(
         if (dev && dev->dma_mask && (*(dev->dma_mask) < max_sysmem_address))
         {
             gfp_mask = NV_GFP_DMA32;
         }
     }
-#if defined(__GFP_NORETRY)
+#if defined(__GFP_RETRY_MAYFAIL)
+    gfp_mask |= __GFP_RETRY_MAYFAIL;
+#elif defined(__GFP_NORETRY)
     gfp_mask |= __GFP_NORETRY;
 #endif
 #if defined(__GFP_ZERO)
     if (at->flags & NV_ALLOC_TYPE_ZEROED)
         gfp_mask |= __GFP_ZERO;
diff --git a/kernel/nvidia/nv.c b/kernel/nvidia/nv.c
index 83e233b..ac08341 100644
--- a/kernel/nvidia/nv.c
+++ b/kernel/nvidia/nv.c
@@ -36,10 +36,16 @@
 
 #if !defined(CONFIG_RETPOLINE)
 #include "nv-retpoline.h"
 #endif
 
+#include <sound/core.h>             /* HDA struct snd_card */
+
+#if defined(NV_SOUND_HDAUDIO_H_PRESENT)
+#include "sound/hdaudio.h"
+#endif
+
 #include "conftest/patches.h"
 
 /*
  * our global state; one per device
  */
@@ -158,10 +164,16 @@ struct dev_pm_ops nv_pm_ops = {
 
 /***
  *** see nv.h for functions exported to other parts of resman
  ***/
 
+#if defined(HDA_MAX_CODECS)
+#define NV_HDA_MAX_CODECS HDA_MAX_CODECS
+#else
+#define NV_HDA_MAX_CODECS 8
+#endif
+
 /***
  *** STATIC functions
  ***/
 
 static
-- 
2.28.0

