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  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  *
25  */
26 
27 #include <common.h>
28 #include <asm/asi.h>
29 #include <asm/leon.h>
30 #include <ambapp.h>
31 
32 #include <config.h>
33 
34 DECLARE_GLOBAL_DATA_PTR;
35 
36 /* reset CPU (jump to 0, without reset) */
37 void start(void);
38 
39 /* find & initialize the memory controller */
40 int init_memory_ctrl(void);
41 
42 ambapp_dev_irqmp *irqmp = NULL;
43 ambapp_dev_mctrl memctrl;
44 ambapp_dev_gptimer *gptimer = NULL;
45 unsigned int gptimer_irq = 0;
46 int leon3_snooping_avail = 0;
47 
48 struct {
49 	gd_t gd_area;
50 	bd_t bd;
51 } global_data;
52 
53 /*
54  * Breath some life into the CPU...
55  *
56  * Set up the memory map,
57  * initialize a bunch of registers.
58  *
59  * Run from FLASH/PROM:
60  *  - until memory controller is set up, only registers avaiable
61  *  - no global variables available for writing
62  *  - constants avaiable
63  */
64 
cpu_init_f(void)65 void cpu_init_f(void)
66 {
67 	/* these varaiable must not be initialized */
68 	ambapp_dev_irqmp *irqmp;
69 	ambapp_apbdev apbdev;
70 	register unsigned int apbmst;
71 
72 	/* find AMBA APB Master */
73 	apbmst = (unsigned int)
74 	    ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
75 	if (!apbmst) {
76 		/*
77 		 * no AHB/APB bridge, something is wrong
78 		 * ==> jump to start (or hang)
79 		 */
80 		while (1) ;
81 	}
82 	/* Init memory controller */
83 	if (init_memory_ctrl()) {
84 		while (1) ;
85 	}
86 
87 	/****************************************************
88 	 * From here we can use the main memory and the stack.
89 	 */
90 
91 	/* Find AMBA APB IRQMP Controller */
92 	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
93 		/* no IRQ controller, something is wrong
94 		 * ==> jump to start (or hang)
95 		 */
96 		while (1) ;
97 	}
98 	irqmp = (ambapp_dev_irqmp *) apbdev.address;
99 
100 	/* initialize the IRQMP */
101 	irqmp->ilevel = 0xf;	/* all IRQ off */
102 	irqmp->iforce = 0;
103 	irqmp->ipend = 0;
104 	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
105 	irqmp->cpu_mask[0] = 0;	/* mask all IRQs on CPU 0 */
106 	irqmp->cpu_force[0] = 0;	/* no force IRQ on CPU 0 */
107 
108 	/* cache */
109 }
110 
cpu_init_f2(void)111 void cpu_init_f2(void)
112 {
113 
114 }
115 
116 /*
117  * initialize higher level parts of CPU like time base and timers
118  */
cpu_init_r(void)119 int cpu_init_r(void)
120 {
121 	ambapp_apbdev apbdev;
122 
123 	/*
124 	 * Find AMBA APB IRQMP Controller,
125 	 * When we come so far we know there is a IRQMP available
126 	 */
127 	ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
128 	irqmp = (ambapp_dev_irqmp *) apbdev.address;
129 
130 	/* timer */
131 	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
132 		printf("cpu_init_r: gptimer not found!\n");
133 		return 1;
134 	}
135 	gptimer = (ambapp_dev_gptimer *) apbdev.address;
136 	gptimer_irq = apbdev.irq;
137 
138 	/* initialize prescaler common to all timers to 1MHz */
139 	gptimer->scalar = gptimer->scalar_reload =
140 	    (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
141 
142 	return (0);
143 }
144 
145 /* find & setup memory controller */
init_memory_ctrl()146 int init_memory_ctrl()
147 {
148 	register ambapp_dev_mctrl *mctrl;
149 	register ambapp_dev_sdctrl *sdctrl;
150 	register ambapp_dev_ddrspa *ddrspa;
151 	register ambapp_dev_ddr2spa *ddr2spa;
152 	register ahbctrl_pp_dev *ahb;
153 	register unsigned int base;
154 	register int not_found_mctrl = -1;
155 
156 	/* find ESA Memory controller */
157 	base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
158 	if (base) {
159 		mctrl = (ambapp_dev_mctrl *) base;
160 
161 		/* config MCTRL memory controller */
162 		mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
163 		mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2;
164 		mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3;
165 		not_found_mctrl = 0;
166 	}
167 
168 	/* find Gaisler Fault Tolerant Memory controller */
169 	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
170 	if (base) {
171 		mctrl = (ambapp_dev_mctrl *) base;
172 
173 		/* config MCTRL memory controller */
174 		mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
175 		mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2;
176 		mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3;
177 		not_found_mctrl = 0;
178 	}
179 
180 	/* find SDRAM controller */
181 	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
182 	if (base) {
183 		sdctrl = (ambapp_dev_sdctrl *) base;
184 
185 		/* config memory controller */
186 		sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM;
187 		not_found_mctrl = 0;
188 	}
189 
190 	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
191 	if (ahb) {
192 		ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
193 
194 		/* Config DDR2 memory controller */
195 		ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1;
196 		ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3;
197 		not_found_mctrl = 0;
198 	}
199 
200 	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
201 	if (ahb) {
202 		ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
203 
204 		/* Config DDR memory controller */
205 		ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG;
206 		not_found_mctrl = 0;
207 	}
208 
209 	/* failed to find any memory controller */
210 	return not_found_mctrl;
211 }
212 
213 /* Uses Timer 0 to get accurate
214  * pauses. Max 2 raised to 32 ticks
215  *
216  */
cpu_wait_ticks(unsigned long ticks)217 void cpu_wait_ticks(unsigned long ticks)
218 {
219 	unsigned long start = get_timer(0);
220 	while (get_timer(start) < ticks) ;
221 }
222 
223 /* initiate and setup timer0 interrupt to 1MHz
224  * Return irq number for timer int or a negative number for
225  * dealing with self
226  */
timer_interrupt_init_cpu(void)227 int timer_interrupt_init_cpu(void)
228 {
229 	/* 1ms ticks */
230 	gptimer->e[0].val = 0;
231 	gptimer->e[0].rld = 999;	/* (((1000000 / 100) - 1)) */
232 	gptimer->e[0].ctrl =
233 	    (LEON3_GPTIMER_EN |
234 	     LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
235 
236 	return gptimer_irq;
237 }
238 
239 /*
240  * This function is intended for SHORT delays only.
241  */
cpu_usec2ticks(unsigned long usec)242 unsigned long cpu_usec2ticks(unsigned long usec)
243 {
244 	/* timer set to 1kHz ==> 1 clk tick = 1 msec */
245 	if (usec < 1000)
246 		return 1;
247 	return (usec / 1000);
248 }
249 
cpu_ticks2usec(unsigned long ticks)250 unsigned long cpu_ticks2usec(unsigned long ticks)
251 {
252 	/* 1tick = 1usec */
253 	return ticks * 1000;
254 }
255