blob: 3cbd8eb20f6ee849c4124f52813ef10ac05050a8 [file] [log] [blame]
Martin Roth97bd2a72020-02-17 13:17:19 -07001/* SPDX-License-Identifier: GPL-2.0-only */
Martin Roth97bd2a72020-02-17 13:17:19 -07002
Felix Heldbf213082020-05-18 20:27:04 +02003#include <console/console.h>
Elyes Haouasf743e0c2022-10-31 13:46:00 +01004#include <cpu/cpu.h>
Felix Held828ca062020-05-20 02:34:59 +02005#include <fsp/util.h>
Elyes Haouasf743e0c2022-10-31 13:46:00 +01006#include <FspGuids.h>
Felix Held828ca062020-05-20 02:34:59 +02007#include <misc_data.h>
Martin Roth97bd2a72020-02-17 13:17:19 -07008#include <soc/cpu.h>
9#include <soc/soc_util.h>
Felix Heldbf213082020-05-18 20:27:04 +020010#include <types.h>
11
Felix Heldaf05c862020-06-26 19:15:43 +020012/*
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.
18 */
19
Felix Heldbf213082020-05-18 20:27:04 +020020#define SOCKET_TYPE_SHIFT 28
Angel Pons6ca33752021-03-18 00:58:26 +010021#define SOCKET_TYPE_MASK (0xf << SOCKET_TYPE_SHIFT)
Felix Heldbf213082020-05-18 20:27:04 +020022
Felix Held3c93b7e2020-05-27 23:25:38 +020023/* some Pollock engineering samples return the wrong socket type */
Felix Held828ca062020-05-20 02:34:59 +020024enum socket_type get_socket_type(void)
Felix Heldbf213082020-05-18 20:27:04 +020025{
26 uint32_t ebx = cpuid_ebx(0x80000001);
Angel Pons6ca33752021-03-18 00:58:26 +010027 ebx = (ebx & SOCKET_TYPE_MASK) >> SOCKET_TYPE_SHIFT;
Felix Heldbf213082020-05-18 20:27:04 +020028 return (enum socket_type)ebx;
29}
30
31void print_socket_type(void)
32{
33 enum socket_type socket = get_socket_type();
34
35 printk(BIOS_INFO, "Socket type: ");
36
37 switch (socket) {
38 case SOCKET_FP5:
39 printk(BIOS_INFO, "FP5\n");
40 break;
41 case SOCKET_AM4:
42 printk(BIOS_INFO, "AM4\n");
43 break;
44 case SOCKET_FT5:
45 printk(BIOS_INFO, "FT5\n");
46 break;
47 default:
48 printk(BIOS_INFO, "unknown\n");
49 }
50}
Martin Roth97bd2a72020-02-17 13:17:19 -070051
Felix Held828ca062020-05-20 02:34:59 +020052/* returns 0 in case or errors */
53static uint32_t get_internal_silicon_type(void)
Martin Roth97bd2a72020-02-17 13:17:19 -070054{
Felix Held828ca062020-05-20 02:34:59 +020055 static uint32_t silicon_type;
56 size_t hob_size = 0;
57 const struct picasso_misc_data *hob;
58
59 if (silicon_type)
60 return silicon_type;
61
62 hob = fsp_find_extension_hob_by_guid(PICASSO_MISC_DATA_HOB_GUID.b, &hob_size);
63
64 if (hob == NULL || hob_size == 0) {
65 printk(BIOS_ERR, "Couldn't find Picasso misc data HOB.\n");
66 return 0;
67 }
68
69 if (hob->version != PICASSO_MISC_DATA_VERSION) {
70 printk(BIOS_ERR, "Unexpected Picasso misc data HOB version.\n");
71 return 0;
72 }
73
74 silicon_type = hob->silicon_id;
75
76 printk(BIOS_DEBUG, "Silicon ID = 0x%x\n", silicon_type);
77
78 return silicon_type;
Martin Roth97bd2a72020-02-17 13:17:19 -070079}
80
Felix Held828ca062020-05-20 02:34:59 +020081#define SILICON_IS_MYSTERY_MEAT (1 << 31)
82#define SILICON_IS_RV2 (1 << 30)
83
84static bool is_rv2_silicon(void)
Martin Roth97bd2a72020-02-17 13:17:19 -070085{
Felix Held828ca062020-05-20 02:34:59 +020086 return get_internal_silicon_type() & SILICON_IS_RV2;
Martin Roth97bd2a72020-02-17 13:17:19 -070087}
88
Felix Held828ca062020-05-20 02:34:59 +020089static bool is_mystery_silicon(void)
Martin Roth97bd2a72020-02-17 13:17:19 -070090{
Felix Held828ca062020-05-20 02:34:59 +020091 return get_internal_silicon_type() & SILICON_IS_MYSTERY_MEAT;
Martin Roth97bd2a72020-02-17 13:17:19 -070092}
93
Felix Held828ca062020-05-20 02:34:59 +020094static bool is_fam17_1x(void)
95{
Felix Heldb6969db2023-02-06 19:47:11 +010096 return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID,
97 CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK);
Felix Held828ca062020-05-20 02:34:59 +020098}
99
100static bool is_fam17_11(void)
101{
Felix Heldb6969db2023-02-06 19:47:11 +0100102 return cpuid_match(cpuid_eax(1), RAVEN1_B0_CPUID, CPUID_ALL_STEPPINGS_MASK);
Felix Held828ca062020-05-20 02:34:59 +0200103}
104
105static bool is_fam17_18(void)
106{
Felix Heldb6969db2023-02-06 19:47:11 +0100107 return cpuid_match(cpuid_eax(1), PICASSO_B0_CPUID, CPUID_ALL_STEPPINGS_MASK);
Felix Held828ca062020-05-20 02:34:59 +0200108}
109
110static bool is_fam17_2x(void)
Martin Roth97bd2a72020-02-17 13:17:19 -0700111{
Felix Heldb6969db2023-02-06 19:47:11 +0100112 return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID,
113 CPUID_ALL_STEPPINGS_AND_BASE_MODELS_MASK);
Martin Roth97bd2a72020-02-17 13:17:19 -0700114}
115
Felix Held828ca062020-05-20 02:34:59 +0200116static bool is_fam17_20(void)
Martin Roth97bd2a72020-02-17 13:17:19 -0700117{
Felix Heldb6969db2023-02-06 19:47:11 +0100118 return cpuid_match(cpuid_eax(1), RAVEN2_A0_CPUID, CPUID_ALL_STEPPINGS_MASK);
Felix Held828ca062020-05-20 02:34:59 +0200119}
120
121enum silicon_type get_silicon_type(void)
122{
123 /*
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.
126 */
127 if (is_fam17_20() || is_rv2_silicon())
128 return SILICON_RV2;
129
130 if (is_fam17_18() && !is_rv2_silicon())
131 return SILICON_PCO;
132
133 if (is_fam17_11() && !is_rv2_silicon())
134 return SILICON_RV1;
135
136 /* some cases might still be missing */
137
138 return SILICON_UNKNOWN;
139}
140
Felix Held3c93b7e2020-05-27 23:25:38 +0200141/* some Pollock engineering samples return the wrong socket type and get detected as Dali */
Felix Held828ca062020-05-20 02:34:59 +0200142enum soc_type get_soc_type(void)
143{
144 switch (get_socket_type()) {
145 case SOCKET_FP5:
146 if (is_fam17_1x() && !is_mystery_silicon())
147 return SOC_PICASSO;
148
149 if (is_fam17_2x() || (is_fam17_1x() && is_mystery_silicon()))
150 return SOC_DALI;
151
152 break;
153 case SOCKET_FT5:
154 /* add is_fam17_20() CPUID sanity check here? */
155 return SOC_POLLOCK;
Felix Held828ca062020-05-20 02:34:59 +0200156 case SOCKET_AM4:
157 /* AM4 SoC type detection logic not implemented */
158 break;
159 }
160
161 return SOC_UNKNOWN;
162}
163
164void print_silicon_type(void)
165{
166 const enum silicon_type silicon = get_silicon_type();
167
168 printk(BIOS_INFO, "Silicon type: ");
169
170 switch (silicon) {
171 case SILICON_RV1:
172 printk(BIOS_INFO, "RV1\n");
173 break;
174 case SILICON_PCO:
175 printk(BIOS_INFO, "PCO\n");
176 break;
177 case SILICON_RV2:
178 printk(BIOS_INFO, "RV2\n");
179 break;
180 default:
181 printk(BIOS_INFO, "unknown\n");
182 }
183}
184
185void print_soc_type(void)
186{
187 const enum soc_type soc = get_soc_type();
188
189 printk(BIOS_INFO, "SoC type: ");
190
191 switch (soc) {
192 case SOC_PICASSO:
193 printk(BIOS_INFO, "Picasso\n");
194 break;
195 case SOC_DALI:
196 printk(BIOS_INFO, "Dali\n");
197 break;
198 case SOC_POLLOCK:
199 printk(BIOS_INFO, "Pollock\n");
200 break;
201 default:
202 printk(BIOS_INFO, "unknown\n");
203 }
204}
205
Felix Held42b0e8f2020-06-26 18:03:53 +0200206bool soc_is_reduced_io_sku(void)
Felix Held828ca062020-05-20 02:34:59 +0200207{
Felix Held42b0e8f2020-06-26 18:03:53 +0200208 return get_silicon_type() == SILICON_RV2 || get_soc_type() == SOC_DALI;
Felix Held828ca062020-05-20 02:34:59 +0200209}
210
Felix Held828ca062020-05-20 02:34:59 +0200211bool soc_is_raven2(void)
212{
213 return get_silicon_type() == SILICON_RV2;
Martin Roth97bd2a72020-02-17 13:17:19 -0700214}