• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <string.h>
17 #include "wm_debug.h"
18 #include "wm_regs.h"
19 #include "wm_irq.h"
20 #include "wm_pwm.h"
21 #include "wm_gpio.h"
22 #include "wm_timer.h"
23 #include "wm_cpu.h"
24 #include "tls_common.h"
25 #include "wm_wifi.h"
26 #include "wm_pmu.h"
27 
28 struct pmu_irq_context {
29     tls_pmu_irq_callback callback;
30     void *arg;
31 };
32 
33 static struct pmu_irq_context pmu_timer1_context = {0};
34 static struct pmu_irq_context pmu_timer0_context = {0};
35 static struct pmu_irq_context pmu_gpio_wake_context = {0};
36 static struct pmu_irq_context pmu_sdio_wake_context = {0};
37 
PMU_TIMER1_IRQHandler(void)38 void PMU_TIMER1_IRQHandler(void)
39 {
40     tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(1)|0x180); /* clear timer1 interrupt */
41     tls_reg_write32(HR_PMU_TIMER1, tls_reg_read32(HR_PMU_TIMER1) & (~BIT(16)));
42     if (pmu_timer1_context.callback != NULL) {
43         pmu_timer1_context.callback(pmu_timer1_context.arg);
44     }
45     return;
46 }
47 
PMU_TIMER0_IRQHandler(void)48 void PMU_TIMER0_IRQHandler(void)
49 {
50     tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(0)|0x180); /* clear timer0 interrupt */
51     tls_reg_write32(HR_PMU_TIMER0, tls_reg_read32(HR_PMU_TIMER0) & (~BIT(16)));
52 
53     if (pmu_timer0_context.callback != NULL)
54         pmu_timer0_context.callback(pmu_timer0_context.arg);
55     return;
56 }
57 
PMU_GPIO_WAKE_IRQHandler(void)58 void PMU_GPIO_WAKE_IRQHandler(void)
59 {
60     tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(2)|0x180); /* clear gpio wake interrupt */
61 
62     if (pmu_gpio_wake_context.callback != NULL)
63         pmu_gpio_wake_context.callback(pmu_gpio_wake_context.arg);
64     return;
65 }
66 
PMU_SDIO_WAKE_IRQHandler(void)67 void PMU_SDIO_WAKE_IRQHandler(void)
68 {
69     tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(3)|0x180); /* clear sdio wake interrupt */
70 
71     if (pmu_sdio_wake_context.callback != NULL)
72         pmu_sdio_wake_context.callback(pmu_sdio_wake_context.arg);
73     return;
74 }
75 
76 /**
77  * @brief              This function is used to register pmu timer1 interrupt
78  *
79  * @param[in]          callback        the pmu timer1 interrupt call back function
80  * @param[in]          arg                 parameter of call back function
81  *
82  * @return             None
83  *
84  * @note
85  * user not need clear interrupt flag.
86  * pmu timer1 callback function is called in interrupt,
87  * so can not operate the critical data in the callback fuuction,
88  * recommendation to send messages to other tasks to operate it.
89  */
tls_pmu_timer1_isr_register(tls_pmu_irq_callback callback,void * arg)90 void tls_pmu_timer1_isr_register(tls_pmu_irq_callback callback, void *arg)
91 {
92     pmu_timer1_context.callback = callback;
93     pmu_timer1_context.arg      = arg;
94 
95     tls_irq_enable(PMU_IRQn);
96 
97     return;
98 }
99 
100 /**
101  * @brief              This function is used to register pmu timer0 interrupt
102  *
103  * @param[in]          callback        the pmu timer0 interrupt call back function
104  * @param[in]          arg                 parameter of call back function
105  *
106  * @return             None
107  *
108  * @note
109  * user not need clear interrupt flag.
110  * pmu timer0 callback function is called in interrupt,
111  * so can not operate the critical data in the callback fuuction,
112  * recommendation to send messages to other tasks to operate it.
113  */
tls_pmu_timer0_isr_register(tls_pmu_irq_callback callback,void * arg)114 void tls_pmu_timer0_isr_register(tls_pmu_irq_callback callback, void *arg)
115 {
116     pmu_timer0_context.callback = callback;
117     pmu_timer0_context.arg      = arg;
118 
119     tls_irq_enable(PMU_IRQn);
120 
121     return;
122 }
123 
124 /**
125  * @brief              This function is used to register pmu gpio interrupt
126  *
127  * @param[in]          callback        the pmu gpio interrupt call back function
128  * @param[in]          arg                 parameter of call back function
129  *
130  * @return             None
131  *
132  * @note
133  * user not need clear interrupt flag.
134  * pmu gpio callback function is called in interrupt,
135  * so can not operate the critical data in the callback fuuction,
136  * recommendation to send messages to other tasks to operate it.
137  */
tls_pmu_gpio_isr_register(tls_pmu_irq_callback callback,void * arg)138 void tls_pmu_gpio_isr_register(tls_pmu_irq_callback callback, void *arg)
139 {
140     pmu_gpio_wake_context.callback = callback;
141     pmu_gpio_wake_context.arg      = arg;
142 
143     tls_irq_enable(PMU_IRQn);
144 
145     return;
146 }
147 
148 /**
149  * @brief              This function is used to register pmu sdio interrupt
150  *
151  * @param[in]          callback        the pmu sdio interrupt call back function
152  * @param[in]          arg                 parameter of call back function
153  *
154  * @return             None
155  *
156  * @note
157  * user not need clear interrupt flag.
158  * pmu sdio callback function is called in interrupt,
159  * so can not operate the critical data in the callback fuuction,
160  * recommendation to send messages to other tasks to operate it.
161  */
tls_pmu_sdio_isr_register(tls_pmu_irq_callback callback,void * arg)162 void tls_pmu_sdio_isr_register(tls_pmu_irq_callback callback, void *arg)
163 {
164     pmu_sdio_wake_context.callback = callback;
165     pmu_sdio_wake_context.arg      = arg;
166 
167     tls_irq_enable(PMU_IRQn);
168 
169     return;
170 }
171 
172 /**
173  * @brief              This function is used to select pmu clk
174  *
175  * @param[in]          bypass        pmu clk whether or not use bypass mode
176  *                ohter           pmu clk use 32K by 40MHZ
177  *                0             pmu clk 32K by calibration circuit
178  *
179  * @return             None
180  *
181  * @note               None
182  */
tls_pmu_clk_select(u8 bypass)183 void tls_pmu_clk_select(u8 bypass)
184 {
185     u32 val;
186 
187     val = tls_reg_read32(HR_PMU_PS_CR);
188     if (bypass) {
189         val |= BIT(4);
190     } else {
191         val &= ~BIT(4);
192     }
193     val |= BIT(3);
194     tls_reg_write32(HR_PMU_PS_CR, val);
195 }
196 
197 /**
198  * @brief              This function is used to start pmu timer0
199  *
200  * @param[in]          second      vlaue of timer0 count[s]
201  *
202  * @return             None
203  *
204  * @note               None
205  */
tls_pmu_timer0_start(u16 second)206 void tls_pmu_timer0_start(u16 second)
207 {
208     u32 val;
209     val = tls_reg_read32(HR_PMU_INTERRUPT_SRC);
210     if (val&0x180) {
211         tls_reg_write32(HR_PMU_INTERRUPT_SRC, val);
212     }
213 
214     val = tls_reg_read32(HR_PMU_PS_CR);
215     /* cal 32K osc */
216     val |= BIT(3);
217     tls_reg_write32(HR_PMU_PS_CR, val);
218 
219     val = second;
220     val |= BIT(16);
221     tls_reg_write32(HR_PMU_TIMER0, val);
222 }
223 
224 /**
225  * @brief              This function is used to stop pmu timer0
226  *
227  * @param        None
228  *
229  * @return             None
230  *
231  * @note               None
232  */
tls_pmu_timer0_stop(void)233 void tls_pmu_timer0_stop(void)
234 {
235     u32 val;
236 
237     val = tls_reg_read32(HR_PMU_TIMER0);
238     val &= ~BIT(16);
239     tls_reg_write32(HR_PMU_TIMER0, val);
240 }
241 
242 /**
243  * @brief              This function is used to start pmu timer1
244  *
245  * @param[in]          second      vlaue of timer1 count[ms]
246  *
247  * @return             None
248  *
249  * @note               None
250  */
tls_pmu_timer1_start(u16 msec)251 void tls_pmu_timer1_start(u16 msec)
252 {
253     u32 val;
254 
255     val = tls_reg_read32(HR_PMU_INTERRUPT_SRC);
256     if (val&0x180) {
257         tls_reg_write32(HR_PMU_INTERRUPT_SRC, val);
258     }
259 
260     val = tls_reg_read32(HR_PMU_PS_CR);
261     /* cal 32K osc */
262     val |= BIT(3);
263     if (!(val & BIT(4))) {
264         tls_reg_write32(HR_PMU_PS_CR, val);
265         if (msec < 5) {
266             val = 5;
267         } else {
268             val = msec;
269         }
270         // Ĭ�ϲ�����С��λ1ms
271         val = (val - 5) | (1<<16) | (0<<17) | (0<<20) | (0<<24);
272     } else {
273         // Ĭ�ϲ�����С��λ1ms
274         val = (msec-1)|(1<<16) | (0<<17) | (0<<20) | (0<<24);
275     }
276     tls_reg_write32(HR_PMU_TIMER1, val);
277 }
278 
279 /**
280  * @brief              This function is used to stop pmu timer1
281  *
282  * @param        None
283  *
284  * @return             None
285  *
286  * @note               None
287  */
tls_pmu_timer1_stop(void)288 void tls_pmu_timer1_stop(void)
289 {
290     u32 val;
291     val = tls_reg_read32(HR_PMU_TIMER1);
292     val &= ~BIT(16);
293     val &= ~BIT(17);
294     tls_reg_write32(HR_PMU_TIMER1, val);
295 }
296 
297 /**
298  * @brief              This function is used to start pmu goto standby
299  *
300  * @param        None
301  *
302  * @return             None
303  *
304  * @note               None
305  */
tls_pmu_standby_start(void)306 void tls_pmu_standby_start(void)
307 {
308     u32 val;
309 
310     tls_irq_enable(PMU_IRQn);        // Ĭ�ϴ��ж�Ϊ�����IO���ѵ��жϱ��
311 
312     /* Clear Sleep status after exit sleep mode and enter standby mode */
313     val = tls_reg_read32(HR_PMU_INTERRUPT_SRC);
314     if (val&0x180) {
315         tls_reg_write32(HR_PMU_INTERRUPT_SRC, val);
316     }
317 
318     val = tls_reg_read32(HR_PMU_PS_CR);
319     TLS_DBGPRT_INFO("goto standby here\n");
320     val |= BIT(0);
321     tls_reg_write32(HR_PMU_PS_CR, val);
322 }
323 
324 /**
325  * @brief              This function is used to start pmu goto sleep
326  *
327  * @param        None
328  *
329  * @return             None
330  *
331  * @note               None
332  */
tls_pmu_sleep_start(void)333 void tls_pmu_sleep_start(void)
334 {
335     u32 val;
336     u32 use40M;
337 
338     tls_irq_enable(PMU_IRQn);        // Ĭ�ϴ��ж�Ϊ�����IO����
339 
340     /* Clear Standby status after exit standby mode and enter sleep mode */
341     val = tls_reg_read32(HR_PMU_INTERRUPT_SRC);
342     if (val&0x180) {
343         tls_reg_write32(HR_PMU_INTERRUPT_SRC, val);
344     }
345 
346     val = tls_reg_read32(HR_PMU_PS_CR);
347     if (val&BIT(4)) {
348         use40M    = tls_reg_read32(HR_PMU_WLAN_STTS);
349         use40M |= BIT(8);
350         tls_reg_write32(HR_PMU_WLAN_STTS, use40M);
351     }
352     TLS_DBGPRT_INFO("goto sleep here\n");
353     val |= BIT(1);
354     tls_reg_write32(HR_PMU_PS_CR, val);
355 }
356 
357 /**
358  * @brief              This function is used to close peripheral's clock
359  *
360  * @param[in]          devices      peripherals
361  *
362  * @return             None
363  *
364  * @note               None
365  */
tls_close_peripheral_clock(tls_peripheral_type_s devices)366 void tls_close_peripheral_clock(tls_peripheral_type_s devices)
367 {
368     return;
369 }
370 
371 /**
372  * @brief              This function is used to open peripheral's clock
373  *
374  * @param[in]          devices      peripherals
375  *
376  * @return             None
377  *
378  * @note               None
379  */
tls_open_peripheral_clock(tls_peripheral_type_s devices)380 void tls_open_peripheral_clock(tls_peripheral_type_s devices)
381 {
382     return;
383 }