mirror of
https://gitlab.com/dm38/padavan-ng.git
synced 2024-02-13 08:34:03 +08:00
3762 lines
101 KiB
C
3762 lines
101 KiB
C
/*
|
|
* (C) Copyright 2003
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
*
|
|
* 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>
|
|
|
|
#include <gpio.h>
|
|
#include <cmd_tftpServer.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
#undef DEBUG
|
|
|
|
#define SDRAM_CFG1_REG RALINK_SYSCTL_BASE + 0x0304
|
|
|
|
int modifies= 0;
|
|
unsigned char BootType='3';
|
|
|
|
#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_LEN CFG_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 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 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;
|
|
|
|
#if defined (RALINK_USB ) || defined (MTK_USB)
|
|
#include <usb.h>
|
|
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 */
|
|
extern image_header_t header;
|
|
extern int verify_kernel_image(ulong, ulong *, ulong *, ulong *);
|
|
|
|
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;})
|
|
|
|
#if defined (CONFIG_DDR_CAL)
|
|
__attribute__((nomips16)) void dram_cali(void);
|
|
#endif
|
|
|
|
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)
|
|
clk_sel = (reg>>6) & 0x1; // XTAL 25/40
|
|
reg = RALINK_REG(RALINK_CLKCFG0_REG);
|
|
if (reg & (0x1<<1)) {
|
|
/* BBP PLL */
|
|
mips_cpu_feq = (480*1000*1000)/CPU_FRAC_DIV;
|
|
}else if (reg & 0x1) {
|
|
/* XTAL */
|
|
mips_cpu_feq = (clk_sel) ? (40*1000*1000)/CPU_FRAC_DIV : (25*1000*1000)/CPU_FRAC_DIV;
|
|
}else {
|
|
/* CPU PLL */
|
|
mips_cpu_feq = (clk_sel) ? (580*1000*1000)/CPU_FRAC_DIV : (575*1000*1000)/CPU_FRAC_DIV;
|
|
}
|
|
mips_bus_feq = mips_cpu_feq/3;
|
|
#elif defined(MT7621_ASIC_BOARD)
|
|
clk_sel = (reg>>5)&0x1; // OCP
|
|
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;
|
|
}
|
|
/* SYS_CLK always CPU/4 (not depend from OCP) */
|
|
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) {
|
|
ulong ram_size = gd->ram_size;
|
|
#if defined (ON_BOARD_4096M_DRAM_COMPONENT)
|
|
ram_size += 64*1024*1024;
|
|
#endif
|
|
print_size (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
|
|
|
|
//
|
|
__attribute__((nomips16)) 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;
|
|
void (*ptr)(void);
|
|
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;
|
|
value &= ~(0x1F);
|
|
value |= (step&0x1F);
|
|
RALINK_REG(RT2880_SYSCLKCFG_REG) = value;
|
|
udelay(10);
|
|
};
|
|
#elif defined(MT7628_ASIC_BOARD)
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = (unsigned long)((value>>8)&0x0F);
|
|
if ((CPU_FRAC_DIV < 1) || (CPU_FRAC_DIV > 10))
|
|
frac = (unsigned long)(value&0x0F);
|
|
else
|
|
frac = CPU_FRAC_DIV;
|
|
i = 0;
|
|
|
|
while(frac < fdiv) {
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = ((value>>8)&0x0F);
|
|
fdiv--;
|
|
value &= ~(0x0F<<8);
|
|
value |= (fdiv<<8);
|
|
RALINK_REG(RALINK_DYN_CFG0_REG) = value;
|
|
udelay(500);
|
|
i++;
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = ((value>>8)&0x0F);
|
|
//frac = (unsigned long)(value&0x0F);
|
|
}
|
|
#elif defined (MT7621_ASIC_BOARD)
|
|
#if (MT7621_CPU_FREQUENCY!=50)
|
|
value = RALINK_REG(RALINK_CUR_CLK_STS_REG);
|
|
fdiv = ((value>>8)&0x1F);
|
|
frac = (unsigned long)(value&0x1F);
|
|
|
|
i = 0;
|
|
|
|
while(frac < fdiv) {
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = ((value>>8)&0x0F);
|
|
fdiv--;
|
|
value &= ~(0x0F<<8);
|
|
value |= (fdiv<<8);
|
|
RALINK_REG(RALINK_DYN_CFG0_REG) = value;
|
|
udelay(500);
|
|
i++;
|
|
value = RALINK_REG(RALINK_CUR_CLK_STS_REG);
|
|
fdiv = ((value>>8)&0x1F);
|
|
frac = (unsigned long)(value&0x1F);
|
|
}
|
|
|
|
#endif
|
|
#if ((MT7621_CPU_FREQUENCY!=50) && (MT7621_CPU_FREQUENCY!=500))
|
|
//change CPLL from GPLL to MEMPLL
|
|
value = RALINK_REG(RALINK_CLKCFG0_REG);
|
|
value &= ~(0x3<<30);
|
|
value |= (0x1<<30);
|
|
RALINK_REG(RALINK_CLKCFG0_REG) = value;
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef CONFIG_PURPLE
|
|
void copy_code (ulong);
|
|
#endif
|
|
//*pio_mode = 0xFFFF;
|
|
|
|
/* Pointer is writable since we allocated a register for it.
|
|
*/
|
|
gd = &gd_data;
|
|
/* compiler optimization barrier needed for GCC >= 3.4 */
|
|
__asm__ __volatile__("": : :"memory");
|
|
|
|
|
|
memset ((void *)gd, 0, sizeof (gd_t));
|
|
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
watchdog_reset();
|
|
#endif
|
|
timer_init();
|
|
env_init(); /* initialize environment */
|
|
init_baudrate(); /* initialze baudrate settings */
|
|
serial_init(); /* serial communications setup */
|
|
console_init_f();
|
|
#if (TEXT_BASE == 0xBFC00000) || (TEXT_BASE == 0xBF000000) || (TEXT_BASE == 0xBC000000)
|
|
#if defined (CONFIG_DDR_CAL)
|
|
ptr = dram_cali;
|
|
ptr = (void*)((u32)ptr & ~(1<<29));
|
|
(*ptr)();
|
|
#endif
|
|
#endif
|
|
display_banner(); /* say that we are here */
|
|
checkboard();
|
|
|
|
init_func_ram();
|
|
|
|
gpio_init();
|
|
|
|
/* reset Frame Engine */
|
|
value = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0034));
|
|
#if defined (RT2880_FPGA_BOARD) || defined (RT2880_ASIC_BOARD)
|
|
value |= (1U << 18);
|
|
#elif defined (MT7620_FPGA_BOARD) || defined (MT7620_ASIC_BOARD)
|
|
/* reset PPE & FE */
|
|
value |= ((1U << 31)|(1U << 21));
|
|
#elif defined (MT7621_FPGA_BOARD) || defined (MT7621_ASIC_BOARD)
|
|
/* reset PPE & FE */
|
|
value |= ((1U << 31)|(1U << 6));
|
|
//value |= (1<<26 | 1<<25 | 1<<24); /* PCIE de-assert for E3 */
|
|
#elif defined (MT7628_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || \
|
|
defined (RT5350_FPGA_BOARD) || defined (RT5350_ASIC_BOARD)
|
|
/* reset ESW & FE */
|
|
value |= ((1U << 23)|(1U << 21));
|
|
#else
|
|
/* 3052/3352/3883 (FE only) */
|
|
value |= (1U << 21);
|
|
#endif
|
|
*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0034) = cpu_to_le32(value);
|
|
udelay(100);
|
|
#if defined (RT2880_FPGA_BOARD) || defined (RT2880_ASIC_BOARD)
|
|
value &= ~(1U << 18);
|
|
#elif defined (MT7620_FPGA_BOARD) || defined (MT7620_ASIC_BOARD)
|
|
value &= ~((1U << 31)|(1U << 21));
|
|
#elif defined (MT7621_FPGA_BOARD) || defined (MT7621_ASIC_BOARD)
|
|
value &= ~((1U << 31)|(1U << 6));
|
|
#elif defined (MT7628_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || \
|
|
defined (RT5350_FPGA_BOARD) || defined (RT5350_ASIC_BOARD)
|
|
value &= ~((1U << 23)|(1U << 21));
|
|
#else
|
|
value &= ~(1U << 21);
|
|
#endif
|
|
*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x0034) = cpu_to_le32(value);
|
|
udelay(300);
|
|
|
|
#if 0
|
|
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
|
|
|
|
if ((*init_fnc_ptr)() != 0) {
|
|
hang ();
|
|
}
|
|
}
|
|
#endif
|
|
#ifdef DEBUG
|
|
debug("rt2880 uboot %s %s\n", VERSION, DATE);
|
|
#endif
|
|
|
|
/*
|
|
* Now that we have DRAM mapped and working, we can
|
|
* relocate the code and continue running from DRAM.
|
|
*/
|
|
addr = CFG_SDRAM_BASE + gd->ram_size;
|
|
|
|
/* We can reserve some RAM "on top" here.
|
|
*/
|
|
#ifdef DEBUG
|
|
debug ("SERIAL_CLOCK_DIVISOR =%d \n", SERIAL_CLOCK_DIVISOR);
|
|
debug ("kaiker,,CONFIG_BAUDRATE =%d \n", CONFIG_BAUDRATE);
|
|
debug ("SDRAM SIZE:%08X\n",gd->ram_size);
|
|
#endif
|
|
|
|
/* round down to next 4 kB limit.
|
|
*/
|
|
addr &= ~(4096 - 1);
|
|
#ifdef DEBUG
|
|
debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
|
|
#endif
|
|
|
|
/* Reserve memory for U-Boot code, data & bss
|
|
* round down to next 16 kB limit
|
|
*/
|
|
addr -= len;
|
|
addr &= ~(16 * 1024 - 1);
|
|
#ifdef DEBUG
|
|
debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
|
|
#endif
|
|
/* Reserve memory for malloc() arena.
|
|
*/
|
|
addr_sp = addr - TOTAL_MALLOC_LEN;
|
|
#ifdef DEBUG
|
|
debug ("Reserving %dk for malloc() at: %08lx\n",
|
|
TOTAL_MALLOC_LEN >> 10, addr_sp);
|
|
#endif
|
|
/*
|
|
* (permanently) allocate a Board Info struct
|
|
* and a permanent copy of the "global" data
|
|
*/
|
|
addr_sp -= sizeof(bd_t);
|
|
bd = (bd_t *)addr_sp;
|
|
gd->bd = bd;
|
|
#ifdef DEBUG
|
|
debug ("Reserving %d Bytes for Board Info at: %08lx\n",
|
|
sizeof(bd_t), addr_sp);
|
|
#endif
|
|
addr_sp -= sizeof(gd_t);
|
|
id = (gd_t *)addr_sp;
|
|
#ifdef DEBUG
|
|
debug ("Reserving %d Bytes for Global Data at: %08lx\n",
|
|
sizeof (gd_t), addr_sp);
|
|
#endif
|
|
/* Reserve memory for boot params.
|
|
*/
|
|
addr_sp -= CFG_BOOTPARAMS_LEN;
|
|
bd->bi_boot_params = addr_sp;
|
|
#ifdef DEBUG
|
|
debug ("Reserving %dk for boot params() at: %08lx\n",
|
|
CFG_BOOTPARAMS_LEN >> 10, addr_sp);
|
|
#endif
|
|
/*
|
|
* Finally, we set up a new (bigger) stack.
|
|
*
|
|
* Leave some safety gap for SP, force alignment on 16 byte boundary
|
|
* Clear initial stack frame
|
|
*/
|
|
addr_sp -= 16;
|
|
addr_sp &= ~0xF;
|
|
s = (ulong *)addr_sp;
|
|
*s-- = 0;
|
|
*s-- = 0;
|
|
addr_sp = (ulong)s;
|
|
#ifdef DEBUG
|
|
debug ("Stack Pointer at: %08lx\n", addr_sp);
|
|
#endif
|
|
|
|
/*
|
|
* Save local variables to board info struct
|
|
*/
|
|
bd->bi_memstart = CFG_SDRAM_BASE; /* start of DRAM memory */
|
|
bd->bi_memsize = gd->ram_size; /* size of DRAM memory in bytes */
|
|
bd->bi_baudrate = gd->baudrate; /* Console Baudrate */
|
|
|
|
memcpy (id, (void *)gd, sizeof (gd_t));
|
|
|
|
/* On the purple board we copy the code in a special way
|
|
* in order to solve flash problems
|
|
*/
|
|
#ifdef CONFIG_PURPLE
|
|
copy_code(addr);
|
|
#endif
|
|
|
|
|
|
#if defined(CFG_RUN_CODE_IN_RAM)
|
|
/*
|
|
* tricky: relocate code to original TEXT_BASE
|
|
* for ICE souce level debuggind mode
|
|
*/
|
|
// debug ("relocate_code Pointer at: %08lx\n", addr);
|
|
relocate_code (addr_sp, id, /*TEXT_BASE*/ addr);
|
|
#else
|
|
// debug ("relocate_code Pointer at: %08lx\n", addr);
|
|
relocate_code (addr_sp, id, addr);
|
|
#endif
|
|
|
|
/* NOTREACHED - relocate_code() does not return */
|
|
}
|
|
|
|
#define SEL_LOAD_LINUX_WRITE_FLASH_BY_SERIAL 0
|
|
#define SEL_LOAD_LINUX_SDRAM 1
|
|
#define SEL_LOAD_LINUX_WRITE_FLASH 2
|
|
#define SEL_BOOT_FLASH 3
|
|
#define SEL_ENTER_CLI 4
|
|
#define SEL_LOAD_LINUX_WRITE_FLASH_BY_USB 5
|
|
#define SEL_LOAD_BOOT_WRITE_FLASH_BY_SERIAL 7
|
|
#define SEL_LOAD_BOOT_SDRAM 8
|
|
#define SEL_LOAD_BOOT_WRITE_FLASH 9
|
|
|
|
|
|
void OperationSelect(void)
|
|
{
|
|
printf("\nPlease choose the operation: \n");
|
|
#ifdef RALINK_UPGRADE_BY_SERIAL
|
|
printf(" %d: Load %s code then write to Flash via %s.\n", SEL_LOAD_LINUX_WRITE_FLASH_BY_SERIAL, "system", "Serial");
|
|
#endif
|
|
printf(" %d: Load system code to SDRAM via TFTP.\n", SEL_LOAD_LINUX_SDRAM);
|
|
printf(" %d: Load %s code then write to Flash via %s.\n", SEL_LOAD_LINUX_WRITE_FLASH, "system", "TFTP");
|
|
printf(" %d: Boot system code via Flash (default).\n", SEL_BOOT_FLASH);
|
|
#ifdef RALINK_CMDLINE
|
|
printf(" %d: Enter boot command line interface.\n", SEL_ENTER_CLI);
|
|
#endif
|
|
#if defined (RALINK_USB) || defined (MTK_USB)
|
|
printf(" %d: Load %s code then write to Flash via %s.\n", SEL_LOAD_LINUX_WRITE_FLASH_BY_USB, "system", "USB Storage");
|
|
#endif
|
|
#ifdef RALINK_UPGRADE_BY_SERIAL
|
|
printf(" %d: Load %s code then write to Flash via %s.\n", SEL_LOAD_BOOT_WRITE_FLASH_BY_SERIAL, "U-Boot", "Serial");
|
|
#endif
|
|
printf(" %d: Load %s code then write to Flash via %s.\n", SEL_LOAD_BOOT_WRITE_FLASH, "U-Boot", "TFTP");
|
|
}
|
|
|
|
int tftp_config(int type, char *argv[])
|
|
{
|
|
char *s;
|
|
char default_file[ARGV_LEN], file[ARGV_LEN], devip[ARGV_LEN], srvip[ARGV_LEN], default_ip[ARGV_LEN];
|
|
|
|
printf(" Please Input new ones /or Ctrl-C to discard\n");
|
|
|
|
memset(default_file, 0, ARGV_LEN);
|
|
memset(file, 0, ARGV_LEN);
|
|
memset(devip, 0, ARGV_LEN);
|
|
memset(srvip, 0, ARGV_LEN);
|
|
memset(default_ip, 0, ARGV_LEN);
|
|
|
|
printf("\tInput device IP ");
|
|
s = getenv("ipaddr");
|
|
memcpy(devip, s, strlen(s));
|
|
memcpy(default_ip, s, strlen(s));
|
|
|
|
printf("(%s) ", devip);
|
|
input_value(devip);
|
|
setenv("ipaddr", devip);
|
|
if (strcmp(default_ip, devip) != 0)
|
|
modifies++;
|
|
|
|
printf("\tInput server IP ");
|
|
s = getenv("serverip");
|
|
memcpy(srvip, s, strlen(s));
|
|
memset(default_ip, 0, ARGV_LEN);
|
|
memcpy(default_ip, s, strlen(s));
|
|
|
|
printf("(%s) ", srvip);
|
|
input_value(srvip);
|
|
setenv("serverip", srvip);
|
|
if (strcmp(default_ip, srvip) != 0)
|
|
modifies++;
|
|
|
|
if(type == SEL_LOAD_BOOT_SDRAM
|
|
|| type == SEL_LOAD_BOOT_WRITE_FLASH
|
|
#ifdef RALINK_UPGRADE_BY_SERIAL
|
|
|| type == SEL_LOAD_BOOT_WRITE_FLASH_BY_SERIAL
|
|
#endif
|
|
) {
|
|
if(type == SEL_LOAD_BOOT_SDRAM)
|
|
#if defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD)
|
|
argv[1] = "0x8a200000";
|
|
#else
|
|
argv[1] = "0x80200000";
|
|
#endif
|
|
else
|
|
#if defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD)
|
|
argv[1] = "0x8a100000";
|
|
#else
|
|
argv[1] = "0x80100000";
|
|
#endif
|
|
printf("\tInput Uboot filename ");
|
|
//argv[2] = "uboot.bin";
|
|
strncpy(argv[2], "uboot.bin", ARGV_LEN);
|
|
}
|
|
else if (type == SEL_LOAD_LINUX_WRITE_FLASH) {
|
|
#if defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD)
|
|
argv[1] = "0x8a100000";
|
|
#else
|
|
argv[1] = "0x80100000";
|
|
#endif
|
|
printf("\tInput Linux Kernel filename ");
|
|
//argv[2] = "uImage"; winfred: use strncpy instead to prevent the buffer overflow at copy_filename later
|
|
strncpy(argv[2], "uImage", ARGV_LEN);
|
|
}
|
|
else if (type == SEL_LOAD_LINUX_SDRAM ) {
|
|
/* bruce to support ramdisk */
|
|
#if defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD)
|
|
argv[1] = "0x8a800000";
|
|
#else
|
|
argv[1] = "0x80A00000";
|
|
#endif
|
|
printf("\tInput Linux Kernel filename ");
|
|
//argv[2] = "uImage";
|
|
strncpy(argv[2], "uImage", ARGV_LEN);
|
|
}
|
|
|
|
s = getenv("bootfile");
|
|
if (s != NULL) {
|
|
memcpy(file, s, strlen(s));
|
|
memcpy(default_file, s, strlen(s));
|
|
}
|
|
printf("(%s) ", file);
|
|
input_value(file);
|
|
if (file == NULL)
|
|
return 1;
|
|
copy_filename (argv[2], file, sizeof(file));
|
|
setenv("bootfile", file);
|
|
if (strcmp(default_file, file) != 0)
|
|
modifies++;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline void trigger_hw_reset(void)
|
|
{
|
|
#ifdef GPIO14_RESET_MODE
|
|
//set GPIO14 as output to trigger hw reset circuit
|
|
RALINK_REG(RT2880_REG_PIODIR)|=1<<14; //output mode
|
|
|
|
RALINK_REG(RT2880_REG_PIODATA)|=1<<14; //pull high
|
|
udelay(100);
|
|
RALINK_REG(RT2880_REG_PIODATA)&=~(1<<14); //pull low
|
|
#endif
|
|
}
|
|
|
|
#ifdef DUAL_IMAGE_SUPPORT
|
|
|
|
/*
|
|
* dir=1: Image1 to Image2
|
|
* dir=2: Image2 to Image1
|
|
*/
|
|
int copy_image(int dir, unsigned long image_size)
|
|
{
|
|
int ret = 0;
|
|
#ifdef CFG_ENV_IS_IN_FLASH
|
|
unsigned long e_end, len;
|
|
#endif
|
|
|
|
if (dir == 1) {
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
printf("\nCopy Image:\nImage1(0x%X) to Image2(0x%X), size=0x%X\n",
|
|
CFG_KERN_ADDR - CFG_FLASH_BASE,
|
|
CFG_KERN2_ADDR - CFG_FLASH_BASE, image_size);
|
|
ranand_read((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
ret = ranand_erase_write((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN2_ADDR-CFG_FLASH_BASE, image_size);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
printf("\nCopy Image:\nImage1(0x%X) to Image2(0x%X), size=0x%X\n",
|
|
CFG_KERN_ADDR - CFG_FLASH_BASE,
|
|
CFG_KERN2_ADDR - CFG_FLASH_BASE, image_size);
|
|
raspi_read((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
ret = raspi_erase_write((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN2_ADDR-CFG_FLASH_BASE, image_size);
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
printf("\nCopy Image:\nImage1(0x%X) to Image2(0x%X), size=0x%X\n", CFG_KERN_ADDR, CFG_KERN2_ADDR, image_size);
|
|
e_end = CFG_KERN2_ADDR + image_size - 1;
|
|
if (get_addr_boundary(&e_end) != 0)
|
|
return -1;
|
|
printf("Erase from 0x%X to 0x%X\n", CFG_KERN2_ADDR, e_end);
|
|
flash_sect_erase(CFG_KERN2_ADDR, e_end);
|
|
memcpy(CFG_LOAD_ADDR, (void *)CFG_KERN_ADDR, image_size);
|
|
ret = flash_write((uchar *)CFG_LOAD_ADDR, (ulong)CFG_KERN2_ADDR, image_size);
|
|
#endif
|
|
}
|
|
else if (dir == 2) {
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
printf("\nCopy Image:\nImage2(0x%X) to Image1(0x%X), size=0x%X\n",
|
|
CFG_KERN2_ADDR - CFG_FLASH_BASE,
|
|
CFG_KERN_ADDR - CFG_FLASH_BASE, image_size);
|
|
ranand_read((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN2_ADDR-CFG_FLASH_BASE, image_size);
|
|
ret = ranand_erase_write((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
printf("\nCopy Image:\nImage2(0x%X) to Image1(0x%X), size=0x%X\n",
|
|
CFG_KERN2_ADDR - CFG_FLASH_BASE,
|
|
CFG_KERN_ADDR - CFG_FLASH_BASE, image_size);
|
|
raspi_read((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN2_ADDR-CFG_FLASH_BASE, image_size);
|
|
ret = raspi_erase_write((char *)CFG_SPINAND_LOAD_ADDR, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
printf("\nCopy Image:\nImage2(0x%X) to Image1(0x%X), size=0x%X\n", CFG_KERN2_ADDR, CFG_KERN_ADDR, image_size);
|
|
#if defined (ON_BOARD_16M_FLASH_COMPONENT) && (defined (RT2880_ASIC_BOARD) || defined (RT2880_FPGA_BOARD) || defined (RT3052_MP1))
|
|
len = 0x400000 - (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE);
|
|
if (image_size <= len) {
|
|
e_end = CFG_KERN_ADDR + image_size - 1;
|
|
if (get_addr_boundary(&e_end) != 0)
|
|
return -1;
|
|
printf("Erase from 0x%X To 0x%X\n", CFG_KERN_ADDR, e_end);
|
|
flash_sect_erase(CFG_KERN_ADDR, e_end);
|
|
memcpy(CFG_LOAD_ADDR, (void *)CFG_KERN2_ADDR, image_size);
|
|
ret = flash_write((uchar *)CFG_LOAD_ADDR, (ulong)CFG_KERN_ADDR, image_size);
|
|
}
|
|
else {
|
|
e_end = CFG_KERN_ADDR + len - 1;
|
|
if (get_addr_boundary(&e_end) != 0)
|
|
return -1;
|
|
printf("Erase from 0x%X To 0x%X\n", CFG_KERN_ADDR, e_end);
|
|
flash_sect_erase(CFG_KERN_ADDR, e_end);
|
|
e_end = PHYS_FLASH_2 + (image_size - len) - 1;
|
|
if (get_addr_boundary(&e_end) != 0)
|
|
return -1;
|
|
printf("From 0x%X To 0x%X\n", PHYS_FLASH_2, e_end);
|
|
flash_sect_erase(PHYS_FLASH_2, e_end);
|
|
memcpy(CFG_LOAD_ADDR, (void *)CFG_KERN2_ADDR, image_size);
|
|
ret = flash_write((uchar *)CFG_LOAD_ADDR, (ulong)CFG_KERN_ADDR, len);
|
|
ret = flash_write((uchar *)(CFG_LOAD_ADDR + len), (ulong)PHYS_FLASH_2, image_size - len);
|
|
}
|
|
#else
|
|
e_end = CFG_KERN_ADDR + image_size - 1;
|
|
if (get_addr_boundary(&e_end) != 0)
|
|
return -1;
|
|
printf("Erase from 0x%X to 0x%X\n", CFG_KERN_ADDR, e_end);
|
|
flash_sect_erase(CFG_KERN_ADDR, e_end);
|
|
memcpy(CFG_LOAD_ADDR, (void *)CFG_KERN2_ADDR, image_size);
|
|
ret = flash_write((uchar *)CFG_LOAD_ADDR, (ulong)CFG_KERN_ADDR, image_size);
|
|
#endif
|
|
#endif
|
|
if (ret == 0) {
|
|
setenv("Image1Stable", "0");
|
|
setenv("Image1Try", "0");
|
|
saveenv();
|
|
}
|
|
}
|
|
else
|
|
ret = -1;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
int debug_mode(void)
|
|
{
|
|
printf("Upgrade Mode~~\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define MAX_TRY_TIMES 3
|
|
int check_image_validation(void)
|
|
{
|
|
int ret = 0;
|
|
int broken1 = 0, broken2 = 0;
|
|
unsigned long len = 0, chksum = 0;
|
|
image_header_t hdr1, hdr2;
|
|
unsigned char *hdr1_addr, *hdr2_addr;
|
|
char *stable, *try;
|
|
|
|
hdr1_addr = (unsigned char *)CFG_KERN_ADDR;
|
|
hdr2_addr = (unsigned char *)CFG_KERN2_ADDR;
|
|
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
ranand_read((char *)&hdr1, (unsigned int)hdr1_addr - CFG_FLASH_BASE, sizeof(image_header_t));
|
|
ranand_read(char *)(&hdr2, (unsigned int)hdr2_addr - CFG_FLASH_BASE, sizeof(image_header_t));
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
raspi_read((char *)&hdr1, (unsigned int)hdr1_addr - CFG_FLASH_BASE, sizeof(image_header_t));
|
|
raspi_read((char *)&hdr2, (unsigned int)hdr2_addr - CFG_FLASH_BASE, sizeof(image_header_t));
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
memmove(&hdr1, (char *)hdr1_addr, sizeof(image_header_t));
|
|
memmove(&hdr2, (char *)hdr2_addr, sizeof(image_header_t));
|
|
#endif
|
|
|
|
printf("\n=================================================\n");
|
|
printf("Check image validation:\n");
|
|
|
|
/* Check header magic number */
|
|
printf ("Image1 Header Magic Number --> ");
|
|
if (ntohl(hdr1.ih_magic) != IH_MAGIC) {
|
|
broken1 = 1;
|
|
printf("Failed\n");
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
|
|
printf ("Image2 Header Magic Number --> ");
|
|
if (ntohl(hdr2.ih_magic) != IH_MAGIC) {
|
|
broken2 = 1;
|
|
printf("Failed\n");
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
|
|
/* Check header crc */
|
|
/* Skip crc checking if there is no valid header, or it may hang on due to broken header length */
|
|
if (broken1 == 0) {
|
|
printf("Image1 Header Checksum --> ");
|
|
len = sizeof(image_header_t);
|
|
chksum = ntohl(hdr1.ih_hcrc);
|
|
hdr1.ih_hcrc = 0;
|
|
if (crc32(0, (char *)&hdr1, len) != chksum) {
|
|
broken1 = 1;
|
|
printf("Failed\n");
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
}
|
|
|
|
if (broken2 == 0) {
|
|
printf("Image2 Header Checksum --> ");
|
|
len = sizeof(image_header_t);
|
|
chksum = ntohl(hdr2.ih_hcrc);
|
|
hdr2.ih_hcrc = 0;
|
|
if (crc32(0, (char *)&hdr2, len) != chksum) {
|
|
printf("Failed\n");
|
|
broken2 = 1;
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
}
|
|
|
|
/* Check data crc */
|
|
/* Skip crc checking if there is no valid header, or it may hang on due to broken data length */
|
|
if (broken1 == 0) {
|
|
printf("Image1 Data Checksum --> ");
|
|
len = ntohl(hdr1.ih_size);
|
|
chksum = ntohl(hdr1.ih_dcrc);
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
ranand_read((char *)CFG_SPINAND_LOAD_ADDR,
|
|
(unsigned int)hdr1_addr - CFG_FLASH_BASE + sizeof(image_header_t),
|
|
len);
|
|
if (crc32(0, (char *)CFG_SPINAND_LOAD_ADDR, len) != chksum)
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
raspi_read((char *)CFG_SPINAND_LOAD_ADDR,
|
|
(unsigned int)hdr1_addr - CFG_FLASH_BASE + sizeof(image_header_t),
|
|
len);
|
|
if (crc32(0, (char *)CFG_SPINAND_LOAD_ADDR, len) != chksum)
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
if (crc32(0, (char *)(hdr1_addr + sizeof(image_header_t)), len) != chksum)
|
|
#endif
|
|
{
|
|
broken1 = 1;
|
|
printf("Failed\n");
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
}
|
|
|
|
if (broken2 == 0) {
|
|
printf("Image2 Data Checksum --> ");
|
|
len = ntohl(hdr2.ih_size);
|
|
chksum = ntohl(hdr2.ih_dcrc);
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
ranand_read((char *)CFG_SPINAND_LOAD_ADDR,
|
|
(unsigned int)hdr2_addr - CFG_FLASH_BASE + sizeof(image_header_t),
|
|
len);
|
|
if (crc32(0, (char *)CFG_SPINAND_LOAD_ADDR, len) != chksum)
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
raspi_read((char *)CFG_SPINAND_LOAD_ADDR,
|
|
(unsigned int)hdr2_addr - CFG_FLASH_BASE + sizeof(image_header_t),
|
|
len);
|
|
if (crc32(0, (char *)CFG_SPINAND_LOAD_ADDR, len) != chksum)
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
if (crc32(0, (char *)(hdr2_addr + sizeof(image_header_t)), len) != chksum)
|
|
#endif
|
|
{
|
|
broken2 = 1;
|
|
printf("Failed\n");
|
|
}
|
|
else
|
|
printf("OK\n");
|
|
}
|
|
|
|
/* Check stable flag and try counter */
|
|
stable = getenv("Image1Stable");
|
|
printf("Image1 Stable Flag --> %s\n", !strcmp(stable, "1") ? "Stable" : "Not stable");
|
|
try = getenv("Image1Try");
|
|
printf("Image1 Try Counter --> %s\n", (try == NULL) ? "0" : try);
|
|
if ((strcmp(stable, "1") != 0) && (simple_strtoul(try, NULL, 10)) > MAX_TRY_TIMES
|
|
&& (broken1 == 0)) {
|
|
printf("\nImage1 is not stable and try counter > %X. Take it as a broken image.", MAX_TRY_TIMES);
|
|
broken1 = 1;
|
|
}
|
|
|
|
printf("\nImage1: %s Image2: %s\n", broken1 ? "Broken" : "OK", broken2 ? "Broken" : "OK");
|
|
if (broken1 == 1 && broken2 == 0) {
|
|
len = ntohl(hdr2.ih_size) + sizeof(image_header_t);
|
|
if (len > CFG_KERN_SIZE)
|
|
printf("\nImage1 is broken, but Image2 size(0x%X) is too big(limit=0x%X)!!\
|
|
\nGive up copying image.\n", len, CFG_KERN_SIZE);
|
|
else {
|
|
printf("Image1 is broken. Copy Image2 to Image1\n");
|
|
copy_image(2, len);
|
|
}
|
|
}
|
|
else if (broken1 == 0 && broken2 == 1) {
|
|
len = ntohl(hdr1.ih_size) + sizeof(image_header_t);
|
|
if (len > CFG_KERN2_SIZE)
|
|
printf("\nImage2 is broken, but Image1 size(0x%X) is too big(limit=0x%X)!!\
|
|
\nGive up copying image.\n", len, CFG_KERN2_SIZE);
|
|
else {
|
|
printf("\nImage2 is broken. Copy Image1 to Image2.\n");
|
|
copy_image(1, len);
|
|
}
|
|
}
|
|
else if (broken1 == 1 && broken2 == 1)
|
|
debug_mode();
|
|
else
|
|
ret = -1;
|
|
|
|
printf("\n=================================================\n");
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
static int check_uboot_image(ulong image_ptr, ulong image_size)
|
|
{
|
|
image_header_t *hdr = (image_header_t*)image_ptr;
|
|
|
|
if (image_size > UBOOT_FILE_SIZE_MAX) {
|
|
printf("%s image size %d too big!\n", "U-Boot", image_size);
|
|
return -1;
|
|
}
|
|
|
|
if (image_size < UBOOT_FILE_SIZE_MIN) {
|
|
printf("%s image size %d too small!\n", "U-Boot", image_size);
|
|
return -1;
|
|
}
|
|
|
|
#if defined (UBOOT_RAM) && (defined (CFG_ENV_IS_IN_NAND) || defined (CFG_ENV_IS_IN_SPI))
|
|
/* RAM mode Uboot */
|
|
if (ntohl(hdr->ih_magic) != IH_MAGIC) {
|
|
printf("Invalid U-Boot image %s!\n", "header");
|
|
return -1;
|
|
}
|
|
#else
|
|
/* ROM mode Uboot */
|
|
if (ntohl(hdr->ih_magic) == IH_MAGIC) {
|
|
printf("Invalid U-Boot image %s!\n", "(RAM mode)");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int flash_uboot_image(ulong image_ptr, ulong image_size)
|
|
{
|
|
int rrc = 0;
|
|
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = ranand_erase_write((char *)image_ptr, 0, image_size);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = raspi_erase_write((char *)image_ptr, 0, image_size);
|
|
#else
|
|
ulong e_end = CFG_FLASH_BASE+CFG_BOOTLOADER_SIZE-1;
|
|
|
|
flash_sect_protect(0, CFG_FLASH_BASE, e_end);
|
|
printf("\n Erase %s block from 0x%X to 0x%X\n", "U-Boot", CFG_FLASH_BASE, e_end);
|
|
flash_sect_erase(CFG_FLASH_BASE, e_end);
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = flash_write((uchar *)image_ptr, CFG_FLASH_BASE, image_size);
|
|
flash_sect_protect(1, CFG_FLASH_BASE, e_end);
|
|
#endif
|
|
|
|
if (rrc) {
|
|
#if defined (CFG_ENV_IS_IN_NAND) || defined (CFG_ENV_IS_IN_SPI)
|
|
printf("Error code: %d\n", rrc);
|
|
#else
|
|
flash_perror(rrc);
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
printf("%d bytes flashed\n", image_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int flash_kernel_image(ulong image_ptr, ulong image_size)
|
|
{
|
|
int rrc = 0;
|
|
ulong e_end;
|
|
|
|
if (image_size < LINUX_FILE_SIZE_MIN) {
|
|
printf("%s image size %d too small!\n", "Linux", image_size);
|
|
return -1;
|
|
}
|
|
|
|
memset(&header, 0, sizeof(header));
|
|
if (verify_kernel_image(image_ptr, NULL, NULL, NULL) <= 0) {
|
|
printf("Check image error!\n");
|
|
return -1;
|
|
}
|
|
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = ranand_erase_write((char *)image_ptr, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = raspi_erase_write((char *)image_ptr, CFG_KERN_ADDR-CFG_FLASH_BASE, image_size);
|
|
#else
|
|
if (image_size > (gd->bd->bi_flashsize - (CFG_BOOTLOADER_SIZE + CFG_CONFIG_SIZE + CFG_FACTORY_SIZE))) {
|
|
printf("%s image size %d too big!\n", "Linux", image_size);
|
|
return -1;
|
|
}
|
|
|
|
e_end = CFG_KERN_ADDR + image_size - 1;
|
|
if (get_addr_boundary(&e_end) == 0) {
|
|
printf("\n Erase %s block from 0x%X to 0x%X\n", "Linux", CFG_KERN_ADDR, e_end);
|
|
flash_sect_erase(CFG_KERN_ADDR, e_end);
|
|
printf("\n Copy %d bytes to Flash... \n", image_size);
|
|
rrc = flash_write((uchar *)image_ptr, CFG_KERN_ADDR, image_size);
|
|
} else {
|
|
rrc = ERR_ALIGN;
|
|
}
|
|
#endif
|
|
|
|
if (rrc) {
|
|
#if defined (CFG_ENV_IS_IN_NAND) || defined (CFG_ENV_IS_IN_SPI)
|
|
printf("Error code: %d\n", rrc);
|
|
#else
|
|
flash_perror(rrc);
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
printf("%d bytes flashed\n", image_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined (RALINK_USB) || defined (MTK_USB)
|
|
int flash_kernel_image_from_usb(cmd_tbl_t *cmdtp)
|
|
{
|
|
char *argv[5];
|
|
char addr_str[16], dev_str[4];
|
|
int i, done;
|
|
|
|
argv[1] = "start";
|
|
|
|
do_usb(cmdtp, 0, 2, argv);
|
|
if (usb_stor_curr_dev < 0) {
|
|
printf("\n No USB Storage found. Upgrade FW failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
sprintf(addr_str, "0x%X", CFG_LOAD_ADDR);
|
|
|
|
argv[1] = "usb";
|
|
argv[2] = &dev_str[0];
|
|
argv[3] = &addr_str[0];
|
|
argv[4] = "root_uImage";
|
|
|
|
done = 0;
|
|
for (i = 0; i < USB_MAX_STOR_DEV; ++i) {
|
|
block_dev_desc_t *stor_dev = usb_stor_get_dev(i);
|
|
if (stor_dev->type != DEV_TYPE_UNKNOWN) {
|
|
sprintf(dev_str, "%d", i);
|
|
if (do_fat_fsload(cmdtp, 0, 5, argv) == 0) {
|
|
done = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!done) {
|
|
printf("\n Upgrade FW from USB storage failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
NetBootFileXferSize = simple_strtoul(getenv("filesize"), NULL, 16);
|
|
if (flash_kernel_image(CFG_LOAD_ADDR, NetBootFileXferSize) != 0)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
void perform_system_reset(void)
|
|
{
|
|
printf("\nSYSTEM RESET!!!\n\n");
|
|
udelay(500);
|
|
do_reset(NULL, 0, 0, NULL);
|
|
}
|
|
|
|
/************************************************************************
|
|
*
|
|
* This is the next part if the initialization sequence: we are now
|
|
* running from RAM and have a "normal" C environment, i. e. global
|
|
* data can be written, BSS has been cleared, the stack size in not
|
|
* that critical any more, etc.
|
|
*
|
|
************************************************************************
|
|
*/
|
|
|
|
gd_t gd_data;
|
|
|
|
__attribute__((nomips16)) void board_init_r (gd_t *id, ulong dest_addr)
|
|
{
|
|
cmd_tbl_t *cmdtp;
|
|
ulong size;
|
|
extern void malloc_bin_reloc (void);
|
|
#ifndef CFG_ENV_IS_NOWHERE
|
|
extern char * env_name_spec;
|
|
#endif
|
|
char *s, *e;
|
|
bd_t *bd;
|
|
int i;
|
|
int timer1= CONFIG_BOOTDELAY;
|
|
unsigned char confirm=0;
|
|
int is_soft_reset=0;
|
|
int my_tmp;
|
|
char addr_str[16];
|
|
#if defined (CFG_ENV_IS_IN_FLASH)
|
|
ulong e_end;
|
|
#endif
|
|
ulong load_address;
|
|
#if defined (UBOOT_RAM) && (defined (CFG_ENV_IS_IN_NAND) || defined (CFG_ENV_IS_IN_SPI))
|
|
char *uboot_file = "uboot.img";
|
|
#else
|
|
char *uboot_file = "uboot.bin";
|
|
#endif
|
|
u32 reg;
|
|
#if defined (RT2880_FPGA_BOARD) || defined (RT2880_ASIC_BOARD)
|
|
u32 value,kk;
|
|
|
|
memcpy(&gd_data, (void *)gd, sizeof(gd_t));
|
|
gd = &gd_data;
|
|
#else
|
|
u32 config1,lsize,icache_linesz,icache_sets,icache_ways,icache_size;
|
|
u32 dcache_linesz,dcache_sets,dcache_ways,dcache_size;
|
|
|
|
memcpy((void *)(CFG_SDRAM_BASE + DRAM_SIZE*0x100000 - 0x10000), (void *)gd, sizeof(gd_t));
|
|
gd = (gd_t *)(CFG_SDRAM_BASE + DRAM_SIZE*0x100000- 0x10000);//&gd_data;
|
|
#endif
|
|
|
|
#if defined(MT7620_ASIC_BOARD)
|
|
/* Enable E-PHY clock */ /* TODO: remove printf()*/
|
|
printf("enable ephy clock...");
|
|
i = 5;
|
|
rw_rf_reg(1, 29, &i);
|
|
printf("done. ");
|
|
rw_rf_reg(0, 29, &i);
|
|
|
|
/* print SSC for confirmation */ /* TODO: remove these in formanl release*/
|
|
reg = RALINK_REG(0xb0000054);
|
|
reg >>= 4;
|
|
if(reg & 0x00000008){
|
|
unsigned long swing = ((reg & 0x00000007) + 1) * 1250;
|
|
printf("SSC enabled. swing=%d, upperbound=%d\n", swing, (reg >> 4) & 0x3);
|
|
}else{
|
|
printf("SSC disabled.\n");
|
|
}
|
|
#endif
|
|
|
|
#if defined(RT3052_ASIC_BOARD)
|
|
void adjust_voltage(void);
|
|
// adjust core voltage ASAP
|
|
adjust_voltage();
|
|
#endif
|
|
|
|
#if defined (RT3052_FPGA_BOARD) || defined(RT3052_ASIC_BOARD)
|
|
#ifdef RALINK_EPHY_INIT
|
|
void enable_mdio(int);
|
|
// disable MDIO access ASAP
|
|
enable_mdio(0);
|
|
#endif
|
|
#endif
|
|
|
|
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
|
|
|
|
Init_System_Mode(); /* Get CPU rate */
|
|
|
|
#if defined(MT7628_ASIC_BOARD) /* Enable WLED share pin */
|
|
RALINK_REG(RALINK_SYSCTL_BASE+0x3C)|= (1<<8);
|
|
#endif
|
|
#if defined(RT3052_ASIC_BOARD) || defined(RT3352_ASIC_BOARD) || defined(RT5350_ASIC_BOARD)
|
|
//turn on all Ethernet LEDs around 0.5sec.
|
|
#if 0
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xA4)=0xC;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xA8)=0xC;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xAC)=0xC;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xB0)=0xC;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xB4)=0xC;
|
|
udelay(500000);
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xA4)=0x5;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xA8)=0x5;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xAC)=0x5;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xB0)=0x5;
|
|
RALINK_REG(RALINK_ETH_SW_BASE+0xB4)=0x5;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(RT3052_ASIC_BOARD) || defined(RT2883_ASIC_BOARD)
|
|
void config_usbotg(void);
|
|
config_usbotg();
|
|
#elif defined(RT3883_ASIC_BOARD) || defined(RT3352_ASIC_BOARD) || \
|
|
defined(RT5350_ASIC_BOARD) || defined(RT6855_ASIC_BOARD) || \
|
|
defined(MT7620_ASIC_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
void config_usb_ehciohci(void);
|
|
config_usb_ehciohci();
|
|
#elif defined(MT7621_ASIC_BOARD)
|
|
void config_usb_mtk_xhci();
|
|
config_usb_mtk_xhci();
|
|
#endif
|
|
#if defined (MT7620_ASIC_BOARD) || defined (MT7628_ASIC_BOARD)
|
|
void disable_pcie();
|
|
disable_pcie();
|
|
#endif
|
|
|
|
reg = RALINK_REG(RT2880_RSTSTAT_REG);
|
|
if(reg & RT2880_WDRST ){
|
|
printf("***********************\n");
|
|
printf("Watchdog Reset Occurred\n");
|
|
printf("***********************\n");
|
|
RALINK_REG(RT2880_RSTSTAT_REG)|=RT2880_WDRST;
|
|
RALINK_REG(RT2880_RSTSTAT_REG)&=~RT2880_WDRST;
|
|
}else if(reg & RT2880_SWSYSRST){
|
|
printf("******************************\n");
|
|
printf("Software System Reset Occurred\n");
|
|
printf("******************************\n");
|
|
RALINK_REG(RT2880_RSTSTAT_REG)|=RT2880_SWSYSRST;
|
|
RALINK_REG(RT2880_RSTSTAT_REG)&=~RT2880_SWSYSRST;
|
|
}else if (reg & RT2880_SWCPURST){
|
|
printf("***************************\n");
|
|
printf("Software CPU Reset Occurred\n");
|
|
printf("***************************\n");
|
|
RALINK_REG(RT2880_RSTSTAT_REG)|=RT2880_SWCPURST;
|
|
RALINK_REG(RT2880_RSTSTAT_REG)&=~RT2880_SWCPURST;
|
|
}
|
|
|
|
if(reg & (RT2880_WDRST|RT2880_SWSYSRST|RT2880_SWCPURST)){
|
|
is_soft_reset=1;
|
|
trigger_hw_reset();
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
|
|
#endif
|
|
gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
|
|
|
|
monitor_flash_len = (ulong)&uboot_end_data - dest_addr;
|
|
#ifdef DEBUG
|
|
debug("\n monitor_flash_len =%d \n",monitor_flash_len);
|
|
#endif
|
|
/*
|
|
* We have to relocate the command table manually
|
|
*/
|
|
for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
|
|
ulong addr;
|
|
|
|
addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
|
|
#ifdef DEBUG
|
|
printf ("Command \"%s\": 0x%08lx => 0x%08lx\n",
|
|
cmdtp->name, (ulong) (cmdtp->cmd), addr);
|
|
#endif
|
|
cmdtp->cmd =
|
|
(int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
|
|
|
|
addr = (ulong)(cmdtp->name) + gd->reloc_off;
|
|
cmdtp->name = (char *)addr;
|
|
|
|
if (cmdtp->usage) {
|
|
addr = (ulong)(cmdtp->usage) + gd->reloc_off;
|
|
cmdtp->usage = (char *)addr;
|
|
}
|
|
#ifdef CFG_LONGHELP
|
|
if (cmdtp->help) {
|
|
addr = (ulong)(cmdtp->help) + gd->reloc_off;
|
|
cmdtp->help = (char *)addr;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
/* there are some other pointer constants we must deal with */
|
|
#ifndef CFG_ENV_IS_NOWHERE
|
|
env_name_spec += gd->reloc_off;
|
|
#endif
|
|
|
|
bd = gd->bd;
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
#if defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD)
|
|
if ((size = mtk_nand_probe()) != (ulong)0) {
|
|
printf("nand probe fail\n");
|
|
while(1);
|
|
}
|
|
#else
|
|
if ((size = ranand_init()) == (ulong)-1) {
|
|
printf("ra_nand_init fail\n");
|
|
while(1);
|
|
}
|
|
#endif
|
|
bd->bi_flashstart = 0;
|
|
bd->bi_flashsize = size;
|
|
bd->bi_flashoffset = 0;
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
if ((size = raspi_init()) == (ulong)-1) {
|
|
printf("ra_spi_init fail\n");
|
|
while(1);
|
|
}
|
|
bd->bi_flashstart = 0;
|
|
bd->bi_flashsize = size;
|
|
bd->bi_flashoffset = 0;
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
/* configure available FLASH banks */
|
|
size = flash_init();
|
|
|
|
bd->bi_flashstart = CFG_FLASH_BASE;
|
|
bd->bi_flashsize = size;
|
|
#if CFG_MONITOR_BASE == CFG_FLASH_BASE
|
|
bd->bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */
|
|
#else
|
|
bd->bi_flashoffset = 0;
|
|
#endif
|
|
#endif //CFG_ENV_IS_IN_FLASH
|
|
|
|
#if defined(MT7628_ASIC_BOARD)
|
|
/* Enable ePA/eLNA share pin */
|
|
{
|
|
char ee35, ee36;
|
|
raspi_read((char *)&ee35, CFG_FACTORY_ADDR-CFG_FLASH_BASE+0x35, 1);
|
|
raspi_read((char *)&ee36, CFG_FACTORY_ADDR-CFG_FLASH_BASE+0x36, 1);
|
|
if ((ee35 & 0x2) || ((ee36 & 0xc) == 0xc))
|
|
{
|
|
RALINK_REG(RALINK_SYSCTL_BASE+0x60)|= ((0x3<<24)|(0x3 << 6));
|
|
}
|
|
}
|
|
|
|
// reset MIPS now also reset Andes
|
|
RALINK_REG(RALINK_SYSCTL_BASE+0x38)|= 0x200;
|
|
#endif
|
|
/* initialize malloc() area */
|
|
mem_malloc_init();
|
|
malloc_bin_reloc();
|
|
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
nand_env_init();
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
spi_env_init();
|
|
#else
|
|
flash_env_init();
|
|
#endif //CFG_ENV_IS_IN_FLASH
|
|
|
|
#if defined(RT3052_ASIC_BOARD)
|
|
void adjust_frequency(void);
|
|
//adjust_frequency();
|
|
#endif
|
|
#if defined (RT3352_ASIC_BOARD)
|
|
void adjust_crystal_circuit(void);
|
|
adjust_crystal_circuit();
|
|
#endif
|
|
#if defined (RT3352_ASIC_BOARD) || defined (RT3883_ASIC_BOARD)
|
|
void adjust_rf_r17(void);
|
|
adjust_rf_r17();
|
|
#endif
|
|
|
|
/* relocate environment function pointers etc. */
|
|
env_relocate();
|
|
|
|
/* board MAC address */
|
|
s = getenv ("ethaddr");
|
|
for (i = 0; i < 6; ++i) {
|
|
bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
|
|
if (s)
|
|
s = (*e) ? e + 1 : e;
|
|
}
|
|
|
|
/* IP Address */
|
|
bd->bi_ip_addr = getenv_IPaddr("ipaddr");
|
|
|
|
#if defined(CONFIG_PCI)
|
|
/*
|
|
* Do pci configuration
|
|
*/
|
|
puts("\n Do pci configuration !!\n");
|
|
pci_init();
|
|
#endif
|
|
|
|
/** leave this here (after malloc(), environment and PCI are working) **/
|
|
/* Initialize devices */
|
|
devices_init ();
|
|
|
|
jumptable_init ();
|
|
|
|
/* Initialize the console (after the relocation and devices init) */
|
|
console_init_r ();
|
|
|
|
/* Initialize from environment */
|
|
if ((s = getenv ("loadaddr")) != NULL) {
|
|
load_addr = simple_strtoul (s, NULL, 16);
|
|
}
|
|
#if (CONFIG_COMMANDS & CFG_CMD_NET)
|
|
if ((s = getenv ("bootfile")) != NULL) {
|
|
copy_filename (BootFile, s, sizeof (BootFile));
|
|
}
|
|
#endif /* CFG_CMD_NET */
|
|
|
|
#if defined(CONFIG_MISC_INIT_R)
|
|
/* miscellaneous platform dependent initialisations */
|
|
misc_init_r ();
|
|
#endif
|
|
|
|
/* RT2880 Boot Loader Menu */
|
|
#if defined(RT3352_FPGA_BOARD) || defined (RT3352_ASIC_BOARD) || \
|
|
defined(RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) || \
|
|
defined(RT5350_FPGA_BOARD) || defined (RT5350_ASIC_BOARD)
|
|
|
|
#if defined(CFG_ENV_IS_IN_SPI) || defined (CFG_ENV_IS_IN_NAND)
|
|
{
|
|
int reg, boot_from_eeprom=0;
|
|
reg = RALINK_REG(RT2880_SYSCFG_REG);
|
|
/* Uboot Version and Configuration*/
|
|
printf("============================================ \n");
|
|
printf("%s U-Boot Version: %s\n", RLT_MTK_VENDOR_NAME, RALINK_LOCAL_VERSION);
|
|
printf("-------------------------------------------- \n");
|
|
printf("%s %s %s\n",CHIP_TYPE, CHIP_VERSION, GMAC_MODE);
|
|
boot_from_eeprom = ((reg>>18) & 0x01);
|
|
if(boot_from_eeprom){
|
|
printf("DRAM_CONF_FROM: EEPROM \n");
|
|
printf("DRAM_SIZE: %d Mbits %s\n", DRAM_COMPONENT, DDR_INFO);
|
|
printf("DRAM_TOTAL_WIDTH: %d bits\n", DRAM_BUS );
|
|
printf("TOTAL_MEMORY_SIZE: %d MBytes\n", DRAM_SIZE);
|
|
}else{
|
|
int dram_width, is_ddr2, dram_total_width, total_size;
|
|
int _x = ((reg >> 12) & 0x7);
|
|
|
|
#if defined(RT3352_FPGA_BOARD) || defined (RT3352_ASIC_BOARD)
|
|
int dram_size = (_x == 6)? 2048 : (_x == 5)? 1024 : (_x == 4)? 512 : (_x == 3)? 256 : (_x == 2)? 128 : \
|
|
(_x == 1)? 64 : (_x == 0)? 16 : 0;
|
|
#elif defined (RT5350_FPGA_BOARD) || defined (RT5350_ASIC_BOARD)
|
|
int dram_size = (_x == 4)? 512 : (_x == 3)? 256 : (_x == 2)? 128 : \
|
|
(_x == 1)? 64 : (_x == 0)? 16 : 0;
|
|
#elif defined (RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD)
|
|
int dram_size = (_x == 6)? 2048 : (_x == 5)? 1024 : (_x == 4)? 512 : \
|
|
(_x == 3)? 256 : (_x == 2)? 128 : (_x == 1)? 64 : \
|
|
(_x == 0)? 16 : 0;
|
|
#endif
|
|
if(((reg >> 15) & 0x1)){
|
|
dram_total_width = 32;
|
|
}else{
|
|
dram_total_width = 16;
|
|
}
|
|
|
|
is_ddr2 = ((reg >> 17) & 0x1);
|
|
if(is_ddr2){
|
|
if((reg >> 10) & 0x1){
|
|
dram_width = 16;
|
|
}else{
|
|
dram_width = 8;
|
|
}
|
|
}else{
|
|
if((reg >> 10) & 0x1){
|
|
dram_width = 32;
|
|
}else{
|
|
dram_width = 16;
|
|
}
|
|
}
|
|
total_size = (dram_size*(dram_total_width/dram_width))/8;
|
|
|
|
printf("DRAM_CONF_FROM: %s \n", boot_from_eeprom ? "EEPROM":"Boot-Strapping");
|
|
printf("DRAM_TYPE: %s \n", is_ddr2 ? "DDR2":"SDRAM");
|
|
printf("DRAM_SIZE: %d Mbits\n", dram_size);
|
|
printf("DRAM_WIDTH: %d bits\n", dram_width);
|
|
printf("DRAM_TOTAL_WIDTH: %d bits\n", dram_total_width );
|
|
printf("TOTAL_MEMORY_SIZE: %d MBytes\n", total_size);
|
|
}
|
|
printf("%s\n", FLASH_MSG);
|
|
printf("%s\n", "Date:" __DATE__ " Time:" __TIME__ );
|
|
printf("============================================ \n");
|
|
}
|
|
#else
|
|
SHOW_VER_STR();
|
|
#endif /* defined(CFG_ENV_IS_IN_SPI) || defined (CFG_ENV_IS_IN_NAND) */
|
|
|
|
|
|
#elif (defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \
|
|
defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD) || \
|
|
defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || \
|
|
defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD)) && defined (UBOOT_RAM)
|
|
{
|
|
unsigned long chip_mode, dram_comp, dram_bus, is_ddr1, is_ddr2, data, cfg0, cfg1, size=0;
|
|
int dram_type_bit_offset = 0;
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
data = RALINK_REG(RALINK_SYSCTL_BASE+0x8c);
|
|
chip_mode = ((data>>28) & 0x3)|(((data>>22) & 0x3)<<2);
|
|
dram_type_bit_offset = 24;
|
|
#else
|
|
data = RALINK_REG(RALINK_SYSCTL_BASE+0x10);
|
|
chip_mode = (data&0x0F);
|
|
dram_type_bit_offset = 4;
|
|
#endif
|
|
switch((data>>dram_type_bit_offset)&0x3)
|
|
{
|
|
default:
|
|
case 0:
|
|
is_ddr2 = is_ddr1 = 0;
|
|
break;
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
#else
|
|
case 3:
|
|
#endif
|
|
#if defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD)
|
|
is_ddr1 = 1;
|
|
is_ddr2 = 0;
|
|
#else
|
|
is_ddr2 = is_ddr1 = 0;
|
|
#endif
|
|
break;
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
case 2:
|
|
#else
|
|
case 1:
|
|
#endif
|
|
is_ddr2 = 0;
|
|
is_ddr1 = 1;
|
|
break;
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
case 3:
|
|
#else
|
|
case 2:
|
|
#endif
|
|
is_ddr2 = 1;
|
|
is_ddr1 = 0;
|
|
break;
|
|
}
|
|
|
|
switch((data>>dram_type_bit_offset)&0x3)
|
|
{
|
|
case 0:
|
|
#if defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD) || \
|
|
defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
#else
|
|
case 3:
|
|
#endif
|
|
cfg0 = RALINK_REG(RALINK_MEMCTRL_BASE+0x0);
|
|
cfg1 = RALINK_REG(RALINK_MEMCTRL_BASE+0x4);
|
|
data = cfg1;
|
|
|
|
dram_comp = 1<<(2+(((data>>16)&0x3)+11)+(((data>>20)&0x3)+8)+1+3-20);
|
|
dram_bus = ((data>>24)&0x1) ? 32 : 16;
|
|
size = 1<<(2 +(((data>>16)&0x3)+11)+(((data>>20)&0x3)+8)+1-20);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
#if defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD) || \
|
|
defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
case 3:
|
|
#endif
|
|
cfg0 = RALINK_REG(RALINK_MEMCTRL_BASE+0x40);
|
|
cfg1 = RALINK_REG(RALINK_MEMCTRL_BASE+0x44);
|
|
data = cfg1;
|
|
dram_comp = 1<<(((data>>18)&0x7)+5);
|
|
dram_bus = 1<<(((data>>12)&0x3)+2);
|
|
if(((data>>16)&0x3) < ((data>>12)&0x3))
|
|
{
|
|
size = 1<<(((data>>18)&0x7) + 22 + 1-20);
|
|
}
|
|
else
|
|
{
|
|
size = 1<<(((data>>18)&0x7) + 22-20);
|
|
}
|
|
break;
|
|
}
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
if ((((RALINK_REG(RALINK_SYSCTL_BASE+0x8c)>>30)&0x1)==0) && ((chip_mode==2)||(chip_mode==3)))
|
|
{
|
|
#if defined(ON_BOARD_DDR2)
|
|
is_ddr2 = 1;
|
|
is_ddr1 = 0;
|
|
#elif defined(ON_BOARD_DDR1)
|
|
is_ddr2 = 0;
|
|
is_ddr1 = 1;
|
|
#else
|
|
is_ddr2 = is_ddr1 = 0;
|
|
#endif
|
|
dram_comp = DRAM_COMPONENT;
|
|
dram_bus = DRAM_BUS;
|
|
size = DRAM_SIZE;
|
|
}
|
|
#endif
|
|
printf("============================================ \n");
|
|
printf("%s U-Boot Version: %s\n", RLT_MTK_VENDOR_NAME, RALINK_LOCAL_VERSION);
|
|
printf("-------------------------------------------- \n");
|
|
printf("%s %s %s\n",CHIP_TYPE, CHIP_VERSION, GMAC_MODE);
|
|
#if defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD)
|
|
#if defined (RT6855A_FPGA_BOARD)
|
|
if((!is_ddr2)&&(!is_ddr1))
|
|
{
|
|
printf("[SDR_CFG0=0x%08X, SDR_CFG1=0x%08X]\n", RALINK_REG(RALINK_MEMCTRL_BASE+0x0),\
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x4));
|
|
}
|
|
else
|
|
{
|
|
printf("[DDR_CFG0 =0x%08X, DDR_CFG1 =0x%08X]\n", RALINK_REG(RALINK_MEMCTRL_BASE+0x40),\
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x44));
|
|
printf("[DDR_CFG2 =0x%08X, DDR_CFG3 =0x%08X]\n", RALINK_REG(RALINK_MEMCTRL_BASE+0x48),\
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x4C));
|
|
printf("[DDR_CFG4 =0x%08X, DDR_CFG10=0x%08X]\n", RALINK_REG(RALINK_MEMCTRL_BASE+0x50),\
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x68));
|
|
}
|
|
#endif
|
|
printf("DRAM_CONF_FROM: %s \n", ((RALINK_REG(RALINK_SYSCTL_BASE+0x8c)>>30)&0x1) ? \
|
|
"From SPI/NAND": (((chip_mode==2)||(chip_mode==3)) ? "From Uboot" : "Boot-strap"));
|
|
#elif defined (MT7620_ASIC_BOARD) || defined(MT7620_FPGA_BOARD) || defined (MT7628_ASIC_BOARD) || defined(MT7628_FPGA_BOARD)
|
|
printf("DRAM_CONF_FROM: %s \n", (((RALINK_REG(RALINK_SYSCTL_BASE+0x10)>>8)&0x1)==0) ? "From SPI/NAND":
|
|
(((chip_mode==2)||(chip_mode==3)) ? "From Uboot" : "Auto-detection"));
|
|
#else
|
|
printf("DRAM_CONF_FROM: %s \n", ((RALINK_REG(RALINK_SYSCTL_BASE+0x10)>>7)&0x1) ? "From SPI/NAND":
|
|
(((chip_mode==2)||(chip_mode==3)) ? "From Uboot" : "Auto-detection"));
|
|
#endif
|
|
printf("DRAM_TYPE: %s \n", is_ddr2 ? "DDR2": (is_ddr1 ? "DDR1" : "SDRAM"));
|
|
printf("DRAM component: %d Mbits\n", dram_comp);
|
|
printf("DRAM bus: %d bit\n", dram_bus);
|
|
printf("Total memory: %d MBytes\n", size);
|
|
printf("%s\n", FLASH_MSG);
|
|
printf("%s\n", "Date:" __DATE__ " Time:" __TIME__ );
|
|
printf("============================================ \n");
|
|
}
|
|
#elif (defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD))
|
|
{
|
|
printf("============================================ \n");
|
|
printf("%s U-Boot Version: %s\n", RLT_MTK_VENDOR_NAME, RALINK_LOCAL_VERSION);
|
|
printf("-------------------------------------------- \n");
|
|
#ifdef RALINK_DUAL_CORE_FUN
|
|
printf("%s %s %s %s\n", CHIP_TYPE, RALINK_REG(RT2880_CHIP_REV_ID_REG)>>16&0x1 ? "MT7621A" : "MT7621N", "DualCore", GMAC_MODE);
|
|
#else
|
|
if(RALINK_REG(RT2880_CHIP_REV_ID_REG)>>17&0x1) {
|
|
printf("%s %s %s %s\n", CHIP_TYPE, RALINK_REG(RT2880_CHIP_REV_ID_REG)>>16&0x1 ? "MT7621A" : "MT7621N", "SingleCore", GMAC_MODE);
|
|
}else {
|
|
printf("%s %s%s %s\n", CHIP_TYPE, RALINK_REG(RT2880_CHIP_REV_ID_REG)>>16&0x1 ? "MT7621A" : "MT7621N", "S", GMAC_MODE);
|
|
}
|
|
#endif
|
|
printf("DRAM_CONF_FROM: %s \n", RALINK_REG(RT2880_SYSCFG_REG)>>9&0x1 ? "Auto-Detection" : "EEPROM");
|
|
printf("DRAM_TYPE: %s \n", RALINK_REG(RT2880_SYSCFG_REG)>>4&0x1 ? "DDR2": "DDR3");
|
|
printf("DRAM bus: %d bit\n", DRAM_BUS);
|
|
printf("Xtal Mode=%d OCP Ratio=%s\n", RALINK_REG(RT2880_SYSCFG_REG)>>6&0x7, RALINK_REG(RT2880_SYSCFG_REG)>>5&0x1 ? "1/4":"1/3");
|
|
printf("%s\n", FLASH_MSG);
|
|
printf("%s\n", "Date:" __DATE__ " Time:" __TIME__ );
|
|
printf("============================================ \n");
|
|
}
|
|
#else
|
|
SHOW_VER_STR();
|
|
#endif /* defined(RT3352_FPGA_BOARD) || defined (RT3352_ASIC_BOARD) || defined(RT3883_FPGA_BOARD) || defined (RT3883_ASIC_BOARD) */
|
|
|
|
|
|
|
|
#if defined (RT2880_FPGA_BOARD) || defined (RT2880_ASIC_BOARD)
|
|
value = read_32bit_cp0_register_with_select1(CP0_CONFIG);
|
|
|
|
kk = value >> 7;
|
|
kk = kk & 0x7;
|
|
|
|
if(kk)
|
|
{
|
|
debug(" D-CACHE set to %d way \n",kk + 1);
|
|
}
|
|
else
|
|
{
|
|
debug("\n D-CACHE Direct mapped\n");
|
|
}
|
|
|
|
kk = value >> 16;
|
|
kk = kk & 0x7;
|
|
|
|
|
|
if(kk)
|
|
{
|
|
debug(" I-CACHE set to %d way \n",kk + 1);
|
|
}
|
|
else
|
|
{
|
|
debug("\n I-CACHE Direct mapped\n");
|
|
}
|
|
#else
|
|
|
|
config1 = read_32bit_cp0_register_with_select1(CP0_CONFIG);
|
|
|
|
if ((lsize = ((config1 >> 19) & 7)))
|
|
icache_linesz = 2 << lsize;
|
|
else
|
|
icache_linesz = lsize;
|
|
icache_sets = 64 << ((config1 >> 22) & 7);
|
|
icache_ways = 1 + ((config1 >> 16) & 7);
|
|
|
|
icache_size = icache_sets *
|
|
icache_ways *
|
|
icache_linesz;
|
|
|
|
printf("icache: sets:%d, ways:%d, linesz:%d, total:%d\n",
|
|
icache_sets, icache_ways, icache_linesz, icache_size);
|
|
|
|
/*
|
|
* Now probe the MIPS32 / MIPS64 data cache.
|
|
*/
|
|
|
|
if ((lsize = ((config1 >> 10) & 7)))
|
|
dcache_linesz = 2 << lsize;
|
|
else
|
|
dcache_linesz = lsize;
|
|
dcache_sets = 64 << ((config1 >> 13) & 7);
|
|
dcache_ways = 1 + ((config1 >> 7) & 7);
|
|
|
|
dcache_size = dcache_sets *
|
|
dcache_ways *
|
|
dcache_linesz;
|
|
|
|
printf("dcache: sets:%d, ways:%d, linesz:%d, total:%d \n",
|
|
dcache_sets, dcache_ways, dcache_linesz, dcache_size);
|
|
|
|
#endif
|
|
|
|
debug("\n #### The CPU freq = %d MHZ #### \n", mips_cpu_feq/1000/1000);
|
|
|
|
#if defined (ON_BOARD_4096M_DRAM_COMPONENT)
|
|
debug(" estimate memory size = %d Mbytes\n", gd->ram_size/1024/1024 + 64);
|
|
#else
|
|
debug(" estimate memory size = %d Mbytes\n", gd->ram_size/1024/1024 );
|
|
#endif
|
|
|
|
LED_HIDE_ALL();
|
|
|
|
#if defined (RT3052_ASIC_BOARD) || defined (RT3052_FPGA_BOARD) || \
|
|
defined (RT3352_ASIC_BOARD) || defined (RT3352_FPGA_BOARD) || \
|
|
defined (RT5350_ASIC_BOARD) || defined (RT5350_FPGA_BOARD) || \
|
|
defined (MT7628_ASIC_BOARD) || defined (MT7628_FPGA_BOARD)
|
|
rt305x_esw_init();
|
|
#elif defined (RT6855_ASIC_BOARD) || defined (RT6855_FPGA_BOARD) || \
|
|
defined (MT7620_ASIC_BOARD) || defined (MT7620_FPGA_BOARD)
|
|
rt_gsw_init();
|
|
#elif defined (RT6855A_ASIC_BOARD) || defined (RT6855A_FPGA_BOARD)
|
|
#ifdef FPGA_BOARD
|
|
rt6855A_eth_gpio_reset();
|
|
#endif
|
|
rt6855A_gsw_init();
|
|
#elif defined (MT7621_ASIC_BOARD) || defined (MT7621_FPGA_BOARD)
|
|
setup_internal_gsw();
|
|
#elif defined (RT3883_ASIC_BOARD) && defined (MAC_TO_MT7530_MODE)
|
|
rt3883_gsw_init();
|
|
#endif
|
|
|
|
#if defined (MAC_TO_RTL8367_MODE)
|
|
extern int rtl8367_gsw_init_pre(int sw_reset);
|
|
rtl8367_gsw_init_pre(is_soft_reset);
|
|
#else
|
|
LANWANPartition();
|
|
#endif
|
|
|
|
#ifdef DUAL_IMAGE_SUPPORT
|
|
check_image_validation();
|
|
#endif
|
|
/*config bootdelay via environment parameter: bootdelay */
|
|
{
|
|
char * s;
|
|
s = getenv ("bootdelay");
|
|
timer1 = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
|
|
}
|
|
|
|
OperationSelect();
|
|
while (timer1 > 0) {
|
|
--timer1;
|
|
/* delay 100 * 10ms */
|
|
for (i=0; i<100; ++i) {
|
|
if ((my_tmp = tstc()) != 0) { /* we got a key press */
|
|
timer1 = 0; /* no more delay */
|
|
BootType = getc();
|
|
if ((BootType < '0' || BootType > '5') && (BootType != '7') && (BootType != '8') && (BootType != '9'))
|
|
BootType = '3';
|
|
printf("\n\rYou choosed %c\n\n", BootType);
|
|
break;
|
|
}
|
|
udelay (10000);
|
|
}
|
|
printf ("\b\b\b%2d ", timer1);
|
|
}
|
|
|
|
#if (CONFIG_COMMANDS & CFG_CMD_NET)
|
|
eth_initialize(gd->bd);
|
|
#endif
|
|
|
|
putc ('\n');
|
|
if(BootType == '3') {
|
|
char *argv[2];
|
|
|
|
printf(" \n%d: System Boot system code via Flash.\n", 3);
|
|
sprintf(addr_str, "0x%X", CFG_KERN_ADDR);
|
|
argv[1] = &addr_str[0];
|
|
|
|
/* prepare tftpd, check buttons, image integrity and boot */
|
|
do_tftpd(cmdtp, 0, 2, argv);
|
|
}
|
|
else {
|
|
char *argv[4];
|
|
int argc = 3;
|
|
|
|
argv[2] = &file_name_space[0];
|
|
memset(file_name_space,0,ARGV_LEN);
|
|
|
|
switch(BootType) {
|
|
case '1':
|
|
printf(" \n%d: System Load Linux to SDRAM via TFTP. \n", SEL_LOAD_LINUX_SDRAM);
|
|
tftp_config(SEL_LOAD_LINUX_SDRAM, argv);
|
|
|
|
setenv("autostart", "yes");
|
|
|
|
argc = 3;
|
|
do_tftpb(cmdtp, 0, argc, argv);
|
|
break;
|
|
|
|
case '2':
|
|
retry_kernel_tftp:
|
|
printf(" \n%d: System Load %s then write to Flash via %s. \n", SEL_LOAD_LINUX_WRITE_FLASH, "Linux", "TFTP");
|
|
printf(" Warning!! Erase %s in Flash then burn new one. Are you sure? (Y/N)\n", "Linux");
|
|
confirm = getc();
|
|
if (confirm != 'y' && confirm != 'Y') {
|
|
printf(" Operation terminated\n");
|
|
break;
|
|
}
|
|
tftp_config(SEL_LOAD_LINUX_WRITE_FLASH, argv);
|
|
|
|
setenv("autostart", "no");
|
|
|
|
argc = 3;
|
|
do_tftpb(cmdtp, 0, argc, argv);
|
|
|
|
load_address = simple_strtoul(argv[1], NULL, 16);
|
|
if (flash_kernel_image(load_address, NetBootFileXferSize) != 0)
|
|
goto retry_kernel_tftp;
|
|
|
|
#ifdef DUAL_IMAGE_SUPPORT
|
|
/* Don't do anything to the firmware upgraded in Uboot, since it may be used for testing */
|
|
setenv("Image1Stable", "1");
|
|
saveenv();
|
|
perform_system_reset();
|
|
#endif
|
|
|
|
//bootm bc050000
|
|
argc = 2;
|
|
sprintf(addr_str, "0x%X", CFG_KERN_ADDR);
|
|
argv[1] = &addr_str[0];
|
|
do_bootm(cmdtp, 0, argc, argv);
|
|
break;
|
|
|
|
#ifdef RALINK_CMDLINE
|
|
case '4':
|
|
printf(" \n%d: System Enter Boot Command Line Interface.\n", SEL_ENTER_CLI);
|
|
printf ("\n%s\n", version_string);
|
|
/* main_loop() can return to retry autoboot, if so just run it again. */
|
|
for (;;) {
|
|
main_loop ();
|
|
}
|
|
break;
|
|
#endif // RALINK_CMDLINE //
|
|
|
|
#ifdef RALINK_UPGRADE_BY_SERIAL
|
|
case '7':
|
|
retry_uboot_serial:
|
|
printf(" \n%d: System Load %s then write to Flash via %s. \n", SEL_LOAD_BOOT_WRITE_FLASH_BY_SERIAL, "Boot Loader", "Serial");
|
|
printf(" Warning!! Erase %s in Flash then burn new one. Are you sure? (Y/N)\n", "Boot Loader");
|
|
confirm = getc();
|
|
if (confirm != 'y' && confirm != 'Y') {
|
|
printf(" Operation terminated\n");
|
|
break;
|
|
}
|
|
|
|
setenv("autostart", "no");
|
|
|
|
argc = 1;
|
|
if (do_load_serial_bin(cmdtp, 0, argc, argv) == 1) {
|
|
printf("\n Download aborted!\n");
|
|
break;
|
|
}
|
|
|
|
NetBootFileXferSize = simple_strtoul(getenv("filesize"), NULL, 16);
|
|
if (check_uboot_image(CFG_LOAD_ADDR, NetBootFileXferSize) != 0)
|
|
goto retry_uboot_serial;
|
|
|
|
if (flash_uboot_image(CFG_LOAD_ADDR, NetBootFileXferSize) != 0)
|
|
goto retry_uboot_serial;
|
|
|
|
break;
|
|
|
|
case '0':
|
|
retry_kernel_serial:
|
|
printf(" \n%d: System Load %s then write to Flash via %s. \n", SEL_LOAD_LINUX_WRITE_FLASH_BY_SERIAL, "Linux", "Serial");
|
|
printf(" Warning!! Erase %s in Flash then burn new one. Are you sure? (Y/N)\n", "Linux");
|
|
confirm = getc();
|
|
if (confirm != 'y' && confirm != 'Y') {
|
|
printf(" Operation terminated\n");
|
|
break;
|
|
}
|
|
|
|
setenv("autostart", "no");
|
|
|
|
argc = 1;
|
|
if (do_load_serial_bin(cmdtp, 0, argc, argv) == 1) {
|
|
printf("\n Download aborted!\n");
|
|
break;
|
|
}
|
|
|
|
NetBootFileXferSize = simple_strtoul(getenv("filesize"), NULL, 16);
|
|
if (flash_kernel_image(CFG_LOAD_ADDR, NetBootFileXferSize) != 0)
|
|
goto retry_kernel_serial;
|
|
|
|
break;
|
|
#endif /* RALINK_UPGRADE_BY_SERIAL */
|
|
|
|
case '8':
|
|
printf(" \n%d: System Load UBoot to SDRAM via TFTP. \n", SEL_LOAD_BOOT_SDRAM);
|
|
tftp_config(SEL_LOAD_BOOT_SDRAM, argv);
|
|
setenv("autostart", "yes");
|
|
argc = 3;
|
|
do_tftpb(cmdtp, 0, argc, argv);
|
|
break;
|
|
|
|
case '9':
|
|
retry_uboot_tftp:
|
|
printf(" \n%d: System Load %s then write to Flash via %s. \n", SEL_LOAD_BOOT_WRITE_FLASH, "Boot Loader", "TFTP");
|
|
printf(" Warning!! Erase %s in Flash then burn new one. Are you sure? (Y/N)\n", "Boot Loader");
|
|
confirm = getc();
|
|
if (confirm != 'y' && confirm != 'Y') {
|
|
printf(" Operation terminated\n");
|
|
break;
|
|
}
|
|
setenv("bootfile", uboot_file);
|
|
tftp_config(SEL_LOAD_BOOT_WRITE_FLASH, argv);
|
|
setenv("autostart", "no");
|
|
|
|
argc = 3;
|
|
do_tftpb(cmdtp, 0, argc, argv);
|
|
|
|
load_address = simple_strtoul(argv[1], NULL, 16);
|
|
if (check_uboot_image(load_address, NetBootFileXferSize) != 0)
|
|
goto retry_uboot_tftp;
|
|
|
|
if (flash_uboot_image(load_address, NetBootFileXferSize) != 0)
|
|
goto retry_uboot_tftp;
|
|
|
|
break;
|
|
|
|
#if defined (RALINK_USB) || defined (MTK_USB)
|
|
case '5':
|
|
printf(" \n%d: System Load %s then write to Flash via %s. \n", SEL_LOAD_LINUX_WRITE_FLASH_BY_USB, "Linux", "USB Storage");
|
|
printf(" Warning!! Erase %s in Flash then burn new one. Are you sure? (Y/N)\n", "Linux");
|
|
confirm = getc();
|
|
if (confirm != 'y' && confirm != 'Y') {
|
|
printf(" Operation terminated\n");
|
|
break;
|
|
}
|
|
|
|
setenv("autostart", "no");
|
|
|
|
flash_kernel_image_from_usb(cmdtp);
|
|
|
|
break;
|
|
#endif // RALINK_UPGRADE_BY_USB //
|
|
|
|
default:
|
|
printf(" \nSystem Boot Linux via Flash.\n");
|
|
do_bootm(cmdtp, 0, 1, argv);
|
|
break;
|
|
} /* end of switch */
|
|
|
|
perform_system_reset();
|
|
|
|
} /* end of else */
|
|
|
|
/* NOTREACHED - no way out of command loop except booting */
|
|
}
|
|
|
|
|
|
void hang (void)
|
|
{
|
|
puts ("### ERROR ### Please RESET the board ###\n");
|
|
for (;;);
|
|
}
|
|
|
|
#if defined (RALINK_RW_RF_REG_FUN)
|
|
#if defined (MT7620_ASIC_BOARD)
|
|
#define RF_CSR_CFG 0xb0180500
|
|
#define RF_CSR_KICK (1<<0)
|
|
int rw_rf_reg(int write, int reg, int *data)
|
|
{
|
|
u32 rfcsr, i = 0;
|
|
|
|
while (1) {
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
if (! (rfcsr & (u32)RF_CSR_KICK) )
|
|
break;
|
|
if (++i > 10000) {
|
|
puts("Warning: Abort rw rf register: too busy\n");
|
|
return -1;
|
|
}
|
|
}
|
|
rfcsr = (u32)(RF_CSR_KICK | ((reg & 0x3f) << 16) | ((*data & 0xff) << 8));
|
|
if (write)
|
|
rfcsr |= 0x10;
|
|
|
|
RALINK_REG(RF_CSR_CFG) = cpu_to_le32(rfcsr);
|
|
i = 0;
|
|
while (1) {
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
if (! (rfcsr & (u32)RF_CSR_KICK) )
|
|
break;
|
|
if (++i > 10000) {
|
|
puts("Warning: still busy\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
if (((rfcsr & 0x3f0000) >> 16) != (reg & 0x3f)) {
|
|
puts("Error: rw register failed\n");
|
|
return -1;
|
|
}
|
|
*data = (int)( (rfcsr & 0xff00) >> 8) ;
|
|
return 0;
|
|
}
|
|
#else
|
|
#define RF_CSR_CFG 0xb0180500
|
|
#define RF_CSR_KICK (1<<17)
|
|
int rw_rf_reg(int write, int reg, int *data)
|
|
{
|
|
u32 rfcsr, i = 0;
|
|
|
|
while (1) {
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
if (! (rfcsr & (u32)RF_CSR_KICK) )
|
|
break;
|
|
if (++i > 10000) {
|
|
puts("Warning: Abort rw rf register: too busy\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
rfcsr = (u32)(RF_CSR_KICK | ((reg & 0x3f) << 8) | (*data & 0xff));
|
|
if (write)
|
|
rfcsr |= 0x10000;
|
|
|
|
RALINK_REG(RF_CSR_CFG) = cpu_to_le32(rfcsr);
|
|
|
|
i = 0;
|
|
while (1) {
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
if (! (rfcsr & (u32)RF_CSR_KICK) )
|
|
break;
|
|
if (++i > 10000) {
|
|
puts("Warning: still busy\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
rfcsr = RALINK_REG(RF_CSR_CFG);
|
|
|
|
if (((rfcsr&0x1f00) >> 8) != (reg & 0x1f)) {
|
|
puts("Error: rw register failed\n");
|
|
return -1;
|
|
}
|
|
*data = (int)(rfcsr & 0xff);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef RALINK_RW_RF_REG_FUN
|
|
#ifdef RALINK_CMDLINE
|
|
int do_rw_rf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|
{
|
|
int write, reg, data;
|
|
|
|
if ((argv[1][0] == 'r' || argv[1][0] == 'R') && (argc == 3)) {
|
|
write = 0;
|
|
reg = (int)simple_strtoul(argv[2], NULL, 10);
|
|
data = 0;
|
|
}
|
|
else if ((argv[1][0] == 'w' || argv[1][0] == 'W') && (argc == 4)) {
|
|
write = 1;
|
|
reg = (int)simple_strtoul(argv[2], NULL, 10);
|
|
data = (int)simple_strtoul(argv[3], NULL, 16);
|
|
}
|
|
else {
|
|
printf ("Usage:\n%s\n", cmdtp->usage);
|
|
return 1;
|
|
}
|
|
|
|
rw_rf_reg(write, reg, &data);
|
|
if (!write)
|
|
printf("rf reg <%d> = 0x%x\n", reg, data);
|
|
return 0;
|
|
}
|
|
|
|
U_BOOT_CMD(
|
|
rf, 4, 1, do_rw_rf,
|
|
"rf - read/write rf register\n",
|
|
"usage:\n"
|
|
"rf r <reg> - read rf register\n"
|
|
"rf w <reg> <data> - write rf register (reg: decimal, data: hex)\n"
|
|
);
|
|
#endif // RALINK_CMDLINE //
|
|
#endif
|
|
|
|
#if defined(RT3352_ASIC_BOARD)
|
|
void adjust_crystal_circuit(void)
|
|
{
|
|
int d = 0x45;
|
|
|
|
rw_rf_reg(1, 18, &d);
|
|
}
|
|
#endif
|
|
|
|
#if defined(RT3052_ASIC_BOARD)
|
|
/*
|
|
* Adjust core voltage to 1.2V using RF reg 26 for the 3052 two layer board.
|
|
*/
|
|
void adjust_voltage(void)
|
|
{
|
|
int d = 0x25;
|
|
rw_rf_reg(1, 26, &d);
|
|
}
|
|
|
|
void adjust_frequency(void)
|
|
{
|
|
u32 r23;
|
|
|
|
//read from EE offset 0x3A
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
ranand_read((char *)&r23, CFG_FACTORY_ADDR-CFG_FLASH_BASE+0x3a, 1);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
raspi_read((char *)&r23, CFG_FACTORY_ADDR-CFG_FLASH_BASE+0x3a, 1);
|
|
#else //CFG_ENV_IS_IN_FLASH
|
|
r23 = *(volatile u32 *)(CFG_FACTORY_ADDR+0x38);
|
|
r23 >>= 16;
|
|
#endif
|
|
r23 &= 0xff;
|
|
//write to RF R23
|
|
rw_rf_reg(1, 23, &r23);
|
|
}
|
|
#endif
|
|
|
|
#if defined (RT3352_ASIC_BOARD) || defined (RT3883_ASIC_BOARD)
|
|
void adjust_rf_r17(void)
|
|
{
|
|
u32 r17;
|
|
u32 i;
|
|
u32 val;
|
|
u32 r17_offs = 0x3a;
|
|
u32 j = 0;
|
|
|
|
#if defined (RT3883_ASIC_BOARD)
|
|
r17_offs = 0x44;
|
|
#endif
|
|
|
|
//read from EE offset 0x3A
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
ranand_read((char *)&r17, CFG_FACTORY_ADDR-CFG_FLASH_BASE+r17_offs, 1);
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
raspi_read((char *)&r17, CFG_FACTORY_ADDR-CFG_FLASH_BASE+r17_offs, 1);
|
|
#else
|
|
r17 = *(volatile u32 *)(CFG_FACTORY_ADDR+r17_offs);
|
|
#endif
|
|
r17 &= 0xff;
|
|
|
|
if ((r17 == 0) || (r17 == 0xff)){
|
|
r17 = 0x26;
|
|
}
|
|
|
|
if(r17 <= 0xf) {
|
|
for(i=1; i<=r17; i++) {
|
|
//write to RF R17
|
|
val = i;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
}
|
|
else{
|
|
for(i=1; i<=0xf; i++) {
|
|
//write to RF R17
|
|
val = i;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
val = 0x1f;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
|
|
if(r17 <= 0x1f) {
|
|
for(i=0x1e; i>=r17; i--) {
|
|
//write to RF R17
|
|
val = i;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
} else if((r17 > 0x1f) && (r17 <=0x2f)){
|
|
for(i=0x2f; i>=r17; i--) {
|
|
//write to RF R17
|
|
val = i;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
}else {
|
|
val = 0x2f;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
if((r17 > 0x2f) && (r17 <= 0x3f)){
|
|
for(i=0x3f; i>=r17; i--) {
|
|
//write to RF R17
|
|
val = i;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
}
|
|
if(r17 > 0x3f){
|
|
val = 0x3f;
|
|
val |= 1 << 7;
|
|
rw_rf_reg(1, 17, &val);
|
|
udelay(2000);
|
|
//rw_rf_reg(0, 17, &val);
|
|
//printf("Only Update RF_R17 to 0x%0X\n", val);
|
|
}
|
|
}
|
|
|
|
// rw_rf_reg(0, 17, &val);
|
|
// printf("Read RF_R17 = 0x%0X\n", val);
|
|
}
|
|
#endif
|
|
|
|
#if defined(RT3883_ASIC_BOARD) || defined(RT3352_ASIC_BOARD) || \
|
|
defined(RT5350_ASIC_BOARD) || defined(RT6855_ASIC_BOARD) || \
|
|
defined(MT7620_ASIC_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
/*
|
|
* enter power saving mode
|
|
*/
|
|
void config_usb_ehciohci(void)
|
|
{
|
|
u32 val;
|
|
|
|
val = RALINK_REG(RT2880_RSTCTRL_REG); // toggle host & device RST bit
|
|
val |= RALINK_UHST_RST | RALINK_UDEV_RST;
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
|
|
val = RALINK_REG(RT2880_CLKCFG1_REG);
|
|
#if defined(RT5350_ASIC_BOARD) || defined(RT6855_ASIC_BOARD)
|
|
val &= ~(RALINK_UPHY0_CLK_EN) ; // disable USB port0 PHY.
|
|
#else
|
|
val &= ~(RALINK_UPHY0_CLK_EN | RALINK_UPHY1_CLK_EN); // disable USB port0 & port1 PHY.
|
|
#endif
|
|
RALINK_REG(RT2880_CLKCFG1_REG) = val;
|
|
}
|
|
#endif /* (RT3883_ASIC_BOARD) || defined(RT3352_ASIC_BOARD)|| defined(RT5350_ASIC_BOARD) || defined(RT6855_ASIC_BOARD) || defined (MT7620_ASIC_BOARD) */
|
|
|
|
|
|
#if defined(MT7621_ASIC_BOARD)
|
|
void config_usb_mtk_xhci(void)
|
|
{
|
|
u32 regValue;
|
|
|
|
regValue = RALINK_REG(RALINK_SYSCTL_BASE + 0x10);
|
|
regValue = (regValue >> 6) & 0x7;
|
|
if(regValue >= 6) { //25Mhz Xtal
|
|
printf("\nConfig XHCI 25M PLL \n");
|
|
RALINK_REG(0xbe1d0784) = 0x20201a;
|
|
RALINK_REG(0xbe1d0c20) = 0x80004;
|
|
RALINK_REG(0xbe1d0c1c) = 0x18181819;
|
|
RALINK_REG(0xbe1d0c24) = 0x18000000;
|
|
RALINK_REG(0xbe1d0c38) = 0x25004a;
|
|
RALINK_REG(0xbe1d0c40) = 0x48004a;
|
|
RALINK_REG(0xbe1d0b24) = 0x190;
|
|
RALINK_REG(0xbe1d0b10) = 0x1c000000;
|
|
RALINK_REG(0xbe1d0b04) = 0x20000004;
|
|
RALINK_REG(0xbe1d0b08) = 0xf203200;
|
|
|
|
RALINK_REG(0xbe1d0b2c) = 0x1400028;
|
|
//RALINK_REG(0xbe1d0a30) =;
|
|
RALINK_REG(0xbe1d0a40) = 0xffff0001;
|
|
RALINK_REG(0xbe1d0a44) = 0x60001;
|
|
} else if (regValue >=3 ) { // 40 Mhz
|
|
printf("\nConfig XHCI 40M PLL \n");
|
|
RALINK_REG(0xbe1d0784) = 0x20201a;
|
|
RALINK_REG(0xbe1d0c20) = 0x80104;
|
|
RALINK_REG(0xbe1d0c1c) = 0x1818181e;
|
|
RALINK_REG(0xbe1d0c24) = 0x1e400000;
|
|
RALINK_REG(0xbe1d0c38) = 0x250073;
|
|
RALINK_REG(0xbe1d0c40) = 0x71004a;
|
|
RALINK_REG(0xbe1d0b24) = 0x140;
|
|
RALINK_REG(0xbe1d0b10) = 0x23800000;
|
|
RALINK_REG(0xbe1d0b04) = 0x20000005;
|
|
RALINK_REG(0xbe1d0b08) = 0x12203200;
|
|
|
|
RALINK_REG(0xbe1d0b2c) = 0x1400028;
|
|
//RALINK_REG(0xbe1d0a30) =;
|
|
RALINK_REG(0xbe1d0a40) = 0xffff0001;
|
|
RALINK_REG(0xbe1d0a44) = 0x60001;
|
|
} else { //20Mhz Xtal
|
|
|
|
/* TODO */
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined(RT3052_ASIC_BOARD) || defined(RT2883_ASIC_BOARD)
|
|
int usbotg_host_suspend(void)
|
|
{
|
|
u32 val;
|
|
int i, rc=0, retry_count=0;
|
|
|
|
printf(".");
|
|
|
|
retry_suspend:
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
val = val >> 10;
|
|
val = val & 0x00000003;
|
|
|
|
if(val == 0x3){
|
|
if(retry_count++ < 0x100000)
|
|
goto retry_suspend;
|
|
printf("*** Error: D+/D- is 1/1, config usb failed.\n");
|
|
return -1;
|
|
}
|
|
//printf("Config usb otg 2\n");
|
|
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0400));
|
|
//printf("1.b01c0400 = 0x%08x\n", val);
|
|
//printf("force \"FS-LS only mode\"\n");
|
|
val = val | (1 << 2);
|
|
*(volatile u_long *)(0xB01C0400) = cpu_to_le32(val);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0400));
|
|
//printf("2.b01c0400 = 0x%08x\n", val);
|
|
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("3.b01c0440 = 0x%08x\n", val);
|
|
|
|
//printf("port power on\n");
|
|
val = val | (1 << 12);
|
|
*(volatile u_long *)(0xB01C0440) = cpu_to_le32(val);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("4.b01c0440 = 0x%08x\n", val);
|
|
|
|
udelay(3000); // 3ms
|
|
|
|
////printf("check port connect status\n");
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
////printf("5.b01c0440 = 0x%08x\n", val);
|
|
|
|
////printf("port reset --set\n");
|
|
val = val | (1 << 8);
|
|
*(volatile u_long *)(0xB01C0440) = cpu_to_le32(val);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("6.b01c0440 = 0x%08x\n", val);
|
|
|
|
udelay(10000);
|
|
|
|
//printf("port reset -- clear\n");
|
|
val = val & ~(1 << 8);
|
|
*(volatile u_long *)(0xB01C0440) = cpu_to_le32(val);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("7.b01c0440 = 0x%08x\n", val);
|
|
|
|
udelay(1000);
|
|
|
|
//printf("port suspend --set\n");
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("b.b01c0440 = 0x%08x\n", val);
|
|
val = val | (1 << 7);
|
|
/* avoid write 1 to port enable */
|
|
val = val & 0xFFFFFFF3;
|
|
|
|
*(volatile u_long *)(0xB01C0440) = cpu_to_le32(val);
|
|
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("c.b01c0440 = 0x%08x\n", val);
|
|
|
|
//printf(" stop pclk\n");
|
|
*(volatile u_long *)(0xB01C0E00) = cpu_to_le32(0x1);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0E00));
|
|
//printf("8.b01c0e00 = 0x%08x\n", val);
|
|
|
|
//printf("wait for suspend...");
|
|
for(i=0; i<200000; i++){
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
val = val & (1 << 7);
|
|
if(val)
|
|
break; // done.
|
|
udelay(1);
|
|
}
|
|
|
|
if(i==200000){
|
|
//printf("timeout, ignore...(0x%08x)\n", val);
|
|
rc = -1;
|
|
}
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0440));
|
|
//printf("val = 0x%08x\n", val);
|
|
udelay(100000);
|
|
|
|
val = RALINK_REG(RT2880_RSTCTRL_REG); // reset OTG
|
|
val = val | RALINK_OTG_RST;
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
val = val & ~(RALINK_OTG_RST);
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
udelay(200000);
|
|
|
|
udelay(200000);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
int usbotg_device_suspend(void)
|
|
{
|
|
u32 val;
|
|
int rc = -1, try_count;
|
|
|
|
printf(".");
|
|
|
|
RALINK_REG(0xB01C0E00) = 0xF;
|
|
udelay(100000);
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0808));
|
|
//printf("B01c0808 = 0x%08x\n", val);
|
|
|
|
RALINK_REG(0xB01C000C) = 0x40001408; // force device mode
|
|
udelay(50000);
|
|
RALINK_REG(0xB01C0E00) = 0x1; // stop pclock
|
|
udelay(100000);
|
|
|
|
/* Some layouts need more time. */
|
|
for(try_count=0 ; try_count< 1000 /* ms */; try_count++)
|
|
{
|
|
val = le32_to_cpu(*(volatile u_long *)(0xB01C0808));
|
|
//printf("B01C0808 = 0x%08x\n", val);
|
|
if((val & 0x1)){
|
|
rc = 0;
|
|
break;
|
|
}
|
|
udelay(1000);
|
|
}
|
|
|
|
val = RALINK_REG(RT2880_RSTCTRL_REG); // reset OTG
|
|
val = val | RALINK_OTG_RST;
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
val = val & ~(RALINK_OTG_RST);
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
udelay(200000);
|
|
|
|
return rc;
|
|
}
|
|
|
|
void config_usbotg(void)
|
|
{
|
|
int i, host_rc, device_rc;
|
|
|
|
printf("config usb");
|
|
for(i=0;i<2;i++){
|
|
device_rc = usbotg_device_suspend();
|
|
host_rc = usbotg_host_suspend();
|
|
|
|
if(host_rc == -1 && device_rc == -1)
|
|
continue;
|
|
else
|
|
break;
|
|
}
|
|
|
|
RALINK_REG(0xB01C0E00) = 0xF; //disable USB module, optimize for power-saving
|
|
printf("\n");
|
|
return;
|
|
}
|
|
|
|
#endif
|
|
|
|
#if defined (RT6855A_ASIC_BOARD) || defined(RT6855A_FPGA_BOARD)
|
|
static int watchdog_reset()
|
|
{
|
|
unsigned int word;
|
|
unsigned int i;
|
|
|
|
/* check if do watch dog reset */
|
|
if ((RALINK_REG(RALINK_HIR_REG) & 0xffff0000) == 0x40000) {
|
|
if (!(RALINK_REG(0xbfb00080) >> 31)) {
|
|
/* set delay counter */
|
|
RALINK_REG(RALINK_TIMER5_LDV) = 1000;
|
|
/* enable watch dog timer */
|
|
word = RALINK_REG(RALINK_TIMER_CTL);
|
|
word |= ((1 << 5) | (1 << 25));
|
|
RALINK_REG(RALINK_TIMER_CTL) = word;
|
|
while(1);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
#if defined (MT7620_ASIC_BOARD) || defined (MT7628_ASIC_BOARD)
|
|
void disable_pcie(void)
|
|
{
|
|
u32 val;
|
|
|
|
val = RALINK_REG(RT2880_RSTCTRL_REG); // assert RC RST
|
|
val |= RALINK_PCIE0_RST;
|
|
RALINK_REG(RT2880_RSTCTRL_REG) = val;
|
|
|
|
#if defined (MT7628_ASIC_BOARD)
|
|
val = RALINK_REG(RT2880_CLKCFG1_REG); // disable PCIe clock
|
|
val &= ~RALINK_PCIE_CLK_EN;
|
|
RALINK_REG(RT2880_CLKCFG1_REG) = val;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#if defined (CONFIG_DDR_CAL)
|
|
#include <asm-mips/mipsregs.h>
|
|
#include <asm-mips/cacheops.h>
|
|
#include <asm/mipsregs.h>
|
|
#include <asm/cache.h>
|
|
|
|
#if defined (CONFIG_TINY_UBOOT)
|
|
__attribute__((nomips16))
|
|
#endif
|
|
static inline void cal_memcpy(void* src, void* dst, unsigned int size)
|
|
{
|
|
int i;
|
|
unsigned char* psrc = (unsigned char*)src, *pdst=(unsigned char*)dst;
|
|
for (i = 0; i < size; i++, psrc++, pdst++)
|
|
(*pdst) = (*psrc);
|
|
return;
|
|
}
|
|
#if defined (CONFIG_TINY_UBOOT)
|
|
__attribute__((nomips16))
|
|
#endif
|
|
static inline void cal_memset(void* src, unsigned char pat, unsigned int size)
|
|
{
|
|
int i;
|
|
unsigned char* psrc = (unsigned char*)src;
|
|
for (i = 0; i < size; i++, psrc++)
|
|
(*psrc) = pat;
|
|
return;
|
|
}
|
|
|
|
#define pref_op(hint,addr) \
|
|
__asm__ __volatile__( \
|
|
" .set push \n" \
|
|
" .set noreorder \n" \
|
|
" pref %0, %1 \n" \
|
|
" .set pop \n" \
|
|
: \
|
|
: "i" (hint), "R" (*(unsigned char *)(addr)))
|
|
|
|
#define cache_op(op,addr) \
|
|
__asm__ __volatile__( \
|
|
" .set push \n" \
|
|
" .set noreorder \n" \
|
|
" .set mips3\n\t \n" \
|
|
" cache %0, %1 \n" \
|
|
" .set pop \n" \
|
|
: \
|
|
: "i" (op), "R" (*(unsigned char *)(addr)))
|
|
|
|
__attribute__((nomips16)) static void inline cal_invalidate_dcache_range(ulong start_addr, ulong stop)
|
|
{
|
|
unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
|
|
unsigned long addr = start_addr & ~(lsize - 1);
|
|
unsigned long aend = (stop - 1) & ~(lsize - 1);
|
|
|
|
while (1) {
|
|
cache_op(HIT_INVALIDATE_D, addr);
|
|
if (addr == aend)
|
|
break;
|
|
addr += lsize;
|
|
}
|
|
}
|
|
|
|
#if defined (CONFIG_TINY_UBOOT)
|
|
__attribute__((nomips16))
|
|
#endif
|
|
static void inline cal_patgen(unsigned long* start_addr, unsigned int size, unsigned bias)
|
|
{
|
|
int i = 0;
|
|
for (i = 0; i < size; i++)
|
|
start_addr[i] = ((ulong)start_addr+i+bias);
|
|
|
|
return;
|
|
}
|
|
|
|
#define NUM_OF_CACHELINE 128
|
|
#define MIN_START 6
|
|
#define MIN_FINE_START 0xF
|
|
#define MAX_START 7
|
|
#define MAX_FINE_START 0x0
|
|
#define cal_debug debug
|
|
|
|
#define HWDLL_FIXED 1
|
|
#if defined (HWDLL_FIXED)
|
|
#define DU_COARSE_WIDTH 16
|
|
#define DU_FINE_WIDTH 16
|
|
#define C2F_RATIO 8
|
|
#define HWDLL_AVG 1
|
|
#define HWDLL_LV 1
|
|
//#define HWDLL_HV 1
|
|
#define HWDLL_MINSCAN 1
|
|
#endif
|
|
|
|
#define MAX_TEST_LOOP 8
|
|
|
|
__attribute__((nomips16)) void dram_cali(void)
|
|
{
|
|
#if defined(ON_BOARD_64M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x800000
|
|
#endif
|
|
#if defined(ON_BOARD_128M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x1000000
|
|
#endif
|
|
#if defined(ON_BOARD_256M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x2000000
|
|
#endif
|
|
#if defined(ON_BOARD_512M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x4000000
|
|
#endif
|
|
#if defined(ON_BOARD_1024M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x8000000
|
|
#endif
|
|
#if defined(ON_BOARD_2048M_DRAM_COMPONENT)
|
|
#define DRAM_BUTTOM 0x10000000
|
|
#endif
|
|
|
|
unsigned int * nc_addr = 0xA0000000+DRAM_BUTTOM-0x0400;
|
|
unsigned int * c_addr = 0x80000000+DRAM_BUTTOM-0x0400;
|
|
unsigned int min_coarse_dqs[2];
|
|
unsigned int max_coarse_dqs[2];
|
|
unsigned int min_fine_dqs[2];
|
|
unsigned int max_fine_dqs[2];
|
|
unsigned int coarse_dqs[2];
|
|
unsigned int fine_dqs[2];
|
|
unsigned int min_dqs[2];
|
|
unsigned int max_dqs[2];
|
|
unsigned int total_min_comp_dqs[2];
|
|
unsigned int total_max_comp_dqs[2];
|
|
unsigned int avg_min_cg_comp_dqs[2];
|
|
unsigned int avg_max_cg_comp_dqs[2];
|
|
unsigned int avg_min_fg_comp_dqs[2];
|
|
unsigned int avg_max_fg_comp_dqs[2];
|
|
unsigned int min_comp_dqs[2][MAX_TEST_LOOP];
|
|
unsigned int max_comp_dqs[2][MAX_TEST_LOOP];
|
|
unsigned int reg = 0, ddr_cfg2_reg = 0, dqs_dly_reg = 0;
|
|
unsigned int reg_avg = 0, reg_with_dll = 0, hw_dll_reg = 0;
|
|
int ret = 0;
|
|
int flag = 0, min_failed_pos[2], max_failed_pos[2], min_fine_failed_pos[2], max_fine_failed_pos[2];
|
|
int i,j, k;
|
|
int dqs = 0;
|
|
unsigned int min_coarse_dqs_bnd, min_fine_dqs_bnd, coarse_dqs_dll, fine_dqs_dll;
|
|
unsigned int reg_minscan = 0;
|
|
unsigned int avg_cg_dly[2],avg_fg_dly[2];
|
|
unsigned int g_min_coarse_dqs_dly[2], g_min_fine_dqs_dly[2];
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
unsigned int cid = (RALINK_REG(RALINK_SYSCTL_BASE+0xC)>>16)&0x01;
|
|
#endif
|
|
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
#else
|
|
unsigned int cache_pat[8*40];
|
|
#endif
|
|
u32 value, test_count = 0;;
|
|
u32 fdiv = 0, step = 0, frac = 0;
|
|
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = (unsigned long)((value>>8)&0x0F);
|
|
if ((CPU_FRAC_DIV < 1) || (CPU_FRAC_DIV > 10))
|
|
frac = (unsigned long)(value&0x0F);
|
|
else
|
|
frac = CPU_FRAC_DIV;
|
|
i = 0;
|
|
|
|
while(frac < fdiv) {
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = ((value>>8)&0x0F);
|
|
fdiv--;
|
|
value &= ~(0x0F<<8);
|
|
value |= (fdiv<<8);
|
|
RALINK_REG(RALINK_DYN_CFG0_REG) = value;
|
|
udelay(500);
|
|
i++;
|
|
value = RALINK_REG(RALINK_DYN_CFG0_REG);
|
|
fdiv = ((value>>8)&0x0F);
|
|
}
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
#else
|
|
cal_memcpy(cache_pat, dram_patterns, 32*6);
|
|
cal_memcpy(cache_pat+32*6, line_toggle_pattern, 32);
|
|
cal_memcpy(cache_pat+32*6+32, pattern_ken, 32*13);
|
|
#endif
|
|
|
|
#if defined (HWDLL_LV)
|
|
#if defined (HWDLL_HV)
|
|
RALINK_REG(RALINK_RGCTRL_BASE+0x108) = 0x01300;
|
|
mdelay(100);
|
|
#else
|
|
//RALINK_REG(RALINK_RGCTRL_BASE+0x108) = 0x0F00;//0x0d00;//0x0b00;
|
|
#endif
|
|
//cal_debug("\nSet [0x10001108]=%08X\n",RALINK_REG(RALINK_RGCTRL_BASE+0x108));
|
|
//mdelay(100);
|
|
#endif
|
|
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x10) &= ~(0x1<<4);
|
|
#else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x18) = &= ~(0x1<<4);
|
|
#endif
|
|
ddr_cfg2_reg = RALINK_REG(RALINK_MEMCTRL_BASE+0x48);
|
|
dqs_dly_reg = RALINK_REG(RALINK_MEMCTRL_BASE+0x64);
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x48)&=(~((0x3<<28)|(0x3<<26)));
|
|
|
|
total_min_comp_dqs[0] = 0;
|
|
total_min_comp_dqs[1] = 0;
|
|
total_max_comp_dqs[0] = 0;
|
|
total_max_comp_dqs[1] = 0;
|
|
TEST_LOOP:
|
|
min_coarse_dqs[0] = MIN_START;
|
|
min_coarse_dqs[1] = MIN_START;
|
|
min_fine_dqs[0] = MIN_FINE_START;
|
|
min_fine_dqs[1] = MIN_FINE_START;
|
|
max_coarse_dqs[0] = MAX_START;
|
|
max_coarse_dqs[1] = MAX_START;
|
|
max_fine_dqs[0] = MAX_FINE_START;
|
|
max_fine_dqs[1] = MAX_FINE_START;
|
|
min_failed_pos[0] = 0xFF;
|
|
min_fine_failed_pos[0] = 0;
|
|
min_failed_pos[1] = 0xFF;
|
|
min_fine_failed_pos[1] = 0;
|
|
max_failed_pos[0] = 0xFF;
|
|
max_fine_failed_pos[0] = 0;
|
|
max_failed_pos[1] = 0xFF;
|
|
max_fine_failed_pos[1] = 0;
|
|
dqs = 0;
|
|
|
|
// Add by KP, DQS MIN boundary
|
|
reg = RALINK_REG(RALINK_MEMCTRL_BASE+0x20);
|
|
coarse_dqs_dll = (reg & 0xF00) >> 8;
|
|
fine_dqs_dll = (reg & 0xF0) >> 4;
|
|
if (coarse_dqs_dll<=8)
|
|
min_coarse_dqs_bnd = 8 - coarse_dqs_dll;
|
|
else
|
|
min_coarse_dqs_bnd = 0;
|
|
|
|
if (fine_dqs_dll<=8)
|
|
min_fine_dqs_bnd = 8 - fine_dqs_dll;
|
|
else
|
|
min_fine_dqs_bnd = 0;
|
|
// DQS MIN boundary
|
|
|
|
DQS_CAL:
|
|
flag = 0;
|
|
j = 0;
|
|
|
|
for (k = 0; k < 2; k ++)
|
|
{
|
|
unsigned int test_dqs, failed_pos = 0;
|
|
if (k == 0)
|
|
test_dqs = MAX_START;
|
|
else
|
|
test_dqs = MAX_FINE_START;
|
|
flag = 0;
|
|
do
|
|
{
|
|
flag = 0;
|
|
for (nc_addr = 0xA0000000; nc_addr < (0xA0000000+DRAM_BUTTOM-NUM_OF_CACHELINE*32); nc_addr+=((DRAM_BUTTOM>>6)+1*0x400))
|
|
{
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00007474;
|
|
wmb();
|
|
c_addr = (unsigned int*)((ulong)nc_addr & 0xDFFFFFFF);
|
|
cal_memset(((unsigned char*)c_addr), 0x1F, NUM_OF_CACHELINE*32);
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
cal_patgen(nc_addr, NUM_OF_CACHELINE*8, 3);
|
|
#else
|
|
cal_memcpy(((unsigned char*)nc_addr), ((unsigned char*)cache_pat), NUM_OF_CACHELINE*32);
|
|
#endif
|
|
|
|
if (dqs > 0)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00000074|(((k==1) ? max_coarse_dqs[dqs] : test_dqs)<<12)|(((k==0) ? 0xF : test_dqs)<<8);
|
|
else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00007400|(((k==1) ? max_coarse_dqs[dqs] : test_dqs)<<4)|(((k==0) ? 0xF : test_dqs)<<0);
|
|
wmb();
|
|
|
|
cal_invalidate_dcache_range(((unsigned char*)c_addr), ((unsigned char*)c_addr)+NUM_OF_CACHELINE*32);
|
|
wmb();
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
if (i % 8 ==0)
|
|
pref_op(0, &c_addr[i]);
|
|
}
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
if (c_addr[i] != (ulong)nc_addr+i+3)
|
|
#else
|
|
if (c_addr[i] != cache_pat[i])
|
|
#endif
|
|
{
|
|
flag = -1;
|
|
failed_pos = i;
|
|
goto MAX_FAILED;
|
|
}
|
|
}
|
|
}
|
|
MAX_FAILED:
|
|
if (flag==-1)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
test_dqs++;
|
|
}while(test_dqs<=0xF);
|
|
|
|
if (k==0)
|
|
{
|
|
max_coarse_dqs[dqs] = test_dqs;
|
|
max_failed_pos[dqs] = failed_pos;
|
|
}
|
|
else
|
|
{
|
|
test_dqs--;
|
|
|
|
if (test_dqs==MAX_FINE_START-1)
|
|
{
|
|
max_coarse_dqs[dqs]--;
|
|
max_fine_dqs[dqs] = 0xF;
|
|
}
|
|
else
|
|
{
|
|
max_fine_dqs[dqs] = test_dqs;
|
|
}
|
|
max_fine_failed_pos[dqs] = failed_pos;
|
|
}
|
|
}
|
|
|
|
for (k = 0; k < 2; k ++)
|
|
{
|
|
unsigned int test_dqs, failed_pos = 0;
|
|
if (k == 0)
|
|
test_dqs = MIN_START;
|
|
else
|
|
test_dqs = MIN_FINE_START;
|
|
flag = 0;
|
|
do
|
|
{
|
|
for (nc_addr = 0xA0000000; nc_addr < (0xA0000000+DRAM_BUTTOM-NUM_OF_CACHELINE*32); (nc_addr+=(DRAM_BUTTOM>>6)+1*0x480))
|
|
{
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00007474;
|
|
wmb();
|
|
c_addr = (unsigned int*)((ulong)nc_addr & 0xDFFFFFFF);
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00007474;
|
|
wmb();
|
|
cal_memset(((unsigned char*)c_addr), 0x1F, NUM_OF_CACHELINE*32);
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
cal_patgen(nc_addr, NUM_OF_CACHELINE*8, 1);
|
|
#else
|
|
cal_memcpy(((unsigned char*)nc_addr), ((unsigned char*)cache_pat), NUM_OF_CACHELINE*32);
|
|
#endif
|
|
if (dqs > 0)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00000074|(((k==1) ? min_coarse_dqs[dqs] : test_dqs)<<12)|(((k==0) ? 0x0 : test_dqs)<<8);
|
|
else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = 0x00007400|(((k==1) ? min_coarse_dqs[dqs] : test_dqs)<<4)|(((k==0) ? 0x0 : test_dqs)<<0);
|
|
wmb();
|
|
cal_invalidate_dcache_range(((unsigned char*)c_addr), ((unsigned char*)c_addr)+NUM_OF_CACHELINE*32);
|
|
wmb();
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
if (i % 8 ==0)
|
|
pref_op(0, &c_addr[i]);
|
|
}
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
if (c_addr[i] != (ulong)nc_addr+i+1)
|
|
#else
|
|
if (c_addr[i] != cache_pat[i])
|
|
#endif
|
|
{
|
|
flag = -1;
|
|
failed_pos = i;
|
|
goto MIN_FAILED;
|
|
}
|
|
}
|
|
}
|
|
|
|
MIN_FAILED:
|
|
|
|
if (k==0)
|
|
{
|
|
if ((flag==-1)||(test_dqs==min_coarse_dqs_bnd))
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
test_dqs--;
|
|
|
|
if (test_dqs < min_coarse_dqs_bnd)
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (flag==-1)
|
|
{
|
|
test_dqs++;
|
|
break;
|
|
}
|
|
else if (test_dqs==min_fine_dqs_bnd)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
test_dqs--;
|
|
}
|
|
|
|
if (test_dqs < min_fine_dqs_bnd)
|
|
break;
|
|
|
|
}
|
|
}while(test_dqs>=0);
|
|
|
|
if (k==0)
|
|
{
|
|
min_coarse_dqs[dqs] = test_dqs;
|
|
min_failed_pos[dqs] = failed_pos;
|
|
}
|
|
else
|
|
{
|
|
if (test_dqs==MIN_FINE_START+1)
|
|
{
|
|
min_coarse_dqs[dqs]++;
|
|
min_fine_dqs[dqs] = 0x0;
|
|
}
|
|
else
|
|
{
|
|
min_fine_dqs[dqs] = test_dqs;
|
|
}
|
|
min_fine_failed_pos[dqs] = failed_pos;
|
|
}
|
|
}
|
|
|
|
min_comp_dqs[dqs][test_count] = (8-min_coarse_dqs[dqs])*8+(8-min_fine_dqs[dqs]);
|
|
total_min_comp_dqs[dqs] += min_comp_dqs[dqs][test_count];
|
|
max_comp_dqs[dqs][test_count] = (max_coarse_dqs[dqs]-8)*8+(max_fine_dqs[dqs]-8);
|
|
total_max_comp_dqs[dqs] += max_comp_dqs[dqs][test_count];
|
|
|
|
if (max_comp_dqs[dqs][test_count]+ min_comp_dqs[dqs][test_count] <=(2*8))
|
|
{
|
|
reg_minscan = 0x18180000;
|
|
reg_with_dll = 0x88880000;
|
|
g_min_coarse_dqs_dly[0] = g_min_coarse_dqs_dly[1] = 0;
|
|
g_min_fine_dqs_dly[0] = g_min_fine_dqs_dly[1] = 0;
|
|
hw_dll_reg = RALINK_REG(RALINK_MEMCTRL_BASE+0x20);
|
|
goto FINAL_SETUP;
|
|
}
|
|
|
|
if (dqs==0)
|
|
{
|
|
dqs = 1;
|
|
goto DQS_CAL;
|
|
}
|
|
|
|
for (i=0 ; i < 2; i++)
|
|
{
|
|
unsigned int temp;
|
|
coarse_dqs[i] = (max_coarse_dqs[i] + min_coarse_dqs[i])>>1;
|
|
temp = (((max_coarse_dqs[i] + min_coarse_dqs[i])%2)*4) + ((max_fine_dqs[i] + min_fine_dqs[i])>>1);
|
|
if (temp >= 0x10)
|
|
{
|
|
coarse_dqs[i] ++;
|
|
fine_dqs[i] = (temp-0x10) +0x8;
|
|
}
|
|
else
|
|
{
|
|
fine_dqs[i] = temp;
|
|
}
|
|
}
|
|
reg = (coarse_dqs[1]<<12)|(fine_dqs[1]<<8)|(coarse_dqs[0]<<4)|fine_dqs[0];
|
|
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
if (cid == 1)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x10) &= ~(0x1<<4);
|
|
#else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x18) = &= ~(0x1<<4);
|
|
#endif
|
|
if (cid == 1) {
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = reg;
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x48) = ddr_cfg2_reg;
|
|
}
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
if (cid == 1)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x10) |= (0x1<<4);
|
|
#else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x18) |= (0x1<<4);
|
|
#endif
|
|
|
|
test_count++;
|
|
|
|
|
|
FINAL:
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
if (cid==1)
|
|
#endif
|
|
{
|
|
for (j = 0; j < 2; j++)
|
|
cal_debug("[%02X%02X%02X%02X]",min_coarse_dqs[j],min_fine_dqs[j], max_coarse_dqs[j],max_fine_dqs[j]);
|
|
cal_debug("\nDDR Calibration DQS reg = %08X\n",reg);
|
|
goto EXIT;
|
|
}
|
|
if (test_count < MAX_TEST_LOOP)
|
|
goto TEST_LOOP;
|
|
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
unsigned int min_count = MAX_TEST_LOOP;
|
|
unsigned int max_count = MAX_TEST_LOOP;
|
|
|
|
unsigned int tmp_min_comp_dqs = total_min_comp_dqs[j]>>3;
|
|
unsigned int tmp_total_min_comp_dqs = total_min_comp_dqs[j];
|
|
|
|
unsigned int tmp_max_comp_dqs = total_max_comp_dqs[j]>>3;
|
|
unsigned int tmp_total_max_comp_dqs = total_max_comp_dqs[j];
|
|
|
|
for (k = 0; k < MAX_TEST_LOOP; k++)
|
|
{
|
|
int diff_min = ((tmp_min_comp_dqs-min_comp_dqs[j][k]) > 0) ? (tmp_min_comp_dqs-min_comp_dqs[j][k]) : (min_comp_dqs[j][k]-tmp_min_comp_dqs);
|
|
int diff_max = ((tmp_max_comp_dqs-max_comp_dqs[j][k]) > 0) ? (tmp_max_comp_dqs-max_comp_dqs[j][k]) : (max_comp_dqs[j][k]-tmp_max_comp_dqs);
|
|
|
|
if (diff_min > 5)
|
|
{
|
|
//cal_debug("remove the %d min comp dqs %d (%d)\n" ,k ,min_comp_dqs[j][k],tmp_min_comp_dqs);
|
|
tmp_total_min_comp_dqs-= min_comp_dqs[j][k];
|
|
tmp_total_min_comp_dqs += tmp_min_comp_dqs;
|
|
min_count--;
|
|
}
|
|
if (diff_max > 5)
|
|
{
|
|
//cal_debug("remove the %d (diff=%d) max comp dqs %d (%d)\n" ,k ,diff_max,max_comp_dqs[j][k],tmp_max_comp_dqs);
|
|
tmp_total_max_comp_dqs-= max_comp_dqs[j][k];
|
|
tmp_total_max_comp_dqs += tmp_max_comp_dqs;
|
|
max_count--;
|
|
}
|
|
}
|
|
tmp_min_comp_dqs = tmp_total_min_comp_dqs>>3;
|
|
avg_min_cg_comp_dqs[j] = 8-(tmp_min_comp_dqs>>3);
|
|
avg_min_fg_comp_dqs[j] = 8-(tmp_min_comp_dqs&0x7);
|
|
|
|
tmp_max_comp_dqs = tmp_total_max_comp_dqs>>3;
|
|
avg_max_cg_comp_dqs[j] = 8+(tmp_max_comp_dqs>>3);
|
|
avg_max_fg_comp_dqs[j] = 8+(tmp_max_comp_dqs&0x7);
|
|
|
|
}
|
|
//cal_debug("\n\r");
|
|
//for (j = 0; j < 2; j++)
|
|
// cal_debug("[%02X%02X%02X%02X]", avg_min_cg_comp_dqs[j],avg_min_fg_comp_dqs[j], avg_max_cg_comp_dqs[j],avg_max_fg_comp_dqs[j]);
|
|
|
|
for (i=0 ; i < 2; i++)
|
|
{
|
|
unsigned int temp;
|
|
coarse_dqs[i] = (avg_max_cg_comp_dqs[i] + avg_min_cg_comp_dqs[i])>>1;
|
|
temp = (((avg_max_cg_comp_dqs[i] + avg_min_cg_comp_dqs[i])%2)*4) + ((avg_max_fg_comp_dqs[i] + avg_min_fg_comp_dqs[i])>>1);
|
|
if (temp >= 0x10)
|
|
{
|
|
coarse_dqs[i] ++;
|
|
fine_dqs[i] = (temp-0x10) +0x8;
|
|
}
|
|
else
|
|
{
|
|
fine_dqs[i] = temp;
|
|
}
|
|
}
|
|
|
|
reg = (coarse_dqs[1]<<12)|(fine_dqs[1]<<8)|(coarse_dqs[0]<<4)|fine_dqs[0];
|
|
|
|
#if defined (HWDLL_FIXED)
|
|
/* Read DLL HW delay */
|
|
{
|
|
unsigned int sel_fine[2],sel_coarse[2];
|
|
unsigned int sel_mst_coarse, sel_mst_fine;
|
|
unsigned int avg_cg_dly[2],avg_fg_dly[2];
|
|
|
|
hw_dll_reg = RALINK_REG(RALINK_MEMCTRL_BASE+0x20);
|
|
sel_mst_coarse = (hw_dll_reg >> 8) & 0x0F;
|
|
sel_mst_fine = (hw_dll_reg >> 4) & 0x0F;
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
unsigned int cg_dly_adj, fg_dly_adj,sel_fine_tmp,sel_coarse_tmp;
|
|
|
|
cg_dly_adj = coarse_dqs[j];
|
|
fg_dly_adj = fine_dqs[j];
|
|
|
|
sel_fine_tmp = sel_mst_fine + fg_dly_adj - 8;
|
|
sel_coarse_tmp = ((sel_mst_coarse + cg_dly_adj - 8) > DU_COARSE_WIDTH -1) ? DU_COARSE_WIDTH-1 : \
|
|
((sel_mst_coarse + cg_dly_adj -8) < 0) ? 0 : sel_mst_coarse + cg_dly_adj -8;
|
|
|
|
if (sel_fine_tmp > (DU_FINE_WIDTH-1)) {
|
|
if (sel_coarse_tmp < (DU_COARSE_WIDTH-1)) {
|
|
sel_fine[j] = sel_fine_tmp - C2F_RATIO;
|
|
sel_coarse[j] = sel_coarse_tmp + 1;
|
|
}
|
|
else {
|
|
sel_fine[j] = DU_FINE_WIDTH-1;
|
|
sel_coarse[j] = sel_coarse_tmp;
|
|
}
|
|
}
|
|
else if (sel_fine_tmp < 0){
|
|
if (sel_coarse_tmp > 0) {
|
|
sel_fine[j] = sel_fine_tmp + C2F_RATIO;
|
|
sel_coarse[j] = sel_coarse_tmp - 1;
|
|
}
|
|
else {
|
|
//saturate
|
|
sel_fine[j] = 0;
|
|
sel_coarse[j] = sel_coarse_tmp;
|
|
}
|
|
}
|
|
else {
|
|
sel_fine[j] = sel_fine_tmp;
|
|
sel_coarse[j] = sel_coarse_tmp;
|
|
}
|
|
}
|
|
reg_with_dll = (sel_coarse[1]<<28)|(sel_fine[1]<<24)|(sel_coarse[0]<<20)|(sel_fine[0]<<16);
|
|
|
|
#if defined(HWDLL_AVG)
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
unsigned int avg;
|
|
int min_coarse_dqs_dly,min_fine_dqs_dly;
|
|
min_coarse_dqs_dly = sel_mst_coarse - (8 - min_coarse_dqs[j]);
|
|
min_fine_dqs_dly = sel_mst_fine - (8 -min_fine_dqs[j]);
|
|
min_coarse_dqs_dly = (min_coarse_dqs_dly < 0) ? 0 : min_coarse_dqs_dly;
|
|
min_fine_dqs_dly = (min_fine_dqs_dly < 0) ? 0 : min_fine_dqs_dly;
|
|
|
|
|
|
avg_cg_dly[j] = ((min_coarse_dqs_dly<<1) + (sel_coarse[j]<<1))>>1;
|
|
avg_cg_dly[j] = avg_cg_dly[j]&0x01 ? ((avg_cg_dly[j]>>1)+1) : (avg_cg_dly[j]>>1);
|
|
|
|
avg_fg_dly[j] = ((min_fine_dqs_dly<<1) + (sel_fine[j]<<1))>>1;
|
|
avg_fg_dly[j] = avg_fg_dly[j]&0x01 ? ((avg_fg_dly[j]>>1)+1) : (avg_fg_dly[j]>>1);
|
|
|
|
g_min_coarse_dqs_dly[j] = min_coarse_dqs_dly;
|
|
g_min_fine_dqs_dly[j] = min_fine_dqs_dly;
|
|
}
|
|
reg_avg = (avg_cg_dly[1]<<28)|(avg_fg_dly[1]<<24)|(avg_cg_dly[0]<<20)|(avg_fg_dly[0]<<16);
|
|
#endif
|
|
|
|
#if defined (HWDLL_MINSCAN)
|
|
{
|
|
unsigned int min_scan_cg_dly[2], min_scan_fg_dly[2], adj_dly[2], reg_scan;
|
|
|
|
RALINK_REG(RALINK_RGCTRL_BASE+0x108) = 0x01300;
|
|
|
|
k=9583000;
|
|
do {k--; }while(k>0);
|
|
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = reg_with_dll;
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x68) |= (0x1<<4);
|
|
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
min_scan_cg_dly[j] = 0;
|
|
min_scan_fg_dly[j] = 0;
|
|
|
|
do
|
|
{
|
|
int diff_dly;
|
|
for (nc_addr = 0xA0000000; nc_addr < (0xA0000000+DRAM_BUTTOM-NUM_OF_CACHELINE*32); nc_addr+=((DRAM_BUTTOM>>6)+1*0x400))
|
|
{
|
|
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = reg_with_dll;
|
|
wmb();
|
|
c_addr = (unsigned int*)((ulong)nc_addr & 0xDFFFFFFF);
|
|
cal_memset(((unsigned char*)c_addr), 0x1F, NUM_OF_CACHELINE*32);
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
cal_patgen(nc_addr, NUM_OF_CACHELINE*8, 2);
|
|
#else
|
|
cal_memcpy(((unsigned char*)nc_addr), ((unsigned char*)cache_pat), NUM_OF_CACHELINE*32);
|
|
#endif
|
|
if (j == 0)
|
|
reg_scan = (reg_with_dll&0xFF000000)|(min_scan_cg_dly[j]<<20)|(min_scan_fg_dly[j]<<16);
|
|
else
|
|
reg_scan = (reg_with_dll&0x00FF0000)|(min_scan_cg_dly[j]<<28)|(min_scan_fg_dly[j]<<24);
|
|
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = reg_scan;
|
|
wmb();
|
|
cal_invalidate_dcache_range(((unsigned char*)c_addr), ((unsigned char*)c_addr)+NUM_OF_CACHELINE*32);
|
|
wmb();
|
|
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
if (i % 8 ==0)
|
|
pref_op(0, &c_addr[i]);
|
|
}
|
|
for (i = 0; i < NUM_OF_CACHELINE*8; i ++)
|
|
{
|
|
#if (NUM_OF_CACHELINE > 40)
|
|
if (c_addr[i] != (ulong)nc_addr+i+2)
|
|
#else
|
|
if (c_addr[i] != cache_pat[i])
|
|
#endif
|
|
{
|
|
goto MINSCAN_FAILED;
|
|
}
|
|
}
|
|
}
|
|
diff_dly = (avg_cg_dly[j]*8 + avg_fg_dly[j])-(min_scan_cg_dly[j]*8+min_scan_fg_dly[j]);
|
|
if (diff_dly < 0)
|
|
cal_debug("diff_dly=%d\n",diff_dly);
|
|
|
|
if (diff_dly < 6)
|
|
adj_dly[j] = (avg_cg_dly[j]*8 + avg_fg_dly[j]) + (6 - diff_dly);
|
|
else
|
|
adj_dly[j] = (avg_cg_dly[j]*8 + avg_fg_dly[j]);
|
|
|
|
break;
|
|
MINSCAN_FAILED:
|
|
min_scan_fg_dly[j] ++;
|
|
if (min_scan_fg_dly[j] > 8)
|
|
{
|
|
min_scan_fg_dly[j] = 0;
|
|
min_scan_cg_dly[j]++;
|
|
if ((min_scan_cg_dly[j]*8+min_scan_fg_dly[j]) >= (avg_cg_dly[j]*8 + avg_fg_dly[j]))
|
|
{
|
|
if (j==0)
|
|
adj_dly[0] = ((reg_with_dll>>20) &0x0F)*8 + ((reg_with_dll>>16) &0x0F);
|
|
else
|
|
adj_dly[1] = ((reg_with_dll>>28) &0x0F)*8 + ((reg_with_dll>>24) &0x0F);
|
|
break;
|
|
}
|
|
}
|
|
}while(1);
|
|
} /* dqs loop */
|
|
{
|
|
unsigned int tmp_cg_dly[2],tmp_fg_dly[2];
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
if (adj_dly[j]==(avg_cg_dly[j]*8+avg_fg_dly[j]))
|
|
{
|
|
tmp_cg_dly[j] = avg_cg_dly[j];
|
|
tmp_fg_dly[j] = avg_fg_dly[j];
|
|
}
|
|
else
|
|
{
|
|
tmp_cg_dly[j] = adj_dly[j]>>3;
|
|
tmp_fg_dly[j] = adj_dly[j]&0x7;
|
|
}
|
|
}
|
|
reg_minscan = (tmp_cg_dly[1]<<28) | (tmp_fg_dly[1]<<24) | (tmp_cg_dly[0]<<20) | (tmp_fg_dly[0]<<16);
|
|
}
|
|
}
|
|
|
|
#endif /* HWDLL_MINSCAN */
|
|
|
|
#if defined (HWDLL_LV)
|
|
RALINK_REG(RALINK_RGCTRL_BASE+0x108) = 0x0f00;
|
|
|
|
k=9583000;
|
|
do {k--; }while(k>0);
|
|
#endif
|
|
|
|
FINAL_SETUP:
|
|
#if (defined(HWDLL_AVG) && (!defined(HWDLL_MINSCAN)))
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = (reg_avg&0xFFFF0000)|((reg_with_dll>>16)&0x0FFFF);
|
|
#elif defined(HWDLL_MINSCAN)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = (reg_minscan&0xFFFF0000)|((reg_with_dll>>16)&0x0FFFF);
|
|
#else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64) = (reg_with_dll&0xFFFF0000)|(reg&0x0FFFF);
|
|
#endif
|
|
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x68) |= (0x1<<4);
|
|
cal_debug("\n\r");
|
|
for (j = 0; j < 2; j++)
|
|
cal_debug("[%02X%02X%02X%02X]", avg_min_cg_comp_dqs[j],avg_min_fg_comp_dqs[j], avg_max_cg_comp_dqs[j],avg_max_fg_comp_dqs[j]);
|
|
|
|
cal_debug("[%04X%02X%02X][%08X][00%04X%02X]\n", reg&0x0FFFF,\
|
|
(g_min_coarse_dqs_dly[0]<<4)|g_min_coarse_dqs_dly[0], \
|
|
(g_min_coarse_dqs_dly[1]<<4)|g_min_coarse_dqs_dly[1], \
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x64),
|
|
(reg_avg&0xFFFF0000)>>16,
|
|
(hw_dll_reg>>4)&0x0FF
|
|
);
|
|
cal_debug("DU Setting Cal Done\n");
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x48) = ddr_cfg2_reg;
|
|
#if defined(MT7628_FPGA_BOARD) || defined(MT7628_ASIC_BOARD)
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x10) |= (0x1<<4);
|
|
#else
|
|
RALINK_REG(RALINK_MEMCTRL_BASE+0x18) |= (0x1<<4);
|
|
#endif
|
|
|
|
#endif
|
|
}
|
|
|
|
EXIT:
|
|
|
|
return ;
|
|
}
|
|
#endif /* #defined (CONFIG_DDR_CAL) */
|
|
|
|
|
|
/* Restore to default. */
|
|
int reset_to_default(void)
|
|
{
|
|
ulong addr, size;
|
|
|
|
addr = CFG_ENV_ADDR;
|
|
size = CFG_CONFIG_SIZE;
|
|
|
|
/* Erase U-Boot Env partition */
|
|
#if defined (CFG_ENV_IS_IN_NAND)
|
|
/* Erase only one NAND block */
|
|
size = CFG_BLOCKSIZE;
|
|
ranand_erase((addr-CFG_FLASH_BASE), size);
|
|
|
|
/* Erase 'Config' partition with NVRAM */
|
|
if (CFG_NVRAM_ADDR > addr) {
|
|
addr = CFG_NVRAM_ADDR;
|
|
ranand_erase((addr-CFG_FLASH_BASE), size);
|
|
}
|
|
#elif defined (CFG_ENV_IS_IN_SPI)
|
|
printf("Erase 0x%08x size 0x%x\n", addr, size);
|
|
raspi_erase((addr-CFG_FLASH_BASE), size);
|
|
#else
|
|
printf("Erase 0x%08x size 0x%x\n", addr, size);
|
|
flash_sect_protect(0, addr, addr+size-1);
|
|
flash_sect_erase(addr, addr+size-1);
|
|
flash_sect_protect(1, addr, addr+size-1);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|