]>
Commit | Line | Data |
---|---|---|
8e6f1a8e WD |
1 | /******************************************************************** |
2 | * | |
3 | * Unless otherwise specified, Copyright (C) 2004-2005 Barco Control Rooms | |
4 | * | |
5 | * $Source: /home/services/cvs/firmware/ppc/u-boot-1.1.2/board/barco/barco.c,v $ | |
6 | * $Revision: 1.4 $ | |
7 | * $Author: mleeman $ | |
8 | * $Date: 2005/03/02 16:40:20 $ | |
9 | * | |
10 | * Last ChangeLog Entry | |
11 | * $Log: barco.c,v $ | |
12 | * Revision 1.4 2005/03/02 16:40:20 mleeman | |
13 | * remove empty labels (3.4 complains) | |
14 | * | |
15 | * Revision 1.3 2005/02/21 12:48:58 mleeman | |
16 | * update of copyright years (feedback wd) | |
17 | * | |
18 | * Revision 1.2 2005/02/21 10:10:53 mleeman | |
19 | * - split up switch statement to a function call (Linux kernel coding guidelines) | |
20 | * ( feedback wd) | |
21 | * | |
22 | * Revision 1.1 2005/02/14 09:31:07 mleeman | |
23 | * renaming of files | |
24 | * | |
25 | * Revision 1.1 2005/02/14 09:23:46 mleeman | |
26 | * - moved 'barcohydra' directory to a more generic barco; since we will be | |
27 | * supporting and adding multiple boards | |
28 | * | |
29 | * Revision 1.3 2005/02/10 13:57:32 mleeman | |
30 | * fixed flash corruption: I should exit from the moment I find the correct value | |
31 | * | |
32 | * Revision 1.2 2005/02/09 12:56:23 mleeman | |
33 | * add generic header to track changes in sources | |
34 | * | |
35 | * | |
36 | *******************************************************************/ | |
37 | ||
38 | /* | |
39 | * (C) Copyright 2004 | |
40 | * Marc Leeman <marc.leeman@barco.com> | |
41 | * | |
42 | * This program is free software; you can redistribute it and/or | |
43 | * modify it under the terms of the GNU General Public License as | |
44 | * published by the Free Software Foundation; either version 2 of | |
45 | * the License, or (at your option) any later version. | |
46 | * | |
47 | * This program is distributed in the hope that it will be useful, | |
48 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
49 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
50 | * GNU General Public License for more details. | |
51 | * | |
52 | * You should have received a copy of the GNU General Public License | |
53 | * along with this program; if not, write to the Free Software | |
54 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
55 | * MA 02111-1307 USA | |
56 | */ | |
57 | ||
58 | #include <common.h> | |
59 | #include <mpc824x.h> | |
60 | #include <pci.h> | |
61 | #include <malloc.h> | |
62 | #include <command.h> | |
63 | ||
64 | #include "config.h" | |
65 | #include "barco_svc.h" | |
66 | ||
67 | #define TRY_WORKING (3) | |
68 | #define BOOT_DEFAULT (2) | |
69 | #define BOOT_WORKING (1) | |
70 | ||
71 | int checkboard (void) | |
72 | { | |
73 | /*TODO: Check processor type */ | |
74 | ||
75 | puts ( "Board: Streaming Video Card for Hydra systems " | |
76 | #ifdef CONFIG_MPC8240 | |
77 | "8240" | |
78 | #endif | |
79 | #ifdef CONFIG_MPC8245 | |
80 | "8245" | |
81 | #endif | |
82 | " Unity ##Test not implemented yet##\n"); | |
83 | return 0; | |
84 | } | |
85 | ||
9973e3c6 | 86 | phys_size_t initdram (int board_type) |
8e6f1a8e WD |
87 | { |
88 | long size; | |
89 | long new_bank0_end; | |
90 | long mear1; | |
91 | long emear1; | |
92 | ||
f57f70aa | 93 | size = get_ram_size (CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE); |
8e6f1a8e WD |
94 | |
95 | new_bank0_end = size - 1; | |
f57f70aa WD |
96 | mear1 = mpc824x_mpc107_getreg (MEAR1); |
97 | emear1 = mpc824x_mpc107_getreg (EMEAR1); | |
8e6f1a8e WD |
98 | mear1 = (mear1 & 0xFFFFFF00) | |
99 | ((new_bank0_end & MICR_ADDR_MASK) >> MICR_ADDR_SHIFT); | |
100 | emear1 = (emear1 & 0xFFFFFF00) | | |
101 | ((new_bank0_end & MICR_ADDR_MASK) >> MICR_EADDR_SHIFT); | |
f57f70aa WD |
102 | mpc824x_mpc107_setreg (MEAR1, mear1); |
103 | mpc824x_mpc107_setreg (EMEAR1, emear1); | |
8e6f1a8e WD |
104 | |
105 | return (size); | |
106 | } | |
107 | ||
108 | /* | |
109 | * Initialize PCI Devices, report devices found. | |
110 | */ | |
111 | #ifndef CONFIG_PCI_PNP | |
112 | static struct pci_config_table pci_barcohydra_config_table[] = { | |
113 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x0f, PCI_ANY_ID, | |
114 | pci_cfgfunc_config_device, { PCI_ENET0_IOADDR, | |
115 | PCI_ENET0_MEMADDR, | |
f57f70aa | 116 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER } }, |
8e6f1a8e WD |
117 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x10, PCI_ANY_ID, |
118 | pci_cfgfunc_config_device, { PCI_ENET1_IOADDR, | |
119 | PCI_ENET1_MEMADDR, | |
f57f70aa | 120 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER } }, |
8e6f1a8e WD |
121 | { } |
122 | }; | |
123 | #endif | |
124 | ||
125 | struct pci_controller hose = { | |
126 | #ifndef CONFIG_PCI_PNP | |
127 | config_table: pci_barcohydra_config_table, | |
128 | #endif | |
129 | }; | |
130 | ||
f57f70aa | 131 | void pci_init_board (void) |
8e6f1a8e | 132 | { |
f57f70aa | 133 | pci_mpc824x_init (&hose); |
8e6f1a8e WD |
134 | } |
135 | ||
f57f70aa | 136 | int write_flash (char *addr, char value) |
8e6f1a8e WD |
137 | { |
138 | char *adr = (char *)0xFF800000; | |
139 | int cnt = 0; | |
140 | char status,oldstatus; | |
8e6f1a8e | 141 | |
f57f70aa WD |
142 | *(adr+0x55) = 0xAA; udelay (1); |
143 | *(adr+0xAA) = 0x55; udelay (1); | |
144 | *(adr+0x55) = 0xA0; udelay (1); | |
8e6f1a8e WD |
145 | *addr = value; |
146 | ||
147 | status = *addr; | |
f57f70aa | 148 | do { |
8e6f1a8e WD |
149 | oldstatus = status; |
150 | status = *addr; | |
151 | ||
f57f70aa | 152 | if ((oldstatus & 0x40) == (status & 0x40)) { |
8e6f1a8e WD |
153 | return 4; |
154 | } | |
155 | cnt++; | |
f57f70aa | 156 | if (cnt > 10000) { |
8e6f1a8e WD |
157 | return 2; |
158 | } | |
f57f70aa | 159 | } while ( (status & 0x20) == 0 ); |
8e6f1a8e WD |
160 | |
161 | oldstatus = *addr; | |
162 | status = *addr; | |
163 | ||
f57f70aa WD |
164 | if ((oldstatus & 0x40) == (status & 0x40)) { |
165 | return 0; | |
166 | } else { | |
8e6f1a8e WD |
167 | *(adr+0x55) = 0xF0; |
168 | return 1; | |
169 | } | |
170 | } | |
171 | ||
f57f70aa WD |
172 | unsigned update_flash (unsigned char *buf) |
173 | { | |
174 | switch ((*buf) & 0x3) { | |
175 | case TRY_WORKING: | |
176 | printf ("found 3 and converted it to 2\n"); | |
77ddac94 | 177 | write_flash ((char *)buf, (*buf) & 0xFE); |
f57f70aa WD |
178 | *((unsigned char *)0xFF800000) = 0xF0; |
179 | udelay (100); | |
06c53bea | 180 | printf ("buf [%#010x] %#010x\n", (unsigned)buf, (*buf)); |
f57f70aa WD |
181 | /* XXX - fall through??? */ |
182 | case BOOT_WORKING : | |
183 | return BOOT_WORKING; | |
8e6f1a8e WD |
184 | } |
185 | return BOOT_DEFAULT; | |
186 | } | |
187 | ||
f57f70aa | 188 | unsigned scan_flash (void) |
8e6f1a8e WD |
189 | { |
190 | char section[] = "kernel"; | |
8e6f1a8e WD |
191 | int cfgFileLen = (CFG_FLASH_ERASE_SECTOR_LENGTH >> 1); |
192 | int sectionPtr = 0; | |
193 | int foundItem = 0; /* 0: None, 1: section found, 2: "=" found */ | |
194 | int bufPtr; | |
195 | unsigned char *buf; | |
196 | ||
197 | buf = (unsigned char*)(CFG_FLASH_RANGE_BASE + CFG_FLASH_RANGE_SIZE \ | |
198 | - CFG_FLASH_ERASE_SECTOR_LENGTH); | |
f57f70aa | 199 | for (bufPtr = 0; bufPtr < cfgFileLen; ++bufPtr) { |
8e6f1a8e WD |
200 | if ((buf[bufPtr]==0xFF) && (*(int*)(buf+bufPtr)==0xFFFFFFFF)) { |
201 | return BOOT_DEFAULT; | |
202 | } | |
f57f70aa WD |
203 | /* This is the scanning loop, we try to find a particular |
204 | * quoted value | |
205 | */ | |
206 | switch (foundItem) { | |
207 | case 0: | |
208 | if ((section[sectionPtr] == 0)) { | |
8e6f1a8e | 209 | ++foundItem; |
f57f70aa WD |
210 | } else if (buf[bufPtr] == section[sectionPtr]) { |
211 | ++sectionPtr; | |
212 | } else { | |
213 | sectionPtr = 0; | |
214 | } | |
215 | break; | |
216 | case 1: | |
217 | ++foundItem; | |
218 | break; | |
219 | case 2: | |
220 | ++foundItem; | |
221 | break; | |
222 | case 3: | |
223 | default: | |
224 | return update_flash (&buf[bufPtr - 1]); | |
8e6f1a8e WD |
225 | } |
226 | } | |
227 | ||
f57f70aa | 228 | printf ("Failed to read %s\n",section); |
8e6f1a8e WD |
229 | return BOOT_DEFAULT; |
230 | } | |
231 | ||
f57f70aa | 232 | TSBootInfo* find_boot_info (void) |
8e6f1a8e | 233 | { |
f57f70aa WD |
234 | unsigned bootimage = scan_flash (); |
235 | TSBootInfo* info = (TSBootInfo*)malloc (sizeof(TSBootInfo)); | |
236 | ||
237 | switch (bootimage) { | |
238 | case TRY_WORKING: | |
239 | info->address = CFG_WORKING_KERNEL_ADDRESS; | |
240 | break; | |
241 | case BOOT_WORKING : | |
242 | info->address = CFG_WORKING_KERNEL_ADDRESS; | |
243 | break; | |
244 | case BOOT_DEFAULT: | |
245 | default: | |
246 | info->address= CFG_DEFAULT_KERNEL_ADDRESS; | |
8e6f1a8e WD |
247 | |
248 | } | |
249 | info->size = *((unsigned int *)(info->address )); | |
250 | ||
251 | return info; | |
252 | } | |
253 | ||
f57f70aa | 254 | void barcobcd_boot (void) |
8e6f1a8e WD |
255 | { |
256 | TSBootInfo* start; | |
257 | char *bootm_args[2]; | |
258 | char *buf; | |
259 | int cnt; | |
f57f70aa | 260 | extern int do_bootm (cmd_tbl_t *, int, int, char *[]); |
8e6f1a8e WD |
261 | |
262 | buf = (char *)(0x00800000); | |
263 | /* make certain there are enough chars to print the command line here! | |
264 | */ | |
f57f70aa WD |
265 | bootm_args[0] = (char *)malloc (16*sizeof(char)); |
266 | bootm_args[1] = (char *)malloc (16*sizeof(char)); | |
8e6f1a8e | 267 | |
f57f70aa | 268 | start = find_boot_info (); |
8e6f1a8e | 269 | |
f57f70aa | 270 | printf ("Booting kernel at address %#10x with size %#10x\n", |
8e6f1a8e WD |
271 | start->address, start->size); |
272 | ||
273 | /* give length of the kernel image to bootm */ | |
f57f70aa | 274 | sprintf (bootm_args[0],"%x",start->size); |
8e6f1a8e | 275 | /* give address of the kernel image to bootm */ |
06c53bea | 276 | sprintf (bootm_args[1],"%x",(unsigned)buf); |
8e6f1a8e | 277 | |
f57f70aa | 278 | printf ("flash address: %#10x\n",start->address+8); |
06c53bea | 279 | printf ("buf address: %#10x\n",(unsigned)buf); |
8e6f1a8e WD |
280 | |
281 | /* aha, we reserve 8 bytes here... */ | |
f57f70aa | 282 | for (cnt = 0; cnt < start->size ; cnt++) { |
8e6f1a8e WD |
283 | buf[cnt] = ((char *)start->address)[cnt+8]; |
284 | } | |
285 | ||
286 | /* initialise RAM memory */ | |
287 | *((unsigned int *)0xFEC00000) = 0x00141A98; | |
f57f70aa | 288 | do_bootm (NULL,0,2,bootm_args); |
8e6f1a8e WD |
289 | } |
290 | ||
f57f70aa | 291 | int barcobcd_boot_image (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) |
8e6f1a8e WD |
292 | { |
293 | #if 0 | |
294 | if (argc > 1) { | |
295 | printf ("Usage:\n (%d) %s\n", argc, cmdtp->usage); | |
296 | return 1; | |
297 | } | |
298 | #endif | |
f57f70aa | 299 | barcobcd_boot (); |
8e6f1a8e WD |
300 | |
301 | return 0; | |
302 | } | |
303 | ||
304 | /* Currently, boot_working and boot_default are the same command. This is | |
305 | * left in here to see what we'll do in the future */ | |
306 | ||
f57f70aa | 307 | U_BOOT_CMD ( |
8e6f1a8e WD |
308 | try_working, 1, 1, barcobcd_boot_image, |
309 | " try_working - check flash value and boot the appropriate image\n", | |
310 | "\n" | |
311 | ); | |
312 | ||
f57f70aa | 313 | U_BOOT_CMD ( |
8e6f1a8e WD |
314 | boot_working, 1, 1, barcobcd_boot_image, |
315 | " boot_working - check flash value and boot the appropriate image\n", | |
316 | "\n" | |
317 | ); | |
318 | ||
f57f70aa | 319 | U_BOOT_CMD ( |
8e6f1a8e WD |
320 | boot_default, 1, 1, barcobcd_boot_image, |
321 | " boot_default - check flash value and boot the appropriate image\n", | |
322 | "\n" | |
323 | ); | |
324 | /* | |
325 | * We are not using serial communication, so just provide empty functions | |
326 | */ | |
f57f70aa WD |
327 | int serial_init (void) |
328 | { | |
329 | return 0; | |
330 | } | |
331 | void serial_setbrg (void) | |
332 | { | |
333 | return; | |
334 | } | |
335 | void serial_putc (const char c) | |
336 | { | |
337 | return; | |
338 | } | |
339 | void serial_puts (const char *c) | |
340 | { | |
341 | return; | |
342 | } | |
343 | void serial_addr (unsigned int i) | |
344 | { | |
345 | return; | |
346 | } | |
347 | int serial_getc (void) | |
348 | { | |
349 | return 0; | |
350 | } | |
351 | int serial_tstc (void) | |
352 | { | |
353 | return 0; | |
354 | } | |
355 | ||
356 | unsigned long post_word_load (void) | |
357 | { | |
358 | return 0l; | |
359 | } | |
360 | void post_word_store (unsigned long val) | |
361 | { | |
362 | return; | |
363 | } |