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