]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: Convert init_mem_ranges into common helpers
authorHawking Zhang <Hawking.Zhang@amd.com>
Sat, 21 Jun 2025 13:27:22 +0000 (21:27 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 24 Jun 2025 14:04:16 +0000 (10:04 -0400)
They can be shared across multiple products

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c

index a65dff25c35a86bc35b288542d4fe236ee7e0abd..97b562a79ea8ee04c3b5321ef93117a311160a75 100644 (file)
@@ -1491,3 +1491,189 @@ amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev)
        else
                return amdgpu_gmc_get_memory_partition(adev, NULL);
 }
+
+static bool amdgpu_gmc_validate_partition_info(struct amdgpu_device *adev)
+{
+       enum amdgpu_memory_partition mode;
+       u32 supp_modes;
+       bool valid;
+
+       mode = amdgpu_gmc_get_memory_partition(adev, &supp_modes);
+
+       /* Mode detected by hardware not present in supported modes */
+       if ((mode != UNKNOWN_MEMORY_PARTITION_MODE) &&
+           !(BIT(mode - 1) & supp_modes))
+               return false;
+
+       switch (mode) {
+       case UNKNOWN_MEMORY_PARTITION_MODE:
+       case AMDGPU_NPS1_PARTITION_MODE:
+               valid = (adev->gmc.num_mem_partitions == 1);
+               break;
+       case AMDGPU_NPS2_PARTITION_MODE:
+               valid = (adev->gmc.num_mem_partitions == 2);
+               break;
+       case AMDGPU_NPS4_PARTITION_MODE:
+               valid = (adev->gmc.num_mem_partitions == 3 ||
+                        adev->gmc.num_mem_partitions == 4);
+               break;
+       case AMDGPU_NPS8_PARTITION_MODE:
+               valid = (adev->gmc.num_mem_partitions == 8);
+               break;
+       default:
+               valid = false;
+       }
+
+       return valid;
+}
+
+static bool amdgpu_gmc_is_node_present(int *node_ids, int num_ids, int nid)
+{
+       int i;
+
+       /* Check if node with id 'nid' is present in 'node_ids' array */
+       for (i = 0; i < num_ids; ++i)
+               if (node_ids[i] == nid)
+                       return true;
+
+       return false;
+}
+
+static void
+amdgpu_gmc_init_acpi_mem_ranges(struct amdgpu_device *adev,
+                               struct amdgpu_mem_partition_info *mem_ranges)
+{
+       struct amdgpu_numa_info numa_info;
+       int node_ids[AMDGPU_MAX_MEM_RANGES];
+       int num_ranges = 0, ret;
+       int num_xcc, xcc_id;
+       uint32_t xcc_mask;
+
+       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+       xcc_mask = (1U << num_xcc) - 1;
+
+       for_each_inst(xcc_id, xcc_mask) {
+               ret = amdgpu_acpi_get_mem_info(adev, xcc_id, &numa_info);
+               if (ret)
+                       continue;
+
+               if (numa_info.nid == NUMA_NO_NODE) {
+                       mem_ranges[0].size = numa_info.size;
+                       mem_ranges[0].numa.node = numa_info.nid;
+                       num_ranges = 1;
+                       break;
+               }
+
+               if (amdgpu_gmc_is_node_present(node_ids, num_ranges,
+                                            numa_info.nid))
+                       continue;
+
+               node_ids[num_ranges] = numa_info.nid;
+               mem_ranges[num_ranges].numa.node = numa_info.nid;
+               mem_ranges[num_ranges].size = numa_info.size;
+               ++num_ranges;
+       }
+
+       adev->gmc.num_mem_partitions = num_ranges;
+}
+
+void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev,
+                                  struct amdgpu_mem_partition_info *mem_ranges)
+{
+       enum amdgpu_memory_partition mode;
+       u32 start_addr = 0, size;
+       int i, r, l;
+
+       mode = amdgpu_gmc_query_memory_partition(adev);
+
+       switch (mode) {
+       case UNKNOWN_MEMORY_PARTITION_MODE:
+               adev->gmc.num_mem_partitions = 0;
+               break;
+       case AMDGPU_NPS1_PARTITION_MODE:
+               adev->gmc.num_mem_partitions = 1;
+               break;
+       case AMDGPU_NPS2_PARTITION_MODE:
+               adev->gmc.num_mem_partitions = 2;
+               break;
+       case AMDGPU_NPS4_PARTITION_MODE:
+               if (adev->flags & AMD_IS_APU)
+                       adev->gmc.num_mem_partitions = 3;
+               else
+                       adev->gmc.num_mem_partitions = 4;
+               break;
+       case AMDGPU_NPS8_PARTITION_MODE:
+               adev->gmc.num_mem_partitions = 8;
+               break;
+       default:
+               adev->gmc.num_mem_partitions = 1;
+               break;
+       }
+
+       /* Use NPS range info, if populated */
+       r = amdgpu_gmc_get_nps_memranges(adev, mem_ranges,
+                                        &adev->gmc.num_mem_partitions);
+       if (!r) {
+               l = 0;
+               for (i = 1; i < adev->gmc.num_mem_partitions; ++i) {
+                       if (mem_ranges[i].range.lpfn >
+                           mem_ranges[i - 1].range.lpfn)
+                               l = i;
+               }
+
+       } else {
+               if (!adev->gmc.num_mem_partitions) {
+                       dev_warn(adev->dev,
+                                "Not able to detect NPS mode, fall back to NPS1\n");
+                       adev->gmc.num_mem_partitions = 1;
+               }
+               /* Fallback to sw based calculation */
+               size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
+               size /= adev->gmc.num_mem_partitions;
+
+               for (i = 0; i < adev->gmc.num_mem_partitions; ++i) {
+                       mem_ranges[i].range.fpfn = start_addr;
+                       mem_ranges[i].size =
+                               ((u64)size << AMDGPU_GPU_PAGE_SHIFT);
+                       mem_ranges[i].range.lpfn = start_addr + size - 1;
+                       start_addr += size;
+               }
+
+               l = adev->gmc.num_mem_partitions - 1;
+       }
+
+       /* Adjust the last one */
+       mem_ranges[l].range.lpfn =
+               (adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT) - 1;
+       mem_ranges[l].size =
+               adev->gmc.real_vram_size -
+               ((u64)mem_ranges[l].range.fpfn << AMDGPU_GPU_PAGE_SHIFT);
+}
+
+int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev)
+{
+       bool valid;
+
+       adev->gmc.mem_partitions = kcalloc(AMDGPU_MAX_MEM_RANGES,
+                                          sizeof(struct amdgpu_mem_partition_info),
+                                          GFP_KERNEL);
+       if (!adev->gmc.mem_partitions)
+               return -ENOMEM;
+
+       if (adev->gmc.is_app_apu)
+               amdgpu_gmc_init_acpi_mem_ranges(adev, adev->gmc.mem_partitions);
+       else
+               amdgpu_gmc_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
+
+       if (amdgpu_sriov_vf(adev))
+               valid = true;
+       else
+               valid = amdgpu_gmc_validate_partition_info(adev);
+       if (!valid) {
+               /* TODO: handle invalid case */
+               dev_warn(adev->dev,
+                        "Mem ranges not matching with hardware config\n");
+       }
+
+       return 0;
+}
index 95a68e0eb96e972d842fd5d1cad5d489ec12d8ae..397c6ccdb9033bac752e5aa5ee8f566d428bdc0f 100644 (file)
@@ -464,4 +464,7 @@ enum amdgpu_memory_partition
 amdgpu_gmc_get_memory_partition(struct amdgpu_device *adev, u32 *supp_modes);
 enum amdgpu_memory_partition
 amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev);
+int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev);
+void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev,
+                                  struct amdgpu_mem_partition_info *mem_ranges);
 #endif
index fa897ced71e60378c4121fb771fa0936d48d76d2..380b7b81ac1fc3620f1c04da49471c72303e0448 100644 (file)
@@ -1838,188 +1838,6 @@ static void gmc_v9_0_save_registers(struct amdgpu_device *adev)
                adev->gmc.sdpif_register = RREG32_SOC15(DCE, 0, mmDCHUBBUB_SDPIF_MMIO_CNTRL_0);
 }
 
-static bool gmc_v9_0_validate_partition_info(struct amdgpu_device *adev)
-{
-       enum amdgpu_memory_partition mode;
-       u32 supp_modes;
-       bool valid;
-
-       mode = amdgpu_gmc_get_memory_partition(adev, &supp_modes);
-
-       /* Mode detected by hardware not present in supported modes */
-       if ((mode != UNKNOWN_MEMORY_PARTITION_MODE) &&
-           !(BIT(mode - 1) & supp_modes))
-               return false;
-
-       switch (mode) {
-       case UNKNOWN_MEMORY_PARTITION_MODE:
-       case AMDGPU_NPS1_PARTITION_MODE:
-               valid = (adev->gmc.num_mem_partitions == 1);
-               break;
-       case AMDGPU_NPS2_PARTITION_MODE:
-               valid = (adev->gmc.num_mem_partitions == 2);
-               break;
-       case AMDGPU_NPS4_PARTITION_MODE:
-               valid = (adev->gmc.num_mem_partitions == 3 ||
-                        adev->gmc.num_mem_partitions == 4);
-               break;
-       default:
-               valid = false;
-       }
-
-       return valid;
-}
-
-static bool gmc_v9_0_is_node_present(int *node_ids, int num_ids, int nid)
-{
-       int i;
-
-       /* Check if node with id 'nid' is present in 'node_ids' array */
-       for (i = 0; i < num_ids; ++i)
-               if (node_ids[i] == nid)
-                       return true;
-
-       return false;
-}
-
-static void
-gmc_v9_0_init_acpi_mem_ranges(struct amdgpu_device *adev,
-                             struct amdgpu_mem_partition_info *mem_ranges)
-{
-       struct amdgpu_numa_info numa_info;
-       int node_ids[AMDGPU_MAX_MEM_RANGES];
-       int num_ranges = 0, ret;
-       int num_xcc, xcc_id;
-       uint32_t xcc_mask;
-
-       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
-       xcc_mask = (1U << num_xcc) - 1;
-
-       for_each_inst(xcc_id, xcc_mask) {
-               ret = amdgpu_acpi_get_mem_info(adev, xcc_id, &numa_info);
-               if (ret)
-                       continue;
-
-               if (numa_info.nid == NUMA_NO_NODE) {
-                       mem_ranges[0].size = numa_info.size;
-                       mem_ranges[0].numa.node = numa_info.nid;
-                       num_ranges = 1;
-                       break;
-               }
-
-               if (gmc_v9_0_is_node_present(node_ids, num_ranges,
-                                            numa_info.nid))
-                       continue;
-
-               node_ids[num_ranges] = numa_info.nid;
-               mem_ranges[num_ranges].numa.node = numa_info.nid;
-               mem_ranges[num_ranges].size = numa_info.size;
-               ++num_ranges;
-       }
-
-       adev->gmc.num_mem_partitions = num_ranges;
-}
-
-static void
-gmc_v9_0_init_sw_mem_ranges(struct amdgpu_device *adev,
-                           struct amdgpu_mem_partition_info *mem_ranges)
-{
-       enum amdgpu_memory_partition mode;
-       u32 start_addr = 0, size;
-       int i, r, l;
-
-       mode = amdgpu_gmc_query_memory_partition(adev);
-
-       switch (mode) {
-       case UNKNOWN_MEMORY_PARTITION_MODE:
-               adev->gmc.num_mem_partitions = 0;
-               break;
-       case AMDGPU_NPS1_PARTITION_MODE:
-               adev->gmc.num_mem_partitions = 1;
-               break;
-       case AMDGPU_NPS2_PARTITION_MODE:
-               adev->gmc.num_mem_partitions = 2;
-               break;
-       case AMDGPU_NPS4_PARTITION_MODE:
-               if (adev->flags & AMD_IS_APU)
-                       adev->gmc.num_mem_partitions = 3;
-               else
-                       adev->gmc.num_mem_partitions = 4;
-               break;
-       default:
-               adev->gmc.num_mem_partitions = 1;
-               break;
-       }
-
-       /* Use NPS range info, if populated */
-       r = amdgpu_gmc_get_nps_memranges(adev, mem_ranges,
-                                        &adev->gmc.num_mem_partitions);
-       if (!r) {
-               l = 0;
-               for (i = 1; i < adev->gmc.num_mem_partitions; ++i) {
-                       if (mem_ranges[i].range.lpfn >
-                           mem_ranges[i - 1].range.lpfn)
-                               l = i;
-               }
-
-       } else {
-               if (!adev->gmc.num_mem_partitions) {
-                       dev_err(adev->dev,
-                               "Not able to detect NPS mode, fall back to NPS1");
-                       adev->gmc.num_mem_partitions = 1;
-               }
-               /* Fallback to sw based calculation */
-               size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
-               size /= adev->gmc.num_mem_partitions;
-
-               for (i = 0; i < adev->gmc.num_mem_partitions; ++i) {
-                       mem_ranges[i].range.fpfn = start_addr;
-                       mem_ranges[i].size =
-                               ((u64)size << AMDGPU_GPU_PAGE_SHIFT);
-                       mem_ranges[i].range.lpfn = start_addr + size - 1;
-                       start_addr += size;
-               }
-
-               l = adev->gmc.num_mem_partitions - 1;
-       }
-
-       /* Adjust the last one */
-       mem_ranges[l].range.lpfn =
-               (adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT) - 1;
-       mem_ranges[l].size =
-               adev->gmc.real_vram_size -
-               ((u64)mem_ranges[l].range.fpfn << AMDGPU_GPU_PAGE_SHIFT);
-}
-
-static int gmc_v9_0_init_mem_ranges(struct amdgpu_device *adev)
-{
-       bool valid;
-
-       adev->gmc.mem_partitions = kcalloc(AMDGPU_MAX_MEM_RANGES,
-                                          sizeof(struct amdgpu_mem_partition_info),
-                                          GFP_KERNEL);
-       if (!adev->gmc.mem_partitions)
-               return -ENOMEM;
-
-       /* TODO : Get the range from PSP/Discovery for dGPU */
-       if (adev->gmc.is_app_apu)
-               gmc_v9_0_init_acpi_mem_ranges(adev, adev->gmc.mem_partitions);
-       else
-               gmc_v9_0_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
-
-       if (amdgpu_sriov_vf(adev))
-               valid = true;
-       else
-               valid = gmc_v9_0_validate_partition_info(adev);
-       if (!valid) {
-               /* TODO: handle invalid case */
-               dev_WARN(adev->dev,
-                        "Mem ranges not matching with hardware config");
-       }
-
-       return 0;
-}
-
 static void gmc_v9_4_3_init_vram_info(struct amdgpu_device *adev)
 {
        adev->gmc.vram_type = AMDGPU_VRAM_TYPE_HBM;
@@ -2192,7 +2010,7 @@ static int gmc_v9_0_sw_init(struct amdgpu_ip_block *ip_block)
        amdgpu_gmc_get_vbios_allocations(adev);
 
        if (amdgpu_is_multi_aid(adev)) {
-               r = gmc_v9_0_init_mem_ranges(adev);
+               r = amdgpu_gmc_init_mem_ranges(adev);
                if (r)
                        return r;
        }
@@ -2474,7 +2292,7 @@ static int gmc_v9_0_resume(struct amdgpu_ip_block *ip_block)
         * information again.
         */
        if (adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS) {
-               gmc_v9_0_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
+               amdgpu_gmc_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);
                adev->gmc.reset_flags &= ~AMDGPU_GMC_INIT_RESET_NPS;
        }