mb/ocp/tiogapass: Wait for BMC

The mainboard code relies on IPMI communication with the BMC.

Since the x86 and BMC start booting at the same time on ACPI G3
exit and the x86 is a bit faster, wait for the BMC to signal it's
done booting by pulling GPP_F4 low.

Fixes lots of error messages in coreboot about not working IPMI:
[ERROR]  wait_ibf timeout!
[ERROR]  IPMI START WRITE failed
[ERROR]  ipmi_kcs_send_message failed

TEST: Once GPP_F4 is low IPMI communication over the KCS is also
      working on ocp/tiogapass.
      The log contains the line:
      [DEBUG]  BMC ready after 125560 ms

Change-Id: I925aff1ff1ffd3d7388835e62aad2ba339e52472
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85492
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Patrick Rudolph 2024-12-04 12:53:14 +01:00 committed by Lean Sheng Tan
commit b659fb5cea
2 changed files with 29 additions and 1 deletions

View file

@ -5,6 +5,8 @@
#include <soc/gpio.h>
#define GPIO_BMC_READY_N GPP_F4
/* Pad configuration table for C621 Lewisburg PCH */
static const struct pad_config gpio_table[] = {
/* ------- GPIO Community 0 ------- */
@ -116,7 +118,7 @@ static const struct pad_config gpio_table[] = {
PAD_CFG_GPI_TRIG_OWN(GPP_F2, NONE, DEEP, OFF, DRIVER),
/* GPP_F3 - GPIO */
PAD_CFG_GPI_TRIG_OWN(GPP_F3, NONE, DEEP, OFF, DRIVER),
/* GPP_F4 - GPIO */
/* GPP_F4 - BMC_READY_N */
PAD_CFG_GPI_TRIG_OWN(GPP_F4, NONE, DEEP, OFF, DRIVER),
/* GPP_F5 - GPIO */
PAD_CFG_GPI_TRIG_OWN(GPP_F5, NONE, DEEP, OFF, DRIVER),

View file

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <delay.h>
#include <drivers/ipmi/ipmi_if.h>
#include <drivers/ipmi/ocp/ipmi_ocp.h>
#include <fsp/api.h>
@ -10,8 +11,10 @@
#include <soc/romstage.h>
#include <string.h>
#include <skxsp_tp_iio.h>
#include <timer.h>
#include "ipmi.h"
#include "tp_pch_gpio.h"
static uint8_t iio_table_buf[sizeof(tp_iio_bifur_table)];
@ -52,8 +55,31 @@ static void mainboard_config_iio(FSPM_UPD *mupd)
oem_update_iio(mupd);
}
static void mainboard_wait_for_bmc_ready(void)
{
struct stopwatch sw;
static const long timeout_ms = 300 * 1000;
printk(BIOS_DEBUG, "Waiting for BMC ready\n");
gpio_input(GPIO_BMC_READY_N);
stopwatch_init_msecs_expire(&sw, timeout_ms);
while (gpio_get(GPIO_BMC_READY_N)) {
if (stopwatch_expired(&sw)) {
printk(BIOS_WARNING,
"BMC not ready after %ld ms. Abort.\n", timeout_ms);
return;
}
}
printk(BIOS_DEBUG, "BMC ready after %lld ms\n",
stopwatch_duration_msecs(&sw));
}
void mainboard_memory_init_params(FSPM_UPD *mupd)
{
/* Need to wait for BMC ready so that IPMI works. */
mainboard_wait_for_bmc_ready();
/* It's better to run get BMC selftest result first */
if (ipmi_premem_init(CONFIG_BMC_KCS_BASE, 0) == CB_SUCCESS) {
ipmi_set_post_start(CONFIG_BMC_KCS_BASE);