board_init函数的作用:
1.对时钟进行初始化
2.对GPIO进行初始化
3.设置arch number和boot params的地址
4.使能数据缓存和指令缓存
代码的位置:
kangear-u-boot-2009.11\board\tekkamanninja\mini2440\mini2440.c
/*
* Miscellaneous platform dependent initialisations
*/
int board_init (void)
{
struct s3c24x0_clock_power * const clk_power =
s3c24x0_get_base_clock_power();
struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
/* to reduce PLL lock time, adjust the LOCKTIME register */
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */
delay (8000);
/* set up the I/O ports */
gpio->GPACON = 0x007FFFFF;
#if defined(CONFIG_MINI2440)
gpio->GPBCON = 0x00295551;
#else
gpio->GPBCON = 0x00044556;
#endif
gpio->GPBUP = 0x000007FF;
#if defined(CONFIG_MINI2440)
gpio->GPCCON = 0xAAAAA6AA;
gpio->GPCDAT &= ~(1<<5);
#else
gpio->GPCCON = 0xAAAAAAAA;
#endif
gpio->GPCUP = 0xFFFFFFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0xFFFFFFFF;
gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FF3A;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x0016FAAA;
gpio->GPHUP = 0x000007FF;
gpio->EXTINT0=0x22222222;
gpio->EXTINT1=0x22222222;
gpio->EXTINT2=0x22222222;
#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable();
#if defined(CONFIG_MINI2440_LED)
gpio->GPBDAT = 0x00000180;
#endif
return 0;
}
分析代码
1.初始化时钟
首先定义了一个struct s3c24x0_clock_power结构体指针,该结构体类型定义在:
kangear-u-boot-2009.11\include\s3c24x0.h :
/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */
/* (see S3C2410 manual chapter 7) */
struct s3c24x0_clock_power {
S3C24X0_REG32 LOCKTIME;
S3C24X0_REG32 MPLLCON;
S3C24X0_REG32 UPLLCON;
S3C24X0_REG32 CLKCON;
S3C24X0_REG32 CLKSLOW;
S3C24X0_REG32 CLKDIVN;
#if defined (CONFIG_S3C2440)
S3C24X0_REG32 CAMDIVN;
#endif
};
每个结构体成员占4个字节。
struct s3c24x0_clock_power * const clk_power =
s3c24x0_get_base_clock_power();
该函数位于kangear-u-boot-2009.11\include\s3c2410.h,返回S3C24X0_CLOCK_POWER_BASE,是几个时钟寄存器的的起始地址。
static inline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void)
{
return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE;
}
该宏位于kangear-u-boot-2009.11\include\s
3c2410.h
#define S3C24X0_CLOCK_POWER_BASE 0x4C000000
所以clk_power指向0x4C000000,接下来开始进行时钟方面的设置:
/* to reduce PLL lock time, adjust the LOCKTIME register */
clk_power->LOCKTIME = 0xFFFFFF;
/* configure MPLL */
clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
/* some delay between MPLL and UPLL */
delay (4000);
/* configure UPLL */
clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
/* some delay between MPLL and UPLL */
delay (8000);
数据手册上LOCKTIME的默认值是0xFFFFFFFF,这里的设置值是
0xFFFFFF。
然后设置MPLLCON
#if defined(CONFIG_S3C2440)
/* Fout = 405MHz */
#define M_MDIV 0x7f
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif
所以MDIV = 127,PDIV = 2,SDIV=1.
m = ( MDIV + 8 ) = 135, p = ( PDIV + 2 ) = 4, s = SDIV = 1,Fin = 12M
Mpll = ( 2 × m × Fin ) / ( p × 2s ) = 405M
即CPU运行在405MHz。
即CPU运行在405MHz。
接下来设置UPLLCON,MPLLCON和UPLLCON的设置之间要有一些delay。
Upll的值算下来是48
2.对GPIO进行初始化
先看一下struct s3c24x0_gpio 结构体
/* I/O PORT (see manual chapter 9) */
struct s3c24x0_gpio {
#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
S3C24X0_REG32 GPACON;
S3C24X0_REG32 GPADAT;
S3C24X0_REG32 res1[2];
S3C24X0_REG32 GPBCON;
S3C24X0_REG32 GPBDAT;
S3C24X0_REG32 GPBUP;
S3C24X0_REG32 res2;
S3C24X0_REG32 GPCCON;
S3C24X0_REG32 GPCDAT;
S3C24X0_REG32 GPCUP;
S3C24X0_REG32 res3;
S3C24X0_REG32 GPDCON;
S3C24X0_REG32 GPDDAT;
S3C24X0_REG32 GPDUP;
S3C24X0_REG32 res4;
S3C24X0_REG32 GPECON;
S3C24X0_REG32 GPEDAT;
S3C24X0_REG32 GPEUP;
S3C24X0_REG32 res5;
S3C24X0_REG32 GPFCON;
S3C24X0_REG32 GPFDAT;
S3C24X0_REG32 GPFUP;
S3C24X0_REG32 res6;
S3C24X0_REG32 GPGCON;
S3C24X0_REG32 GPGDAT;
S3C24X0_REG32 GPGUP;
S3C24X0_REG32 res7;
S3C24X0_REG32 GPHCON;
S3C24X0_REG32 GPHDAT;
S3C24X0_REG32 GPHUP;
S3C24X0_REG32 res8;
S3C24X0_REG32 MISCCR;
S3C24X0_REG32 DCLKCON;
S3C24X0_REG32 EXTINT0;
S3C24X0_REG32 EXTINT1;
S3C24X0_REG32 EXTINT2;
S3C24X0_REG32 EINTFLT0;
S3C24X0_REG32 EINTFLT1;
S3C24X0_REG32 EINTFLT2;
S3C24X0_REG32 EINTFLT3;
S3C24X0_REG32 EINTMASK;
S3C24X0_REG32 EINTPEND;
S3C24X0_REG32 GSTATUS0;
S3C24X0_REG32 GSTATUS1;
S3C24X0_REG32 GSTATUS2;
S3C24X0_REG32 GSTATUS3;
S3C24X0_REG32 GSTATUS4;
#if defined (CONFIG_S3C2440)
S3C24X0_REG32 res9[3];
S3C24X0_REG32 MSLCON;
S3C24X0_REG32 GPJCON;
S3C24X0_REG32 GPJDAT;
S3C24X0_REG32 GPJUP;
#endif
#endif
};
结构体指针gpio最后获得的值是0x56000000,指向GPIO所有寄存器中的第一个寄存器。
接下来是对GPIO寄存器的设置。
#if defined(CONFIG_MINI2440)
gpio->GPBCON = 0x00295551;
#else
gpio->GPBCON = 0x00044556;
#endif
gpio->GPBUP = 0x000007FF;
#if defined(CONFIG_MINI2440)
gpio->GPCCON = 0xAAAAA6AA;
gpio->GPCDAT &= ~(1<<5);
#else
gpio->GPCCON = 0xAAAAAAAA;
#endif
gpio->GPCUP = 0xFFFFFFFF;
gpio->GPDCON = 0xAAAAAAAA;
gpio->GPDUP = 0xFFFFFFFF;
<span style="white-space:pre"> </span>gpio->GPECON = 0xAAAAAAAA;
gpio->GPEUP = 0x0000FFFF;
gpio->GPFCON = 0x000055AA;
gpio->GPFUP = 0x000000FF;
gpio->GPGCON = 0xFF95FF3A;
gpio->GPGUP = 0x0000FFFF;
gpio->GPHCON = 0x0016FAAA;
gpio->GPHUP = 0x000007FF;
gpio->EXTINT0=0x22222222;
gpio->EXTINT1=0x22222222;
gpio->EXTINT2=0x22222222;
3.设置arch number和boot params的地址
#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
gd->bd->bi_arch_number是机器码,对于mini2440是1999
gd->bd->bi_boot_params
存放参数的地址,这些参数用来启动
Linux
内核
4.使能数据缓存和指令缓存
icache_enable();
dcache_enable();