From 2b75a8188b76b8e3814547e5793689549f5e317e Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Wed, 15 Oct 2025 09:59:43 +0000 Subject: [PATCH 1/3] manifest: hal_renesas: Update revision for hal_renesas Update revision for hal_renesas for lpc support Signed-off-by: Quy Tran --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 4ca483350b2ff..744a097602ba8 100644 --- a/west.yml +++ b/west.yml @@ -226,7 +226,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 3ce2bdc7f5cb19b961c015ba561b0cf15f7df3b4 + revision: 8c5505d957db35816f3f2ddc93f6805fd648a90c groups: - hal - name: hal_rpi_pico From ec32a16dea7eade69c3efcacba76ab01f5976136 Mon Sep 17 00:00:00 2001 From: Phi Tran Date: Mon, 31 Mar 2025 12:09:29 +0700 Subject: [PATCH 2/3] soc: renesas: rx: initial support pm for RX130 Add initial support power management for Renesas RX130 Signed-off-by: Phi Tran --- dts/rx/renesas/rx130-common.dtsi | 16 ++++++ modules/Kconfig.renesas | 7 +++ soc/renesas/rx/rx130/CMakeLists.txt | 4 ++ soc/renesas/rx/rx130/Kconfig | 1 + soc/renesas/rx/rx130/power.c | 75 +++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 soc/renesas/rx/rx130/power.c diff --git a/dts/rx/renesas/rx130-common.dtsi b/dts/rx/renesas/rx130-common.dtsi index d2a0db56c5f18..58463ba4e165f 100644 --- a/dts/rx/renesas/rx130-common.dtsi +++ b/dts/rx/renesas/rx130-common.dtsi @@ -25,8 +25,24 @@ compatible = "renesas,rxv1"; device_type = "cpu"; reg = <0>; + cpu-power-states = <&idle &standby>; status = "okay"; }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <300>; + }; + + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <3000>; + exit-latency-us = <500>; + }; + }; }; icu: interrupt-controller@87000 { diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index cfca82cb3e1f6..63844e8136d9f 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -421,4 +421,11 @@ config USE_RX_RDP_LVD help Enable RX RDP LVD driver +config USE_RX_RDP_LPC + bool + default y + depends on PM + help + Enable RX RDP LPC driver + endif # HAS_RENESAS_RX_RDP diff --git a/soc/renesas/rx/rx130/CMakeLists.txt b/soc/renesas/rx/rx130/CMakeLists.txt index 44936565508f6..1a707b29571fc 100644 --- a/soc/renesas/rx/rx130/CMakeLists.txt +++ b/soc/renesas/rx/rx130/CMakeLists.txt @@ -11,3 +11,7 @@ zephyr_linker_sources(SECTIONS ofsm.ld) zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/rx/linker.ld CACHE INTERNAL "") + +zephyr_sources_ifdef(CONFIG_PM + power.c +) diff --git a/soc/renesas/rx/rx130/Kconfig b/soc/renesas/rx/rx130/Kconfig index 66f481b78cf8a..161a2071447ea 100644 --- a/soc/renesas/rx/rx130/Kconfig +++ b/soc/renesas/rx/rx130/Kconfig @@ -9,6 +9,7 @@ config SOC_SERIES_RX130 select HAS_RENESAS_RX_RDP select CLOCK_CONTROL select SOC_EARLY_INIT_HOOK + select HAS_PM if SOC_SERIES_RX130 if WDT_RENESAS_RX_IWDT_AUTO_START_MODE diff --git a/soc/renesas/rx/rx130/power.c b/soc/renesas/rx/rx130/power.c new file mode 100644 index 0000000000000..56fb9f76560b2 --- /dev/null +++ b/soc/renesas/rx/rx130/power.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_RENESAS_RX_DTC +#include +#endif + +LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); + +#ifdef CONFIG_RENESAS_RX_DTC +static const struct device *const dtc = DEVICE_DT_GET(DT_NODELABEL(dtc)); +#endif + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + int err = 0; + + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + err = R_LPC_LowPowerModeConfigure(LPC_LP_SLEEP); + if (err) { + LOG_DBG("LPC config failed %d", err); + } + err = R_LPC_LowPowerModeActivate(FIT_NO_FUNC); + if (err) { + LOG_DBG("LPC active failed %d", err); + } + break; + case PM_STATE_STANDBY: +#ifdef CONFIG_RENESAS_RX_DTC + err = dtc_renesas_rx_off(dtc); + if (err) { + LOG_DBG("turn off module DTC failed %d", err); + } +#endif + err = R_LPC_LowPowerModeConfigure(LPC_LP_DEEP_SLEEP); + if (err) { + LOG_DBG("LPC config failed %d", err); + } + err = R_LPC_LowPowerModeActivate(FIT_NO_FUNC); + if (err) { + LOG_DBG("LPC active failed %d", err); + } + break; + default: + LOG_DBG("Unsupported power state %u", state); + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + + if (state == PM_STATE_STANDBY) { +#ifdef CONFIG_RENESAS_RX_DTC + int err = dtc_renesas_rx_on(dtc); + + if (err) { + LOG_DBG("turn off module DTC failed %d", err); + } +#endif + } +} From 41138bceb8efbfebf767f6fc15b6c00f881792ff Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Mon, 20 Oct 2025 04:45:32 +0000 Subject: [PATCH 3/3] drivers: serial: Support PM device for serial driver Support PM for serial driver of Renesas RX Signed-off-by: Quy Tran --- drivers/serial/uart_renesas_rx_sci.c | 72 +++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/drivers/serial/uart_renesas_rx_sci.c b/drivers/serial/uart_renesas_rx_sci.c index aa9de7963c59b..afbc0d003c447 100644 --- a/drivers/serial/uart_renesas_rx_sci.c +++ b/drivers/serial/uart_renesas_rx_sci.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "r_sci_rx_if.h" #include "iodefine_sci.h" @@ -60,6 +62,8 @@ static void uart_rx_sci_txi_isr(const struct device *dev); struct uart_rx_sci_config { uint32_t regs; const struct pinctrl_dev_config *pcfg; + const struct device *clock; + struct clock_control_rx_subsys_cfg clock_subsys; }; struct uart_rx_sci_data { @@ -293,6 +297,9 @@ static void uart_rx_irq_tx_enable(const struct device *dev) sci->SCR.BYTE |= (BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); irq_enable(data->tei_irq); +#ifdef CONFIG_PM_DEVICE + pm_device_busy_set(dev); +#endif } static void uart_rx_irq_tx_disable(const struct device *dev) @@ -302,6 +309,9 @@ static void uart_rx_irq_tx_disable(const struct device *dev) sci->SCR.BYTE &= ~(BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); irq_disable(data->tei_irq); +#ifdef CONFIG_PM_DEVICE + pm_device_busy_clear(dev); +#endif } static int uart_rx_irq_tx_ready(const struct device *dev) @@ -324,6 +334,9 @@ static void uart_rx_irq_rx_enable(const struct device *dev) volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.RIE = 1U; +#ifdef CONFIG_PM_DEVICE + pm_device_busy_set(dev); +#endif } static void uart_rx_irq_rx_disable(const struct device *dev) @@ -331,6 +344,9 @@ static void uart_rx_irq_rx_disable(const struct device *dev) volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.RIE = 0U; +#ifdef CONFIG_PM_DEVICE + pm_device_busy_clear(dev); +#endif } static int uart_rx_irq_rx_ready(const struct device *dev) @@ -532,6 +548,11 @@ static int uart_rx_sci_async_tx(const struct device *dev, const uint8_t *buf, si goto end; } +#ifdef CONFIG_PM + pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif + enable_tx(dev); data->tx_buffer = (uint8_t *)buf; data->tx_buf_cap = len; @@ -804,14 +825,12 @@ static int uart_rx_init(const struct device *dev) #endif sci_err = R_SCI_Open(data->channel, SCI_MODE_ASYNC, &data->sci_config, NULL, &data->hdl); - if (sci_err) { return -EIO; } /* Set the Asynchronous Start Bit Edge Detection Select to falling edge on the RXDn pin */ sci_err = R_SCI_Control(data->hdl, SCI_CMD_START_BIT_EDGE, FIT_NO_PTR); - if (sci_err) { return -EIO; } @@ -819,6 +838,37 @@ static int uart_rx_init(const struct device *dev) return 0; } +#ifdef CONFIG_PM_DEVICE +static int uart_rx_sci_pm_action(const struct device *dev, enum pm_device_action action) +{ + const struct uart_rx_sci_config *config = dev->config; + int ret = 0; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + ret = clock_control_on(config->clock, + (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + break; + + case PM_DEVICE_ACTION_SUSPEND: + ret = clock_control_off(config->clock, + (clock_control_subsys_t)&config->clock_subsys); + if (ret < 0) { + return ret; + } + break; + default: + ret = -ENOTSUP; + break; + } + + return ret; +} +#endif + static DEVICE_API(uart, uart_rx_driver_api) = { .poll_in = uart_rx_sci_poll_in, .poll_out = uart_rx_sci_poll_out, @@ -924,6 +974,10 @@ static void uart_rx_sci_tei_isr(const struct device *dev) .data.tx.len = data->tx_buf_cap, }; async_user_callback(dev, &event); +#ifdef CONFIG_PM + pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); +#endif #endif } @@ -1043,6 +1097,12 @@ static void uart_rx_sci_eri_isr(const struct device *dev) static const struct uart_rx_sci_config uart_rx_sci_config_##index = { \ .regs = DT_REG_ADDR(DT_INST_PARENT(index)), \ .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(index)), \ + .clock = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_INST_PARENT(index))), \ + .clock_subsys = \ + { \ + .mstp = DT_CLOCKS_CELL(DT_INST_PARENT(index), mstp), \ + .stop_bit = DT_CLOCKS_CELL(DT_INST_PARENT(index), stop_bit), \ + }, \ }; \ \ static struct uart_rx_sci_data uart_rx_sci_data_##index = { \ @@ -1068,9 +1128,9 @@ static void uart_rx_sci_eri_isr(const struct device *dev) } \ return 0; \ }; \ - \ - DEVICE_DT_INST_DEFINE(index, uart_rx_init_##index, NULL, &uart_rx_sci_data_##index, \ - &uart_rx_sci_config_##index, PRE_KERNEL_1, \ - CONFIG_SERIAL_INIT_PRIORITY, &uart_rx_driver_api); + PM_DEVICE_DT_INST_DEFINE(index, uart_rx_sci_pm_action); \ + DEVICE_DT_INST_DEFINE(index, uart_rx_init_##index, PM_DEVICE_DT_INST_GET(index), \ + &uart_rx_sci_data_##index, &uart_rx_sci_config_##index, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, &uart_rx_driver_api); DT_INST_FOREACH_STATUS_OKAY(UART_RX_INIT)