uboot杂记之时钟分析

在分析初始化时钟代码之前先阅读下2440的datasheet:

S3C2440A 中的时钟控制逻辑可以产生几种必须的时钟信号,包括 CPU 的 FCLK,AHB 总线外设的 HCLK 以及APB 总线外设的 PCLK

S3C2440A 包含两个锁相环(PLL):一个提供给 FCLK、HCLK 和 PCLK,另一个专用于USB 模块(48MHz)。时钟控制逻辑也可以不使用 PLL 来减慢时钟的频率,并且可以由软件连接或断开各外设模块的时钟,以降低功耗。

下面是2440的时钟模块:


由上面的模块图可以看到2440的模块的外部链接可以分为2种,一种为一个外部晶振(XTIpll)一种为外部时钟(EXTCLK)。(回去查看TQ2440的引脚是如何连接的,并将引脚图贴上)。并且看到一个连接到外部晶振的振荡器(OSC)(震荡放大器) 还含有 S3C2440A 所必须的两个用于产生高频率时钟的 PLL,(锁相环MPLL,UPLL)。

时钟源的选择:

由上图可以看到,当OM[3:2]选择不同的连接,所选择的时钟是不同的(查看TQ2440的时钟源
特别注意:

由上图可以看到,只要设置相应的引脚,MPLL的状态就已经开启了,其实MPLL 输出(Mpll)并没有作为系统时钟,直到软件写入有效值来设置 MPLLCON寄存器MPLL才可以输出。在设置此值之前,是将外部晶振或外部时钟源提供的时钟直接作为系统时钟。即使用户不想改变 MPLLCON寄存器的默认值,用户也应当写入与之相同的值到 MPLLCON 寄存器寄存器中。(这也就是为什么在设置时钟之前系统运行的速度比较慢的原因了)

Mpll(输出时钟频率)与 Fin (参考输入时钟频率)有如下等式:

猜想:对于分频器M,P,S的值应该是在寄存器中进行设置的。(下面分析讨论)

上电复位

上面就是复位后的时钟的变化时序图,可以看到,在复位的开始阶段,上电复位后的 PLL 是不稳定的,因此在软件重新配置PLLCON 寄存器之前,先使用 Fin(xtipll) 代替 Mpll(PLL 输出)直接提供给 FCLK进行使用。即使用户不希望在复位后改变 PLLCON 寄存器的默认值,用户还是应该用软件写入相同的值到 PLLCON 寄存器中。

FCLK,HCLK 和 PCLK
1.FCLK :提供给 ARM920T 的时钟(直接由MPLL提供)。
2.HCLK 是提供给用于 ARM920T,存储器控制器,中断控制器,LCD 控制器,DMA 和 USB 主机模块的 AHB总线的时钟。
3.PCLK 是提供给用于外设如 WDT,IIS,I2C,PWM 定时器,MMC/SD 接口,ADC,UART,GPIO,RTC 和SPI 的 APB 总线的时钟

S3C2440A 还支持对 FCLK、HCLK 和 PCLK 之间分频比例的选择。该比例由 CLKDIVN 控制寄存器中的 HDIVN和 PDIVN 所决定

从上图可以看到2440支持很多的分频比。(设置分频比的原因是不是本着够用的原则?????

注意:

1. 应当谨慎设置 CLKDIVN,不要使其超过 HCLK 和 PCLK 的最小值。
2. 如果 HDIVN 不为 0,CPU 总线模式应该使用以下指令使其从快总线模式改变为异步总线模式(S3C2440不支持同步总线模式)。

MMU_SetAsyncBusMode
MRC p15, 0, r0, c1, c0, 0
ORR r0, r0, #R1_nF:OR:R1_iA
MCR p15, 0, r0, c1, c0, 0

OK,下面分析下代码:
void clock_init(void)
{
	S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000;

	/* FCLK:HCLK:PCLK = ?:?:? */
#if CONFIG_133MHZ_SDRAM
	clk_power->CLKDIVN = S3C2440_CLKDIV136;			//HJ 1:3:6,
#else
	clk_power->CLKDIVN = S3C2440_CLKDIV;				//HJ 1:4:8 设置分配系数FCLK:HCLK:PCLK == 1:4:8
#endif                                                                  //下面设置FCLK==400MHZ,则HCLK == 100MHZ PCLK == 50MHZ
	/* change to asynchronous bus mod */
	__asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */  
                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */  
                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */  
                    :::"r1"
                    );

	/* to reduce PLL lock time, adjust the LOCKTIME register */
	clk_power->LOCKTIME = 0xFFFFFF;

	/* configure UPLL */
	clk_power->UPLLCON = S3C2440_UPLL_48MHZ;		//fin=12.000MHz
//	clk_power->UPLLCON = S3C2440_UPLL_48MHZ_Fin16MHz;	//fin=16.934MHz

	/* some delay between MPLL and UPLL */
	delay (4000);

	/* configure MPLL */
	clk_power->MPLLCON = S3C2440_MPLL_400MHZ;		//fin=12.000MHz
//	clk_power->MPLLCON = S3C2440_MPLL_405MHZ;				//HJ 405MHz
//	clk_power->MPLLCON = S3C2440_MPLL_440MHZ;				//HJ 440MHz
//	clk_power->MPLLCON = S3C2440_MPLL_480MHZ;				//HJ 480MHz
//	clk_power->MPLLCON = S3C2440_MPLL_399MHz;		//fin=16.934MHz
	/* some delay between MPLL and UPLL */
	delay (8000);
}


S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000; //首先获取时钟的相关寄存器首地址
/*搜索S3C24X0_CLOCK_POWER可以发现它的定义如下*/
typedef struct {
    S3C24X0_REG32   LOCKTIME;                  //锁定时间计数寄存器,用于在MPLL输出频率稳定之前的时间,设置为默认值0xFFFFFF即可
    S3C24X0_REG32   MPLLCON;                   //MPLL 配置寄存器 
    S3C24X0_REG32   UPLLCON;
    S3C24X0_REG32   CLKCON;
    S3C24X0_REG32   CLKSLOW;
    S3C24X0_REG32   CLKDIVN;
    S3C24X0_REG32   CAMDIVN;    /* for s3c2440, by www.embedsky.net */
} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

本开发板设置的MPLLCON为:

clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
#define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))  //设置的输出频率为400MHZ

看下MPLLCON的寄存器设置

计算方法如下:


按照上面的公式将代码中的输出频率计算一下:

#define S3C2440_MPLL_400MHZ    ((0x5c<<12)|(0x01<<4)|(0x01))
0x5c  <---> 92

m = 92 + 8 =>100

p = 1 + 2 =>3

s = 1

Mpll = (2 * 100 * 12) / (3*2) ==> 400  //和代码中的注释一样

下面有三星推荐的参考配置:

注意:

在datasheet中,明确指出:当你设置 MPLL 和 UPLL 的值时,你必须首先设置 UPLL 值再设置 MPLL 值。(大约需要 7 个 NOP 的间隔)。

这也就解释了为什么在UPLL设置后要做一段delay的原因了。。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值