From 46e3b43859831d7b5de4e7f1ef82f5b48dc48416 Mon Sep 17 00:00:00 2001 From: Sam Demeulemeester Date: Sun, 10 Nov 2024 23:45:49 +0100 Subject: [PATCH] Add support for latest AMD Zen5 CPU (Ryzen 9000) Change DDR5 SPD Bank switch method on AMD according to feedbacks from betatesters --- system/cpuinfo.c | 18 +++++++++++++++++- system/cpuinfo.h | 7 ++++++- system/i2c_x86.c | 37 ++++++++++++++++++++++++++----------- system/memctrl.c | 1 + 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/system/cpuinfo.c b/system/cpuinfo.c index a560cc4..d06001b 100644 --- a/system/cpuinfo.c +++ b/system/cpuinfo.c @@ -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; diff --git a/system/cpuinfo.h b/system/cpuinfo.h index db94761..2bc6052 100644 --- a/system/cpuinfo.h +++ b/system/cpuinfo.h @@ -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) diff --git a/system/i2c_x86.c b/system/i2c_x86.c index 33089a9..4ef4a0b 100644 --- a/system/i2c_x86.c +++ b/system/i2c_x86.c @@ -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; diff --git a/system/memctrl.c b/system/memctrl.c index 52f9946..b9e6964 100644 --- a/system/memctrl.c +++ b/system/memctrl.c @@ -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: