Add support for latest AMD Zen5 CPU (Ryzen 9000)

Change DDR5 SPD Bank switch method on AMD according to feedbacks from betatesters
This commit is contained in:
Sam Demeulemeester 2024-11-10 23:45:49 +01:00
parent 0736cf2112
commit 46e3b43859
4 changed files with 50 additions and 13 deletions

View File

@ -361,7 +361,23 @@ static void determine_imc(void)
}
break;
case 0xB:
imc.family = IMC_K19_GRG; // Zen5 APU (Family 19h - Granite Ridge)
switch(cpuid_info.version.extendedModel) {
case 2:
imc.family = IMC_K1A_STP; // Zen5 APU (Family 1Ah - Strix Point)
break;
case 4:
imc.family = IMC_K1A_GRG; // Zen5 CPU (Family 1Ah - Granite Ridge)
break;
case 6:
imc.family = IMC_K1A_KRN; // Zen5 APU (Family 1Ah - Krackan)
break;
case 7:
imc.family = IMC_K1A_STH; // Zen5 APU (Family 1Ah - Strix Halo)
break;
case 8:
imc.family = IMC_K1A_MDS; // Zen6 CPU (Family 1Ah - Medusa)
break;
}
break;
default:
break;

View File

@ -73,7 +73,12 @@
#define IMC_K19_RPL 0x8110 // Zen4 (Raphael)
#define IMC_K19_PHX 0x8120 // Zen4 (Phoenix)
#define IMC_K19_STK 0x81A0 // Zen4 (Storm Peak)
#define IMC_K19_GRG 0x8150 // Zen5 (Granite Ridge)
#define IMC_K1A_STP 0x8200 // Zen5 (Strix Point)
#define IMC_K1A_GRG 0x8210 // Zen5 (Granite Ridge)
#define IMC_K1A_KRN 0x8220 // Zen5 (Krackan)
#define IMC_K1A_STH 0x8230 // Zen5 (Strix Halo)
#define IMC_K1A_MDS 0x8240 // Zen6 (Medusa)
#define IMC_LSLA 0xC000 // Loongson LoongArch family
#define IMC_LA464 0xC010 // LA464 (Loongson 3th Gen)

View File

@ -446,7 +446,7 @@ static bool fch_zen_get_smb(void)
pm_reg |= __inb(AMD_DATA_IO_PORT);
// Special case for AMD Family 19h & Extended Model > 4 (get smb address in memory)
if ((imc.family == IMC_K19_CZN || imc.family == IMC_K19_RPL) && pm_reg == 0xFFFF) {
if ((imc.family == IMC_K19_CZN || imc.family == IMC_K19_RPL || imc.family >= IMC_K1A_STP) && pm_reg == 0xFFFF) {
smbusbase = ((*(const uint32_t *)(0xFED80000 + 0x300) >> 8) & 0xFF) << 8;
return true;
}
@ -555,7 +555,7 @@ static uint8_t ich5_read_spd_byte(uint8_t smbus_adr, uint16_t spd_adr)
__outb((0x37 << 1) | I2C_WRITE, SMBHSTADD);
__outb(SMBHSTCNT_BYTE_DATA, SMBHSTCNT);
ich5_process(); // return should 0x42 or 0x44
ich5_process(); // return should be 0x42 or 0x44
spd_page = 1;
} else if (spd_adr <= 0xFF && spd_page != 0) {
@ -575,17 +575,32 @@ static uint8_t ich5_read_spd_byte(uint8_t smbus_adr, uint16_t spd_adr)
if (adr_page != spd_page || last_adr != smbus_adr) {
__outb((smbus_adr << 1) | I2C_READ, SMBHSTADD);
__outb(SPD5_MR11 & 0x7F, SMBHSTCMD);
__outb(adr_page & 7, SMBHSTDAT0);
__outb(0, SMBHSTDAT1);
__outb(SMBHSTCNT_PROC_CALL, SMBHSTCNT);
// DDR5 SPD Bank switch can be achieved using 2 methods
if(((smbus_id >> 16) & 0xFFFF) == PCI_VID_INTEL) {
// On Intel, we use the process call method because the SMBUS write command
// is sometimes disabled by BIOS to avoid unexpected SPD corruption
__outb((smbus_adr << 1) | I2C_READ, SMBHSTADD);
__outb(SPD5_MR11 & 0x7F, SMBHSTCMD);
__outb(adr_page & 7, SMBHSTDAT0);
__outb(0, SMBHSTDAT1);
__outb(SMBHSTCNT_PROC_CALL, SMBHSTCNT);
ich5_process();
ich5_process();
// These dummy read are mandatory to finish a Proc Call
__inb(SMBHSTDAT0);
__inb(SMBHSTDAT1);
// These dummy read are mandatory to terminate a Proc Call
__inb(SMBHSTDAT0);
__inb(SMBHSTDAT1);
} else {
// On AMD, we continue to use the standard smbus write command as it seems
// more reliable than the process call method. This may be reevaluated later.
__outb((smbus_adr << 1) | I2C_WRITE, SMBHSTADD);
__outb(SPD5_MR11 & 0x7F, SMBHSTCMD);
__outb(adr_page & 7, SMBHSTDAT0);
__outb(SMBHSTCNT_BYTE_DATA, SMBHSTCNT);
ich5_process();
}
spd_page = adr_page;
last_adr = smbus_adr;

View File

@ -37,6 +37,7 @@ void memctrl_init(void)
case IMC_K19_VRM:
case IMC_K19_RPL:
case IMC_K19_RBT:
case IMC_K1A_GRG:
get_imc_config_amd_zen();
break;
case IMC_SNB: