Skip to content

Commit e6bb7fc

Browse files
Titan-Realtekkartben
authored andcommitted
soc : realtek: ec: rts5912: add support ULPM
Port rts5912 ULPM on Zephyr Signed-off-by: Titan Chen <[email protected]>
1 parent b4c1dc6 commit e6bb7fc

File tree

8 files changed

+312
-2
lines changed

8 files changed

+312
-2
lines changed

dts/arm/realtek/ec/rts5912.dtsi

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,45 @@
372372
&jtag_clk_gpio90 &jtag_tms_gpio91>;
373373
pinctrl-names = "default";
374374
};
375+
376+
ulpm: ulpm {
377+
compatible = "realtek,rts5912-ulpm";
378+
wkup-pins-max = <6>; /* 6 system wake-up pins */
379+
status = "disabled";
380+
381+
#address-cells = <1>;
382+
#size-cells = <0>;
383+
384+
wkup-pin@0 {
385+
reg = <0x0>;
386+
wkup-pin-mode = "gpio";
387+
};
388+
389+
wkup-pin@1 {
390+
reg = <0x1>;
391+
wkup-pin-mode = "gpio";
392+
};
393+
394+
wkup-pin@2 {
395+
reg = <0x2>;
396+
wkup-pin-mode = "gpio";
397+
};
398+
399+
wkup-pin@3 {
400+
reg = <0x3>;
401+
wkup-pin-mode = "gpio";
402+
};
403+
404+
wkup-pin@4 {
405+
reg = <0x4>;
406+
wkup-pin-mode = "gpio";
407+
};
408+
409+
wkup-pin@5 {
410+
reg = <0x5>;
411+
wkup-pin-mode = "gpio";
412+
};
413+
};
375414
};
376415

377416
&nvic {
Lines changed: 45 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 23 additions & 0 deletions
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+
if (IS_ENABLED(CONFIG_SOC_RTS5912_ULPM)) {
15+
rts5912_ulpm_enable();
16+
17+
/* Spin and wait for ULPM */
18+
while (1) {
19+
;
20+
}
21+
CODE_UNREACHABLE;
22+
}
23+
}

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

Lines changed: 4 additions & 2 deletions
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)
@@ -332,4 +332,6 @@ typedef struct {
332332
#define SYSTEM_PERICLKPWR2_RC32KSRC_Pos (30UL)
333333
#define SYSTEM_PERICLKPWR2_RC32KSRC_Msk GENMASK(31, 30)
334334

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