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
6 changes: 6 additions & 0 deletions drivers/counter/Kconfig.nrfx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ config COUNTER_NRF_RTC
def_bool y
depends on DT_HAS_NORDIC_NRF_RTC_ENABLED

config COUNTER_NRFX_TIMER_USE_CLOCK_CONTROL
def_bool y
depends on $(dt_nodelabel_enabled,timer120) || \
$(dt_nodelabel_enabled,timer121)
select CLOCK_CONTROL

# Internal flag which detects if PPI wrap feature is enabled for any instance
config COUNTER_RTC_WITH_PPI_WRAP
def_bool $(dt_nodelabel_bool_prop,rtc0,ppi-wrap) || \
Expand Down
86 changes: 75 additions & 11 deletions drivers/counter/counter_nrfx_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/counter.h>
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
#include <zephyr/devicetree.h>
#include <hal/nrf_timer.h>
#include <zephyr/sys/atomic.h>

Expand Down Expand Up @@ -32,11 +34,32 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL);
#define MAYBE_CONST_CONFIG const
#endif

#ifdef CONFIG_SOC_NRF54H20_GPD
#include <nrf/gpd.h>

#define NRF_CLOCKS_INSTANCE_IS_FAST(node) \
COND_CODE_1(DT_NODE_HAS_PROP(node, power_domains), \
(IS_EQ(DT_PHA(node, power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
(0))

/* Macro must resolve to literal 0 or 1 */
#define INSTANCE_IS_FAST(idx) NRF_CLOCKS_INSTANCE_IS_FAST(DT_DRV_INST(idx))

#define INSTANCE_IS_FAST_OR(idx) INSTANCE_IS_FAST(idx) ||

#if (DT_INST_FOREACH_STATUS_OKAY(INSTANCE_IS_FAST_OR) 0)
#define COUNTER_ANY_FAST 1
#endif
#endif

struct counter_nrfx_data {
counter_top_callback_t top_cb;
void *top_user_data;
uint32_t guard_period;
atomic_t cc_int_pending;
#ifdef COUNTER_ANY_FAST
atomic_t active;
#endif
};

struct counter_nrfx_ch_data {
Expand All @@ -48,6 +71,10 @@ struct counter_nrfx_config {
struct counter_config_info info;
struct counter_nrfx_ch_data *ch_data;
NRF_TIMER_Type *timer;
#ifdef COUNTER_ANY_FAST
const struct device *clk_dev;
struct nrf_clock_spec clk_spec;
#endif
LOG_INSTANCE_PTR_DECLARE(log);
};

Expand All @@ -61,6 +88,18 @@ static int start(const struct device *dev)
{
const struct counter_nrfx_config *config = dev->config;

#ifdef COUNTER_ANY_FAST
struct counter_nrfx_data *data = dev->data;

if (config->clk_dev && atomic_cas(&data->active, 0, 1)) {
int err;

err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER);
if (err < 0) {
return err;
}
}
#endif
nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_START);

return 0;
Expand All @@ -71,6 +110,18 @@ static int stop(const struct device *dev)
const struct counter_nrfx_config *config = dev->config;

nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_STOP);
#ifdef COUNTER_ANY_FAST
struct counter_nrfx_data *data = dev->data;

if (config->clk_dev && atomic_cas(&data->active, 1, 0)) {
int err;

err = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
if (err < 0) {
return err;
}
}
#endif

return 0;
}
Expand Down Expand Up @@ -403,6 +454,20 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = {
.set_guard_period = set_guard_period,
};

/* Get initialization level of an instance. Instances that requires clock control
* which is using nrfs (IPC) are initialized later.
*/
#define TIMER_INIT_LEVEL(idx) \
COND_CODE_1(INSTANCE_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1))

/* Get initialization priority of an instance. Instances that requires clock control
* which is using nrfs (IPC) are initialized later.
*/
#define TIMER_INIT_PRIO(idx) \
COND_CODE_1(INSTANCE_IS_FAST(idx), \
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
(CONFIG_COUNTER_INIT_PRIORITY))

/*
* Device instantiation is done with node labels due to HAL API
* requirements. In particular, TIMERx_MAX_SIZE values from HALs
Expand All @@ -419,14 +484,6 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = {
irq_handler, DEVICE_DT_INST_GET(idx), 0)) \
)

#if !defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
#define CHECK_MAX_FREQ(idx) \
BUILD_ASSERT(DT_INST_PROP(idx, max_frequency) == \
NRF_TIMER_BASE_FREQUENCY_GET((NRF_TIMER_Type *)DT_INST_REG_ADDR(idx)))
#else
#define CHECK_MAX_FREQ(idx)
#endif

#define COUNTER_NRFX_TIMER_DEVICE(idx) \
BUILD_ASSERT(DT_INST_PROP(idx, prescaler) <= \
TIMER_PRESCALER_PRESCALER_Msk, \
Expand Down Expand Up @@ -456,22 +513,29 @@ static DEVICE_API(counter, counter_nrfx_driver_api) = {
static MAYBE_CONST_CONFIG struct counter_nrfx_config nrfx_counter_##idx##_config = { \
.info = { \
.max_top_value = (uint32_t)BIT64_MASK(DT_INST_PROP(idx, max_bit_width)),\
.freq = DT_INST_PROP(idx, max_frequency) / \
.freq = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)) / \
BIT(DT_INST_PROP(idx, prescaler)), \
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
.channels = CC_TO_ID(DT_INST_PROP(idx, cc_num)), \
}, \
.ch_data = counter##idx##_ch_data, \
.timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \
IF_ENABLED(INSTANCE_IS_FAST(idx), \
(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \
.clk_spec = { \
.frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \
.accuracy = 0, \
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT, \
}, \
)) \
LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx) \
}; \
CHECK_MAX_FREQ(idx); \
DEVICE_DT_INST_DEFINE(idx, \
counter_##idx##_init, \
NULL, \
&counter_##idx##_data, \
&nrfx_counter_##idx##_config.info, \
PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY, \
TIMER_INIT_LEVEL(idx), TIMER_INIT_PRIO(idx), \
&counter_nrfx_driver_api);

DT_INST_FOREACH_STATUS_OKAY(COUNTER_NRFX_TIMER_DEVICE)
5 changes: 5 additions & 0 deletions drivers/serial/Kconfig.nrfx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ rsource "Kconfig.nrfx_uart_instance"
endif

if HAS_HW_NRF_UARTE120

config UART_NRFX_UARTE_USE_CLOCK_CONTROL
def_bool y
select CLOCK_CONTROL

nrfx_uart_num = 120
rsource "Kconfig.nrfx_uart_instance"
endif
Expand Down
83 changes: 64 additions & 19 deletions drivers/serial/uart_nrfx_uarte.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
#include <zephyr/linker/devicetree_regions.h>
#include <zephyr/irq.h>
#include <zephyr/logging/log.h>

#ifdef CONFIG_SOC_NRF54H20_GPD
#include <nrf/gpd.h>
#endif
#include <zephyr/drivers/clock_control/nrf_clock_control.h>

LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);

Expand Down Expand Up @@ -110,17 +107,22 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
#define UARTE_ANY_LOW_POWER 1
#endif

#ifdef CONFIG_SOC_NRF54H20_GPD
#include <nrf/gpd.h>

/* Macro must resolve to literal 0 or 1 */
#define INSTANCE_IS_FAST(unused, prefix, idx, _) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should stay so that it does not take disabled instances into account

(COND_CODE_1(UTIL_AND(IS_ENABLED(CONFIG_SOC_NRF54H20_GPD), \
DT_NODE_HAS_PROP(UARTE(idx), power_domains)), \
(COND_CODE_0(DT_PHA(UARTE(idx), power_domains, id), (1), (0))),\
(0))), (0))
#define INSTANCE_IS_FAST(unused, prefix, idx, _) \
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
(COND_CODE_1(DT_NODE_HAS_PROP(UARTE(idx), power_domains), \
(IS_EQ(DT_PHA(UARTE(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
(0))), (0))

#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST, (||), (0))
/* Fast instance requires special PM treatment so device runtime PM must be enabled. */
BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME));
#define UARTE_ANY_FAST 1
#endif
#endif

#ifdef UARTE_ANY_CACHE
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
Expand Down Expand Up @@ -307,6 +309,10 @@ struct uarte_nrfx_config {
#ifdef CONFIG_HAS_NORDIC_DMM
void *mem_reg;
#endif
#ifdef UARTE_ANY_FAST
const struct device *clk_dev;
struct nrf_clock_spec clk_spec;
#endif
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
/* None-zero in case of high speed instances. Baudrate is adjusted by that ratio. */
uint32_t clock_freq;
Expand Down Expand Up @@ -656,6 +662,16 @@ static void uarte_periph_enable(const struct device *dev)
struct uarte_nrfx_data *data = dev->data;

(void)data;
#ifdef UARTE_ANY_FAST
if (config->clk_dev) {
int err;

err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER);
(void)err;
__ASSERT_NO_MSG(err >= 0);
}
#endif

nrf_uarte_enable(uarte);
#ifdef CONFIG_SOC_NRF54H20_GPD
nrf_gpd_retain_pins_set(config->pcfg, false);
Expand Down Expand Up @@ -737,7 +753,6 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len)
if (LOW_POWER_ENABLED(config)) {
uarte_enable_locked(dev, UARTE_FLAG_LOW_POWER_TX);
}

nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTTX);
}

Expand Down Expand Up @@ -2203,6 +2218,16 @@ static void uarte_pm_suspend(const struct device *dev)
struct uarte_nrfx_data *data = dev->data;

(void)data;
#ifdef UARTE_ANY_FAST
if (cfg->clk_dev) {
int err;

err = nrf_clock_control_release(cfg->clk_dev, &cfg->clk_spec);
(void)err;
__ASSERT_NO_MSG(err >= 0);
}
#endif

#ifdef UARTE_ANY_ASYNC
if (data->async) {
/* Entering inactive state requires device to be no
Expand Down Expand Up @@ -2386,18 +2411,31 @@ static int uarte_instance_init(const struct device *dev,
#define UARTE_DISABLE_RX_INIT(node_id) \
.disable_rx = DT_PROP(node_id, disable_rx)

#define UARTE_GET_FREQ(idx) DT_PROP(DT_CLOCKS_CTLR(UARTE(idx)), clock_frequency)

#define UARTE_GET_BAUDRATE_DIV(idx) \
COND_CODE_1(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
((UARTE_GET_FREQ(idx) / NRF_UARTE_BASE_FREQUENCY_16MHZ)), (1))
/* Get frequency of the clock that driver the UARTE peripheral. Clock node can
* have fixed or variable frequency. For fast UARTE use highest supported frequency.
*/
#define UARTE_GET_BAUDRATE_DIV(idx) \
(NRF_PERIPH_GET_FREQUENCY(UARTE(idx)) / NRF_UARTE_BASE_FREQUENCY_16MHZ)

/* When calculating baudrate we need to take into account that high speed instances
* must have baudrate adjust to the ratio between UARTE clocking frequency and 16 MHz.
*/
#define UARTE_GET_BAUDRATE(idx) \
(NRF_BAUDRATE(UARTE_PROP(idx, current_speed)) / UARTE_GET_BAUDRATE_DIV(idx))

/* Get initialization level of an instance. Instances that requires clock control
* which is using nrfs (IPC) are initialized later.
*/
#define UARTE_INIT_LEVEL(idx) \
COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), (POST_KERNEL), (PRE_KERNEL_1))

/* Get initialization priority of an instance. Instances that requires clock control
* which is using nrfs (IPC) are initialized later.
*/
#define UARTE_INIT_PRIO(idx) \
COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
(CONFIG_SERIAL_INIT_PRIORITY))

/* Macro for setting nRF specific configuration structures. */
#define UARTE_NRF_CONFIG(idx) { \
Expand Down Expand Up @@ -2453,7 +2491,7 @@ static int uarte_instance_init(const struct device *dev,
static const struct uarte_nrfx_config uarte_##idx##z_config = { \
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \
(IF_ENABLED(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
(.clock_freq = UARTE_GET_FREQ(idx),))), \
(.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),))), \
(IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \
(.baudrate = UARTE_PROP(idx, current_speed),)) \
.nrf_baudrate = UARTE_GET_BAUDRATE(idx), \
Expand All @@ -2480,6 +2518,13 @@ static int uarte_instance_init(const struct device *dev,
IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \
(.timer = NRFX_TIMER_INSTANCE( \
CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \
IF_ENABLED(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \
(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(UARTE(idx))), \
.clk_spec = { \
.frequency = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),\
.accuracy = 0, \
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
},)) \
}; \
static int uarte_##idx##_init(const struct device *dev) \
{ \
Expand All @@ -2500,8 +2545,8 @@ static int uarte_instance_init(const struct device *dev,
PM_DEVICE_DT_GET(UARTE(idx)), \
&uarte_##idx##_data, \
&uarte_##idx##z_config, \
PRE_KERNEL_1, \
CONFIG_SERIAL_INIT_PRIORITY, \
UARTE_INIT_LEVEL(idx), \
UARTE_INIT_PRIO(idx), \
&uart_nrfx_uarte_driver_api)

#define UARTE_INT_DRIVEN(idx) \
Expand Down
2 changes: 2 additions & 0 deletions dts/common/nordic/nrf54h20.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@
power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>;
max-bit-width = <32>;
max-frequency = <DT_FREQ_M(320)>;
clocks = <&hsfll120>;
prescaler = <0>;
};

Expand All @@ -639,6 +640,7 @@
power-domains = <&gpd NRF_GPD_FAST_ACTIVE1>;
max-bit-width = <32>;
max-frequency = <DT_FREQ_M(320)>;
clocks = <&hsfll120>;
prescaler = <0>;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ dut: &uart137 {
pinctrl-1 = <&uart137_sleep_alt>;
pinctrl-names = "default", "sleep";
current-speed = <115200>;
zephyr,pm-device-runtime-auto;
};

dut2: &uart120 {
pinctrl-0 = <&uart120_default_alt>;
pinctrl-1 = <&uart120_sleep_alt>;
pinctrl-names = "default", "sleep";
current-speed = <115200>;
zephyr,pm-device-runtime-auto;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y
Loading