source: SVN/rincon/u-boot/board/gth2/gth2.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 10.3 KB
Line 
1/*
2 * (C) Copyright 2005
3 * Thomas.Lange@corelatus.se
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <command.h>
26#include <asm/au1x00.h>
27#include <asm/addrspace.h>
28#include <asm/mipsregs.h>
29#include <asm/io.h>
30#include <watchdog.h>
31
32#include "ee_access.h"
33
34static int wdi_status = 0;
35
36#define SDRAM_SIZE ((64*1024*1024)-(12*4096))
37
38
39#define SERIAL_LOG_BUFFER CKSEG1ADDR(SDRAM_SIZE + (8*4096))
40
41void inline log_serial_char(char c){
42        char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;
43        int serial_log_offset;
44        u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;
45
46        serial_log_offset = *serial_log_offsetp;
47
48        *(serial_log_buffer + serial_log_offset) = c;
49
50        serial_log_offset++;
51
52        if(serial_log_offset >= 4096){
53                serial_log_offset = 4;
54        }
55        *serial_log_offsetp = serial_log_offset;
56}
57
58void init_log_serial(void){
59        char *serial_log_buffer = (char*)SERIAL_LOG_BUFFER;
60        u32 *serial_log_offsetp = (u32*)SERIAL_LOG_BUFFER;
61
62        /* Copy buffer from last run */
63        memcpy(serial_log_buffer + 4096,
64               serial_log_buffer,
65               4096);
66
67        memset(serial_log_buffer, 0, 4096);
68
69        *serial_log_offsetp = 4;
70}
71
72
73void hw_watchdog_reset(void){
74        volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
75        volatile u32 *sys_outputclear = (volatile u32*)SYS_OUTPUTCLR;
76        if(wdi_status){
77                *sys_outputset = GPIO_CPU_LED|GPIO_WDI;
78                wdi_status = 0;
79        }
80        else{
81                *sys_outputclear = GPIO_CPU_LED|GPIO_WDI;
82                wdi_status = 1;
83        }
84}
85
86phys_size_t initdram(int board_type)
87{
88        /* Sdram is setup by assembler code */
89        /* If memory could be changed, we should return the true value here */
90
91        WATCHDOG_RESET();
92
93        return (SDRAM_SIZE);
94}
95
96/* In cpu/mips/cpu.c */
97void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
98
99void set_ledcard(u32 value){
100        /* Clock 24 bits to led card */
101        int i;
102        volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
103        volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;
104
105        /* Start with known values */
106        *sys_outputclr = GPIO_LEDCLK|GPIO_LEDD;
107
108        for(i=0;i<24;i++){
109                if(value&0x00800000){
110                        *sys_outputset = GPIO_LEDD;
111                }
112                else{
113                        *sys_outputclr = GPIO_LEDD;
114                }
115                udelay(1);
116                *sys_outputset = GPIO_LEDCLK;
117                udelay(1);
118                *sys_outputclr = GPIO_LEDCLK;
119                udelay(1);
120
121                value<<=1;
122        }
123        /* Data is enable output */
124        *sys_outputset = GPIO_LEDD;
125}
126
127int checkboard (void)
128{
129        volatile u32 *sys_counter = (volatile u32*)SYS_COUNTER_CNTRL;
130        volatile u32 *sys_outputset = (volatile u32*)SYS_OUTPUTSET;
131        volatile u32 *sys_outputclr = (volatile u32*)SYS_OUTPUTCLR;
132        u32 proc_id;
133
134        WATCHDOG_RESET();
135
136        *sys_counter = 0x100; /* Enable 32 kHz oscillator for RTC/TOY */
137
138        proc_id = read_c0_prid();
139
140        switch (proc_id >> 24) {
141        case 0:
142                puts ("Board: GTH2\n");
143                printf ("CPU: Au1000 500 MHz, id: 0x%02x, rev: 0x%02x\n",
144                        (proc_id >> 8) & 0xFF, proc_id & 0xFF);
145                break;
146        default:
147                printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id >> 24, proc_id);
148        }
149
150        set_io_port_base(0);
151
152#ifdef CONFIG_IDE_PCMCIA
153        /* PCMCIA is on a 36 bit physical address.
154           We need to map it into a 32 bit addresses */
155        write_one_tlb(20,                 /* index */
156                      0x01ffe000,         /* Pagemask, 16 MB pages */
157                      CFG_PCMCIA_IO_BASE, /* Hi */
158                      0x3C000017,         /* Lo0 */
159                      0x3C200017);        /* Lo1 */
160
161        write_one_tlb(21,                   /* index */
162                      0x01ffe000,           /* Pagemask, 16 MB pages */
163                      CFG_PCMCIA_ATTR_BASE, /* Hi */
164                      0x3D000017,           /* Lo0 */
165                      0x3D200017);          /* Lo1 */
166
167        write_one_tlb(22,                   /* index */
168                      0x01ffe000,           /* Pagemask, 16 MB pages */
169                      CFG_PCMCIA_MEM_ADDR,  /* Hi */
170                      0x3E000017,           /* Lo0 */
171                      0x3E200017);          /* Lo1 */
172
173#endif  /* CONFIG_IDE_PCMCIA */
174
175        /* Wait for GPIO ports to become stable */
176        udelay(5000); /* FIXME */
177
178        /* Release reset of ethernet PHY chips */
179        /* Always do this, because linux does not know about it */
180        *sys_outputset = GPIO_ERESET;
181
182        /* Kill FPGA:s */
183        *sys_outputclr = GPIO_CACONFIG|GPIO_DPACONFIG;
184        udelay(2);
185        *sys_outputset = GPIO_CACONFIG|GPIO_DPACONFIG;
186
187        /* Turn front led yellow */
188        set_ledcard(0x00100000);
189
190        return 0;
191}
192
193#define POWER_OFFSET    0xF0000
194#define SW_WATCHDOG_REASON 13
195
196#define BOOTDATA_OFFSET 0xF8000
197#define MAX_ATTEMPTS 5
198
199#define FAILSAFE_BOOT 1
200#define SYSTEM_BOOT   2
201#define SYSTEM2_BOOT  3
202
203#define WRITE_FLASH16(a, d)      \
204do                              \
205{                               \
206  *((volatile u16 *) (a)) = (d);\
207 } while(0)
208
209static void write_bootdata (volatile u16 * addr, u8 System, u8 Count)
210{
211        u16 data;
212        volatile u16 *flash = (u16 *) (CFG_FLASH_BASE);
213
214        switch(System){
215        case FAILSAFE_BOOT:
216                printf ("Setting failsafe boot in flash\n");
217                break;
218        case SYSTEM_BOOT:
219                printf ("Setting system boot in flash\n");
220                break;
221        case SYSTEM2_BOOT:
222                printf ("Setting system2 boot in flash\n");
223                break;
224        default:
225                printf ("Invalid system data %u, setting failsafe\n", System);
226                System = FAILSAFE_BOOT;
227        }
228
229        if ((Count < 1) | (Count > MAX_ATTEMPTS)) {
230                printf ("Invalid boot count %u, setting 1\n", Count);
231                Count = 1;
232        }
233
234        printf ("Boot attempt %d\n", Count);
235
236        data = (System << 8) | Count;
237        /* AMD 16 bit */
238        WRITE_FLASH16 (&flash[0x555], 0xAAAA);
239        WRITE_FLASH16 (&flash[0x2AA], 0x5555);
240        WRITE_FLASH16 (&flash[0x555], 0xA0A0);
241
242        WRITE_FLASH16 (addr, data);
243}
244
245static int random_system(void){
246        /* EEPROM read failed. Just try to choose one
247           system release and hope it works */
248
249        /* FIXME */
250        return(SYSTEM_BOOT);
251}
252
253static int switch_system(int old_system){
254        u8 Rx[10];
255        u8 Tx[5];
256        int valid_release;
257
258        if(old_system==FAILSAFE_BOOT){
259                /* Find out which system release to use */
260
261                /* Copy from nvram to scratchpad */
262                Tx[0] = RECALL_MEMORY;
263                Tx[1] = 7; /* Page */
264                if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {
265                        printf ("EE user page 7 recall failed\n");
266                        return (random_system());
267                }
268
269                Tx[0] = READ_SCRATCHPAD;
270                if (ee_do_cpu_command (Tx, 2, Rx, 9, 1)) {
271                        printf ("EE user page 7 read failed\n");
272                        return (random_system());
273                }
274                /* Crc in 9:th byte */
275                if (!ee_crc_ok (Rx, 8, *(Rx + 8))) {
276                        printf ("EE read failed, page 7. CRC error\n");
277                        return (random_system());
278                }
279
280                valid_release = Rx[7];
281                if((valid_release==0xFF)|
282                   ((valid_release&1) == 0)){
283                        return(SYSTEM_BOOT);
284                }
285                else{
286                        return(SYSTEM2_BOOT);
287                }
288        }
289        else{
290                return(FAILSAFE_BOOT);
291        }
292}
293
294static void check_boot_tries (void)
295{
296        /* Count the number of boot attemps
297           switch system if too many */
298
299        int i;
300        volatile u16 *addr;
301        volatile u16 data;
302        u8 system = FAILSAFE_BOOT;
303        u8 count;
304
305        addr = (u16 *) (CFG_FLASH_BASE + BOOTDATA_OFFSET);
306
307        if (*addr == 0xFFFF) {
308                printf ("*** No bootdata exists. ***\n");
309                write_bootdata (addr, FAILSAFE_BOOT, 1);
310        } else {
311                /* Search for latest written bootdata */
312                i = 0;
313                while ((*(addr + 1) != 0xFFFF) & (i < 8000)) {
314                        addr++;
315                        i++;
316                }
317                if (i >= 8000) {
318                        /* Whoa, dont write any more */
319                        printf ("*** No bootdata found. Not updating flash***\n");
320                } else {
321                        /* See how many times we have tried to boot real system */
322                        data = *addr;
323                        system = data >> 8;
324                        count = data & 0xFF;
325                        if ((system != SYSTEM_BOOT) &
326                            (system != SYSTEM2_BOOT) &
327                            (system != FAILSAFE_BOOT)) {
328                                printf ("*** Wrong system %d\n", system);
329                                system = FAILSAFE_BOOT;
330                                count = 1;
331                        } else {
332                                switch (count) {
333                                case 0:
334                                case 1:
335                                case 2:
336                                case 3:
337                                case 4:
338                                        /* Try same system again if needed */
339                                        count++;
340                                        break;
341
342                                case 5:
343                                        /* Switch system and reset tries */
344                                        count = 1;
345                                        system = switch_system(system);
346                                        printf ("***Too many boot attempts, switching system***\n");
347                                        break;
348                                default:
349                                        /* Switch system, start over and hope it works */
350                                        printf ("***Unexpected data on addr 0x%x, %u***\n",
351                                                (u32) addr, data);
352                                        count = 1;
353                                        system = switch_system(system);
354                                }
355                        }
356                        write_bootdata (addr + 1, system, count);
357                }
358        }
359        switch(system){
360        case FAILSAFE_BOOT:
361                printf ("Booting failsafe system\n");
362                setenv ("bootargs", "panic=1 root=/dev/hda7");
363                setenv ("bootcmd", "ide reset;disk 0x81000000 0:5;run addmisc;bootm");
364                break;
365
366        case SYSTEM_BOOT:
367                printf ("Using normal system\n");
368                setenv ("bootargs", "panic=1 root=/dev/hda4");
369                setenv ("bootcmd", "ide reset;disk 0x81000000 0:2;run addmisc;bootm");
370                break;
371
372        case SYSTEM2_BOOT:
373                printf ("Using normal system2\n");
374                setenv ("bootargs", "panic=1 root=/dev/hda9");
375                setenv ("bootcmd", "ide reset;disk 0x81000000 0:8;run addmisc;bootm");
376                break;
377        default:
378                printf ("Invalid system %d\n", system);
379                printf ("Hanging\n");
380                while(1);
381        }
382}
383
384int misc_init_r(void){
385        u8 Rx[80];
386        u8 Tx[5];
387        int page;
388        int read = 0;
389
390        WATCHDOG_RESET();
391
392        if (ee_init_cpu_data ()) {
393                printf ("EEPROM init failed\n");
394                return (0);
395        }
396
397        /* Check which release to boot */
398        check_boot_tries ();
399
400        /* Read the pages where ethernet address is stored */
401
402        for (page = EE_USER_PAGE_0; page <= EE_USER_PAGE_0 + 2; page++) {
403                /* Copy from nvram to scratchpad */
404                Tx[0] = RECALL_MEMORY;
405                Tx[1] = page;
406                if (ee_do_cpu_command (Tx, 2, NULL, 0, 1)) {
407                        printf ("EE user page %d recall failed\n", page);
408                        return (0);
409                }
410
411                Tx[0] = READ_SCRATCHPAD;
412                if (ee_do_cpu_command (Tx, 2, Rx + read, 9, 1)) {
413                        printf ("EE user page %d read failed\n", page);
414                        return (0);
415                }
416                /* Crc in 9:th byte */
417                if (!ee_crc_ok (Rx + read, 8, *(Rx + read + 8))) {
418                        printf ("EE read failed, page %d. CRC error\n", page);
419                        return (0);
420                }
421                read += 8;
422        }
423
424        /* Add eos after eth addr */
425        Rx[17] = 0;
426
427        printf ("Ethernet addr read from eeprom: %s\n\n", Rx);
428
429        if ((Rx[2] != ':') |
430            (Rx[5] != ':') |
431            (Rx[8] != ':') | (Rx[11] != ':') | (Rx[14] != ':')) {
432                printf ("*** ethernet addr invalid, using default ***\n");
433        } else {
434                setenv ("ethaddr", (char *)Rx);
435        }
436        return (0);
437}
Note: See TracBrowser for help on using the repository browser.