分类: LINUX
2012-03-05 15:05:31
1.2440 有俩个PLL ,UPLL 和MPLL 。UPLL 用于USB 时钟UCLK ,MPLL 对应FCLK .HCLK 、PCLK 。ARM 启动时直接使用外部晶振作为CPU 时钟,对应2440 为12Mhz 。只有在设置了时钟寄存器M P S 三个值,具体的寄存器PLLCON 下面已经说得很清楚了。设置分频寄存器后CPU 时钟即采用倍频后的FCLK 时钟。
2. CPU 时钟即就是FCLK 时钟,HCLK 从FCLK 分频,PCLK 从HCLK 分频。具体的分频比例需要设置寄存器CLKDIVN ,详细见手册。
3. 系统要工作需要首先设置好时钟,时钟是CPU 及外设工作的心脏,当你没有设置时钟时CPU 直接使用外部晶振,所以有些慢设没有设置时钟也能工作。时钟设置时有一个CPU 时钟模式- 快速总线模式和异步时钟模式,具体是实现找了好多资料都没有弄明白,大概有一些了解的地方是 ,快速总线模式下且HDIVN 不为0 时,CPU 使用HCLK 时钟且可以改变CPU 时钟但不改变FCLK 和PCLK 的频率。
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12);
1)FLCK、HCLK和PCLK的关系
S3C2440有三个时钟FLCK、HCLK和PCLK
s3c2440官方手册上说P7-8写到:
FCLK is used by ARM920T,内核时钟,主频。
HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. 也就是总线时钟,包括USB时钟。
PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface,ADC, UART, GPIO, RTC and SPI.即IO接口时钟,例如串口的时钟设置就是从PCLK来的;
那么这三个时钟是什么关系呢?这三个时钟通常设置为1:4:8,1:3:6的分频关系,也就说如果主频FLCK是400MHz,按照1:4:8的设置,那么HLCK是100MHz,PLCK是50MHz
如果CLKDIVN设置为0x5,那么比例即为1:4:8,前提是CAMDIVN[9]为0.
2)输入时钟FIN与主频FCLK的关系
现代的CPU基本上都使用了比主频低的多的时钟输入,在CPU内部使用锁相环进行倍频。对于S3C2440,常用的输入时钟FIN有两种:12MHz和16.9344MHz,那么CPU是如何将FIN倍频为FCLK的呢?
S3C2440使用了三个倍频因子MDIV、PDIV和SDIV来设置将FIN倍频为MPLL,也就是FCLK
MPLL=(2*m*FIN)/(p*2^s) where m=(MDIV+8), p=(PDIV+2), s=SDIV
寄存器MPLLCON就是用来设置倍频因子的
理论上,你可以通过设置该寄存器来实现不同的频率,然而,由于实际存在的各种约束关系,设置一个适当的频率并不容易,手册上列出了一些常用频率的表格,
例如,假设输入时钟FIN=16.9344M,MDIV=110, PDIV=3, SDIV=1,
利用上面的公式,FCLK=2*16.9344*(110+8)/((2+3)*2)=399.65
3)关于USB时钟
S3C2440有两个锁相环,一个主锁相环MPLL提供给FCLK的,另外一个UPLL是提供给USB时钟(48MHz)的,与MPLL一样,UPLL的产生也是通过UPLLCON寄存器设置分频因子得到,计算公式稍有不同:
UPLL=(m*FIN)/(p*2^s) where m=(MDIV+8), p=(PDIV+2), s=SDIV,同样,可以通过查表得到一个合适的值。
最后值得一提的是,在CLKDIVN的第三位DIVN_UPLL用来设置USB时钟UCLK和UPLL的关系,如果UPLL已经是48Mhz了,那么这一位应该设置为0,表示1:1的关系,否则是1:2的关系
USB时钟那里,晶振通过设置UPLLCON进行倍频得到UPLL,然后UPLL通过设置CLKDIVN的第三位DIVN_UPLL 进行分频得到UCLK 给USB提供时钟,USB时钟频率必须为48MHZ,所以在设置UPLLCON和CLKDIVN这两个寄存器的时候要让他们最后得到的UCLK的结果为48MHZ,一般情况下让UPLL的值为48MHZ或96MHZ,所以在设置CLKDIVN这个寄存器的时候就对它不分频或2分频来得到48MHZ.
S3C2410 CPU 默认的工作主频为12MHz ,使用PLL 电路可以产生更高的主频供CPU 及外围器件使用 。S3C2410 有两个PLL :MPLL 和UPLL ,UPLL 专用与USB 设备。MPLL 用于CPU 及其他外围器件。
通过MPLL 会产生三个部分的时钟频率:FCLK 、HCLK 、PLCK 。FCLK 用于CPU 核,HCLK 用于AHB 总线的设备( 比如SDRAM) ,PCLK 用于APB 总线的设备( 比如UART) 。从时钟结构图中可以查看到使用不同时钟频率的硬件。
AHB和APH简介
AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanced Peripheral Bus)外围总线。AMBA片上总线AMBA 2.0规范包括四个部分:AHB、ASB、APB和Test Methodology。AHB的相互连接采用了传统的带有主模块和从模块的共享总线,接口与互连功能分离,这对芯片上模块之间的互连具有重要意义。AMBA已不仅是一种总线,更是一种带有接口模块的互连体系。
基于AMBA的片上系统
大多数挂在总线上的模块(包括处理器)只是单一属性的功能模块:主模块或者从模块。主模块是向从模块发出读写操作的模块,如CPU,DSP等;从模块是接受命令并做出反应的模块,如片上的RAM,AHB/APB 桥等。另外,还有一些模块同时具有两种属性,例如直接存储器存取(DMA)在被编程时是从模块,但在系统读传输数据时必须是主模块。如果总线上存在多个主模块,就需要仲裁器来决定如何控制各种主模块对总线的访问。虽然仲裁规范是AMBA总线规范中的一部分,但具体使用的算法由RTL设计工程师决定,其中两个最常用的算法是固定优先级算法和循环制算法。AHB总线上最多可以有16个主模块和任意多个从模块,如果主模块数目大于16,则需再加一层结构(具体参阅ARM公司推出的Multi-layer AHB规范)。APB 桥既是上唯一的主模块,也是AHB系统总线上的从模块。其主要功能是锁存来自AHB系统总线的地址、数据和控制信号,并提供二级译码以产生APB外围设备的选择信号,从而实现AHB协议到APB协议的转换。
AHB简介
AHB主要用于高性能模块(如CPU、DMA和DSP等)之间的连接,作为SoC的片上系统总线,它包括以下一些特性:单个时钟边沿操作;非三态的实现方式;支持突发传输;支持分段传输;支持多个主控制器;可配置32位~128位总线宽度;支持字节、半字节和字的传输。AHB 系统由主模块、从模块和基础结构(Infrastructure)3部分组成,整个AHB总线上的传输都由主模块发出,由从模块负责回应。基础结构则由仲裁器(arbiter)、主模块到从模块的多路器、从模块到主模块的多路器、译码器(decoder)、虚拟从模块(dummy Slave)、虚拟主模块(dummy Master)所组成。
APB简介
APB主要用于低带宽的周边外设之间的连接,例如UART、1284等,它的总线架构不像AHB支持多个主模块,在APB里面唯一的主模块就是APB 桥。其特性包括:两个时钟周期传输;无需等待周期和回应信号;控制逻辑简单,只有四个控制信号。
1)系统初始化为IDLE状态,此时没有传输操作,也没有选中任何从模块。
2)当有传输要进行时,PSELx=1,PENABLE=0,系统进入SETUP状态,并只会在SETUP 状态停留一个周期。当PCLK的下一个上升沿时到来时,系统进入ENABLE 状态。 3)系统进入ENABLE状态时,维持之前在SETUP 状态的PADDR、PSEL、PWRITE不变,并将PENABLE置为1。传输也只会在ENABLE状态维持一个周期,在经过SETUP与ENABLE状态之后就已完成。之后如果没有传输要进行,就进入IDLE状态等待;如果有连续的传输,则进入SETUP状态。
时钟源选择
表 7-1 描述了模式控制引脚 (OM3 和 OM2) 和选择时钟源之间的对应关系。 OM[3:2] 的状态由 OM3 和 OM2 引脚的状态在 nRESET( 当振荡器 (crystal/oscillatto) 时钟输出稳定后, nRESET 引脚变为高电平 ) 的上升沿锁存得到。
注意: 1 、尽管 MPLL 在系统复位的时候就开始产生,但是只有有效的设置好 MPLLCON 寄存器后 才能用于系统时钟。在此之前,外部时钟将直接作为系统时钟 。即使不需要改变 MPLLCON 寄存器的初值,也必须 将同样的值写入寄存器。
2 、当 OM[1:0] 为 11 时, OM[3:2] 用于决定一种测试模式。
下面介绍MPLL 的启动流程:
如图,刚上电一小段时间后,FCLK=晶振时钟,等待4个时钟周期后,PLL锁存有效,自动插入一段PLL Lock Time,即PLL锁定时间,此时,FCLK停止震荡,CPU停止工作,Lock time的长短由寄存器LOCKTIME设定。PLL Lock Time之后,MPLL输出正常,CPU工作在新的FCLK下。
(注:下面内容部分直接摘录自《s3c2410 完全开发流程》,Clock 部分写了非常好)
S3c2410 datasheet 224 页“Figure 7-4. Power-On Reset Sequence” 展示了上电后MPLL 启动的过程
请跟随FCLK 的图像了解启动过程:
1 、上电几毫秒后,晶振输出稳定,FCLK= 晶振频率,nRESET 信号恢复高电平后,CPU 开始执行指令。
2 、我们可以在程序开头启动MPLL ,在设置MPLL 的几个寄存器后,需要等待一段时间(Lock Time) , MPLL 的输出才稳定。在这段时间(Lock Time) 内,FCLK 停振,CPU 停止工作。Lock Time 的长短由寄存器LOCKTIME 设定。
3 、Lock Time 之后,MPLL 输出正常,CPU 工作在新的FCLK 下
设置S3c2410 的时钟频率就是设置MPLL 的几个寄存器:
1 、LOCKTIME :设为0x00ffffff
前面说过,MPLL 启动后需要等待一段时间(Lock Time) ,使得其输出稳定。位[23:12] 用于UPLL ,位[11:0] 用于MPLL 。使用确省值0x00ffffff 即可。
2 、CLKDIVN :用来设置FCLK:HCLK:PCLK 的比例关系,默认为1:1:1
这里值设为0x03 ,即FCLK:HCLK:PCLK=1:2:4
CLKDIVN 不同的设置及对应的时钟比例关系如下图:
3 、MPLLCON :设为(0x5c << 12)|(0x04 << 4)|(0x00) ,即0x5c0040
对于MPLLCON 寄存器,[19:12] 为MDIV ,[9:4] 为PDIV ,[1:0] 为SDIV 。有如下计算公式:
MPLL(FCLK) = (m * Fin)/(p * 2^s)
其中: m = MDIV + 8, p = PDIV + 2
Fin 即默认输入的时钟频率12MHz 。MPLLCON 设为0x5c0040 ,可以计算出FCLK=200MHz ,再由CLKDIVN 的设置可知:HCLK=100MHz ,PCLK=50MHz 。
通常我们将如上时钟初始化的过程写成clock_init 函数供其他函数调用,代码如下:
void clock_init(void)
{
/*init clock*/
rLOCKTIME = 0xFFFFFF;
/* 设置FCLK:HCLK:PCLK=1:2:4, 这样假设处理器主频为200M, 则HCLK 为 50M,PCLK 为25M 。ARM920T 内核使用FCLK, 内存控制器,LCD 控制器等使用 HCLK ,看门狗、串口等使用PCLK
*/
rCLKDIVN = 0x3;
/* 设置时钟频率为200M*/
rMPLLCON = 0x5c0040;
}
改变2410 的PLL 频率,具体过程:
1 、第一步软件工作: 设置P M S divider control ,也就是设置MPLLCON 寄存器。
关于PMS ,可以看Figure 7-2. 寄存器MPLLCON 的设置呢,其实有一定的规则,并非你想要的每个Fclk 频率都可以得到。官方推荐了一个表PLL VALUE SELECTION TABLE ,要按照这个进行。否则的话,就需要自己按照公式推算,但是mizi 公司并不保证你的设置是合适的。所以,如果想要工作在200MHz ,还是按照vivi 的推荐值即可。
@ step1: set P M S divider control mov r1, #CLK_CTL_BASE ldr r2, =vMPLLCON_200 str r2, [r1, #oMPLLCON] |
其中,MDIV=0x5c ,PDIV=0x04 ,SDIV=0x00. 公式Mpll (Fclk )= (m×Fin )/ (p×(2^s) )【m=MDIV+8, p=PDIV+2,s=SDIV 】
2 、第二步软件工作:设置CLKDIVN 。
这一步是设置分频系数,即Fclk 为cpu 主频,Hclk 由Fclk 分频得到,Pclk 由Hclk 分频得到。假设Hclk 是Fclk 的二分频,Pclk 是 Hclk 的二分频,那么分频系数比就是Fclk :Hclk :Pclk=1 :2 :4. 那么Hclk 为100MHz ,总线时钟周期为10ns 。Pclk 为 50MHz 。
@ step2: change clock divider mov r1, #CLK_CTL_BASE mov r2, #vCLKDIVN str r2, [r1, #oCLKDIVN] |
3 、第三步软件工作: CLKDIVN 的补充设置
void ChangeClockDivider(int hdivn,int pdivn)
{
// hdivn,pdivn FCLK:HCLK:PCLK
// 0,0 1:1:1
// 0,1 1:1:2
// 1,0 1:2:2
// 1,1 1:2:4
rCLKDIVN = (hdivn<<1) | pdivn;
if(hdivn)
MMU_SetAsyncBusMode();
else
MMU_SetFastBusMode();
}
If HDIVN = 1, CPU 总线模式必须从快速总线模式转变为同步总线模式,采用以下指令 ;void MMU_SetFastBusMode(void) ; FCLK:HCLK= 1:1 EXPORT MMU_SetFastBusMode MMU_SetFastBusMode mrc p15,0,r0,c1,c0,0 bic r0,r0,#R1_iA:OR:R1_nF mcr p15,0,r0,c1,c0,0 MOV_PC_LR If HDIVN=1 and CPU 总线模式为快速总线模式时, CPU 由HCLK 提供. 该特性可以在不改变HCLK and PCLK 的前提下把CPU 的频率减半. |
;void MMU_SetAsyncBusMode(void) ; FCLK:HCLK= 1:2 EXPORT MMU_SetAsyncBusMode MMU_SetAsyncBusMode mrc p15,0,r0,c1,c0,0 orr r0,r0,#R1_nF:OR:R1_iA mcr p15,0,r0,c1,c0,0 MOV_PC_LR |
4 、第四步软件工作:等待locktime 时间,让新的Fclk 生效
@ step4: stay locktime mov r1, #CLK_CTL_BASE ldr r2, =vLOCKTIME str r2, [r1, #oLOCKTIME] |
6 、对外设的影响
在这个实验中,主要是有两个需要改变,一个外设是UART ,一个外设是SDRAM 。
(1 )UART ,它是接在APB 总线上,所以对应的时钟信号为Pclk ,现在为50MHz 。如果想要设置波特率为115200bps ,那么根据公式 UBRDIV0=(int)(PCLK/(bps*16))-1 计算,应该为26 。如果放到程序中,那么应该注意形式。具体如下:
UBRDIV0 = ((int)(PCLK/16./UART_BAUD_RATE) -1); |
(2 )SDRAM ,主要的影响因素为刷新频率。前面在SDRAM 中没有具体分析,现在可以详细说明。使用了两片HY57V561620CT-H ,查看手册 其刷新频率为8192 refresh cycles/64ms ,所以刷新周期64ms/8192 =7.8125us 。看寄存器REFRESH 的各个位的设置情况:
·REFEN[23] :开启自动模式,设为1
·TREFMD[22] :设为Auto refresh 模式,设为0
·Trp[21:20] :看看RAS precharge Time ,查看SDRAM 手册,发现-H 系列此参数至少为20ns ,现在Hclk 对应的时钟周期为10ns ,所以至少应该为2 个clock 。可以设为00
·Tsrc : Semi Row Cycle Time ,也就是RAS Cycle Time ,至少65ms ,所以至少得6.5clock ,按照可选值,应该设置为11
·Refresh[10:0] :
公式refresh period = (2^11 - refresh_count +1)/Hclk ,由此推导出refresh_count=2^11+1-refresh period*Hclk 。带入数值,计算得出1268 =0x04f4 ,这个数值要用四舍五入,减少误差。
· 其余的保留值,均设置为0
由此得出该寄存器的值应该为0x008c04f4 。