Skip to content

Commit 899a506

Browse files
adamkondraciukjukkar
authored andcommitted
[nrf fromtree] soc: nordic: Add LRCCONF management
Due to the possibility of simultaneous accesess to LRCCONF registers, additional management is required. Signed-off-by: Adam Kondraciuk <[email protected]> (cherry picked from commit 9b25285) (cherry picked from commit b70ab60)
1 parent a051156 commit 899a506

File tree

9 files changed

+213
-110
lines changed

9 files changed

+213
-110
lines changed

drivers/clock_control/clock_control_nrf2_common.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55

66
#include "clock_control_nrf2_common.h"
7-
#include <hal/nrf_lrcconf.h>
87

98
#include <zephyr/logging/log.h>
109
LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
@@ -25,9 +24,6 @@ LOG_MODULE_REGISTER(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
2524
*/
2625
STRUCT_CLOCK_CONFIG(generic, ONOFF_CNT_MAX);
2726

28-
static sys_slist_t poweron_main_list;
29-
static struct k_spinlock poweron_main_lock;
30-
3127
static void update_config(struct clock_config_generic *cfg)
3228
{
3329
atomic_val_t prev_flags = atomic_or(&cfg->flags, FLAG_UPDATE_NEEDED);
@@ -163,34 +159,3 @@ int api_nosys_on_off(const struct device *dev, clock_control_subsys_t sys)
163159

164160
return -ENOSYS;
165161
}
166-
167-
void clock_request_lrcconf_poweron_main(struct clock_lrcconf_sink *sink)
168-
{
169-
K_SPINLOCK(&poweron_main_lock) {
170-
if (sys_slist_len(&poweron_main_list) == 0) {
171-
LOG_DBG("%s forced on", "main domain");
172-
NRF_LRCCONF010->POWERON &= ~LRCCONF_POWERON_MAIN_Msk;
173-
NRF_LRCCONF010->POWERON |= LRCCONF_POWERON_MAIN_AlwaysOn;
174-
}
175-
176-
sys_slist_find_and_remove(&poweron_main_list, &sink->node);
177-
sys_slist_append(&poweron_main_list, &sink->node);
178-
}
179-
}
180-
181-
void clock_release_lrcconf_poweron_main(struct clock_lrcconf_sink *sink)
182-
{
183-
K_SPINLOCK(&poweron_main_lock) {
184-
if (!sys_slist_find_and_remove(&poweron_main_list, &sink->node)) {
185-
K_SPINLOCK_BREAK;
186-
}
187-
188-
if (sys_slist_len(&poweron_main_list) > 0) {
189-
K_SPINLOCK_BREAK;
190-
}
191-
192-
LOG_DBG("%s automatic", "main domain");
193-
NRF_LRCCONF010->POWERON &= ~LRCCONF_POWERON_MAIN_Msk;
194-
NRF_LRCCONF010->POWERON |= LRCCONF_POWERON_MAIN_Automatic;
195-
}
196-
}

drivers/clock_control/clock_control_nrf2_common.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,4 @@ void clock_config_update_end(void *clk_cfg, int status);
7575

7676
int api_nosys_on_off(const struct device *dev, clock_control_subsys_t sys);
7777

78-
struct clock_lrcconf_sink {
79-
sys_snode_t node;
80-
};
81-
82-
/**
83-
* @brief Request or release lrcconf main power domain
84-
*/
85-
void clock_request_lrcconf_poweron_main(struct clock_lrcconf_sink *sink);
86-
void clock_release_lrcconf_poweron_main(struct clock_lrcconf_sink *sink);
87-
8878
#endif /* ZEPHYR_DRIVERS_CLOCK_CONTROL_NRF2_COMMON_H_ */

drivers/clock_control/clock_control_nrf2_fll16m.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "clock_control_nrf2_common.h"
99
#include <zephyr/devicetree.h>
1010
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
11-
#include <hal/nrf_lrcconf.h>
11+
#include <soc_lrcconf.h>
1212

1313
#include <zephyr/logging/log.h>
1414
LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
@@ -64,7 +64,7 @@ static const struct clock_options {
6464
struct fll16m_dev_data {
6565
STRUCT_CLOCK_CONFIG(fll16m, ARRAY_SIZE(clock_options)) clk_cfg;
6666
struct onoff_client hfxo_cli;
67-
struct clock_lrcconf_sink lrcconf_sink;
67+
sys_snode_t fll16m_node;
6868
};
6969

7070
struct fll16m_dev_config {
@@ -76,13 +76,13 @@ static void activate_fll16m_mode(struct fll16m_dev_data *dev_data, uint8_t mode)
7676
/* TODO: change to nrf_lrcconf_* function when such is available. */
7777

7878
if (mode != FLL16M_MODE_DEFAULT) {
79-
clock_request_lrcconf_poweron_main(&dev_data->lrcconf_sink);
79+
soc_lrcconf_poweron_request(&dev_data->fll16m_node, NRF_LRCCONF_POWER_MAIN);
8080
}
8181

8282
NRF_LRCCONF010->CLKCTRL[0].SRC = mode;
8383

8484
if (mode == FLL16M_MODE_DEFAULT) {
85-
clock_release_lrcconf_poweron_main(&dev_data->lrcconf_sink);
85+
soc_lrcconf_poweron_release(&dev_data->fll16m_node, NRF_LRCCONF_POWER_MAIN);
8686
}
8787

8888
nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_CLKSTART_0);

drivers/clock_control/clock_control_nrf2_hfxo.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <zephyr/logging/log.h>
1212
LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
1313

14-
#include <hal/nrf_lrcconf.h>
14+
#include <soc_lrcconf.h>
1515

1616
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1,
1717
"multiple instances not supported");
@@ -20,7 +20,7 @@ struct dev_data_hfxo {
2020
struct onoff_manager mgr;
2121
onoff_notify_fn notify;
2222
struct k_timer timer;
23-
struct clock_lrcconf_sink lrcconf_sink;
23+
sys_snode_t hfxo_node;
2424
};
2525

2626
struct dev_config_hfxo {
@@ -58,7 +58,7 @@ static void onoff_start_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify)
5858
dev_data->notify = notify;
5959

6060
nrf_lrcconf_event_clear(NRF_LRCCONF010, NRF_LRCCONF_EVENT_HFXOSTARTED);
61-
clock_request_lrcconf_poweron_main(&dev_data->lrcconf_sink);
61+
soc_lrcconf_poweron_request(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN);
6262
nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_REQHFXO);
6363

6464
/* Due to a hardware issue, the HFXOSTARTED event is currently
@@ -74,7 +74,7 @@ static void onoff_stop_hfxo(struct onoff_manager *mgr, onoff_notify_fn notify)
7474
CONTAINER_OF(mgr, struct dev_data_hfxo, mgr);
7575

7676
nrf_lrcconf_task_trigger(NRF_LRCCONF010, NRF_LRCCONF_TASK_STOPREQHFXO);
77-
clock_release_lrcconf_poweron_main(&dev_data->lrcconf_sink);
77+
soc_lrcconf_poweron_release(&dev_data->hfxo_node, NRF_LRCCONF_POWER_MAIN);
7878
notify(mgr, 0);
7979
}
8080

soc/nordic/common/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ if(CONFIG_ARM)
1212
endif()
1313

1414
zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c)
15+
if(CONFIG_ARM)
16+
zephyr_library_sources_ifdef(CONFIG_NRF_PLATFORM_HALTIUM soc_lrcconf.c)
17+
endif()
1518

1619
if((CONFIG_SOC_SERIES_NRF54HX OR CONFIG_SOC_SERIES_NRF92X) AND CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS)
1720
zephyr_library_sources(nrf54hx_nrf92x_mpu_regions.c)

soc/nordic/common/soc_lrcconf.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <soc_lrcconf.h>
8+
#include <zephyr/kernel.h>
9+
10+
static struct k_spinlock lock;
11+
static sys_slist_t poweron_main_list;
12+
static sys_slist_t poweron_active_list;
13+
14+
void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
15+
{
16+
__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
17+
18+
sys_slist_t *poweron_list;
19+
20+
if (domain == NRF_LRCCONF_POWER_MAIN) {
21+
poweron_list = &poweron_main_list;
22+
} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
23+
poweron_list = &poweron_active_list;
24+
} else {
25+
return;
26+
}
27+
28+
K_SPINLOCK(&lock) {
29+
if (sys_slist_len(poweron_list) == 0) {
30+
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, true);
31+
}
32+
33+
sys_slist_find_and_remove(poweron_list, node);
34+
sys_slist_append(poweron_list, node);
35+
}
36+
}
37+
38+
void soc_lrcconf_poweron_release(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain)
39+
{
40+
__ASSERT(is_power_of_two(domain), "Only one bit can be set for the domain parameter");
41+
42+
sys_slist_t *poweron_list;
43+
44+
if (domain == NRF_LRCCONF_POWER_MAIN) {
45+
poweron_list = &poweron_main_list;
46+
} else if (domain == NRF_LRCCONF_POWER_DOMAIN_0) {
47+
poweron_list = &poweron_active_list;
48+
} else {
49+
return;
50+
}
51+
52+
K_SPINLOCK(&lock) {
53+
if (!sys_slist_find_and_remove(poweron_list, node)) {
54+
K_SPINLOCK_BREAK;
55+
}
56+
57+
if (sys_slist_len(poweron_list) > 0) {
58+
K_SPINLOCK_BREAK;
59+
}
60+
nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, domain, false);
61+
}
62+
}

soc/nordic/common/soc_lrcconf.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* @file nRF SoC specific helpers for lrcconf management
9+
*/
10+
11+
#ifndef ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_
12+
#define ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_
13+
14+
#include <hal/nrf_lrcconf.h>
15+
16+
/**
17+
* @brief Request lrcconf power domain
18+
*
19+
* @param node Pointer to the @ref sys_snode_t structure which is the ID of the
20+
* requesting module.
21+
* @param domain The mask that represents the power domain ID.
22+
*/
23+
void soc_lrcconf_poweron_request(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain);
24+
25+
/**
26+
* @brief Release lrcconf power domain
27+
*
28+
* @param node Pointer to the @ref sys_snode_t structure which is the ID of the
29+
* requesting module.
30+
* @param domain The mask that represents the power domain ID.
31+
*/
32+
void soc_lrcconf_poweron_release(sys_snode_t *node, nrf_lrcconf_power_domain_mask_t domain);
33+
34+
#endif /* ZEPHYR_SOC_NORDIC_COMMON_LRCCONF_H_ */

0 commit comments

Comments
 (0)