mt7620的u-boot 代码

/*
 * (C) Copyright 2003
 * Wolfgang Denk, DENX Software Engineering, [email protected].
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */


#include <common.h>
#include <command.h>
#include <malloc.h>
#include <devices.h>
#include <version.h>
#include <net.h>
#include <environment.h>
#include <asm/mipsregs.h>
#include <rt_mmap.h>
#include <spi_api.h>
#include <nand_api.h>


DECLARE_GLOBAL_DATA_PTR;
#undef DEBUG


#define SDRAM_CFG1_REG RALINK_SYSCTL_BASE + 0x0304


int modifies= 0;


#ifdef DEBUG
   #define DATE      "05/25/2006"
   #define VERSION   "v0.00e04"
#endif
#if ( ((CFG_ENV_ADDR+CFG_ENV_SIZE) < CFG_MONITOR_BASE) || \
      (CFG_ENV_ADDR >= (CFG_MONITOR_BASE + CFG_MONITOR_LEN)) ) || \
    defined(CFG_ENV_IS_IN_NVRAM)
#define TOTAL_MALLOC_LEN(CFG_MALLOC_LEN + CFG_ENV_SIZE)
#else
#define TOTAL_MALLOC_LENCFG_MALLOC_LEN
#endif
#define ARGV_LEN  128


#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
static int watchdog_reset();
#endif


extern int timer_init(void);


extern void  rt2880_eth_halt(struct eth_device* dev);


extern void setup_internal_gsw(void); 
extern void setup_external_gsw(void); 
//extern void pci_init(void);


extern int incaip_set_cpuclk(void);
extern int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern int do_tftpb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern int flash_sect_protect (int p, ulong addr_first, ulong addr_last);
int flash_sect_erase (ulong addr_first, ulong addr_last);
int get_addr_boundary (ulong *addr);
extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
extern void input_value(u8 *str);
#if defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \
    defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD)
extern void rt_gsw_init(void);
#elif defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) 
extern void rt6855A_gsw_init(void);
#elif defined (RT3883_ASIC_BOARD) && defined (MAC_TO_MT7530_MODE)
extern void rt3883_gsw_init(void);
#else
extern void rt305x_esw_init(void);
#endif
extern void LANWANPartition(void);


extern struct eth_device* rt2880_pdev;


extern ulong uboot_end_data;
extern ulong uboot_end;


#ifdef RALINK_USB
extern int usb_stor_curr_dev;
#endif


ulong monitor_flash_len;


const char version_string[] =
U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";


extern ulong load_addr; /* Default Load Address */




unsigned long mips_cpu_feq;
unsigned long mips_bus_feq;




/*
 * Begin and End of memory area for malloc(), and current "brk"
 */
static ulong mem_malloc_start;
static ulong mem_malloc_end;
static ulong mem_malloc_brk;


static char  file_name_space[ARGV_LEN];


#define read_32bit_cp0_register_with_select1(source)            \
({ int __res;                                                   \
        __asm__ __volatile__(                                   \
        ".set\tpush\n\t"                                        \
        ".set\treorder\n\t"                                     \
        "mfc0\t%0,"STR(source)",1\n\t"                          \
        ".set\tpop"                                             \
        : "=r" (__res));                                        \
        __res;})




static void Init_System_Mode(void)
{
u32 reg;
#ifdef ASIC_BOARD
u8 clk_sel;
#endif
#if defined(RT5350_ASIC_BOARD)
u8 clk_sel2;
#endif


reg = RALINK_REG(RT2880_SYSCFG_REG);

/* 
* CPU_CLK_SEL (bit 21:20)
*/
#ifdef RT2880_FPGA_BOARD
mips_cpu_feq = 25 * 1000 *1000;
mips_bus_feq = mips_cpu_feq/2;
#elif defined (RT2883_FPGA_BOARD) || defined (RT3052_FPGA_BOARD) || defined (RT3352_FPGA_BOARD) || defined (RT5350_FPGA_BOARD)
mips_cpu_feq = 40 * 1000 *1000;
mips_bus_feq = mips_cpu_feq/3;
#elif defined (RT6855A_FPGA_BOARD)
mips_cpu_feq = 50 * 1000 *1000;
mips_bus_feq = mips_cpu_feq/2;
#elif defined (RT3883_FPGA_BOARD)
mips_cpu_feq = 40 * 1000 *1000;
mips_bus_feq = mips_cpu_feq;
#elif defined (RT6855_FPGA_BOARD) || defined (MT7620_FPGA_BOARD) || defined (MT7628_FPGA_BOARD)
mips_cpu_feq = 50 * 1000 *1000;
mips_bus_feq = mips_cpu_feq/4;
#elif defined (MT7621_FPGA_BOARD)
mips_cpu_feq = 50 * 1000 *1000;
mips_bus_feq = mips_cpu_feq/4;
#elif defined (RT2883_ASIC_BOARD) 
clk_sel = (reg>>20) & 0x03;
switch(clk_sel) {
case 0:
mips_cpu_feq = (380*1000*1000);
break;
case 1:
mips_cpu_feq = (400*1000*1000);
break;
case 2:
mips_cpu_feq = (420*1000*1000);
break;
case 3:
mips_cpu_feq = (430*1000*1000);
break;
}
mips_bus_feq = mips_cpu_feq/2;
#elif defined(RT3052_ASIC_BOARD)
#if defined(RT3350_ASIC_BOARD) 
//MA10 is floating
mips_cpu_feq = (320*1000*1000);
#else
        clk_sel = (reg>>18) & 0x01;
        switch(clk_sel) {
                case 0:
                        mips_cpu_feq = (320*1000*1000);
                        break;
                case 1:
                        mips_cpu_feq = (384*1000*1000);
                        break;
        }
#endif
        mips_bus_feq = mips_cpu_feq / 3;
#elif defined(RT3352_ASIC_BOARD)
clk_sel = (reg>>8) & 0x01;
switch(clk_sel) {
case 0:
mips_cpu_feq = (384*1000*1000);
break;
case 1:
mips_cpu_feq = (400*1000*1000);
break;
}
mips_bus_feq = (133*1000*1000);
#elif defined(RT5350_ASIC_BOARD)
clk_sel2 = (reg>>10) & 0x01;
clk_sel = ((reg>>8) & 0x01) + (clk_sel2 * 2);
switch(clk_sel) {
case 0:
mips_cpu_feq = (360*1000*1000);
mips_bus_feq = (120*1000*1000);
break;
case 1:
//reserved
break;
case 2:
mips_cpu_feq = (320*1000*1000);
mips_bus_feq = (80*1000*1000);
break;
case 3:
mips_cpu_feq = (300*1000*1000);
mips_bus_feq = (100*1000*1000);
break;
}
#elif defined(RT6855_ASIC_BOARD)
mips_cpu_feq = (400*1000*1000);
mips_bus_feq = (133*1000*1000);
#elif defined (RT6855A_ASIC_BOARD)
/* FPGA is 25/32Mhz
* ASIC RT6856/RT63368: DDR(0): 233.33, DDR(1): 175, SDR: 140
*      RT6855/RT6855A: DDR(0): 166.67, DDR(1): 125, SDR: 140 */
reg = RALINK_REG(RT2880_SYSCFG_REG);
if ((reg & (1 << 25)) == 0) { /* SDR */
if ((reg & (1 << 9)) != 0)
mips_cpu_feq = (560*1000*1000);
else {
if ((reg & (1 << 26)) != 0)
mips_cpu_feq = (560*1000*1000);
else
mips_cpu_feq = (420*1000*1000);
} 
mips_bus_feq = (140*1000*1000);
} else { /* DDR */
if ((reg & (1 << 9)) != 0) {
mips_cpu_feq = (700*1000*1000);
if ((reg & (1 << 26)) != 0)
mips_bus_feq = (175*1000*1000);
else
mips_bus_feq = 233333333;
} else {
mips_cpu_feq = (500*1000*1000);
if ((reg & (1 << 26)) != 0)
mips_bus_feq = (125*1000*1000);
else
mips_bus_feq = 166666667;
}
}
#elif defined(MT7620_ASIC_BOARD)
reg = RALINK_REG(RALINK_CPLLCFG1_REG);
if( reg & ((0x1UL) << 24) ){
mips_cpu_feq = (480*1000*1000);/* from BBP PLL */
}else{
reg = RALINK_REG(RALINK_CPLLCFG0_REG);
if(!(reg & CPLL_SW_CONFIG)){
mips_cpu_feq = (600*1000*1000); /* from CPU PLL */
}else{
/* read CPLL_CFG0 to determine real CPU clock */
int mult_ratio = (reg & CPLL_MULT_RATIO) >> CPLL_MULT_RATIO_SHIFT;
int div_ratio = (reg & CPLL_DIV_RATIO) >> CPLL_DIV_RATIO_SHIFT;
mult_ratio += 24;       /* begin from 24 */
if(div_ratio == 0)      /* define from datasheet */
div_ratio = 2;
else if(div_ratio == 1)
div_ratio = 3;
else if(div_ratio == 2)
div_ratio = 4;
else if(div_ratio == 3)
div_ratio = 8;
mips_cpu_feq = ((BASE_CLOCK * mult_ratio ) / div_ratio) * 1000 * 1000;
}
}
reg = (RALINK_REG(RT2880_SYSCFG_REG)) >> 4 & 0x3;
if(reg == 0x0){/* SDR (MT7620 E1) */
mips_bus_feq = mips_cpu_feq/4;
}else if(reg == 0x1 || reg == 0x2 ){/* DDR1 & DDR2 */
mips_bus_feq = mips_cpu_feq/3;
}else{ /* SDR (MT7620 E2) */
mips_bus_feq = mips_cpu_feq/5;
}
#elif defined (MT7628_ASIC_BOARD)
reg = RALINK_REG(RALINK_CLKCFG0_REG);
if (reg & (0x1<<1)) {
mips_cpu_feq = (480*1000*1000)/CPU_FRAC_DIV;
}else if (reg & 0x1) {
mips_cpu_feq = ((RALINK_REG(RALINK_SYSCTL_BASE+0x10)>>6)&0x1) ? (40*1000*1000)/CPU_FRAC_DIV \
  : (25*1000*1000)/CPU_FRAC_DIV;
}else {
mips_cpu_feq = (575*1000*1000)/CPU_FRAC_DIV;
}
mips_bus_feq = mips_cpu_feq/3;
#elif defined(MT7621_ASIC_BOARD)
reg = RALINK_REG(RALINK_SYSCTL_BASE + 0x2C);
if( reg & ((0x1UL) << 30)) {
reg = RALINK_REG(RALINK_MEMCTRL_BASE + 0x648);
mips_cpu_feq = (((reg >> 4) & 0x7F) + 1) * 1000 * 1000;
reg = RALINK_REG(RALINK_SYSCTL_BASE + 0x10);
reg = (reg >> 6) & 0x7;
if(reg >= 6) { //25Mhz Xtal
mips_cpu_feq = mips_cpu_feq * 25;
} else if (reg >=3) { //40Mhz Xtal
mips_cpu_feq = mips_cpu_feq * 20;
} else { //20Mhz Xtal
/* TODO */
}
}else {
reg = RALINK_REG(RALINK_SYSCTL_BASE + 0x44);
mips_cpu_feq = (500 * (reg & 0x1F) / ((reg >> 8) & 0x1F)) * 1000 * 1000;
}
mips_bus_feq = mips_cpu_feq/4;
#elif defined (RT3883_ASIC_BOARD) 
clk_sel = (reg>>8) & 0x03;
switch(clk_sel) {
case 0:
mips_cpu_feq = (250*1000*1000);
break;
case 1:
mips_cpu_feq = (384*1000*1000);
break;
case 2:
mips_cpu_feq = (480*1000*1000);
break;
case 3:
mips_cpu_feq = (500*1000*1000);
break;
}
#if defined (CFG_ENV_IS_IN_SPI)
if ((reg>>17) & 0x1) { //DDR2
switch(clk_sel) {
case 0:
mips_bus_feq = (125*1000*1000);
break;
case 1:
mips_bus_feq = (128*1000*1000);
break;
case 2:
mips_bus_feq = (160*1000*1000);
break;
case 3:
mips_bus_feq = (166*1000*1000);
break;
}
}
else {
switch(clk_sel) {
case 0:
mips_bus_feq = (83*1000*1000);
break;
case 1:
mips_bus_feq = (96*1000*1000);
break;
case 2:
mips_bus_feq = (120*1000*1000);
break;
case 3:
mips_bus_feq = (125*1000*1000);
break;
}
}
#elif defined ON_BOARD_SDR
switch(clk_sel) {
case 0:
mips_bus_feq = (83*1000*1000);
break;
case 1:
mips_bus_feq = (96*1000*1000);
break;
case 2:
mips_bus_feq = (120*1000*1000);
break;
case 3:
mips_bus_feq = (125*1000*1000);
break;
}
#elif defined ON_BOARD_DDR2
switch(clk_sel) {
case 0:
mips_bus_feq = (125*1000*1000);
break;
case 1:
mips_bus_feq = (128*1000*1000);
break;
case 2:
mips_bus_feq = (160*1000*1000);
break;
case 3:
mips_bus_feq = (166*1000*1000);
break;
}
#else
#error undef SDR or DDR
#endif
#else /* RT2880 ASIC version */
clk_sel = (reg>>20) & 0x03;
switch(clk_sel) {
#ifdef RT2880_MP
case 0:
mips_cpu_feq = (250*1000*1000);
break;
case 1:
mips_cpu_feq = (266*1000*1000);
break;
case 2:
mips_cpu_feq = (280*1000*1000);
break;
case 3:
mips_cpu_feq = (300*1000*1000);
break;
#else
case 0:
mips_cpu_feq = (233*1000*1000);
break;
case 1:
mips_cpu_feq = (250*1000*1000);
break;
case 2:
mips_cpu_feq = (266*1000*1000);
break;
case 3:
mips_cpu_feq = (280*1000*1000);
break;

#endif
}
mips_bus_feq = mips_cpu_feq/2;
#endif


    //RALINK_REG(RT2880_SYSCFG_REG) = reg;


/* in general, the spec define 8192 refresh cycles/64ms
* 64ms/8192 = 7.8us
* 7.8us * 106.7Mhz(SDRAM clock) = 832
* the value of refresh cycle shall smaller than 832. 
* so we config it at 0x300 (suggested by ASIC)
*/
#if defined(ON_BOARD_SDR) && defined(ON_BOARD_256M_DRAM_COMPONENT) && (!defined(MT7620_ASIC_BOARD))
{
u32 tREF;
tREF = RALINK_REG(SDRAM_CFG1_REG);
tREF &= 0xffff0000;
#if defined(ASIC_BOARD)
tREF |= 0x00000300;
#elif defined(FPGA_BOARD) 
tREF |= 0x000004B;
#else
#error "not exist"
#endif
RALINK_REG(SDRAM_CFG1_REG) = tREF;
}
#endif


}




/*
 * The Malloc area is immediately below the monitor copy in DRAM
 */
static void mem_malloc_init (void)
{


ulong dest_addr = CFG_MONITOR_BASE + gd->reloc_off;


mem_malloc_end = dest_addr;
mem_malloc_start = dest_addr - TOTAL_MALLOC_LEN;
mem_malloc_brk = mem_malloc_start;


memset ((void *) mem_malloc_start,
0,
mem_malloc_end - mem_malloc_start);
}


void *sbrk (ptrdiff_t increment)
{
ulong old = mem_malloc_brk;
ulong new = old + increment;


if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
return (NULL);
}
mem_malloc_brk = new;
return ((void *) old);
}


static int init_func_ram (void)
{


#ifdef CONFIG_BOARD_TYPES
int board_type = gd->board_type;
#else
int board_type = 0;/* use dummy arg */
#endif
puts ("DRAM:  ");


/*init dram config*/
#ifdef RALINK_DDR_OPTIMIZATION
#ifdef ON_BOARD_DDR2
/*optimize ddr parameter*/
{ 
u32 tDDR;
tDDR = RALINK_REG(DDR_CFG0_REG);


        tDDR &= 0xf0780000; 
tDDR |=  RAS_VALUE << RAS_OFFSET;
tDDR |=  TRFC_VALUE << TRFC_OFFSET;
tDDR |=  TRFI_VALUE << TRFI_OFFSET;
RALINK_REG(DDR_CFG0_REG) = tDDR;
}
#endif
#endif




if ((gd->ram_size = initdram (board_type)) > 0) {
print_size (gd->ram_size, "\n");
return (0);  
}
puts ("*** failed ***\n");


return (1);
}


static int display_banner(void)
{
   
printf ("\n\n%s\n\n", version_string);
return (0);
}


/*
static void display_flash_config(ulong size)
{
puts ("Flash: ");
print_size (size, "\n");
}
*/


static int init_baudrate (void)
{
//uchar tmp[64]; /* long enough for environment variables */
//int i = getenv_r ("baudrate", tmp, sizeof (tmp));
//kaiker 
gd->baudrate = CONFIG_BAUDRATE;
/*
gd->baudrate = (i > 0)
? (int) simple_strtoul (tmp, NULL, 10)
: CONFIG_BAUDRATE;
*/
return (0);
}




/*
 * Breath some life into the board...
 *
 * The first part of initialization is running from Flash memory;
 * its main purpose is to initialize the RAM so that we
 * can relocate the monitor code to RAM.
 */


/*
 * All attempts to come up with a "common" initialization sequence
 * that works for all boards and architectures failed: some of the
 * requirements are just _too_ different. To get rid of the resulting
 * mess of board dependend #ifdef'ed code we now make the whole
 * initialization sequence configurable to the user.
 *
 * The requirements for any new initalization function is simple: it
 * receives a pointer to the "global data" structure as it's only
 * argument, and returns an integer return code, where 0 means
 * "continue" and != 0 means "fatal error, hang the system".
 */
#if 0
typedef int (init_fnc_t) (void);


init_fnc_t *init_sequence[] = {
timer_init,
env_init, /* initialize environment */
init_baudrate,/* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f,
display_banner,/* say that we are here */
checkboard,
init_func_ram,
NULL,
};
#endif


//  
void board_init_f(ulong bootflag)
{
gd_t gd_data, *id;
bd_t *bd;  
//init_fnc_t **init_fnc_ptr;
ulong addr, addr_sp, len = (ulong)&uboot_end - CFG_MONITOR_BASE;
ulong *s;
u32 value;
u32 fdiv = 0, step = 0, frac = 0, i;


#if defined RT6855_FPGA_BOARD || defined RT6855_ASIC_BOARD || \
    defined MT7620_FPGA_BOARD || defined MT7620_ASIC_BOARD
value = le32_to_cpu(*(volatile u_long *)(RALINK_SPI_BASE + 0x10));
value &= ~(0x7);
value |= 0x2;
*(volatile u_long *)(RALINK_SPI_BASE + 0x10) = cpu_to_le32(value);
#elif defined MT7621_FPGA_BOARD || defined MT7628_FPGA_BOARD
value = le32_to_cpu(*(volatile u_long *)(RALINK_SPI_BASE + 0x3c));
value &= ~(0xFFF);
*(volatile u_long *)(RALINK_SPI_BASE + 0x3c) = cpu_to_le32(value);
#elif defined MT7621_ASIC_BOARD
value = le32_to_cpu(*(volatile u_long *)(RALINK_SPI_BASE + 0x3c));
value &= ~(0xFFF);
value |= 5; //work-around 3-wire SPI issue (3 for RFB, 5 for EVB)
*(volatile u_long *)(RALINK_SPI_BASE + 0x3c) = cpu_to_le32(value);
#elif  defined MT7628_ASIC_BOARD
value = le32_to_cpu(*(volatile u_long *)(RALINK_SPI_BASE + 0x3c));
value &= ~(0xFFF);
value |= 8;
*(volatile u_long *)(RALINK_SPI_BASE + 0x3c) = cpu_to_le32(value);
#endif


#if defined(MT7620_FPGA_BOARD) || defined(MT7620_ASIC_BOARD)
/* Adjust CPU Freq from 60Mhz to 600Mhz(or CPLL freq stored from EE) */
value = RALINK_REG(RT2880_SYSCLKCFG_REG);
fdiv = ((value>>8)&0x1F);
step = (unsigned long)(value&0x1F);
while(step < fdiv) {
value = RALINK_REG(RT2880_SYSCLKCFG_REG);
step = (unsigned long)(value&0x1F) + 1;
v
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值