1 /*
2 * Copyright (c) 2021, Shenzhen Academy of Aerospace Technology
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-11-16 Dystopia the first version
9 */
10
11 #include "common.h"
12
13 CSL_BootcfgRegs * gp_bootcfg_regs = (CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS;
14 CSL_CgemRegs * gp_cgem_regs = (CSL_CgemRegs *)CSL_CGEM0_5_REG_BASE_ADDRESS_REGS;
15 CSL_TmrPlusRegs * gp_timer_regs[9] = {
16 (CSL_TmrPlusRegs *)CSL_TIMER_0_REGS,
17 (CSL_TmrPlusRegs *)CSL_TIMER_1_REGS,
18 (CSL_TmrPlusRegs *)CSL_TIMER_2_REGS,
19 (CSL_TmrPlusRegs *)CSL_TIMER_3_REGS,
20 (CSL_TmrPlusRegs *)CSL_TIMER_4_REGS,
21 (CSL_TmrPlusRegs *)CSL_TIMER_5_REGS,
22 (CSL_TmrPlusRegs *)CSL_TIMER_6_REGS,
23 (CSL_TmrPlusRegs *)CSL_TIMER_7_REGS,
24 (CSL_TmrPlusRegs *)(CSL_TIMER_7_REGS+(CSL_TIMER_7_REGS-CSL_TIMER_6_REGS))
25 };
26
cpu_interrupt_init(void)27 void cpu_interrupt_init(void)
28 {
29 //clear interrupt and excpetion events
30 ICR = IFR;
31 ECR = EFR;
32 IER = 3; //disable all interrupts
33
34 /* disable event combine */
35 gp_cgem_regs->EVTMASK[0] = 0xffffffff;
36 gp_cgem_regs->EVTMASK[1] = 0xffffffff;
37 gp_cgem_regs->EVTMASK[2] = 0xffffffff;
38 gp_cgem_regs->EVTMASK[3] = 0xffffffff;
39
40 /*Clear all CPU events*/
41 gp_cgem_regs->EVTCLR[0] = 0xFFFFFFFF;
42 gp_cgem_regs->EVTCLR[1] = 0xFFFFFFFF;
43 gp_cgem_regs->EVTCLR[2] = 0xFFFFFFFF;
44 gp_cgem_regs->EVTCLR[3] = 0xFFFFFFFF;
45
46 /*Interrupt Service Table Pointer to begining of LL2 memory*/
47 ISTP = 0x800000;
48 }
49
keystone_cpu_init(void)50 void keystone_cpu_init(void)
51 {
52 /* clear all interrupt flag/status, setup ISTP to begining of LL2 */
53 cpu_interrupt_init();
54 }
55
56 /*===============================Timer=================================*/
reset_timer(int timer_num)57 void reset_timer(int timer_num)
58 {
59 if(gp_timer_regs[timer_num]->TGCR)
60 {
61 gp_timer_regs[timer_num]->TGCR = 0;
62 gp_timer_regs[timer_num]->TCR= 0;
63 }
64 }
65
timer64_init(Timer64_Config * tmrCfg)66 void timer64_init(Timer64_Config * tmrCfg)
67 {
68 reset_timer(tmrCfg->timer_num);
69
70 gp_timer_regs[tmrCfg->timer_num]->CNTLO = 0;
71 gp_timer_regs[tmrCfg->timer_num]->CNTHI = 0;
72
73 /*please note, in clock mode, two timer periods generate a clock,
74 one timer period output high voltage level, the other timer period
75 output low voltage level, so, the timer period should be half to the
76 desired output clock period*/
77 if(TIMER_PERIODIC_CLOCK == tmrCfg->timerMode)
78 {
79 tmrCfg->period = tmrCfg->period/2;
80 }
81
82 /*the value written into period register is the expected value minus one*/
83 gp_timer_regs[tmrCfg->timer_num]->PRDLO = _loll(tmrCfg->period-1);
84 gp_timer_regs[tmrCfg->timer_num]->PRDHI = _hill(tmrCfg->period-1);
85 if(tmrCfg->reload_period>1)
86 {
87 gp_timer_regs[tmrCfg->timer_num]->RELLO = _loll(tmrCfg->reload_period-1);
88 gp_timer_regs[tmrCfg->timer_num]->RELHI = _hill(tmrCfg->reload_period-1);
89 }
90
91 if(TIMER_WATCH_DOG == tmrCfg->timerMode)
92 {
93 gp_timer_regs[tmrCfg->timer_num]->TGCR =
94 /*Select watch-dog mode*/
95 (CSL_TMR_TIMMODE_WDT << CSL_TMR_TGCR_TIMMODE_SHIFT)
96 /*Remove the timer from reset*/
97 | (CSL_TMR_TGCR_TIMLORS_MASK)
98 | (CSL_TMR_TGCR_TIMHIRS_MASK);
99 }
100 else if(TIMER_PERIODIC_WAVE == tmrCfg->timerMode)
101 {
102 gp_timer_regs[tmrCfg->timer_num]->TGCR = TMR_TGCR_PLUSEN_MASK
103 /*for plus featuers, dual 32-bit unchained timer mode should be used*/
104 | (CSL_TMR_TIMMODE_DUAL_UNCHAINED << CSL_TMR_TGCR_TIMMODE_SHIFT)
105 /*Remove the timer from reset*/
106 | (CSL_TMR_TGCR_TIMLORS_MASK);
107
108 //in plus mode, interrupt/event must be enabled manually
109 gp_timer_regs[tmrCfg->timer_num]->INTCTL_STAT= TMR_INTCTLSTAT_EN_ALL_CLR_ALL;
110 }
111 else
112 {
113 gp_timer_regs[tmrCfg->timer_num]->TGCR =
114 /*Select 64-bit general timer mode*/
115 (CSL_TMR_TIMMODE_GPT << CSL_TMR_TGCR_TIMMODE_SHIFT)
116 /*Remove the timer from reset*/
117 | (CSL_TMR_TGCR_TIMLORS_MASK)
118 | (CSL_TMR_TGCR_TIMHIRS_MASK);
119 }
120
121 /*make timer stop with emulation*/
122 gp_timer_regs[tmrCfg->timer_num]->EMUMGT_CLKSPD = (gp_timer_regs[tmrCfg->timer_num]->EMUMGT_CLKSPD&
123 ~(CSL_TMR_EMUMGT_CLKSPD_FREE_MASK|CSL_TMR_EMUMGT_CLKSPD_SOFT_MASK));
124
125 if(TIMER_WATCH_DOG == tmrCfg->timerMode)
126 {
127 /*enable watchdog timer*/
128 gp_timer_regs[tmrCfg->timer_num]->WDTCR = CSL_TMR_WDTCR_WDEN_MASK
129 | (CSL_TMR_WDTCR_WDKEY_CMD1 << CSL_TMR_WDTCR_WDKEY_SHIFT);
130
131 gp_timer_regs[tmrCfg->timer_num]->TCR =
132 (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT)
133 | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT)
134 /*The timer is enabled continuously*/
135 | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT)
136 | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK)
137 /*select pulse mode*/
138 | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT)
139 | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT)
140 | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT)
141 | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT);
142
143 /*active watchdog timer*/
144 gp_timer_regs[tmrCfg->timer_num]->WDTCR = CSL_TMR_WDTCR_WDEN_MASK
145 | (CSL_TMR_WDTCR_WDKEY_CMD2 << CSL_TMR_WDTCR_WDKEY_SHIFT);
146 }
147 else if(TIMER_ONE_SHOT_PULSE == tmrCfg->timerMode)
148 {
149 gp_timer_regs[tmrCfg->timer_num]->TCR =
150 (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT)
151 | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT)
152 /*The timer is enabled one-shot*/
153 | (CSL_TMR_ENAMODE_ENABLE << CSL_TMR_TCR_ENAMODE_LO_SHIFT)
154 | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK)
155 /*select pulse mode*/
156 | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT)
157 | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT)
158 | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT)
159 | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT);
160 }
161 else if(TIMER_PERIODIC_CLOCK == tmrCfg->timerMode)
162 {
163 gp_timer_regs[tmrCfg->timer_num]->TCR =
164 (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT)
165 | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT)
166 /*The timer is enabled continuously*/
167 | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT)
168 | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK)
169 /*select clock mode*/
170 | (CSL_TMR_CP_CLOCK << CSL_TMR_TCR_CP_LO_SHIFT)
171 | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT)
172 | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT)
173 | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT);
174 }
175 else if(TIMER_PERIODIC_WAVE == tmrCfg->timerMode)
176 {
177 gp_timer_regs[tmrCfg->timer_num]->TCR =
178 (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT)
179 | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT)
180 /*The timer is enabled continuously with period reload*/
181 | (CSL_TMR_ENAMODE_CONT_RELOAD << CSL_TMR_TCR_ENAMODE_LO_SHIFT)
182 | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK)
183 /*select clock mode*/
184 | (CSL_TMR_CP_CLOCK << CSL_TMR_TCR_CP_LO_SHIFT)
185 | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT)
186 | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT)
187 | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT);
188 }
189 else /*TIMER_PERIODIC_PULSE*/
190 {
191 gp_timer_regs[tmrCfg->timer_num]->TCR =
192 (CSL_TMR_CLOCK_INP_NOGATE << CSL_TMR_TCR_TIEN_LO_SHIFT)
193 | (CSL_TMR_CLKSRC_INTERNAL << CSL_TMR_TCR_CLKSRC_LO_SHIFT)
194 /*The timer is enabled continuously*/
195 | (CSL_TMR_ENAMODE_CONT << CSL_TMR_TCR_ENAMODE_LO_SHIFT)
196 | ((tmrCfg->pulseWidth << CSL_TMR_TCR_PWID_LO_SHIFT)&CSL_TMR_TCR_PWID_LO_MASK)
197 /*select clock mode*/
198 | (CSL_TMR_CP_PULSE << CSL_TMR_TCR_CP_LO_SHIFT)
199 | (CSL_TMR_INVINP_UNINVERTED << CSL_TMR_TCR_INVINP_LO_SHIFT)
200 | (CSL_TMR_INVOUTP_UNINVERTED << CSL_TMR_TCR_INVOUTP_LO_SHIFT)
201 | (0 << CSL_TMR_TCR_TSTAT_LO_SHIFT);
202 }
203 }
204