Skip to content

Commit fed6a9d

Browse files
JasonLin-RealTekjhedberg
authored andcommitted
driver: espi: implement espi PM function
1. add cs pin as espi driver wake up reference 2. removed the unnecessary update of the cached date 3. removed the unnecessary busy wait in notify funciton Signed-off-by: Lin Yu-Cheng <[email protected]>
1 parent 45c9bab commit fed6a9d

File tree

3 files changed

+75
-36
lines changed

3 files changed

+75
-36
lines changed

drivers/espi/espi_realtek_rts5912.c

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
2323
#include "reg/reg_kbc.h"
2424
#include "reg/reg_port80.h"
2525

26+
#ifdef CONFIG_PM
27+
#include "reg/reg_gpio.h"
28+
#include <zephyr/pm/device.h>
29+
#include <zephyr/pm/policy.h>
30+
#include "reg/reg_system.h"
31+
#include "zephyr/drivers/gpio/gpio_rts5912.h"
32+
#endif
33+
2634
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "support only one espi compatible node");
2735

2836
struct espi_rts5912_config {
@@ -56,6 +64,9 @@ struct espi_rts5912_config {
5664
volatile struct port80_reg *const port80_reg;
5765
uint32_t port80_clk_grp;
5866
uint32_t port80_clk_idx;
67+
#endif
68+
#ifdef CONFIG_PM
69+
struct gpio_dt_spec cs_pin;
5970
#endif
6071
const struct device *clk_dev;
6172
const struct pinctrl_dev_config *pcfg;
@@ -1200,7 +1211,6 @@ static void notify_host_warning(const struct device *dev, enum espi_vwire_signal
12001211
uint8_t status = 0;
12011212

12021213
espi_rts5912_receive_vwire(dev, signal, &status);
1203-
k_busy_wait(200);
12041214

12051215
switch (signal) {
12061216
case ESPI_VWIRE_SIGNAL_SUS_WARN:
@@ -1397,8 +1407,6 @@ static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_sig
13971407
static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal,
13981408
uint8_t *level)
13991409
{
1400-
const struct espi_rts5912_config *const espi_config = dev->config;
1401-
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
14021410
uint8_t vw_idx, lev_msk, valid_msk;
14031411
uint8_t vw_data;
14041412

@@ -1415,9 +1423,6 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14151423
vw_data = espi_vw_ch_cached_data.idx2;
14161424
break;
14171425
case VW_CH_IDX3:
1418-
if (espi_vw_ch_cached_data.idx3 != espi_reg->EVIDX3) {
1419-
espi_vw_ch_cached_data.idx3 = espi_reg->EVIDX3;
1420-
}
14211426
vw_data = espi_vw_ch_cached_data.idx3;
14221427
break;
14231428
case VW_CH_IDX4:
@@ -1430,60 +1435,33 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14301435
vw_data = espi_vw_tx_cached_data.idx6;
14311436
break;
14321437
case VW_CH_IDX7:
1433-
if (espi_vw_ch_cached_data.idx7 != espi_reg->EVIDX7) {
1434-
espi_vw_ch_cached_data.idx7 = espi_reg->EVIDX7;
1435-
}
14361438
vw_data = espi_vw_ch_cached_data.idx7;
14371439
break;
14381440
case VW_CH_IDX40:
14391441
vw_data = espi_vw_tx_cached_data.idx40;
14401442
break;
14411443
case VW_CH_IDX41:
1442-
if (espi_vw_ch_cached_data.idx41 != espi_reg->EVIDX41) {
1443-
espi_vw_ch_cached_data.idx41 = espi_reg->EVIDX41;
1444-
}
14451444
vw_data = espi_vw_ch_cached_data.idx41;
14461445
break;
14471446
case VW_CH_IDX42:
1448-
if (espi_vw_ch_cached_data.idx42 != espi_reg->EVIDX42) {
1449-
espi_vw_ch_cached_data.idx42 = espi_reg->EVIDX42;
1450-
}
14511447
vw_data = espi_vw_ch_cached_data.idx42;
14521448
break;
14531449
case VW_CH_IDX43:
1454-
if (espi_vw_ch_cached_data.idx43 != espi_reg->EVIDX43) {
1455-
espi_vw_ch_cached_data.idx43 = espi_reg->EVIDX43;
1456-
}
14571450
vw_data = espi_vw_ch_cached_data.idx43;
14581451
break;
14591452
case VW_CH_IDX44:
1460-
if (espi_vw_ch_cached_data.idx44 != espi_reg->EVIDX44) {
1461-
espi_vw_ch_cached_data.idx44 = espi_reg->EVIDX44;
1462-
}
14631453
vw_data = espi_vw_ch_cached_data.idx44;
14641454
break;
14651455
case VW_CH_IDX47:
1466-
if (espi_vw_ch_cached_data.idx47 != espi_reg->EVIDX47) {
1467-
espi_vw_ch_cached_data.idx47 = espi_reg->EVIDX47;
1468-
}
14691456
vw_data = espi_vw_ch_cached_data.idx47;
14701457
break;
14711458
case VW_CH_IDX4A:
1472-
if (espi_vw_ch_cached_data.idx4a != espi_reg->EVIDX4A) {
1473-
espi_vw_ch_cached_data.idx4a = espi_reg->EVIDX4A;
1474-
}
14751459
vw_data = espi_vw_ch_cached_data.idx4a;
14761460
break;
14771461
case VW_CH_IDX51:
1478-
if (espi_vw_ch_cached_data.idx51 != espi_reg->EVIDX51) {
1479-
espi_vw_ch_cached_data.idx51 = espi_reg->EVIDX51;
1480-
}
14811462
vw_data = espi_vw_ch_cached_data.idx51;
14821463
break;
14831464
case VW_CH_IDX61:
1484-
if (espi_vw_ch_cached_data.idx61 != espi_reg->EVIDX61) {
1485-
espi_vw_ch_cached_data.idx61 = espi_reg->EVIDX61;
1486-
}
14871465
vw_data = espi_vw_ch_cached_data.idx61;
14881466
break;
14891467
default:
@@ -2296,7 +2274,18 @@ static void espi_bus_reset_setup(const struct device *dev)
22962274
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
22972275
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), bus_rst, irq));
22982276
}
2277+
#ifdef CONFIG_PM
2278+
void espi_cs_low_isr(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
2279+
{
2280+
gpio_flags_t cs_pin_config;
22992281

2282+
gpio_pin_get_config(port, pins, &cs_pin_config);
2283+
if (cs_pin_config & GPIO_INT_ENABLE) {
2284+
gpio_pin_interrupt_configure(port, (find_msb_set(pins) - 1),
2285+
GPIO_INT_MODE_DISABLED);
2286+
}
2287+
}
2288+
#endif
23002289
static int espi_rts5912_init(const struct device *dev)
23012290
{
23022291
const struct espi_rts5912_config *const espi_config = dev->config;
@@ -2396,13 +2385,44 @@ static int espi_rts5912_init(const struct device *dev)
23962385
goto exit;
23972386
}
23982387
#endif
2399-
2388+
#ifdef CONFIG_PM
2389+
static struct gpio_callback cb;
2390+
uint32_t cs_irq_nun = gpio_rts5912_get_pin_num(&espi_config->cs_pin);
2391+
2392+
NVIC_ClearPendingIRQ(cs_irq_nun);
2393+
gpio_init_callback(&cb, espi_cs_low_isr, BIT(espi_config->cs_pin.pin));
2394+
gpio_add_callback(espi_config->cs_pin.port, &cb);
2395+
irq_enable(cs_irq_nun);
2396+
#endif
24002397
exit:
24012398
return rc;
24022399
}
2400+
#ifdef CONFIG_PM
2401+
static inline int espi_rts5912_pm_action(const struct device *dev, enum pm_device_action action)
2402+
{
2403+
const struct espi_rts5912_config *const espi_config = dev->config;
2404+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
24032405

2404-
PINCTRL_DT_INST_DEFINE(0);
2406+
switch (action) {
2407+
case PM_DEVICE_ACTION_RESUME:
2408+
sys_reg->SLPCTRL &= ~SYSTEM_SLPCTRL_GPIOWKEN_Msk;
2409+
gpio_pin_interrupt_configure_dt(&espi_config->cs_pin, GPIO_INT_MODE_DISABLED);
2410+
break;
2411+
case PM_DEVICE_ACTION_SUSPEND:
2412+
sys_reg->SLPCTRL |= SYSTEM_SLPCTRL_GPIOWKEN_Msk;
2413+
gpio_pin_interrupt_configure_dt(&espi_config->cs_pin,
2414+
GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW);
2415+
break;
2416+
default:
2417+
return -ENOTSUP;
2418+
}
24052419

2420+
return 0;
2421+
}
2422+
PM_DEVICE_DT_INST_DEFINE(0, espi_rts5912_pm_action);
2423+
#endif
2424+
2425+
PINCTRL_DT_INST_DEFINE(0);
24062426
static struct espi_rts5912_data espi_rts5912_data_0;
24072427

24082428
static const struct espi_rts5912_config espi_rts5912_config = {
@@ -2437,10 +2457,18 @@ static const struct espi_rts5912_config espi_rts5912_config = {
24372457
.port80_reg = (volatile struct port80_reg *const)DT_INST_REG_ADDR_BY_NAME(0, port80),
24382458
.port80_clk_grp = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_grp),
24392459
.port80_clk_idx = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_idx),
2460+
#endif
2461+
#ifdef CONFIG_PM
2462+
.cs_pin = GPIO_DT_SPEC_INST_GET(0, cs_gpios),
24402463
#endif
24412464
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
24422465
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
24432466
};
2444-
2467+
#ifdef CONFIG_PM
2468+
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, PM_DEVICE_DT_INST_GET(0), &espi_rts5912_data_0,
2469+
&espi_rts5912_config, PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY,
2470+
&espi_rts5912_driver_api);
2471+
#else
24452472
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, NULL, &espi_rts5912_data_0, &espi_rts5912_config,
24462473
PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, &espi_rts5912_driver_api);
2474+
#endif

dts/arm/realtek/ec/rts5912.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <mem.h>
1414
#include <zephyr/dt-bindings/i2c/i2c.h>
1515
#include <freq.h>
16+
#include <zephyr/dt-bindings/gpio/realtek-gpio.h>
1617

1718
/ {
1819
cpus {
@@ -167,6 +168,7 @@
167168

168169
espi0: espi0@400b1000 {
169170
compatible = "realtek,rts5912-espi";
171+
cs-gpios = <RTS5912_GPIO004 0>;
170172
status = "disabled";
171173

172174
reg = <0x400b1000 0x200 /* espi target */

dts/bindings/espi/realtek,rts5912-espi.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,12 @@ properties:
1717

1818
pinctrl-names:
1919
required: true
20+
21+
cs-gpios:
22+
description: |
23+
select the cs pin to support the espi wakeup
24+
and it is required when CONFIG_PM is enabled.
25+
please check include/zephyr/dt-bindings/gpio/realtek-gpio.h
26+
For example:
27+
cs-gpios = <RTS5912_GPIO004 0>;
28+
type: phandle-array

0 commit comments

Comments
 (0)