samples: drivers: espi: Showcase eSPI OOB channel APIs

Add sample usage for eSPI OOB driver transactions

Signed-off-by: Jose Alberto Meza <jose.a.meza.arellano@intel.com>
This commit is contained in:
Jose Alberto Meza 2020-01-07 18:43:40 -08:00 committed by Anas Nashif
commit d23c570644

View file

@ -6,11 +6,24 @@
#include <errno.h>
#include <zephyr.h>
#include <sys/printk.h>
#include <device.h>
#include <soc.h>
#include <drivers/gpio.h>
#include <drivers/espi.h>
#include <logging/log_ctrl.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(espi, CONFIG_ESPI_LOG_LEVEL);
#define DEST_SLV_ADDR 0x02
#define SRC_SLV_ADDR 0x21
#define OOB_CMDCODE 0x01
struct oob_header {
u8_t dest_slave_addr;
u8_t oob_cmd_code;
u8_t byte_cnt;
u8_t src_slave_addr;
};
#ifdef CONFIG_ESPI_GPIO_DEV_NEEDED
static struct device *gpio_dev0;
@ -19,7 +32,6 @@ static struct device *gpio_dev1;
#endif
static struct device *espi_dev;
static struct espi_callback espi_bus_cb;
static struct espi_callback vw_rdy_cb;
static struct espi_callback vw_cb;
@ -31,7 +43,7 @@ static void espi_reset_handler(struct device *dev,
struct espi_event event)
{
if (event.evt_type == ESPI_BUS_RESET) {
printk("\neSPI BUS reset %d", event.evt_data);
LOG_INF("\neSPI BUS reset %d", event.evt_data);
}
}
@ -41,7 +53,7 @@ static void espi_ch_handler(struct device *dev, struct espi_callback *cb,
{
if (event.evt_type == ESPI_BUS_EVENT_CHANNEL_READY) {
if (event.evt_details == ESPI_CHANNEL_VWIRE) {
printk("\nVW channel is ready\n");
LOG_INF("\nVW channel is ready");
}
}
}
@ -52,7 +64,7 @@ static void vwire_handler(struct device *dev, struct espi_callback *cb,
{
if (event.evt_type == ESPI_BUS_EVENT_VWIRE_RECEIVED) {
if (event.evt_details == ESPI_VWIRE_SIGNAL_PLTRST) {
printk("\nPLT_RST changed %d\n", event.evt_data);
LOG_INF("\nPLT_RST changed %d\n", event.evt_data);
}
}
}
@ -68,14 +80,15 @@ static void periph_handler(struct device *dev, struct espi_callback *cb,
switch (peripheral) {
case ESPI_PERIPHERAL_DEBUG_PORT80:
printk("Postcode %x\n", event.evt_data);
LOG_INF("Postcode %x\n", event.evt_data);
break;
case ESPI_PERIPHERAL_HOST_IO:
printk("ACPI %x\n", event.evt_data);
LOG_INF("ACPI %x\n", event.evt_data);
espi_remove_callback(espi_dev, &p80_cb);
break;
default:
printk("\n%s periph 0x%x [%x]\n", __func__, peripheral,
event.evt_data);
LOG_INF("\n%s periph 0x%x [%x]\n", __func__, peripheral,
event.evt_data);
}
}
}
@ -94,12 +107,12 @@ int espi_init(void)
ret = espi_config(espi_dev, &cfg);
if (ret) {
printk("Failed to configure eSPI slave! error (%d)\n", ret);
LOG_INF("Failed to configure eSPI slave! error (%d)\n", ret);
} else {
printk("eSPI slave configured successfully!\n");
LOG_INF("eSPI slave configured successfully!");
}
printk("eSPI test - callbacks initialization... ");
LOG_INF("eSPI test - callbacks initialization... ");
espi_init_callback(&espi_bus_cb, espi_reset_handler, ESPI_BUS_RESET);
espi_init_callback(&vw_rdy_cb, espi_ch_handler,
ESPI_BUS_EVENT_CHANNEL_READY);
@ -107,14 +120,14 @@ int espi_init(void)
ESPI_BUS_EVENT_VWIRE_RECEIVED);
espi_init_callback(&p80_cb, periph_handler,
ESPI_BUS_PERIPHERAL_NOTIFICATION);
printk("complete\n");
LOG_INF("complete");
printk("eSPI test - callbacks registration... ");
LOG_INF("eSPI test - callbacks registration... ");
espi_add_callback(espi_dev, &espi_bus_cb);
espi_add_callback(espi_dev, &vw_rdy_cb);
espi_add_callback(espi_dev, &vw_cb);
espi_add_callback(espi_dev, &p80_cb);
printk("complete\n");
LOG_INF("complete");
return ret;
}
@ -160,7 +173,7 @@ int wait_for_vwire(struct device *espi_dev, enum espi_vwire_signal signal,
do {
ret = espi_receive_vwire(espi_dev, signal, &level);
if (ret) {
printk("Failed to read %x %d", signal, ret);
LOG_WRN("Failed to read %x %d", signal, ret);
return -EIO;
}
@ -173,7 +186,7 @@ int wait_for_vwire(struct device *espi_dev, enum espi_vwire_signal signal,
} while (loop_cnt > 0);
if (loop_cnt == 0) {
printk("VWIRE %d! is %x\n", signal, level);
LOG_WRN("VWIRE %d! is %x\n", signal, level);
return -ETIMEDOUT;
}
@ -184,85 +197,117 @@ int espi_handshake(void)
{
int ret;
printk("eSPI test - Handshake with eSPI master...\n");
LOG_INF("eSPI test - Handshake with eSPI master...");
ret = wait_for_vwire(espi_dev, ESPI_VWIRE_SIGNAL_SUS_WARN,
CONFIG_ESPI_VIRTUAL_WIRE_TIMEOUT, 1);
if (ret) {
printk("SUS_WARN Timeout!\n");
LOG_WRN("SUS_WARN Timeout");
return ret;
}
printk("\t1st phase completed\n");
LOG_INF("\t1st phase completed");
ret = wait_for_vwire(espi_dev, ESPI_VWIRE_SIGNAL_SLP_S5,
CONFIG_ESPI_VIRTUAL_WIRE_TIMEOUT, 1);
if (ret) {
printk("SLP_S5 Timeout!\n");
LOG_WRN("SLP_S5 Timeout");
return ret;
}
ret = wait_for_vwire(espi_dev, ESPI_VWIRE_SIGNAL_SLP_S4,
CONFIG_ESPI_VIRTUAL_WIRE_TIMEOUT, 1);
if (ret) {
printk("SLP_S4 Timeout!\n");
LOG_WRN("SLP_S4 Timeout");
return ret;
}
ret = wait_for_vwire(espi_dev, ESPI_VWIRE_SIGNAL_SLP_S3,
CONFIG_ESPI_VIRTUAL_WIRE_TIMEOUT, 1);
if (ret) {
printk("SLP_S3 Timeout!\n");
LOG_WRN("SLP_S3 Timeout");
return ret;
}
printk("\t2nd phase completed\n");
LOG_INF("\t2nd phase completed");
return 0;
}
void main(void)
int get_pch_temp(struct device *dev)
{
struct espi_oob_packet req_pckt;
struct espi_oob_packet resp_pckt;
struct oob_header oob_hdr;
struct oob_header rsp;
int ret;
k_sleep(K_MSEC(500));
oob_hdr.dest_slave_addr = DEST_SLV_ADDR;
oob_hdr.oob_cmd_code = OOB_CMDCODE;
oob_hdr.byte_cnt = 1;
oob_hdr.src_slave_addr = SRC_SLV_ADDR;
/* Packetize OOB request */
req_pckt.buf = (u8_t *)&oob_hdr;
req_pckt.len = sizeof(struct oob_header);
resp_pckt.buf = (u8_t *)&rsp;
resp_pckt.len = 0;
ret = espi_send_oob(dev, req_pckt);
if (ret) {
LOG_WRN("espi_send_oob failed %d\n", ret);
return ret;
}
ret = espi_receive_oob(dev, resp_pckt);
if (ret) {
LOG_WRN("espi_receive_oob failed %d\n", ret);
return ret;
}
return 0;
}
int espi_test(void)
{
int ret;
#ifdef CONFIG_ESPI_GPIO_DEV_NEEDED
gpio_dev0 = device_get_binding(CONFIG_ESPI_GPIO_DEV0);
if (!gpio_dev0) {
printk("Fail to find: %s!\n", CONFIG_ESPI_GPIO_DEV0);
return;
LOG_WRN("Fail to find: %s!\n", CONFIG_ESPI_GPIO_DEV0);
return -1;
}
gpio_dev1 = device_get_binding(CONFIG_ESPI_GPIO_DEV1);
if (!gpio_dev1) {
printk("Fail to find: %s!\n", CONFIG_ESPI_GPIO_DEV1);
return;
LOG_WRN("Fail to find: %s!\n", CONFIG_ESPI_GPIO_DEV1);
return -1;
}
#endif
espi_dev = device_get_binding(CONFIG_ESPI_DEV);
if (!espi_dev) {
printk("Fail to find %s!\n", CONFIG_ESPI_DEV);
return;
LOG_WRN("Fail to find %s\n", CONFIG_ESPI_DEV);
return 1;
}
printk("Hello eSPI test! %s\n", CONFIG_BOARD);
LOG_INF("Hello eSPI test! %s\n", CONFIG_BOARD);
#ifdef CONFIG_ESPI_GPIO_DEV_NEEDED
ret = gpio_pin_configure(gpio_dev0, CONFIG_PWRGD_PIN, GPIO_DIR_IN);
if (ret) {
printk("Unable to configure PWRGD %d\n", CONFIG_PWRGD_PIN);
return;
printk("Unable to configure %d:%d\n", CONFIG_PWRGD_PIN, ret);
return ret;
}
ret = gpio_pin_configure(gpio_dev1, CONFIG_ESPI_INIT_PIN, GPIO_DIR_OUT);
if (ret) {
printk("Unable to configure RSMRST %d\n", CONFIG_ESPI_INIT_PIN);
return;
LOG_WRN("Unable to config %d: %d\n", CONFIG_ESPI_INIT_PIN, ret);
return ret;
}
ret = gpio_pin_write(gpio_dev1, CONFIG_ESPI_INIT_PIN, 0);
if (ret) {
printk("Unable to initialize %d\n", CONFIG_ESPI_INIT_PIN);
return;
LOG_WRN("Unable to initialize %d\n", CONFIG_ESPI_INIT_PIN);
return -1;
}
#endif
@ -271,19 +316,30 @@ void main(void)
#ifdef CONFIG_ESPI_GPIO_DEV_NEEDED
ret = wait_for_pin(gpio_dev0, CONFIG_PWRGD_PIN, PWR_SEQ_TIMEOUT, 1);
if (ret) {
printk("RSMRST_PWRGD timeout!\n");
return;
printk("RSMRST_PWRGD timeout!");
return ret;
}
ret = gpio_pin_write(gpio_dev1, CONFIG_ESPI_INIT_PIN, 1);
if (ret) {
printk("Failed to write %x %d\n", CONFIG_ESPI_INIT_PIN, ret);
return;
return ret;
}
#endif
ret = espi_handshake();
if (ret) {
printk("Test failed %d\n", ret);
LOG_PANIC();
return ret;
}
/* Attempt anyways to test failure case */
get_pch_temp(espi_dev);
return 0;
}
void main(void)
{
espi_test();
}