aboutsummaryrefslogtreecommitdiff
path: root/src/soc/amd/picasso/soc_util.c
diff options
context:
space:
mode:
authorFelix Held <felix.held@amd.corp-partner.google.com>2020-05-20 02:34:59 +0200
committerFelix Held <felix-coreboot@felixheld.de>2020-05-27 15:56:29 +0000
commit828ca06cdbedacb41f73dc70bf18262031f7ad90 (patch)
tree01f01d20ed60cf4963bb3f02387f0fa349553cac /src/soc/amd/picasso/soc_util.c
parentb77b446ca8cbca1a5e56570b94e24a57b9889554 (diff)
soc/amd/picasso: rewrite soc_util
This adds proper RV2 silicon and Dali SKU detection using both CPUID information and some bits from silicon_id in the Picasso misc data HOB that FSP-M stores in memory. BUG=b:153779573 Change-Id: I589be3bdac4b94785e6ecacf55235be4ad5673d9 Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41630 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
Diffstat (limited to 'src/soc/amd/picasso/soc_util.c')
-rw-r--r--src/soc/amd/picasso/soc_util.c179
1 files changed, 164 insertions, 15 deletions
diff --git a/src/soc/amd/picasso/soc_util.c b/src/soc/amd/picasso/soc_util.c
index 89aa0a40ff..70cc578ec9 100644
--- a/src/soc/amd/picasso/soc_util.c
+++ b/src/soc/amd/picasso/soc_util.c
@@ -2,6 +2,9 @@
#include <arch/cpu.h>
#include <console/console.h>
+#include <FspGuids.h>
+#include <fsp/util.h>
+#include <misc_data.h>
#include <soc/cpu.h>
#include <soc/soc_util.h>
#include <types.h>
@@ -9,7 +12,7 @@
#define SOCKET_TYPE_SHIFT 28
#define SOCKET_TYPSE_MASK (0xf << SOCKET_TYPE_SHIFT)
-static enum socket_type get_socket_type(void)
+enum socket_type get_socket_type(void)
{
uint32_t ebx = cpuid_ebx(0x80000001);
ebx = (ebx & SOCKET_TYPSE_MASK) >> SOCKET_TYPE_SHIFT;
@@ -37,33 +40,179 @@ void print_socket_type(void)
}
}
-bool soc_is_pollock(void)
+/* returns 0 in case or errors */
+static uint32_t get_internal_silicon_type(void)
{
- return soc_is_zen_plus() && get_socket_type() == SOCKET_FT5;
+ static uint32_t silicon_type;
+ size_t hob_size = 0;
+ const struct picasso_misc_data *hob;
+
+ if (silicon_type)
+ return silicon_type;
+
+ hob = fsp_find_extension_hob_by_guid(PICASSO_MISC_DATA_HOB_GUID.b, &hob_size);
+
+ if (hob == NULL || hob_size == 0) {
+ printk(BIOS_ERR, "Couldn't find Picasso misc data HOB.\n");
+ return 0;
+ }
+
+ if (hob->version != PICASSO_MISC_DATA_VERSION) {
+ printk(BIOS_ERR, "Unexpected Picasso misc data HOB version.\n");
+ return 0;
+ }
+
+ silicon_type = hob->silicon_id;
+
+ printk(BIOS_DEBUG, "Silicon ID = 0x%x\n", silicon_type);
+
+ return silicon_type;
}
-/*
- * TODO: This detection works for the Dali SKUs used in Chrome-devices, but fails for other
- * Dali SKUs, since other Dali SKUs have a Zen+ CPUID and not a Raven2 one.
- */
-bool soc_is_dali(void)
+#define SILICON_IS_MYSTERY_MEAT (1 << 31)
+#define SILICON_IS_RV2 (1 << 30)
+
+static bool is_rv2_silicon(void)
{
- return soc_is_raven2() && get_socket_type() == SOCKET_FP5;
+ return get_internal_silicon_type() & SILICON_IS_RV2;
}
-bool soc_is_picasso(void)
+static bool is_mystery_silicon(void)
{
- return soc_is_zen_plus() && get_socket_type() == SOCKET_FP5;
+ return get_internal_silicon_type() & SILICON_IS_MYSTERY_MEAT;
}
-bool soc_is_raven2(void)
+static bool is_fam17_1x(void)
{
/* mask lower model number nibble and stepping */
- return cpuid_eax(1) >> 8 == RAVEN2_CPUID >> 8;
+ return cpuid_eax(1) >> 8 == PICASSO_CPUID >> 8;
+}
+
+static bool is_fam17_11(void)
+{
+ /* only mask stepping */
+ return cpuid_eax(1) >> 4 == RAVEN1_CPUID >> 4;
+}
+
+static bool is_fam17_18(void)
+{
+ /* only mask stepping */
+ return cpuid_eax(1) >> 4 == PICASSO_CPUID >> 4;
}
-bool soc_is_zen_plus(void)
+static bool is_fam17_2x(void)
{
/* mask lower model number nibble and stepping */
- return cpuid_eax(1) >> 8 == PICASSO_CPUID >> 8;
+ return cpuid_eax(1) >> 8 == RAVEN2_CPUID >> 8;
+}
+
+static bool is_fam17_20(void)
+{
+ /* only mask stepping */
+ return cpuid_eax(1) >> 4 == RAVEN2_A1_CPUID >> 4;
+}
+
+enum silicon_type get_silicon_type(void)
+{
+ /*
+ * RV2 is fam17_20, but might return a fam17_1x CPUID in the is_mystery_silicon() case.
+ * is_rv2_silicon() has the correct information, but requires the HOB to be present.
+ */
+ if (is_fam17_20() || is_rv2_silicon())
+ return SILICON_RV2;
+
+ if (is_fam17_18() && !is_rv2_silicon())
+ return SILICON_PCO;
+
+ if (is_fam17_11() && !is_rv2_silicon())
+ return SILICON_RV1;
+
+ /* some cases might still be missing */
+
+ return SILICON_UNKNOWN;
+}
+
+enum soc_type get_soc_type(void)
+{
+ switch (get_socket_type()) {
+ case SOCKET_FP5:
+ if (is_fam17_1x() && !is_mystery_silicon())
+ return SOC_PICASSO;
+
+ if (is_fam17_2x() || (is_fam17_1x() && is_mystery_silicon()))
+ return SOC_DALI;
+
+ break;
+ case SOCKET_FT5:
+ /* add is_fam17_20() CPUID sanity check here? */
+ return SOC_POLLOCK;
+ break;
+ case SOCKET_AM4:
+ /* AM4 SoC type detection logic not implemented */
+ break;
+ }
+
+ return SOC_UNKNOWN;
+}
+
+void print_silicon_type(void)
+{
+ const enum silicon_type silicon = get_silicon_type();
+
+ printk(BIOS_INFO, "Silicon type: ");
+
+ switch (silicon) {
+ case SILICON_RV1:
+ printk(BIOS_INFO, "RV1\n");
+ break;
+ case SILICON_PCO:
+ printk(BIOS_INFO, "PCO\n");
+ break;
+ case SILICON_RV2:
+ printk(BIOS_INFO, "RV2\n");
+ break;
+ default:
+ printk(BIOS_INFO, "unknown\n");
+ }
+}
+
+void print_soc_type(void)
+{
+ const enum soc_type soc = get_soc_type();
+
+ printk(BIOS_INFO, "SoC type: ");
+
+ switch (soc) {
+ case SOC_PICASSO:
+ printk(BIOS_INFO, "Picasso\n");
+ break;
+ case SOC_DALI:
+ printk(BIOS_INFO, "Dali\n");
+ break;
+ case SOC_POLLOCK:
+ printk(BIOS_INFO, "Pollock\n");
+ break;
+ default:
+ printk(BIOS_INFO, "unknown\n");
+ }
+}
+
+bool soc_is_pollock(void)
+{
+ return get_soc_type() == SOC_POLLOCK;
+}
+
+bool soc_is_dali(void)
+{
+ return get_soc_type() == SOC_DALI;
+}
+
+bool soc_is_picasso(void)
+{
+ return get_soc_type() == SOC_PICASSO;
+}
+
+bool soc_is_raven2(void)
+{
+ return get_silicon_type() == SILICON_RV2;
}