drivers/ipmi: implement "POST complete" notification functionality
Some server boards like OCP Tiogapass and X11-LGA1151 boards use a gpio for signalling "POST complete" to BMC/IPMI. Add a new driver devicetree option to set the gpio and configure a callback that pulls the gpio low right before jumping to the payload. Test: Check that sensor readings appear in BMC web interface when the payload gets executed. Successfully tested on Supermicro X11SSM-F with CB:48097, X11SSH-TF with CB:48711 and OCP DeltaLake with CB:48672. Change-Id: I34764858be9c7f7f1110ce885fa056591164f148 Tested-by: Johnny Lin <Johnny_Lin@wiwynn.com> Tested-by: Michael Niewöhner <foss@mniewoehner.de> Tested-by: Patrick Rudolph <siro@das-labor.org> Signed-off-by: Michael Niewöhner <foss@mniewoehner.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/48096 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
parent
31830d3c2c
commit
548a3dc7a6
|
@ -22,6 +22,9 @@ struct drivers_ipmi_config {
|
||||||
* If present, the jumper overrides the devicetree.
|
* If present, the jumper overrides the devicetree.
|
||||||
*/
|
*/
|
||||||
u32 bmc_jumper_gpio;
|
u32 bmc_jumper_gpio;
|
||||||
|
/* "POST complete" GPIO and polarity */
|
||||||
|
u32 post_complete_gpio;
|
||||||
|
bool post_complete_invert;
|
||||||
/*
|
/*
|
||||||
* Wait for BMC to boot.
|
* Wait for BMC to boot.
|
||||||
* This can be used if the BMC takes a long time to boot after PoR:
|
* This can be used if the BMC takes a long time to boot after PoR:
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
|
#include <bootstate.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/gpio.h>
|
#include <device/gpio.h>
|
||||||
|
@ -34,6 +35,8 @@ static u8 ipmi_revision_minor = 0x0;
|
||||||
static u8 bmc_revision_major = 0x0;
|
static u8 bmc_revision_major = 0x0;
|
||||||
static u8 bmc_revision_minor = 0x0;
|
static u8 bmc_revision_minor = 0x0;
|
||||||
|
|
||||||
|
static struct boot_state_callback bscb_post_complete;
|
||||||
|
|
||||||
static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp)
|
static int ipmi_get_device_id(struct device *dev, struct ipmi_devid_rsp *rsp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -74,6 +77,26 @@ static int ipmi_get_bmc_self_test_result(struct device *dev, struct ipmi_selftes
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bmc_set_post_complete_gpio_callback(void *arg)
|
||||||
|
{
|
||||||
|
struct drivers_ipmi_config *conf = arg;
|
||||||
|
const struct gpio_operations *gpio_ops;
|
||||||
|
|
||||||
|
if (!conf || !conf->post_complete_gpio)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gpio_ops = dev_get_gpio_ops(conf->gpio_dev);
|
||||||
|
if (!gpio_ops) {
|
||||||
|
printk(BIOS_WARNING, "IPMI: specified gpio device is missing gpio ops!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set POST Complete pin. The `invert` field controls the polarity. */
|
||||||
|
gpio_ops->output(conf->post_complete_gpio, conf->post_complete_invert ^ 1);
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "BMC: POST complete gpio set\n");
|
||||||
|
}
|
||||||
|
|
||||||
static void ipmi_kcs_init(struct device *dev)
|
static void ipmi_kcs_init(struct device *dev)
|
||||||
{
|
{
|
||||||
struct ipmi_devid_rsp rsp;
|
struct ipmi_devid_rsp rsp;
|
||||||
|
@ -105,6 +128,13 @@ static void ipmi_kcs_init(struct device *dev)
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "IPMI: PNP KCS 0x%x\n", dev->path.pnp.port);
|
printk(BIOS_DEBUG, "IPMI: PNP KCS 0x%x\n", dev->path.pnp.port);
|
||||||
|
|
||||||
|
/* Set up boot state callback for POST_COMPLETE# */
|
||||||
|
if (conf->post_complete_gpio) {
|
||||||
|
bscb_post_complete.callback = bmc_set_post_complete_gpio_callback;
|
||||||
|
bscb_post_complete.arg = conf;
|
||||||
|
boot_state_sched_on_entry(&bscb_post_complete, BS_PAYLOAD_BOOT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get IPMI version for ACPI and SMBIOS */
|
/* Get IPMI version for ACPI and SMBIOS */
|
||||||
if (conf->wait_for_bmc && conf->bmc_boot_timeout) {
|
if (conf->wait_for_bmc && conf->bmc_boot_timeout) {
|
||||||
struct stopwatch sw;
|
struct stopwatch sw;
|
||||||
|
|
Loading…
Reference in New Issue