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