3 * Thomas.Lange@corelatus.se
5 * See file CREDITS for list of people who contributed to this
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.
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.
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,
26 #include <asm/au1x00.h>
27 #include <asm/addrspace.h>
28 #include <asm/mipsregs.h>
32 #include "ee_access.h"
34 static int wdi_status
= 0;
36 #define SDRAM_SIZE ((64*1024*1024)-(12*4096))
39 #define SERIAL_LOG_BUFFER CKSEG1ADDR(SDRAM_SIZE + (8*4096))
41 void 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
;
46 serial_log_offset
= *serial_log_offsetp
;
48 *(serial_log_buffer
+ serial_log_offset
) = c
;
52 if(serial_log_offset
>= 4096){
53 serial_log_offset
= 4;
55 *serial_log_offsetp
= serial_log_offset
;
58 void init_log_serial(void){
59 char *serial_log_buffer
= (char*)SERIAL_LOG_BUFFER
;
60 u32
*serial_log_offsetp
= (u32
*)SERIAL_LOG_BUFFER
;
62 /* Copy buffer from last run */
63 memcpy(serial_log_buffer
+ 4096,
67 memset(serial_log_buffer
, 0, 4096);
69 *serial_log_offsetp
= 4;
73 void hw_watchdog_reset(void){
74 volatile u32
*sys_outputset
= (volatile u32
*)SYS_OUTPUTSET
;
75 volatile u32
*sys_outputclear
= (volatile u32
*)SYS_OUTPUTCLR
;
77 *sys_outputset
= GPIO_CPU_LED
|GPIO_WDI
;
81 *sys_outputclear
= GPIO_CPU_LED
|GPIO_WDI
;
86 phys_size_t
initdram(int board_type
)
88 /* Sdram is setup by assembler code */
89 /* If memory could be changed, we should return the true value here */
96 /* In cpu/mips/cpu.c */
97 void write_one_tlb( int index
, u32 pagemask
, u32 hi
, u32 low0
, u32 low1
);
99 void set_ledcard(u32 value
){
100 /* Clock 24 bits to led card */
102 volatile u32
*sys_outputset
= (volatile u32
*)SYS_OUTPUTSET
;
103 volatile u32
*sys_outputclr
= (volatile u32
*)SYS_OUTPUTCLR
;
105 /* Start with known values */
106 *sys_outputclr
= GPIO_LEDCLK
|GPIO_LEDD
;
109 if(value
&0x00800000){
110 *sys_outputset
= GPIO_LEDD
;
113 *sys_outputclr
= GPIO_LEDD
;
116 *sys_outputset
= GPIO_LEDCLK
;
118 *sys_outputclr
= GPIO_LEDCLK
;
123 /* Data is enable output */
124 *sys_outputset
= GPIO_LEDD
;
127 int checkboard (void)
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
;
136 *sys_counter
= 0x100; /* Enable 32 kHz oscillator for RTC/TOY */
138 proc_id
= read_c0_prid();
140 switch (proc_id
>> 24) {
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);
147 printf ("Unsupported cpu %d, proc_id=0x%x\n", proc_id
>> 24, proc_id
);
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 CONFIG_SYS_PCMCIA_IO_BASE
, /* Hi */
158 0x3C000017, /* Lo0 */
159 0x3C200017); /* Lo1 */
161 write_one_tlb(21, /* index */
162 0x01ffe000, /* Pagemask, 16 MB pages */
163 CONFIG_SYS_PCMCIA_ATTR_BASE
, /* Hi */
164 0x3D000017, /* Lo0 */
165 0x3D200017); /* Lo1 */
167 write_one_tlb(22, /* index */
168 0x01ffe000, /* Pagemask, 16 MB pages */
169 CONFIG_SYS_PCMCIA_MEM_ADDR
, /* Hi */
170 0x3E000017, /* Lo0 */
171 0x3E200017); /* Lo1 */
173 #endif /* CONFIG_IDE_PCMCIA */
175 /* Wait for GPIO ports to become stable */
176 udelay(5000); /* FIXME */
178 /* Release reset of ethernet PHY chips */
179 /* Always do this, because linux does not know about it */
180 *sys_outputset
= GPIO_ERESET
;
183 *sys_outputclr
= GPIO_CACONFIG
|GPIO_DPACONFIG
;
185 *sys_outputset
= GPIO_CACONFIG
|GPIO_DPACONFIG
;
187 /* Turn front led yellow */
188 set_ledcard(0x00100000);
193 #define POWER_OFFSET 0xF0000
194 #define SW_WATCHDOG_REASON 13
196 #define BOOTDATA_OFFSET 0xF8000
197 #define MAX_ATTEMPTS 5
199 #define FAILSAFE_BOOT 1
200 #define SYSTEM_BOOT 2
201 #define SYSTEM2_BOOT 3
203 #define WRITE_FLASH16(a, d) \
206 *((volatile u16 *) (a)) = (d);\
209 static void write_bootdata (volatile u16
* addr
, u8 System
, u8 Count
)
212 volatile u16
*flash
= (u16
*) (CONFIG_SYS_FLASH_BASE
);
216 printf ("Setting failsafe boot in flash\n");
219 printf ("Setting system boot in flash\n");
222 printf ("Setting system2 boot in flash\n");
225 printf ("Invalid system data %u, setting failsafe\n", System
);
226 System
= FAILSAFE_BOOT
;
229 if ((Count
< 1) | (Count
> MAX_ATTEMPTS
)) {
230 printf ("Invalid boot count %u, setting 1\n", Count
);
234 printf ("Boot attempt %d\n", Count
);
236 data
= (System
<< 8) | Count
;
238 WRITE_FLASH16 (&flash
[0x555], 0xAAAA);
239 WRITE_FLASH16 (&flash
[0x2AA], 0x5555);
240 WRITE_FLASH16 (&flash
[0x555], 0xA0A0);
242 WRITE_FLASH16 (addr
, data
);
245 static int random_system(void){
246 /* EEPROM read failed. Just try to choose one
247 system release and hope it works */
253 static int switch_system(int old_system
){
258 if(old_system
==FAILSAFE_BOOT
){
259 /* Find out which system release to use */
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());
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());
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());
280 valid_release
= Rx
[7];
281 if((valid_release
==0xFF)|
282 ((valid_release
&1) == 0)){
286 return(SYSTEM2_BOOT
);
290 return(FAILSAFE_BOOT
);
294 static void check_boot_tries (void)
296 /* Count the number of boot attemps
297 switch system if too many */
302 u8 system
= FAILSAFE_BOOT
;
305 addr
= (u16
*) (CONFIG_SYS_FLASH_BASE
+ BOOTDATA_OFFSET
);
307 if (*addr
== 0xFFFF) {
308 printf ("*** No bootdata exists. ***\n");
309 write_bootdata (addr
, FAILSAFE_BOOT
, 1);
311 /* Search for latest written bootdata */
313 while ((*(addr
+ 1) != 0xFFFF) & (i
< 8000)) {
318 /* Whoa, dont write any more */
319 printf ("*** No bootdata found. Not updating flash***\n");
321 /* See how many times we have tried to boot real system */
325 if ((system
!= SYSTEM_BOOT
) &
326 (system
!= SYSTEM2_BOOT
) &
327 (system
!= FAILSAFE_BOOT
)) {
328 printf ("*** Wrong system %d\n", system
);
329 system
= FAILSAFE_BOOT
;
338 /* Try same system again if needed */
343 /* Switch system and reset tries */
345 system
= switch_system(system
);
346 printf ("***Too many boot attempts, switching system***\n");
349 /* Switch system, start over and hope it works */
350 printf ("***Unexpected data on addr 0x%x, %u***\n",
353 system
= switch_system(system
);
356 write_bootdata (addr
+ 1, system
, count
);
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");
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");
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");
378 printf ("Invalid system %d\n", system
);
379 printf ("Hanging\n");
384 int misc_init_r(void){
392 if (ee_init_cpu_data ()) {
393 printf ("EEPROM init failed\n");
397 /* Check which release to boot */
400 /* Read the pages where ethernet address is stored */
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
;
406 if (ee_do_cpu_command (Tx
, 2, NULL
, 0, 1)) {
407 printf ("EE user page %d recall failed\n", page
);
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
);
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
);
424 /* Add eos after eth addr */
427 printf ("Ethernet addr read from eeprom: %s\n\n", Rx
);
431 (Rx
[8] != ':') | (Rx
[11] != ':') | (Rx
[14] != ':')) {
432 printf ("*** ethernet addr invalid, using default ***\n");
434 setenv ("ethaddr", (char *)Rx
);