1 /*
2 * Copyright (c) 2020 - 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <nrf_802154_config.h>
8 #include <platform/nrf_802154_clock.h>
9
10 #include <stddef.h>
11
12 #include <compiler_abstraction.h>
13 #include <zephyr/kernel.h>
14 #if defined(CONFIG_CLOCK_CONTROL_NRF)
15 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
16 #include <zephyr/drivers/clock_control.h>
17 #elif !defined(NRF54H_SERIES)
18 #error No implementation to start or stop HFCLK due to missing clock_control.
19 #endif
20
21 static bool hfclk_is_running;
22
nrf_802154_clock_init(void)23 void nrf_802154_clock_init(void)
24 {
25 /* Intentionally empty. */
26 }
27
nrf_802154_clock_deinit(void)28 void nrf_802154_clock_deinit(void)
29 {
30 /* Intentionally empty. */
31 }
32
nrf_802154_clock_hfclk_is_running(void)33 bool nrf_802154_clock_hfclk_is_running(void)
34 {
35 return hfclk_is_running;
36 }
37
38 #if defined(CONFIG_CLOCK_CONTROL_NRF)
39
40 static struct onoff_client hfclk_cli;
41
hfclk_on_callback(struct onoff_manager * mgr,struct onoff_client * cli,uint32_t state,int res)42 static void hfclk_on_callback(struct onoff_manager *mgr,
43 struct onoff_client *cli,
44 uint32_t state,
45 int res)
46 {
47 hfclk_is_running = true;
48 nrf_802154_clock_hfclk_ready();
49 }
50
nrf_802154_clock_hfclk_start(void)51 void nrf_802154_clock_hfclk_start(void)
52 {
53 int ret;
54 struct onoff_manager *mgr =
55 z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
56
57 __ASSERT_NO_MSG(mgr != NULL);
58
59 sys_notify_init_callback(&hfclk_cli.notify, hfclk_on_callback);
60
61 ret = onoff_request(mgr, &hfclk_cli);
62 __ASSERT_NO_MSG(ret >= 0);
63 }
64
nrf_802154_clock_hfclk_stop(void)65 void nrf_802154_clock_hfclk_stop(void)
66 {
67 int ret;
68 struct onoff_manager *mgr =
69 z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF);
70
71 __ASSERT_NO_MSG(mgr != NULL);
72
73 ret = onoff_cancel_or_release(mgr, &hfclk_cli);
74 __ASSERT_NO_MSG(ret >= 0);
75 hfclk_is_running = false;
76 }
77
78 #elif defined(NRF54H_SERIES)
79
80 #define NRF_LRCCONF_RADIO_PD NRF_LRCCONF010
81 /* HF clock time to ramp-up. */
82 #define MAX_HFXO_RAMP_UP_TIME_US 550
83
hfclk_started_timer_handler(struct k_timer * dummy)84 static void hfclk_started_timer_handler(struct k_timer *dummy)
85 {
86 hfclk_is_running = true;
87 nrf_802154_clock_hfclk_ready();
88 }
89
90 K_TIMER_DEFINE(hfclk_started_timer, hfclk_started_timer_handler, NULL);
91
nrf_802154_clock_hfclk_start(void)92 void nrf_802154_clock_hfclk_start(void)
93 {
94 /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger.
95 * This code might cause troubles if there are other HFXO users in this CPU.
96 */
97 NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0;
98 NRF_LRCCONF_RADIO_PD->TASKS_REQHFXO = 0x1;
99
100 k_timer_start(&hfclk_started_timer, K_USEC(MAX_HFXO_RAMP_UP_TIME_US), K_NO_WAIT);
101 }
102
nrf_802154_clock_hfclk_stop(void)103 void nrf_802154_clock_hfclk_stop(void)
104 {
105 /* Use register directly, there is no support for that task in nrf_lrcconf_task_trigger.
106 * This code might cause troubles if there are other HFXO users in this CPU.
107 */
108 NRF_LRCCONF_RADIO_PD->TASKS_STOPREQHFXO = 0x1;
109 NRF_LRCCONF_RADIO_PD->EVENTS_HFXOSTARTED = 0x0;
110
111 hfclk_is_running = false;
112 }
113
114 #endif
115