Skip to content

Commit d6e7492

Browse files
committed
[nrf fromlist] drivers: clock_control: Separated nrf hfclk192m shim from nrf clock shim.
Separated clock_control_nrf_hfclk192m shim from clock_control_nrf shim. Upstream PR #: 97372 Signed-off-by: Michal Frankiewicz <[email protected]>
1 parent 7aba91b commit d6e7492

File tree

8 files changed

+383
-0
lines changed

8 files changed

+383
-0
lines changed

drivers/clock_control/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_AUXPLL clock_cont
6363
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HFCLK clock_control_nrf_hfclk.c)
6464
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_XO clock_control_nrf_xo.c)
6565
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_LFCLK clock_control_nrf_lfclk.c)
66+
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HFCLK192M clock_control_nrf_hfclk192m.c)
6667
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_COMMON clock_control_nrf_common.c)
6768
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL60X clock_control_bl60x.c)
6869
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL61X clock_control_bl61x.c)

drivers/clock_control/Kconfig.nrf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ config CLOCK_CONTROL_NRF_LFCLK
344344
select CLOCK_CONTROL_NRF_COMMON
345345
default y
346346

347+
config CLOCK_CONTROL_NRF_HFCLK192M
348+
bool "NRF HFCLK192M driver support"
349+
depends on DT_HAS_NORDIC_NRF_CLOCK_HFCLK192M_ENABLED
350+
select CLOCK_CONTROL_NRF_COMMON
351+
default y
352+
347353
config CLOCK_CONTROL_NRF_AUXPLL
348354
bool "nRF Auxiliary PLL driver"
349355
default y
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
/*
2+
* Copyright (c) 2016-2020 Nordic Semiconductor ASA
3+
* Copyright (c) 2016 Vinayak Kariappa Chettimada
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <soc.h>
9+
#include <zephyr/sys/onoff.h>
10+
#include <zephyr/drivers/clock_control.h>
11+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
12+
#include "nrf_clock_calibration.h"
13+
#include "clock_control_nrf_common.h"
14+
#include <nrfx_clock_hfclk192m.h>
15+
#include <zephyr/logging/log.h>
16+
#include <zephyr/shell/shell.h>
17+
#include <zephyr/irq.h>
18+
#include <nrf_erratas.h>
19+
20+
LOG_MODULE_REGISTER(clock_control_hfclk192m, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
21+
22+
#define DT_DRV_COMPAT nordic_nrf_clock_hfclk192m
23+
24+
#define CLOCK_DEVICE_HFCLK192M DEVICE_DT_GET(DT_NODELABEL(hfclk192m))
25+
26+
#define CTX_ONOFF BIT(6)
27+
#define CTX_API BIT(7)
28+
#define CTX_MASK (CTX_ONOFF | CTX_API)
29+
30+
#define STATUS_MASK 0x7
31+
#define GET_STATUS(flags) (flags & STATUS_MASK)
32+
#define GET_CTX(flags) (flags & CTX_MASK)
33+
34+
/* Helper logging macros. */
35+
#ifdef CONFIG_LOG
36+
#define CLOCK_LOG(lvl, dev, ...) \
37+
LOG_##lvl("%s: " GET_ARG_N(1, __VA_ARGS__), \
38+
"hfclk192m" \
39+
COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__),\
40+
(), (, GET_ARGS_LESS_N(1, __VA_ARGS__))))
41+
#else
42+
#define CLOCK_LOG(...)
43+
#endif
44+
45+
#define ERR(dev, ...) CLOCK_LOG(ERR, dev, __VA_ARGS__)
46+
#define WRN(dev, ...) CLOCK_LOG(WRN, dev, __VA_ARGS__)
47+
#define INF(dev, ...) CLOCK_LOG(INF, dev, __VA_ARGS__)
48+
#define DBG(dev, ...) CLOCK_LOG(DBG, dev, __VA_ARGS__)
49+
50+
typedef void (*clk_ctrl_func_t)(void);
51+
52+
typedef struct {
53+
struct onoff_manager mgr;
54+
clock_control_cb_t cb;
55+
void *user_data;
56+
uint32_t flags;
57+
} hfclk192m_data_t;
58+
59+
typedef struct {
60+
clk_ctrl_func_t start; /* Clock start function */
61+
clk_ctrl_func_t stop; /* Clock stop function */
62+
} hfclk192m_config_t;
63+
64+
static int set_off_state(uint32_t *flags, uint32_t ctx)
65+
{
66+
int err = 0;
67+
unsigned int key = irq_lock();
68+
uint32_t current_ctx = GET_CTX(*flags);
69+
70+
if ((current_ctx != 0) && (current_ctx != ctx)) {
71+
err = -EPERM;
72+
} else {
73+
*flags = CLOCK_CONTROL_STATUS_OFF;
74+
}
75+
76+
irq_unlock(key);
77+
78+
return err;
79+
}
80+
81+
static int set_starting_state(uint32_t *flags, uint32_t ctx)
82+
{
83+
int err = 0;
84+
unsigned int key = irq_lock();
85+
uint32_t current_ctx = GET_CTX(*flags);
86+
87+
if ((*flags & (STATUS_MASK)) == CLOCK_CONTROL_STATUS_OFF) {
88+
*flags = CLOCK_CONTROL_STATUS_STARTING | ctx;
89+
} else if (current_ctx != ctx) {
90+
err = -EPERM;
91+
} else {
92+
err = -EALREADY;
93+
}
94+
95+
irq_unlock(key);
96+
97+
return err;
98+
}
99+
100+
static void set_on_state(uint32_t *flags)
101+
{
102+
unsigned int key = irq_lock();
103+
104+
*flags = CLOCK_CONTROL_STATUS_ON | GET_CTX(*flags);
105+
irq_unlock(key);
106+
}
107+
108+
static void clkstarted_handle(const struct device *dev)
109+
{
110+
clock_control_cb_t callback = ((hfclk192m_data_t *)dev->data)->cb;
111+
112+
((hfclk192m_data_t *)dev->data)->cb = NULL;
113+
set_on_state(&((hfclk192m_data_t *)dev->data)->flags);
114+
DBG(dev, "Clock started");
115+
116+
if (callback) {
117+
callback(dev, NULL, (hfclk192m_data_t *)dev->data)->user_data);
118+
}
119+
}
120+
121+
static void hfclk192m_start(void)
122+
{
123+
nrfx_clock_hfclk192m_start();
124+
}
125+
126+
static void hfclk192m_stop(void)
127+
{
128+
nrfx_clock_hfclk192m_stop();
129+
}
130+
131+
static int stop(const struct device *dev, uint32_t ctx)
132+
{
133+
int err;
134+
135+
err = set_off_state(&((hfclk192m_data_t *)dev->data)->flags, ctx);
136+
if (err < 0) {
137+
return err;
138+
}
139+
140+
((hfclk192m_config_t *)dev->config)->stop();
141+
142+
return 0;
143+
}
144+
145+
static int async_start(const struct device *dev, clock_control_cb_t cb, void *user_data,
146+
uint32_t ctx)
147+
{
148+
int err;
149+
150+
err = set_starting_state(&((hfclk192m_data_t *)dev->data)->flags, ctx);
151+
if (err < 0) {
152+
return err;
153+
}
154+
155+
((hfclk192m_data_t *)dev->data)->cb = cb;
156+
((hfclk192m_data_t *)dev->data)->user_data = user_data;
157+
158+
((hfclk192m_config_t *)dev->config)->start();
159+
160+
return 0;
161+
}
162+
163+
static void blocking_start_callback(const struct device *dev,
164+
clock_control_subsys_t subsys,
165+
void *user_data)
166+
{
167+
ARG_UNUSED(subsys);
168+
169+
struct k_sem *sem = user_data;
170+
171+
k_sem_give(sem);
172+
}
173+
174+
static void onoff_stop(struct onoff_manager *mgr,
175+
onoff_notify_fn notify)
176+
{
177+
int res;
178+
179+
res = stop(CLOCK_DEVICE_HFCLK192M, CTX_ONOFF);
180+
notify(mgr, res);
181+
}
182+
183+
static void onoff_started_callback(const struct device *dev,
184+
clock_control_subsys_t sys,
185+
void *user_data)
186+
{
187+
ARG_UNUSED(sys);
188+
189+
onoff_notify_fn notify = user_data;
190+
191+
notify(&((hfclk192m_data_t *)dev->data)->mgr, 0);
192+
}
193+
194+
static void onoff_start(struct onoff_manager *mgr,
195+
onoff_notify_fn notify)
196+
{
197+
int err;
198+
199+
err = async_start(CLOCK_DEVICE_HFCLK192M, onoff_started_callback, notify, CTX_ONOFF);
200+
if (err < 0) {
201+
notify(mgr, err);
202+
}
203+
}
204+
205+
static void clock_event_handler(void)
206+
{
207+
const struct device *dev = CLOCK_DEVICE_HFCLK192M;
208+
209+
clkstarted_handle(dev);
210+
}
211+
212+
static int api_start(const struct device *dev, clock_control_subsys_t subsys,
213+
clock_control_cb_t cb, void *user_data)
214+
{
215+
ARG_UNUSED(subsys);
216+
217+
return async_start(dev, cb, user_data, CTX_API);
218+
}
219+
220+
static int api_blocking_start(const struct device *dev,
221+
clock_control_subsys_t subsys)
222+
{
223+
struct k_sem sem = Z_SEM_INITIALIZER(sem, 0, 1);
224+
int err;
225+
226+
if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
227+
return -ENOTSUP;
228+
}
229+
230+
err = api_start(dev, subsys, blocking_start_callback, &sem);
231+
if (err < 0) {
232+
return err;
233+
}
234+
235+
return k_sem_take(&sem, K_MSEC(500));
236+
}
237+
238+
static int api_stop(const struct device *dev, clock_control_subsys_t subsys)
239+
{
240+
ARG_UNUSED(subsys);
241+
242+
return stop(dev, CTX_API);
243+
}
244+
245+
static enum clock_control_status api_get_status(const struct device *dev,
246+
clock_control_subsys_t subsys)
247+
{
248+
ARG_UNUSED(subsys);
249+
250+
return GET_STATUS(((hfclk192m_data_t *)dev->data)->flags);
251+
}
252+
253+
static int api_request(const struct device *dev,
254+
const struct nrf_clock_spec *spec,
255+
struct onoff_client *cli)
256+
{
257+
hfclk192m_data_t *dev_data = dev->data;
258+
259+
ARG_UNUSED(spec);
260+
261+
return onoff_request(&dev_data->mgr, cli);
262+
}
263+
264+
static int api_release(const struct device *dev,
265+
const struct nrf_clock_spec *spec)
266+
{
267+
hfclk192m_data_t *dev_data = dev->data;
268+
269+
ARG_UNUSED(spec);
270+
271+
return onoff_release(&dev_data->mgr);
272+
}
273+
274+
static int api_cancel_or_release(const struct device *dev,
275+
const struct nrf_clock_spec *spec,
276+
struct onoff_client *cli)
277+
{
278+
hfclk192m_data_t *dev_data = dev->data;
279+
280+
ARG_UNUSED(spec);
281+
282+
return onoff_cancel_or_release(&dev_data->mgr, cli);
283+
}
284+
285+
static int clk_init(const struct device *dev)
286+
{
287+
nrfx_err_t nrfx_err;
288+
int err;
289+
static const struct onoff_transitions transitions = {
290+
.start = onoff_start,
291+
.stop = onoff_stop
292+
};
293+
294+
clock_control_nrf_common_connect_irq();
295+
296+
nrfx_err = nrfx_clock_hfclk192m_init(clock_event_handler);
297+
if (nrfx_err != NRFX_SUCCESS) {
298+
return -EIO;
299+
}
300+
301+
err = onoff_manager_init(&((hfclk192m_data_t *)dev->data)->mgr,
302+
&transitions);
303+
if (err < 0) {
304+
return err;
305+
}
306+
307+
((hfclk192m_data_t *)dev->data)->flags = CLOCK_CONTROL_STATUS_OFF;
308+
309+
return 0;
310+
}
311+
312+
CLOCK_CONTROL_NRF_IRQ_HANDLERS_ITERABLE(clock_control_nrf_hfclk192m,
313+
&nrfx_clock_hfclk192m_irq_handler);
314+
315+
static DEVICE_API(nrf_clock_control, clock_control_api) = {
316+
.std_api = {
317+
.on = api_blocking_start,
318+
.off = api_stop,
319+
.async_on = api_start,
320+
.get_status = api_get_status,
321+
},
322+
.request = api_request,
323+
.release = api_release,
324+
.cancel_or_release = api_cancel_or_release,
325+
};
326+
327+
static hfclk192m_data_t data;
328+
329+
static const hfclk192m_config_t config = {
330+
.start = hfclk192m_start,
331+
.stop = hfclk192m_stop,
332+
};
333+
334+
DEVICE_DT_DEFINE(DT_NODELABEL(hfclk192m), clk_init, NULL,
335+
&data, &config,
336+
PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
337+
&clock_control_api);

dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ lfclk: lfclk@5000 {
8282
status = "okay";
8383
};
8484

85+
hfclk192m: hfclk192m@5000 {
86+
compatible = "nordic,nrf-clock-hfclk192m";
87+
reg = <0x5000 0x1000>;
88+
interrupts = <5 NRF_DEFAULT_IRQ_PRIORITY>;
89+
status = "okay";
90+
};
91+
8592
power: power@5000 {
8693
compatible = "nordic,nrf-power";
8794
reg = <0x5000 0x1000>;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Nordic nRF hfclk192m clock control node
5+
6+
compatible: "nordic,nrf-clock-hfclk192m"
7+
8+
include: base.yaml
9+
10+
properties:
11+
reg:
12+
required: true
13+
14+
interrupts:
15+
required: true

modules/hal_nordic/nrfx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock.c)
136136
zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock_hfclk.c)
137137
zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock_xo.c)
138138
zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock_lfclk.c)
139+
zephyr_library_sources_ifdef(CONFIG_NRFX_CLOCK ${SRC_DIR}/nrfx_clock_hfclk192m.c)
139140
zephyr_library_sources_ifdef(CONFIG_NRFX_COMP ${SRC_DIR}/nrfx_comp.c)
140141
zephyr_library_sources_ifdef(CONFIG_NRFX_CRACEN ${SRC_DIR}/nrfx_cracen.c)
141142
zephyr_library_sources_ifdef(CONFIG_NRFX_DPPI ${SRC_DIR}/nrfx_dppi.c)

0 commit comments

Comments
 (0)