1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stddef.h>
7 #include <stdint.h>
8 
9 #include <device_mec5.h>
10 #include "mec_defs.h"
11 #include "mec_ecia_api.h"
12 #include "mec_pcr_api.h"
13 #include "mec_rtimer_api.h"
14 #include "mec_retval.h"
15 
16 #define MEC_RTMR_GIRQ 23
17 #define MEC_RTMR_GIRQ_POS 10
18 #define MEC_RTMR_NVIC_NUM 111
19 #define MEC_RTMR_ECIA_INFO MEC5_ECIA_INFO(MEC_RTMR_GIRQ, MEC_RTMR_GIRQ_POS, 14, 111)
20 
mec_hal_rtimer_init(struct mec_rtmr_regs * regs,uint32_t rtmr_config,uint32_t preload)21 int mec_hal_rtimer_init(struct mec_rtmr_regs *regs, uint32_t rtmr_config, uint32_t preload)
22 {
23     uint32_t ctrl = 0;
24     int irq_en = 0;
25 
26     if ((uintptr_t)regs != (uintptr_t)MEC_RTMR0_BASE) {
27         return MEC_RET_ERR_INVAL;
28     }
29 
30     mec_hal_pcr_clr_blk_slp_en(MEC_PCR_RTMR);
31 
32     regs->CTRL = 0;
33     regs->PRELOAD = preload;
34 
35     if (rtmr_config & MEC_BIT(MEC_RTMR_CFG_EN_POS)) {
36         ctrl |= MEC_BIT(MEC_RTMR_CTRL_ENABLE_Pos);
37     }
38 
39     if (rtmr_config & MEC_BIT(MEC_RTMR_CFG_AUTO_RELOAD_POS)) {
40         ctrl |= MEC_BIT(MEC_RTMR_CTRL_AUTO_RELOAD_Pos);
41     }
42 
43     if (rtmr_config & MEC_BIT(MEC_RTMR_CFG_START_POS)) {
44         ctrl |= MEC_BIT(MEC_RTMR_CTRL_START_Pos);
45     }
46 
47     if (rtmr_config & MEC_BIT(MEC_RTMR_CFG_DBG_HALT_POS)) {
48         ctrl |= MEC_BIT(MEC_RTMR_CTRL_EXT_HALT_Pos);
49     }
50 
51     if (rtmr_config & MEC_BIT(MEC_RTMR_CFG_IEN_POS)) {
52         irq_en = 1;
53     }
54 
55     mec_hal_girq_clr_src(MEC_RTMR_ECIA_INFO);
56     mec_hal_girq_ctrl(MEC_RTMR_ECIA_INFO, irq_en);
57 
58     regs->CTRL = ctrl;
59 
60     return MEC_RET_OK;
61 }
62 
mec_hal_rtimer_status(struct mec_rtmr_regs * regs)63 uint32_t mec_hal_rtimer_status(struct mec_rtmr_regs *regs)
64 {
65     (void)regs;
66 
67     if (mec_hal_girq_src(MEC_RTMR_ECIA_INFO)) {
68         return MEC_BIT(MEC_RTMR_STATUS_TERM_POS);
69     }
70 
71     return 0;
72 }
73 
mec_hal_rtimer_status_clear(struct mec_rtmr_regs * regs,uint32_t status)74 void mec_hal_rtimer_status_clear(struct mec_rtmr_regs *regs, uint32_t status)
75 {
76     (void)regs;
77 
78     if (status & MEC_BIT(MEC_RTMR_STATUS_TERM_POS)) {
79         mec_hal_girq_clr_src(MEC_RTMR_ECIA_INFO);
80     }
81 }
82 
mec_hal_rtimer_status_clear_all(struct mec_rtmr_regs * regs)83 void mec_hal_rtimer_status_clear_all(struct mec_rtmr_regs *regs)
84 {
85     (void)regs;
86 
87     mec_hal_girq_clr_src(MEC_RTMR_ECIA_INFO);
88 }
89 
mec_hal_rtimer_intr_ctrl(struct mec_rtmr_regs * regs,uint8_t enable)90 void mec_hal_rtimer_intr_ctrl(struct mec_rtmr_regs *regs, uint8_t enable)
91 {
92     (void)regs;
93 
94     mec_hal_girq_ctrl(MEC_RTMR_ECIA_INFO, (int)enable);
95 }
96 
97 /* Reload RTOS timer count.
98  * RTOS timer internal logic runs on 32 KHz and requires a sequence
99  * to restart the timer with a new count down value.
100  * 1. Save CTRL value and make sure FW halt is clear.
101  * 2. Make sure start and enable bits are set in saved CTRL.
102  * 3. disable RTOS timer to clear registers to default state
103  * 4. write new count into PRELOAD register
104  * 5. write CTRL value
105  * 6. If new count down is not 0 wait for RTOS timer to start
106  *    counting down (up to one 32 KHz period).
107  */
mec_hal_rtimer_restart(struct mec_rtmr_regs * regs,uint32_t new_count,uint8_t restart)108 void mec_hal_rtimer_restart(struct mec_rtmr_regs *regs, uint32_t new_count, uint8_t restart)
109 {
110     uint32_t ctrl = regs->CTRL;
111 
112     regs->CTRL = 0;
113     ctrl &= (uint32_t)~MEC_BIT(MEC_RTMR_CTRL_FW_HALT_Pos);
114     ctrl |= MEC_BIT(MEC_RTMR_CTRL_ENABLE_Pos);
115     if (restart) {
116         ctrl |= MEC_BIT(MEC_RTMR_CTRL_START_Pos);
117     }
118 
119     regs->PRELOAD = new_count;
120     regs->CTRL = ctrl;
121 }
122 
123 /* end mec_rtimer.c */
124