void do_exception(unsigned reason,unsigned lr) { serial_puts("Enter Exception:"); serial_put_dword(reason); serial_puts("\tlink addr:"); serial_put_dword(lr); #ifdef CONFIG_ENABLE_WATCHDOG AML_WATCH_DOG_START();//enable watch dog #endif }
void relocate_init(unsigned __TEXT_BASE,unsigned __TEXT_SIZE) { unsigned por_cfg=romboot_info->por_cfg; unsigned boot_id=romboot_info->boot_id; unsigned size; int i; unsigned * mem; int rc=0; size=__TEXT_SIZE; // if(rc) // rc=fw_init_extl(por_cfg);//INTL device BOOT FAIL // if(rc==0) // rc=fw_load_extl(por_cfg,__TEXT_BASE,size); // asm volatile("wfi"); if(boot_id>1) boot_id=0; if(boot_id==0) { rc=fw_load_intl(por_cfg,__TEXT_BASE,size); if(!rc) return ; rc=fw_init_extl(por_cfg);//INTL device BOOT FAIL } if(rc==0) { rc=fw_load_extl(por_cfg,__TEXT_BASE,size); } #if CONFIG_ENABLE_SPL_DEBUG_ROM while(rc||serial_tstc()) { serial_put_dword(rc); debug_rom(__FILE__,__LINE__); #else while(rc) { #endif if(rc) rc=fw_init_extl(por_cfg);//INTL device BOOT FAIL if(rc==0) rc=fw_load_extl(por_cfg,__TEXT_BASE,size); } #if 0 //comment out by Elvis Yu for(i=0;i<sizeof(__load_table)/sizeof(__load_table[0]);i++) { if(__load_table[i].size==0) continue; memcpy(__load_table[i].dest,__load_table[i].src+__TEXT_BASE,__load_table[i].size); } // __asm__ __volatile__("wfi"); #endif return ; }
unsigned main(unsigned __TEXT_BASE,unsigned __TEXT_SIZE) { //Adjust 1us timer base timer_init(); serial_init(UART_CONTROL_SET(CONFIG_BAUDRATE,CONFIG_CRYSTAL_MHZ*1000000)); serial_put_dword(get_utimer(0)); AML_WATCH_DOG_DISABLE();//disable Watchdog debug_rom(__FILE__,__LINE__); return 0; }
STATIC_PREFIX void clk_msr(int argc, char * argv[]) { unsigned id; serial_puts(argv[1]); serial_puts("(Mhz)="); get_dword(argv[1],&id); serial_put_dword(clk_util_clk_msr(id)); }
void lowlevel_init(void* cur,void * target) { #if 0 if(cur != target) //r0!=r1 { //running from spi // take me as a spi rom boot mode romboot_info->por_cfg = POR_INTL_SPI | (READ_CBUS_REG(ASSIST_POR_CONFIG)&(~POR_INTL_CFG_MASK)); romboot_info->boot_id = 0;//boot from spi /// Release pull up registers . } #endif power_hold(); backlight_off(); //changed by Elvis, add uart rx pull up //pull up LINUX_RX(B15--->GPIOE_19) reg (7422y v1.pdf) //GPIOE_19(M1-Apps v25- 2010-07-19-BGA372_297-6.xls serach B15) WRITE_CBUS_REG( PAD_PULL_UP_REG3, READ_CBUS_REG(PAD_PULL_UP_REG3) & ~(1<<2) ); // Meson-pull-up-down_table.xlsx ( GPIOE_19 is PAD_PULL_UP_REG3---0x203e 2bits) //Adjust 1us timer base WRITE_CBUS_REG_BITS(PREG_CTLREG0_ADDR,CONFIG_CRYSTAL_MHZ,4,5); /* Select TimerE 1 us base */ clrsetbits_le32(P_ISA_TIMER_MUX,0x7<<8,0x1<<8); memory_pll_init(0,NULL); serial_puts("\nFirmware start at: "); serial_put_dword(get_timer(0)); #if CONFIG_ENABLE_SPL_DEBUG_ROM __udelay(100000);//wait for a uart input if(serial_tstc()) { debug_rom(__FILE__,__LINE__); } #else __udelay(1000);//delay 1 ms , wait pll ready #endif // writel((0<<22)|1000000,P_WATCHDOG_TC);//enable Watchdog unsigned por_cfg; #if CONFIG_ENABLE_SPL_DEBUG_ROM if(ddr_init_test()) debug_rom(__FILE__,__LINE__); #else do{ }while(ddr_init_test()); #endif serial_puts("\nFirmware started, now starting u-boot..."); }
STATIC_PREFIX short check_sum(unsigned * addr,unsigned short check_sum,unsigned size) { serial_put_dword(addr[15]); if(addr[15]!=CONFIG_AML_UBOOT_MAGIC) return -1; #if 0 int i; unsigned short * p=(unsigned short *)addr; for(i=0;i<size>>1;i++) check_sum^=p[i]; #endif return 0; }
static void display_error(unsigned por_cfg,char * hint) { serial_puts(hint); if(por_cfg) { serial_puts("fail"); serial_put_dword(por_cfg); }else{ serial_puts("pass"); } serial_puts("\n"); }
void relocate_init(unsigned __TEXT_BASE,unsigned __TEXT_SIZE) { unsigned por_cfg=romboot_info->por_cfg; unsigned boot_id=romboot_info->boot_id; unsigned size; int i; unsigned * mem; int rc=0; size=__TEXT_SIZE; if(boot_id>1) boot_id=0; if(boot_id==0) { rc=fw_load_intl(por_cfg,__TEXT_BASE,size); if(!rc) return ; rc=fw_init_extl(por_cfg);//INTL device BOOT FAIL } if(rc==0) { rc=fw_load_extl(por_cfg,__TEXT_BASE,size); } #if CONFIG_ENABLE_SPL_DEBUG_ROM while(rc||serial_tstc()) { unsigned char c; if(serial_tstc()&&serial_getc()!='e') break; serial_put_dword(rc); debug_rom(__FILE__,__LINE__); #else while(rc) { #endif if(rc) rc=fw_init_extl(por_cfg);//INTL device BOOT FAIL if(rc==0) rc=fw_load_extl(por_cfg,__TEXT_BASE,size); } load_ext(por_cfg,boot_id,__TEXT_BASE); // __asm__ __volatile__("wfi"); return ; }
STATIC_PREFIX void start_arc(int argc,char * argv[] ) { unsigned addr; spi_init(); get_dword(argv[1],&addr); /** copy ARM code*/ memcpy((void*)0x49008000,(const void*)0x49000000,16*1024); writel((0x49008000>>14)&0xf,0xc810001c); /** copy ARC code*/ memcpy((void*)0x49008000,(const void*)addr,16*1024); writel(0x1<<4,0xc8100020); writel(0x7fffffff,P_AO_RTI_STATUS_REG0); serial_puts("start up ARC\n"); // writel(0x51001,0xc8100030); writel(1,P_AO_RTI_STATUS_REG1); writel(0x1,0xc1109964); writel(0x0,0xc1109964); unsigned a,b; unsigned timer_base; a=b=0x7fffffff; serial_puts("ARM is Live\n"); timer_base=get_timer(0); do{ a=readl(P_AO_RTI_STATUS_REG0); if((a&0x80000000)|| ((a==b)&&(get_timer(timer_base)<10000000))) { continue; } timer_base=get_timer(0); b=a; serial_puts("ARM is Live: "); serial_put_dword(a); switch(a&0xffff) { case 0: serial_puts("ARM Exit Sleep Mode\n"); break; } }while(a); }
STATIC_PREFIX void pll_clk_list(void) { unsigned long clk_freq; unsigned char clk_list[]={3,10,11}; char *clk_list_name[]={"arm","ddr","other"}; unsigned long i; for(i=0;i<3;i++) { clk_freq = clk_util_clk_msr(clk_list[i] // unsigned long clk_mux, // Measure A9 clock ); // unsigned long uS_gate_time ) // 50us gate time serial_puts(clk_list_name[i]); serial_puts("_clk="); serial_put_dword(clk_freq); serial_puts("\n"); } }
STATIC_PREFIX void load_ext(unsigned por_cfg,unsigned bootid,unsigned target) { int i; unsigned temp_addr; #if CONFIG_UCL temp_addr=target-0x800000; #else temp_addr=target; #endif if(bootid==0&&(POR_GET_1ST_CFG(por_cfg)==POR_1ST_SPI||POR_GET_1ST_CFG(por_cfg)==POR_1ST_SPI_RESERVED)) { // spi boot temp_addr=(unsigned)(NOR_START_ADDR+READ_SIZE); } for(i=0;i<sizeof(__load_table)/sizeof(__load_table[0]);i++) { if(__load_table[i].size==0) continue; #if CONFIG_UCL #ifndef CONFIG_IMPROVE_UCL_DEC unsigned len; int rc; if( __load_table[i].size&(~0x3fffff)) { rc=uclDecompress((char*)(__load_table[i].dest),&len,(char*)(temp_addr+__load_table[i].src)); if(rc) { serial_put_dword(i); serial_puts("decompress Fail\n"); } }else #endif #endif memcpy((void*)(__load_table[i].dest),(const void*)(__load_table[i].src+temp_addr),__load_table[i].size&0x3fffff); } }
STATIC_PREFIX void debug_rom(char * file, int line) { #ifdef AML_DEBUGROM nf_erase(); #endif //int c; serial_puts("Enter Debugrom mode at "); serial_puts(file); serial_putc(':'); serial_put_dword(line); #if (defined AML_DEBUGROM)||(CONFIG_ENABLE_SPL_MORE_CMD) char * cmd=debugrom_startup(); while(cmd&&*cmd) { run_cmd(cmd); cmd=debugrom_startup(); } #endif while(run_cmd(get_cmd())) { ; } }
STATIC_PREFIX datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes) { unsigned long offset; unsigned long nWords = nBytes / sizeof(datum); datum pattern; datum antipattern; serial_puts("Total Size");serial_put_dword(nBytes); /* * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { baseAddress[offset] = pattern; #ifdef AML_DEBUG_ROM if(((offset+1)&0x3ffff)==0) { serial_putc('\r');serial_put_hex((offset+1)<<2,32); writel(0,P_WATCHDOG_RESET); } #endif } serial_puts(" Stage 1 finish\n"); // serial_putc('\n'); /* * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { if (baseAddress[offset] != pattern) { return ((datum *) &baseAddress[offset]); } antipattern = ~pattern; baseAddress[offset] = antipattern; #ifdef AML_DEBUG_ROM if(((offset+1)&0x3ffff)==0) { writel(0,P_WATCHDOG_RESET); serial_putc('\r');serial_put_hex((offset+1)<<2,32); } #endif } serial_puts(" Stage 2 finish\n"); /* * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) { antipattern = ~pattern; if (baseAddress[offset] != antipattern) { return ((datum *) &baseAddress[offset]); } #ifdef AML_DEBUG_ROM if(((offset+1)&0x3ffff)==0) { writel(0,P_WATCHDOG_RESET); serial_putc('\r');serial_put_hex((offset+1)<<2,32); } #endif } #undef AML_DEBUG_ROM serial_puts(" Stage 3 finish\n"); return (NULL); } /* memTestDevice() */
SPL_STATIC_FUNC void pll_init(struct pll_clk_settings * plls) { //Enable PLLs pins //*P_AM_ANALOG_TOP_REG1 |= 0x1; // Enable DDR_PLL enable pin //#define AM_ANALOG_TOP_REG1 0x206F -> 0xC11081BC Wr(AM_ANALOG_TOP_REG1, Rd(AM_ANALOG_TOP_REG1)|1); //*P_HHI_MPLL_CNTL5 |= 0x1; // Enable Both MPLL and SYS_PLL enable pin //move to following SYS PLL init Wr(HHI_MPLL_CNTL, 0x4000067d ); //switch a9 clock to oscillator in the first. This is sync mux. #if 0 Wr( HHI_A9_CLK_CNTL, 0); #else Wr( HHI_A9_CLK_CNTL, Rd(HHI_A9_CLK_CNTL) & (~(1<<7))); __udelay(10); Wr( HHI_A9_CLK_CNTL, 0); __udelay(10); Wr(HHI_MPEG_CLK_CNTL, Rd(HHI_MPEG_CLK_CNTL) & (~(1<<8)) ); #endif serial_init(52|UART_CNTL_MASK_TX_EN|UART_CNTL_MASK_RX_EN); //clk81 switch to 24M, init serial to print info __udelay(100); do{ //BANDGAP reset for SYS_PLL,AUD_PLL,MPLL lock fail //Note: once SYS PLL is up, there is no need to // use AM_ANALOG_TOP_REG1 for AUD, MPLL // lock fail Wr_reg_bits(HHI_MPLL_CNTL5,0,0,1); __udelay(10); Wr_reg_bits(HHI_MPLL_CNTL5,1,0,1); __udelay(1000); //1ms for bandgap bootup M6TV_PLL_RESET(HHI_SYS_PLL_CNTL); Wr(HHI_SYS_PLL_CNTL2,M6TV_SYS_PLL_CNTL_2); Wr(HHI_SYS_PLL_CNTL3,M6TV_SYS_PLL_CNTL_3); Wr(HHI_SYS_PLL_CNTL4,M6TV_SYS_PLL_CNTL_4); Wr(HHI_SYS_PLL_CNTL, plls->sys_pll_cntl); //M6TV_PLL_WAIT_FOR_LOCK(HHI_SYS_PLL_CNTL); __udelay(500); //wait 100us for PLL lock #ifdef CONFIG_ENABLE_WATCHDOG pll_times++; if(pll_times > 1){ serial_puts("\npll_times1:"); serial_put_dword(pll_times); if(pll_times>PLL_TIMES){ serial_puts(__FILE__); serial_puts(__FUNCTION__); serial_put_dword(__LINE__); AML_WATCH_DOG_START(); } } #endif }while((Rd(HHI_SYS_PLL_CNTL)&0x80000000)==0); //A9 clock setting Wr(HHI_A9_CLK_CNTL,(plls->sys_clk_cntl & (~(1<<7)))); __udelay(1); //enable A9 clock Wr(HHI_A9_CLK_CNTL,(plls->sys_clk_cntl | (1<<7))); /* //AUDIO PLL M6TV_PLL_RESET(HHI_AUDCLK_PLL_CNTL); Wr(HHI_AUDCLK_PLL_CNTL2, M6TV_AUD_PLL_CNTL_2 ); Wr(HHI_AUDCLK_PLL_CNTL3, M6TV_AUD_PLL_CNTL_3 ); Wr(HHI_AUDCLK_PLL_CNTL4, M6TV_AUD_PLL_CNTL_4 ); Wr(HHI_AUDCLK_PLL_CNTL5, M6TV_AUD_PLL_CNTL_5 ); Wr(HHI_AUDCLK_PLL_CNTL6, M6TV_AUD_PLL_CNTL_6 ); Wr(HHI_AUDCLK_PLL_CNTL, 0x20242 ); M6TV_PLL_WAIT_FOR_LOCK(HHI_AUDCLK_PLL_CNTL); */ //FIXED PLL/Multi-phase PLL, fixed to 2GHz M6TV_PLL_RESET(HHI_MPLL_CNTL); Wr(HHI_MPLL_CNTL2, M6TV_MPLL_CNTL_2 ); Wr(HHI_MPLL_CNTL3, M6TV_MPLL_CNTL_3 ); Wr(HHI_MPLL_CNTL4, M6TV_MPLL_CNTL_4 ); Wr(HHI_MPLL_CNTL5, M6TV_MPLL_CNTL_5 ); Wr(HHI_MPLL_CNTL6, M6TV_MPLL_CNTL_6 ); Wr(HHI_MPLL_CNTL7, M6TV_MPLL_CNTL_7 ); Wr(HHI_MPLL_CNTL8, M6TV_MPLL_CNTL_8 ); Wr(HHI_MPLL_CNTL9, M6TV_MPLL_CNTL_9 ); Wr(HHI_MPLL_CNTL10,M6TV_MPLL_CNTL_10); Wr(HHI_MPLL_CNTL, 0x4000067d ); M6TV_PLL_WAIT_FOR_LOCK(HHI_MPLL_CNTL); //clk81=fclk_div5 /2=400/2=200M Wr(HHI_MPEG_CLK_CNTL, plls->mpeg_clk_cntl ); serial_init(plls->uart); //clk81 switch to MPLL, init serial to print info #ifdef CONFIG_ENABLE_WATCHDOG pll_times=0; #endif Wr_reg_bits(AM_ANALOG_TOP_REG1,0,0,1); __udelay(10); Wr_reg_bits(AM_ANALOG_TOP_REG1,1,0,1); __udelay(1000); //1ms for bandgap bootup //asm volatile ("wfi"); //VID PLL do{ //BANDGAP reset for VID_PLL,DDR_PLL lock fail //Note: once VID PLL is up, there is no need to // use AM_ANALOG_TOP_REG1 for DDR PLL // lock fail Wr_reg_bits(AM_ANALOG_TOP_REG1,0,0,1); __udelay(10); Wr_reg_bits(AM_ANALOG_TOP_REG1,1,0,1); __udelay(1000); //1ms for bandgap bootup M6TV_PLL_RESET(HHI_VID_PLL_CNTL); //Wr(HHI_VID_PLL_CNTL, 0x600b0442 ); //change VID PLL from 1.584GHz to 1.512GHz Wr(HHI_VID_PLL_CNTL, 0x600b043f );//change VID PLL from 1.584GHz to 1.512GHz Wr(HHI_VID_PLL_CNTL2, M6TV_VID_PLL_CNTL_2 ); Wr(HHI_VID_PLL_CNTL3, M6TV_VID_PLL_CNTL_3 ); Wr(HHI_VID_PLL_CNTL4, M6TV_VID_PLL_CNTL_4 ); //Wr(HHI_VID_PLL_CNTL, 0x400b0442 ); //change VID PLL from 1.584GHz to 1.512GHz Wr(HHI_VID_PLL_CNTL, 0x400b043f ); //change VID PLL from 1.584GHz to 1.512GHz //M6TV_PLL_WAIT_FOR_LOCK(HHI_VID_PLL_CNTL); __udelay(500); //wait 100us for PLL lock #ifdef CONFIG_ENABLE_WATCHDOG pll_times++; if(pll_times > 1){ serial_puts("\npll_times2:"); serial_put_dword(pll_times); if(pll_times>PLL_TIMES){ serial_puts(__FILE__); serial_puts(__FUNCTION__); serial_put_dword(__LINE__); AML_WATCH_DOG_START(); } } #endif }while((Rd(HHI_VID_PLL_CNTL)&0x80000000)==0); __udelay(100); }