thor: fix invalid larger device descriptor than requested
[profile/mobile/platform/kernel/u-boot-tm1.git] / board / gth2 / gth2.c
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
34 static 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
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;
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
58 void 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
73 void 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
86 phys_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 arch/mips/cpu/cpu.c */
97 void write_one_tlb( int index, u32 pagemask, u32 hi, u32 low0, u32 low1 );
98
99 void 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
127 int 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                       CONFIG_SYS_PCMCIA_IO_BASE, /* Hi */
158                       0x3C000017,         /* Lo0 */
159                       0x3C200017);        /* Lo1 */
160
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 */
166
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 */
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)      \
204 do                              \
205 {                               \
206   *((volatile u16 *) (a)) = (d);\
207  } while(0)
208
209 static void write_bootdata (volatile u16 * addr, u8 System, u8 Count)
210 {
211         u16 data;
212         volatile u16 *flash = (u16 *) (CONFIG_SYS_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
245 static 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
253 static 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
294 static 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 *) (CONFIG_SYS_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
384 int 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 }