drm/amdgpu: Add NPS switch support for GC 9.4.3
authorLijo Lazar <lijo.lazar@amd.com>
Fri, 20 Sep 2024 09:55:10 +0000 (15:25 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 15 Oct 2024 15:17:25 +0000 (11:17 -0400)
Add dynamic NPS switch support for GC 9.4.3 variants. Only GC v9.4.3 and
GC v9.4.4 currently support this. NPS switch is only supported if an SOC
supports multiple NPS modes.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Rajneesh Bhardwaj <rajneesh.bhardwaj@amd.com>
Reviewed-by: Feifei Xu <Feifei.Xu@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c

index f61d117b0cafe36f2ada19df50a37b581b75311c..79c2f807b9fe87eb479fd94c0a3511dbaf23d305 100644 (file)
@@ -101,6 +101,7 @@ struct amdgpu_nbio_funcs {
        int (*get_compute_partition_mode)(struct amdgpu_device *adev);
        u32 (*get_memory_partition_mode)(struct amdgpu_device *adev,
                                         u32 *supp_modes);
+       bool (*is_nps_switch_requested)(struct amdgpu_device *adev);
        u64 (*get_pcie_replay_count)(struct amdgpu_device *adev);
        void (*set_reg_remap)(struct amdgpu_device *adev);
 };
index 94600e5c8ea31aa35fbf3355204849e56a718fd7..bfbfbcc9b89b0522758153a21e51ca8119b52993 100644 (file)
@@ -1395,6 +1395,17 @@ gmc_v9_0_query_memory_partition(struct amdgpu_device *adev)
        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,
@@ -1406,6 +1417,8 @@ static const struct amdgpu_gmc_funcs gmc_v9_0_gmc_funcs = {
        .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)
@@ -1545,6 +1558,28 @@ static void gmc_v9_0_set_xgmi_ras_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;
@@ -2165,6 +2200,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
        if (r)
                return r;
 
+       gmc_v9_0_init_nps_details(adev);
        /*
         * number of VMs
         * VMID 0 is reserved for System
@@ -2435,8 +2471,17 @@ static int gmc_v9_0_suspend(struct amdgpu_ip_block *ip_block)
 
 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;
index d1bd79bbae532facedf9d2534008d8d8ce20d7bb..8a0a63ac88d2b68406d835beb7ac99ed4377654d 100644 (file)
@@ -401,6 +401,17 @@ static int nbio_v7_9_get_compute_partition_mode(struct amdgpu_device *adev)
        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)
 {
@@ -508,6 +519,7 @@ const struct amdgpu_nbio_funcs nbio_v7_9_funcs = {
        .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,