Skip to content

Commit a0a6b04

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 #: 99290 Signed-off-by: Michal Frankiewicz <[email protected]>
1 parent 1fa000e commit a0a6b04

File tree

7 files changed

+366
-0
lines changed

7 files changed

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

tests/drivers/clock_control/clock_control_api/src/nrf_device_subsys.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ static const struct device_subsys_data subsys_data_lfclk[] = {
3232
}
3333
};
3434
#endif /* !defined(CONFIG_SOC_NRF52832) */
35+
#if NRF_CLOCK_HAS_HFCLK192M
36+
static const struct device_subsys_data subsys_data_hfclk192m[] = {
37+
{
38+
.subsys = CLOCK_CONTROL_NRF_SUBSYS_HF192M,
39+
.startup_us = 5
40+
}
41+
};
42+
#endif /* NRF_CLOCK_HAS_HFCLK192M */
3543

3644
static const struct device_data devices[] = {
3745
#if NRF_CLOCK_HAS_HFCLK
@@ -59,4 +67,11 @@ static const struct device_data devices[] = {
5967
.subsys_cnt = ARRAY_SIZE(subsys_data_lfclk)
6068
},
6169
#endif /* !defined(CONFIG_SOC_NRF52832) */
70+
#if NRF_CLOCK_HAS_HFCLK192M
71+
{
72+
.dev = DEVICE_DT_GET_ONE(nordic_nrf_clock_hfclk192m),
73+
.subsys_data = subsys_data_hfclk192m,
74+
.subsys_cnt = ARRAY_SIZE(subsys_data_hfclk192m)
75+
},
76+
#endif /* NRF_CLOCK_HAS_HFCLK192M */
6277
};

0 commit comments

Comments
 (0)