Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 66 additions & 6 deletions drivers/serial/uart_renesas_rx_sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <soc.h>
#include <zephyr/irq.h>
#include <zephyr/spinlock.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>

#include "r_sci_rx_if.h"
#include "iodefine_sci.h"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -324,13 +334,19 @@ 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)
{
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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -804,21 +825,50 @@ 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;
}

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,
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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 = { \
Expand All @@ -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)
16 changes: 16 additions & 0 deletions dts/rx/renesas/rx130-common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
7 changes: 7 additions & 0 deletions modules/Kconfig.renesas
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 4 additions & 0 deletions soc/renesas/rx/rx130/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
1 change: 1 addition & 0 deletions soc/renesas/rx/rx130/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
75 changes: 75 additions & 0 deletions soc/renesas/rx/rx130/power.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2025 Renesas Electronics Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <soc.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/pm.h>
#include <zephyr/logging/log.h>

#include <r_lpc_rx_if.h>

#ifdef CONFIG_RENESAS_RX_DTC
#include <zephyr/drivers/misc/renesas_rx_dtc/renesas_rx_dtc.h>
#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
}
}
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ manifest:
- hal
- name: hal_renesas
path: modules/hal/renesas
revision: 3ce2bdc7f5cb19b961c015ba561b0cf15f7df3b4
revision: 8c5505d957db35816f3f2ddc93f6805fd648a90c
groups:
- hal
- name: hal_rpi_pico
Expand Down