return gmc_v9_0_get_memory_partition(adev, NULL);
 }
 
+static bool gmc_v9_0_need_reset_on_init(struct amdgpu_device *adev)
+{
+       if (adev->nbio.funcs && adev->nbio.funcs->is_nps_switch_requested &&
+           adev->nbio.funcs->is_nps_switch_requested(adev)) {
+               adev->gmc.reset_flags |= AMDGPU_GMC_INIT_RESET_NPS;
+               return true;
+       }
+
+       return false;
+}
+
 static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
        .flush_gpu_tlb = gmc_v9_0_flush_gpu_tlb,
        .flush_gpu_tlb_pasid = gmc_v9_0_flush_gpu_tlb_pasid,
        .override_vm_pte_flags = gmc_v9_0_override_vm_pte_flags,
        .get_vbios_fb_size = gmc_v9_0_get_vbios_fb_size,
        .query_mem_partition_mode = &gmc_v9_0_query_memory_partition,
+       .request_mem_partition_mode = &amdgpu_gmc_request_memory_partition,
+       .need_reset_on_init = &gmc_v9_0_need_reset_on_init,
 };
 
 static void gmc_v9_0_set_gmc_funcs(struct amdgpu_device *adev)
                adev->gmc.xgmi.ras = &xgmi_ras;
 }
 
+static void gmc_v9_0_init_nps_details(struct amdgpu_device *adev)
+{
+       adev->gmc.supported_nps_modes = 0;
+
+       if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
+               return;
+
+       /*TODO: Check PSP version also which supports NPS switch. Otherwise keep
+        * supported modes as 0.
+        */
+       switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
+       case IP_VERSION(9, 4, 3):
+       case IP_VERSION(9, 4, 4):
+               adev->gmc.supported_nps_modes =
+                       BIT(AMDGPU_NPS1_PARTITION_MODE) |
+                       BIT(AMDGPU_NPS4_PARTITION_MODE);
+               break;
+       default:
+               break;
+       }
+}
+
 static int gmc_v9_0_early_init(struct amdgpu_ip_block *ip_block)
 {
        struct amdgpu_device *adev = ip_block->adev;
        if (r)
                return r;
 
+       gmc_v9_0_init_nps_details(adev);
        /*
         * number of VMs
         * VMID 0 is reserved for System
 
 static int gmc_v9_0_resume(struct amdgpu_ip_block *ip_block)
 {
+       struct amdgpu_device *adev = ip_block->adev;
        int r;
 
+       /* If a reset is done for NPS mode switch, read the memory range
+        * information again.
+        */
+       if (adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS) {
+               gmc_v9_0_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
+               adev->gmc.reset_flags &= ~AMDGPU_GMC_INIT_RESET_NPS;
+       }
+
        r = gmc_v9_0_hw_init(ip_block);
        if (r)
                return r;
 
        return px;
 }
 
+static bool nbio_v7_9_is_nps_switch_requested(struct amdgpu_device *adev)
+{
+       u32 tmp;
+
+       tmp = RREG32_SOC15(NBIO, 0, regBIF_BX_PF0_PARTITION_MEM_STATUS);
+       tmp = REG_GET_FIELD(tmp, BIF_BX_PF0_PARTITION_MEM_STATUS,
+                           CHANGE_STATUE);
+
+       /* 0x8 - NPS switch requested */
+       return (tmp == 0x8);
+}
 static u32 nbio_v7_9_get_memory_partition_mode(struct amdgpu_device *adev,
                                               u32 *supp_modes)
 {
        .remap_hdp_registers = nbio_v7_9_remap_hdp_registers,
        .get_compute_partition_mode = nbio_v7_9_get_compute_partition_mode,
        .get_memory_partition_mode = nbio_v7_9_get_memory_partition_mode,
+       .is_nps_switch_requested = nbio_v7_9_is_nps_switch_requested,
        .init_registers = nbio_v7_9_init_registers,
        .get_pcie_replay_count = nbio_v7_9_get_pcie_replay_count,
        .set_reg_remap = nbio_v7_9_set_reg_remap,