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>
This commit is contained in:
Felix Held 2020-05-20 02:34:59 +02:00 committed by Felix Held
parent b77b446ca8
commit 828ca06cdb
2 changed files with 188 additions and 17 deletions

View File

@ -11,12 +11,34 @@ enum socket_type {
SOCKET_FT5 = 3,
};
void print_socket_type(void);
enum silicon_type {
SILICON_RV1,
SILICON_PCO,
SILICON_RV2,
SILICON_UNKNOWN,
};
enum soc_type {
SOC_PICASSO,
SOC_DALI,
SOC_POLLOCK,
SOC_UNKNOWN,
};
enum socket_type get_socket_type(void);
enum silicon_type get_silicon_type(void);
enum soc_type get_soc_type(void);
void print_socket_type(void);
void print_silicon_type(void);
void print_soc_type(void);
/* functions to determine the connectivity feature set */
bool soc_is_pollock(void);
bool soc_is_dali(void);
bool soc_is_picasso(void);
/* function to determine the iGPU type */
bool soc_is_raven2(void);
bool soc_is_zen_plus(void);
#endif /* __PICASSO_SOC_UTIL_H__ */

View File

@ -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 == 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;
}
static bool is_fam17_2x(void)
{
/* mask lower model number nibble and stepping */
return cpuid_eax(1) >> 8 == RAVEN2_CPUID >> 8;
}
bool soc_is_zen_plus(void)
static bool is_fam17_20(void)
{
/* mask lower model number nibble and stepping */
return cpuid_eax(1) >> 8 == PICASSO_CPUID >> 8;
/* 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;
}