Skip to content

Commit 24798c4

Browse files
ppryga-nordicnordicjm
authored andcommitted
mpsl: clock_ctrl: Add integration layer for nRF54H20
Add integration layer for MPSL external clock driver and nrf2 clock control for nRF5420. This is mandatory for the nRF54H20. Note: The nrf2 clock control requires the MPSL initialization to be done later. The nrf2 clock control depends on nRFS that is initialized at POST_KENREL init level. Its init priority is CONFIG_NRFS_BACKEND_IPC_SERVICE_INIT_PRIO that is lower than former MPSL init level. To make sure the mpsl lfclk request and response is handled corrently we must make the MPSL is initialized after it. Signed-off-by: Piotr Pryga <[email protected]>
1 parent f3d45ca commit 24798c4

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

subsys/mpsl/clock_ctrl/mpsl_clock_ctrl.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ static struct clock_onoff_state m_lfclk_state;
3131

3232
static int32_t m_lfclk_release(void);
3333

34+
#if defined(CONFIG_CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS)
35+
#define MPSL_LFCLK_REQUEST_WAIT_TIMEOUT_MS CONFIG_CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS
36+
#else
3437
#define MPSL_LFCLK_REQUEST_WAIT_TIMEOUT_MS 1000
38+
#endif /* CONFIG_CLOCK_CONTROL_NRF2_NRFS_CLOCK_TIMEOUT_MS */
3539

3640
/** @brief LFCLK request callback.
3741
*
@@ -198,6 +202,106 @@ static bool m_hfclk_is_running(void)
198202
return false;
199203
}
200204

205+
#elif defined(CONFIG_CLOCK_CONTROL_NRF2)
206+
207+
/* Temporary macro because there is no system level configuration of LFCLK source and its accuracy
208+
* for nRF54H SoC series. What more, there is no API to retrieve the information about accuracy of
209+
* available LFCLK.
210+
*/
211+
#define MPSL_LFCLK_ACCURACY_PPM 500
212+
213+
static const struct nrf_clock_spec m_lfclk_specs = {
214+
.frequency = 32768,
215+
.accuracy = MPSL_LFCLK_ACCURACY_PPM,
216+
/* This affects selected LFCLK source. It doesn't switch to higher accuracy but selects more
217+
* precise but current hungry lfclk source.
218+
*/
219+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,
220+
};
221+
222+
static void m_lfclk_calibration_start(void)
223+
{
224+
/* This function is not supported when CONFIG_CLOCK_CONTROL_NRF2 is set.
225+
* As of now MPSL does not use this API in this configuration.
226+
*/
227+
__ASSERT_NO_MSG(false);
228+
}
229+
230+
static bool m_lfclk_calibration_is_enabled(void)
231+
{
232+
/* This function should not be called from MPSL if CONFIG_CLOCK_CONTROL_NRF2 is set */
233+
__ASSERT_NO_MSG(false);
234+
return false;
235+
}
236+
237+
static int32_t m_lfclk_request(void)
238+
{
239+
const struct device *lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
240+
int err;
241+
242+
sys_notify_init_callback(&m_lfclk_state.cli.notify, lfclk_request_cb);
243+
k_sem_init(&m_lfclk_state.sem, 0, 1);
244+
245+
err = nrf_clock_control_request(lfclk_dev, &m_lfclk_specs, &m_lfclk_state.cli);
246+
if (err < 0) {
247+
return err;
248+
}
249+
250+
atomic_inc(&m_lfclk_state.m_clk_refcnt);
251+
252+
return 0;
253+
}
254+
255+
static int32_t m_lfclk_release(void)
256+
{
257+
const struct device *lfclk_dev = DEVICE_DT_GET(DT_NODELABEL(lfclk));
258+
int err;
259+
260+
err = nrf_clock_control_cancel_or_release(lfclk_dev, &m_lfclk_specs, &m_lfclk_state.cli);
261+
if (err < 0) {
262+
return err;
263+
}
264+
265+
atomic_dec(&m_lfclk_state.m_clk_refcnt);
266+
267+
return 0;
268+
}
269+
270+
static void m_hfclk_request(void)
271+
{
272+
if (atomic_inc(&m_hfclk_refcnt) > (atomic_val_t)0) {
273+
return;
274+
}
275+
276+
nrf_clock_control_hfxo_request();
277+
}
278+
279+
static void m_hfclk_release(void)
280+
{
281+
if (atomic_get(&m_hfclk_refcnt) < (atomic_val_t)1) {
282+
LOG_WRN("Mismatch between HFCLK request/release");
283+
return;
284+
}
285+
286+
if (atomic_dec(&m_hfclk_refcnt) > (atomic_val_t)1) {
287+
return;
288+
}
289+
290+
nrf_clock_control_hfxo_release();
291+
}
292+
293+
static bool m_hfclk_is_running(void)
294+
{
295+
/* As of now assume the HFCLK is running after the request was put.
296+
* This puts the responsibility to the user to check if the time
297+
* since last request is larger than the HFXO rampup time.
298+
*/
299+
if (atomic_get(&m_hfclk_refcnt) < (atomic_val_t)1) {
300+
return false;
301+
}
302+
303+
return true;
304+
}
201305
#else
202306
#error "Unsupported clock control"
203307
#endif /* CONFIG_CLOCK_CONTROL_NRF */

0 commit comments

Comments
 (0)