]>
Commit | Line | Data |
---|---|---|
1e9a164e DH |
1 | /* Initializes CPU and basic hardware such as memory |
2 | * controllers, IRQ controller and system timer 0. | |
3 | * | |
4 | * (C) Copyright 2007 | |
5 | * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
1e9a164e DH |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <asm/asi.h> | |
12 | #include <asm/leon.h> | |
13 | #include <ambapp.h> | |
14 | ||
15 | #include <config.h> | |
16 | ||
1c1c7506 DH |
17 | #define TIMER_BASE_CLK 1000000 |
18 | #define US_PER_TICK (1000000 / CONFIG_SYS_HZ) | |
19 | ||
1e9a164e DH |
20 | DECLARE_GLOBAL_DATA_PTR; |
21 | ||
22 | /* reset CPU (jump to 0, without reset) */ | |
23 | void start(void); | |
24 | ||
25 | /* find & initialize the memory controller */ | |
26 | int init_memory_ctrl(void); | |
27 | ||
28 | ambapp_dev_irqmp *irqmp = NULL; | |
29 | ambapp_dev_mctrl memctrl; | |
30 | ambapp_dev_gptimer *gptimer = NULL; | |
31 | unsigned int gptimer_irq = 0; | |
32 | int leon3_snooping_avail = 0; | |
33 | ||
34 | struct { | |
35 | gd_t gd_area; | |
36 | bd_t bd; | |
37 | } global_data; | |
38 | ||
39 | /* | |
40 | * Breath some life into the CPU... | |
41 | * | |
42 | * Set up the memory map, | |
43 | * initialize a bunch of registers. | |
44 | * | |
45 | * Run from FLASH/PROM: | |
6052cbab | 46 | * - until memory controller is set up, only registers available |
1e9a164e | 47 | * - no global variables available for writing |
6052cbab | 48 | * - constants available |
1e9a164e DH |
49 | */ |
50 | ||
51 | void cpu_init_f(void) | |
52 | { | |
53 | /* these varaiable must not be initialized */ | |
54 | ambapp_dev_irqmp *irqmp; | |
55 | ambapp_apbdev apbdev; | |
56 | register unsigned int apbmst; | |
57 | ||
58 | /* find AMBA APB Master */ | |
59 | apbmst = (unsigned int) | |
60 | ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0); | |
61 | if (!apbmst) { | |
62 | /* | |
63 | * no AHB/APB bridge, something is wrong | |
64 | * ==> jump to start (or hang) | |
65 | */ | |
66 | while (1) ; | |
67 | } | |
68 | /* Init memory controller */ | |
69 | if (init_memory_ctrl()) { | |
70 | while (1) ; | |
71 | } | |
72 | ||
73 | /**************************************************** | |
74 | * From here we can use the main memory and the stack. | |
75 | */ | |
76 | ||
77 | /* Find AMBA APB IRQMP Controller */ | |
78 | if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) { | |
79 | /* no IRQ controller, something is wrong | |
80 | * ==> jump to start (or hang) | |
81 | */ | |
82 | while (1) ; | |
83 | } | |
84 | irqmp = (ambapp_dev_irqmp *) apbdev.address; | |
85 | ||
86 | /* initialize the IRQMP */ | |
87 | irqmp->ilevel = 0xf; /* all IRQ off */ | |
88 | irqmp->iforce = 0; | |
89 | irqmp->ipend = 0; | |
90 | irqmp->iclear = 0xfffe; /* clear all old pending interrupts */ | |
91 | irqmp->cpu_mask[0] = 0; /* mask all IRQs on CPU 0 */ | |
92 | irqmp->cpu_force[0] = 0; /* no force IRQ on CPU 0 */ | |
93 | ||
94 | /* cache */ | |
95 | } | |
96 | ||
97 | void cpu_init_f2(void) | |
98 | { | |
99 | ||
100 | } | |
101 | ||
102 | /* | |
103 | * initialize higher level parts of CPU like time base and timers | |
104 | */ | |
105 | int cpu_init_r(void) | |
106 | { | |
107 | ambapp_apbdev apbdev; | |
108 | ||
109 | /* | |
110 | * Find AMBA APB IRQMP Controller, | |
111 | * When we come so far we know there is a IRQMP available | |
112 | */ | |
113 | ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev); | |
114 | irqmp = (ambapp_dev_irqmp *) apbdev.address; | |
115 | ||
116 | /* timer */ | |
117 | if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) { | |
118 | printf("cpu_init_r: gptimer not found!\n"); | |
119 | return 1; | |
120 | } | |
121 | gptimer = (ambapp_dev_gptimer *) apbdev.address; | |
122 | gptimer_irq = apbdev.irq; | |
123 | ||
124 | /* initialize prescaler common to all timers to 1MHz */ | |
125 | gptimer->scalar = gptimer->scalar_reload = | |
126 | (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1; | |
127 | ||
128 | return (0); | |
129 | } | |
130 | ||
131 | /* find & setup memory controller */ | |
132 | int init_memory_ctrl() | |
133 | { | |
134 | register ambapp_dev_mctrl *mctrl; | |
135 | register ambapp_dev_sdctrl *sdctrl; | |
136 | register ambapp_dev_ddrspa *ddrspa; | |
137 | register ambapp_dev_ddr2spa *ddr2spa; | |
138 | register ahbctrl_pp_dev *ahb; | |
139 | register unsigned int base; | |
140 | register int not_found_mctrl = -1; | |
141 | ||
142 | /* find ESA Memory controller */ | |
143 | base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0); | |
144 | if (base) { | |
145 | mctrl = (ambapp_dev_mctrl *) base; | |
146 | ||
147 | /* config MCTRL memory controller */ | |
6d0f6bcf JCPV |
148 | mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300); |
149 | mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2; | |
150 | mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3; | |
1e9a164e DH |
151 | not_found_mctrl = 0; |
152 | } | |
153 | ||
154 | /* find Gaisler Fault Tolerant Memory controller */ | |
155 | base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0); | |
156 | if (base) { | |
157 | mctrl = (ambapp_dev_mctrl *) base; | |
158 | ||
159 | /* config MCTRL memory controller */ | |
6d0f6bcf JCPV |
160 | mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300); |
161 | mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2; | |
162 | mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3; | |
1e9a164e DH |
163 | not_found_mctrl = 0; |
164 | } | |
165 | ||
166 | /* find SDRAM controller */ | |
167 | base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0); | |
168 | if (base) { | |
169 | sdctrl = (ambapp_dev_sdctrl *) base; | |
170 | ||
171 | /* config memory controller */ | |
6d0f6bcf | 172 | sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM; |
1e9a164e DH |
173 | not_found_mctrl = 0; |
174 | } | |
175 | ||
176 | ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0); | |
177 | if (ahb) { | |
178 | ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1); | |
179 | ||
180 | /* Config DDR2 memory controller */ | |
6d0f6bcf JCPV |
181 | ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1; |
182 | ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3; | |
1e9a164e DH |
183 | not_found_mctrl = 0; |
184 | } | |
185 | ||
186 | ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0); | |
187 | if (ahb) { | |
188 | ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1); | |
189 | ||
190 | /* Config DDR memory controller */ | |
6d0f6bcf | 191 | ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG; |
1e9a164e DH |
192 | not_found_mctrl = 0; |
193 | } | |
194 | ||
195 | /* failed to find any memory controller */ | |
196 | return not_found_mctrl; | |
197 | } | |
198 | ||
199 | /* Uses Timer 0 to get accurate | |
200 | * pauses. Max 2 raised to 32 ticks | |
201 | * | |
202 | */ | |
203 | void cpu_wait_ticks(unsigned long ticks) | |
204 | { | |
205 | unsigned long start = get_timer(0); | |
206 | while (get_timer(start) < ticks) ; | |
207 | } | |
208 | ||
1c1c7506 | 209 | /* initiate and setup timer0 interrupt to configured HZ. Base clock is 1MHz. |
1e9a164e DH |
210 | * Return irq number for timer int or a negative number for |
211 | * dealing with self | |
212 | */ | |
213 | int timer_interrupt_init_cpu(void) | |
214 | { | |
1c1c7506 | 215 | /* SYS_HZ ticks per second */ |
1e9a164e | 216 | gptimer->e[0].val = 0; |
1c1c7506 | 217 | gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 1; |
1e9a164e DH |
218 | gptimer->e[0].ctrl = |
219 | (LEON3_GPTIMER_EN | | |
220 | LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN); | |
221 | ||
222 | return gptimer_irq; | |
223 | } | |
224 | ||
4148b3d0 DH |
225 | ulong get_tbclk(void) |
226 | { | |
227 | return TIMER_BASE_CLK; | |
228 | } | |
229 | ||
1e9a164e DH |
230 | /* |
231 | * This function is intended for SHORT delays only. | |
232 | */ | |
233 | unsigned long cpu_usec2ticks(unsigned long usec) | |
234 | { | |
1c1c7506 | 235 | if (usec < US_PER_TICK) |
1e9a164e | 236 | return 1; |
1c1c7506 | 237 | return usec / US_PER_TICK; |
1e9a164e DH |
238 | } |
239 | ||
240 | unsigned long cpu_ticks2usec(unsigned long ticks) | |
241 | { | |
1c1c7506 | 242 | return ticks * US_PER_TICK; |
1e9a164e | 243 | } |