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:
parent
b77b446ca8
commit
828ca06cdb
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue