Skip to content

Commit f1f0dad

Browse files
Dino-Linashif
authored andcommitted
driver: espi: it8xxx2: enable ESPI_OOB_CHANNEL
This enable eSPI out-of-band channel. Signed-off-by: Dino Li <[email protected]>
1 parent 0b06a06 commit f1f0dad

File tree

4 files changed

+192
-17
lines changed

4 files changed

+192
-17
lines changed

drivers/espi/Kconfig.it8xxx2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ config ESPI_IT8XXX2
99

1010
if ESPI_IT8XXX2
1111

12+
config ESPI_OOB_CHANNEL
13+
default y
14+
1215
config ESPI_PERIPHERAL_8042_KBC
1316
default y
1417

drivers/espi/espi_it8xxx2.c

Lines changed: 154 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,18 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
4545
#define IT8XXX2_ESPI_VW_INTERRUPT_ENABLE BIT(7)
4646
#define IT8XXX2_ESPI_INTERRUPT_PUT_PC BIT(7)
4747

48+
#define IT8XXX2_ESPI_UPSTREAM_ENABLE BIT(7)
49+
#define IT8XXX2_ESPI_UPSTREAM_GO BIT(6)
4850
#define IT8XXX2_ESPI_UPSTREAM_INTERRUPT_ENABLE BIT(5)
4951
#define IT8XXX2_ESPI_UPSTREAM_CHANNEL_DISABLE BIT(2)
5052
#define IT8XXX2_ESPI_UPSTREAM_DONE BIT(1)
53+
#define IT8XXX2_ESPI_UPSTREAM_BUSY BIT(0)
54+
55+
#define IT8XXX2_ESPI_CYCLE_TYPE_OOB 0x07
5156

5257
#define IT8XXX2_ESPI_PUT_OOB_STATUS BIT(7)
5358
#define IT8XXX2_ESPI_PUT_OOB_INTERRUPT_ENABLE BIT(7)
59+
#define IT8XXX2_ESPI_PUT_OOB_LEN_MASK GENMASK(6, 0)
5460

5561
#define IT8XXX2_ESPI_INPUT_PAD_GATING BIT(6)
5662

@@ -66,6 +72,9 @@ struct espi_it8xxx2_config {
6672

6773
struct espi_it8xxx2_data {
6874
sys_slist_t callbacks;
75+
#ifdef CONFIG_ESPI_OOB_CHANNEL
76+
struct k_sem oob_upstream_go;
77+
#endif
6978
};
7079

7180
/* Driver convenience defines */
@@ -687,22 +696,145 @@ static int espi_it8xxx2_write_lpc_request(const struct device *dev,
687696
}
688697

689698
#ifdef CONFIG_ESPI_OOB_CHANNEL
699+
/* eSPI cycle type field */
700+
#define ESPI_OOB_CYCLE_TYPE 0x21
701+
#define ESPI_OOB_TAG 0x00
702+
#define ESPI_OOB_TIMEOUT_MS 200
703+
704+
/* eSPI oob cycle type, tag, and length fields. */
705+
#define ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE 3
706+
707+
struct espi_oob_msg_packet {
708+
uint8_t cycle_type;
709+
uint8_t tag_len_bit_11_8;
710+
uint8_t len_bit_7_0;
711+
uint8_t data_byte[0];
712+
};
713+
690714
static int espi_it8xxx2_send_oob(const struct device *dev,
691715
struct espi_oob_packet *pckt)
692716
{
693-
/* TODO: implement me... */
694-
ARG_UNUSED(dev);
717+
const struct espi_it8xxx2_config *const config = DRV_CONFIG(dev);
718+
struct espi_slave_regs *const slave_reg =
719+
(struct espi_slave_regs *)config->base_espi_slave;
720+
struct espi_queue1_regs *const queue1_reg =
721+
(struct espi_queue1_regs *)config->base_espi_queue1;
722+
struct espi_oob_msg_packet *oob_pckt =
723+
(struct espi_oob_msg_packet *)pckt->buf;
724+
uint16_t oob_msg_len;
725+
726+
__ASSERT(pckt->len >= ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE,
727+
"Invalid OOB packet length");
728+
729+
if (!(slave_reg->CH_OOB_CAPCFG3 & IT8XXX2_ESPI_OOB_READY_MASK)) {
730+
LOG_ERR("%s: OOB channel isn't ready", __func__);
731+
return -EIO;
732+
}
733+
734+
if (slave_reg->ESUCTRL0 & IT8XXX2_ESPI_UPSTREAM_BUSY) {
735+
LOG_ERR("%s: OOB upstream busy", __func__);
736+
return -EIO;
737+
}
738+
739+
oob_msg_len = oob_pckt->len_bit_7_0 |
740+
((oob_pckt->tag_len_bit_11_8 & 0xf) << 8);
741+
742+
if (pckt->len < (oob_msg_len +
743+
ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE)) {
744+
LOG_ERR("%s: Out of tx buf %d vs %d", __func__, pckt->len,
745+
(oob_msg_len + ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE));
746+
return -EINVAL;
747+
}
695748

696-
return -EIO;
749+
if (oob_msg_len > ESPI_IT8XXX2_OOB_MAX_PAYLOAD_SIZE) {
750+
LOG_ERR("%s: Out of OOB queue space", __func__);
751+
return -EINVAL;
752+
}
753+
754+
/* Set cycle type */
755+
slave_reg->ESUCTRL1 = IT8XXX2_ESPI_CYCLE_TYPE_OOB;
756+
/* Set tag and length[11:8] */
757+
slave_reg->ESUCTRL2 = oob_pckt->tag_len_bit_11_8;
758+
/* Set length [7:0] */
759+
slave_reg->ESUCTRL3 = oob_pckt->len_bit_7_0;
760+
761+
/* Set data byte */
762+
for (int i = 0; i < oob_msg_len; i++) {
763+
queue1_reg->UPSTREAM_DATA[i] = oob_pckt->data_byte[i];
764+
}
765+
766+
/* Set upstream enable */
767+
slave_reg->ESUCTRL0 |= IT8XXX2_ESPI_UPSTREAM_ENABLE;
768+
/* Set upstream go */
769+
slave_reg->ESUCTRL0 |= IT8XXX2_ESPI_UPSTREAM_GO;
770+
771+
return 0;
697772
}
698773

699774
static int espi_it8xxx2_receive_oob(const struct device *dev,
700775
struct espi_oob_packet *pckt)
701776
{
702-
/* TODO: implement me... */
703-
ARG_UNUSED(dev);
777+
const struct espi_it8xxx2_config *const config = DRV_CONFIG(dev);
778+
struct espi_it8xxx2_data *const data = DRV_DATA(dev);
779+
struct espi_slave_regs *const slave_reg =
780+
(struct espi_slave_regs *)config->base_espi_slave;
781+
struct espi_queue0_regs *const queue0_reg =
782+
(struct espi_queue0_regs *)config->base_espi_queue0;
783+
struct espi_oob_msg_packet *oob_pckt =
784+
(struct espi_oob_msg_packet *)pckt->buf;
785+
int ret;
786+
uint8_t oob_len;
787+
788+
if (!(slave_reg->CH_OOB_CAPCFG3 & IT8XXX2_ESPI_OOB_READY_MASK)) {
789+
LOG_ERR("%s: OOB channel isn't ready", __func__);
790+
return -EIO;
791+
}
704792

705-
return -EIO;
793+
/* Wait until receive OOB message or timeout */
794+
ret = k_sem_take(&data->oob_upstream_go, K_MSEC(ESPI_OOB_TIMEOUT_MS));
795+
if (ret == -EAGAIN) {
796+
LOG_ERR("%s: Timeout", __func__);
797+
return -ETIMEDOUT;
798+
}
799+
800+
/* Get length */
801+
oob_len = (slave_reg->ESOCTRL4 & IT8XXX2_ESPI_PUT_OOB_LEN_MASK);
802+
/*
803+
* Buffer passed to driver isn't enough.
804+
* The first three bytes of buffer are cycle type, tag, and length.
805+
*/
806+
if ((oob_len + ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE) > pckt->len) {
807+
LOG_ERR("%s: Out of rx buf %d vs %d", __func__,
808+
(oob_len + ESPI_OOB_PACKET_SIZE_WITHOUT_DATA_BYTE), pckt->len);
809+
return -EINVAL;
810+
}
811+
812+
oob_pckt->cycle_type = ESPI_OOB_CYCLE_TYPE;
813+
oob_pckt->tag_len_bit_11_8 = ESPI_OOB_TAG;
814+
oob_pckt->len_bit_7_0 = oob_len;
815+
816+
/* Get data byte */
817+
for (int i = 0; i < oob_pckt->len_bit_7_0; i++) {
818+
oob_pckt->data_byte[i] = queue0_reg->PUT_OOB_DATA[i];
819+
}
820+
821+
return 0;
822+
}
823+
824+
static void espi_it8xxx2_oob_init(const struct device *dev)
825+
{
826+
const struct espi_it8xxx2_config *const config = DRV_CONFIG(dev);
827+
struct espi_it8xxx2_data *const data = DRV_DATA(dev);
828+
struct espi_slave_regs *const slave_reg =
829+
(struct espi_slave_regs *)config->base_espi_slave;
830+
831+
k_sem_init(&data->oob_upstream_go, 0, 1);
832+
833+
/* Upstream interrupt enable */
834+
slave_reg->ESUCTRL0 |= IT8XXX2_ESPI_UPSTREAM_INTERRUPT_ENABLE;
835+
836+
/* PUT_OOB interrupt enable */
837+
slave_reg->ESOCTRL1 |= IT8XXX2_ESPI_PUT_OOB_INTERRUPT_ENABLE;
706838
}
707839
#endif
708840

@@ -1052,6 +1184,7 @@ static void espi_it8xxx2_put_pc_status_isr(const struct device *dev)
10521184
slave_reg->ESPCTRL0 = IT8XXX2_ESPI_INTERRUPT_PUT_PC;
10531185
}
10541186

1187+
#ifdef CONFIG_ESPI_OOB_CHANNEL
10551188
static void espi_it8xxx2_upstream_channel_disable_isr(const struct device *dev)
10561189
{
10571190
const struct espi_it8xxx2_config *const config = DRV_CONFIG(dev);
@@ -1070,23 +1203,25 @@ static void espi_it8xxx2_upstream_done_isr(const struct device *dev)
10701203
struct espi_slave_regs *const slave_reg =
10711204
(struct espi_slave_regs *)config->base_espi_slave;
10721205

1073-
LOG_INF("isr %s is ignored!", __func__);
1074-
10751206
/* write-1 to clear this bit */
10761207
slave_reg->ESUCTRL0 |= IT8XXX2_ESPI_UPSTREAM_DONE;
1208+
/* upstream disable */
1209+
slave_reg->ESUCTRL0 &= ~IT8XXX2_ESPI_UPSTREAM_ENABLE;
10771210
}
10781211

10791212
static void espi_it8xxx2_put_oob_status_isr(const struct device *dev)
10801213
{
10811214
const struct espi_it8xxx2_config *const config = DRV_CONFIG(dev);
1215+
struct espi_it8xxx2_data *const data = DRV_DATA(dev);
10821216
struct espi_slave_regs *const slave_reg =
10831217
(struct espi_slave_regs *)config->base_espi_slave;
10841218

1085-
LOG_INF("isr %s is ignored!", __func__);
1086-
10871219
/* Write-1 to clear this bit for the next coming posted transaction. */
10881220
slave_reg->ESOCTRL0 |= IT8XXX2_ESPI_PUT_OOB_STATUS;
1221+
1222+
k_sem_give(&data->oob_upstream_go);
10891223
}
1224+
#endif
10901225

10911226
/*
10921227
* The ISR of espi interrupt event in array need to be matched bit order in
@@ -1110,7 +1245,9 @@ static void espi_it8xxx2_isr(const struct device *dev)
11101245
(struct espi_slave_regs *)config->base_espi_slave;
11111246
/* get espi interrupt events */
11121247
uint8_t espi_event = slave_reg->ESGCTRL0;
1248+
#ifdef CONFIG_ESPI_OOB_CHANNEL
11131249
uint8_t espi_upstream = slave_reg->ESUCTRL0;
1250+
#endif
11141251

11151252
/* write-1 to clear */
11161253
slave_reg->ESGCTRL0 = espi_event;
@@ -1132,6 +1269,7 @@ static void espi_it8xxx2_isr(const struct device *dev)
11321269
espi_it8xxx2_put_pc_status_isr(dev);
11331270
}
11341271

1272+
#ifdef CONFIG_ESPI_OOB_CHANNEL
11351273
/*
11361274
* The corresponding channel of the eSPI upstream transaction is
11371275
* disabled.
@@ -1149,6 +1287,7 @@ static void espi_it8xxx2_isr(const struct device *dev)
11491287
if (slave_reg->ESOCTRL0 & IT8XXX2_ESPI_PUT_OOB_STATUS) {
11501288
espi_it8xxx2_put_oob_status_isr(dev);
11511289
}
1290+
#endif
11521291
}
11531292

11541293
void espi_it8xxx2_enable_pad_ctrl(const struct device *dev, bool enable)
@@ -1208,8 +1347,8 @@ static struct espi_it8xxx2_data espi_it8xxx2_data_0;
12081347
static const struct espi_it8xxx2_config espi_it8xxx2_config_0 = {
12091348
.base_espi_slave = DT_INST_REG_ADDR_BY_IDX(0, 0),
12101349
.base_espi_vw = DT_INST_REG_ADDR_BY_IDX(0, 1),
1211-
.base_espi_queue1 = DT_INST_REG_ADDR_BY_IDX(0, 2),
1212-
.base_espi_queue0 = DT_INST_REG_ADDR_BY_IDX(0, 3),
1350+
.base_espi_queue0 = DT_INST_REG_ADDR_BY_IDX(0, 2),
1351+
.base_espi_queue1 = DT_INST_REG_ADDR_BY_IDX(0, 3),
12131352
.base_ec2i = DT_INST_REG_ADDR_BY_IDX(0, 4),
12141353
.base_kbc = DT_INST_REG_ADDR_BY_IDX(0, 5),
12151354
.base_pmc = DT_INST_REG_ADDR_BY_IDX(0, 6),
@@ -1259,11 +1398,9 @@ static int espi_it8xxx2_init(const struct device *dev)
12591398
DEVICE_DT_INST_GET(0), 0);
12601399
irq_enable(IT8XXX2_ESPI_VW_IRQ);
12611400

1262-
/* Upstream interrupt enable */
1263-
slave_reg->ESUCTRL0 |= IT8XXX2_ESPI_UPSTREAM_INTERRUPT_ENABLE;
1264-
1265-
/* PUT_OOB interrupt enable */
1266-
slave_reg->ESOCTRL1 |= IT8XXX2_ESPI_PUT_OOB_INTERRUPT_ENABLE;
1401+
#ifdef CONFIG_ESPI_OOB_CHANNEL
1402+
espi_it8xxx2_oob_init(dev);
1403+
#endif
12671404

12681405
/* Enable espi interrupt */
12691406
slave_reg->ESGCTRL1 |= IT8XXX2_ESPI_INTERRUPT_ENABLE;

soc/riscv/riscv-ite/common/check_regs.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ IT8XXX2_REG_OFFSET_CHECK(espi_vw_regs, VW_INDEX, 0x00);
5555
IT8XXX2_REG_OFFSET_CHECK(espi_vw_regs, VWCTRL0, 0x90);
5656
IT8XXX2_REG_OFFSET_CHECK(espi_vw_regs, VWCTRL1, 0x91);
5757

58+
/* eSPI Queue 0 registers structure check */
59+
IT8XXX2_REG_SIZE_CHECK(espi_queue0_regs, 0xd0);
60+
IT8XXX2_REG_OFFSET_CHECK(espi_queue0_regs, PUT_OOB_DATA, 0x80);
61+
62+
/* eSPI Queue 1 registers structure check */
63+
IT8XXX2_REG_SIZE_CHECK(espi_queue1_regs, 0xc0);
64+
IT8XXX2_REG_OFFSET_CHECK(espi_queue1_regs, UPSTREAM_DATA, 0x00);
65+
IT8XXX2_REG_OFFSET_CHECK(espi_queue1_regs, PUT_FLASH_NP_DATA, 0x80);
66+
5867
/* GCTRL register structure check */
5968
IT8XXX2_REG_SIZE_CHECK(gctrl_it8xxx2_regs, 0x88);
6069
IT8XXX2_REG_OFFSET_CHECK(gctrl_it8xxx2_regs, GCTRL_RSTS, 0x06);

soc/riscv/riscv-ite/common/chip_chipregs.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,6 +2291,32 @@ struct espi_vw_regs {
22912291
/* 0x98-0x99: Reserved3 */
22922292
volatile uint8_t reserved3[2];
22932293
};
2294+
2295+
#define ESPI_IT8XXX2_OOB_MAX_PAYLOAD_SIZE 80
2296+
/*
2297+
* eSPI Queue 0 registers
2298+
*/
2299+
struct espi_queue0_regs {
2300+
/* 0x00-0x3f: PUT_PC Data Byte 0-63 */
2301+
volatile uint8_t PUT_PC_DATA[0x40];
2302+
/* 0x40-0x7f: Reserved1 */
2303+
volatile uint8_t reserved1[0x40];
2304+
/* 0x80-0xcf: PUT_OOB Data Byte 0-79 */
2305+
volatile uint8_t PUT_OOB_DATA[ESPI_IT8XXX2_OOB_MAX_PAYLOAD_SIZE];
2306+
};
2307+
2308+
/*
2309+
* eSPI Queue 1 registers
2310+
*/
2311+
struct espi_queue1_regs {
2312+
/* 0x00-0x4f: Upstream Data Byte 0-79 */
2313+
volatile uint8_t UPSTREAM_DATA[ESPI_IT8XXX2_OOB_MAX_PAYLOAD_SIZE];
2314+
/* 0x50-0x7f: Reserved1 */
2315+
volatile uint8_t reserved1[0x30];
2316+
/* 0x80-0xbf: PUT_FLASH_NP Data Byte 0-63 */
2317+
volatile uint8_t PUT_FLASH_NP_DATA[0x40];
2318+
};
2319+
22942320
#endif /* !__ASSEMBLER__ */
22952321

22962322
#endif /* CHIP_CHIPREGS_H */

0 commit comments

Comments
 (0)