diff --git a/src/cpu/intel/haswell/Makefile.mk b/src/cpu/intel/haswell/Makefile.mk index 8b8e98600a..41ca9c9d98 100644 --- a/src/cpu/intel/haswell/Makefile.mk +++ b/src/cpu/intel/haswell/Makefile.mk @@ -5,6 +5,7 @@ bootblock-y += ../car/non-evict/cache_as_ram.S bootblock-y += ../car/bootblock.c bootblock-y += ../../x86/early_reset.S +romstage-y += pcode_mailbox.c romstage-y += romstage.c romstage-y += ../car/romstage.c @@ -12,6 +13,7 @@ postcar-y += ../car/non-evict/exit_car.S ramstage-y += acpi.c ramstage-y += haswell_init.c +ramstage-y += pcode_mailbox.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smmrelocate.c smm-y += finalize.c diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h index f63b0ef4b3..f42199de0a 100644 --- a/src/cpu/intel/haswell/haswell.h +++ b/src/cpu/intel/haswell/haswell.h @@ -171,6 +171,11 @@ int cpu_config_tdp_levels(void); void set_max_freq(void); +/* pcode_mailbox.c */ +int pcode_ready(void); +u32 pcode_mailbox_read(u32 command); +int pcode_mailbox_write(u32 command, u32 data); + /* CPU identification */ static inline u32 cpu_family_model(void) { diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index 86dcbea177..8232453a57 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -77,25 +77,11 @@ static const u8 power_limit_time_msr_to_sec[] = { [0x11] = 128, }; -/* The core 100MHz BCLK is disabled in deeper c-states. One needs to calibrate +/* + * The core 100MHz BCLK is disabled in deeper c-states. One needs to calibrate * the 100MHz BCLK against the 24MHz BCLK to restore the clocks properly - * when a core is woken up. */ -static int pcode_ready(void) -{ - int wait_count; - const int delay_step = 10; - - wait_count = 0; - do { - if (!(mchbar_read32(BIOS_MAILBOX_INTERFACE) & MAILBOX_RUN_BUSY)) - return 0; - wait_count += delay_step; - udelay(delay_step); - } while (wait_count < 1000); - - return -1; -} - + * when a core is woken up. + */ static void calibrate_24mhz_bclk(void) { int err_code; @@ -117,8 +103,7 @@ static void calibrate_24mhz_bclk(void) err_code = mchbar_read32(BIOS_MAILBOX_INTERFACE) & 0xff; - printk(BIOS_DEBUG, "PCODE: 24MHz BCLK calibration response: %d\n", - err_code); + printk(BIOS_DEBUG, "PCODE: 24MHz BCLK calibration response: %d\n", err_code); /* Read the calibrated value. */ mchbar_write32(BIOS_MAILBOX_INTERFACE, @@ -133,45 +118,6 @@ static void calibrate_24mhz_bclk(void) mchbar_read32(BIOS_MAILBOX_DATA)); } -static u32 pcode_mailbox_read(u32 command) -{ - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); - return 0; - } - - /* Send command and start transaction */ - mchbar_write32(BIOS_MAILBOX_INTERFACE, command | MAILBOX_RUN_BUSY); - - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); - return 0; - } - - /* Read mailbox */ - return mchbar_read32(BIOS_MAILBOX_DATA); -} - -static int pcode_mailbox_write(u32 command, u32 data) -{ - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); - return -1; - } - - mchbar_write32(BIOS_MAILBOX_DATA, data); - - /* Send command and start transaction */ - mchbar_write32(BIOS_MAILBOX_INTERFACE, command | MAILBOX_RUN_BUSY); - - if (pcode_ready() < 0) { - printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); - return -1; - } - - return 0; -} - static struct device *cpu_cluster; static void initialize_vr_config(void) diff --git a/src/cpu/intel/haswell/pcode_mailbox.c b/src/cpu/intel/haswell/pcode_mailbox.c new file mode 100644 index 0000000000..7d866466e7 --- /dev/null +++ b/src/cpu/intel/haswell/pcode_mailbox.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +#include "haswell.h" + +int pcode_ready(void) +{ + int wait_count; + const int delay_step = 10; + + wait_count = 0; + do { + if (!(mchbar_read32(BIOS_MAILBOX_INTERFACE) & MAILBOX_RUN_BUSY)) + return 0; + wait_count += delay_step; + udelay(delay_step); + } while (wait_count < 1000); + + return -1; +} + +u32 pcode_mailbox_read(u32 command) +{ + if (pcode_ready() < 0) { + printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); + return 0; + } + + /* Send command and start transaction */ + mchbar_write32(BIOS_MAILBOX_INTERFACE, command | MAILBOX_RUN_BUSY); + + if (pcode_ready() < 0) { + printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); + return 0; + } + + /* Read mailbox */ + return mchbar_read32(BIOS_MAILBOX_DATA); +} + +int pcode_mailbox_write(u32 command, u32 data) +{ + if (pcode_ready() < 0) { + printk(BIOS_ERR, "PCODE: mailbox timeout on wait ready.\n"); + return -1; + } + + mchbar_write32(BIOS_MAILBOX_DATA, data); + + /* Send command and start transaction */ + mchbar_write32(BIOS_MAILBOX_INTERFACE, command | MAILBOX_RUN_BUSY); + + if (pcode_ready() < 0) { + printk(BIOS_ERR, "PCODE: mailbox timeout on completion.\n"); + return -1; + } + + return 0; +}