Skip to content

Commit cbb3229

Browse files
TomChang19carlescufi
authored andcommitted
drivers: espi: npcx: support espi taf rpmc request
This commit adds support for handling espi taf rpmc requests. Signed-off-by: Tom Chang <[email protected]>
1 parent e6dd4cd commit cbb3229

File tree

6 files changed

+143
-8
lines changed

6 files changed

+143
-8
lines changed

drivers/espi/Kconfig.npcx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ config ESPI_TAF_PR_NUM
9090
This size is display how many group of slave attached flash protection
9191
region.
9292

93+
config ESPI_TAF_NPCX_RPMC_SUPPORT
94+
bool "eSPI TAF RPMC support"
95+
depends on ESPI_TAF_NPCX
96+
select FLASH_EX_OP_ENABLED
97+
help
98+
This option enable the handler for eSPI TAF RPMC request.
99+
93100
# The default value 'y' for the existing options if ESPI_NPCX is selected.
94101
if ESPI_NPCX
95102

drivers/espi/espi_npcx.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,10 @@ static uint32_t espi_taf_parse(const struct device *dev)
402402
taf_addr = inst->FLASHRXBUF[1];
403403
taf_pckt.addr = sys_cpu_to_be32(taf_addr);
404404

405-
/* Get written data if eSPI TAF write */
406-
if (taf_pckt.type == NPCX_ESPI_TAF_REQ_WRITE) {
405+
/* Get written data if eSPI TAF write or RPMC OP1 */
406+
if ((taf_pckt.type == NPCX_ESPI_TAF_REQ_WRITE) ||
407+
(IS_ENABLED(CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT) &&
408+
(taf_pckt.type == NPCX_ESPI_TAF_REQ_RPMC_OP1))) {
407409
roundsize = DIV_ROUND_UP(taf_pckt.len, sizeof(uint32_t));
408410
for (i = 0; i < roundsize; i++) {
409411
taf_pckt.src[i] = inst->FLASHRXBUF[2 + i];

drivers/espi/espi_taf_npcx.c

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include <zephyr/drivers/espi.h>
1111
#include <zephyr/drivers/espi_saf.h>
1212
#include <zephyr/drivers/flash.h>
13+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
14+
#include <zephyr/drivers/flash/npcx_flash_api_ex.h>
15+
#endif
1316
#include <zephyr/kernel.h>
1417
#include <zephyr/logging/log.h>
1518

@@ -31,8 +34,14 @@ struct espi_taf_npcx_config {
3134
uintptr_t rx_plsz;
3235
enum NPCX_ESPI_TAF_ERASE_BLOCK_SIZE erase_sz;
3336
enum NPCX_ESPI_TAF_MAX_READ_REQ max_rd_sz;
37+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
38+
uint8_t rpmc_cnt_num;
39+
uint8_t rpmc_op1_code;
40+
#endif
3441
};
3542

43+
#define MAX_TX_PAYLOAD_SIZE DT_PROP(DT_INST_PARENT(0), tx_plsize)
44+
3645
struct espi_taf_npcx_data {
3746
sys_slist_t *callbacks;
3847
const struct device *host_dev;
@@ -41,6 +50,7 @@ struct espi_taf_npcx_data {
4150
uint32_t address;
4251
uint16_t length;
4352
uint32_t src[16];
53+
uint8_t read_buf[MAX_TX_PAYLOAD_SIZE];
4454
struct k_work work;
4555
};
4656

@@ -74,8 +84,9 @@ static void espi_taf_get_pckt(const struct device *dev, struct espi_taf_npcx_dat
7484
pckt->length = data_ptr->len;
7585
pckt->taf_tag = data_ptr->tag;
7686
pckt->address = data_ptr->addr;
77-
78-
if (data_ptr->type == NPCX_ESPI_TAF_REQ_WRITE) {
87+
if ((data_ptr->type == NPCX_ESPI_TAF_REQ_WRITE) ||
88+
(IS_ENABLED(CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT) &&
89+
(data_ptr->type == NPCX_ESPI_TAF_REQ_RPMC_OP1))) {
7990
memcpy(pckt->src, data_ptr->src, sizeof(pckt->src));
8091
}
8192
}
@@ -322,7 +333,6 @@ static int espi_taf_npcx_flash_read(const struct device *dev, struct espi_saf_pa
322333
uint8_t flash_req_size = GET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLASHREQSIZE);
323334
uint8_t target_max_size = GET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLREQSUP);
324335
uint16_t max_read_req = 32 << flash_req_size;
325-
uint8_t read_buf[64];
326336
int rc;
327337

328338
if (flash_req_size > target_max_size) {
@@ -352,14 +362,14 @@ static int espi_taf_npcx_flash_read(const struct device *dev, struct espi_saf_pa
352362
}
353363

354364
do {
355-
rc = flash_read(spi_dev, addr, &read_buf[0], len);
365+
rc = flash_read(spi_dev, addr, npcx_espi_taf_data.read_buf, len);
356366
if (rc) {
357367
LOG_ERR("flash read fail 0x%x", rc);
358368
return -EIO;
359369
}
360370

361371
rc = taf_npcx_completion_handler(dev, cycle_type, taf_data_ptr->tag, len,
362-
(uint32_t *)&read_buf[0]);
372+
(uint32_t *)npcx_espi_taf_data.read_buf);
363373
if (rc) {
364374
LOG_ERR("espi taf completion handler fail");
365375
return rc;
@@ -444,6 +454,73 @@ static int espi_taf_npcx_flash_erase(const struct device *dev, struct espi_saf_p
444454
return 0;
445455
}
446456

457+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
458+
static int espi_taf_npcx_rpmc_op1(const struct device *dev, struct espi_saf_packet *pckt)
459+
{
460+
struct espi_taf_npcx_pckt *taf_data_ptr = (struct espi_taf_npcx_pckt *)pckt->buf;
461+
uint8_t *data_ptr = taf_data_ptr->data;
462+
struct npcx_ex_ops_uma_in op_in = {
463+
.opcode = ESPI_TAF_RPMC_OP1_CMD,
464+
.tx_buf = data_ptr + 1,
465+
.tx_count = (pckt->len) - 1,
466+
.rx_count = 0,
467+
};
468+
int rc;
469+
470+
rc = flash_ex_op(spi_dev, FLASH_NPCX_EX_OP_EXEC_UMA, (uintptr_t)&op_in, NULL);
471+
if (rc) {
472+
LOG_ERR("flash RPMC OP1 fail");
473+
return -EIO;
474+
}
475+
476+
rc = taf_npcx_completion_handler(dev, CYC_SCS_CMP_WITHOUT_DATA, taf_data_ptr->tag, 0x0,
477+
NULL);
478+
if (rc) {
479+
LOG_ERR("espi taf completion handler fail");
480+
return rc;
481+
}
482+
483+
return 0;
484+
}
485+
486+
static int espi_taf_npcx_rpmc_op2(const struct device *dev, struct espi_saf_packet *pckt)
487+
{
488+
struct espi_taf_npcx_pckt *taf_data_ptr = (struct espi_taf_npcx_pckt *)pckt->buf;
489+
uint8_t dummy_byte = 0;
490+
struct npcx_ex_ops_uma_in op_in = {
491+
.opcode = ESPI_TAF_RPMC_OP2_CMD,
492+
.tx_buf = &dummy_byte,
493+
.tx_count = 1,
494+
.rx_count = pckt->len,
495+
};
496+
struct npcx_ex_ops_uma_out op_out = {
497+
.rx_buf = npcx_espi_taf_data.read_buf,
498+
};
499+
500+
int rc;
501+
502+
if (pckt->len > MAX_TX_PAYLOAD_SIZE) {
503+
LOG_ERR("Invalid size");
504+
return -EINVAL;
505+
}
506+
507+
rc = flash_ex_op(spi_dev, FLASH_NPCX_EX_OP_EXEC_UMA, (uintptr_t)&op_in, &op_out);
508+
if (rc) {
509+
LOG_ERR("flash RPMC OP2 fail");
510+
return -EIO;
511+
}
512+
513+
rc = taf_npcx_completion_handler(dev, CYC_SCS_CMP_WITH_DATA_ONLY, taf_data_ptr->tag,
514+
pckt->len, (uint32_t *)npcx_espi_taf_data.read_buf);
515+
if (rc) {
516+
LOG_ERR("espi taf completion handler fail");
517+
return rc;
518+
}
519+
520+
return 0;
521+
}
522+
#endif
523+
447524
static int espi_taf_npcx_flash_unsuccess(const struct device *dev, struct espi_saf_packet *pckt)
448525
{
449526
struct espi_taf_npcx_pckt *taf_data_ptr = (struct espi_taf_npcx_pckt *)pckt->buf;
@@ -470,7 +547,9 @@ static void espi_taf_work(struct k_work *item)
470547
pckt_taf.flash_addr = info->address;
471548
pckt_taf.len = info->length;
472549
taf_data.tag = info->taf_tag;
473-
if (info->taf_type == NPCX_ESPI_TAF_REQ_WRITE) {
550+
if ((info->taf_type == NPCX_ESPI_TAF_REQ_WRITE) ||
551+
(IS_ENABLED(CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT) &&
552+
(info->taf_type == NPCX_ESPI_TAF_REQ_RPMC_OP1))) {
474553
taf_data.data = (uint8_t *)info->src;
475554
} else {
476555
taf_data.data = NULL;
@@ -489,6 +568,14 @@ static void espi_taf_work(struct k_work *item)
489568
case NPCX_ESPI_TAF_REQ_WRITE:
490569
ret = espi_taf_npcx_flash_write(info->host_dev, &pckt_taf);
491570
break;
571+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
572+
case NPCX_ESPI_TAF_REQ_RPMC_OP1:
573+
ret = espi_taf_npcx_rpmc_op1(info->host_dev, &pckt_taf);
574+
break;
575+
case NPCX_ESPI_TAF_REQ_RPMC_OP2:
576+
ret = espi_taf_npcx_rpmc_op2(info->host_dev, &pckt_taf);
577+
break;
578+
#endif
492579
}
493580

494581
if (ret != 0) {
@@ -533,6 +620,21 @@ static int espi_taf_npcx_init(const struct device *dev)
533620
config->max_rd_sz);
534621
inst->FLASHBASE = config->mapped_addr;
535622

623+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
624+
uint8_t count_num = 0;
625+
626+
/* RPMC_CFG1_CNTR is 0-based number, e.g. 0 indicates that 1 counter is supported, 1
627+
* indicates 2 counters, etc.
628+
*/
629+
if (config->rpmc_cnt_num > 0) {
630+
count_num = config->rpmc_cnt_num - 1;
631+
}
632+
633+
SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_CNTR, count_num);
634+
SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_OP1, config->rpmc_op1_code);
635+
SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_TRGRPMCSUP, config->rpmc_cnt_num);
636+
#endif
637+
536638
return 0;
537639
}
538640

@@ -549,6 +651,10 @@ static const struct espi_taf_npcx_config espi_taf_npcx_config = {
549651
.rx_plsz = DT_PROP(DT_INST_PARENT(0), rx_plsize),
550652
.erase_sz = DT_INST_STRING_TOKEN(0, erase_sz),
551653
.max_rd_sz = DT_INST_STRING_TOKEN(0, max_read_sz),
654+
#ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
655+
.rpmc_cnt_num = DT_INST_PROP(0, rpmc_cntr),
656+
.rpmc_op1_code = DT_INST_PROP(0, rpmc_op1_code),
657+
#endif
552658
};
553659

554660
DEVICE_DT_INST_DEFINE(0, &espi_taf_npcx_init, NULL,

dts/bindings/espi/nuvoton,npcx-espi-taf.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,15 @@ properties:
5858
- "NPCX_ESPI_TAF_MAX_READ_REQ_1024B"
5959
- "NPCX_ESPI_TAF_MAX_READ_REQ_2048B"
6060
- "NPCX_ESPI_TAF_MAX_READ_REQ_4096B"
61+
62+
rpmc-cntr:
63+
type: int
64+
description: |
65+
RPMC counter on RPMC flash devices.
66+
default: 0
67+
68+
rpmc-op1-code:
69+
type: int
70+
description: |
71+
RPMC OP1 opcode on RPMC flash devices.
72+
default: 0

soc/nuvoton/npcx/common/reg/reg_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,9 @@ struct espi_reg {
791791
#define NPCX_FLASH_PRTR_HADDR FIELD(12, 15)
792792
#define NPCX_FLASH_TAG_OVR_RPR FIELD(16, 16)
793793
#define NPCX_FLASH_TAG_OVR_WPR FIELD(0, 16)
794+
#define NPCX_FLASH_RPMC_CFG1_CNTR FIELD(0, 4)
795+
#define NPCX_FLASH_RPMC_CFG1_OP1 FIELD(4, 8)
796+
#define NPCX_FLASH_RPMC_CFG1_TRGRPMCSUP FIELD(26, 6)
794797
#define NPCX_ONLY_ESPI_REG1_UNLOCK_REG2 0x55
795798
#define NPCX_ONLY_ESPI_REG1_LOCK_REG2 0
796799
#define NPCX_ONLY_ESPI_REG2_TRANS_END_CONFIG 4

soc/nuvoton/npcx/common/soc_espi_taf.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ extern "C" {
5555
/* Unsuccessful Only Completion Without Data */
5656
#define CYC_UNSCS_CMP_WITHOUT_DATA_ONLY 0x0E
5757

58+
/* ESPI TAF RPMC OP1 instruction */
59+
#define ESPI_TAF_RPMC_OP1_CMD 0x9B
60+
/* ESPI TAF RPMC OP2 instruction */
61+
#define ESPI_TAF_RPMC_OP2_CMD 0x96
62+
5863
/* Timeout for checking transmit buffer available and no completion was sent */
5964
#define NPCX_FLASH_CHK_TIMEOUT 10000
6065

0 commit comments

Comments
 (0)