Setting up repository
[linux-libre-firmware.git] / ath9k_htc / sboot / magpie_1_1 / sboot / athos / src / athos_main.c
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted (subject to the limitations in the
7  * disclaimer below) provided that the following conditions are met:
8  *
9  *  * Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  *  * Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the
15  *    distribution.
16  *
17  *  * Neither the name of Qualcomm Atheros nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
22  * GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
23  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
24  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 /*
36  * Copyright (c) 2000-2008 Atheros Communications, Inc., All Rights Reserved
37  *
38  * $Id: //depot/sw/branches/fusion_usb/target_firmware/magpie_fw_dev/build/magpie_1_1/sboot/athos/src/athos_main.c#1 $
39  *
40  * This file contains type definitions
41  */
42
43 /* osapi support */
44 #include "sys_cfg.h"
45 #include "athos_api.h"
46 //#include <fwd.h>
47
48 #include "regdump.h"
49
50 /* dhry mips stone test */
51 //#include "dhry.h"
52
53 /* usb support */
54 //#include "usb_defs.h"
55 //#include "usb_type.h"
56
57 /* xtensa related */
58 #include "xtensa/corebits.h"
59 #include "xtensa/tie/xt_core.h"
60
61 #include <dma_lib.h>
62 #include <hif_pci.h>
63 #include <hif_gmac.h>
64 #include <fwd.h>
65
66
67 BOOLEAN download_enable = FALSE;
68
69 /* #define ALLOCRAM_START       0x512800 */
70 /* #define ALLOCRAM_SIZE        ( SYS_RAM_SZIE - ( ALLOCRAM_START - SYS_D_RAM_REGION_0_BASE) - SYS_D_RAM_STACK_SIZE) */
71
72 #define ALLOCRAM_START       SYS_D_RAM_REGION_3_BASE
73 #define ALLOCRAM_SIZE        SYS_RAM_BLOCK_SIZE
74
75 extern unsigned int _text_start_in_rom;
76 extern unsigned int _text_start;
77 extern unsigned int _text_end;
78
79 extern unsigned int _rodata_start_in_rom;
80 extern unsigned int _lit4_start;
81 extern unsigned int _lit4_end;
82
83 /*
84  * This special table is used by Xtensa startup code to copy
85  * ROM-based data into RAM.  See Xtensa documentation or
86  * "unpack" code in ResetVector.S for details.
87  */
88 const uint32_t _rom_store_table[] = {
89     (uint32_t)&_data_start,   (uint32_t)&_data_end, (uint32_t)&_data_start_in_rom,
90     (uint32_t)&_text_start,   (uint32_t)&_text_end, (uint32_t)0xf002000,
91     (uint32_t)&_lit4_start,   (uint32_t)&_lit4_end, (uint32_t)0xf008000,
92     (uint32_t)0x00500400,   (uint32_t)0x00500940,  (uint32_t)0x004e0260,
93     0,   0,             0
94 };
95
96
97 #define ATH_DATE_STRING     __DATE__" "__TIME__
98
99
100 /*
101  * 03/09: it'll always fall into this exception if we enable this exception handler, need to do more testing, Ryan
102  */
103 void
104 Magpie_fatal_exception_handler(CPU_exception_frame_t *exc_frame)
105 {
106     struct register_dump_s dump;
107
108     dump.exc_frame              = *exc_frame; /* structure copy */
109     dump.badvaddr               = XT_RSR_EXCVADDR();
110     dump.exc_frame.xt_exccause  = XT_RSR_EXCCAUSE();
111     dump.pc                     = exc_frame->xt_pc;
112     dump.assline                = 0;
113
114     A_PRINTF("Fatal exception (%d): pc=0x%x badvaddr=0x%x dump area=0x%x\n",
115                 dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr, &dump);
116     // PRINT_FAILURE_STATE();
117
118     // A_ASSFAIL(&dump); // misc module
119 }
120
121 //dummy now
122 //void app_start(void);
123
124 static int
125 athos_linkage_check(int sz, struct _A_os_linkage_check *link_check)
126 {
127     if (sz != sizeof(struct _A_os_linkage_check)) {
128         goto app_link_error;
129     }
130
131     if (link_check->version != OS_LINKAGE_VERSION) {
132         goto app_link_error;
133     }
134
135     if (link_check->table != sizeof(struct _A_magpie_indirection_table) &&
136         (link_check->table != 0)) {
137         goto app_link_error;
138     }
139
140     return 1; /* successful linkage check */
141
142 app_link_error:
143 //    A_PRINTF("athos_linkage_check failure!\n");
144     A_PUTS("-A1-\n\r");
145     return 0;
146 }
147
148
149 #ifdef SYSTEM_MODULE_INTR
150
151 /* Mask of Interrupt Level bits in Xtensa's Processor Status register */
152 #define XTENSA_PS_INTLEVEL_MASK 0xf
153
154 LOCAL uint32_t
155 athos_block_all_intrlvl(void)
156 {
157     uint32_t tmp;
158
159     /*
160      * This function doesn't actually block ALL interrupts;
161      * it leaves ERROR & WDT interrupts -- which are fatal
162      * and are at level 3 -- active.
163      */
164     asm volatile("rsil %0,2" : "=r" (tmp));
165
166     return (uint32_t)((A_UINT32)tmp & XTENSA_PS_INTLEVEL_MASK);
167 }
168
169 LOCAL void
170 athos_unblock_all_intrlvl(void)
171 {
172     unsigned int tmp;
173
174     asm volatile("rsil %0, 0" : "=r" (tmp));
175 }
176
177 LOCAL void
178 athos_restore_intrlvl(uint32_t old_intr)
179 {
180     if (old_intr == 0) {
181         athos_unblock_all_intrlvl();
182     }
183 }
184 #endif
185
186
187 static void
188 AR6002_misaligned_load_handler(CPU_exception_frame_t *exc_frame)
189 {
190     struct register_dump_s dump;
191     uint32_t *stkptr;
192
193 #if SYSTEM_MODULE_PRINT
194     A_PRINTF("misaligned_load\n\r");
195 #else
196     A_PUTS("misaligned_load\n\r");
197 #endif
198
199     dump.exc_frame = *exc_frame; /* structure copy */
200     dump.badvaddr  = XT_RSR_EXCVADDR();
201     dump.pc        = exc_frame->xt_pc;
202
203     asm volatile("mov %0,a1" : "=r" (stkptr));
204
205     /* Stores a0,a1,a2,a3 on stack; but leaves sp unchanged */
206     xthal_window_spill();
207
208         {
209         int i;
210
211 #define MAGPIE_REGDUMP_FRAMES 5
212
213         /* Walk back the stack */
214         for (i=0; i<MAGPIE_REGDUMP_FRAMES; i++) {
215             dump.exc_frame.wb[i].a0 = stkptr[-4];
216             dump.exc_frame.wb[i].a1 = stkptr[-3];
217             dump.exc_frame.wb[i].a2 = stkptr[-2];
218             dump.exc_frame.wb[i].a3 = stkptr[-1];
219             if (dump.exc_frame.wb[i].a0 == 0) {
220                 break;
221             }
222             stkptr = (uint32_t *)dump.exc_frame.wb[i].a1;
223         }
224     }
225
226     A_MISALIGNED_LOAD_HANDLER(&dump);
227
228 }
229
230 static void
231 AR6002_fatal_exception_handler(CPU_exception_frame_t *exc_frame)
232 {
233     struct register_dump_s dump;
234
235     dump.exc_frame              = *exc_frame; /* structure copy */
236     dump.badvaddr               = XT_RSR_EXCVADDR();
237     dump.exc_frame.xt_exccause  = XT_RSR_EXCCAUSE();
238     dump.pc                     = exc_frame->xt_pc;
239     dump.assline                = 0;
240
241 #if SYSTEM_MODULE_PRINT
242     A_PRINTF("Fatal exception (%d): \tpc=0x%x \n\r\tbadvaddr=0x%x \n\r\tdump area=0x%x\n",
243                 dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr, &dump);
244     PRINT_FAILURE_STATE();
245  #else
246     A_PUTS("Fatal exception\n\r");
247 #endif
248
249     A_ASSFAIL(&dump);
250
251      // trigger wdt, in case hang
252 #if defined(_ROM_)     
253     //HAL_WORD_REG_WRITE(MAGPIE_REG_RST_WDT_TIMER_CTRL_ADDR, 0x03);
254     //HAL_WORD_REG_WRITE(MAGPIE_REG_RST_WDT_TIMER_ADDR, 0x10);
255         A_WDT_ENABLE();
256 #endif
257
258     while(1)
259         ;
260 }
261
262
263 typedef void (*INSTFN)(void *);
264
265 /*
266  * These are all modules that reside in ROM which are installed
267  * by default by the operating system.  Other ROM modules may
268  * be installed by the application if they are needed.
269  */
270 struct {
271     void (* install_fn)(void *);
272     void *api_tbl;
273 } basic_ROM_module_table[] =
274 {
275
276 #if SYSTEM_MODULE_MEM
277     {(INSTFN)cmnos_mem_module_install,          (void *)&A_CMN(mem)},
278 #endif
279
280 #if SYSTEM_MODULE_MISC
281     {(INSTFN)cmnos_misc_module_install,         (void *)&A_CMN(misc)},
282 #endif
283
284 #if SYSTEM_MODULE_PRINT
285     {(INSTFN)cmnos_printf_module_install,       (void *)&A_CMN(printf)},
286 #endif
287
288 #if SYSTEM_MODULE_UART
289     {(INSTFN)cmnos_uart_module_install,       (void *)&A_CMN(uart)},
290 #endif
291
292 #if SYSTEM_MODULE_USB
293     {(INSTFN)cmnos_usb_module_install,       (void *)&A_CMN(usb)},
294 #endif
295
296 #if SYSTEM_MODULE_INTR
297     {(INSTFN)cmnos_intr_module_install,       (void *)&A_CMN(intr)},
298 #endif
299
300 #if SYSTEM_MODULE_TIMER
301     {(INSTFN)cmnos_timer_module_install,       (void *)&A_CMN(timer)},
302 #endif
303
304 #if SYSTEM_MODULE_CLOCK
305     {(INSTFN)cmnos_clock_module_install,       (void *)&A_CMN(clock)},
306 #endif
307
308 #if SYSTEM_MODULE_ALLOCRAM
309     {(INSTFN)cmnos_allocram_module_install,       (void *)&A_CMN(allocram)},
310 #endif
311
312 #if SYSTEM_MODULE_ROM_PATCH
313     {(INSTFN)cmnos_romp_module_install,       (void *)&A_CMN(romp)},
314 #endif
315
316 #if SYSTEM_MODULE_WDT
317     {(INSTFN)cmnos_wdt_module_install,       (void *)&A_CMN(wdt_timer)},
318 #endif
319
320 #if SYSTEM_MODULE_EEPROM
321     {(INSTFN)cmnos_eep_module_install,       (void *)&A_CMN(eep)},
322 #endif
323     {(INSTFN)cmnos_string_module_install,        (void *)&A_CMN(string)},
324     {(INSTFN)cmnos_tasklet_module_install,        (void *)&A_CMN(tasklet)},
325     {(INSTFN)vdesc_module_install,                  (void *)&A_INDIR(vdesc)},
326     {(INSTFN)vbuf_module_install,                   (void *)&A_INDIR(vbuf)},
327     {(INSTFN)generic_hif_module_install,                   (void *)&A_INDIR(hif)},
328     {(INSTFN)buf_pool_module_install,                  (void *)&A_INDIR(buf_pool)},
329     {(INSTFN)usbfifo_module_install,                  (void *)&A_INDIR(usbfifo_api)},
330     {(INSTFN)dma_engine_module_install,             (void *)&A_INDIR(dma_engine)}, 
331     {(INSTFN)dma_lib_module_install,                (void *)&A_INDIR(dma_lib)}, 
332 };
333
334 #define BASIC_ROM_MODULE_TABLE_SZ (sizeof(basic_ROM_module_table)/sizeof(basic_ROM_module_table[0]))
335
336 void
337 generic_hif_module_install(struct hif_api *apis)
338 {
339   A_HOSTIF hostif;
340
341   hostif = A_IS_HOST_PRESENT();
342
343   switch(hostif){
344         case HIF_USB:
345           hif_usb_module_install(apis);
346       break;
347         }
348 }
349
350 void
351 athos_indirection_table_install(void)
352 {
353     unsigned int i;
354
355     /* Sanity: start with a clear table */
356     {
357         //char *tbl = (char *)_A_OS_INDIRECTION_TABLE;
358         char *tbl = (char *)_A_MAGPIE_INDIRECTION_TABLE;
359
360         //for (i=0; i<_A_OS_INDIRECTION_TABLE_SIZE; i++) {
361         for (i=0; i<_A_MAGPIE_INDIRECTION_TABLE_SIZE; i++) {
362             tbl[i] = 0;
363         }
364     }
365
366     /* Install basic ROM modules */
367     for (i=0; i<BASIC_ROM_MODULE_TABLE_SZ; i++) {
368         basic_ROM_module_table[i].install_fn(basic_ROM_module_table[i].api_tbl);
369     }
370
371         #if !defined(_ROM_)
372         DBG_MODULE_INSTALL(); // move DBG to indirection table
373         #endif
374
375     //_A_OS_INDIRECTION_TABLE->cmnos.app_start = app_start;
376     //_A_OS_INDIRECTION_TABLE->cmnos.hal_linkage_check     = athos_linkage_check;
377     //_A_MAGPIE_INDIRECTION_TABLE->cmnos.app_start = app_start;
378     _A_MAGPIE_INDIRECTION_TABLE->cmnos.hal_linkage_check     = athos_linkage_check;
379
380 //    _A_OS_INDIRECTION_TABLE->cmnos.start_bss             = &START_BSS;
381
382 #if SYSTEM_MODULE_INTR
383     /* Install a few CPU-specific functions */
384     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._get_intrenable = xthal_get_intenable;
385     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._set_intrenable = xthal_set_intenable;
386     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._get_intrpending = xthal_get_interrupt;
387     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._unblock_all_intrlvl = athos_unblock_all_intrlvl;
388     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._intr_disable = athos_block_all_intrlvl;
389     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._intr_restore = athos_restore_intrlvl;
390 #endif
391
392     /* UNALIGNED references are used for ASSERTs */
393     (void)_xtos_set_exception_handler(EXCCAUSE_UNALIGNED, AR6002_misaligned_load_handler);
394     (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_ERROR, AR6002_fatal_exception_handler);
395     (void)_xtos_set_exception_handler(EXCCAUSE_ILLEGAL, AR6002_fatal_exception_handler);
396     (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_ERROR, AR6002_fatal_exception_handler);
397     (void)_xtos_set_exception_handler(EXCCAUSE_PRIVILEGED, AR6002_fatal_exception_handler);
398     (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_DATA_ERROR, AR6002_fatal_exception_handler);
399     (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, AR6002_fatal_exception_handler);
400     (void)_xtos_set_exception_handler(EXCCAUSE_DIVIDE_BY_ZERO, AR6002_fatal_exception_handler);
401 }
402
403
404 #ifdef SYSTEM_MODULE_INTR
405 /*
406  * All interrupts pass through here.  Yes, it adds a
407  * bit of overhead; but it may be very helpful with
408  * debugging, ROM patching, and workarounds.
409  *
410  * NB: Assembler code that calls this loops through all
411  * pending & enabled interrupts.
412  */
413 void
414 athos_interrupt_handler(unsigned int inum, unsigned int *interrupt_frame)
415 {
416     A_INVOKE_ISR(inum);
417 }
418 #endif
419
420 void
421 athos_interrupt_init(void)
422 {
423 #ifdef SYSTEM_MODULE_INTR
424     int i;
425     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x20;
426
427     for (i=0; i<NUM_DIRECT_INTR; i++) {
428         (void)_xtos_set_interrupt_handler(i, athos_interrupt_handler);
429     }
430     
431     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x21;
432     A_INTR_INIT();
433 //    A_MC_REG_WRITE(ADDR_ERROR_CONTROL_ADDRESS, ADDR_ERROR_CONTROL_ENABLE_MASK);
434
435     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x22;
436     athos_unblock_all_intrlvl();
437 #endif
438 }
439
440
441
442 void athos_init(A_HOSTIF hif)
443 {
444
445     ///////////////////////////////////////////////////////
446     //init each module, should be put together..
447     A_CLOCK_INIT(SYSTEM_CLK);
448
449     A_UART_INIT();
450     A_PRINTF_INIT();
451
452     A_EEP_INIT();
453 }
454
455 void led_on(unsigned int bit)
456 {
457     *(unsigned long *)0x5200c = 1<<bit;
458 }
459
460 void led_off(unsigned int bit)
461 {
462     *(unsigned long *)0x52010 = 1<<bit;
463 }
464
465
466 void led_all_on() 
467 {
468     led_on(10);
469     led_on(12);
470 }
471
472 void led_all_off()
473 {
474     led_off(10);
475     led_off(12);
476 }
477
478
479 unsigned long i=0;
480 #define LED_ON_OFF_FREQ 500
481
482 void led_task()
483 {
484     i++;
485    
486     if(i==LED_ON_OFF_FREQ*1)
487         led_on(10);
488     else if (i==LED_ON_OFF_FREQ*2)
489         led_on(12);
490     else if (i==LED_ON_OFF_FREQ*3)
491         led_off(12);
492     else if (i==LED_ON_OFF_FREQ*4)
493         led_off(10);
494     else if (i==LED_ON_OFF_FREQ*5)
495         led_all_on();
496     else if (i==LED_ON_OFF_FREQ*6)
497     {
498         i=0;
499         led_all_off();
500     }
501 }
502
503
504 void bootload()
505 {
506     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xe;
507     CURRENT_PROGRAM = (uint32_t)bootload;
508     A_PUTS("8. wait for read/read_comp.... \n\r");
509     while(1) {
510
511         /* update wdt timer */
512         //A_WDT_TASK();
513
514         /* high priority tasks */
515         A_USB_ROM_TASK();
516         
517 //        A_DBG_TASK();
518         led_task();
519
520         if( download_enable )
521             break;
522     }
523
524 }
525
526 void
527 change_magpie_clk(uint32_t  cpu_freq, uint32_t ahb_div)
528 {
529     volatile uint32_t i = 0;
530     volatile uint32_t rd_data = 0, wd_data = 0;
531
532     /* Put the PLL into reset */
533     rd_data = HAL_WORD_REG_READ(0x00050010) | (1<<1);
534     HAL_WORD_REG_WRITE(0x00050010,rd_data);
535
536     HAL_WORD_REG_WRITE(0x00056004, 0x11);
537     rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
538
539     /* Wait for the update bit to get cleared */
540     while (rd_data)
541         rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
542
543     /* Setting of the PLL */
544     if (cpu_freq== 100) wd_data = 0x142;      /* PLL 400 MHz*/
545     else if (cpu_freq== 105) wd_data = 0x152; /* PLL 420 MHz */
546     else if (cpu_freq== 110) wd_data = 0x162; /* PLL 440 MHz*/
547     else if (cpu_freq== 115) wd_data = 0x172; /* PLL 460 MHz */
548     else if (cpu_freq== 120) wd_data = 0x182; /* PLL 480 MHz */
549     else if (cpu_freq== 125) wd_data = 0x192; /* PLL 500 MHz */
550     else if (cpu_freq== 130) wd_data = 0x1a2; /* PLL 520 MHz */
551     else if (cpu_freq== 135) wd_data = 0x1b2; /* PLL 540 MHz */
552     else if (cpu_freq== 140) wd_data = 0x1c2; /* PLL 560 MHz */
553     else if (cpu_freq== 145) wd_data = 0x1d2; /* PLL 580 MHz */
554     else if (cpu_freq== 150) wd_data = 0x1e2; /* PLL 600 MHz */
555     else if (cpu_freq== 155) wd_data = 0x1f2; /* PLL 620 MHz */
556     else if (cpu_freq== 160) wd_data = 0x202; /* PLL 640 MHz */
557     else if (cpu_freq== 165) wd_data = 0x212; /* PLL 660 MHz */
558     else if (cpu_freq== 170) wd_data = 0x222; /* PLL 680 MHz */
559     else if (cpu_freq== 175) wd_data = 0x232; /* PLL 700 MHz */
560     else if (cpu_freq== 180) wd_data = 0x242; /* PLL 720 MHz */
561     else if (cpu_freq== 185) wd_data = 0x252; /* PLL 740 MHz */
562     else if (cpu_freq== 190) wd_data = 0x262; /* PLL 760 MHz */
563     else if (cpu_freq== 195) wd_data = 0x272; /* PLL 780 MHz */
564     else if (cpu_freq== 200) wd_data = 0x142; /* PLL 400 MHz */
565     else if (cpu_freq== 210) wd_data = 0x152; /* PLL 420 MHz */
566     else if (cpu_freq== 220) wd_data = 0x162; /* PLL 440 MHz */
567     else if (cpu_freq== 230) wd_data = 0x172; /* PLL 460 MHz */
568     else if (cpu_freq== 240) wd_data = 0x182; /* PLL 480 MHz */
569     else if (cpu_freq== 250) wd_data = 0x192; /* PLL 500 MHz */
570     else if (cpu_freq== 260) wd_data = 0x1a2; /* PLL 520 MHz */
571     else if (cpu_freq== 270) wd_data = 0x1b2; /* PLL 540 MHz */
572     else if (cpu_freq== 280) wd_data = 0x1c2; /* PLL 560 MHz */
573     else if (cpu_freq== 290) wd_data = 0x1d2; /* PLL 580 MHz */
574     else if (cpu_freq== 300) wd_data = 0x1e2; /* PLL 600 MHz */
575     else if (cpu_freq== 310) wd_data = 0x1f2; /* PLL 620 MHz */
576     else if (cpu_freq== 320) wd_data = 0x202; /* PLL 640 MHz */
577     else if (cpu_freq== 330) wd_data = 0x212; /* PLL 660 MHz */
578     else if (cpu_freq== 340) wd_data = 0x222; /* PLL 680 MHz */
579     else if (cpu_freq== 350) wd_data = 0x232; /* PLL 700 MHz */
580     else if (cpu_freq== 360) wd_data = 0x242; /* PLL 720 MHz */
581     else if (cpu_freq== 370) wd_data = 0x252; /* PLL 740 MHz */
582     else if (cpu_freq== 380) wd_data = 0x262; /* PLL 760 MHz */
583     else if (cpu_freq== 390) wd_data = 0x272; /* PLL 780 MHz */
584     else if (cpu_freq== 400) wd_data = 0x282; /* PLL 800 MHz */
585     else wd_data = 0x142;                     /* PLL 400 MHz*/
586
587     HAL_WORD_REG_WRITE(0x00056000, wd_data);
588
589     /* Pull CPU PLL out of Reset */
590     rd_data = HAL_WORD_REG_READ(0x00050010) & ~(1<<1);
591     HAL_WORD_REG_WRITE(0x00050010,rd_data);
592
593     /* CPU & AHB settings */
594     rd_data = HAL_WORD_REG_READ(0x00056004);
595
596     /*  > 200 Mhz CPU clock (PLL / 2) or  < 200 Mhz (PLL / 4) */
597     if (cpu_freq > 195)
598         rd_data = (rd_data & ~(0xff<<16)) | (1<<16);
599     else
600         rd_data = (rd_data & ~(0xff<<16)) | (2<<16);
601
602     /* AHB Clock, AHB_FREQ = CPU_FREQ / ahb_div */
603     switch (ahb_div) {
604     case 1:
605         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | 0x1;
606         break;
607     case 2:
608         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (1<<8) | 0x1;
609         break;
610     case 4:
611         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (2<<8) | 0x1;
612         break;
613     default:
614         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (1<<8) | 0x1;
615         break;
616     }
617     
618     HAL_WORD_REG_WRITE(0x00056004, rd_data);
619     rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
620
621     while(rd_data)
622         rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
623
624     while(i++ < 1000)
625         ;
626     
627     /* UART Setting */
628     A_UART_HWINIT((cpu_freq / ahb_div) * (1000*1000), 115200);
629
630 //    A_PRINTF("reg_read(0x56000): %p \n", HAL_WORD_REG_READ(0x00056000));
631 //    A_PRINTF("reg_read(0x56004): %p \n", HAL_WORD_REG_READ(0x00056004));
632
633     /* set the current reference clock */
634 //    A_CLOCK_INIT(cpu_freq);
635
636 }
637
638 /* 
639  * rom1.0 fix: turn off rc if no patch/eeprom exist
640 */
641 void turn_off_rc()
642 {
643     extern BOOLEAN eep_state;
644
645         // clear the cmnos_eeprom init state
646         eep_state = FALSE;
647
648     // reset the pcie_rc shift, pll and phy
649     HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|(BIT10|BIT9|BIT8|BIT7)));
650         
651     // reset ahb_arb of pcie_rc
652     HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|BIT1));
653 }
654
655 void bootentry(void)
656 {
657     /* uint32_t reset_temp; */
658     A_HOSTIF hostif=0x0;
659     T_BOOT_TYPE rst_status;
660     T_EEP_RET retEEP;
661
662     ///////////////////////////////////
663     athos_indirection_table_install();
664
665     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x1;
666     CURRENT_PROGRAM = (uint32_t)bootentry;
667     // athos module install
668     athos_init(hostif);     // move all the athos indirection table init function to here
669
670     athos_interrupt_init(); // install all interrupt function to known state
671
672     A_WDT_DISABLE();        // make srue wdt is diable
673
674     rst_status = A_WDT_LASTBOOT(); 
675
676     // pump up flash clock to 12.5Mhz
677     HAL_WORD_REG_WRITE(0x5b01c, 0x401);
678     
679         /*
680          *
681          * 1. turn on CPU PLL, reg(0x560000), 0x305
682          * 2. pll reset reg(0x50010), 0x03
683          * 3. pll reset reg(0x50010), 0x01
684          *
685          * - after enabling CPU PLL, left the interface pll setting
686          *   be done in each interface
687          *
688          * e.g usb_init we mdid
689          * 4. usb divide reg(0x56008), 0x0808
690          * 5. clear register reg(0x50010), bit0, bit3, bit4
691          * 6. set register reg(0x50010), bit0, bit3, bit4
692          * 7. clear register reg(0x50010), bit0, bit3, bit4
693          *
694          *  - wait for 200ms for usb phy 30mhz stable -
695          *
696          * 8. usb clock up, proceed reset of things
697          */
698
699         /* reset_temp = HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR); */
700         /* A_PRINTF("reset temp is %x \n",reset_temp); */
701         /* HAL_WORD_REG_WRITE( MAGPIE_REG_RST_RESET_ADDR, 0); */
702         
703
704     /*! move the whole cpu pll setup to host interface specific 
705      *  since when bootup, we have an external clock source
706      */
707     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x2;
708
709     hostif = A_IS_HOST_PRESENT();
710
711 /*!
712  *   GPIO_FUNCTION(0x28) - config uart (sin, sout) pair, 
713  *
714  *   pci host interface will only have (GPIO1, GPIO0), other hif (usb, pcie, gmac)
715  *   will use (GPIO5, GPIO4)
716  *
717  *   BIT8 --> (9,8)
718  *   BIT7 --> (7,6)
719  *   BIT6 --> (5,4)
720  *   BIT5 --> (3,2)
721  *   BIT4 --> (1,0)
722  *   
723  */
724     {
725         HAL_WORD_REG_WRITE( MAGPIE_REG_GPIO_FUNCTION, (HAL_WORD_REG_READ(MAGPIE_REG_GPIO_FUNCTION)&(~(BIT4|BIT5|BIT6|BIT7|BIT8))) );
726         HAL_WORD_REG_WRITE( MAGPIE_REG_GPIO_FUNCTION, (HAL_WORD_REG_READ(MAGPIE_REG_GPIO_FUNCTION)|(BIT8)) );
727     }
728
729     change_magpie_clk(200, 2);
730
731     // power on self test
732     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x5;
733         A_PUTS("\n - Boot from SFLASH - \n\r");
734
735     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x9;
736
737     /*!
738      * check the host interface type,
739      */
740     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x15;
741     hostif = A_IS_HOST_PRESENT();
742
743     retEEP = A_EEP_IS_EXIST();
744
745     turn_off_rc();
746
747     if( hostif == HIF_USB )
748     {
749         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xb;
750 #if 0
751         if( retEEP == RET_SUCCESS)
752         {
753             A_EEP_INIT();
754             /* read the usb descriptor information from rom to ram */
755             read_usb_conf();
756             
757             turn_off_rc();
758         }    
759 #endif
760         A_USB_INIT();
761
762         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xd;
763         bootload();
764     }
765
766 }
767
768
769 int main(void)
770 {
771     *(unsigned long *)0x52000 = 0x7ebff;    // set bit10/bit12 output mode
772     *(unsigned long *)0x0053fff8 = 0x0;
773     
774     // for debug purpose in case we don't know where we are
775     // keep this address update, so that we could trace the where is is
776     DEBUG_SYSTEM_STATE = 0x0;
777
778     bootentry();
779
780     A_PRINTF("FLASH_READ_COMP, jump to firmware\n");
781  
782         led_on(10);
783     led_on(12);
784
785     return 0;
786 }
787