diff --git a/debian/changelog b/debian/changelog
index ab6ab0787b21dcf0fe152071a37755d6e8fb2f00..07666e67cca5a8bd6996cb82f481962d2984aeaf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+nvidia-settings (535.171.04-1~deb12u1) bookworm; urgency=medium
+
+  * Rebuild for bookworm.
+
+ -- Andreas Beckmann <anbe@debian.org>  Thu, 28 Mar 2024 16:50:02 +0100
+
+nvidia-settings (535.171.04-1) unstable; urgency=medium
+
+  * New upstream release 535.171.04.
+    - Updated the nvidia-settings control panel to ensure that the entire
+      Display Configuration page can be used when the Layout window is shown.
+    - Updated the nvidia-settings control panel to allow the primary display
+      to be set on any GPU in a multi-GPU system.
+  * New upstream release 535.146.02.
+    - Fixed a bug that caused the nvidia-settings control panel to crash
+      when running on Wayland with newer versions of libwayland-client.
+  * New upstream release 535.54.03.
+    - Fixed a bug that prevented SLI Mosaic controls from being displayed in
+      the nvidia-settings control panel when using GSP Firmware.
+  * New upstream release 535.43.02.
+    - Added power usage and power limits information to nvidia-settings
+      PowerMizer page.
+
+ -- Andreas Beckmann <anbe@debian.org>  Mon, 25 Mar 2024 11:28:14 +0100
+
+nvidia-settings (530.41.03-1) unstable; urgency=medium
+
+  * New upstream release 530.41.03.
+  * Switch B-D from pkg-config to pkgconf.
+
+ -- Andreas Beckmann <anbe@debian.org>  Tue, 19 Mar 2024 19:47:39 +0100
+
 nvidia-settings (525.147.05-1~deb12u1) bookworm; urgency=medium
 
   * Rebuild for bookworm.
diff --git a/debian/control b/debian/control
index 3cd072a832b820b571e69decf97d46778faea248..9422f632d9ac00b4c40cc0143058e661fdebb151 100644
--- a/debian/control
+++ b/debian/control
@@ -15,7 +15,7 @@ Build-Depends:
  libvdpau-dev,
  libxv-dev,
  libxxf86vm-dev,
- pkg-config,
+ pkgconf,
  xserver-xorg-dev,
 Build-Conflicts:
  libxnvctrl-dev,
diff --git a/debian/patches/12_nvidia-settings.desktop.diff b/debian/patches/12_nvidia-settings.desktop.diff
index 381b03cbe60068b25f6b643a70aba476097564aa..b615abafd54ad7b1650a3aa2d6f5965216be9291 100644
--- a/debian/patches/12_nvidia-settings.desktop.diff
+++ b/debian/patches/12_nvidia-settings.desktop.diff
@@ -12,7 +12,7 @@ Forwarded: not-needed
 -Name=NVIDIA X Server Settings
 -Comment=Configure NVIDIA X Server Settings
 -Exec=__UTILS_PATH__/nvidia-settings
--Icon=__PIXMAP_PATH__/nvidia-settings.png
+-Icon=nvidia-settings
 -Categories=__NVIDIA_SETTINGS_DESKTOP_CATEGORIES__
 +Exec=nvidia-settings
 +Terminal=false
diff --git a/doc/nvidia-settings.desktop b/doc/nvidia-settings.desktop
index 252d4fc61e546685b24266a3bbe49d28a4ac9831..a06fefb39eca4a86b2fec852802a11f392131ff8 100644
--- a/doc/nvidia-settings.desktop
+++ b/doc/nvidia-settings.desktop
@@ -4,7 +4,7 @@ Encoding=UTF-8
 Name=NVIDIA X Server Settings
 Comment=Configure NVIDIA X Server Settings
 Exec=__UTILS_PATH__/nvidia-settings
-Icon=__PIXMAP_PATH__/nvidia-settings.png
+Icon=nvidia-settings
 Categories=__NVIDIA_SETTINGS_DESKTOP_CATEGORIES__
 
 # Translation by Marcin Mikołajczak
diff --git a/doc/version.mk b/doc/version.mk
index dae35ac2315e7ed874c063beacadec078b9447d1..89404cd76a7444270097f0872a9cf1a582796891 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 525.147.05
+NVIDIA_VERSION = 535.171.04
 
 # This file.
 VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))
diff --git a/samples/version.mk b/samples/version.mk
index dae35ac2315e7ed874c063beacadec078b9447d1..89404cd76a7444270097f0872a9cf1a582796891 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 525.147.05
+NVIDIA_VERSION = 535.171.04
 
 # This file.
 VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))
diff --git a/src/Makefile b/src/Makefile
index 68eb14067c378899a0cde1d2d7ea6191ab5e461c..3e067c2ddae63ed71ff9576c56be572ae463f3ef 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -42,10 +42,10 @@ ifndef WAYLAND_AVAILABLE
 endif
 ifeq (1,$(WAYLAND_AVAILABLE))
   ifndef WAYLAND_CFLAGS
-    WAYLAND_CFLAGS := $(shell $(PKG_CONFIG) --cflags )
+    WAYLAND_CFLAGS := $(shell $(PKG_CONFIG) --cflags wayland-client)
   endif
   ifndef WAYLAND_LDFLAGS
-    WAYLAND_LDFLAGS := $(shell $(PKG_CONFIG) --libs )
+    WAYLAND_LDFLAGS := $(shell $(PKG_CONFIG) --libs wayland-client)
   endif
   BUILD_WAYLANDLIB = 1
 endif
diff --git a/src/gtk+-2.x/ctkappprofile.c b/src/gtk+-2.x/ctkappprofile.c
index 77dd503463ba476baf487b3c5dee5f217cd28219..99923347e7e797d1d9754cc71a3bcdf45f4d7579 100644
--- a/src/gtk+-2.x/ctkappprofile.c
+++ b/src/gtk+-2.x/ctkappprofile.c
@@ -48,6 +48,7 @@
 
 enum {
    RULE_FEATURE_PROCNAME,
+   RULE_FEATURE_CMDLINE,
    RULE_FEATURE_DSO,
    RULE_FEATURE_TRUE,
    NUM_RULE_FEATURES
@@ -55,12 +56,14 @@ enum {
 
 static const char *rule_feature_label_strings[] = {
     "Process Name (procname)",      // RULE_FEATURE_PROCNAME
+    "Command line name (cmdline)",  // RULE_FEATURE_CMDLINE
     "Shared Object Name (dso)",     // RULE_FEATURE_DSO
     "Always Applies (true)"         // RULE_FEATURE_TRUE
 };
 
 static const char *rule_feature_identifiers[] = {
     "procname",                     // RULE_FEATURE_PROCNAME
+    "cmdline",                      // RULE_FEATURE_CMDLINE
     "dso",                          // RULE_FEATURE_DSO
     "true"                          // RULE_FEATURE_TRUE
 };
@@ -72,6 +75,10 @@ static const char *rule_feature_help_text[] = {
     "against the pathname of the current process with the leading directory components removed, "
     "and match if they are equal.", // RULE_FEATURE_PROCNAME
     "Patterns using this feature compare the string provided by the " MATCHES_INPUT_DESCRIPTION " "
+    "against the argument 0 of the command line for the current process, as stored in "
+    "/proc/self/cmdline (with leading directory components removed, separated by slashes and "
+    "backslashes).", // RULE_FEATURE_CMDLINE
+    "Patterns using this feature compare the string provided by the " MATCHES_INPUT_DESCRIPTION " "
     "against the list of currently loaded libraries in the current process, and match if "
     "the string matches one of the entries in the list (with leading directory components removed).", // RULE_FEATURE_DSO
     "Patterns using this feature will always match the process, regardless of the "
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 578e5433af920bb99c240713a5a052d902bae58a..8f627ce355800b92bd560e1864c93eeb205a652b 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -122,6 +122,7 @@ static gboolean force_layout_reset(gpointer user_data);
 static void user_changed_attributes(CtkDisplayConfig *ctk_object);
 static void update_forcecompositionpipeline_buttons(CtkDisplayConfig
                                                     *ctk_object);
+static void confirm_valid_screen_sizes(CtkDisplayConfig *ctk_object);
 
 static XConfigPtr xconfig_generate(XConfigPtr xconfCur,
                                    Bool merge,
@@ -147,7 +148,7 @@ static void update_layout(CtkDisplayConfig *ctk_object);
 #define GTK_RESPONSE_USER_DISPLAY_ENABLE_TWINVIEW 1
 #define GTK_RESPONSE_USER_DISPLAY_ENABLE_XSCREEN  2
 
-#define MIN_LAYOUT_SCREENSIZE 600
+#define MIN_LAYOUT_SCREENSIZE 700
 typedef struct SwitchModeCallbackInfoRec {
     CtkDisplayConfig *ctk_object;
     int screen;
@@ -1067,6 +1068,8 @@ static void user_changed_attributes(CtkDisplayConfig *ctk_object)
         ctk_object->forced_reset_allowed = FALSE;
     }
 
+    confirm_valid_screen_sizes(ctk_object);
+
 } /* user_changed_attributes() */
 
 
@@ -1281,6 +1284,86 @@ static void screen_size_changed(GdkScreen *screen,
 
 
 
+/*** clear_layout_warning() ******************************************
+ *
+ * Hide and clear the string from the layout warning label.
+ *
+ **/
+
+static void clear_layout_warning(CtkDisplayConfig *ctk_object)
+{
+    gtk_label_set_text(GTK_LABEL(ctk_object->lbl_layout_warning), "");
+    gtk_widget_hide(ctk_object->lbl_layout_warning);
+}
+
+
+
+/*** update_layout_warning() *****************************************
+ *
+ * Set the given string to the layout warning text and show the label.
+ *
+ **/
+
+static void update_layout_warning(CtkDisplayConfig *ctk_object, const char* msg)
+{
+
+    if (msg && msg[0] != '\0') {
+        gtk_label_set_text(GTK_LABEL(ctk_object->lbl_layout_warning), msg);
+        gtk_widget_show(ctk_object->lbl_layout_warning);
+    } else {
+        clear_layout_warning(ctk_object);
+    }
+}
+
+
+
+/** confirm_valid_screen_sizes() *************************************
+ *
+ * Check that the dimensions of all screens are less than the maximum allowed
+ * sizes. Otherwise, show a layout warning to the user.
+ *
+ **/
+static void confirm_valid_screen_sizes(CtkDisplayConfig *ctk_object)
+{
+    nvScreenPtr screen;
+    GdkRectangle *dim;
+
+    char *t_str = NULL;
+    char *str = NULL;
+
+    for (screen = ctk_object->layout->screens;
+         screen;
+         screen = screen->next_in_layout) {
+        char *old_str;
+
+        if (screen->cur_metamode) {
+            dim = &(screen->cur_metamode->dim);
+        } else {
+            dim = &(screen->dim);
+        }
+
+        if (dim->width > screen->max_width ||
+            dim->height > screen->max_height) {
+
+            t_str = g_strdup_printf("Screen-%d exceeds maximum dimensions.",
+                                    screen->scrnum);
+            if (str == NULL) {
+                str = t_str;
+            } else {
+                old_str = str;
+                str = nvstrcat(str, "\n", t_str, NULL);
+                free(old_str);
+                free(t_str);
+            }
+        }
+    }
+
+    update_layout_warning(ctk_object, str);
+    free(str);
+}
+
+
+
 /** update_gui() *****************************************************
  *
  * Sync state of all widgets to reflect current configuration
@@ -1295,6 +1378,7 @@ static void update_gui(CtkDisplayConfig *ctk_object)
     setup_selected_item_dropdown(ctk_object);
     update_selected_page(ctk_object);
     setup_layout_frame(ctk_object);
+    confirm_valid_screen_sizes(ctk_object);
 
 } /* update_gui() */
 
@@ -1432,6 +1516,10 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target,
                      G_CALLBACK(screen_size_changed),
                      (gpointer) ctk_object);
 
+    /* Layout Warning label */
+    ctk_object->lbl_layout_warning = gtk_label_new("");
+    gtk_label_set_line_wrap(GTK_LABEL(ctk_object->lbl_layout_warning), 1);
+
     /* Mosaic button */
     ctk_object->chk_mosaic_enabled =
         gtk_check_button_new_with_label("");
@@ -1918,6 +2006,10 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target,
         vbox2 = gtk_vbox_new(FALSE, 5);
         gtk_container_add(GTK_CONTAINER(hbox), vbox2);
 
+        /* Layout Warning label */
+        gtk_box_pack_start(GTK_BOX(vbox2), ctk_object->lbl_layout_warning,
+                           FALSE, FALSE, 0);
+
         /* Mosaic checkbox */
         gtk_box_pack_start(GTK_BOX(vbox2), ctk_object->chk_mosaic_enabled,
                            FALSE, FALSE, 0);
@@ -5910,9 +6002,15 @@ static void do_enable_display_on_xscreen(CtkDisplayConfig *ctk_object,
 
         nvDisplayPtr other;
         nvModePtr rightmost = NULL;
+        nvModePtr bottommost = NULL;
+        int new_w = 0, new_h = 0;
 
 
-        /* Get the right-most mode of the metamode */
+        /*
+         * Get the right-most mode of the metamode or, in case right-side
+         * placement would be over the max screen width, the bottom-most
+         * left-aligned mode.
+         */
         for (other = screen->displays; other; other = other->next_in_screen) {
             for (mode = other->modes; mode; mode = mode->next) {
                 if (!rightmost ||
@@ -5920,6 +6018,10 @@ static void do_enable_display_on_xscreen(CtkDisplayConfig *ctk_object,
                      (rightmost->pan.x + rightmost->pan.width))) {
                     rightmost = mode;
                 }
+                if (!bottommost ||
+                    (mode->pan.x == 0 && mode->pan.y > bottommost->pan.y)) {
+                    bottommost = mode;
+                }
             }
         }
 
@@ -5935,8 +6037,33 @@ static void do_enable_display_on_xscreen(CtkDisplayConfig *ctk_object,
         }
 
 
-        /* Position the new mode to the right of the right-most metamode */
         if (rightmost) {
+            new_w = rightmost->pan.x + rightmost->pan.width + mode->pan.width;
+        }
+
+        if (bottommost) {
+            new_h =
+                bottommost->pan.y + bottommost->pan.height + mode->pan.height;
+        }
+
+        if (new_w > screen->max_width) {
+            /*
+             * If adding the display to the right of the right-most display
+             * is too wide, add this screen below the bottom-left display.
+             */
+            if (new_h > screen->max_height) {
+                mode->position_type = CONF_ADJ_ABSOLUTE;
+                mode->relative_to = NULL;
+                mode->pan.x = 0;
+                mode->pan.y = 0;
+            } else {
+                mode->position_type = CONF_ADJ_BELOW;
+                mode->relative_to = bottommost->display;
+                mode->pan.x = bottommost->display->cur_mode->pan.x;
+                mode->pan.y = bottommost->display->cur_mode->pan.y;
+            }
+        } else if (rightmost) {
+            /* Position the new mode to the right of the right-most metamode */
             mode->position_type = CONF_ADJ_RIGHTOF;
             mode->relative_to = rightmost->display;
             mode->pan.x = rightmost->display->cur_mode->pan.x;
@@ -8629,7 +8756,7 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data)
         if (screen->primaryDisplay && ctk_object->primary_display_changed) {
             ret = NvCtrlSetStringAttribute(screen->ctrl_target,
                                            NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER,
-                                           screen->primaryDisplay->typeIdName);
+                                           screen->primaryDisplay->randrName);
             if (ret != NvCtrlSuccess) {
                 nv_error_msg("Failed to set primary display for screen %d",
                              screen->scrnum);
@@ -9042,31 +9169,34 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object,
         display = screen->displays;;
 
         if (!display) {
-            nv_error_msg("Unable to find a display device for screen %d!",
-                         screen->scrnum);
-            goto fail;
-        }
+            nv_warning_msg("Unable to find a display device for screen %d!",
+                           screen->scrnum);
+            xconfigAddNewOption(&conf_screen->options,
+                                "AllowEmptyInitialConfiguration",
+                                "True");
+        } else {
 
+            /* Create the screen's only Monitor section from the first display */
+            if (!add_monitor_to_xconfig(display, config, screen->scrnum)) {
+                nv_error_msg("Failed to add display device '%s' to screen %d!",
+                             display->logName, screen->scrnum);
+                goto fail;
+            }
 
-        /* Create the screen's only Monitor section from the first display */
-        if (!add_monitor_to_xconfig(display, config, screen->scrnum)) {
-            nv_error_msg("Failed to add display device '%s' to screen %d!",
-                         display->logName, screen->scrnum);
-            goto fail;
-        }
 
+            /* Tie the screen to the monitor section */
+            conf_screen->monitor_name =
+                xconfigStrdup(display->conf_monitor->identifier);
+            conf_screen->monitor = display->conf_monitor;
 
-        /* Tie the screen to the monitor section */
-        conf_screen->monitor_name =
-            xconfigStrdup(display->conf_monitor->identifier);
-        conf_screen->monitor = display->conf_monitor;
 
+            /* Add the modelines of all other connected displays to the monitor */
+            for (other = display->next_in_screen;
+                 other;
+                 other = other->next_in_screen) {
+                add_modelines_to_monitor(display->conf_monitor, other->modes);
+            }
 
-        /* Add the modelines of all other connected displays to the monitor */
-        for (other = display->next_in_screen;
-             other;
-             other = other->next_in_screen) {
-            add_modelines_to_monitor(display->conf_monitor, other->modes);
         }
 
         /* Set the Stereo option */
@@ -9080,7 +9210,7 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object,
         if (screen->primaryDisplay) {
             xconfigAddNewOption(&conf_screen->options,
                                 "nvidiaXineramaInfoOrder",
-                                screen->primaryDisplay->typeIdName);
+                                screen->primaryDisplay->randrName);
         }
 
         /* Create the "metamode" option string. */
@@ -9097,8 +9227,10 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object,
         }
 
         if (metamode_strs) {
-            xconfigAddNewOption(&conf_screen->options, "metamodes",
-                                metamode_strs);
+            if (g_ascii_strcasecmp(metamode_strs, "NULL") != 0) {
+                xconfigAddNewOption(&conf_screen->options, "metamodes",
+                                    metamode_strs);
+            }
             free(metamode_strs);
         }
 
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index 7fcaefc32a14be70e16641059bd10814389ee557..6384fedb3d84fba5a035aec72ba554cd0f749cd8 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -91,6 +91,7 @@ typedef struct _CtkDisplayConfig
     GtkWidget *obj_layout;
     GtkWidget *label_layout;
 
+    GtkWidget *lbl_layout_warning;
     GtkWidget *chk_mosaic_enabled;
     GtkWidget *chk_xinerama_enabled;
     GtkWidget *chk_primary_display;
diff --git a/src/gtk+-2.x/ctkdisplaydevice.c b/src/gtk+-2.x/ctkdisplaydevice.c
index 66ff2aa3df7f56fd2f5d5059174c5a0c982917d8..e759c349945af2d8eb57f5b8fb6aa495604de6f1 100644
--- a/src/gtk+-2.x/ctkdisplaydevice.c
+++ b/src/gtk+-2.x/ctkdisplaydevice.c
@@ -54,6 +54,11 @@ static void callback_link_changed(GObject *object, CtrlEvent *event,
 static void callback_refresh_rate_changed(GObject *object, CtrlEvent *event,
                                           gpointer user_data);
 
+static void callback_number_of_hardware_heads_used_changed(GObject *object,
+                                                           CtrlEvent *event,
+                                                           gpointer user_data);
+
+
 static gboolean update_guid_info(InfoEntry *entry);
 static gboolean update_tv_encoder_info(InfoEntry *entry);
 static gboolean update_chip_info(InfoEntry *entry);
@@ -65,11 +70,12 @@ static gboolean update_multistream_info(InfoEntry *entry);
 static gboolean update_audio_info(InfoEntry *entry);
 static gboolean update_vrr_type_info(InfoEntry *entry);
 static gboolean update_vrr_enabled_info(InfoEntry *entry);
+static gboolean update_number_of_hardware_heads_used_info(InfoEntry *entry);
 
 static gboolean register_link_events(InfoEntry *entry);
-static gboolean unregister_link_events(InfoEntry *entry);
+static gboolean unregister_events(InfoEntry *entry);
 static gboolean register_refresh_rate_events(InfoEntry *entry);
-static gboolean unregister_refresh_rate_events(InfoEntry *entry);
+static gboolean register_number_of_hardware_heads_used_events(InfoEntry *entry);
 
 static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
                                      CtkConfig *ctk_config,
@@ -127,6 +133,12 @@ static const char * __vrr_enabled_help =
 "Server Display Configuration page, or by using the AllowGSYNCCompatible "
 "MetaMode attribute.";
 
+static const char * __number_of_hardware_heads_used_help =
+"Driving a display device normally requires a single hardware head.  In some "
+"rare cases, such as very high resolutions or refresh rates, multiple "
+"hardware heads are required.  This reports how many hardware "
+"heads are currently in use to drive the display device.";
+
 typedef gboolean (*InfoEntryFunc)(InfoEntry *entry);
 
 typedef struct {
@@ -171,14 +183,14 @@ static InfoEntryData __info_entry_data[] = {
         &__info_link_help,
         update_link_info,
         register_link_events,
-        unregister_link_events,
+        unregister_events,
     },
     {
         "Refresh Rate",
         &__refresh_rate_help,
         update_refresh_rate,
         register_refresh_rate_events,
-        unregister_refresh_rate_events,
+        unregister_events,
     },
     {
         "DisplayPort Connector Type",
@@ -215,6 +227,13 @@ static InfoEntryData __info_entry_data[] = {
         NULL,
         NULL,
     },
+    {
+        "Number of Hardware Heads Used",
+        &__number_of_hardware_heads_used_help,
+        update_number_of_hardware_heads_used_info,
+        register_number_of_hardware_heads_used_events,
+        unregister_events,
+    },
 };
 
 GType ctk_display_device_get_type(void)
@@ -960,6 +979,29 @@ static gboolean update_refresh_rate(InfoEntry *entry)
 
 
 
+static gboolean update_number_of_hardware_heads_used_info(InfoEntry *entry)
+{
+    CtkDisplayDevice *ctk_object = entry->ctk_object;
+    CtrlTarget *ctrl_target = ctk_object->ctrl_target;
+    ReturnStatus ret;
+    gint val;
+    char str[16];
+
+    ret = NvCtrlGetAttribute(ctrl_target,
+                             NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED, &val);
+    if (ret != NvCtrlSuccess) {
+        return FALSE;
+    }
+
+    snprintf(str, sizeof(str), "%d", val);
+
+    gtk_label_set_text(GTK_LABEL(entry->txt), str);
+
+    return TRUE;
+}
+
+
+
 /*
  * update_device_info() - (Re)Queries the static display device information.
  */
@@ -1050,7 +1092,7 @@ static gboolean register_link_events(InfoEntry *entry)
     return TRUE;
 }
 
-static gboolean unregister_link_events(InfoEntry *entry)
+static gboolean unregister_events(InfoEntry *entry)
 {
     CtkDisplayDevice *ctk_object = entry->ctk_object;
 
@@ -1075,17 +1117,14 @@ static gboolean register_refresh_rate_events(InfoEntry *entry)
     return TRUE;
 }
 
-static gboolean unregister_refresh_rate_events(InfoEntry *entry)
+static gboolean register_number_of_hardware_heads_used_events(InfoEntry *entry)
 {
     CtkDisplayDevice *ctk_object = entry->ctk_object;
 
-    g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event),
-                                         G_SIGNAL_MATCH_DATA,
-                                         0, /* signal_id */
-                                         0, /* detail */
-                                         NULL, /* closure */
-                                         NULL, /* func */
-                                         (gpointer) entry);
+    g_signal_connect(G_OBJECT(ctk_object->ctk_event),
+                     CTK_EVENT_NAME(NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED),
+                     G_CALLBACK(callback_number_of_hardware_heads_used_changed),
+                     (gpointer) entry);
     return TRUE;
 }
 
@@ -1128,6 +1167,15 @@ static void callback_refresh_rate_changed(GObject *object,
     update_refresh_rate(entry);
 }
 
+static void callback_number_of_hardware_heads_used_changed(GObject *object,
+                                                           CtrlEvent *event,
+                                                           gpointer user_data)
+{
+    InfoEntry *entry = (InfoEntry *)user_data;
+
+    update_number_of_hardware_heads_used_info(entry);
+}
+
 
 static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
                                      CtkConfig *ctk_config,
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index e8d85d3783bde613f031044e3d4de70ef4523edd..b7f8add595b52d0301e3a7a2bbbeba5e1b4fc6be 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -2508,6 +2508,27 @@ static void select_default_item(CtkDisplayLayout *ctk_object)
 
 
 
+/** reselect_selected_item() **************************************************
+ *
+ * Make sure the currently selected item is at the top of drawing stack of
+ * layout items.
+ *
+ */
+static void reselect_selected_item(CtkDisplayLayout *ctk_object)
+{
+    if (ctk_object->selected_display) {
+        select_display(ctk_object, ctk_object->selected_display);
+    } else if (ctk_object->selected_screen) {
+        select_screen(ctk_object, ctk_object->selected_screen);
+    } else if (ctk_object->selected_prime_display) {
+        select_prime_display(ctk_object, ctk_object->selected_prime_display);
+    } else {
+        select_default_item(ctk_object);
+    }
+}
+
+
+
 /** get_display_tooltip() ********************************************
  *
  * Returns the text to use for displaying a tooltip from the given
@@ -3855,6 +3876,8 @@ void ctk_display_layout_update_zorder(CtkDisplayLayout *ctk_object)
 {
     zorder_layout(ctk_object);
 
+    reselect_selected_item(ctk_object);
+
     queue_layout_redraw(ctk_object);
 
 } /* ctk_display_layout_update_zorder() */
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index b3e35a9d73813575cc0575e56651783e08524cf8..aee6a9d34f2f5a386801ef90ddde7826700d2b16 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -295,6 +295,9 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class,
     MAKE_SIGNAL(NV_CTRL_DISPLAY_VRR_ENABLED);
     MAKE_SIGNAL(NV_CTRL_PLATFORM_POWER_MODE);
     MAKE_SIGNAL(NV_CTRL_MUX_AUTO_SWITCH);
+    MAKE_SIGNAL(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE);
+    MAKE_SIGNAL(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE);
+    MAKE_SIGNAL(NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED);
 #undef MAKE_SIGNAL
 
     /*
@@ -304,7 +307,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class,
      * knows about.
      */
 
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DYNAMIC_BOOST_SUPPORT
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED
 #warning "There are attributes that do not emit signals!"
 #endif
 
diff --git a/src/gtk+-2.x/ctkframelock.c b/src/gtk+-2.x/ctkframelock.c
index 8a0aa1a020a89e03c6610d8c8087db385d6bdcc9..cf79853612503991a319435add59fc6658575b3d 100644
--- a/src/gtk+-2.x/ctkframelock.c
+++ b/src/gtk+-2.x/ctkframelock.c
@@ -112,6 +112,8 @@ const char *__FrameLockSignals[] =
         CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_SYNC_INTERVAL),
         CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_POLARITY),
         CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_VIDEO_MODE),
+        CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE),
+        CTK_EVENT_NAME(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE),
     };
 
 typedef struct _nvListTreeRec      nvListTreeRec, *nvListTreePtr;
@@ -264,6 +266,11 @@ static gchar *syncEdgeStrings[] = {
     NULL
     };
 
+static gchar *muldivModeStrings[] = {
+    "Multiply", /* NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY */
+    "Divide", /* NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE */
+    NULL
+    };
 
 /* Tooltips */
 
@@ -296,6 +303,17 @@ static const char * __house_sync_mode_combo_help =
 "an incoming house sync signal is present on the BNC connector, requesting "
 "Output mode will have no effect.";
 
+static const char * __muldiv_value_help =
+"The Sync Multiply/Divide Value allows you to set the number that the "
+"external house sync signal will be multiplied or divided by before comparing "
+"it to this board's internal sync rate.  For example, this may allow a "
+"Quadro Sync II board to sync displays at 120Hz from a 60Hz house sync input.";
+
+static const char * __muldiv_mode_combo_help =
+"The Sync Muldiply/Divide Mode allows you to control whether the external "
+"house sync signal will be multiplied or divided by the sync multiply/divide "
+"value before being interpreted by this Quadro Sync device.";
+
 static const char * __sync_interval_scale_help =
 "The Sync Interval allows you to set the number of incoming house sync "
 "pulses the server frame lock board receives before generating an outgoing "
@@ -363,6 +381,8 @@ static void toggle_client(GtkWidget *, gpointer);
 static void toggle_sync_enable(GtkWidget *, gpointer);
 static void toggle_test_link(GtkWidget *, gpointer);
 static void sync_interval_changed(GtkRange *, gpointer);
+static void changed_muldiv_mode(GtkComboBox *combo_box, gpointer user_data);
+static void muldiv_value_changed(GtkRange *range, gpointer user_data);
 static void changed_video_mode(GtkComboBox *, gpointer);
 static void toggle_detect_video_mode(GtkToggleButton *, gpointer);
 
@@ -2569,7 +2589,7 @@ static gboolean get_server_id(CtrlTarget *ctrl_target,
  */
 static void changed_house_sync_mode(GtkComboBox *combo_box, gpointer user_data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *)user_data;
+    CtkFramelock *ctk_framelock = user_data;
     nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
     nvListEntryPtr entry;
     gint house_sync_mode;
@@ -2594,7 +2614,7 @@ static void changed_house_sync_mode(GtkComboBox *combo_box, gpointer user_data)
         return;
     }
 
-    data = (nvFrameLockDataPtr) entry->data;
+    data = entry->data;
     ctrl_target = data->ctrl_target;
 
     NvCtrlSetAttribute(ctrl_target, NV_CTRL_USE_HOUSE_SYNC, house_sync_mode);
@@ -3021,9 +3041,9 @@ static void update_enable_confirm_text(CtkFramelock *ctk_framelock)
  * Timeout callback for reverting enabling of Frame Lock.
  *
  **/
-static gboolean do_enable_confirm_countdown(gpointer *user_data)
+static gboolean do_enable_confirm_countdown(gpointer user_data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *) user_data;
+    CtkFramelock *ctk_framelock = user_data;
 
     ctk_framelock->enable_confirm_countdown--;
     if (ctk_framelock->enable_confirm_countdown > 0) {
@@ -3047,7 +3067,7 @@ static gboolean do_enable_confirm_countdown(gpointer *user_data)
  *
  */
 static Bool confirm_serverless_framelock(CtkFramelock *ctk_framelock)
-{ 
+{
     gint result;
 
 
@@ -3086,7 +3106,7 @@ static Bool confirm_serverless_framelock(CtkFramelock *ctk_framelock)
  */
 static void toggle_sync_enable(GtkWidget *button, gpointer data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *) data;
+    CtkFramelock *ctk_framelock = data;
     guint val;
     gboolean enabled;
     gboolean something_enabled;
@@ -3125,7 +3145,7 @@ static void toggle_sync_enable(GtkWidget *button, gpointer data)
 
     entry = get_gpu_server_entry(tree);
     if (enabled && entry && framelock_enabled) {
-        nvGPUDataPtr data = (nvGPUDataPtr)(entry->data);
+        nvGPUDataPtr data = entry->data;
         CtrlTarget *ctrl_target = data->ctrl_target;
         NvCtrlSetAttribute(ctrl_target,
                            NV_CTRL_FRAMELOCK_TEST_SIGNAL,
@@ -3311,7 +3331,7 @@ static void toggle_test_link(GtkWidget *button, gpointer data)
  */
 static void sync_interval_changed(GtkRange *range, gpointer user_data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *)user_data;
+    CtkFramelock *ctk_framelock = user_data;
     nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
     nvListEntryPtr entry = get_framelock_server_entry(tree);
     nvFrameLockDataPtr data = NULL;
@@ -3321,12 +3341,35 @@ static void sync_interval_changed(GtkRange *range, gpointer user_data)
         return;
     }
 
-    data = (nvFrameLockDataPtr)(entry->data);
+    data = entry->data;
 
     NvCtrlSetAttribute(data->ctrl_target, NV_CTRL_FRAMELOCK_SYNC_INTERVAL,
                        interval);
 }
 
+/*
+ * muldiv_value_changed() - callback function for when the user changes the
+ * house sync multiply/divide value.
+ */
+static void muldiv_value_changed(GtkRange *range, gpointer user_data)
+{
+    CtkFramelock *ctk_framelock = user_data;
+    nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
+    nvListEntryPtr entry = get_framelock_server_entry(tree);
+    nvFrameLockDataPtr data = NULL;
+    gint muldiv = gtk_range_get_value(range);
+
+    if (!entry) {
+        return;
+    }
+
+    data = entry->data;
+
+    NvCtrlSetAttribute(data->ctrl_target,
+                       NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,
+                       muldiv);
+}
+
 
 /*
  * format_sync_interval() - callback for the "format-value" signal from
@@ -3343,6 +3386,20 @@ static gchar *format_sync_interval(GtkScale *scale, gdouble arg1,
 }
 
 
+/*
+ * format_sync_muldiv() - callback for the "format-value" signal from
+ * the sync multiply/divide value; return a string describing the current value
+ * of the house sync multiplier/divider.
+ */
+static gchar *format_sync_muldiv(GtkScale *scale, gdouble arg1,
+                                   gpointer user_data)
+{
+    gint val = (gint)arg1;
+
+    return g_strdup_printf("%d", val);
+}
+
+
 /** changed_sync_edge() **********************************************
  *
  * Callback function for when the user changes a frame lock device's
@@ -3351,7 +3408,7 @@ static gchar *format_sync_interval(GtkScale *scale, gdouble arg1,
  */
 static void changed_sync_edge(GtkComboBox *combo_box, gpointer user_data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *)user_data;
+    CtkFramelock *ctk_framelock = user_data;
     nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
     nvListEntryPtr entry = get_framelock_server_entry(tree);
     nvFrameLockDataPtr data;
@@ -3363,12 +3420,38 @@ static void changed_sync_edge(GtkComboBox *combo_box, gpointer user_data)
         return;
     }
 
-    data = (nvFrameLockDataPtr) entry->data;
+    data = entry->data;
 
     NvCtrlSetAttribute(data->ctrl_target, NV_CTRL_FRAMELOCK_POLARITY, edge);
 }
 
 
+/** changed_muldiv_mode() **********************************************
+ *
+ * Callback function for when the user changes a frame lock device's
+ * house sync multiply/divide mode.
+ *
+ */
+static void changed_muldiv_mode(GtkComboBox *combo_box, gpointer user_data)
+{
+    CtkFramelock *ctk_framelock = user_data;
+    nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
+    nvListEntryPtr entry = get_framelock_server_entry(tree);
+    nvFrameLockDataPtr data;
+
+    gint mode = gtk_combo_box_get_active(combo_box);
+
+    if (!entry ||
+        (mode < NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY) ||
+        (mode > NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE)) {
+        return;
+    }
+
+    data = entry->data;
+
+    NvCtrlSetAttribute(data->ctrl_target, NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE, mode);
+}
+
 
 /** changed_video_mode() *********************************************
  *
@@ -3378,7 +3461,7 @@ static void changed_sync_edge(GtkComboBox *combo_box, gpointer user_data)
  */
 static void changed_video_mode(GtkComboBox *combo_box, gpointer user_data)
 {
-    CtkFramelock *ctk_framelock = (CtkFramelock *)user_data;
+    CtkFramelock *ctk_framelock = user_data;
     nvListTreePtr tree = (nvListTreePtr)(ctk_framelock->tree);
     nvListEntryPtr entry = get_framelock_server_entry(tree);
     nvFrameLockDataPtr data;
@@ -3388,7 +3471,7 @@ static void changed_video_mode(GtkComboBox *combo_box, gpointer user_data)
         return;
     }
 
-    data = (nvFrameLockDataPtr) entry->data;
+    data = entry->data;
 
     NvCtrlSetAttribute(data->ctrl_target, NV_CTRL_FRAMELOCK_VIDEO_MODE, mode);
 }
@@ -4043,19 +4126,6 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
 
         /* Update GUI to reflect server settings */
 
-        g_signal_handlers_block_by_func
-            (G_OBJECT(ctk_framelock->sync_interval_scale),
-             G_CALLBACK(sync_interval_changed),
-             (gpointer) ctk_framelock);
-
-        gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
-                            sync_interval);
-
-        g_signal_handlers_unblock_by_func
-            (G_OBJECT(ctk_framelock->sync_interval_scale),
-             G_CALLBACK(sync_interval_changed),
-             (gpointer) ctk_framelock);
-
         if (sync_edge < NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE)
             sync_edge = NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE;
         if (sync_edge > NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES)
@@ -4090,6 +4160,68 @@ static void update_house_sync_controls(CtkFramelock *ctk_framelock)
             }
         }
 
+        if (ctk_framelock->muldiv_supported) {
+            gint muldiv_mode, muldiv_value;
+            NvCtrlGetAttribute(server_data->ctrl_target,
+                               NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE,
+                               &muldiv_mode);
+            NvCtrlGetAttribute(server_data->ctrl_target,
+                               NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,
+                               &muldiv_value);
+
+            if (muldiv_mode < NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY)
+                muldiv_mode = NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY;
+            if (muldiv_mode > NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE)
+                muldiv_mode = NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE;
+
+            g_signal_handlers_block_by_func
+                 (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo)),
+                  G_CALLBACK(changed_muldiv_mode),
+                  (gpointer) ctk_framelock);
+
+            gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo),
+                                     muldiv_mode);
+
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo)),
+                 G_CALLBACK(changed_muldiv_mode),
+                 (gpointer) ctk_framelock);
+
+            g_signal_handlers_block_by_func
+                (G_OBJECT(ctk_framelock->muldiv_value_scale),
+                 G_CALLBACK(muldiv_value_changed),
+                 (gpointer) ctk_framelock);
+
+            gtk_range_set_value(GTK_RANGE(ctk_framelock->muldiv_value_scale),
+                                muldiv_value);
+
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(ctk_framelock->muldiv_value_scale),
+                 G_CALLBACK(muldiv_value_changed),
+                 (gpointer) ctk_framelock);
+
+            if (house_sync_mode != NV_CTRL_USE_HOUSE_SYNC_INPUT) {
+                gtk_widget_set_sensitive(ctk_framelock->muldiv_mode_combo, False);
+                gtk_widget_set_sensitive(ctk_framelock->muldiv_value_scale, False);
+            } else {
+                gtk_widget_set_sensitive(ctk_framelock->muldiv_mode_combo, True);
+                gtk_widget_set_sensitive(ctk_framelock->muldiv_value_scale, True);
+            }
+        } else {
+            g_signal_handlers_block_by_func
+                (G_OBJECT(ctk_framelock->sync_interval_scale),
+                 G_CALLBACK(sync_interval_changed),
+                 (gpointer) ctk_framelock);
+
+            gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
+                                sync_interval);
+
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(ctk_framelock->sync_interval_scale),
+                 G_CALLBACK(sync_interval_changed),
+                 (gpointer) ctk_framelock);
+        }
+
         if (house_format < NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE)
             house_format = NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE;
         if (house_format > NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV)
@@ -4486,6 +4618,7 @@ static void framelock_state_received(GObject *object,
         get_framelock_server_entry(entry->tree);
 
     gint sync_edge;
+    gint muldiv_mode;
     gint house_sync_mode;
     gint house_format;
 
@@ -4526,18 +4659,60 @@ static void framelock_state_received(GObject *object,
         break;
 
     case NV_CTRL_FRAMELOCK_SYNC_INTERVAL:
-        g_signal_handlers_block_by_func
-            (G_OBJECT(ctk_framelock->sync_interval_scale),
-             G_CALLBACK(sync_interval_changed),
-             (gpointer) ctk_framelock);
+        if (!ctk_framelock->muldiv_supported) {
+            g_signal_handlers_block_by_func
+                (G_OBJECT(ctk_framelock->sync_interval_scale),
+                 G_CALLBACK(sync_interval_changed),
+                 (gpointer) ctk_framelock);
 
-        gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
-                            event->int_attr.value);
+            gtk_range_set_value(GTK_RANGE(ctk_framelock->sync_interval_scale),
+                                event->int_attr.value);
 
-        g_signal_handlers_unblock_by_func
-            (G_OBJECT(ctk_framelock->sync_interval_scale),
-             G_CALLBACK(sync_interval_changed),
-             (gpointer) ctk_framelock);
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(ctk_framelock->sync_interval_scale),
+                 G_CALLBACK(sync_interval_changed),
+                 (gpointer) ctk_framelock);
+        }
+        break;
+
+    case NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE:
+        if (ctk_framelock->muldiv_supported) {
+            g_signal_handlers_block_by_func
+                (G_OBJECT(ctk_framelock->muldiv_value_scale),
+                 G_CALLBACK(muldiv_value_changed),
+                 (gpointer) ctk_framelock);
+
+            gtk_range_set_value(GTK_RANGE(ctk_framelock->muldiv_value_scale),
+                                event->int_attr.value);
+
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(ctk_framelock->muldiv_value_scale),
+                 G_CALLBACK(muldiv_value_changed),
+                 (gpointer) ctk_framelock);
+        }
+        break;
+
+    case NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE:
+        if (ctk_framelock->muldiv_supported) {
+            muldiv_mode = event->int_attr.value;
+            if (muldiv_mode < NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY)
+                muldiv_mode = NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY;
+            if (muldiv_mode > NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE)
+                muldiv_mode = NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE;
+
+            g_signal_handlers_block_by_func
+                 (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo)),
+                  G_CALLBACK(changed_muldiv_mode),
+                  (gpointer) ctk_framelock);
+
+            gtk_combo_box_set_active(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo),
+                                     muldiv_mode);
+
+            g_signal_handlers_unblock_by_func
+                (G_OBJECT(GTK_COMBO_BOX(ctk_framelock->muldiv_mode_combo)),
+                 G_CALLBACK(changed_muldiv_mode),
+                 (gpointer) ctk_framelock);
+        }
         break;
 
     case NV_CTRL_FRAMELOCK_POLARITY:
@@ -4771,6 +4946,7 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target,
     ctk_framelock->video_mode_read_only = TRUE;
     ctk_framelock->house_sync_output_supported = FALSE;
     ctk_framelock->house_sync_output_warning_dlg_shown = FALSE;
+    ctk_framelock->muldiv_supported = FALSE;
 
     /* create the watch cursor */
 
@@ -4937,6 +5113,21 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target,
     ctk_framelock->sync_edge_combo = combo_box;
 
 
+    combo_box = ctk_combo_box_text_new();
+    ctk_combo_box_text_append_text(combo_box,
+         muldivModeStrings[NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY]);
+    ctk_combo_box_text_append_text(combo_box,
+         muldivModeStrings[NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE]);
+
+    gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
+
+    g_signal_connect(G_OBJECT(GTK_COMBO_BOX(combo_box)),
+                     "changed", G_CALLBACK(changed_muldiv_mode),
+                     (gpointer) ctk_framelock);
+    ctk_config_set_tooltip(ctk_config, combo_box,
+                           __muldiv_mode_combo_help);
+    ctk_framelock->muldiv_mode_combo = combo_box;
+
     /* Cache images */
 
     ctk_framelock->led_grey_pixbuf = CTK_LOAD_PIXBUF(led_grey);
@@ -5055,8 +5246,81 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target,
     ctk_framelock->house_sync_vbox = padding;
     gtk_box_pack_start(GTK_BOX(vbox), padding, FALSE, FALSE, 0);
 
-    /* add the house sync interval */
-    {
+    /* add the house sync multiply/divide mode if supported */
+    ret = NvCtrlGetValidAttributeValues(ctrl_target,
+                                        NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE,
+                                        &valid);
+    if (ret == NvCtrlSuccess) {
+        GtkWidget *frame2 = gtk_frame_new(NULL);
+        hbox = gtk_hbox_new(FALSE, 5);
+        label = gtk_label_new("Sync Multiply/Divide Mode:");
+
+        ctk_framelock->muldiv_supported = TRUE;
+        ctk_framelock->muldiv_mode_frame = frame2;
+
+        gtk_box_pack_start(GTK_BOX(padding), frame2, FALSE, FALSE, 0);
+        gtk_container_add(GTK_CONTAINER(frame2), hbox);
+
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+        gtk_box_pack_start(GTK_BOX(hbox), ctk_framelock->muldiv_mode_combo,
+                           FALSE, FALSE, 5);
+
+        /* add the house sync multiply/divide value slider if supported */
+        ret = NvCtrlGetValidAttributeValues(ctrl_target,
+                                            NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,
+                                            &valid);
+
+        /* if multiply/divide mode is supported, multiply/divide value should
+         * be supported as well */
+        if (ret != NvCtrlSuccess) {
+            return NULL;
+        }
+
+        frame2 = gtk_frame_new(NULL);
+
+        if (valid.valid_type != CTRL_ATTRIBUTE_VALID_TYPE_RANGE) {
+            return NULL;
+        }
+
+        if (NvCtrlSuccess !=
+            NvCtrlGetAttribute(ctrl_target,
+                               NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,
+                               &val)) {
+            return NULL;
+        }
+
+        hbox = gtk_hbox_new(FALSE, 5);
+        label = gtk_label_new("Sync Multiply/Divide Value:");
+
+        adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(val, valid.range.min,
+                                                       valid.range.max,
+                                                       1, 1, 0));
+        scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+        gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), val);
+
+        gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
+        gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
+        gtk_scale_set_digits(GTK_SCALE(scale), 0);
+
+        g_signal_connect(G_OBJECT(scale), "format-value",
+                         G_CALLBACK(format_sync_muldiv),
+                         (gpointer) ctk_framelock);
+        g_signal_connect(G_OBJECT(scale), "value-changed",
+                         G_CALLBACK(muldiv_value_changed),
+                         (gpointer) ctk_framelock);
+        ctk_config_set_tooltip(ctk_config, scale, __muldiv_value_help);
+
+        ctk_framelock->muldiv_value_frame = frame2;
+        ctk_framelock->muldiv_value_scale = scale;
+
+        gtk_box_pack_start(GTK_BOX(padding), frame2, FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+        gtk_box_pack_start(GTK_BOX(hbox), scale, TRUE, TRUE, 5);
+        gtk_container_add(GTK_CONTAINER(frame2), hbox);
+
+    } else {
+        /* House sync interval is deprecated in favor of house sync
+         * multiply/divide mode */
         GtkWidget *frame2 = gtk_frame_new(NULL);
 
         ret = NvCtrlGetValidAttributeValues(ctrl_target,
@@ -5092,6 +5356,7 @@ GtkWidget* ctk_framelock_new(CtrlTarget *ctrl_target,
 
         gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
         gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
+        gtk_scale_set_digits(GTK_SCALE(scale), 0);
 
         g_signal_connect(G_OBJECT(scale), "format-value",
                          G_CALLBACK(format_sync_interval),
@@ -5937,6 +6202,8 @@ static void add_entry_to_parsed_attributes(nvListEntryPtr entry,
                 int sync_interval;
                 int sync_edge;
                 int video_mode;
+                int muldiv_mode;
+                int muldiv_value;
 
                 NvCtrlGetAttribute(ctrl_target,
                                    NV_CTRL_FRAMELOCK_SYNC_INTERVAL,
@@ -5947,10 +6214,18 @@ static void add_entry_to_parsed_attributes(nvListEntryPtr entry,
                 NvCtrlGetAttribute(ctrl_target,
                                    NV_CTRL_FRAMELOCK_VIDEO_MODE,
                                    &video_mode);
+                NvCtrlGetAttribute(ctrl_target,
+                                   NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE,
+                                   &muldiv_mode);
+                NvCtrlGetAttribute(ctrl_target,
+                                   NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,
+                                   &muldiv_value);
 
                 __ADD_ATTR(NV_CTRL_FRAMELOCK_SYNC_INTERVAL, sync_interval);
                 __ADD_ATTR(NV_CTRL_FRAMELOCK_POLARITY, sync_edge);
                 __ADD_ATTR(NV_CTRL_FRAMELOCK_VIDEO_MODE, video_mode);
+                __ADD_ATTR(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE, muldiv_mode);
+                __ADD_ATTR(NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE, muldiv_value);
             }
 
             free(display_name);
diff --git a/src/gtk+-2.x/ctkframelock.h b/src/gtk+-2.x/ctkframelock.h
index 6926436202f5383ede2c14bd57b6620c35ef864a..892b9e9f0c47a87dad8b425289a8978dfdc86bfe 100644
--- a/src/gtk+-2.x/ctkframelock.h
+++ b/src/gtk+-2.x/ctkframelock.h
@@ -80,6 +80,10 @@ struct _CtkFramelock
     GtkWidget             *sync_interval_scale;
     GtkWidget             *sync_edge_frame;
     GtkWidget             *sync_edge_combo;
+    GtkWidget             *muldiv_mode_frame;
+    GtkWidget             *muldiv_mode_combo;
+    GtkWidget             *muldiv_value_frame;
+    GtkWidget             *muldiv_value_scale;
     GtkWidget             *video_mode_frame;
     GtkWidget             *video_mode_widget;
     GtkWidget             *video_mode_detect;
@@ -89,6 +93,7 @@ struct _CtkFramelock
     gboolean               video_mode_read_only;
     gboolean               house_sync_output_supported;
     gboolean               house_sync_output_warning_dlg_shown;
+    gboolean               muldiv_supported;
 
     /* Dialogs */
     GtkWidget             *warn_dialog;
diff --git a/src/gtk+-2.x/ctkgridlicense.c b/src/gtk+-2.x/ctkgridlicense.c
index 6b0a599a25591b203017931705bf4358dd95b483..65e0db02c3305d2fc8bfd59be088a5f2dfc87f36 100644
--- a/src/gtk+-2.x/ctkgridlicense.c
+++ b/src/gtk+-2.x/ctkgridlicense.c
@@ -2,7 +2,7 @@
  * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
  * and Linux systems.
  *
- * Copyright (C) 2022 NVIDIA Corporation.
+ * Copyright (C) 2022-2023 NVIDIA Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -46,10 +46,11 @@
 #define DEFAULT_UPDATE_GRID_LICENSE_STATUS_INFO_TIME_INTERVAL   1000
 #define GRID_CONFIG_FILE                                        "/etc/nvidia/gridd.conf"
 #define GRID_CONFIG_FILE_TEMPLATE                               "/etc/nvidia/gridd.conf.template"
+#define BUF_LEN                                                 256
 
 static const char * __manage_grid_licenses_help =
 "Use the Manage License page to obtain licenses "
-"for NVIDIA vGPU or NVIDIA RTX Virtual Workstation on supported Tesla products. "
+"for NVIDIA vGPU or NVIDIA RTX Virtual Workstation or NVIDIA Virtual Compute Server on supported Tesla products. "
 "The current license status is displayed on the page. If licensed, the license expiry information in GMT time zone is shown.";
 static const char * __manage_grid_licenses_vcompute_help =
 "Use the Manage License page to obtain licenses "
@@ -64,27 +65,21 @@ static const char * __grid_vapp_help =
 static const char * __license_edition_help =
 "This section indicates the status of vGPU Software licensing on the system.";
 static const char * __license_server_help =
-"Shows the configured NVIDIA vGPU license server details.";
+"Shows the configured license server details read from Client Configuration token.";
 static const char * __primary_server_address_help =
-"Enter the address of your local NVIDIA vGPU license server. "
-"The address can be a fully-qualified domain name such as vgpulicense.example.com, "
-"or an IP address such as 10.31.20.45.";
+"The address of Primary license server.";
 static const char * __primary_server_port_help =
-"This field can be left empty, and will default to 7070, "
-"which is the default port number used by the NVIDIA vGPU license server.";
+"Port number used by the Primary license server.";
 static const char * __secondary_server_help =
-"This field is optional. Enter the address of your backup NVIDIA vGPU license server. "
-"The address can be a fully-qualified domain name such as backuplicense.example.com, "
-"or an IP address such as 10.31.20.46.";
+"The address of Secondary license server.";
 static const char * __secondary_server_port_help =
-"This field can be left empty, and will default to 7070, "
-"which is the default port number used by the NVIDIA vGPU license server.";
+"Port number used by the Secondary license server";
 static const char * __apply_button_help =
-"Clicking the Apply button updates license settings in the gridd.conf file and "
+"Clicking the Apply button updates license feature type in the gridd.conf file and "
 "sends update license request to the NVIDIA vGPU licensing daemon.";
 static const char * __cancel_button_help =
-"Clicking the Cancel button sets the text in all textboxes from the gridd.conf file. "
-"Any changes you have done will be lost.";
+"Clicking the Cancel button sets the license settings from the gridd.conf file. "
+"Any changes you have done on this page will be lost.";
 
 typedef struct
 {
@@ -121,9 +116,6 @@ static void ctk_manage_grid_license_finalize(GObject *object);
 static void ctk_manage_grid_license_class_init(CtkManageGridLicenseClass *, gpointer);
 static void dbusClose(DbusData *dbusData);
 static gboolean checkConfigfile(gboolean *writable);
-static gboolean disallow_whitespace(GtkWidget *widget, GdkEvent *event, gpointer user_data);
-static gboolean allow_digits(GtkWidget *widget, GdkEvent *event, gpointer user_data);
-static gboolean enable_disable_ui_controls(GtkWidget *widget, GdkEvent *event, gpointer user_data);
 static void update_gui_from_griddconfig(gpointer user_data);
 static gboolean licenseStateQueryFailed = FALSE;
 static void get_licensable_feature_information(gpointer user_data);
@@ -161,22 +153,14 @@ GType ctk_manage_grid_license_get_type(void)
 
 typedef enum
 {
-    NV_GRIDD_SERVER_ADDRESS = 0,
-    NV_GRIDD_SERVER_PORT,
-    NV_GRIDD_FEATURE_TYPE,
+    NV_GRIDD_FEATURE_TYPE = 0,
     NV_GRIDD_ENABLE_UI,
-    NV_GRIDD_BACKUP_SERVER_ADDRESS,
-    NV_GRIDD_BACKUP_SERVER_PORT,
     NV_GRIDD_MAX_TOKENS
 } CfgParams;
 
 static const char *configParamsList[] = {
-    [NV_GRIDD_SERVER_ADDRESS]        = "ServerAddress",
-    [NV_GRIDD_SERVER_PORT]           = "ServerPort",
     [NV_GRIDD_FEATURE_TYPE]          = "FeatureType",
     [NV_GRIDD_ENABLE_UI]             = "EnableUI",
-    [NV_GRIDD_BACKUP_SERVER_ADDRESS] = "BackupServerAddress",
-    [NV_GRIDD_BACKUP_SERVER_PORT]    = "BackupServerPort",
 };
 
 typedef struct NvGriddConfigParamsRec
@@ -265,12 +249,8 @@ static NvGriddConfigParams *AllocNvGriddConfigParams(void)
 {
     NvGriddConfigParams *griddConfig = nvalloc(sizeof(*griddConfig));
 
-    griddConfig->str[NV_GRIDD_SERVER_ADDRESS]        = nvstrdup("");
-    griddConfig->str[NV_GRIDD_SERVER_PORT]           = nvstrdup("");
     griddConfig->str[NV_GRIDD_FEATURE_TYPE]          = nvstrdup("0");
     griddConfig->str[NV_GRIDD_ENABLE_UI]             = nvstrdup("FALSE");
-    griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS] = nvstrdup("");
-    griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT]    = nvstrdup("");
 
     return griddConfig;
 }
@@ -438,25 +418,6 @@ static void UpdateGriddConfigFromGui(
 {
     const char *tmp;
 
-    /* serverAddress */
-
-    tmp = gtk_entry_get_text(GTK_ENTRY(
-                              ctk_manage_grid_license->txt_server_address));
-    if (strcmp(tmp, griddConfig->str[NV_GRIDD_SERVER_ADDRESS]) != 0) {
-        nvfree(griddConfig->str[NV_GRIDD_SERVER_ADDRESS]);
-        griddConfig->str[NV_GRIDD_SERVER_ADDRESS] = nvstrdup(tmp ? tmp : "");
-    }
-
-    /* serverPort */
-
-    tmp = gtk_entry_get_text(GTK_ENTRY(
-                              ctk_manage_grid_license->txt_server_port));
-    if (strcmp(tmp, griddConfig->str[NV_GRIDD_SERVER_PORT]) != 0) {
-        nvfree(griddConfig->str[NV_GRIDD_SERVER_PORT]);
-        griddConfig->str[NV_GRIDD_SERVER_PORT] =
-            nvstrdup((strcmp(tmp, "") != 0) ? tmp : "7070");
-    }
-
     /* featureType */
 
     switch (ctk_manage_grid_license->feature_type) {
@@ -481,24 +442,6 @@ static void UpdateGriddConfigFromGui(
     }
 
     /* note: nothing in the UI will alter enableUI */
-
-    /* backupServerAddress */
-
-    tmp = gtk_entry_get_text(GTK_ENTRY(
-                              ctk_manage_grid_license->txt_secondary_server_address));
-    if (strcmp(tmp, griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS]) != 0) {
-        nvfree(griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS]);
-        griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS] = nvstrdup(tmp ? tmp : "");
-    }
-
-    /* backupServerPort */
-
-    tmp = gtk_entry_get_text(GTK_ENTRY(
-                              ctk_manage_grid_license->txt_secondary_server_port));
-    if (strcmp(tmp, griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT]) != 0) {
-        nvfree(griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT]);
-        griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT] = nvstrdup(tmp ? tmp : "");
-    }
 }
 
 /*
@@ -778,6 +721,70 @@ done:
     return ret;
 }
 
+static gboolean send_string_message_to_gridd(CtkManageGridLicense *ctk_manage_grid_license, char *param, char *value)
+{
+    gboolean ret = FALSE;
+    DBusMessage *msg, *reply;
+    DBusMessageIter args;
+    DBusError err;
+    char *receivedVal = NULL;
+
+    DbusData *dbusData = ctk_manage_grid_license->dbusData;
+    DBusConnection* conn = dbusData->conn;
+
+    /* initialise the errors */
+    dbusData->dbus.dbusErrorInit(&err);
+
+    /* a new method call */
+    msg = dbusData->dbus.dbusMessageNewMethodCall(NV_GRID_DBUS_TARGET, // target for the method call
+                                                  NV_GRID_DBUS_OBJECT, // object to call on
+                                                  NV_GRID_DBUS_INTERFACE, // interface to call on
+                                                  NV_GRID_DBUS_METHOD); // method name
+    if (NULL == msg)
+    {
+        return FALSE;
+    }
+    /* append arguments */
+    dbusData->dbus.dbusMessageIterInitAppend(msg, &args);
+
+    if (!dbusData->dbus.dbusMessageIterAppendBasic(&args, DBUS_TYPE_STRING, &param))
+    {
+        goto done;
+    }
+
+    /* send a message and block for a default time period
+    while waiting for a reply and returns NULL on failure with an error code.*/
+    reply = dbusData->dbus.dbusConnectionSendWithReplyAndBlock(conn, msg, -1, &err);  // -1 is default timeout
+    if ((reply == NULL) || (dbusData->dbus.dbusErrorIsSet(&err)))
+    {
+        goto done;
+    }
+
+    /* read the parameters */
+    if (!dbusData->dbus.dbusMessageIterInit(reply, &args))
+    {
+        nv_error_msg("vGPU License dbus communication: Message has no arguments!\n");
+    }
+    else if (DBUS_TYPE_STRING != dbusData->dbus.dbusMessageIterGetArgType(&args))
+    {
+        nv_error_msg("vGPU License dbus communication: Argument is not string!\n");
+    }
+    else
+    {
+        dbusData->dbus.dbusMessageIterGetBasic(&args, &receivedVal);
+        if (receivedVal != NULL)
+        {
+            strncpy(value, receivedVal, BUF_LEN);
+        }
+    }
+
+    ret = TRUE;
+done:
+    /* free message */
+    dbusData->dbus.dbusMessageUnref(msg);
+    return ret;
+}
+
 /*
  * update_manage_grid_license_state_info() - update manage_grid_license state
  */
@@ -790,6 +797,9 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
 
     int licenseState            = NV_GRID_UNLICENSED;
     int griddFeatureType        = ctk_manage_grid_license->feature_type;
+    int portNum = 0;
+    char licenseServerInfo[BUF_LEN] = { 0 };
+    char port[BUF_LEN] = { 0 };
 
     /* Send license state and feature type request */
     if ((!(send_message_to_gridd(ctk_manage_grid_license, LICENSE_STATE_REQUEST,
@@ -803,11 +813,6 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
                                "dbus-daemon are running.\n";
         gtk_label_set_text(GTK_LABEL(ctk_manage_grid_license->label_license_state),
                            licenseStatusMessage);
-        /* Disable text controls on UI. */
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_address, FALSE);
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_port, FALSE);
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, FALSE);
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, FALSE);
         /* Disable Apply/Cancel button. */
         gtk_widget_set_sensitive(ctk_manage_grid_license->btn_apply, FALSE);
         gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, FALSE);
@@ -950,6 +955,30 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
                     break;
             }
         }
+        else if (licenseState == NV_GRID_LICENSE_RENEWING) {
+            switch (ctk_manage_grid_license->feature_type) {
+                case NV_GRID_LICENSE_FEATURE_TYPE_VAPP:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VWS:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VGPU:
+                    ctk_manage_grid_license->licenseStatus = NV_GRID_LICENSE_STATUS_RENEWING;
+                    break;
+                default:
+                    break;
+            }
+        }
+        else if (licenseState == NV_GRID_LICENSE_RENEW_FAILED) {
+            switch (ctk_manage_grid_license->feature_type) {
+                case NV_GRID_LICENSE_FEATURE_TYPE_VAPP:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VWS:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE:
+                case NV_GRID_LICENSE_FEATURE_TYPE_VGPU:
+                    ctk_manage_grid_license->licenseStatus = NV_GRID_LICENSE_STATUS_RENEW_FAILED;
+                    break;
+                default:
+                    break;
+            }
+        }
         else if ((ctk_manage_grid_license->feature_type == ctk_manage_grid_license->gridd_feature_type) &&  // 'Apply' button is clicked
                  (licenseState == NV_GRID_LICENSE_EXPIRED)) {
             switch (ctk_manage_grid_license->feature_type) {
@@ -980,10 +1009,61 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
         }
     }
 
+    // Fetch License Server details from nvidia-gridd through dbus
+    if (send_string_message_to_gridd(ctk_manage_grid_license, PRIMARY_SERVER_ADDRESS, licenseServerInfo))
+    {
+        // nvidia-gridd sends "Not Configured" if primary node is not available
+        if ((strlen(licenseServerInfo) > 0) && (strcmp(licenseServerInfo, SERVER_DETAILS_NOT_CONFIGURED) != 0))
+        {
+            gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_address), licenseServerInfo);
+            // Fetch primary server port number
+            if (send_message_to_gridd(ctk_manage_grid_license, LICENSE_SERVER_PORT_REQUEST, &portNum))
+            {
+                snprintf(port, BUF_LEN, "%d", portNum);
+            }
+            if (strlen(port) > 0)
+            {
+                gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_port), port);
+            }
+        }
+
+        memset(licenseServerInfo, '\0', BUF_LEN);
+        // Fetch Secondary Server Address
+        if (send_string_message_to_gridd(ctk_manage_grid_license, SECONDARY_SERVER_ADDRESS, licenseServerInfo))
+        {
+            // nvidia-gridd sends "Not Configured" if secondary node is not available
+            if ((strlen(licenseServerInfo) > 0) && (strcmp(licenseServerInfo, SERVER_DETAILS_NOT_CONFIGURED) != 0))
+            {
+                gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address), licenseServerInfo);
+                portNum = 0;
+                // Fetch secondary server port number
+                if (send_message_to_gridd(ctk_manage_grid_license, LICENSE_SERVER_PORT_REQUEST, &portNum))
+                {
+                    memset(port, '\0', BUF_LEN);
+                    snprintf(port, BUF_LEN, "%d", portNum);
+                }
+                if (strlen(port) > 0)
+                {
+                    gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port), port);
+                }
+            }
+        }
+    }
+    else
+    {
+        licenseStatusMessage = "Unable to query license server information "
+                               "from the NVIDIA vGPU "
+                               "licensing daemon.\n"
+                               "Please make sure nvidia-gridd and "
+                               "dbus-daemon are running.\n";
+        gtk_label_set_text(GTK_LABEL(ctk_manage_grid_license->label_license_state), licenseStatusMessage);
+        return ret;
+    }
+
     switch (ctk_manage_grid_license->licenseStatus) {
     case NV_GRID_UNLICENSED_VGPU:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Your system does not have a valid %s license.\n"
-              "Enter license server details and apply.", ctk_manage_grid_license->productName);
+              "Please configure client configuration token to acquire license.", ctk_manage_grid_license->productName);
           break;
     case NV_GRID_UNLICENSED_VAPP:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Your system is currently configured for %s.", NVIDIA_VIRTUAL_APPLICATIONS);
@@ -998,6 +1078,12 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
     case NV_GRID_LICENSE_STATUS_FAILED:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Failed to acquire %s license.", ctk_manage_grid_license->productName);
           break;
+    case NV_GRID_LICENSE_STATUS_RENEWING:
+          snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Renewing license for %s.", ctk_manage_grid_license->productName);
+          break;
+    case NV_GRID_LICENSE_STATUS_RENEW_FAILED:
+         snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Failed to renew license for %s, expiring at %s.", ctk_manage_grid_license->productName, ctk_manage_grid_license->licenseExpiry);
+         break;
     case NV_GRID_LICENSE_STATUS_EXPIRED:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "%s license has expired.", ctk_manage_grid_license->productName);
           break;
@@ -1024,11 +1110,11 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
           break;
     case NV_GRID_UNLICENSED_REQUEST_DETAILS_VWS:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Your system does not have a valid %s license.\n"
-              "Enter license server details and apply.", ctk_manage_grid_license->productNamevWS);
+              "Please configure client configuration token to acquire license.", ctk_manage_grid_license->productNamevWS);
           break;
     case NV_GRID_UNLICENSED_REQUEST_DETAILS_VCOMPUTE:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Your system does not have a valid %s license.\n"
-              "Enter license server details and apply.", ctk_manage_grid_license->productNamevCompute);
+              "Please configure client configuration token to acquire license.", ctk_manage_grid_license->productNamevCompute);
           break;
     case NV_GRID_LICENSE_GSP_REQUIRED_VCS:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Enable GSP firmware for %s.", ctk_manage_grid_license->productNamevCompute);
@@ -1038,7 +1124,7 @@ static gboolean update_manage_grid_license_state_info(gpointer user_data)
           break;
     default:
           snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "Your system does not have a valid GRID license.\n"
-              "Enter license server details and apply.");
+              "Please configure client configuration token to acquire license.");
           break;
     }
 
@@ -1270,26 +1356,9 @@ static void update_gui_from_griddconfig(gpointer user_data)
 {
     CtkManageGridLicense *ctk_manage_grid_license = CTK_MANAGE_GRID_LICENSE(user_data);
     NvGriddConfigParams *griddConfig = NULL;
-    const char *textBoxServerStr;
 
     griddConfig = GetNvGriddConfigParams();
-    if (!griddConfig) {
-        nv_error_msg("Null griddConfig. \n");
-        /* If griddConfig is Null, clear out all the textboxes. */
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_address), "");
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_port), "");
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address), "");
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port), "");
-    } else {
-        /* Set the text in all the textboxes from the griddconfig. */
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_address),
-                           griddConfig->str[NV_GRIDD_SERVER_ADDRESS]);
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_port),
-                           griddConfig->str[NV_GRIDD_SERVER_PORT]);
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address),
-                           griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS]);
-        gtk_entry_set_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port),
-                           griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT]);
+    if (griddConfig) {
         /* set default value for feature type based on the user configured parameter or virtualization mode */
         updateFeatureTypeFromGriddConfig(ctk_manage_grid_license, griddConfig);
 
@@ -1304,9 +1373,6 @@ static void update_gui_from_griddconfig(gpointer user_data)
                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctk_manage_grid_license->radio_btn_vapp), TRUE);
         }
 
-        /* Enable Primary server address/port textboxes. */
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_address, TRUE);
-        gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_port, TRUE);
         /* Enable toggle buttons. */
         if (ctk_manage_grid_license->radio_btn_vcompute) {
             gtk_widget_set_sensitive(ctk_manage_grid_license->radio_btn_vcompute, TRUE);
@@ -1318,15 +1384,6 @@ static void update_gui_from_griddconfig(gpointer user_data)
             gtk_widget_set_sensitive(ctk_manage_grid_license->radio_btn_vapp, TRUE);
         }
 
-        textBoxServerStr = gtk_entry_get_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_address));
-        /* Enable/Disable Secondary server address/port textboxes if Primary server address textbox string is empty. */
-        if (strcmp(textBoxServerStr, "") == 0) {
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, FALSE);
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, FALSE);
-        } else {
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, TRUE);
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, TRUE);
-        }
         /* Disable Apply/Cancel button. */
         gtk_widget_set_sensitive(ctk_manage_grid_license->btn_apply, FALSE);
         gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, FALSE);
@@ -1357,7 +1414,6 @@ static void license_edition_toggled(GtkWidget *widget, gpointer user_data)
     user_data = g_object_get_data(G_OBJECT(widget), "button_id");
 
     if (GPOINTER_TO_INT(user_data) == NV_GRID_LICENSE_FEATURE_TYPE_VWS) {
-        gtk_widget_set_sensitive(ctk_manage_grid_license->box_server_info, TRUE);
         snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "You selected %s", ctk_manage_grid_license->productNamevWS);
         statusBarMsg = licenseStatusMsgTmp;
         ctk_manage_grid_license->feature_type =
@@ -1368,7 +1424,6 @@ static void license_edition_toggled(GtkWidget *widget, gpointer user_data)
                 gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, TRUE);
         }
     }  else if (GPOINTER_TO_INT(user_data) == NV_GRID_LICENSE_FEATURE_TYPE_VAPP) {
-        gtk_widget_set_sensitive(ctk_manage_grid_license->box_server_info, FALSE);
         ctk_manage_grid_license->feature_type = 
             NV_GRID_LICENSE_FEATURE_TYPE_VAPP;
         snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "You selected %s", NVIDIA_VIRTUAL_APPLICATIONS);
@@ -1379,7 +1434,6 @@ static void license_edition_toggled(GtkWidget *widget, gpointer user_data)
             gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, TRUE);
         }
     } else if (GPOINTER_TO_INT(user_data) == NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE) {
-        gtk_widget_set_sensitive(ctk_manage_grid_license->box_server_info, TRUE);
         snprintf(licenseStatusMsgTmp, sizeof(licenseStatusMsgTmp), "You selected %s", ctk_manage_grid_license->productNamevCompute);
         statusBarMsg = licenseStatusMsgTmp;
         ctk_manage_grid_license->feature_type =
@@ -1398,106 +1452,6 @@ static void license_edition_toggled(GtkWidget *widget, gpointer user_data)
     FreeNvGriddConfigParams(griddConfig);
 }
 
-static gboolean disallow_whitespace(GtkWidget *widget, GdkEvent *event, gpointer user_data)
-{
-    GdkEventKey *key_event;
-
-    if (event->type == GDK_KEY_PRESS) {
-        key_event = (GdkEventKey *) event;
-
-        if (isspace(key_event->keyval)) {
-            return TRUE;
-        }
-    }
-
-    return FALSE;
-}
-
-static gboolean enable_disable_ui_controls(GtkWidget *widget, GdkEvent *event, gpointer user_data)
-{
-    CtkManageGridLicense *ctk_manage_grid_license = CTK_MANAGE_GRID_LICENSE(user_data);
-    NvGriddConfigParams *griddConfig;
-    const char *textBoxServerStr, *textBoxServerPortStr, *textBoxSecondaryServerStr, *textBoxSecondaryServerPortStr;
-
-    griddConfig = GetNvGriddConfigParams();
-    if (!griddConfig)
-        return TRUE;
-
-    if (event->type == GDK_KEY_RELEASE) {
-
-        // Read license strings from textboxes.
-        textBoxServerStr = gtk_entry_get_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_address));
-        textBoxServerPortStr = gtk_entry_get_text(GTK_ENTRY(ctk_manage_grid_license->txt_server_port));
-        textBoxSecondaryServerStr = gtk_entry_get_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address));
-        textBoxSecondaryServerPortStr = gtk_entry_get_text(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port));
-
-        /* Enable apply/cancel button if either:
-            Primary server address/port textbox string doesn't match with the Primary server string from the vGPU license config file or
-            Secondary server address/port textbox string doesn't match with the Secondary server string from the vGPU license config file. */
-        if ((strcmp(griddConfig->str[NV_GRIDD_SERVER_ADDRESS], textBoxServerStr) != 0) ||
-            ((strcmp(griddConfig->str[NV_GRIDD_BACKUP_SERVER_ADDRESS], textBoxSecondaryServerStr) != 0) ||
-            (strcmp(griddConfig->str[NV_GRIDD_BACKUP_SERVER_PORT], textBoxSecondaryServerPortStr) != 0) ||
-            (strcmp(griddConfig->str[NV_GRIDD_SERVER_PORT], textBoxServerPortStr) != 0))) {
-                gtk_widget_set_sensitive(ctk_manage_grid_license->btn_apply, TRUE);
-                gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, TRUE);
-        } else {
-                gtk_widget_set_sensitive(ctk_manage_grid_license->btn_apply, FALSE);
-                gtk_widget_set_sensitive(ctk_manage_grid_license->btn_cancel, FALSE);
-        }
-
-        /* Disable Secondary server address/port textboxes if Primary server address text box string is empty
-            to notify user that Primary server address is mandatory. */
-        if (strcmp(textBoxServerStr, "") == 0) {
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, FALSE);
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, FALSE);
-        } else {
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, TRUE);
-            gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, TRUE);
-        }
-    }
-
-    FreeNvGriddConfigParams(griddConfig);
-
-    return FALSE;
-}
-
-static gboolean allow_digits(GtkWidget *widget, GdkEvent *event, gpointer user_data)
-{
-    GdkEventKey *key_event;
-
-    if (event->type == GDK_KEY_PRESS) {
-        key_event = (GdkEventKey *) event;
-        switch (key_event->keyval) {
-        case GDK_Left:
-        case GDK_KP_Left:
-        case GDK_Down:
-        case GDK_KP_Down:
-        case GDK_Right:
-        case GDK_KP_Right:
-        case GDK_Up:
-        case GDK_KP_Up:
-        case GDK_Page_Down:
-        case GDK_KP_Page_Down:
-        case GDK_Page_Up:
-        case GDK_KP_Page_Up:
-        case GDK_BackSpace:
-        case GDK_Delete:
-        case GDK_Tab:
-        case GDK_KP_Tab:
-        case GDK_ISO_Left_Tab:
-            // Allow all control keys
-            return FALSE;
-        default:
-            // Allow digits
-            if (isdigit(key_event->keyval)) {
-                return FALSE;
-            }
-        }
-    }
-
-    return TRUE;
-}
-
 static gboolean checkConfigfile(gboolean *writable)
 {
     struct stat st;
@@ -1788,7 +1742,7 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
     gtk_container_add(GTK_CONTAINER(frame), vbox2);
     
     /* License Server */
-    label = gtk_label_new("License Server:");
+    label = gtk_label_new("License Server Details:");
     hbox = gtk_hbox_new(FALSE, 0);
     eventbox = gtk_event_box_new();
     gtk_container_add(GTK_CONTAINER(eventbox), label);
@@ -1808,7 +1762,7 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
 
 
     /* Primary License Server Address */
-    label = gtk_label_new("Primary Server:");
+    label = gtk_label_new("Primary Server Address:");
     ctk_manage_grid_license->txt_server_address = gtk_entry_new();
     hbox = gtk_hbox_new(FALSE, 0);
     eventbox = gtk_event_box_new();
@@ -1817,15 +1771,10 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
     gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, TRUE, 0);
     gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2,
                      GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_server_address), "key-press-event",
-                     G_CALLBACK(disallow_whitespace),
-                     (gpointer) ctk_manage_grid_license);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_server_address), "key-release-event",
-                     G_CALLBACK(enable_disable_ui_controls),
-                     (gpointer) ctk_manage_grid_license);
 
     /* value */
     hbox = gtk_hbox_new(FALSE, 0);
+    gtk_widget_set_size_request(ctk_manage_grid_license->txt_server_address, BUF_LEN, -1);
     gtk_box_pack_start(GTK_BOX(hbox),
                        ctk_manage_grid_license->txt_server_address,
                        FALSE, FALSE, 0);
@@ -1845,21 +1794,17 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
 
     /* value */
     ctk_manage_grid_license->txt_server_port = gtk_entry_new();
+
+    gtk_widget_set_size_request(ctk_manage_grid_license->txt_server_port, BUF_LEN, -1);
     hbox = gtk_hbox_new(FALSE, 0);
     gtk_box_pack_start(GTK_BOX(hbox),
                        ctk_manage_grid_license->txt_server_port,
                        FALSE, FALSE, 0);
     gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 2, 3,
                      GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_server_port), "key-press-event",
-                     G_CALLBACK(allow_digits),
-                     (gpointer) ctk_manage_grid_license);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_server_port), "key-release-event",
-                     G_CALLBACK(enable_disable_ui_controls),
-                     (gpointer) ctk_manage_grid_license);
 
     /* Backup Server Address */
-    label = gtk_label_new("Secondary Server:");
+    label = gtk_label_new("Secondary Server Address:");
     ctk_manage_grid_license->txt_secondary_server_address = gtk_entry_new();
 
     hbox = gtk_hbox_new(FALSE, 0);
@@ -1870,15 +1815,10 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
     gtk_box_pack_start(GTK_BOX(hbox), eventbox, FALSE, TRUE, 0);
     gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 5, 6,
                      GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address), "key-press-event",
-                     G_CALLBACK(disallow_whitespace),
-                     (gpointer) ctk_manage_grid_license);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_address), "key-release-event",
-                     G_CALLBACK(enable_disable_ui_controls),
-                     (gpointer) ctk_manage_grid_license);
 
     /* value */
     hbox = gtk_hbox_new(FALSE, 0);
+    gtk_widget_set_size_request(ctk_manage_grid_license->txt_secondary_server_address, BUF_LEN, -1);
     gtk_box_pack_start(GTK_BOX(hbox),
                        ctk_manage_grid_license->txt_secondary_server_address,
                        FALSE, FALSE, 0);
@@ -1898,19 +1838,13 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
 
     /* value */
     ctk_manage_grid_license->txt_secondary_server_port = gtk_entry_new();
-
+    gtk_widget_set_size_request(ctk_manage_grid_license->txt_secondary_server_port, BUF_LEN, -1);
     hbox = gtk_hbox_new(FALSE, 0);
     gtk_box_pack_start(GTK_BOX(hbox),
                        ctk_manage_grid_license->txt_secondary_server_port,
                        FALSE, FALSE, 0);
     gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 6, 7,
                      GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port), "key-press-event",
-                     G_CALLBACK(allow_digits),
-                     (gpointer) ctk_manage_grid_license);
-    g_signal_connect(GTK_ENTRY(ctk_manage_grid_license->txt_secondary_server_port), "key-release-event",
-                     G_CALLBACK(enable_disable_ui_controls),
-                     (gpointer) ctk_manage_grid_license);
     ctk_manage_grid_license->box_server_info = vbox2;
 
     /* Apply button */
@@ -1940,6 +1874,12 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
                      G_CALLBACK(cancel_clicked),
                      (gpointer) ctk_manage_grid_license);
 
+    // Disable write action text boxes for license server information
+    gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_address, FALSE);
+    gtk_widget_set_sensitive(ctk_manage_grid_license->txt_server_port, FALSE);
+    gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_address, FALSE);
+    gtk_widget_set_sensitive(ctk_manage_grid_license->txt_secondary_server_port, FALSE);
+
     /* Update GUI with information from the vGPU license config file */
     update_gui_from_griddconfig(ctk_manage_grid_license);
 
@@ -2009,16 +1949,16 @@ GtkTextBuffer *ctk_manage_grid_license_create_help(GtkTextTagTable *table,
         ctk_help_para(b, &i, "%s", __grid_vapp_help);
     }
 
-    ctk_help_heading(b, &i, "License Server");
+    ctk_help_heading(b, &i, "License Server Details");
     ctk_help_para(b, &i, "%s", __license_server_help);
 
-    ctk_help_heading(b, &i, "Primary Server");
+    ctk_help_heading(b, &i, "Primary Server Address");
     ctk_help_para(b, &i, "%s", __primary_server_address_help);
 
     ctk_help_heading(b, &i, "Port Number");
     ctk_help_para(b, &i, "%s", __primary_server_port_help);
 
-    ctk_help_heading(b, &i, "Secondary Server");
+    ctk_help_heading(b, &i, "Secondary Server Address");
     ctk_help_para(b, &i, "%s", __secondary_server_help);
 
     ctk_help_heading(b, &i, "Port Number");
diff --git a/src/gtk+-2.x/ctkgridlicense.h b/src/gtk+-2.x/ctkgridlicense.h
index a26b442a90ce38076840e55e0800591d61129da0..24dd51aec19d0a55535340a3519273b487c11378 100644
--- a/src/gtk+-2.x/ctkgridlicense.h
+++ b/src/gtk+-2.x/ctkgridlicense.h
@@ -2,7 +2,7 @@
  * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
  * and Linux systems.
  *
- * Copyright (C) 2022 NVIDIA Corporation.
+ * Copyright (C) 2022-2023 NVIDIA Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -93,6 +93,8 @@ typedef enum
     NV_GRID_LICENSE_STATUS_ACQUIRED,
     NV_GRID_LICENSE_STATUS_REQUESTING,
     NV_GRID_LICENSE_STATUS_FAILED,
+    NV_GRID_LICENSE_STATUS_RENEWING,
+    NV_GRID_LICENSE_STATUS_RENEW_FAILED,
     NV_GRID_LICENSE_STATUS_EXPIRED,
     NV_GRID_LICENSE_RESTART_REQUIRED_VAPP,
     NV_GRID_LICENSE_RESTART_REQUIRED_VWS,
diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c
index 0640f5e8a27ebcac7f7af0830c1cf0750f74090c..04316d0306f1c8e61a0f4ef0c7a52c845a56fc3e 100644
--- a/src/gtk+-2.x/ctkpowermizer.c
+++ b/src/gtk+-2.x/ctkpowermizer.c
@@ -66,6 +66,15 @@ static const char *__power_source_help =
 "The Power Source indicates whether the machine "
 "is running on AC or Battery power.";
 
+static const char *__power_draw_help =
+"This indicates the current power usage of the GPU, in Watts.";
+
+static const char *__default_tgp_help =
+"This indicates the default Total Graphics Power (TGP) of the GPU, in Watts.";
+
+static const char *__max_tgp_help =
+"This indicates the maximum Total Graphics Power (TGP) of the GPU, in Watts.";
+
 static const char *__current_pcie_link_width_help =
 "This is the current PCIe link width of the GPU, in number of lanes.";
 
@@ -905,12 +914,13 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
 
 static gboolean update_powermizer_info(gpointer user_data)
 {
+    gint power_draw;
     gint power_source, adaptive_clock, perf_level;
     gint gpu_clock, memory_transfer_rate;
     CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(user_data);
     CtrlTarget *ctrl_target = ctk_powermizer->ctrl_target;
     gint ret;
-    gchar *s;
+    gchar *s = NULL;
     char *clock_string = NULL;
     perfModeEntry pEntry;
 
@@ -974,6 +984,9 @@ static gboolean update_powermizer_info(gpointer user_data)
         else if (power_source == NV_CTRL_GPU_POWER_SOURCE_BATTERY) {
             s = g_strdup_printf("Battery");
         }
+        else if (power_source == NV_CTRL_GPU_POWER_SOURCE_UNDERSIZED) {
+            s = g_strdup_printf("Undersized");
+        }
         else {
             s = g_strdup_printf("Error");
         }
@@ -982,6 +995,46 @@ static gboolean update_powermizer_info(gpointer user_data)
         g_free(s);
     }
 
+    /* Power Draw */
+    ret = NvCtrlGetAttribute(ctrl_target,
+                             NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE,
+                             &power_draw);
+    if ((ret == NvCtrlSuccess) && ctk_powermizer->power_draw) {
+        /* Round up to 1 watt for display  */
+        if (power_draw < 1000) {
+            power_draw = 1000;
+        }
+        s = g_strdup_printf("%.2f W", power_draw / 1000.0f);
+        gtk_label_set_text(GTK_LABEL(ctk_powermizer->power_draw), s);
+        g_free(s);
+    }
+
+    /* Show TGP as N/A when power source is battery or undersized. */
+    if ((power_source == NV_CTRL_GPU_POWER_SOURCE_BATTERY) ||
+        (power_source == NVML_POWER_SOURCE_UNDERSIZED)) {
+        s = g_strdup_printf("N/A");
+        if (ctk_powermizer->default_tgp) {
+            gtk_label_set_text(GTK_LABEL(ctk_powermizer->default_tgp), s);
+        }
+        if (ctk_powermizer->max_tgp) {
+            gtk_label_set_text(GTK_LABEL(ctk_powermizer->max_tgp), s);
+        }
+        g_free(s);
+    } else if (power_source == NV_CTRL_GPU_POWER_SOURCE_AC) {
+        if (ctk_powermizer->default_tgp) {
+            s = g_strdup_printf("%.2f W",
+                                ctk_powermizer->default_tgp_value / 1000.0f);
+            gtk_label_set_text(GTK_LABEL(ctk_powermizer->default_tgp), s);
+            g_free(s);
+        }
+        if (ctk_powermizer->max_tgp) {
+            s = g_strdup_printf("%.2f W",
+                                ctk_powermizer->max_tgp_value / 1000.0f);
+            gtk_label_set_text(GTK_LABEL(ctk_powermizer->max_tgp), s);
+            g_free(s);
+        }
+    }
+
     if (ctk_powermizer->link_width) {
         /* NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH */
         s = get_pcie_link_width_string(ctrl_target,
@@ -1099,11 +1152,16 @@ GtkWidget* ctk_powermizer_new(CtrlTarget *ctrl_target,
     CtkDropDownMenu *menu;
     ReturnStatus ret;
     gint nvclock_attribute = 0, mem_transfer_rate_attribute = 0;
+    gint default_tgp = 0;
+    gint max_tgp = 0;
     gint val;
     gint row = 0;
     gchar *s = NULL;
     gint tmp;
     gboolean power_source_available = FALSE;
+    gboolean power_draw_available = FALSE;
+    gboolean max_tgp_available = FALSE;
+    gboolean default_tgp_available = FALSE;
     gboolean perf_level_available = FALSE;
     gboolean gpu_clock_available = FALSE;
     gboolean mem_transfer_rate_available = FALSE;
@@ -1229,6 +1287,29 @@ GtkWidget* ctk_powermizer_new(CtrlTarget *ctrl_target,
     ctk_powermizer->nvclock_attribute = nvclock_attribute;
     ctk_powermizer->mem_transfer_rate_attribute = mem_transfer_rate_attribute;
 
+    /* check if power management information is available */
+
+    ret = NvCtrlGetAttribute(ctrl_target,
+                             NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE,
+                             &tmp);
+    if (ret == NvCtrlSuccess) {
+        power_draw_available = TRUE;
+    }
+    ret = NvCtrlGetAttribute(ctrl_target,
+                             NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP,
+                             &default_tgp);
+    if (ret == NvCtrlSuccess) {
+        default_tgp_available = TRUE;
+        ctk_powermizer->default_tgp_value = default_tgp;
+    }
+    ret = NvCtrlGetAttribute(ctrl_target,
+                             NV_CTRL_ATTR_NVML_GPU_MAX_TGP,
+                             &max_tgp);
+    if (ret == NvCtrlSuccess) {
+        max_tgp_available = TRUE;
+        ctk_powermizer->max_tgp_value = max_tgp;
+    }
+
     /* set container properties for the CtkPowermizer widget */
 
     gtk_box_set_spacing(GTK_BOX(ctk_powermizer), 5);
@@ -1325,6 +1406,58 @@ GtkWidget* ctk_powermizer_new(CtrlTarget *ctrl_target,
     } else {
         ctk_powermizer->power_source = NULL;
     }
+    /* Power Draw */
+    if (power_draw_available) {
+        /* spacing */
+        row += 3;
+        ctk_powermizer->power_draw =
+            add_table_row_with_help_text(table, ctk_config,
+                                         __power_draw_help,
+                                         row++, //row
+                                         0,  // column
+                                         0.0f,
+                                         0.5,
+                                         "Power Draw:",
+                                         0.0,
+                                         0.5,
+                                         NULL);
+    } else {
+        ctk_powermizer->power_draw = NULL;
+    }
+    /* Default TGP */
+    if (default_tgp_available) {
+        /* spacing */
+        ctk_powermizer->default_tgp =
+            add_table_row_with_help_text(table, ctk_config,
+                                         __default_tgp_help,
+                                         row++, //row
+                                         0,  // column
+                                         0.0f,
+                                         0.5,
+                                         "Default TGP:",
+                                         0.0,
+                                         0.5,
+                                         NULL);
+    } else {
+        ctk_powermizer->default_tgp = NULL;
+    }
+    /* Max TGP */
+    if (max_tgp_available) {
+        /* spacing */
+        ctk_powermizer->max_tgp =
+            add_table_row_with_help_text(table, ctk_config,
+                                         __max_tgp_help,
+                                         row++, //row
+                                         0,  // column
+                                         0.0f,
+                                         0.5,
+                                         "Max TGP:",
+                                         0.0,
+                                         0.5,
+                                         NULL);
+    } else {
+        ctk_powermizer->max_tgp = NULL;
+    }
     /* PCIe Gen Info block */
     if (pcie_link_width_available || pcie_link_speed_available) {
         /* spacing */
@@ -1719,6 +1852,19 @@ GtkTextBuffer *ctk_powermizer_create_help(GtkTextTagTable *table,
         ctk_help_para(b, &i, "%s", __power_source_help);
     }
 
+    if (ctk_powermizer->power_draw) {
+        ctk_help_heading(b, &i, "Power Draw");
+        ctk_help_para(b, &i, "%s", __power_draw_help);
+    }
+    if (ctk_powermizer->default_tgp) {
+        ctk_help_heading(b, &i, "Default TGP");
+        ctk_help_para(b, &i, "%s", __default_tgp_help);
+    }
+    if (ctk_powermizer->max_tgp) {
+        ctk_help_heading(b, &i, "Max TGP");
+        ctk_help_para(b, &i, "%s", __max_tgp_help);
+    }
+
     if (ctk_powermizer->link_width) {
         ctk_help_heading(b, &i, "Current PCIe link width");
         ctk_help_para(b, &i, "%s", __current_pcie_link_width_help);
diff --git a/src/gtk+-2.x/ctkpowermizer.h b/src/gtk+-2.x/ctkpowermizer.h
index 10712e0f03cd89bcadddc9662483a80d15c28492..4666aeb548074a9ad304fb66d142bfd346cd351f 100644
--- a/src/gtk+-2.x/ctkpowermizer.h
+++ b/src/gtk+-2.x/ctkpowermizer.h
@@ -77,6 +77,12 @@ struct _CtkPowermizer
 
     GtkWidget *link_width;
     GtkWidget *link_speed;
+    GtkWidget *max_tgp;
+    GtkWidget *default_tgp;
+    GtkWidget *power_draw;
+
+    gint      max_tgp_value;
+    gint      default_tgp_value;
 };
 
 struct _CtkPowermizerClass
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index df888cf128e053fc0497210fb2c5c46f7c14c809..dc35d64e64f28ce0feeb41968fce95b93cddc47d 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -1968,6 +1968,7 @@
 #define NV_CTRL_GPU_POWER_SOURCE                                262 /* R--G */
 #define NV_CTRL_GPU_POWER_SOURCE_AC                               0
 #define NV_CTRL_GPU_POWER_SOURCE_BATTERY                          1
+#define NV_CTRL_GPU_POWER_SOURCE_UNDERSIZED                       2
 
 
 /*
@@ -3637,7 +3638,37 @@
  */
 #define NV_CTRL_DYNAMIC_BOOST_SUPPORT                           439
 
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DYNAMIC_BOOST_SUPPORT
+/*
+ * NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE - Controls the value to multiply or
+ * divide the house sync input timing by before comparing it to this board's
+ * framelock sync rate.
+ *
+ * This attribute may be queried through XNVCTRLQueryTargetAttribute()
+ * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN
+ * target.
+ */
+#define NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE                 440 /* RW-F */
+
+/*
+ * NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE - Controls whether
+ * NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE should be used to multiply or
+ * divide the house sync input rate.
+ *
+ * This attribute may be queried through XNVCTRLQueryTargetAttribute()
+ * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN
+ * target.
+ */
+#define NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE                  441 /* RW-F */
+#define NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_MULTIPLY           0
+#define NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE_DIVIDE             1
+
+/*
+ * NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED - Returns how many underlying hardware
+ * heads are currently used to drive this display.
+ */
+#define NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED                      442 /* R-DG */
+
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED
 
 /**************************************************************************/
 
diff --git a/src/libXNVCtrl/version.mk b/src/libXNVCtrl/version.mk
index dae35ac2315e7ed874c063beacadec078b9447d1..89404cd76a7444270097f0872a9cf1a582796891 100644
--- a/src/libXNVCtrl/version.mk
+++ b/src/libXNVCtrl/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 525.147.05
+NVIDIA_VERSION = 535.171.04
 
 # This file.
 VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index af424bb14eabb573f297c2e16063ceb46f731b05..8e4817d8d4c89154d923b0173236045f56b0d0c3 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -286,7 +286,13 @@ typedef enum {
 
 #define NV_CTRL_ATTR_NVML_GSP_FIRMWARE_MODE                     (NV_CTRL_ATTR_NVML_BASE + 3)
 
-#define NV_CTRL_ATTR_NVML_LAST_ATTRIBUTE (NV_CTRL_ATTR_NVML_GSP_FIRMWARE_MODE)
+#define NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE                   (NV_CTRL_ATTR_NVML_BASE + 5)
+
+#define NV_CTRL_ATTR_NVML_GPU_MAX_TGP                           (NV_CTRL_ATTR_NVML_BASE + 6)
+
+#define NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP                       (NV_CTRL_ATTR_NVML_BASE + 7)
+
+#define NV_CTRL_ATTR_NVML_LAST_ATTRIBUTE (NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP)
 
 #define NV_CTRL_ATTR_LAST_ATTRIBUTE \
         (NV_CTRL_ATTR_NVML_LAST_ATTRIBUTE)
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
index 656d2367e9038d2cff7aa1a38a9ecc2fae708b97..0dabffa9e05138ce3dad648d517ec5e49a9d0802 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
@@ -167,8 +167,8 @@ static void UnloadNvml(NvCtrlNvmlAttributes *nvml)
         return;
     }
 
-    if (nvml->lib.shutdown != NULL) {
-        nvmlReturn_t ret = nvml->lib.shutdown();
+    if (nvml->lib.Shutdown != NULL) {
+        nvmlReturn_t ret = nvml->lib.Shutdown();
         if (ret != NVML_SUCCESS) {
             printNvmlError(ret);
         }
@@ -206,62 +206,72 @@ static Bool LoadNvml(NvCtrlNvmlAttributes *nvml)
         goto fail;
     }
 
-#define GET_SYMBOL(_required, _proc, _name)             \
-    nvml->lib._proc = dlsym(nvml->lib.handle, _name);   \
-    if (nvml->lib._proc == NULL) {                      \
-        if (_required) {                                \
-            goto fail;                                  \
-        } else {                                        \
-            nvml->lib._proc = (void*) NvmlStubFunction; \
-        }                                               \
-    }
-
-    GET_SYMBOL(_REQUIRED, init,                           "nvmlInit");
-    GET_SYMBOL(_REQUIRED, shutdown,                       "nvmlShutdown");
-    GET_SYMBOL(_REQUIRED, deviceGetHandleByIndex,         "nvmlDeviceGetHandleByIndex");
-    GET_SYMBOL(_REQUIRED, deviceGetUUID,                  "nvmlDeviceGetUUID");
-    GET_SYMBOL(_REQUIRED, deviceGetCount,                 "nvmlDeviceGetCount");
-    GET_SYMBOL(_REQUIRED, deviceGetTemperature,           "nvmlDeviceGetTemperature");
-    GET_SYMBOL(_REQUIRED, deviceGetName,                  "nvmlDeviceGetName");
-    GET_SYMBOL(_REQUIRED, deviceGetVbiosVersion,          "nvmlDeviceGetVbiosVersion");
-    GET_SYMBOL(_REQUIRED, deviceGetMemoryInfo,            "nvmlDeviceGetMemoryInfo");
-    GET_SYMBOL(_REQUIRED, deviceGetPciInfo,               "nvmlDeviceGetPciInfo");
-    GET_SYMBOL(_REQUIRED, deviceGetCurrPcieLinkWidth,     "nvmlDeviceGetCurrPcieLinkWidth");
-    GET_SYMBOL(_REQUIRED, deviceGetMaxPcieLinkGeneration, "nvmlDeviceGetMaxPcieLinkGeneration");
-    GET_SYMBOL(_REQUIRED, deviceGetMaxPcieLinkWidth,      "nvmlDeviceGetMaxPcieLinkWidth");
-    GET_SYMBOL(_REQUIRED, deviceGetVirtualizationMode,    "nvmlDeviceGetVirtualizationMode");
-    GET_SYMBOL(_REQUIRED, deviceGetUtilizationRates,      "nvmlDeviceGetUtilizationRates");
-    GET_SYMBOL(_REQUIRED, deviceGetTemperatureThreshold,  "nvmlDeviceGetTemperatureThreshold");
-    GET_SYMBOL(_REQUIRED, deviceGetFanSpeed_v2,           "nvmlDeviceGetFanSpeed_v2");
-    GET_SYMBOL(_REQUIRED, systemGetDriverVersion,         "nvmlSystemGetDriverVersion");
-    GET_SYMBOL(_REQUIRED, deviceGetEccMode,               "nvmlDeviceGetEccMode");
-    GET_SYMBOL(_REQUIRED, deviceSetEccMode,               "nvmlDeviceSetEccMode");
-    GET_SYMBOL(_REQUIRED, deviceGetTotalEccErrors,        "nvmlDeviceGetTotalEccErrors");
-    GET_SYMBOL(_REQUIRED, deviceClearEccErrorCounts,      "nvmlDeviceClearEccErrorCounts");
-    GET_SYMBOL(_REQUIRED, systemGetNVMLVersion,           "nvmlSystemGetNVMLVersion");
-    GET_SYMBOL(_REQUIRED, deviceGetMemoryErrorCounter,    "nvmlDeviceGetMemoryErrorCounter");
-    GET_SYMBOL(_REQUIRED, deviceGetNumGpuCores,           "nvmlDeviceGetNumGpuCores");
-    GET_SYMBOL(_REQUIRED, deviceGetMemoryBusWidth,        "nvmlDeviceGetMemoryBusWidth");
-    GET_SYMBOL(_REQUIRED, deviceGetIrqNum,                "nvmlDeviceGetIrqNum");
-    GET_SYMBOL(_REQUIRED, deviceGetPowerSource,           "nvmlDeviceGetPowerSource");
-    GET_SYMBOL(_REQUIRED, deviceGetNumFans,               "nvmlDeviceGetNumFans");
-    GET_SYMBOL(_REQUIRED, deviceGetDefaultEccMode,        "nvmlDeviceGetDefaultEccMode");
+#define STRINGIFY_SYMBOL(_symbol) #_symbol
+
+#define EXPAND_STRING(_symbol) STRINGIFY_SYMBOL(_symbol)
+
+#define GET_SYMBOL(_required, _proc)                                           \
+    nvml->lib._proc = dlsym(nvml->lib.handle, "nvml" STRINGIFY_SYMBOL(_proc)); \
+    nvml->lib._proc = dlsym(nvml->lib.handle, EXPAND_STRING(nvml ## _proc));   \
+    if (nvml->lib._proc == NULL) {                                             \
+        if (_required) {                                                       \
+            goto fail;                                                         \
+        } else {                                                               \
+            nvml->lib._proc = (void*) NvmlStubFunction;                        \
+        }                                                                      \
+    }
+
+    GET_SYMBOL(_REQUIRED, Init);
+    GET_SYMBOL(_REQUIRED, Shutdown);
+    GET_SYMBOL(_REQUIRED, DeviceGetHandleByIndex);
+    GET_SYMBOL(_REQUIRED, DeviceGetUUID);
+    GET_SYMBOL(_REQUIRED, DeviceGetCount);
+    GET_SYMBOL(_REQUIRED, DeviceGetTemperature);
+    GET_SYMBOL(_REQUIRED, DeviceGetName);
+    GET_SYMBOL(_REQUIRED, DeviceGetVbiosVersion);
+    GET_SYMBOL(_REQUIRED, DeviceGetMemoryInfo);
+    GET_SYMBOL(_REQUIRED, DeviceGetPciInfo);
+    GET_SYMBOL(_REQUIRED, DeviceGetCurrPcieLinkWidth);
+    GET_SYMBOL(_REQUIRED, DeviceGetMaxPcieLinkGeneration);
+    GET_SYMBOL(_REQUIRED, DeviceGetMaxPcieLinkWidth);
+    GET_SYMBOL(_REQUIRED, DeviceGetVirtualizationMode);
+    GET_SYMBOL(_REQUIRED, DeviceGetUtilizationRates);
+    GET_SYMBOL(_REQUIRED, DeviceGetTemperatureThreshold);
+    GET_SYMBOL(_REQUIRED, DeviceGetFanSpeed_v2);
+    GET_SYMBOL(_REQUIRED, SystemGetDriverVersion);
+    GET_SYMBOL(_REQUIRED, DeviceGetEccMode);
+    GET_SYMBOL(_REQUIRED, DeviceSetEccMode);
+    GET_SYMBOL(_REQUIRED, DeviceGetTotalEccErrors);
+    GET_SYMBOL(_REQUIRED, DeviceClearEccErrorCounts);
+    GET_SYMBOL(_REQUIRED, SystemGetNVMLVersion);
+    GET_SYMBOL(_REQUIRED, DeviceGetMemoryErrorCounter);
+    GET_SYMBOL(_REQUIRED, DeviceGetNumGpuCores);
+    GET_SYMBOL(_REQUIRED, DeviceGetMemoryBusWidth);
+    GET_SYMBOL(_REQUIRED, DeviceGetIrqNum);
+    GET_SYMBOL(_REQUIRED, DeviceGetPowerSource);
+    GET_SYMBOL(_REQUIRED, DeviceGetNumFans);
+    GET_SYMBOL(_REQUIRED, DeviceGetDefaultEccMode);
     
 /* Do not fail with older drivers */
     
-    GET_SYMBOL(_OPTIONAL, deviceGetGridLicensableFeatures, "nvmlDeviceGetGridLicensableFeatures_v4");
-    GET_SYMBOL(_OPTIONAL, deviceGetGspFirmwareMode,        "nvmlDeviceGetGspFirmwareMode");
-    GET_SYMBOL(_OPTIONAL, deviceGetMemoryInfo_v2,          "nvmlDeviceGetMemoryInfo_v2");
-    GET_SYMBOL(_OPTIONAL, deviceSetFanSpeed_v2,            "nvmlDeviceSetFanSpeed_v2");
-    GET_SYMBOL(_OPTIONAL, deviceGetTargetFanSpeed,         "nvmlDeviceGetTargetFanSpeed");
-    GET_SYMBOL(_OPTIONAL, deviceGetMinMaxFanSpeed,         "nvmlDeviceGetMinMaxFanSpeed");
-    GET_SYMBOL(_OPTIONAL, deviceSetFanControlPolicy,       "nvmlDeviceSetFanControlPolicy");
-    GET_SYMBOL(_OPTIONAL, deviceGetFanControlPolicy_v2,    "nvmlDeviceGetFanControlPolicy_v2");
-    GET_SYMBOL(_OPTIONAL, deviceSetDefaultFanSpeed_v2,     "nvmlDeviceSetDefaultFanSpeed_v2");
+    GET_SYMBOL(_OPTIONAL, DeviceGetGridLicensableFeatures);
+    GET_SYMBOL(_OPTIONAL, DeviceGetGspFirmwareMode);
+    GET_SYMBOL(_OPTIONAL, DeviceGetMemoryInfo_v2);
+    GET_SYMBOL(_OPTIONAL, DeviceSetFanSpeed_v2);
+    GET_SYMBOL(_OPTIONAL, DeviceGetTargetFanSpeed);
+    GET_SYMBOL(_OPTIONAL, DeviceGetMinMaxFanSpeed);
+    GET_SYMBOL(_OPTIONAL, DeviceSetFanControlPolicy);
+    GET_SYMBOL(_OPTIONAL, DeviceGetFanControlPolicy_v2);
+    GET_SYMBOL(_OPTIONAL, DeviceSetDefaultFanSpeed_v2);
+    GET_SYMBOL(_OPTIONAL, DeviceGetPowerUsage);
+    GET_SYMBOL(_OPTIONAL, DeviceGetPowerManagementLimitConstraints);
+    GET_SYMBOL(_OPTIONAL, DeviceGetPowerManagementDefaultLimit);
 
 #undef GET_SYMBOL
+#undef EXPAND_STRING
+#undef STRINGIFY_SYMBOL
 
-    ret = nvml->lib.init();
+    ret = nvml->lib.Init();
 
     if (ret != NVML_SUCCESS) {
         printNvmlError(ret);
@@ -326,11 +336,11 @@ static Bool matchNvCtrlWithNvmlIds(const NvCtrlNvmlAttributes *nvml,
 
             /* Look for the same UUID through NVML */
             for (j = 0; j < nvmlGpuCount; j++) {
-                if (NVML_SUCCESS != nvml->lib.deviceGetHandleByIndex(j, &device)) {
+                if (NVML_SUCCESS != nvml->lib.DeviceGetHandleByIndex(j, &device)) {
                     continue;
                 }
 
-                if (NVML_SUCCESS != nvml->lib.deviceGetUUID(device, nvmlUUID,
+                if (NVML_SUCCESS != nvml->lib.DeviceGetUUID(device, nvmlUUID,
                                                             MAX_NVML_STR_LEN)) {
                     continue;
                 }
@@ -388,7 +398,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
     }
 
     /* Initialize NVML attributes */
-    if (nvml->lib.deviceGetCount(&count) != NVML_SUCCESS) {
+    if (nvml->lib.DeviceGetCount(&count) != NVML_SUCCESS) {
         goto fail;
     }
     nvml->deviceCount = count;
@@ -416,7 +426,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
     for (i = 0; i < count; i++) {
         int devIdx = nvctrlToNvmlId[i];
         nvmlDevice_t device;
-        nvmlReturn_t ret = nvml->lib.deviceGetHandleByIndex(devIdx, &device);
+        nvmlReturn_t ret = nvml->lib.DeviceGetHandleByIndex(devIdx, &device);
         if (ret == NVML_SUCCESS) {
             unsigned int temp;
             unsigned int fans;
@@ -426,7 +436,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
              *     check for nvmlDeviceGetTemperature() success to figure
              *     out if that sensor is available.
              */
-            ret = nvml->lib.deviceGetTemperature(device, NVML_TEMPERATURE_GPU,
+            ret = nvml->lib.DeviceGetTemperature(device, NVML_TEMPERATURE_GPU,
                                                  &temp);
             if (ret == NVML_SUCCESS) {
                 if ((h->target_type == THERMAL_SENSOR_TARGET) &&
@@ -435,11 +445,11 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
                     nvml->deviceIdx = devIdx;
                 }
 
-                nvml->sensorCountPerGPU[i] = 1;
+                nvml->sensorCountPerGPU[devIdx] = 1;
                 nvml->sensorCount++;
             }
 
-            ret = nvml->lib.deviceGetNumFans(device, &fans);
+            ret = nvml->lib.DeviceGetNumFans(device, &fans);
             if (ret == NVML_SUCCESS) {
                 if ((h->target_type == COOLER_TARGET) &&
                     (h->target_id == nvml->coolerCount)) {
@@ -447,7 +457,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
                     nvml->deviceIdx = devIdx;
                 }
 
-                nvml->coolerCountPerGPU[i] = fans;
+                nvml->coolerCountPerGPU[devIdx] = fans;
                 nvml->coolerCount += fans;
             }
         }
@@ -558,11 +568,11 @@ static ReturnStatus NvCtrlNvmlGetGeneralStringAttribute(const CtrlTarget *ctrl_t
 
     switch (attr) {
         case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
-            ret = h->nvml->lib.systemGetDriverVersion(res, MAX_NVML_STR_LEN);
+            ret = h->nvml->lib.SystemGetDriverVersion(res, MAX_NVML_STR_LEN);
             break;
 
         case NV_CTRL_STRING_NVML_VERSION:
-            ret = h->nvml->lib.systemGetNVMLVersion(res, MAX_NVML_STR_LEN);
+            ret = h->nvml->lib.SystemGetNVMLVersion(res, MAX_NVML_STR_LEN);
             break;
 
         default:
@@ -601,19 +611,19 @@ static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_targe
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_STRING_PRODUCT_NAME:
-                ret = nvml->lib.deviceGetName(device, res, MAX_NVML_STR_LEN);
+                ret = nvml->lib.DeviceGetName(device, res, MAX_NVML_STR_LEN);
                 break;
 
             case NV_CTRL_STRING_VBIOS_VERSION:
-                ret = nvml->lib.deviceGetVbiosVersion(device, res, MAX_NVML_STR_LEN);
+                ret = nvml->lib.DeviceGetVbiosVersion(device, res, MAX_NVML_STR_LEN);
                 break;
 
             case NV_CTRL_STRING_GPU_UUID:
-                ret = nvml->lib.deviceGetUUID(device, res, MAX_NVML_STR_LEN);
+                ret = nvml->lib.DeviceGetUUID(device, res, MAX_NVML_STR_LEN);
                 break;
 
             case NV_CTRL_STRING_GPU_UTILIZATION:
@@ -628,7 +638,7 @@ static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_targe
                     return NvCtrlNotSupported;
                 }
 
-                ret = nvml->lib.deviceGetUtilizationRates(device, &util);
+                ret = nvml->lib.DeviceGetUtilizationRates(device, &util);
 
                 if (ret != NVML_SUCCESS) {
                     break;
@@ -734,7 +744,7 @@ static ReturnStatus NvCtrlNvmlSetGPUStringAttribute(CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS:
@@ -822,16 +832,16 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
             case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
                 {
-                    if (nvml->lib.deviceGetMemoryInfo_v2) {
+                    if (nvml->lib.DeviceGetMemoryInfo_v2) {
                         nvmlMemory_v2_t memory;
                         memory.version = nvmlMemory_v2;
-                        ret = nvml->lib.deviceGetMemoryInfo_v2(device, &memory);
+                        ret = nvml->lib.DeviceGetMemoryInfo_v2(device, &memory);
                         if (ret == NVML_SUCCESS) {
                             switch (attr) {
                                 case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
@@ -844,7 +854,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
                         }
                     } else {
                         nvmlMemory_t memory;
-                        ret = nvml->lib.deviceGetMemoryInfo(device, &memory);
+                        ret = nvml->lib.DeviceGetMemoryInfo(device, &memory);
                         if (ret == NVML_SUCCESS) {
                             switch (attr) {
                                 case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
@@ -866,7 +876,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
             case NV_CTRL_PCI_ID:
                 {
                     nvmlPciInfo_t pci;
-                    ret = nvml->lib.deviceGetPciInfo(device, &pci);
+                    ret = nvml->lib.DeviceGetPciInfo(device, &pci);
                     if (ret == NVML_SUCCESS) {
                         switch (attr) {
                             case NV_CTRL_PCI_DOMAIN:
@@ -899,25 +909,25 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
                 break;
 
             case NV_CTRL_GPU_PCIE_GENERATION:
-                ret = nvml->lib.deviceGetMaxPcieLinkGeneration(device, &res);
+                ret = nvml->lib.DeviceGetMaxPcieLinkGeneration(device, &res);
                 break;
 
             case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH:
-                ret = nvml->lib.deviceGetCurrPcieLinkWidth(device, &res);
+                ret = nvml->lib.DeviceGetCurrPcieLinkWidth(device, &res);
                 break;
             case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
-                ret = nvml->lib.deviceGetMaxPcieLinkWidth(device, &res);
+                ret = nvml->lib.DeviceGetMaxPcieLinkWidth(device, &res);
                 break;
             case NV_CTRL_GPU_SLOWDOWN_THRESHOLD:
-                ret = nvml->lib.deviceGetTemperatureThreshold(device,
+                ret = nvml->lib.DeviceGetTemperatureThreshold(device,
                           NVML_TEMPERATURE_THRESHOLD_SLOWDOWN ,&res);
                 break;
             case NV_CTRL_GPU_SHUTDOWN_THRESHOLD:
-                ret = nvml->lib.deviceGetTemperatureThreshold(device,
+                ret = nvml->lib.DeviceGetTemperatureThreshold(device,
                           NVML_TEMPERATURE_THRESHOLD_SHUTDOWN ,&res);
                 break;
             case NV_CTRL_GPU_CORE_TEMPERATURE:
-                ret = nvml->lib.deviceGetTemperature(device,
+                ret = nvml->lib.DeviceGetTemperature(device,
                                                      NVML_TEMPERATURE_GPU,
                                                      &res);
                 break;
@@ -926,7 +936,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
             case NV_CTRL_GPU_ECC_SUPPORTED:
                 {
                     nvmlEnableState_t current, pending;
-                    ret = nvml->lib.deviceGetEccMode(device, &current, &pending);
+                    ret = nvml->lib.DeviceGetEccMode(device, &current, &pending);
                     switch (attr) {
                         case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
                             res = (ret == NVML_SUCCESS) ?
@@ -951,7 +961,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
             case NV_CTRL_GPU_ECC_STATUS:
                 {
                     nvmlEnableState_t current, pending;
-                    ret = nvml->lib.deviceGetEccMode(device, &current, &pending);
+                    ret = nvml->lib.DeviceGetEccMode(device, &current, &pending);
                     if (ret == NVML_SUCCESS) {
                         switch (attr) {
                             case NV_CTRL_GPU_ECC_STATUS:
@@ -968,7 +978,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
             case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION:
                 {
                     nvmlEnableState_t defaultMode;
-                    ret = nvml->lib.deviceGetDefaultEccMode(device, &defaultMode);
+                    ret = nvml->lib.DeviceGetDefaultEccMode(device, &defaultMode);
                     if (ret == NVML_SUCCESS) {
                         res = defaultMode;
                     }
@@ -1002,7 +1012,7 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
                             break;
                     }
 
-                    ret = nvml->lib.deviceGetTotalEccErrors(device, errorType,
+                    ret = nvml->lib.DeviceGetTotalEccErrors(device, errorType,
                                                         counterType, &eccCounts);
                     if (ret == NVML_SUCCESS) {
                         if (val) {
@@ -1014,30 +1024,48 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
                 break;
 
             case NV_CTRL_GPU_CORES:
-                ret = nvml->lib.deviceGetNumGpuCores(device, &res);
+                ret = nvml->lib.DeviceGetNumGpuCores(device, &res);
                 break;
             case NV_CTRL_GPU_MEMORY_BUS_WIDTH:
-                ret = nvml->lib.deviceGetMemoryBusWidth(device, &res);
+                ret = nvml->lib.DeviceGetMemoryBusWidth(device, &res);
                 break;
             case NV_CTRL_IRQ:
-                ret = nvml->lib.deviceGetIrqNum(device, &res);
+                ret = nvml->lib.DeviceGetIrqNum(device, &res);
                 break;
             case NV_CTRL_GPU_POWER_SOURCE:
                 assert(NV_CTRL_GPU_POWER_SOURCE_AC == NVML_POWER_SOURCE_AC);
                 assert(NV_CTRL_GPU_POWER_SOURCE_BATTERY == NVML_POWER_SOURCE_BATTERY);
-                ret = nvml->lib.deviceGetPowerSource(device, &res);
+                assert(NV_CTRL_GPU_POWER_SOURCE_UNDERSIZED == NVML_POWER_SOURCE_UNDERSIZED);
+                ret = nvml->lib.DeviceGetPowerSource(device, &res);
                 break;
+            case NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE:
+                ret = nvml->lib.DeviceGetPowerUsage(device, &res);
+                break;
+
+            case NV_CTRL_ATTR_NVML_GPU_MAX_TGP:
+                {
+                    unsigned int minLimit;
+                    ret = nvml->lib.DeviceGetPowerManagementLimitConstraints(device,
+                                                                             &minLimit, &res);
+                }
+                break;
+
+            case NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP:
+                ret = nvml->lib.DeviceGetPowerManagementDefaultLimit(device, &res);
+                break;
+
             case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
                 {
                     nvmlFanControlPolicy_t policy;
+                    int count = nvml->coolerCountPerGPU[nvml->deviceIdx];
 
                     /* Return early if GPU has no fan */
-                    if (nvml->coolerCount == 0) {
+                    if (count == 0) {
                         return NvCtrlNotSupported;
                     }
 
                     /* Get cooler control policy */
-                    ret = nvml->lib.deviceGetFanControlPolicy_v2(device, 0, &policy);
+                    ret = nvml->lib.DeviceGetFanControlPolicy_v2(device, 0, &policy);
                     res = (policy == NVML_FAN_POLICY_MANUAL) ?
                         NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE :
                         NV_CTRL_GPU_COOLER_MANUAL_CONTROL_FALSE;
@@ -1094,20 +1122,17 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
             case NV_CTRL_ATTR_NVML_GPU_VIRTUALIZATION_MODE:
                 {
                     nvmlGpuVirtualizationMode_t mode;
-                    ret = nvml->lib.deviceGetVirtualizationMode(device, &mode);
+                    ret = nvml->lib.DeviceGetVirtualizationMode(device, &mode);
                     res = mode;
                 }
                 break;
 
             case NV_CTRL_ATTR_NVML_GPU_GRID_LICENSE_SUPPORTED:
-                if (nvml->lib.deviceGetGridLicensableFeatures) {
+                {
                     nvmlGridLicensableFeatures_t gridLicensableFeatures;
-                    ret = nvml->lib.deviceGetGridLicensableFeatures(device,
+                    ret = nvml->lib.DeviceGetGridLicensableFeatures(device,
                                                           &gridLicensableFeatures);
                     res = !!(gridLicensableFeatures.isGridLicenseSupported);
-                } else {
-                    /* return NvCtrlNotSupported against older driver */
-                    ret = NVML_ERROR_FUNCTION_NOT_FOUND;
                 }
 
                 break;
@@ -1146,22 +1171,19 @@ static ReturnStatus NvCtrlNvmlGetGridLicensableFeatures(const CtrlTarget *ctrl_t
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
         if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_ATTR_NVML_GPU_GRID_LICENSABLE_FEATURES:
-                if (nvml->lib.deviceGetGridLicensableFeatures) {
+                {
                     nvmlGridLicensableFeatures_t *gridLicensableFeatures;
                     gridLicensableFeatures = (nvmlGridLicensableFeatures_t *)nvalloc(sizeof(nvmlGridLicensableFeatures_t));
-                    ret = nvml->lib.deviceGetGridLicensableFeatures(device,
+                    ret = nvml->lib.DeviceGetGridLicensableFeatures(device,
                                                                     gridLicensableFeatures);
                     if (ret == NVML_SUCCESS) {
                         *val = gridLicensableFeatures;
                         return NvCtrlSuccess;
                     }
-                } else {
-                    /* return NvCtrlNotSupported against older driver */
-                    ret = NVML_ERROR_FUNCTION_NOT_FOUND;
                 }
 
                 break;
@@ -1193,23 +1215,20 @@ static ReturnStatus NvCtrlNvmlDeviceGetGspFeatures(const CtrlTarget *ctrl_target
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
     switch (attr) {
         case NV_CTRL_ATTR_NVML_GSP_FIRMWARE_MODE:
-            if (nvml->lib.deviceGetGspFirmwareMode) {
+            {
                 unsigned int isEnabled_t = 0;
                 unsigned int defaultMode_t = 0;
-                ret = nvml->lib.deviceGetGspFirmwareMode(device,
+                ret = nvml->lib.DeviceGetGspFirmwareMode(device,
                                                          &isEnabled_t, &defaultMode_t);
                 if (ret == NVML_SUCCESS) {
                     *isEnabled = isEnabled_t;
                     *defaultMode = defaultMode_t;
                     return NvCtrlSuccess;
                 }
-            } else {
-                /* return NvCtrlNotSupported against older driver */
-                ret = NVML_ERROR_FUNCTION_NOT_FOUND;
             }
 
             break;
@@ -1278,7 +1297,7 @@ static ReturnStatus NvCtrlNvmlGetThermalAttribute(const CtrlTarget *ctrl_target,
     }
 
 
-    ret = nvml->lib.deviceGetHandleByIndex(deviceId, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(deviceId, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_THERMAL_SENSOR_READING:
@@ -1332,14 +1351,14 @@ static ReturnStatus NvCtrlNvmlGetCoolerAttribute(const CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(deviceId, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(deviceId, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_THERMAL_COOLER_LEVEL:
-                ret = nvml->lib.deviceGetTargetFanSpeed(device, coolerId, &res);
+                ret = nvml->lib.DeviceGetTargetFanSpeed(device, coolerId, &res);
                 break;
             case NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL:
-                ret = nvml->lib.deviceGetFanSpeed_v2(device, coolerId, &res);
+                ret = nvml->lib.DeviceGetFanSpeed_v2(device, coolerId, &res);
                 break;
 
             case NV_CTRL_THERMAL_COOLER_SPEED:
@@ -1464,11 +1483,11 @@ static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_GPU_ECC_CONFIGURATION:
-                ret = nvml->lib.deviceSetEccMode(device, val);
+                ret = nvml->lib.DeviceSetEccMode(device, val);
                 break;
 
             case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS:
@@ -1482,7 +1501,7 @@ static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
                             counterType = NVML_AGGREGATE_ECC;
                             break;
                     }
-                    ret = nvml->lib.deviceClearEccErrorCounts(device,
+                    ret = nvml->lib.DeviceClearEccErrorCounts(device,
                                                               counterType);
                 }
                 break;
@@ -1493,7 +1512,7 @@ static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
                     int count = nvml->coolerCountPerGPU[nvml->deviceIdx];
 
                     for (i = 0; i < count; i++) {
-                        ret = nvml->lib.deviceSetFanControlPolicy(device, i, val);
+                        ret = nvml->lib.DeviceSetFanControlPolicy(device, i, val);
                     }
                 }
                 break;
@@ -1552,15 +1571,15 @@ static ReturnStatus NvCtrlNvmlSetCoolerAttribute(CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(deviceId, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(deviceId, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_THERMAL_COOLER_LEVEL:
-                ret = nvml->lib.deviceSetFanSpeed_v2(device, coolerId, val);
+                ret = nvml->lib.DeviceSetFanSpeed_v2(device, coolerId, val);
                 break;
 
             case NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT:
-                ret = nvml->lib.deviceSetDefaultFanSpeed_v2(device, coolerId);
+                ret = nvml->lib.DeviceSetDefaultFanSpeed_v2(device, coolerId);
                 break;
 
             default:
@@ -1633,7 +1652,7 @@ static nvmlReturn_t getDeviceMemoryCounts(const CtrlTarget *ctrl_target,
          i < NVML_MEMORY_LOCATION_COUNT;
          i++) {
 
-        ret = nvml->lib.deviceGetMemoryErrorCounter(device, errorType,
+        ret = nvml->lib.DeviceGetMemoryErrorCounter(device, errorType,
                                                     counterType, i, &count);
         if (ret == NVML_SUCCESS) {
             anySuccess = NVML_SUCCESS;
@@ -1669,7 +1688,7 @@ NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target,
         return NvCtrlBadHandle;
     }
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU:
@@ -1679,7 +1698,7 @@ NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target,
                 int offset = 0;
                 int i = 0;
 
-                ret = nvml->lib.deviceGetNumFans(device, &count);
+                ret = nvml->lib.DeviceGetNumFans(device, &count);
                 if (ret != NVML_SUCCESS) {
                     return NvCtrlNotSupported;
                 }
@@ -1948,7 +1967,7 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
 
     val->permissions.write = NV_FALSE;
 
-    ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(nvml->deviceIdx, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
@@ -1968,6 +1987,9 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
             case NV_CTRL_GPU_CORES:
             case NV_CTRL_IRQ:
             case NV_CTRL_GPU_POWER_SOURCE:
+            case NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE:
+            case NV_CTRL_ATTR_NVML_GPU_MAX_TGP:
+            case NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP:
                 val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_INTEGER;
                 break;
 
@@ -2080,7 +2102,7 @@ NvCtrlNvmlGetThermalValidAttributeValues(const CtrlTarget *ctrl_target,
     }
 
 
-    ret = nvml->lib.deviceGetHandleByIndex(deviceId, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(deviceId, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_THERMAL_SENSOR_READING:
@@ -2132,7 +2154,7 @@ NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target,
     }
 
 
-    ret = nvml->lib.deviceGetHandleByIndex(deviceId, &device);
+    ret = nvml->lib.DeviceGetHandleByIndex(deviceId, &device);
     if (ret == NVML_SUCCESS) {
         switch (attr) {
             case NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL:
@@ -2143,7 +2165,7 @@ NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target,
                 return NvCtrlSuccess;
 
             case NV_CTRL_THERMAL_COOLER_LEVEL:
-                ret = nvml->lib.deviceGetMinMaxFanSpeed(device, &minSpeed, &maxSpeed);
+                ret = nvml->lib.DeviceGetMinMaxFanSpeed(device, &minSpeed, &maxSpeed);
                 if (ret == NVML_SUCCESS) {
                     /* Range as a percent */
                     val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_RANGE;
@@ -2268,6 +2290,9 @@ static ReturnStatus NvCtrlNvmlGetIntegerAttributePerms(int attr,
         case NV_CTRL_GPU_CORES:
         case NV_CTRL_IRQ:
         case NV_CTRL_GPU_POWER_SOURCE:
+        case NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE:
+        case NV_CTRL_ATTR_NVML_GPU_MAX_TGP:
+        case NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP:
         case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
         /* CTRL_ATTRIBUTE_VALID_TYPE_BOOL */
         case NV_CTRL_GPU_ECC_SUPPORTED:
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
index 3395950f9c391b3015ce55b98b77f06eeff7518e..962c522f4d7d7a2db6139ec7971e75ff98069b6a 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
@@ -164,45 +164,48 @@ struct __NvCtrlNvmlAttributes {
     struct {
         void *handle;
 
-        typeof(nvmlInit)                                (*init);
-        typeof(nvmlShutdown)                            (*shutdown);
-        typeof(nvmlDeviceGetHandleByIndex)              (*deviceGetHandleByIndex);
-        typeof(nvmlDeviceGetUUID)                       (*deviceGetUUID);
-        typeof(nvmlDeviceGetCount)                      (*deviceGetCount);
-        typeof(nvmlDeviceGetTemperature)                (*deviceGetTemperature);
-        typeof(nvmlDeviceGetName)                       (*deviceGetName);
-        typeof(nvmlDeviceGetVbiosVersion)               (*deviceGetVbiosVersion);
-        typeof(nvmlDeviceGetMemoryInfo)                 (*deviceGetMemoryInfo);
-        typeof(nvmlDeviceGetMemoryInfo_v2)              (*deviceGetMemoryInfo_v2);
-        typeof(nvmlDeviceGetPciInfo)                    (*deviceGetPciInfo);
-        typeof(nvmlDeviceGetCurrPcieLinkWidth)          (*deviceGetCurrPcieLinkWidth);
-        typeof(nvmlDeviceGetMaxPcieLinkGeneration)      (*deviceGetMaxPcieLinkGeneration);
-        typeof(nvmlDeviceGetMaxPcieLinkWidth)           (*deviceGetMaxPcieLinkWidth);
-        typeof(nvmlDeviceGetVirtualizationMode)         (*deviceGetVirtualizationMode);
-        typeof(nvmlDeviceGetGridLicensableFeatures_v4)  (*deviceGetGridLicensableFeatures);
-        typeof(nvmlDeviceGetGspFirmwareMode)            (*deviceGetGspFirmwareMode);
-        typeof(nvmlDeviceGetUtilizationRates)           (*deviceGetUtilizationRates);
-        typeof(nvmlDeviceGetTemperatureThreshold)       (*deviceGetTemperatureThreshold);
-        typeof(nvmlDeviceGetFanSpeed_v2)                (*deviceGetFanSpeed_v2);
-        typeof(nvmlSystemGetDriverVersion)              (*systemGetDriverVersion);
-        typeof(nvmlDeviceGetEccMode)                    (*deviceGetEccMode);
-        typeof(nvmlDeviceGetDefaultEccMode)             (*deviceGetDefaultEccMode);
-        typeof(nvmlDeviceSetEccMode)                    (*deviceSetEccMode);
-        typeof(nvmlDeviceGetTotalEccErrors)             (*deviceGetTotalEccErrors);
-        typeof(nvmlDeviceClearEccErrorCounts)           (*deviceClearEccErrorCounts);
-        typeof(nvmlDeviceGetMemoryErrorCounter)         (*deviceGetMemoryErrorCounter);
-        typeof(nvmlSystemGetNVMLVersion)                (*systemGetNVMLVersion);
-        typeof(nvmlDeviceGetNumGpuCores)                (*deviceGetNumGpuCores);
-        typeof(nvmlDeviceGetMemoryBusWidth)             (*deviceGetMemoryBusWidth);
-        typeof(nvmlDeviceGetIrqNum)                     (*deviceGetIrqNum);
-        typeof(nvmlDeviceGetPowerSource)                (*deviceGetPowerSource);
-        typeof(nvmlDeviceGetNumFans)                    (*deviceGetNumFans);
-        typeof(nvmlDeviceSetFanSpeed_v2)                (*deviceSetFanSpeed_v2);
-        typeof(nvmlDeviceGetTargetFanSpeed)             (*deviceGetTargetFanSpeed);
-        typeof(nvmlDeviceGetMinMaxFanSpeed)             (*deviceGetMinMaxFanSpeed);
-        typeof(nvmlDeviceSetFanControlPolicy)           (*deviceSetFanControlPolicy);
-        typeof(nvmlDeviceGetFanControlPolicy_v2)        (*deviceGetFanControlPolicy_v2);
-        typeof(nvmlDeviceSetDefaultFanSpeed_v2)         (*deviceSetDefaultFanSpeed_v2);
+        typeof(nvmlInit)                                (*Init);
+        typeof(nvmlShutdown)                            (*Shutdown);
+        typeof(nvmlDeviceGetHandleByIndex)              (*DeviceGetHandleByIndex);
+        typeof(nvmlDeviceGetUUID)                       (*DeviceGetUUID);
+        typeof(nvmlDeviceGetCount)                      (*DeviceGetCount);
+        typeof(nvmlDeviceGetTemperature)                (*DeviceGetTemperature);
+        typeof(nvmlDeviceGetName)                       (*DeviceGetName);
+        typeof(nvmlDeviceGetVbiosVersion)               (*DeviceGetVbiosVersion);
+        typeof(nvmlDeviceGetMemoryInfo)                 (*DeviceGetMemoryInfo);
+        typeof(nvmlDeviceGetMemoryInfo_v2)              (*DeviceGetMemoryInfo_v2);
+        typeof(nvmlDeviceGetPciInfo)                    (*DeviceGetPciInfo);
+        typeof(nvmlDeviceGetCurrPcieLinkWidth)          (*DeviceGetCurrPcieLinkWidth);
+        typeof(nvmlDeviceGetMaxPcieLinkGeneration)      (*DeviceGetMaxPcieLinkGeneration);
+        typeof(nvmlDeviceGetMaxPcieLinkWidth)           (*DeviceGetMaxPcieLinkWidth);
+        typeof(nvmlDeviceGetVirtualizationMode)         (*DeviceGetVirtualizationMode);
+        typeof(nvmlDeviceGetGridLicensableFeatures)     (*DeviceGetGridLicensableFeatures);
+        typeof(nvmlDeviceGetGspFirmwareMode)            (*DeviceGetGspFirmwareMode);
+        typeof(nvmlDeviceGetUtilizationRates)           (*DeviceGetUtilizationRates);
+        typeof(nvmlDeviceGetTemperatureThreshold)       (*DeviceGetTemperatureThreshold);
+        typeof(nvmlDeviceGetFanSpeed_v2)                (*DeviceGetFanSpeed_v2);
+        typeof(nvmlSystemGetDriverVersion)              (*SystemGetDriverVersion);
+        typeof(nvmlDeviceGetEccMode)                    (*DeviceGetEccMode);
+        typeof(nvmlDeviceGetDefaultEccMode)             (*DeviceGetDefaultEccMode);
+        typeof(nvmlDeviceSetEccMode)                    (*DeviceSetEccMode);
+        typeof(nvmlDeviceGetTotalEccErrors)             (*DeviceGetTotalEccErrors);
+        typeof(nvmlDeviceClearEccErrorCounts)           (*DeviceClearEccErrorCounts);
+        typeof(nvmlDeviceGetMemoryErrorCounter)         (*DeviceGetMemoryErrorCounter);
+        typeof(nvmlSystemGetNVMLVersion)                (*SystemGetNVMLVersion);
+        typeof(nvmlDeviceGetNumGpuCores)                (*DeviceGetNumGpuCores);
+        typeof(nvmlDeviceGetMemoryBusWidth)             (*DeviceGetMemoryBusWidth);
+        typeof(nvmlDeviceGetIrqNum)                     (*DeviceGetIrqNum);
+        typeof(nvmlDeviceGetPowerSource)                (*DeviceGetPowerSource);
+        typeof(nvmlDeviceGetNumFans)                    (*DeviceGetNumFans);
+        typeof(nvmlDeviceSetFanSpeed_v2)                (*DeviceSetFanSpeed_v2);
+        typeof(nvmlDeviceGetTargetFanSpeed)             (*DeviceGetTargetFanSpeed);
+        typeof(nvmlDeviceGetMinMaxFanSpeed)             (*DeviceGetMinMaxFanSpeed);
+        typeof(nvmlDeviceSetFanControlPolicy)           (*DeviceSetFanControlPolicy);
+        typeof(nvmlDeviceGetFanControlPolicy_v2)        (*DeviceGetFanControlPolicy_v2);
+        typeof(nvmlDeviceSetDefaultFanSpeed_v2)         (*DeviceSetDefaultFanSpeed_v2);
+        typeof(nvmlDeviceGetPowerUsage)                 (*DeviceGetPowerUsage);
+        typeof(nvmlDeviceGetPowerManagementDefaultLimit)     (*DeviceGetPowerManagementDefaultLimit);
+        typeof(nvmlDeviceGetPowerManagementLimitConstraints) (*DeviceGetPowerManagementLimitConstraints);
 
     } lib;
 
diff --git a/src/nv_grid_dbus.h b/src/nv_grid_dbus.h
index d5b6b482a93089eb5311cd4b89e2f9cfb50fa562..52202f9fafbc2ba89f5bfd2dcdaaf1694df984bc 100644
--- a/src/nv_grid_dbus.h
+++ b/src/nv_grid_dbus.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017-2019 NVIDIA Corporation.
+ * Copyright (C) 2017-2023 NVIDIA Corporation.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -31,6 +31,10 @@
 #define LICENSE_STATE_REQUEST           1
 #define LICENSE_DETAILS_UPDATE_REQUEST  2
 #define LICENSE_FEATURE_TYPE_REQUEST    3
+#define LICENSE_SERVER_PORT_REQUEST     4
+#define PRIMARY_SERVER_ADDRESS          "PrimaryServerAddress"
+#define SECONDARY_SERVER_ADDRESS        "SecondaryServerAddress"
+#define SERVER_DETAILS_NOT_CONFIGURED   "Not Configured"
 
 /*
  * vGPU software license states
diff --git a/src/nvml.h b/src/nvml.h
index 9ac2324180ae72e0215147d376c7dd5cecb7fe2b..de9ddaeee262f5ebb397a46b0027297cccf3bdb4 100644
--- a/src/nvml.h
+++ b/src/nvml.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 1993-2023 NVIDIA Corporation.  All rights reserved.
+ * Copyright 1993-2024 NVIDIA Corporation.  All rights reserved.
  *
  * NOTICE TO USER:
  *
@@ -275,23 +275,41 @@ typedef struct nvmlProcessInfo_v2_st
                                             //  0xFFFFFFFF otherwise.
     unsigned int        computeInstanceId;  //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId is set to
                                             //  0xFFFFFFFF otherwise.
-} nvmlProcessInfo_v2_t;
+} nvmlProcessInfo_v2_t, nvmlProcessInfo_t;
 
 /**
- * Information about running compute processes on the GPU
- * Version 2 adds versioning for the struct
+ * Information about running process on the GPU with protected memory
  */
-typedef struct nvmlProcessInfo_st
+typedef struct
 {
-    unsigned int        pid;                //!< Process ID
-    unsigned long long  usedGpuMemory;      //!< Amount of used GPU memory in bytes.
-                                            //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported
-                                            //! because Windows KMD manages all the memory and not the NVIDIA driver
-    unsigned int        gpuInstanceId;      //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is set to
-                                            //  0xFFFFFFFF otherwise.
-    unsigned int        computeInstanceId;  //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId is set to
-                                            //  0xFFFFFFFF otherwise.
-} nvmlProcessInfo_t;
+    unsigned int        pid;                      //!< Process ID
+    unsigned long long  usedGpuMemory;            //!< Amount of used GPU memory in bytes.
+                                                  //! Under WDDM, \ref NVML_VALUE_NOT_AVAILABLE is always reported
+                                                  //! because Windows KMD manages all the memory and not the NVIDIA driver
+    unsigned int        gpuInstanceId;            //!< If MIG is enabled, stores a valid GPU instance ID. gpuInstanceId is
+                                                  //  set to 0xFFFFFFFF otherwise.
+    unsigned int        computeInstanceId;        //!< If MIG is enabled, stores a valid compute instance ID. computeInstanceId
+                                                  //  is set to 0xFFFFFFFF otherwise.
+    unsigned long long  usedGpuCcProtectedMemory; //!< Amount of used GPU conf compute protected memory in bytes.
+} nvmlProcessDetail_v1_t;
+
+/**
+ * Information about all running processes on the GPU for the given mode
+ */
+typedef struct
+{
+    unsigned int           version;             //!< Struct version, MUST be nvmlProcessDetailList_v1
+    unsigned int           mode;                //!< Process mode(Compute/Graphics/MPSCompute)
+    unsigned int           numProcArrayEntries; //!< Number of process entries in procArray
+    nvmlProcessDetail_v1_t *procArray;          //!< Process array
+} nvmlProcessDetailList_v1_t;
+
+typedef nvmlProcessDetailList_v1_t nvmlProcessDetailList_t;
+
+/**
+ * nvmlProcessDetailList version
+ */
+#define nvmlProcessDetailList_v1 NVML_STRUCT_VERSION(ProcessDetailList, 1)
 
 typedef struct nvmlDeviceAttributes_st
 {
@@ -498,6 +516,7 @@ typedef enum nvmlSamplingType_enum
     NVML_DEC_UTILIZATION_SAMPLES    = 4, //!< To represent percent of time during which NVDEC remains busy
     NVML_PROCESSOR_CLK_SAMPLES      = 5, //!< To represent processor clock samples
     NVML_MEMORY_CLK_SAMPLES         = 6, //!< To represent memory clock samples
+    NVML_MODULE_POWER_SAMPLES       = 7, //!< To represent module power samples for total module starting Grace Hopper
 
     // Keep this last
     NVML_SAMPLINGTYPE_COUNT
@@ -538,7 +557,7 @@ typedef enum nvmlValueType_enum
 typedef union nvmlValue_st
 {
     double dVal;                    //!< If the value is double
-    int siVal;                      //!< If the value is signed long long
+    int siVal;                      //!< If the value is signed int
     unsigned int uiVal;             //!< If the value is unsigned int
     unsigned long ulVal;            //!< If the value is unsigned long
     unsigned long long ullVal;      //!< If the value is unsigned long long
@@ -974,7 +993,8 @@ typedef enum nvmlReturn_enum
     NVML_ERROR_INSUFFICIENT_RESOURCES = 23,    //!< Ran out of critical resources, other than memory
     NVML_ERROR_FREQ_NOT_SUPPORTED = 24,        //!< Ran out of critical resources, other than memory
     NVML_ERROR_ARGUMENT_VERSION_MISMATCH = 25, //!< The provided version is invalid/unsupported
-    NVML_ERROR_DEPRECATED  = 26,	           //!< The requested functionality has been deprecated
+    NVML_ERROR_DEPRECATED  = 26,               //!< The requested functionality has been deprecated
+    NVML_ERROR_NOT_READY = 27,                 //!< The system is not ready for the request
     NVML_ERROR_UNKNOWN = 999                   //!< An internal driver error occurred
 } nvmlReturn_t;
 
@@ -1105,7 +1125,6 @@ typedef enum nvmlVgpuCapability_enum
     NVML_VGPU_CAP_COUNT
 } nvmlVgpuCapability_t;
 
-
 /**
 * vGPU driver queryable capabilities
 */
@@ -1116,7 +1135,6 @@ typedef enum nvmlVgpuDriverCapability_enum
     NVML_VGPU_DRIVER_CAP_COUNT
 } nvmlVgpuDriverCapability_t;
 
-
 /**
 * Device vGPU queryable capabilities
 */
@@ -1219,6 +1237,10 @@ typedef struct nvmlVgpuProcessUtilizationSample_st
 
 #define NVML_SCHEDULER_SW_MAX_LOG_ENTRIES 200
 
+#define NVML_VGPU_SCHEDULER_ARR_DEFAULT   0
+#define NVML_VGPU_SCHEDULER_ARR_DISABLE   1
+#define NVML_VGPU_SCHEDULER_ARR_ENABLE    2
+
 /**
  * Union to represent the vGPU Scheduler Parameters
  */
@@ -1257,7 +1279,7 @@ typedef struct nvmlVgpuSchedulerLog_st
 {
     unsigned int                engineId;                                       //!< Engine whose software runlist log entries are fetched
     unsigned int                schedulerPolicy;                                //!< Scheduler policy
-    unsigned int                isEnabledARR;                                   //!< Flag to check Adaptive Round Robin scheduler mode
+    unsigned int                arrMode;                                        //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*.
     nvmlVgpuSchedulerParams_t   schedulerParams;
     unsigned int                entriesCount;                                   //!< Count of log entries fetched
     nvmlVgpuSchedulerLogEntry_t logEntries[NVML_SCHEDULER_SW_MAX_LOG_ENTRIES];
@@ -1269,10 +1291,38 @@ typedef struct nvmlVgpuSchedulerLog_st
 typedef struct nvmlVgpuSchedulerGetState_st
 {
     unsigned int                schedulerPolicy;    //!< Scheduler policy
-    unsigned int                isEnabledARR;       //!< Flag to check Adaptive Round Robin scheduler mode
+    unsigned int                arrMode;            //!< Adaptive Round Robin scheduler mode. One of the NVML_VGPU_SCHEDULER_ARR_*.
     nvmlVgpuSchedulerParams_t   schedulerParams;
 } nvmlVgpuSchedulerGetState_t;
 
+/**
+ * Union to represent the vGPU Scheduler set Parameters
+ */
+typedef union
+{
+    struct
+    {
+        unsigned int    avgFactor;          //!< Average factor in compensating the timeslice for Adaptive Round Robin mode
+        unsigned int    frequency;          //!< Frequency for Adaptive Round Robin mode
+    } vgpuSchedDataWithARR;
+
+    struct
+    {
+        unsigned int    timeslice;          //!< The timeslice in ns(Nanoseconds) for each software run list as configured, or the default value otherwise
+    } vgpuSchedData;
+
+} nvmlVgpuSchedulerSetParams_t;
+
+/**
+ * Structure to set the vGPU scheduler state
+ */
+typedef struct nvmlVgpuSchedulerSetState_st
+{
+    unsigned int                    schedulerPolicy;    //!< Scheduler policy
+    unsigned int                    enableARRMode;      //!< Adaptive Round Robin scheduler
+    nvmlVgpuSchedulerSetParams_t    schedulerParams;
+} nvmlVgpuSchedulerSetState_t;
+
 /**
  * Structure to store the vGPU scheduler capabilities
  */
@@ -1369,6 +1419,29 @@ typedef struct nvmlGridLicensableFeatures_st
     nvmlGridLicensableFeature_t gridLicensableFeatures[NVML_GRID_LICENSE_FEATURE_MAX_COUNT];  //!< Array of vGPU software licensable features.
 } nvmlGridLicensableFeatures_t;
 
+/**
+ * Structure to store SRAM uncorrectable error counters
+ */
+typedef struct
+{
+    unsigned int version;                                   //!< the API version number
+    unsigned long long aggregateUncParity;                  //!< aggregate uncorrectable parity error count
+    unsigned long long aggregateUncSecDed;                  //!< aggregate uncorrectable SEC-DED error count
+    unsigned long long aggregateCor;                        //!< aggregate correctable error count
+    unsigned long long volatileUncParity;                   //!< volatile uncorrectable parity error count
+    unsigned long long volatileUncSecDed;                   //!< volatile uncorrectable SEC-DED error count
+    unsigned long long volatileCor;                         //!< volatile correctable error count
+    unsigned long long aggregateUncBucketL2;                //!< aggregate uncorrectable error count for L2 cache bucket
+    unsigned long long aggregateUncBucketSm;                //!< aggregate uncorrectable error count for SM bucket
+    unsigned long long aggregateUncBucketPcie;              //!< aggregate uncorrectable error count for PCIE bucket
+    unsigned long long aggregateUncBucketMcu;               //!< aggregate uncorrectable error count for Microcontroller bucket
+    unsigned long long aggregateUncBucketOther;             //!< aggregate uncorrectable error count for Other bucket
+    unsigned int bThresholdExceeded;                        //!< if the error threshold of field diag is exceeded
+} nvmlEccSramErrorStatus_v1_t;
+ 
+typedef nvmlEccSramErrorStatus_v1_t nvmlEccSramErrorStatus_t;
+#define nvmlEccSramErrorStatus_v1 NVML_STRUCT_VERSION(EccSramErrorStatus, 1)
+
 /**
  * GSP firmware
  */
@@ -1419,8 +1492,9 @@ typedef unsigned int nvmlFanControlPolicy_t;
 /**
  * Device Power Source
  */
-#define NVML_POWER_SOURCE_AC      0x00000000
-#define NVML_POWER_SOURCE_BATTERY 0x00000001
+#define NVML_POWER_SOURCE_AC         0x00000000
+#define NVML_POWER_SOURCE_BATTERY    0x00000001
+#define NVML_POWER_SOURCE_UNDERSIZED 0x00000002
 
 typedef unsigned int nvmlPowerSource_t;
 
@@ -1732,9 +1806,10 @@ typedef struct nvmlGpuDynamicPstatesInfo_st
 
 #define NVML_FI_DEV_PCIE_L0_TO_RECOVERY_COUNTER       169 //!< Device PEX error recovery counter
 
-/*
- * PCIe error counter
- */
+#define NVML_FI_DEV_C2C_LINK_COUNT                    170 //!< Number of C2C Links present on the device
+#define NVML_FI_DEV_C2C_LINK_GET_STATUS               171 //!< C2C Link Status 0=INACTIVE 1=ACTIVE
+#define NVML_FI_DEV_C2C_LINK_GET_MAX_BW               172 //!< C2C Link Speed in MBps for active links
+
 #define NVML_FI_DEV_PCIE_COUNT_CORRECTABLE_ERRORS     173
 #define NVML_FI_DEV_PCIE_COUNT_NAKS_RECEIVED          174
 #define NVML_FI_DEV_PCIE_COUNT_RECEIVER_ERROR         175
@@ -1744,15 +1819,29 @@ typedef struct nvmlGpuDynamicPstatesInfo_st
 #define NVML_FI_DEV_PCIE_COUNT_NON_FATAL_ERROR        179
 #define NVML_FI_DEV_PCIE_COUNT_FATAL_ERROR            180
 #define NVML_FI_DEV_PCIE_COUNT_UNSUPPORTED_REQ        181
-#define NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR             182 
+#define NVML_FI_DEV_PCIE_COUNT_LCRC_ERROR             182
+#define NVML_FI_DEV_PCIE_COUNT_LANE_ERROR             183
+
+#define NVML_FI_DEV_IS_RESETLESS_MIG_SUPPORTED        184
 
 /**
  * Retrieves power usage for this GPU in milliwatts.
  * It is only available if power management mode is supported. See \ref nvmlDeviceGetPowerManagementMode and
  * \ref nvmlDeviceGetPowerUsage.
+ *
+ * scopeId needs to be specified. It signifies:
+ * 0 - GPU Only Scope - Metrics for GPU are retrieved
+ * 1 - Module scope - Metrics for the module (e.g. CPU + GPU) are retrieved.
+ * Note: CPU here refers to NVIDIA CPU (e.g. Grace). x86 or non-NVIDIA ARM is not supported
  */
 #define NVML_FI_DEV_POWER_AVERAGE                     185 //!< GPU power averaged over 1 sec interval, supported on Ampere (except GA100) or newer architectures.
 #define NVML_FI_DEV_POWER_INSTANT                     186 //!< Current GPU power, supported on all architectures.
+#define NVML_FI_DEV_POWER_MIN_LIMIT                   187 //!< Minimum power limit in milliwatts.
+#define NVML_FI_DEV_POWER_MAX_LIMIT                   188 //!< Maximum power limit in milliwatts.
+#define NVML_FI_DEV_POWER_DEFAULT_LIMIT               189 //!< Default power limit in milliwatts (limit which device boots with).
+#define NVML_FI_DEV_POWER_CURRENT_LIMIT               190 //!< Limit currently enforced in milliwatts (This includes other limits set elsewhere. E.g. Out-of-band).
+#define NVML_FI_DEV_ENERGY                            191 //!< Total energy consumption (in mJ) since the driver was last reloaded. Same as \ref NVML_FI_DEV_TOTAL_ENERGY_CONSUMPTION for the GPU.
+#define NVML_FI_DEV_POWER_REQUESTED_LIMIT             192 //!< Power limit requested by NVML or any other userspace client.
 
 /**
  * GPU T.Limit temperature thresholds in degree Celsius
@@ -1764,7 +1853,7 @@ typedef struct nvmlGpuDynamicPstatesInfo_st
 #define NVML_FI_DEV_TEMPERATURE_MEM_MAX_TLIMIT        195 //!< T.Limit temperature after which GPU may begin SW slowdown due to memory temperature
 #define NVML_FI_DEV_TEMPERATURE_GPU_MAX_TLIMIT        196 //!< T.Limit temperature after which GPU may be throttled below base clock
 
-#define NVML_FI_MAX 197 //!< One greater than the largest field ID defined above
+#define NVML_FI_MAX                                   197 //!< One greater than the largest field ID defined above
 
 /**
  * Information for a Field Value Sample
@@ -1973,7 +2062,7 @@ typedef struct nvmlEventData_st
 /** @} */
 
 /***************************************************************************************************/
-/** @addtogroup nvmlClocksThrottleReasons
+/** @addtogroup nvmlClocksEventReasons
  *  @{
  */
 /***************************************************************************************************/
@@ -1981,28 +2070,28 @@ typedef struct nvmlEventData_st
 /** Nothing is running on the GPU and the clocks are dropping to Idle state
  * \note This limiter may be removed in a later release
  */
-#define nvmlClocksThrottleReasonGpuIdle                   0x0000000000000001LL
+#define nvmlClocksEventReasonGpuIdle                   0x0000000000000001LL
 
 /** GPU clocks are limited by current setting of applications clocks
  *
  * @see nvmlDeviceSetApplicationsClocks
  * @see nvmlDeviceGetApplicationsClock
  */
-#define nvmlClocksThrottleReasonApplicationsClocksSetting 0x0000000000000002LL
+#define nvmlClocksEventReasonApplicationsClocksSetting 0x0000000000000002LL
 
 /**
  * @deprecated Renamed to \ref nvmlClocksThrottleReasonApplicationsClocksSetting
  *             as the name describes the situation more accurately.
  */
-#define nvmlClocksThrottleReasonUserDefinedClocks         nvmlClocksThrottleReasonApplicationsClocksSetting
+#define nvmlClocksThrottleReasonUserDefinedClocks         nvmlClocksEventReasonApplicationsClocksSetting
 
-/** SW Power Scaling algorithm is reducing the clocks below requested clocks
+/** The clocks have been optimized to ensure not to exceed currently set power limits
  *
  * @see nvmlDeviceGetPowerUsage
  * @see nvmlDeviceSetPowerManagementLimit
  * @see nvmlDeviceGetPowerManagementLimit
  */
-#define nvmlClocksThrottleReasonSwPowerCap                0x0000000000000004LL
+#define nvmlClocksEventReasonSwPowerCap                0x0000000000000004LL
 
 /** HW Slowdown (reducing the core clocks by a factor of 2 or more) is engaged
  *
@@ -2028,16 +2117,16 @@ typedef struct nvmlEventData_st
  * holding this one at lower clocks.
  *
  */
-#define nvmlClocksThrottleReasonSyncBoost                 0x0000000000000010LL
+#define nvmlClocksEventReasonSyncBoost                 0x0000000000000010LL
 
 /** SW Thermal Slowdown
  *
- * This is an indicator of one or more of the following:
- *  - Current GPU temperature above the GPU Max Operating Temperature
- *  - Current memory temperature above the Memory Max Operating Temperature
+ * The current clocks have been optimized to ensure the the following is true:
+ *  - Current GPU temperature does not exceed GPU Max Operating Temperature
+ *  - Current memory temperature does not exceeed Memory Max Operating Temperature
  *
  */
-#define nvmlClocksThrottleReasonSwThermalSlowdown         0x0000000000000020LL
+#define nvmlClocksEventReasonSwThermalSlowdown         0x0000000000000020LL
 
 /** HW Thermal Slowdown (reducing the core clocks by a factor of 2 or more) is engaged
  *
@@ -2065,28 +2154,61 @@ typedef struct nvmlEventData_st
  *
  * @see bug 1997531
  */
-#define nvmlClocksThrottleReasonDisplayClockSetting       0x0000000000000100LL
+#define nvmlClocksEventReasonDisplayClockSetting       0x0000000000000100LL
 
 /** Bit mask representing no clocks throttling
  *
  * Clocks are as high as possible.
  * */
-#define nvmlClocksThrottleReasonNone                      0x0000000000000000LL
+#define nvmlClocksEventReasonNone                      0x0000000000000000LL
 
 /** Bit mask representing all supported clocks throttling reasons
  * New reasons might be added to this list in the future
  */
-#define nvmlClocksThrottleReasonAll (nvmlClocksThrottleReasonNone \
-      | nvmlClocksThrottleReasonGpuIdle                           \
-      | nvmlClocksThrottleReasonApplicationsClocksSetting         \
-      | nvmlClocksThrottleReasonSwPowerCap                        \
+#define nvmlClocksEventReasonAll (nvmlClocksThrottleReasonNone \
+      | nvmlClocksEventReasonGpuIdle                           \
+      | nvmlClocksEventReasonApplicationsClocksSetting         \
+      | nvmlClocksEventReasonSwPowerCap                        \
       | nvmlClocksThrottleReasonHwSlowdown                        \
-      | nvmlClocksThrottleReasonSyncBoost                         \
-      | nvmlClocksThrottleReasonSwThermalSlowdown                 \
+      | nvmlClocksEventReasonSyncBoost                         \
+      | nvmlClocksEventReasonSwThermalSlowdown                 \
       | nvmlClocksThrottleReasonHwThermalSlowdown                 \
       | nvmlClocksThrottleReasonHwPowerBrakeSlowdown              \
-      | nvmlClocksThrottleReasonDisplayClockSetting               \
+      | nvmlClocksEventReasonDisplayClockSetting               \
 )
+
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonGpuIdle instead
+ */
+#define nvmlClocksThrottleReasonGpuIdle                      nvmlClocksEventReasonGpuIdle
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonApplicationsClocksSetting instead
+ */
+#define nvmlClocksThrottleReasonApplicationsClocksSetting    nvmlClocksEventReasonApplicationsClocksSetting
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonSyncBoost instead
+ */
+#define nvmlClocksThrottleReasonSyncBoost                    nvmlClocksEventReasonSyncBoost
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonSwPowerCap instead
+ */
+#define nvmlClocksThrottleReasonSwPowerCap                   nvmlClocksEventReasonSwPowerCap
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonSwThermalSlowdown instead
+ */
+#define nvmlClocksThrottleReasonSwThermalSlowdown            nvmlClocksEventReasonSwThermalSlowdown
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonDisplayClockSetting instead
+ */
+#define nvmlClocksThrottleReasonDisplayClockSetting          nvmlClocksEventReasonDisplayClockSetting
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonNone instead
+ */
+#define nvmlClocksThrottleReasonNone                         nvmlClocksEventReasonNone
+/**
+ * @deprecated Use \ref nvmlClocksEventReasonAll instead
+ */
+#define nvmlClocksThrottleReasonAll                          nvmlClocksEventReasonAll
 /** @} */
 
 /***************************************************************************************************/
@@ -2142,8 +2264,10 @@ typedef struct nvmlAccountingStats_st {
  */
 typedef enum nvmlEncoderQueryType_enum
 {
-    NVML_ENCODER_QUERY_H264 = 0,        //!< H264 encoder
-    NVML_ENCODER_QUERY_HEVC = 1         //!< HEVC encoder
+    NVML_ENCODER_QUERY_H264     = 0x00,        //!< H264 encoder
+    NVML_ENCODER_QUERY_HEVC     = 0x01,        //!< HEVC encoder
+    NVML_ENCODER_QUERY_AV1      = 0x02,        //!< AV1 encoder
+    NVML_ENCODER_QUERY_UNKNOWN  = 0xFF         //!< Unknown encoder
 }nvmlEncoderType_t;
 
 /**
@@ -2244,6 +2368,103 @@ typedef enum nvmlPcieLinkState_enum
 
 /** @} */
 
+/***************************************************************************************************/
+/** @defgroup nvmlSystem/nvmlDevice definitions related to Confidential Computing
+ *  @{
+ */
+/***************************************************************************************************/
+/**
+ * Confidential Compute CPU Capabilities values
+ */
+#define NVML_CC_SYSTEM_CPU_CAPS_NONE      0
+#define NVML_CC_SYSTEM_CPU_CAPS_AMD_SEV   1
+#define NVML_CC_SYSTEM_CPU_CAPS_INTEL_TDX 2
+
+/**
+ * Confidenial Compute GPU Capabilities values
+ */
+#define NVML_CC_SYSTEM_GPUS_CC_NOT_CAPABLE 0
+#define NVML_CC_SYSTEM_GPUS_CC_CAPABLE     1
+
+typedef struct nvmlConfComputeSystemCaps_st {
+    unsigned int cpuCaps;
+    unsigned int gpusCaps;
+} nvmlConfComputeSystemCaps_t;
+
+/**
+ * Confidential Compute DevTools Mode values
+ */
+#define NVML_CC_SYSTEM_DEVTOOLS_MODE_OFF 0
+#define NVML_CC_SYSTEM_DEVTOOLS_MODE_ON  1
+
+/**
+ * Confidential Compute Environment values
+ */
+#define NVML_CC_SYSTEM_ENVIRONMENT_UNAVAILABLE 0
+#define NVML_CC_SYSTEM_ENVIRONMENT_SIM         1
+#define NVML_CC_SYSTEM_ENVIRONMENT_PROD        2
+
+/**
+ * Confidential Compute Feature Status values
+ */
+#define NVML_CC_SYSTEM_FEATURE_DISABLED 0
+#define NVML_CC_SYSTEM_FEATURE_ENABLED  1
+
+typedef struct nvmlConfComputeSystemState_st {
+    unsigned int environment;
+    unsigned int ccFeature;
+    unsigned int devToolsMode;
+} nvmlConfComputeSystemState_t;
+
+/**
+ * Protected memory size
+ */
+typedef struct
+nvmlConfComputeMemSizeInfo_st
+{
+    unsigned long long protectedMemSizeKib;
+    unsigned long long unprotectedMemSizeKib;
+} nvmlConfComputeMemSizeInfo_t;
+
+/**
+ * Confidential Compute GPUs/System Ready State values
+ */
+#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE 0
+#define NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE  1
+
+/**
+ * GPU Certificate Details
+ */
+#define NVML_GPU_CERT_CHAIN_SIZE 0x1000
+#define NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE 0x1400
+
+typedef struct nvmlConfComputeGpuCertificate_st {
+    unsigned int certChainSize;
+    unsigned int attestationCertChainSize;
+    unsigned char certChain[NVML_GPU_CERT_CHAIN_SIZE];
+    unsigned char attestationCertChain[NVML_GPU_ATTESTATION_CERT_CHAIN_SIZE];
+} nvmlConfComputeGpuCertificate_t;
+
+/**
+ * GPU Attestation Report
+ */
+#define NVML_CC_GPU_CEC_NONCE_SIZE 0x20
+#define NVML_CC_GPU_ATTESTATION_REPORT_SIZE 0x2000
+#define NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE 0x1000
+#define NVML_CC_CEC_ATTESTATION_REPORT_NOT_PRESENT 0
+#define NVML_CC_CEC_ATTESTATION_REPORT_PRESENT 1
+
+typedef struct nvmlConfComputeGpuAttestationReport_st {
+    unsigned int isCecAttestationReportPresent;
+    unsigned int attestationReportSize;
+    unsigned int cecAttestationReportSize;
+    unsigned char nonce[NVML_CC_GPU_CEC_NONCE_SIZE];
+    unsigned char attestationReport[NVML_CC_GPU_ATTESTATION_REPORT_SIZE];
+    unsigned char cecAttestationReport[NVML_CC_GPU_CEC_ATTESTATION_REPORT_SIZE];
+} nvmlConfComputeGpuAttestationReport_t;
+
+/** @} */
+
 #define NVML_GPU_FABRIC_UUID_LEN 16
 
 #define NVML_GPU_FABRIC_STATE_NOT_SUPPORTED 0
@@ -2259,6 +2480,24 @@ typedef struct {
     unsigned int         partitionId;                           //!< ID of the fabric partition to which this GPU belongs
     nvmlGpuFabricState_t state;                                 //!< Current state of GPU registration process
 } nvmlGpuFabricInfo_t;
+
+/**
+ * Device Scope - This is useful to retrieve the telemetry at GPU and module (e.g. GPU + CPU) level
+ */
+#define NVML_POWER_SCOPE_GPU     0U    //!< Targets only GPU
+#define NVML_POWER_SCOPE_MODULE  1U    //!< Targets the whole module
+
+typedef unsigned char nvmlPowerScopeType_t;
+
+typedef struct
+{
+    unsigned int         version;       //!< Structure format version (must be 1)
+    nvmlPowerScopeType_t powerScope;    //!< [in]  Device type: GPU or Total Module
+    unsigned int         powerValueMw;  //!< [out] Power value to retrieve or set in milliwatts
+} nvmlPowerValue_v2_t;
+ 
+#define nvmlPowerValue_v2 NVML_STRUCT_VERSION(PowerValue, 2)
+
 /** @} */
 
 /***************************************************************************************************/
@@ -3000,6 +3239,23 @@ nvmlReturn_t DECLDIR nvmlDeviceGetIndex(nvmlDevice_t device, unsigned int *index
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetSerial(nvmlDevice_t device, char *serial, unsigned int length);
 
+/*
+* Get a unique identifier for the device module on the baseboard
+*
+* This API retrieves a unique identifier for each GPU module that exists on a given baseboard.
+* For non-baseboard products, this ID would always be 0.
+*
+* @param device                               The identifier of the target device
+* @param moduleId                             Unique identifier for the GPU module
+*
+* @return
+*         - \ref NVML_SUCCESS                 if \a moduleId has been successfully retrieved
+*         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+*         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device or \a moduleId is invalid
+*         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+*/
+nvmlReturn_t DECLDIR nvmlDeviceGetModuleId(nvmlDevice_t device, unsigned int *moduleId);
+
 
 /***************************************************************************************************/
 
@@ -3400,6 +3656,27 @@ nvmlReturn_t DECLDIR nvmlDeviceGetInforomConfigurationChecksum(nvmlDevice_t devi
  */
 nvmlReturn_t DECLDIR nvmlDeviceValidateInforom(nvmlDevice_t device);
 
+/**
+ * Retrieves the timestamp and the duration of the last flush of the BBX (blackbox) infoROM object during the current run.
+ *
+ * For all products with an inforom.
+ *
+ * @param device                               The identifier of the target device
+ * @param timestamp                            The start timestamp of the last BBX Flush
+ * @param durationUs                           The duration (us) of the last BBX Flush
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a timestamp and \a durationUs are successfully retrieved
+ *         - \ref NVML_ERROR_NOT_READY         if the BBX object has not been flushed yet
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not have an infoROM
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ *
+ * @see nvmlDeviceGetInforomVersion
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetLastBBXFlushTime(nvmlDevice_t device, unsigned long long *timestamp,
+                                                   unsigned long *durationUs);
+
 /**
  * Retrieves the display mode for the device.
  *
@@ -4224,50 +4501,60 @@ nvmlReturn_t DECLDIR nvmlDeviceGetThermalSettings(nvmlDevice_t device, unsigned
 nvmlReturn_t DECLDIR nvmlDeviceGetPerformanceState(nvmlDevice_t device, nvmlPstates_t *pState);
 
 /**
- * Retrieves current clocks throttling reasons.
+ * Retrieves current clocks event reasons.
  *
  * For all fully supported products.
  *
  * \note More than one bit can be enabled at the same time. Multiple reasons can be affecting clocks at once.
  *
  * @param device                                The identifier of the target device
- * @param clocksThrottleReasons                 Reference in which to return bitmask of active clocks throttle
+ * @param clocksEventReasons                    Reference in which to return bitmask of active clocks event
  *                                                  reasons
  *
  * @return
- *         - \ref NVML_SUCCESS                 if \a clocksThrottleReasons has been set
+ *         - \ref NVML_SUCCESS                 if \a clocksEventReasons has been set
  *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
- *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a clocksThrottleReasons is NULL
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a clocksEventReasons is NULL
  *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not support this feature
  *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
  *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
  *
- * @see nvmlClocksThrottleReasons
- * @see nvmlDeviceGetSupportedClocksThrottleReasons
+ * @see nvmlClocksEventReasons
+ * @see nvmlDeviceGetSupportedClocksEventReasons
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksEventReasons(nvmlDevice_t device, unsigned long long *clocksEventReasons);
+
+/**
+ * @deprecated Use \ref nvmlDeviceGetCurrentClocksEventReasons instead
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetCurrentClocksThrottleReasons(nvmlDevice_t device, unsigned long long *clocksThrottleReasons);
 
 /**
- * Retrieves bitmask of supported clocks throttle reasons that can be returned by
- * \ref nvmlDeviceGetCurrentClocksThrottleReasons
+ * Retrieves bitmask of supported clocks event reasons that can be returned by
+ * \ref nvmlDeviceGetCurrentClocksEventReasons
  *
  * For all fully supported products.
  *
  * This method is not supported in virtual machines running virtual GPU (vGPU).
  *
  * @param device                               The identifier of the target device
- * @param supportedClocksThrottleReasons       Reference in which to return bitmask of supported
- *                                              clocks throttle reasons
+ * @param supportedClocksEventReasons       Reference in which to return bitmask of supported
+ *                                              clocks event reasons
  *
  * @return
- *         - \ref NVML_SUCCESS                 if \a supportedClocksThrottleReasons has been set
+ *         - \ref NVML_SUCCESS                 if \a supportedClocksEventReasons has been set
  *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
- *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a supportedClocksThrottleReasons is NULL
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a supportedClocksEventReasons is NULL
  *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
  *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
  *
- * @see nvmlClocksThrottleReasons
- * @see nvmlDeviceGetCurrentClocksThrottleReasons
+ * @see nvmlClocksEventReasons
+ * @see nvmlDeviceGetCurrentClocksEventReasons
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksEventReasons(nvmlDevice_t device, unsigned long long *supportedClocksEventReasons);
+
+/**
+ * @deprecated Use \ref nvmlDeviceGetSupportedClocksEventReasons instead
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetSupportedClocksThrottleReasons(nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons);
 
@@ -4604,6 +4891,14 @@ nvmlReturn_t DECLDIR nvmlDeviceGetGpuOperationMode(nvmlDevice_t device, nvmlGpuO
  *
  * @note nvmlDeviceGetMemoryInfo_v2 adds additional memory information.
  *
+ * @note On systems where GPUs are NUMA nodes, the accuracy of FB memory utilization
+ *       provided by this API depends on the memory accounting of the operating system.
+ *       This is because FB memory is managed by the operating system instead of the NVIDIA GPU driver.
+ *       Typically, pages allocated from FB memory are not released even after
+ *       the process terminates to enhance performance. In scenarios where
+ *       the operating system is under memory pressure, it may resort to utilizing FB memory.
+ *       Such actions can result in discrepancies in the accuracy of memory reporting.
+ *
  * @param device                               The identifier of the target device
  * @param memory                               Reference in which to return the memory information
  *
@@ -5006,6 +5301,48 @@ nvmlReturn_t DECLDIR nvmlDeviceGetEncoderSessions(nvmlDevice_t device, unsigned
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetDecoderUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs);
 
+/**
+ * Retrieves the current utilization and sampling size in microseconds for the JPG
+ *
+ * %TURING_OR_NEWER%
+ *
+ * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported.
+ *
+ * @param device                               The identifier of the target device
+ * @param utilization                          Reference to an unsigned int for jpg utilization info
+ * @param samplingPeriodUs                     Reference to an unsigned int for the sampling period in US
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a utilization has been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not support this feature
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetJpgUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs);
+
+/**
+ * Retrieves the current utilization and sampling size in microseconds for the OFA (Optical Flow Accelerator)
+ *
+ * %TURING_OR_NEWER%
+ *
+ * @note On MIG-enabled GPUs, querying decoder utilization is not currently supported.
+ *
+ * @param device                               The identifier of the target device
+ * @param utilization                          Reference to an unsigned int for ofa utilization info
+ * @param samplingPeriodUs                     Reference to an unsigned int for the sampling period in US
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a utilization has been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid, \a utilization is NULL, or \a samplingPeriodUs is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not support this feature
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetOfaUtilization(nvmlDevice_t device, unsigned int *utilization, unsigned int *samplingPeriodUs);
+
 /**
 * Retrieves the active frame buffer capture sessions statistics for a given device.
 *
@@ -5252,6 +5589,57 @@ nvmlReturn_t DECLDIR nvmlDeviceGetGraphicsRunningProcesses_v3(nvmlDevice_t devic
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v3(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_t *infos);
 
+/**
+ * Get information about running processes on a device for input context
+ *
+ * %HOPPER_OR_NEWER%
+ *
+ * This function returns information only about running processes (e.g. CUDA application which have
+ * active context).
+ *
+ * To determine the size of the @ref plist->procArray array to allocate, call the function with
+ * @ref plist->numProcArrayEntries set to zero and @ref plist->procArray set to NULL. The return
+ * code will be either NVML_ERROR_INSUFFICIENT_SIZE (if there are valid processes of type 
+ * @ref plist->mode to report on, in which case the @ref plist->numProcArrayEntries field will
+ * indicate the required number of entries in the array) or NVML_SUCCESS (if no processes of type
+ * @ref plist->mode exist).
+ *
+ * The usedGpuMemory field returned is all of the memory used by the application.
+ * The usedGpuCcProtectedMemory field returned is all of the protected memory used by the application.
+ *
+ * Keep in mind that information returned by this call is dynamic and the number of elements might change in
+ * time. Allocate more space for \a plist->procArray table in case new processes are spawned.
+ *
+ * @note In MIG mode, if device handle is provided, the API returns aggregate information, only if
+ *       the caller has appropriate privileges. Per-instance information can be queried by using
+ *       specific MIG device handles.
+ *       Querying per-instance information using MIG device handles is not supported if the device is in
+ *       vGPU Host virtualization mode.
+ *       Protected memory usage is currently not available in MIG mode and in windows.
+ *
+ * @param device                               The device handle or MIG device handle
+ * @param plist                                Reference in which to process detail list
+ * @param plist->version                       The api version
+ * @param plist->mode                          The process mode
+ * @param plist->procArray                     Reference in which to return the process information
+ * @param plist->numProcArrayEntries           Proc array size of returned entries
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a plist->numprocArrayEntries and \a plist->procArray have been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INSUFFICIENT_SIZE if \a plist->numprocArrayEntries indicates that the \a plist->procArray is too small
+ *                                             \a plist->numprocArrayEntries will contain minimal amount of space necessary for
+ *                                             the call to complete
+ *         - \ref NVML_ERROR_NO_PERMISSION     if the user doesn't have permission to perform this operation
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid, \a plist is NULL, \a plist->version is invalid,
+ *                                             \a plist->mode is invalid,
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by \a device
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ *
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetRunningProcessDetailList(nvmlDevice_t device, nvmlProcessDetailList_t *plist);
+
 /**
  * Check if the GPU devices are on the same physical board.
  *
@@ -5495,7 +5883,9 @@ nvmlReturn_t DECLDIR nvmlDeviceGetPcieSpeed(nvmlDevice_t device, unsigned int *p
  * Gets the device's Adaptive Clock status
  *
  * @param device                               The identifier of the target device
- * @param adaptiveClockStatus                  The current adaptive clocking status
+ * @param adaptiveClockStatus                  The current adaptive clocking status, either
+ *                                             @ref NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED 
+ *                                             or @ref NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED
  *
  * @return
  *         - \ref NVML_SUCCESS                 if the current adaptive clocking status is successfully retrieved
@@ -5541,6 +5931,128 @@ nvmlReturn_t DECLDIR nvmlDeviceGetBusType(nvmlDevice_t device, nvmlBusType_t *ty
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetGpuFabricInfo(nvmlDevice_t device, nvmlGpuFabricInfo_t *gpuFabricInfo);
 
+/**
+ * Get Conf Computing System capabilities.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param capabilities                         System CC capabilities
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a capabilities were successfully queried
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a capabilities is invalid
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlSystemGetConfComputeCapabilities(nvmlConfComputeSystemCaps_t *capabilities);
+
+/**
+ * Get Conf Computing System State.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param state                                System CC State
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a state were successfully queried
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a state is invalid
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlSystemGetConfComputeState(nvmlConfComputeSystemState_t *state);
+
+/**
+ * Get Conf Computing Protected and Unprotected Memory Sizes.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param device                               Device handle
+ * @param memInfo                              Protected/Unprotected Memory sizes
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a memInfo were successfully queried
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a memInfo or \a device is invalid
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeMemSizeInfo(nvmlDevice_t device, nvmlConfComputeMemSizeInfo_t *memInfo);
+
+/**
+ * Get Conf Computing GPUs ready state.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param isAcceptingWork                      Returns GPU current work accepting state,
+ *                                             NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or
+ *                                             NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE
+ *
+ * return
+ *         - \ref NVML_SUCCESS                 if \a current GPUs ready state were successfully queried
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a isAcceptingWork is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlSystemGetConfComputeGpusReadyState(unsigned int *isAcceptingWork);
+
+/**
+ * Get Conf Computing protected memory usage.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param device                               The identifier of the target device
+ * @param memory                               Reference in which to return the memory information
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a memory has been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a memory is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeProtectedMemoryUsage(nvmlDevice_t device, nvmlMemory_t *memory);
+
+/**
+ * Get Conf Computing Gpu certificate details.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param device                               The identifier of the target device
+ * @param gpuCert                              Reference in which to return the gpu certificate information
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a gpu certificate info has been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a memory is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuCertificate(nvmlDevice_t device,
+                                                            nvmlConfComputeGpuCertificate_t *gpuCert);
+
+/**
+ * Get Conf Computing Gpu attestation report.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param device                               The identifier of the target device
+ * @param gpuAtstReport                        Reference in which to return the gpu attestation report
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a gpu attestation report has been populated
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a memory is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetConfComputeGpuAttestationReport(nvmlDevice_t device,
+                                                                  nvmlConfComputeGpuAttestationReport_t *gpuAtstReport);
 
 /**
  * @}
@@ -6362,6 +6874,40 @@ nvmlReturn_t DECLDIR nvmlDeviceSetGpcClkVfOffset(nvmlDevice_t device, int offset
  */
 nvmlReturn_t DECLDIR nvmlDeviceSetMemClkVfOffset(nvmlDevice_t device, int offset);
 
+/**
+ * Set Conf Computing Unprotected Memory Size.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param device                               Device Handle
+ * @param sizeKiB                              Unprotected Memory size to be set in KiB
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a sizeKiB successfully set
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlDeviceSetConfComputeUnprotectedMemSize(nvmlDevice_t device, unsigned long long sizeKiB);
+
+/**
+ * Set Conf Computing GPUs ready state.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Supported on Linux, Windows TCC.
+ *
+ * @param isAcceptingWork                      GPU accepting new work, NVML_CC_ACCEPTING_CLIENT_REQUESTS_TRUE or
+ *                                             NVML_CC_ACCEPTING_CLIENT_REQUESTS_FALSE
+ *
+ * return
+ *         - \ref NVML_SUCCESS                 if \a current GPUs ready state is successfully set
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a isAcceptingWork is invalid
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
+ */
+nvmlReturn_t DECLDIR nvmlSystemSetConfComputeGpusReadyState(unsigned int isAcceptingWork);
+
 /**
  * @}
  */
@@ -7084,7 +7630,8 @@ nvmlReturn_t DECLDIR nvmlDeviceGetGridLicensableFeatures_v4(nvmlDevice_t device,
  * Utilization values are returned as an array of utilization sample structures in the caller-supplied buffer pointed at
  * by \a utilization. One utilization sample structure is returned per process running, that had some non-zero utilization
  * during the last sample period. It includes the CPU timestamp at which  the samples were recorded. Individual utilization values
- * are returned as "unsigned int" values.
+ * are returned as "unsigned int" values. If no valid sample entries are found since the lastSeenTimeStamp, NVML_ERROR_NOT_FOUND
+ * is returned.
  *
  * To read utilization values, first determine the size of buffer required to hold the samples by invoking the function with
  * \a utilization set to NULL. The caller should allocate a buffer of size
@@ -8048,6 +8595,7 @@ nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerLog(nvmlDevice_t device, nvmlVgpu
 
 /**
  * Returns the vGPU scheduler state.
+ * The information returned in \a nvmlVgpuSchedulerGetState_t is not relevant if the BEST EFFORT policy is set.
  *
  * For Pascal &tm; or newer fully supported devices.
  *
@@ -8085,6 +8633,31 @@ nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerState(nvmlDevice_t device, nvmlVg
  */
 nvmlReturn_t DECLDIR nvmlDeviceGetVgpuSchedulerCapabilities(nvmlDevice_t device, nvmlVgpuSchedulerCapabilities_t *pCapabilities);
 
+/**
+ * Sets the vGPU scheduler state.
+ *
+ * For Pascal &tm; or newer fully supported devices.
+ *
+ * The scheduler state change won't persist across module load/unload.
+ * Scheduler state and params will be allowed to set only when no VM is running.
+ * In \a nvmlVgpuSchedulerSetState_t, IFF enableARRMode is enabled then
+ * provide avgFactorForARR and frequency as input. If enableARRMode is disabled
+ * then provide timeslice as input.
+ *
+ * @param device                The identifier of the target \a device
+ * @param pSchedulerState       vGPU \a pSchedulerState to set
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                  vGPU scheduler state has been successfully set
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT   if \a pSchedulerState is NULL or \a device is invalid
+ *         - \ref NVML_ERROR_RESET_REQUIRED     if setting \a pSchedulerState failed with fatal error,
+ *                                              reboot is required to overcome from this error.
+ *         - \ref NVML_ERROR_NOT_SUPPORTED      The API is not supported in current state or \a device not in vGPU host mode
+ *                                              or if any vGPU instance currently exists on the \a device
+ *         - \ref NVML_ERROR_UNKNOWN            on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceSetVgpuSchedulerState(nvmlDevice_t device, nvmlVgpuSchedulerSetState_t *pSchedulerState);
+
 /*
  * Virtual GPU (vGPU) version
  *
@@ -8529,13 +9102,13 @@ typedef struct nvmlGpuInstance_st* nvmlGpuInstance_t;
  * These macros should be passed to \ref nvmlGpuInstanceGetComputeInstanceProfileInfo to retrieve the
  * detailed information about a compute instance such as profile ID, engine counts
  */
-#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE 0x0
-#define NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE 0x1
-#define NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE 0x2
-#define NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE 0x3
-#define NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE 0x4
-#define NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE 0x5
-#define NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE 0x6
+#define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE       0x0
+#define NVML_COMPUTE_INSTANCE_PROFILE_2_SLICE       0x1
+#define NVML_COMPUTE_INSTANCE_PROFILE_3_SLICE       0x2
+#define NVML_COMPUTE_INSTANCE_PROFILE_4_SLICE       0x3
+#define NVML_COMPUTE_INSTANCE_PROFILE_7_SLICE       0x4
+#define NVML_COMPUTE_INSTANCE_PROFILE_8_SLICE       0x5
+#define NVML_COMPUTE_INSTANCE_PROFILE_6_SLICE       0x6
 #define NVML_COMPUTE_INSTANCE_PROFILE_1_SLICE_REV1  0x7
 #define NVML_COMPUTE_INSTANCE_PROFILE_COUNT         0x8
 
@@ -9521,58 +10094,45 @@ nvmlReturn_t DECLDIR nvmlGpmMigSampleGet(nvmlDevice_t device, unsigned int gpuIn
  */
 nvmlReturn_t DECLDIR nvmlGpmQueryDeviceSupport(nvmlDevice_t device, nvmlGpmSupport_t *gpmSupport);
 
-/** @} */ // @defgroup nvmlGpmFunctions
-/** @} */ // @defgroup GPM
-
-/***************************************************************************************************/
-/** @defgroup nvmlDevice definitions related to Counter Collection Unit
- *  @{
- */
-/***************************************************************************************************/
-
-/* CCU Stream State */
-#define NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_DISABLE 0
-#define NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_ENABLE  1
-
+/* GPM Stream State */
 /**
- * Get counter collection unit stream state.
+ * Get GPM stream state.
  *
  * %HOPPER_OR_NEWER%
  * Supported on Linux, Windows TCC.
  *
  * @param device                               The identifier of the target device
- * @param state                                Returns counter collection unit stream state
- *                                             NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_DISABLE or
- *                                             NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_ENABLE
+ * @param state                                Returns GPM stream state
+ *                                             NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED
  *
  * @return
- *         - \ref NVML_SUCCESS                 if \a current counter collection unit stream state were successfully queried
+ *         - \ref NVML_SUCCESS                 if \a current GPM stream state were successfully queried
  *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
  *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a  device is invalid or \a state is NULL
  *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
  */
-nvmlReturn_t DECLDIR nvmlDeviceCcuGetStreamState(nvmlDevice_t device, unsigned int *state);
+nvmlReturn_t DECLDIR nvmlGpmQueryIfStreamingEnabled(nvmlDevice_t device, unsigned int *state);
 
 /**
- * Set counter collection unit stream state.
+ * Set GPM stream state.
  *
  * %HOPPER_OR_NEWER%
  * Supported on Linux, Windows TCC.
  *
  * @param device                               The identifier of the target device
- * @param state                                Counter collection unit stream state,
- *                                             NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_DISABLE or
- *                                             NVML_COUNTER_COLLECTION_UNIT_STREAM_STATE_ENABLE
+ * @param state                                GPM stream state,
+ *                                             NVML_FEATURE_DISABLED or NVML_FEATURE_ENABLED
  *
  * @return
- *         - \ref NVML_SUCCESS                 if \a current counter collection unit stream state is successfully set
+ *         - \ref NVML_SUCCESS                 if \a current GPM stream state is successfully set
  *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
  *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid
  *         - \ref NVML_ERROR_NOT_SUPPORTED     if this query is not supported by the device
  */
-nvmlReturn_t DECLDIR nvmlDeviceCcuSetStreamState(nvmlDevice_t device, unsigned int state);
+nvmlReturn_t DECLDIR nvmlGpmSetStreamingEnabled(nvmlDevice_t device, unsigned int state);
 
-/** @} */ // @defgroup CCU
+/** @} */ // @defgroup nvmlGpmFunctions
+/** @} */ // @defgroup GPM
 
 #define NVML_NVLINK_POWER_STATE_HIGH_SPEED    0x0
 #define NVML_NVLINK_POWER_STATE_LOW           0x1
@@ -9605,6 +10165,88 @@ typedef struct nvmlNvLinkPowerThres_st
  **/
 nvmlReturn_t DECLDIR nvmlDeviceSetNvLinkDeviceLowPowerThreshold(nvmlDevice_t device, nvmlNvLinkPowerThres_t *info);
 
+/**
+ * Set the global nvlink bandwith mode
+ *
+ * @param nvlinkBwMode             nvlink bandwidth mode
+ * @return
+ *         - \ref NVML_SUCCESS                on success
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid argument is provided
+ *         - \ref NVML_ERROR_IN_USE           if P2P object exists
+ *         - \ref NVML_ERROR_NOT_SUPPORTED    if GPU is not Hopper or newer architecture.
+ *         - \ref NVML_ERROR_NO_PERMISSION    if not root user
+ */
+nvmlReturn_t DECLDIR nvmlSystemSetNvlinkBwMode(unsigned int nvlinkBwMode);
+
+/**
+ * Get the global nvlink bandwith mode
+ *
+ * @param nvlinkBwMode             reference of nvlink bandwidth mode
+ * @return
+ *         - \ref NVML_SUCCESS                on success
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT if an invalid pointer is provided
+ *         - \ref NVML_ERROR_NOT_SUPPORTED    if GPU is not Hopper or newer architecture.
+ *         - \ref NVML_ERROR_NO_PERMISSION    if not root user
+ */
+nvmlReturn_t DECLDIR nvmlSystemGetNvlinkBwMode(unsigned int *nvlinkBwMode);
+
+/**
+ * Set new power limit of this device.
+ *
+ * For Kepler &tm; or newer fully supported devices.
+ * Requires root/admin permissions.
+ *
+ * See \ref nvmlDeviceGetPowerManagementLimitConstraints to check the allowed ranges of values.
+ *
+ * See \ref nvmlPowerValue_v2_t for more information on the struct.
+ *
+ * \note Limit is not persistent across reboots or driver unloads.
+ * Enable persistent mode to prevent driver from unloading when no application is using the device.
+ *
+ * This API replaces nvmlDeviceSetPowerManagementLimit. It can be used as a drop-in replacement for the older version.
+ *
+ * @param device                               The identifier of the target device
+ * @param powerValue                           Power management limit in milliwatts to set
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a limit has been set
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a powerValue is NULL or contains invalid values
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not support this feature
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ *
+ * @see NVML_FI_DEV_POWER_AVERAGE 
+ * @see NVML_FI_DEV_POWER_INSTANT
+ * @see NVML_FI_DEV_POWER_MIN_LIMIT
+ * @see NVML_FI_DEV_POWER_MAX_LIMIT
+ * @see NVML_FI_DEV_POWER_CURRENT_LIMIT
+ */
+nvmlReturn_t DECLDIR nvmlDeviceSetPowerManagementLimit_v2(nvmlDevice_t device, nvmlPowerValue_v2_t *powerValue);
+
+/**
+ * Get SRAM ECC error status of this device.
+ *
+ * For Ampere &tm; or newer fully supported devices.
+ * Requires root/admin permissions.
+ *
+ * See \ref nvmlEccSramErrorStatus_v1_t for more information on the struct.
+ *
+ * @param device                               The identifier of the target device
+ * @param status                               Returns SRAM ECC error status
+ *
+ * @return
+ *         - \ref NVML_SUCCESS                 if \a limit has been set
+ *         - \ref NVML_ERROR_UNINITIALIZED     if the library has not been successfully initialized
+ *         - \ref NVML_ERROR_INVALID_ARGUMENT  if \a device is invalid or \a counters is NULL
+ *         - \ref NVML_ERROR_NOT_SUPPORTED     if the device does not support this feature
+ *         - \ref NVML_ERROR_GPU_IS_LOST       if the target GPU has fallen off the bus or is otherwise inaccessible
+ *         - \ref NVML_ERROR_VERSION_MISMATCH  if the version of \a nvmlEccSramErrorStatus_t is invalid
+ *         - \ref NVML_ERROR_UNKNOWN           on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlDeviceGetSramEccErrorStatus(nvmlDevice_t device,
+                                                     nvmlEccSramErrorStatus_t *status);
+
 /**
  * NVML API versioning support
  */
@@ -9632,7 +10274,6 @@ nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses(nvmlDevice_t device
 nvmlReturn_t DECLDIR nvmlDeviceGetMPSComputeRunningProcesses_v2(nvmlDevice_t device, unsigned int *infoCount, nvmlProcessInfo_v2_t *infos);
 nvmlReturn_t DECLDIR nvmlDeviceGetGpuInstancePossiblePlacements(nvmlDevice_t device, unsigned int profileId, nvmlGpuInstancePlacement_t *placements, unsigned int *count);
 nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo(nvmlVgpuInstance_t vgpuInstance, nvmlVgpuLicenseInfo_t *licenseInfo);
-
 #endif // #ifdef NVML_NO_UNVERSIONED_FUNC_DEFS
 
 #if defined(NVML_NO_UNVERSIONED_FUNC_DEFS)
@@ -9658,6 +10299,7 @@ nvmlReturn_t DECLDIR nvmlVgpuInstanceGetLicenseInfo(nvmlVgpuInstance_t vgpuInsta
 #undef nvmlGetBlacklistDeviceInfoByIndex
 #undef nvmlDeviceGetGpuInstancePossiblePlacements
 #undef nvmlVgpuInstanceGetLicenseInfo
+#undef nvmlDeviceSetPowerManagementLimit
 
 #endif
 
diff --git a/src/parse.c b/src/parse.c
index a28ae5bcaa15567676d24e9bcbb8597e4a887204..c8ad537ee627e8a137040937461fd72b7ba49399 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -289,6 +289,7 @@ const AttributeTableEntry attributeTable[] = {
     { "DisplayVRRMode",                   NV_CTRL_DISPLAY_VRR_MODE,                     INT_ATTR, {0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Whether the specified display device is G-SYNC or G-SYNC Compatible." },
     { "DisplayVRRMinRefreshRate",         NV_CTRL_DISPLAY_VRR_MIN_REFRESH_RATE,         INT_ATTR, {0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The minimum refresh rate for the specified VRR display device." },
     { "DisplayVRREnabled",                NV_CTRL_DISPLAY_VRR_ENABLED,                  INT_ATTR, {0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "If this is enabled (1), then VRR was enabled on this display at modeset time." },
+    { "NumberOfHardwareHeadsUsed",        NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED,        INT_ATTR, {0,0,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Returns the number of hardware heads currently used by this display device." },
 
     /* TV */
     { "TVOverScan",                       NV_CTRL_TV_OVERSCAN,                          INT_ATTR, {0,0,0,0,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Adjusts the amount of overscan on the specified display device." },
@@ -341,6 +342,13 @@ const AttributeTableEntry attributeTable[] = {
     /* Dynamic Boost */
     { "DynamicBoostSupport",              NV_CTRL_DYNAMIC_BOOST_SUPPORT,                INT_ATTR, {0,0,0,1,0}, {},  "Returns whether the system supports Dynamic Boost." },
 
+    { "GpuGetPowerUsage",                 NV_CTRL_ATTR_NVML_GPU_GET_POWER_USAGE,        INT_ATTR, {0,0,0,1,1}, {},  "Returns the current power usage of the GPU, in Watts." },
+    { "GPUMaxTGP",                        NV_CTRL_ATTR_NVML_GPU_MAX_TGP,                INT_ATTR, {0,0,0,1,1}, {},  "Returns the max TGP of the GPU, in Watts." },
+    { "GPUDefaultTGP",                    NV_CTRL_ATTR_NVML_GPU_DEFAULT_TGP,            INT_ATTR, {0,0,0,1,1}, {},  "Returns the default TGP of the GPU, in Watts." },
+
+    /* Framelock sync multiplier/divider */
+    { "FrameLockMultiplyDivideValue",     NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_VALUE,      INT_ATTR, {1,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "The value to multiply or divide the house sync input rate by before comparing it to this framelock board's internal sync rate." },
+    { "FrameLockMultiplyDivideMode",      NV_CTRL_FRAMELOCK_MULTIPLY_DIVIDE_MODE,       INT_ATTR, {1,1,0,1,0}, { .int_flags = {0,0,0,0,0,0,0} }, "Whether the house sync rate should be multiplied or divided." },
 };
 
 const int attributeTableLen = ARRAY_LEN(attributeTable);
@@ -351,7 +359,7 @@ const int attributeTableLen = ARRAY_LEN(attributeTable);
  * the last attribute that the table knows about.
  */
 
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DYNAMIC_BOOST_SUPPORT
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NUMBER_OF_HARDWARE_HEADS_USED
 #warning "Have you forgotten to add a new integer attribute to attributeTable?"
 #endif
 
diff --git a/src/version.mk b/src/version.mk
index dae35ac2315e7ed874c063beacadec078b9447d1..89404cd76a7444270097f0872a9cf1a582796891 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 525.147.05
+NVIDIA_VERSION = 535.171.04
 
 # This file.
 VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))
diff --git a/src/wayland-connector.c b/src/wayland-connector.c
index 7e9bec7e1da1bddb5b17c08d25d30c138f29dfc8..0d0eced8b1a839c5d202862e6aa43af7beb54cf2 100644
--- a/src/wayland-connector.c
+++ b/src/wayland-connector.c
@@ -104,9 +104,10 @@ static void registry_handle_global(void *data_in, struct wl_registry *registry,
         wayland_output_info *output;
         output = calloc(1, sizeof(wayland_output_info));
         output->name = name;
-        output->version = version;
+        output->version = 2;
         output->output = wl_registry_bind(data->registry, name,
-                                          &wl_output_interface, version);
+                                          &wl_output_interface,
+                                          output->version);
         wl_output_add_listener(output->output,
                                           &output_listener,
                                           output);
diff --git a/version.mk b/version.mk
index dae35ac2315e7ed874c063beacadec078b9447d1..89404cd76a7444270097f0872a9cf1a582796891 100644
--- a/version.mk
+++ b/version.mk
@@ -1,4 +1,4 @@
-NVIDIA_VERSION = 525.147.05
+NVIDIA_VERSION = 535.171.04
 
 # This file.
 VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))