1 /*
2  * Copyright (c) 2017 Oticon A/S
3  * Copyright (c) 2023, Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Note that the function prototypes are taken from the NRFx HAL
8  */
9 #include "hal/nrf_clock.h"
10 #include "bs_tracing.h"
11 #if defined(NRF54L15) || defined(NRF54L15_XXAA)
12 #include "NHW_54L_CLOCK.h"
13 #else
14 #include "NHW_CLOCK.h"
15 #endif
16 
clock_number_from_ptr(NRF_CLOCK_Type * p_reg)17 static int clock_number_from_ptr(NRF_CLOCK_Type * p_reg)
18 {
19   union NRF_CLKPWR_Type *p = (union NRF_CLKPWR_Type *)p_reg;
20 
21   int i = ( (int)p - (int)&NRF_CLKPWR_regs[0] ) / sizeof(union NRF_CLKPWR_Type);
22   return i;
23 }
24 
nrf_clock_int_enable(NRF_CLOCK_Type * p_reg,uint32_t mask)25 void nrf_clock_int_enable(NRF_CLOCK_Type * p_reg, uint32_t mask)
26 {
27   p_reg->INTENSET = mask;
28 
29   int i = clock_number_from_ptr(p_reg);
30   nhw_CLOCK_regw_sideeffects_INTENSET(i);
31 }
32 
nrf_clock_int_disable(NRF_CLOCK_Type * p_reg,uint32_t mask)33 void nrf_clock_int_disable(NRF_CLOCK_Type * p_reg, uint32_t mask)
34 {
35   p_reg->INTENCLR = mask;
36 
37   int i = clock_number_from_ptr(p_reg);
38   nhw_CLOCK_regw_sideeffects_INTENCLR(i);
39 }
40 
nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)41 void nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg, nrf_clock_task_t task)
42 {
43   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
44 
45   int i = clock_number_from_ptr(p_reg);
46 
47 #define CASE_TASK(TASKN) \
48   case NRF_CLOCK_TASK_##TASKN: nhw_CLOCK_regw_sideeffects_TASKS_##TASKN(i); break;
49 
50   switch (task) {
51 #if NRF_CLOCK_HAS_XO
52     case NRF_CLOCK_TASK_HFCLKSTART: nhw_CLOCK_regw_sideeffects_TASKS_XOSTART(i); break;
53     case NRF_CLOCK_TASK_HFCLKSTOP : nhw_CLOCK_regw_sideeffects_TASKS_XOSTOP(i);  break;
54 #else
55     CASE_TASK(HFCLKSTART)
56     CASE_TASK(HFCLKSTOP)
57 #endif
58 #if NRF_CLOCK_HAS_PLL
59     CASE_TASK(PLLSTART)
60     CASE_TASK(PLLSTOP)
61 #endif
62     CASE_TASK(LFCLKSTART)
63     CASE_TASK(LFCLKSTOP)
64 #if NRF_CLOCK_HAS_CALIBRATION
65     CASE_TASK(CAL)
66 #endif
67 #if NRF_CLOCK_HAS_CALIBRATION_TIMER
68     CASE_TASK(CTSTART)
69     CASE_TASK(CTSTOP)
70 #endif
71 #if NRF_CLOCK_HAS_HFCLKAUDIO
72     CASE_TASK(HFCLKAUDIOSTART)
73     CASE_TASK(HFCLKAUDIOSTOP)
74 #endif
75 #if NRF_CLOCK_HAS_HFCLK192M
76     CASE_TASK(HFCLK192MSTART)
77     CASE_TASK(HFCLK192MSTOP)
78 #endif
79     //Note: XOTUNE and XOTUNEABORT missing from the HAL at this point
80     default:
81       bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
82       break;
83   }
84 #undef CASE_TASK
85 }
86 
nrf_clock_event_clear(NRF_CLOCK_Type * p_reg,nrf_clock_event_t event)87 void nrf_clock_event_clear(NRF_CLOCK_Type * p_reg, nrf_clock_event_t event)
88 {
89     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
90 
91     int i = clock_number_from_ptr(p_reg);
92     nhw_pwrclk_regw_sideeffects_EVENTS_all(i);
93 }
94 
95 #if defined(DPPI_PRESENT)
96 
nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)97 static void nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,
98                                        nrf_clock_task_t task)
99 {
100   int i = clock_number_from_ptr(p_reg);
101 
102 #define CASE_TASK(TASKN) \
103   case NRF_CLOCK_TASK_##TASKN: nhw_CLOCK_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
104 
105   switch (task) {
106 #if NRF_CLOCK_HAS_XO
107     case NRF_CLOCK_TASK_HFCLKSTART: nhw_CLOCK_regw_sideeffects_SUBSCRIBE_XOSTART(i); break;
108     case NRF_CLOCK_TASK_HFCLKSTOP:  nhw_CLOCK_regw_sideeffects_SUBSCRIBE_XOSTOP(i);  break;
109 #else
110     CASE_TASK(HFCLKSTART)
111     CASE_TASK(HFCLKSTOP)
112 #endif
113 #if NRF_CLOCK_HAS_PLL
114     CASE_TASK(PLLSTART)
115     CASE_TASK(PLLSTOP)
116 #endif
117     CASE_TASK(LFCLKSTART)
118     CASE_TASK(LFCLKSTOP)
119 #if NRF_CLOCK_HAS_CALIBRATION
120     CASE_TASK(CAL)
121 #endif
122 #if NRF_CLOCK_HAS_HFCLKAUDIO
123     CASE_TASK(HFCLKAUDIOSTART)
124     CASE_TASK(HFCLKAUDIOSTOP)
125 #endif
126 #if NRF_CLOCK_HAS_HFCLK192M
127     CASE_TASK(HFCLK192MSTART)
128     CASE_TASK(HFCLK192MSTOP)
129 #endif
130     //Note: XOTUNE and XOTUNEABORT missing from the HAL at this point
131     default:
132       bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_clock (%i)\n",
133                                 task);
134       break;
135   }
136 #undef CASE_TASK
137 }
138 
nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task,uint8_t channel)139 void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,
140                              nrf_clock_task_t task,
141                              uint8_t          channel)
142 {
143     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
144             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
145     nrf_clock_subscribe_common(p_reg, task);
146 }
147 
nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)148 void nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,
149                                nrf_clock_task_t task)
150 {
151     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
152     nrf_clock_subscribe_common(p_reg, task);
153 }
154 
155 #endif /* defined(DPPI_PRESENT) */
156