Skip to content

Commit 8f98fdb

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 58e5145 commit 8f98fdb

File tree

8 files changed

+387
-0
lines changed

8 files changed

+387
-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: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
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+
//TODO check all defines if they are used
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+
#ifdef CONFIG_LOG
63+
const char *name;
64+
#endif
65+
} hfclk192m_config_t;
66+
67+
static int set_off_state(uint32_t *flags, uint32_t ctx)
68+
{
69+
int err = 0;
70+
unsigned int key = irq_lock();
71+
uint32_t current_ctx = GET_CTX(*flags);
72+
73+
if ((current_ctx != 0) && (current_ctx != ctx)) {
74+
err = -EPERM;
75+
} else {
76+
*flags = CLOCK_CONTROL_STATUS_OFF;
77+
}
78+
79+
irq_unlock(key);
80+
81+
return err;
82+
}
83+
84+
static int set_starting_state(uint32_t *flags, uint32_t ctx)
85+
{
86+
int err = 0;
87+
unsigned int key = irq_lock();
88+
uint32_t current_ctx = GET_CTX(*flags);
89+
90+
if ((*flags & (STATUS_MASK)) == CLOCK_CONTROL_STATUS_OFF) {
91+
*flags = CLOCK_CONTROL_STATUS_STARTING | ctx;
92+
} else if (current_ctx != ctx) {
93+
err = -EPERM;
94+
} else {
95+
err = -EALREADY;
96+
}
97+
98+
irq_unlock(key);
99+
100+
return err;
101+
}
102+
103+
static void set_on_state(uint32_t *flags)
104+
{
105+
unsigned int key = irq_lock();
106+
107+
*flags = CLOCK_CONTROL_STATUS_ON | GET_CTX(*flags);
108+
irq_unlock(key);
109+
}
110+
111+
static void clkstarted_handle(const struct device *dev)
112+
{
113+
clock_control_cb_t callback = ((hfclk192m_data_t *)dev->data)->cb;
114+
115+
((hfclk192m_data_t *)dev->data)->cb = NULL;
116+
set_on_state(&((hfclk192m_data_t *)dev->data)->flags);
117+
DBG(dev, "Clock started");
118+
119+
if (callback) {
120+
callback(dev, NULL, (hfclk192m_data_t *)dev->data)->user_data);
121+
}
122+
}
123+
124+
static void hfclk192m_start(void)
125+
{
126+
nrfx_clock_hfclk192m_start();
127+
}
128+
129+
static void hfclk192m_stop(void)
130+
{
131+
nrfx_clock_hfclk192m_stop();
132+
}
133+
134+
static int stop(const struct device *dev, uint32_t ctx)
135+
{
136+
int err;
137+
138+
err = set_off_state(&((hfclk192m_data_t *)dev->data)->flags, ctx);
139+
if (err < 0) {
140+
return err;
141+
}
142+
143+
((hfclk192m_config_t *)dev->config)->stop();
144+
145+
return 0;
146+
}
147+
148+
static int async_start(const struct device *dev, clock_control_cb_t cb, void *user_data,
149+
uint32_t ctx)
150+
{
151+
int err;
152+
153+
err = set_starting_state(&((hfclk192m_data_t *)dev->data)->flags, ctx);
154+
if (err < 0) {
155+
return err;
156+
}
157+
158+
((hfclk192m_data_t *)dev->data)->cb = cb;
159+
((hfclk192m_data_t *)dev->data)->user_data = user_data;
160+
161+
((hfclk192m_config_t *)dev->config)->start();
162+
163+
return 0;
164+
}
165+
166+
static void blocking_start_callback(const struct device *dev,
167+
clock_control_subsys_t subsys,
168+
void *user_data)
169+
{
170+
ARG_UNUSED(subsys);
171+
172+
struct k_sem *sem = user_data;
173+
174+
k_sem_give(sem);
175+
}
176+
177+
static void onoff_stop(struct onoff_manager *mgr,
178+
onoff_notify_fn notify)
179+
{
180+
int res;
181+
182+
res = stop(CLOCK_DEVICE_HFCLK192M, CTX_ONOFF);
183+
notify(mgr, res);
184+
}
185+
186+
static void onoff_started_callback(const struct device *dev,
187+
clock_control_subsys_t sys,
188+
void *user_data)
189+
{
190+
ARG_UNUSED(sys);
191+
192+
onoff_notify_fn notify = user_data;
193+
194+
notify(&((hfclk192m_data_t *)dev->data)->mgr, 0);
195+
}
196+
197+
static void onoff_start(struct onoff_manager *mgr,
198+
onoff_notify_fn notify)
199+
{
200+
int err;
201+
202+
err = async_start(CLOCK_DEVICE_HFCLK192M, onoff_started_callback, notify, CTX_ONOFF);
203+
if (err < 0) {
204+
notify(mgr, err);
205+
}
206+
}
207+
208+
static void clock_event_handler(void)
209+
{
210+
const struct device *dev = CLOCK_DEVICE_HFCLK192M;
211+
212+
clkstarted_handle(dev);
213+
}
214+
215+
static int api_start(const struct device *dev, clock_control_subsys_t subsys,
216+
clock_control_cb_t cb, void *user_data)
217+
{
218+
ARG_UNUSED(subsys);
219+
220+
return async_start(dev, cb, user_data, CTX_API);
221+
}
222+
223+
static int api_blocking_start(const struct device *dev,
224+
clock_control_subsys_t subsys)
225+
{
226+
struct k_sem sem = Z_SEM_INITIALIZER(sem, 0, 1);
227+
int err;
228+
229+
if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
230+
return -ENOTSUP;
231+
}
232+
233+
err = api_start(dev, subsys, blocking_start_callback, &sem);
234+
if (err < 0) {
235+
return err;
236+
}
237+
238+
return k_sem_take(&sem, K_MSEC(500));
239+
}
240+
241+
static int api_stop(const struct device *dev, clock_control_subsys_t subsys)
242+
{
243+
ARG_UNUSED(subsys);
244+
245+
return stop(dev, CTX_API);
246+
}
247+
248+
static enum clock_control_status api_get_status(const struct device *dev,
249+
clock_control_subsys_t subsys)
250+
{
251+
ARG_UNUSED(subsys);
252+
253+
return GET_STATUS(((hfclk192m_data_t *)dev->data)->flags);
254+
}
255+
256+
static int api_request(const struct device *dev,
257+
const struct nrf_clock_spec *spec,
258+
struct onoff_client *cli)
259+
{
260+
hfclk192m_data_t *dev_data = dev->data;
261+
262+
ARG_UNUSED(spec);
263+
264+
return onoff_request(&dev_data->mgr, cli);
265+
}
266+
267+
static int api_release(const struct device *dev,
268+
const struct nrf_clock_spec *spec)
269+
{
270+
hfclk192m_data_t *dev_data = dev->data;
271+
272+
ARG_UNUSED(spec);
273+
274+
return onoff_release(&dev_data->mgr);
275+
}
276+
277+
static int api_cancel_or_release(const struct device *dev,
278+
const struct nrf_clock_spec *spec,
279+
struct onoff_client *cli)
280+
{
281+
hfclk192m_data_t *dev_data = dev->data;
282+
283+
ARG_UNUSED(spec);
284+
285+
return onoff_cancel_or_release(&dev_data->mgr, cli);
286+
}
287+
288+
static int clk_init(const struct device *dev)
289+
{
290+
nrfx_err_t nrfx_err;
291+
int err;
292+
static const struct onoff_transitions transitions = {
293+
.start = onoff_start,
294+
.stop = onoff_stop
295+
};
296+
297+
clock_control_nrf_common_connect_irq();
298+
299+
nrfx_err = nrfx_clock_hfclk192m_init(clock_event_handler);
300+
if (nrfx_err != NRFX_SUCCESS) {
301+
return -EIO;
302+
}
303+
304+
err = onoff_manager_init(&((hfclk192m_data_t *)dev->data)->mgr,
305+
&transitions);
306+
if (err < 0) {
307+
return err;
308+
}
309+
310+
((hfclk192m_data_t *)dev->data)->flags = CLOCK_CONTROL_STATUS_OFF;
311+
312+
return 0;
313+
}
314+
315+
CLOCK_CONTROL_NRF_IRQ_HANDLERS_ITERABLE(clock_control_nrf_hfclk192m,
316+
&nrfx_clock_hfclk192m_irq_handler);
317+
318+
static DEVICE_API(nrf_clock_control, clock_control_api) = {
319+
.std_api = {
320+
.on = api_blocking_start,
321+
.off = api_stop,
322+
.async_on = api_start,
323+
.get_status = api_get_status,
324+
},
325+
.request = api_request,
326+
.release = api_release,
327+
.cancel_or_release = api_cancel_or_release,
328+
};
329+
330+
static hfclk192m_data_t data;
331+
332+
static const hfclk192m_config_t config = {
333+
.start = hfclk192m_start,
334+
.stop = hfclk192m_stop,
335+
IF_ENABLED(CONFIG_LOG, (.name = "hfclk192m",))
336+
};
337+
338+
DEVICE_DT_DEFINE(DT_NODELABEL(hfclk192m), clk_init, NULL,
339+
&data, &config,
340+
PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
341+
&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

0 commit comments

Comments
 (0)