Skip to content

Commit 6aa7001

Browse files
committed
soc : realtek: ec: rts5912: add support ULPM
Port rts5912 ULPM on Zephyr Signed-off-by: Titan Chen <[email protected]>
1 parent 19c6240 commit 6aa7001

File tree

8 files changed

+315
-2
lines changed

8 files changed

+315
-2
lines changed

dts/arm/realtek/ec/rts5912.dtsi

+39
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,45 @@
275275
&jtag_clk_gpio90 &jtag_tms_gpio91>;
276276
pinctrl-names = "default";
277277
};
278+
279+
ulpm: ulpm {
280+
compatible = "realtek,rts5912-ulpm";
281+
wkup-pins-max = <6>; /* 6 system wake-up pins */
282+
status = "disabled";
283+
284+
#address-cells = <1>;
285+
#size-cells = <0>;
286+
287+
wkup-pin@0 {
288+
reg = <0x0>;
289+
wkup-pin-mode = "gpio";
290+
};
291+
292+
wkup-pin@1 {
293+
reg = <0x1>;
294+
wkup-pin-mode = "gpio";
295+
};
296+
297+
wkup-pin@2 {
298+
reg = <0x2>;
299+
wkup-pin-mode = "gpio";
300+
};
301+
302+
wkup-pin@3 {
303+
reg = <0x3>;
304+
wkup-pin-mode = "gpio";
305+
};
306+
307+
wkup-pin@4 {
308+
reg = <0x4>;
309+
wkup-pin-mode = "gpio";
310+
};
311+
312+
wkup-pin@5 {
313+
reg = <0x5>;
314+
wkup-pin-mode = "gpio";
315+
};
316+
};
278317
};
279318

280319
&nvic {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: RTS5912 ULPM power controller
5+
6+
compatible: "realtek,rts5912-ulpm"
7+
8+
include: base.yaml
9+
10+
properties:
11+
wkup-pins-max:
12+
type: int
13+
description: |
14+
Max nbr of system wake-up pins.
15+
For example wkup-pins-nb = <5>; on the rts5912
16+
17+
child-binding:
18+
description: |
19+
RTS5912 wake-up pin node.
20+
21+
All nodes using this binding must be named "wkup-pin@[index]"
22+
index starts from 0
23+
24+
properties:
25+
reg:
26+
type: array
27+
required: true
28+
description: Wake-up pin identifier, same as "index" in node name
29+
30+
wkup-pin-pol:
31+
type: string
32+
default: rising
33+
description: indicates a wakeup polarity
34+
enum:
35+
- rising
36+
- falling
37+
38+
wkup-pin-mode:
39+
type: string
40+
default: vin
41+
required: true
42+
description: indicates a wakeup pin mode selection
43+
enum:
44+
- vin
45+
- gpio

soc/realtek/ec/rts5912/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ zephyr_sources_ifdef(CONFIG_PM
1313
)
1414

1515
zephyr_sources_ifdef(CONFIG_RTS5912_DEBUG_SWJ debug_swj.c)
16+
zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c)
17+
zephyr_sources_ifdef(CONFIG_SOC_RTS5912_ULPM rts5912_ulpm.c)
1618

1719
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")

soc/realtek/ec/rts5912/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ config RTS5912_DEBUG_SWJ
2929
help
3030
Enables the serial wire JTAG connection on the RTS5912 EC.
3131

32+
config SOC_RTS5912_ULPM
33+
bool "Realtek RTS5912 ULPM (Ultra Low Power Mode)"
34+
default y
35+
depends on DT_HAS_REALTEK_RTS5912_ULPM_ENABLED
36+
select HAS_POWEROFF
37+
help
38+
Enable support for RTS5912 ULPM PWR wake-up pins.
39+
3240
endif # SOC_SERIES_RTS5912

soc/realtek/ec/rts5912/poweroff.c

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/poweroff.h>
9+
#include <zephyr/toolchain.h>
10+
#include "rts5912_ulpm.h"
11+
12+
void z_sys_poweroff(void)
13+
{
14+
#ifdef CONFIG_SOC_RTS5912_ULPM
15+
rts5912_ulpm_enable();
16+
#endif /* CONFIG_SOC_RTS5912_ULPM */
17+
18+
/* Spin and wait for ULPM */
19+
while (1) {
20+
;
21+
}
22+
CODE_UNREACHABLE;
23+
}

soc/realtek/ec/rts5912/reg/reg_system.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ typedef struct {
294294
#define SYSTEM_VIVOCTRL_VIN2POL_Msk BIT(SYSTEM_VIVOCTRL_VIN2POL_Pos)
295295
#define SYSTEM_VIVOCTRL_VIN3POL_Pos (15UL)
296296
#define SYSTEM_VIVOCTRL_VIN3POL_Msk BIT(SYSTEM_VIVOCTRL_VIN3POL_Pos)
297-
#define SYSTEM_VIVOCTRL_VIN4POL_Pos (16UL)
298-
#define SYSTEM_VIVOCTRL_VIN4POL_Msk BIT(SYSTEM_VIVOCTRL_VIN4POL_Pos)
297+
#define SYSTEM_VIVOCTRL_VODEF_Pos (16UL)
298+
#define SYSTEM_VIVOCTRL_VODEF_Msk BIT(SYSTEM_VIVOCTRL_VODEF_Pos)
299299
#define SYSTEM_VIVOCTRL_VIN5POL_Pos (17UL)
300300
#define SYSTEM_VIVOCTRL_VIN5POL_Msk BIT(SYSTEM_VIVOCTRL_VIN5POL_Pos)
301301
#define SYSTEM_VIVOCTRL_REGWREN_Pos (30UL)

soc/realtek/ec/rts5912/rts5912_ulpm.c

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/device.h>
9+
#include <zephyr/drivers/gpio.h>
10+
#include <zephyr/devicetree.h>
11+
12+
#include "rts5912_ulpm.h"
13+
#include "reg/reg_system.h"
14+
#include "reg/reg_gpio.h"
15+
#include <zephyr/logging/log.h>
16+
17+
LOG_MODULE_REGISTER(ulpm, CONFIG_SOC_LOG_LEVEL);
18+
19+
#define DT_DRV_COMPAT realtek_rts5912_ulpm
20+
21+
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1, "Unsupported number of instances");
22+
23+
#define ULPM_SLEEP(x) k_msleep(x)
24+
25+
#define RTS5912_ULPM_NODE DT_DRV_INST(0)
26+
27+
#define ULPM_RTS5912_MAX_NB_WKUP_PINS DT_INST_PROP(0, wkup_pins_max)
28+
29+
#define RTS5912_VIN_GPIO_INDEX 112
30+
#define RTS5912_SCCON_REG_BASE ((SYSTEM_Type *)(DT_REG_ADDR(DT_NODELABEL(sccon))))
31+
/** @cond INTERNAL_HIDDEN */
32+
33+
/**
34+
* @brief flags for wake-up pin polarity configuration
35+
* @{
36+
*/
37+
#define RTS5912_ULPM_WKUP_PIN_MODE_VIN 0
38+
#define RTS5912_ULPM_WKUP_PIN_MODE_GPIO 1
39+
/* detection of wake-up event on the high level : rising edge */
40+
#define RTS5912_ULPM_WKUP_PIN_POL_RISING 0
41+
/* detection of wake-up event on the low level : falling edge */
42+
#define RTS5912_ULPM_WKUP_PIN_POL_FALLING 1
43+
/** @} */
44+
45+
/**
46+
* @brief Structure for storing the devicetree configuration of a wake-up pin.
47+
*/
48+
struct wkup_pin_dt_cfg_t {
49+
/* starts from 0 */
50+
uint32_t wkup_pin_id;
51+
/* wake up polarity */
52+
uint8_t wkup_pin_pol;
53+
/* wake up polarity auto detect and set */
54+
bool wkup_pin_pol_auto;
55+
/* wake up pin mode, VIN / GPIO */
56+
uint8_t wkup_pin_mode;
57+
};
58+
59+
#define WKUP_PIN_NODE_LABEL(i) wkup_pin_##i
60+
61+
#define WKUP_PIN_NODE_ID_BY_IDX(idx) DT_CHILD(STM32_PWR_NODE, WKUP_PIN_NODE_LABEL(idx))
62+
63+
/**
64+
* @brief Get wake-up pin configuration from a given devicetree node.
65+
*
66+
* This returns a static initializer for a <tt>struct wkup_pin_dt_cfg_t</tt>
67+
* filled with data from a given devicetree node.
68+
*
69+
* @param node_id Devicetree node identifier.
70+
*
71+
* @return Static initializer for a wkup_pin_dt_cfg_t structure.
72+
*/
73+
#define WKUP_PIN_CFG_DT(node_id) \
74+
{ \
75+
.wkup_pin_id = DT_REG_ADDR(node_id), \
76+
.wkup_pin_pol = (uint8_t)DT_ENUM_IDX(node_id, wkup_pin_pol), \
77+
.wkup_pin_mode = (uint8_t)DT_ENUM_IDX(node_id, wkup_pin_mode), \
78+
}
79+
80+
/* wkup_pin idx starts from 0 */
81+
#define WKUP_PIN_CFG_DT_COMMA(wkup_pin_id) WKUP_PIN_CFG_DT(wkup_pin_id),
82+
83+
/** @endcond */
84+
85+
static struct wkup_pin_dt_cfg_t wkup_pins_cfgs[] = {
86+
DT_INST_FOREACH_CHILD(0, WKUP_PIN_CFG_DT_COMMA)};
87+
88+
#define WKUP_PIN_SIZE ARRAY_SIZE(wkup_pins_cfgs)
89+
/**
90+
* @brief Enable VOUT function and set the VOUT default value.
91+
*/
92+
void ulpm_start(void)
93+
{
94+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
95+
/* enable VOUT */
96+
sys_reg->VIVOCTRL &= ~(SYSTEM_VIVOCTRL_VOUTMD_Msk);
97+
ULPM_SLEEP(10);
98+
/* Set the VOUT to low */
99+
sys_reg->VIVOCTRL &= ~(SYSTEM_VIVOCTRL_VODEF_Msk);
100+
ULPM_SLEEP(10);
101+
/* update to ULPM */
102+
sys_reg->VIVOCTRL |= SYSTEM_VIVOCTRL_REGWREN_Msk;
103+
ULPM_SLEEP(10);
104+
}
105+
/**
106+
* @brief Update register value to ULPM IP
107+
*/
108+
void update_vivo_register(void)
109+
{
110+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
111+
/* Update Register & reset bit */
112+
ULPM_SLEEP(10);
113+
sys_reg->VIVOCTRL |= SYSTEM_VIVOCTRL_REGWREN_Msk;
114+
ULPM_SLEEP(10);
115+
sys_reg->VIVOCTRL &= ~(SYSTEM_VIVOCTRL_REGWREN_Msk);
116+
ULPM_SLEEP(10);
117+
}
118+
119+
/**
120+
* @brief Configure & enable a wake-up pin.
121+
*
122+
* @param wakeup_pin_cfg wake-up pin runtime configuration.
123+
*
124+
*/
125+
void rts5912_ulpm_enable(void)
126+
{
127+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
128+
int i, id;
129+
130+
LOG_INF("rts5912 ULPM enabled\n");
131+
/* VoutEnable, Keep VOUT output default value as bit 16 */
132+
sys_reg->VIVOCTRL |= SYSTEM_VIVOCTRL_VODEF_Msk;
133+
ULPM_SLEEP(10);
134+
135+
/* set to GPIO mode to clear status and aviod mis-trigger */
136+
sys_reg->VIVOCTRL |= (SYSTEM_VIVOCTRL_VIN0MD_Msk | SYSTEM_VIVOCTRL_VIN1MD_Msk |
137+
SYSTEM_VIVOCTRL_VIN2MD_Msk | SYSTEM_VIVOCTRL_VIN3MD_Msk |
138+
SYSTEM_VIVOCTRL_VIN4MD_Msk | SYSTEM_VIVOCTRL_VIN5MD_Msk);
139+
140+
/* Update Status Bit to ULPM IP */
141+
update_vivo_register();
142+
/* Configure Mode (VIN/GPIO) and Edge (Falling/Rising) */
143+
for (i = 0; i < WKUP_PIN_SIZE; i++) {
144+
id = wkup_pins_cfgs[i].wkup_pin_id;
145+
/* corner case test */
146+
if ((id < 0) || (id >= ULPM_RTS5912_MAX_NB_WKUP_PINS)) {
147+
continue;
148+
}
149+
150+
/* Configure Mode */
151+
if (wkup_pins_cfgs[i].wkup_pin_mode == RTS5912_ULPM_WKUP_PIN_MODE_VIN) {
152+
LOG_DBG("setup VIN%d in ", id);
153+
/* Configure Polarity */
154+
if (wkup_pins_cfgs[i].wkup_pin_pol == RTS5912_ULPM_WKUP_PIN_POL_RISING) {
155+
/* Falling Edge */
156+
sys_reg->VIVOCTRL |= BIT(SYSTEM_VIVOCTRL_VIN0POL_Pos + id);
157+
LOG_DBG("Falling Edge\n");
158+
} else {
159+
/* Rising Edge */
160+
sys_reg->VIVOCTRL &= ~BIT(SYSTEM_VIVOCTRL_VIN0POL_Pos + id);
161+
LOG_DBG("Rising Edge\n");
162+
}
163+
/* VIN Mode */
164+
sys_reg->VIVOCTRL &= ~BIT(SYSTEM_VIVOCTRL_VIN0MD_Pos + id);
165+
}
166+
}
167+
168+
/* Update Status Bit to ULPM IP */
169+
update_vivo_register();
170+
171+
/* Disable LDO 2 power. */
172+
sys_reg->LDOCTRL &= ~(SYSTEM_LDOCTRL_LDO2EN_Msk);
173+
174+
/* ULPM Start */
175+
ulpm_start();
176+
}

soc/realtek/ec/rts5912/rts5912_ulpm.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2025 Realtek Semiconductor Corporation, SIBG-SD7
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_SOC_REALTEK_RTS5912_ULPM_H_
8+
#define ZEPHYR_SOC_REALTEK_RTS5912_ULPM_H_
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
void rts5912_ulpm_enable(void);
15+
16+
#ifdef __cplusplus
17+
}
18+
#endif
19+
20+
#endif /* ZEPHYR_SOC_REALTEK_RTS5912_ULPM_H_ */

0 commit comments

Comments
 (0)