1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
9 #include <soc/soc_util.h>
13 * The Zen/Zen+ based APUs can be RV (sometimes called RV1), PCO or RV2 silicon. RV2 has less
14 * PCIe, USB3 and DisplayPort connectivity than RV(1) or PCO. A Picasso SoC is always PCO
15 * silicon, a Dali SoC can either be RV2 or fused-down PCO silicon that has the same
16 * connectivity as the RV2 one and Pollock is always RV2 silicon. Picasso and Dali are in a FP5
17 * package while Pollock is in the smaller FT5 package.
20 #define SOCKET_TYPE_SHIFT 28
21 #define SOCKET_TYPE_MASK (0xf << SOCKET_TYPE_SHIFT)
23 /* some Pollock engineering samples return the wrong socket type */
24 enum socket_type
get_socket_type(void)
26 uint32_t ebx
= cpuid_ebx(0x80000001);
27 ebx
= (ebx
& SOCKET_TYPE_MASK
) >> SOCKET_TYPE_SHIFT
;
28 return (enum socket_type
)ebx
;
31 void print_socket_type(void)
33 enum socket_type socket
= get_socket_type();
35 printk(BIOS_INFO
, "Socket type: ");
39 printk(BIOS_INFO
, "FP5\n");
42 printk(BIOS_INFO
, "AM4\n");
45 printk(BIOS_INFO
, "FT5\n");
48 printk(BIOS_INFO
, "unknown\n");
52 /* returns 0 in case or errors */
53 static uint32_t get_internal_silicon_type(void)
55 static uint32_t silicon_type
;
57 const struct picasso_misc_data
*hob
;
62 hob
= fsp_find_extension_hob_by_guid(PICASSO_MISC_DATA_HOB_GUID
.b
, &hob_size
);
64 if (hob
== NULL
|| hob_size
== 0) {
65 printk(BIOS_ERR
, "Couldn't find Picasso misc data HOB.\n");
69 if (hob
->version
!= PICASSO_MISC_DATA_VERSION
) {
70 printk(BIOS_ERR
, "Unexpected Picasso misc data HOB version.\n");
74 silicon_type
= hob
->silicon_id
;
76 printk(BIOS_DEBUG
, "Silicon ID = 0x%x\n", silicon_type
);
81 #define SILICON_IS_MYSTERY_MEAT (1 << 31)
82 #define SILICON_IS_RV2 (1 << 30)
84 static bool is_rv2_silicon(void)
86 return get_internal_silicon_type() & SILICON_IS_RV2
;
89 static bool is_mystery_silicon(void)
91 return get_internal_silicon_type() & SILICON_IS_MYSTERY_MEAT
;
94 static bool is_fam17_1x(void)
96 return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID
,
97 CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK
);
100 static bool is_fam17_11(void)
102 return cpuid_match(cpuid_eax(1), RAVEN1_B0_CPUID
, CPUID_ALL_STEPPINGS_MASK
);
105 static bool is_fam17_18(void)
107 return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID
, CPUID_ALL_STEPPINGS_MASK
);
110 static bool is_fam17_2x(void)
112 return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID
,
113 CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK
);
116 static bool is_fam17_20(void)
118 return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID
, CPUID_ALL_STEPPINGS_MASK
);
121 enum silicon_type
get_silicon_type(void)
124 * RV2 is fam17_20, but might return a fam17_1x CPUID in the is_mystery_silicon() case.
125 * is_rv2_silicon() has the correct information, but requires the HOB to be present.
127 if (is_fam17_20() || is_rv2_silicon())
130 if (is_fam17_18() && !is_rv2_silicon())
133 if (is_fam17_11() && !is_rv2_silicon())
136 /* some cases might still be missing */
138 return SILICON_UNKNOWN
;
141 /* some Pollock engineering samples return the wrong socket type and get detected as Dali */
142 enum soc_type
get_soc_type(void)
144 switch (get_socket_type()) {
146 if (is_fam17_1x() && !is_mystery_silicon())
149 if (is_fam17_2x() || (is_fam17_1x() && is_mystery_silicon()))
154 /* add is_fam17_20() CPUID sanity check here? */
157 /* AM4 SoC type detection logic not implemented */
164 void print_silicon_type(void)
166 const enum silicon_type silicon
= get_silicon_type();
168 printk(BIOS_INFO
, "Silicon type: ");
172 printk(BIOS_INFO
, "RV1\n");
175 printk(BIOS_INFO
, "PCO\n");
178 printk(BIOS_INFO
, "RV2\n");
181 printk(BIOS_INFO
, "unknown\n");
185 void print_soc_type(void)
187 const enum soc_type soc
= get_soc_type();
189 printk(BIOS_INFO
, "SoC type: ");
193 printk(BIOS_INFO
, "Picasso\n");
196 printk(BIOS_INFO
, "Dali\n");
199 printk(BIOS_INFO
, "Pollock\n");
202 printk(BIOS_INFO
, "unknown\n");
206 bool soc_is_reduced_io_sku(void)
208 return get_silicon_type() == SILICON_RV2
|| get_soc_type() == SOC_DALI
;
211 bool soc_is_raven2(void)
213 return get_silicon_type() == SILICON_RV2
;