tscan->amd_node_id = node_id;
 }
 
-static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
+static bool parse_8000_001e(struct topo_scan *tscan, bool has_topoext)
 {
        struct {
                // eax
         * topology_set_dom() would propagate and overwrite the already
         * propagated CORE level.
         */
-       if (!has_0xb) {
+       if (!has_topoext) {
                unsigned int nthreads = leaf.core_nthreads + 1;
 
                topology_update_dom(tscan, TOPO_SMT_DOMAIN, get_count_order(nthreads), nthreads);
 
 static void parse_topology_amd(struct topo_scan *tscan)
 {
-       bool has_0xb = false;
+       bool has_topoext = false;
 
        /*
         * If the extended topology leaf 0x8000_001e is available
-        * try to get SMT and CORE shift from leaf 0xb first, then
-        * try to get the CORE shift from leaf 0x8000_0008.
+        * try to get SMT, CORE, TILE, and DIE shifts from extended
+        * CPUID leaf 0x8000_0026 on supported processors first. If
+        * extended CPUID leaf 0x8000_0026 is not supported, try to
+        * get SMT and CORE shift from leaf 0xb first, then try to
+        * get the CORE shift from leaf 0x8000_0008.
         */
        if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
-               has_0xb = cpu_parse_topology_ext(tscan);
+               has_topoext = cpu_parse_topology_ext(tscan);
 
-       if (!has_0xb && !parse_8000_0008(tscan))
+       if (!has_topoext && !parse_8000_0008(tscan))
                return;
 
        /* Prefer leaf 0x8000001e if available */
-       if (parse_8000_001e(tscan, has_0xb))
+       if (parse_8000_001e(tscan, has_topoext))
                return;
 
        /* Try the NODEID MSR */
 
        CORE_TYPE               = 2,
        MAX_TYPE_0B             = 3,
        MODULE_TYPE             = 3,
+       AMD_CCD_TYPE            = 3,
        TILE_TYPE               = 4,
+       AMD_SOCKET_TYPE         = 4,
+       MAX_TYPE_80000026       = 5,
        DIE_TYPE                = 5,
        DIEGRP_TYPE             = 6,
        MAX_TYPE_1F             = 7,
        [DIEGRP_TYPE]   = TOPO_DIEGRP_DOMAIN,
 };
 
+static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
+       [SMT_TYPE]              = TOPO_SMT_DOMAIN,
+       [CORE_TYPE]             = TOPO_CORE_DOMAIN,
+       [AMD_CCD_TYPE]          = TOPO_TILE_DOMAIN,
+       [AMD_SOCKET_TYPE]       = TOPO_DIE_DOMAIN,
+};
+
 static inline bool topo_subleaf(struct topo_scan *tscan, u32 leaf, u32 subleaf,
                                unsigned int *last_dom)
 {
        switch (leaf) {
        case 0x0b: maxtype = MAX_TYPE_0B; map = topo_domain_map_0b_1f; break;
        case 0x1f: maxtype = MAX_TYPE_1F; map = topo_domain_map_0b_1f; break;
+       case 0x80000026: maxtype = MAX_TYPE_80000026; map = topo_domain_map_80000026; break;
        default: return false;
        }
 
        if (tscan->c->cpuid_level >= 0x1f && parse_topology_leaf(tscan, 0x1f))
                return true;
 
+       /* AMD: Try leaf 0x80000026 first. */
+       if (tscan->c->extended_cpuid_level >= 0x80000026 && parse_topology_leaf(tscan, 0x80000026))
+               return true;
+
        /* Intel/AMD: Fall back to leaf 0xB if available */
        return tscan->c->cpuid_level >= 0x0b && parse_topology_leaf(tscan, 0x0b);
 }