1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-03-30     huijie.feng  first version
9  */
10 
11 #include "cp15.h"
12 #include <rtdef.h>
13 
14 /** Set CNTFRQ
15  *  This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
16  *  @param value: CNTFRQ Register value to set
17  */
__set_cntfrq(rt_uint32_t value)18 static inline void __set_cntfrq(rt_uint32_t value)
19 {
20     __set_cp(15, 0, value, 14, 0, 0);
21 }
22 
23 /** Get CNTFRQ
24  *  This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
25  *  return CNTFRQ Register value
26  */
__get_cntfrq(void)27 static inline rt_uint32_t __get_cntfrq(void)
28 {
29     rt_uint32_t result;
30     __get_cp(15, 0, result, 14, 0 , 0);
31     return result;
32 }
33 
34 /** Set CNTP_TVAL
35  *  This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
36  *  param value: CNTP_TVAL Register value to set
37  */
__set_cntp_tval(rt_uint32_t value)38 static inline void __set_cntp_tval(rt_uint32_t value)
39 {
40     __set_cp(15, 0, value, 14, 2, 0);
41 }
42 
43 /** Get CNTP_TVAL
44  *  This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
45  *  return CNTP_TVAL Register value
46  */
__get_cntp_tval(void)47 static inline rt_uint32_t __get_cntp_tval(void)
48 {
49     rt_uint32_t result;
50     __get_cp(15, 0, result, 14, 2, 0);
51     return result;
52 }
53 
54 /** Get CNTPCT
55  *  This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT).
56  *  return CNTPCT Register value
57  */
__get_cntpct(void)58 static inline rt_uint64_t __get_cntpct(void)
59 {
60     rt_uint64_t result;
61     __get_cp64(15, 0, result, 14);
62     return result;
63 }
64 
65 /** Set CNTP_CVAL
66  *  This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
67  *  param value: CNTP_CVAL Register value to set
68 */
__set_cntp_cval(rt_uint64_t value)69 static inline void __set_cntp_cval(rt_uint64_t value)
70 {
71     __set_cp64(15, 2, value, 14);
72 }
73 
74 /** Get CNTP_CVAL
75  *  This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
76  *  return CNTP_CVAL Register value
77  */
__get_cntp_cval(void)78 static inline rt_uint64_t __get_cntp_cval(void)
79 {
80     rt_uint64_t result;
81     __get_cp64(15, 2, result, 14);
82     return result;
83 }
84 
85 /** Set CNTP_CTL
86  *  This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
87  *  param value: CNTP_CTL Register value to set
88  */
__set_cntp_ctl(rt_uint32_t value)89 static inline void __set_cntp_ctl(rt_uint32_t value)
90 {
91     __set_cp(15, 0, value, 14, 2, 1);
92 }
93 
94 /** Get CNTP_CTL register
95  *  return CNTP_CTL Register value
96  */
__get_cntp_ctl(void)97 static inline rt_uint32_t __get_cntp_ctl(void)
98 {
99     rt_uint32_t result;
100     __get_cp(15, 0, result, 14, 2, 1);
101     return result;
102 }
103 
104 /** Configures the frequency the timer shall run at.
105  *  param value The timer frequency in Hz.
106  */
gtimer_set_counter_frequency(rt_uint32_t value)107 void gtimer_set_counter_frequency(rt_uint32_t value)
108 {
109     __set_cntfrq(value);
110     __asm__ volatile ("isb 0xF":::"memory");
111 }
112 
113 /** Get the frequency the timer shall run at.
114  *  return timer frequency in Hz.
115  */
gtimer_get_counter_frequency(void)116 rt_uint32_t gtimer_get_counter_frequency(void)
117 {
118     return(__get_cntfrq());
119 }
120 
121 /** Sets the reset value of the timer.
122  *  param value: The value the timer is loaded with.
123  */
gtimer_set_load_value(rt_uint32_t value)124 void gtimer_set_load_value(rt_uint32_t value)
125 {
126     __set_cntp_tval(value);
127     __asm__ volatile ("isb 0xF":::"memory");
128 }
129 
130 /** Get the current counter value.
131  *  return Current counter value.
132  */
gtimer_get_current_value(void)133 rt_uint32_t gtimer_get_current_value(void)
134 {
135     return(__get_cntp_tval());
136 }
137 
138 /** Get the current physical counter value.
139  *  return Current physical counter value.
140  */
gtimer_get_current_physical_value(void)141 rt_uint64_t gtimer_get_current_physical_value(void)
142 {
143     return(__get_cntpct());
144 }
145 
146 /** Set the physical compare value.
147  *  param value: New physical timer compare value.
148  */
gtimer_set_physical_compare_value(rt_uint64_t value)149 void gtimer_set_physical_compare_value(rt_uint64_t value)
150 {
151     __set_cntp_cval(value);
152     __asm__ volatile ("isb 0xF":::"memory");
153 }
154 
155 /** Get the physical compare value.
156  *  return Physical compare value.
157  */
gtimer_get_physical_compare_value(void)158 rt_uint64_t gtimer_get_physical_compare_value(void)
159 {
160     return(__get_cntp_cval());
161 }
162 
163 /** Configure the timer by setting the control value.
164  *  param value: New timer control value.
165  */
gtimer_set_control(rt_uint32_t value)166 void gtimer_set_control(rt_uint32_t value)
167 {
168     __set_cntp_ctl(value);
169     __asm__ volatile ("isb 0xF":::"memory");
170 }
171 
172 /** Get the control value.
173  *  return Control value.
174  */
gtimer_get_control(void)175 rt_uint32_t gtimer_get_control(void)
176 {
177     return(__get_cntp_ctl());
178 }
179 
180