一、S5PV210时钟系统
时钟:一定频率的电信号。 时钟系统:基于CMOS工艺的高性能处理器时钟系统,集成PLL可以从内部触发,比从外部触发更快且更准确,能有效地避免一些与信号完整性相关的问题。
S5pv210时钟系统,参考s5pv210手册第三章,CLOCK CONTROLLER
S5pv210时钟管理单元(CMU)主要了解了以下信息
1、时钟域:s5pv210主要由三个时钟域组成
a:MSYS域:Cortex A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、内部SRAM(IRAM和IROM)、INTC和配置接口(SPERI)。Cortex A8仅支持同步模式,因此必须与200MHz轴总线同步运行。
b:DSYS域:与显示相关的模块,包括FIMC、FIMD、JPEG和多媒体IP(X、L和T块中提到的所有其他IP)。都是和视频显示、编解码等有关的模块
c:PSY域:安全、I/O外围设备和低功耗音频播放。如串口、SD接口、I2C、AC97、USB等
每个总线系统分别以200兆赫(最大)、166兆赫和133兆赫运行。在两个不同的域之间有异步总线桥(BRG)。
S5Pv210由三个时钟域组成,即主系统(MSY)、显示系统(DSY)和外围系统(PSY)
2、时钟的声明
S5pv210的时钟包括两种:来自clock pads的时钟,来自CMU的时钟,跟来自USB PHY的时钟
a:来自CLOCK PADS的时钟包括几个晶振接口
•xrtcxti:使用xrtcxti和xrtcxto管脚指定32.768 kHz晶体板的时钟
•xxti:指定从带xxti和xxto针的水晶板的时钟
•xusbxti:指定带有xusbxti和xusbxto引脚的水晶板上的时钟
•xhdmixti:使用xhdmixti和xhdmixto管脚指定27MHz晶体板的时钟
b:来自时钟管理系统(CMU)的时钟
主要分为不同频段的控制输入,在典型的S5Pv210应用中,•Cortex A8和MSys时钟域使用APLL(即,ARMCLK、HCLK-MSY和PCLK-MSY)。
3、时钟的关系
三个时钟域(MSYS时钟域、DSY时钟域、PSY时钟域)对应都有不同对应的取值范围,每个高性能操作的值都对应不同的频率
4、时钟的生成
s5pv210时钟生成的逻辑框图如下
时钟生成器块还包括内置逻辑,用于在每次系统重置后稳定时钟频率,因为时钟在稳定之前需要时间。
s5pv210的两种类型MUX时钟开关:灰色时钟mux表示无故障时钟mux,如果更改时钟选择,则无故障时钟mux。白色的时钟mux代表非无故障时钟mux,在改变时钟源时可能会出现故障。
对于无故障多路复用器,应确保当时钟选择从一个更改为另一个时,两个时钟源都在运行。如果没有同时使用,对于非无故障时钟MUX,在更改时钟时可能会出现故障。时钟更改完成后,用户可以重新启用非无故障时钟MUX的输出,这样就不会因时钟更改而出现故障。非无故障多路复用器的屏蔽输出由时钟源控制寄存器处理。(下面还有时钟源控制寄存器的一些了解)
5、时钟配置程序
基本SFR配置流程:
打开PLL(A、M、E、V)PLL U CON[31]=1;//打开PLL(参考(A、M、E、V)PLL U CON SFR)
wait_lock_time;//等待PLL锁定
(a,m,e,v)pll_sel=1;//在pll输出时钟稳定后,选择pll输出时钟而不是输入参考时钟。
更改系统时钟分频器值clk_div0[31:0]=目标值0;
更改特殊时钟的除法器值clk_div1[31:0]=目标值1;
clk_div2[31:0]=目标值2;
6、S5PV210时钟设置寄存器
-xPLL_LOCK:控制PLL锁定频率的周期,譬如24MHZ变为1GHZ这段是需要一段时间的,通过一个锁相环使得把24MHZ锁定为1GHZ,所以就需要锁定频率的周期了。(锁定频率)
-xPLL_CON:打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等。(决定倍频到多少)
-CLK_SRCn(n:0~6):用来设置时钟来源的,对应时钟框图中的mux开关。(决定时钟来源)
-CLK_SRC_MASKn:打开关闭时钟源。(开头部分)
-CLK_DIV_STATn:各模块的分频参数配制。(决定分频多少)
-CLK_SRC_GATE_x:打开关闭时钟门。(结尾部分)
-CLK_DIV_STATn:分频状态寄存器,确保是否已经分频完成。
-CLK_MUX_STATn:选择开关状态寄存器,确保是否已经选择开关完毕。
7、时钟源控制寄存器
S5Pv210有许多时钟源,包括四个PLL输出、外部振荡器、外部时钟和来自GPIO的其他时钟源。CLK U SRCN寄存器控制每个时钟分频器的源时钟。
以此来设置时钟开关
时钟源寄存器(CLK U SRC0,R/W,地址=0XE010 U 0200)
在s5pv210手册中可以看到,所有的寄存器都是按块分的。我们可以找到一个寄存器的基地址,再通过基址加编址寻址的方式在找到寄存器。
8、后面还有s5pv210时钟的MUX状态SFR 以及各种时钟源开关太多了还没看完
二、s5pv210的内存初始化
1、SDRAM定义和特性
SDRAM:Syncronized Dynamic Ramdam Access Memory,同步动态随机存储器
DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double rate,双倍速度的SDRAM)
DDR有好多代:DDR1 DDR2 DDR3 DDR4 LPDDR
SDRAM的特性:容量大、价格低、掉电易失性、随机读写、总线式访问。
SDRAM在整个硬件系统中是属于外部设备,通过地址总线和数据总线接口与SoC通信
2、内存地址详解
3:寻址详解
在数据手册《NT5TU64M16GG-DDR2-1G-G-R18-Consumer》第10页的block diagram中,详解如上。
采用128Mb * 8 结构,每个Bank可寻址的大小是16MB,BA0-BA2用来选择8个Bank,寻址的方式:Row-Address+Column-Address。
故单内存芯片可寻址的大小为:16MB * 8 = 128MB
两片单芯片内存并联组合成32位数据总线,可与SoC进行总线通信,可寻址的内存大小便为:128MB+128MB= 256MB,在九鼎的开发板上采用了DRAM0+DRAM1分配内存地址,所以DRAM0和DRAM1都是256MB内存大小,合起来就是512MB内存大小。
所以开发板上DRAM0和DRAM1可寻址的有效范围分别为:
DRAM0:0x20000000 - 0x2FFFFFFF (256MB)
DRAM1:0x40000000 - 0x4FFFFFFF (256MB)
其他地址为非法地址,比如:0x30000000
4、SDRAM初始化详解
初始化过程包括phy dll初始化、设置控制器寄存器和内存初始化。内存初始化请参考JEDEC规范和内存设备数据表。有三种不同的内存类型,即lpddr、lpddr2和ddr2。根据内存类型,初始化顺序如下
1)、Lpddr内存初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言和保持CKE到逻辑的高水平。然后应用稳定时钟。注:xddr2sel应为低电平,以将CKE保持在高电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确的值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部内存芯片,也可以设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,不应为可靠运行而关闭。如果频率低,phy dll可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on bit-字段以关闭phy dll。
13、确认
14、通电后稳定时钟是否至少发出200us。使用directCmd寄存器发出pall命令。
15、使用directCmd寄存器发出两个自动刷新命令。
16、使用directcmd寄存器发出mrs命令以编程操作参数。1-3 S5Pv210_M 1 DRAM控制器
17、使用directcmd寄存器发出emrs命令以编程操作参数。
18、如果有两个外部存储芯片,则对Chip1存储设备执行步骤14~17。
19、将控制器设置为打开自动刷新计数器。
20、如果需要断电模式,请设置MEMControl寄存器。
2)lpddr2内存类型的初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言并将CKE保持在逻辑低水平。然后应用稳定时钟。注:xddr2sel应为高电平,以将CKE保持在低电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部存储器芯片,则设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,phy dll不应关闭以实现可靠的操作。除低频运行外,它可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on位字段以关闭phy dll。
13、将phycontrol1.fp_resync位字段设置为“1”以更新dll信息。
14、确认在通电后,CKE仍保持逻辑低电平至少100ns。
15、发出一个nop命令,使用directcmd寄存器断言和保持CKE到一个逻辑高级。
16、至少等待200us。 1-4 S5Pv210_M 1 DRAM控制器
17、使用directCmd寄存器发出mrs命令以重置内存设备并编程操作参数。
18、等待至少1us。
19、使用directcmd寄存器发出mrr命令来轮询mrstatus寄存器的dai位,以了解设备自动初始化是否完成。
20、如果有两个外部存储芯片,则对chip1存储设备执行步骤15~19。
21、将控制器设置为打开自动刷新计数器。22。如果需要断电模式,设置MEMControl寄存器。
3)DDR2内存类型的初始化顺序:
1. DMC及DDR2颗粒上电, 且电压稳定
2. DMC保持CKE为低电平
3. SOC提供时钟(XDDR2SEL保持高电平以保持CKE为低)
4. 根据实际工作时钟频率设置phyControl0.ctrl_start_point和PhyControl0.ctrl_inc
ldr r0, =APB_DMC_0_BASE @ 0xF000_0000
ldr r1, =0x00101000 @ ctrl_start_point: bit[15:8], ctrl_inc: bit[23:16], 按手册建议,这两位都设置为0x10
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
5. 设置PhyControl0.ctrl_dll_on为”1”, 以使能PHY DLL
ldr r1, =0x00101002 @ctrl_dll_on: bit[1]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
6. DQS Cleaning: 根据实际工作时钟频率和tAC设置PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetc (可以和第7步互换顺序)
ldr r1, =0x00000086 @ ctrl_shiftc: bit[2:0], 手册建议设置为6 (DDR2); ctrl_offsetc: bit[14:8], 这里设置为”0”, ctrl_ref: bit[7:4], 默认值为0x4; 所以, 这里应该设置为0x00000046系统也能工作, 设置为”86”可能是原代码作者的错误
str r1, [r0, #DMC_PHYCONTROL1] @ 0xF000_001C
7. 置位PhyControl0.ctrl_start以启动DLL
ldr r1, =0x00101003 @ ctrl_start: bit[0]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
8. 设置ConControl, 注意此时需要保证auto refresh counter off
ldr r1, =0x0FFF2010 @ default time out cycles: FFF; Read data fetch cycles: 2 (CL后再过2个周期latch数据), disable adaptive QoS, disable DQ swap, disable PHY driving (bi-directional pin拉低以省电, enable是不是更好?), disable read cycle gap for 2 different chips (应该是enable),auto refresh counter off, enable out of order scheduling, revise后的设置为(待测试):0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
9. 设置MemControl, 所有power down mode要关掉
ldr r1, =0x00202400 @ MemControl BL=4, 2 chip, 位宽x32 (是指通道位宽), DDR2 type, no additional latency for PALL, disable dynamic self refresh, disable timeout precharge, active/precharge power down, dynamic power down off, dynamic clock control: always running, revise后的设置为(待测试):0x00212400
str r1, [r0, #DMC_MEMCONTROL] @ 0xF000_0004
10. 设置MemControl0和MemControl1寄存器(如果有)
ldr r1, =0x20F01323 @ MemConfig0 设置地址范围0x2000_0000~0x2FFF_FFFF(再在设置的是DMC0,DMC0总共有二片DRAM,每片128MB,因此,严谨的设置应该是0x2000_0000~0x27FF_FFFF, MemConfig1的设置是0x4000_0000~0x47FF_FFFF, 在设置DMC1的流程中,MemConfig0的地址范围可以设置为0x2800_0000~0x2FFF_FFFF, MemConfig1的地址范围设置为0x4800_0000~0x4FFF_FFFF), Mapping Method[15:12] (1:linterleaved), 10bit Column address, 14bit row address, 8 bank, 这样算下来容量不对,查手册得知,应该设置为13bit row address, 8 bank, revised设置:0x20F81313
str r1, [r0, #DMC_MEMCONFIG0] @ 0xF000_0008
ldr r1, =0x40F01323 @ MemConfig1 地址范围0x4000_0000~0x4FFF_FFFF, revised设置:0x40F81313
str r1, [r0, #DMC_MEMCONFIG1] @ 0xF000_000C
补充:
为了DRAM地址的连续性,4片128MB的DDR2可以占用地址空间0x3000_0000~0x4FFF_FFFF,
DMC0_MemConfig0: 0x3000_0000~0x37FF_FFFF
DMC1_MemConfig0: 0x3800_0000~0x3FFF_FFFF
DMC0_MemConfig1: 0x4000_0000~0x47FF_FFFF
DMC1_MemConfig1: 0x4800_0000~0x4FFF_FFFF
11. 设置PrechConfig和PwrdnConfig寄存器
ldr r1, =0xFF000000 @ PrechConfig no precharge for mem0 & mem1
str r1, [r0, #DMC_PRECHCONFIG] @ 0xF000_0014
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG] @ 0xF000_0028
12. 根据AC parameters时序参数设置TimingAref, TimingRow, TimingData和TimingPower寄存器
ldr r1, =0x00000618 @TimingAref 7.8us*200MHz=1560(0x618)
str r1, [r0, #DMC_TIMINGAREF] @ 0xF000_0030
ldr r1, =0x28233287
@TimingRow @200MHz tRFC[31:24]: 127.5ns/5ns+1, tRRD[23:20]: 7.5ns/5ns+1, tRP[19:16]: 15ns/5ns+1, tRCD[15:12]: 15ns/5ns+1, RC[11:6]: 60ns/5ns+1, tRAS[5:0]: 45ns/5ns+1, revised设置:0x1B34434A
str r1, [r0, #DMC_TIMINGROW] @ 0xF000_0034
ldr r1, =0x23240304
@TimingData @200Mhz tWTR[31:28]: 7.5ns/5ns+1, tWR[27:24]:15ns/5ns+1, tRTP[23:20]: 7.5ns/5ns+1, CL[19:16]=3, reserved[15:12], WL[11:8]: RL-1=3, reserved[7:4], RL[3:0]: 4 by default, AL=4-CL=1, revised设置:0x34330304
str r1, [r0, #DMC_TIMINGDATA] @ 0xF000_0038
ldr r1, =0x09C80232
@TimingPower reserved[31:30], tFAW[29:24]: 37.5ns/5ns+1, tXSR[23:16]: 200clk, tXP[15:8]: 2clk, tCKE[7:4]: 3clk, tMRD[3:0]: 2clk
str r1, [r0, #DMC_TIMINGPOWER] @ 0xF000_003C
13. 如果需要QoS,设置QosControl0~15和QosConfig0~15寄存器
14. 等待PhyStatus0.ctrl_locked置”1”(PHY DLL locked)
find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @ 0xF000_0040 Load Phystatus
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val
15. PHY DLL用于制程,电压,温度补偿,DLL开启更可靠,但如果频率很低DLL off也可以正常工作,可以关闭,基于PhyStatus0.ctrl_lock_value[9:2]设置PhyControl0.ctrl_force (BIT[31:24]), 清除PhyControl0.ctrl_dll_on (BIT[1])
and r1, #0x3fc0
@ ctrl_lock_value: bit[13:4], [9:2]相当于ignore最后2bit, 即[13:6]
mov r2, r1, LSL #18
@ LSL: 左移,相当于把ctrl_lock_value这8bit的值赋值到r2的bit[31:24] (DLL Force Delay),
orr r2, r2, #0x100000 @ set bit20, PhyControl0.ctrl_inc=0x10
orr r2 ,r2, #0x1000 @ set bit12, PhyControl0.start_point=0x10
orr r1, r2, #0x3 @ set bit0&1 PhyControl0.ctrl_dll_on&ctrl_start
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
orr r1, r2, #0x1 @ set bit 0 DLL off
str r1, [r0, #DMC_PHYCONTROL0]
16. 确认上电后时钟已经稳定200us
17. 通过DirectCmd寄存器发NOP命令,拉高CKE (DirectCmd见手册1.4.1.5)
ldr r1, =0x07000000 @ DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD] @ 0xF000_0010
18. 等待最小400ns
19. 通过DirectCmd寄存器发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
20. 发EMRS2命令写入工作参数
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
21. 发EMRS3命令写入工作参数
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
22. 发EMRS命令使能memory DLL
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
23. 发MRS命令reset memory DLL
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
24. 发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
25. 发二次Auto Refresh命令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
26. 发MRS命令写入工作参数而不reset memory DLL
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
27. 等待最少200个时钟周期
28. 发EMRS命令写入工作参数,如果没有使用OCD校准,发EMRS命令设定OCD Calibration Default
ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
29. 发EMRS命令退出OCD校准模式并写入工作参数
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]
30. 如果有两片DDR2,重新做第17步到29步
ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit)
31. 设置ConControl开启auto refresh counter (BIT5)
ldr r1, =0x0FF02030 @ConControl auto refresh on, revised: 0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
32. 如果需要使用power down模式,设置MemControl寄存器
ldr r1, =0x00212400
@MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]
一、S5PV210时钟系统
时钟:一定频率的电信号。 时钟系统:基于CMOS工艺的高性能处理器时钟系统,集成PLL可以从内部触发,比从外部触发更快且更准确,能有效地避免一些与信号完整性相关的问题。
S5pv210时钟系统,参考s5pv210手册第三章,CLOCK CONTROLLER
S5pv210时钟管理单元(CMU)主要了解了以下信息
1、时钟域:s5pv210主要由三个时钟域组成
a:MSYS域:Cortex A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、内部SRAM(IRAM和IROM)、INTC和配置接口(SPERI)。Cortex A8仅支持同步模式,因此必须与200MHz轴总线同步运行。
b:DSYS域:与显示相关的模块,包括FIMC、FIMD、JPEG和多媒体IP(X、L和T块中提到的所有其他IP)。都是和视频显示、编解码等有关的模块
c:PSY域:安全、I/O外围设备和低功耗音频播放。如串口、SD接口、I2C、AC97、USB等
每个总线系统分别以200兆赫(最大)、166兆赫和133兆赫运行。在两个不同的域之间有异步总线桥(BRG)。
S5Pv210由三个时钟域组成,即主系统(MSY)、显示系统(DSY)和外围系统(PSY)
2、时钟的声明
S5pv210的时钟包括两种:来自clock pads的时钟,来自CMU的时钟,跟来自USB PHY的时钟
a:来自CLOCK PADS的时钟包括几个晶振接口
•xrtcxti:使用xrtcxti和xrtcxto管脚指定32.768 kHz晶体板的时钟
•xxti:指定从带xxti和xxto针的水晶板的时钟
•xusbxti:指定带有xusbxti和xusbxto引脚的水晶板上的时钟
•xhdmixti:使用xhdmixti和xhdmixto管脚指定27MHz晶体板的时钟
b:来自时钟管理系统(CMU)的时钟
主要分为不同频段的控制输入,在典型的S5Pv210应用中,•Cortex A8和MSys时钟域使用APLL(即,ARMCLK、HCLK-MSY和PCLK-MSY)。
3、时钟的关系
三个时钟域(MSYS时钟域、DSY时钟域、PSY时钟域)对应都有不同对应的取值范围,每个高性能操作的值都对应不同的频率
4、时钟的生成
s5pv210时钟生成的逻辑框图如下
时钟生成器块还包括内置逻辑,用于在每次系统重置后稳定时钟频率,因为时钟在稳定之前需要时间。
s5pv210的两种类型MUX时钟开关:灰色时钟mux表示无故障时钟mux,如果更改时钟选择,则无故障时钟mux。白色的时钟mux代表非无故障时钟mux,在改变时钟源时可能会出现故障。
对于无故障多路复用器,应确保当时钟选择从一个更改为另一个时,两个时钟源都在运行。如果没有同时使用,对于非无故障时钟MUX,在更改时钟时可能会出现故障。时钟更改完成后,用户可以重新启用非无故障时钟MUX的输出,这样就不会因时钟更改而出现故障。非无故障多路复用器的屏蔽输出由时钟源控制寄存器处理。(下面还有时钟源控制寄存器的一些了解)
5、时钟配置程序
基本SFR配置流程:
打开PLL(A、M、E、V)PLL U CON[31]=1;//打开PLL(参考(A、M、E、V)PLL U CON SFR)
wait_lock_time;//等待PLL锁定
(a,m,e,v)pll_sel=1;//在pll输出时钟稳定后,选择pll输出时钟而不是输入参考时钟。
更改系统时钟分频器值clk_div0[31:0]=目标值0;
更改特殊时钟的除法器值clk_div1[31:0]=目标值1;
clk_div2[31:0]=目标值2;
6、S5PV210时钟设置寄存器
-xPLL_LOCK:控制PLL锁定频率的周期,譬如24MHZ变为1GHZ这段是需要一段时间的,通过一个锁相环使得把24MHZ锁定为1GHZ,所以就需要锁定频率的周期了。(锁定频率)
-xPLL_CON:打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等。(决定倍频到多少)
-CLK_SRCn(n:0~6):用来设置时钟来源的,对应时钟框图中的mux开关。(决定时钟来源)
-CLK_SRC_MASKn:打开关闭时钟源。(开头部分)
-CLK_DIV_STATn:各模块的分频参数配制。(决定分频多少)
-CLK_SRC_GATE_x:打开关闭时钟门。(结尾部分)
-CLK_DIV_STATn:分频状态寄存器,确保是否已经分频完成。
-CLK_MUX_STATn:选择开关状态寄存器,确保是否已经选择开关完毕。
7、时钟源控制寄存器
S5Pv210有许多时钟源,包括四个PLL输出、外部振荡器、外部时钟和来自GPIO的其他时钟源。CLK U SRCN寄存器控制每个时钟分频器的源时钟。
以此来设置时钟开关
时钟源寄存器(CLK U SRC0,R/W,地址=0XE010 U 0200)
在s5pv210手册中可以看到,所有的寄存器都是按块分的。我们可以找到一个寄存器的基地址,再通过基址加编址寻址的方式在找到寄存器。
8、后面还有s5pv210时钟的MUX状态SFR 以及各种时钟源开关太多了还没看完
二、s5pv210的内存初始化
1、SDRAM定义和特性
SDRAM:Syncronized Dynamic Ramdam Access Memory,同步动态随机存储器
DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double rate,双倍速度的SDRAM)
DDR有好多代:DDR1 DDR2 DDR3 DDR4 LPDDR
SDRAM的特性:容量大、价格低、掉电易失性、随机读写、总线式访问。
SDRAM在整个硬件系统中是属于外部设备,通过地址总线和数据总线接口与SoC通信
2、内存地址详解
3:寻址详解
在数据手册《NT5TU64M16GG-DDR2-1G-G-R18-Consumer》第10页的block diagram中,详解如上。
采用128Mb * 8 结构,每个Bank可寻址的大小是16MB,BA0-BA2用来选择8个Bank,寻址的方式:Row-Address+Column-Address。
故单内存芯片可寻址的大小为:16MB * 8 = 128MB
两片单芯片内存并联组合成32位数据总线,可与SoC进行总线通信,可寻址的内存大小便为:128MB+128MB= 256MB,在九鼎的开发板上采用了DRAM0+DRAM1分配内存地址,所以DRAM0和DRAM1都是256MB内存大小,合起来就是512MB内存大小。
所以开发板上DRAM0和DRAM1可寻址的有效范围分别为:
DRAM0:0x20000000 - 0x2FFFFFFF (256MB)
DRAM1:0x40000000 - 0x4FFFFFFF (256MB)
其他地址为非法地址,比如:0x30000000
4、SDRAM初始化详解
初始化过程包括phy dll初始化、设置控制器寄存器和内存初始化。内存初始化请参考JEDEC规范和内存设备数据表。有三种不同的内存类型,即lpddr、lpddr2和ddr2。根据内存类型,初始化顺序如下
1)、Lpddr内存初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言和保持CKE到逻辑的高水平。然后应用稳定时钟。注:xddr2sel应为低电平,以将CKE保持在高电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确的值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部内存芯片,也可以设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,不应为可靠运行而关闭。如果频率低,phy dll可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on bit-字段以关闭phy dll。
13、确认
14、通电后稳定时钟是否至少发出200us。使用directCmd寄存器发出pall命令。
15、使用directCmd寄存器发出两个自动刷新命令。
16、使用directcmd寄存器发出mrs命令以编程操作参数。1-3 S5Pv210_M 1 DRAM控制器
17、使用directcmd寄存器发出emrs命令以编程操作参数。
18、如果有两个外部存储芯片,则对Chip1存储设备执行步骤14~17。
19、将控制器设置为打开自动刷新计数器。
20、如果需要断电模式,请设置MEMControl寄存器。
2)lpddr2内存类型的初始化顺序:
1、为了给控制器和存储设备提供稳定的电源,控制器必须断言并将CKE保持在逻辑低水平。然后应用稳定时钟。注:xddr2sel应为高电平,以将CKE保持在低电平。
2、根据时钟频率将phycontrol0.ctrl_start_point和phycontrol0.ctrl_inc位字段设置为正确的值。将phycontrol0.ctrl_dll_on位字段设置为“1”以激活phy dll。
3、DQS清洗:根据时钟频率和内存TAC参数,将phycontrol1.ctrl_shiftc和phycontrol1.ctrl_offsetc位字段设置为正确值。
4、将phycontrol0.ctrl_开始位字段设置为“1”。
5、设置控制器。此时,应关闭自动刷新计数器。
6、设置memcontrol。此时,所有断电模式都应关闭。
7、设置memconfig0寄存器。如果有两个外部存储器芯片,则设置memconfig1寄存器。
8、设置prechconfig和pwrdconfig寄存器。
9、根据存储器交流参数设置正时参考、正时行、正时数据和正时功率寄存器。
10、如果需要QoS方案,请设置QosControl0~15和QosConfig0~15寄存器。
11、等待phystatus0.ctrl_locked位字段更改为“1”。检查phy dll是否被锁定。
12、phy dll可以补偿在内存操作过程中由进程、电压和温度(pvt)变化引起的延迟量的变化。因此,phy dll不应关闭以实现可靠的操作。除低频运行外,它可以关闭。如果使用关闭模式,请根据phystatus0将phycontrol0.ctrl_force位字段设置为正确的值。ctrl_lock_value[9:2]位字段用于固定延迟量。清除phycontrol0.ctrl_dll_on位字段以关闭phy dll。
13、将phycontrol1.fp_resync位字段设置为“1”以更新dll信息。
14、确认在通电后,CKE仍保持逻辑低电平至少100ns。
15、发出一个nop命令,使用directcmd寄存器断言和保持CKE到一个逻辑高级。
16、至少等待200us。 1-4 S5Pv210_M 1 DRAM控制器
17、使用directCmd寄存器发出mrs命令以重置内存设备并编程操作参数。
18、等待至少1us。
19、使用directcmd寄存器发出mrr命令来轮询mrstatus寄存器的dai位,以了解设备自动初始化是否完成。
20、如果有两个外部存储芯片,则对chip1存储设备执行步骤15~19。
21、将控制器设置为打开自动刷新计数器。22。如果需要断电模式,设置MEMControl寄存器。
3)DDR2内存类型的初始化顺序:
1. DMC及DDR2颗粒上电, 且电压稳定
2. DMC保持CKE为低电平
3. SOC提供时钟(XDDR2SEL保持高电平以保持CKE为低)
4. 根据实际工作时钟频率设置phyControl0.ctrl_start_point和PhyControl0.ctrl_inc
ldr r0, =APB_DMC_0_BASE @ 0xF000_0000
ldr r1, =0x00101000 @ ctrl_start_point: bit[15:8], ctrl_inc: bit[23:16], 按手册建议,这两位都设置为0x10
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
5. 设置PhyControl0.ctrl_dll_on为”1”, 以使能PHY DLL
ldr r1, =0x00101002 @ctrl_dll_on: bit[1]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
6. DQS Cleaning: 根据实际工作时钟频率和tAC设置PhyControl1.ctrl_shiftc和PhyControl1.ctrl_offsetc (可以和第7步互换顺序)
ldr r1, =0x00000086 @ ctrl_shiftc: bit[2:0], 手册建议设置为6 (DDR2); ctrl_offsetc: bit[14:8], 这里设置为”0”, ctrl_ref: bit[7:4], 默认值为0x4; 所以, 这里应该设置为0x00000046系统也能工作, 设置为”86”可能是原代码作者的错误
str r1, [r0, #DMC_PHYCONTROL1] @ 0xF000_001C
7. 置位PhyControl0.ctrl_start以启动DLL
ldr r1, =0x00101003 @ ctrl_start: bit[0]
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
8. 设置ConControl, 注意此时需要保证auto refresh counter off
ldr r1, =0x0FFF2010 @ default time out cycles: FFF; Read data fetch cycles: 2 (CL后再过2个周期latch数据), disable adaptive QoS, disable DQ swap, disable PHY driving (bi-directional pin拉低以省电, enable是不是更好?), disable read cycle gap for 2 different chips (应该是enable),auto refresh counter off, enable out of order scheduling, revise后的设置为(待测试):0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
9. 设置MemControl, 所有power down mode要关掉
ldr r1, =0x00202400 @ MemControl BL=4, 2 chip, 位宽x32 (是指通道位宽), DDR2 type, no additional latency for PALL, disable dynamic self refresh, disable timeout precharge, active/precharge power down, dynamic power down off, dynamic clock control: always running, revise后的设置为(待测试):0x00212400
str r1, [r0, #DMC_MEMCONTROL] @ 0xF000_0004
10. 设置MemControl0和MemControl1寄存器(如果有)
ldr r1, =0x20F01323 @ MemConfig0 设置地址范围0x2000_0000~0x2FFF_FFFF(再在设置的是DMC0,DMC0总共有二片DRAM,每片128MB,因此,严谨的设置应该是0x2000_0000~0x27FF_FFFF, MemConfig1的设置是0x4000_0000~0x47FF_FFFF, 在设置DMC1的流程中,MemConfig0的地址范围可以设置为0x2800_0000~0x2FFF_FFFF, MemConfig1的地址范围设置为0x4800_0000~0x4FFF_FFFF), Mapping Method[15:12] (1:linterleaved), 10bit Column address, 14bit row address, 8 bank, 这样算下来容量不对,查手册得知,应该设置为13bit row address, 8 bank, revised设置:0x20F81313
str r1, [r0, #DMC_MEMCONFIG0] @ 0xF000_0008
ldr r1, =0x40F01323 @ MemConfig1 地址范围0x4000_0000~0x4FFF_FFFF, revised设置:0x40F81313
str r1, [r0, #DMC_MEMCONFIG1] @ 0xF000_000C
补充:
为了DRAM地址的连续性,4片128MB的DDR2可以占用地址空间0x3000_0000~0x4FFF_FFFF,
DMC0_MemConfig0: 0x3000_0000~0x37FF_FFFF
DMC1_MemConfig0: 0x3800_0000~0x3FFF_FFFF
DMC0_MemConfig1: 0x4000_0000~0x47FF_FFFF
DMC1_MemConfig1: 0x4800_0000~0x4FFF_FFFF
11. 设置PrechConfig和PwrdnConfig寄存器
ldr r1, =0xFF000000 @ PrechConfig no precharge for mem0 & mem1
str r1, [r0, #DMC_PRECHCONFIG] @ 0xF000_0014
ldr r1, =0xFFFF00FF @PwrdnConfig
str r1, [r0, #DMC_PWRDNCONFIG] @ 0xF000_0028
12. 根据AC parameters时序参数设置TimingAref, TimingRow, TimingData和TimingPower寄存器
ldr r1, =0x00000618 @TimingAref 7.8us*200MHz=1560(0x618)
str r1, [r0, #DMC_TIMINGAREF] @ 0xF000_0030
ldr r1, =0x28233287
@TimingRow @200MHz tRFC[31:24]: 127.5ns/5ns+1, tRRD[23:20]: 7.5ns/5ns+1, tRP[19:16]: 15ns/5ns+1, tRCD[15:12]: 15ns/5ns+1, RC[11:6]: 60ns/5ns+1, tRAS[5:0]: 45ns/5ns+1, revised设置:0x1B34434A
str r1, [r0, #DMC_TIMINGROW] @ 0xF000_0034
ldr r1, =0x23240304
@TimingData @200Mhz tWTR[31:28]: 7.5ns/5ns+1, tWR[27:24]:15ns/5ns+1, tRTP[23:20]: 7.5ns/5ns+1, CL[19:16]=3, reserved[15:12], WL[11:8]: RL-1=3, reserved[7:4], RL[3:0]: 4 by default, AL=4-CL=1, revised设置:0x34330304
str r1, [r0, #DMC_TIMINGDATA] @ 0xF000_0038
ldr r1, =0x09C80232
@TimingPower reserved[31:30], tFAW[29:24]: 37.5ns/5ns+1, tXSR[23:16]: 200clk, tXP[15:8]: 2clk, tCKE[7:4]: 3clk, tMRD[3:0]: 2clk
str r1, [r0, #DMC_TIMINGPOWER] @ 0xF000_003C
13. 如果需要QoS,设置QosControl0~15和QosConfig0~15寄存器
14. 等待PhyStatus0.ctrl_locked置”1”(PHY DLL locked)
find_lock_val:
ldr r1, [r0, #DMC_PHYSTATUS] @ 0xF000_0040 Load Phystatus
and r2, r1, #0x7
cmp r2, #0x7 @Loop until DLL is locked
bne find_lock_val
15. PHY DLL用于制程,电压,温度补偿,DLL开启更可靠,但如果频率很低DLL off也可以正常工作,可以关闭,基于PhyStatus0.ctrl_lock_value[9:2]设置PhyControl0.ctrl_force (BIT[31:24]), 清除PhyControl0.ctrl_dll_on (BIT[1])
and r1, #0x3fc0
@ ctrl_lock_value: bit[13:4], [9:2]相当于ignore最后2bit, 即[13:6]
mov r2, r1, LSL #18
@ LSL: 左移,相当于把ctrl_lock_value这8bit的值赋值到r2的bit[31:24] (DLL Force Delay),
orr r2, r2, #0x100000 @ set bit20, PhyControl0.ctrl_inc=0x10
orr r2 ,r2, #0x1000 @ set bit12, PhyControl0.start_point=0x10
orr r1, r2, #0x3 @ set bit0&1 PhyControl0.ctrl_dll_on&ctrl_start
str r1, [r0, #DMC_PHYCONTROL0] @ 0xF000_0018
orr r1, r2, #0x1 @ set bit 0 DLL off
str r1, [r0, #DMC_PHYCONTROL0]
16. 确认上电后时钟已经稳定200us
17. 通过DirectCmd寄存器发NOP命令,拉高CKE (DirectCmd见手册1.4.1.5)
ldr r1, =0x07000000 @ DirectCmd chip0 Deselect
str r1, [r0, #DMC_DIRECTCMD] @ 0xF000_0010
18. 等待最小400ns
19. 通过DirectCmd寄存器发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
20. 发EMRS2命令写入工作参数
ldr r1, =0x00020000 @DirectCmd chip0 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
21. 发EMRS3命令写入工作参数
ldr r1, =0x00030000 @DirectCmd chip0 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
22. 发EMRS命令使能memory DLL
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
23. 发MRS命令reset memory DLL
ldr r1, =0x00000542 @DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
24. 发PALL命令
ldr r1, =0x01000000 @DirectCmd chip0 PALL
str r1, [r0, #DMC_DIRECTCMD]
25. 发二次Auto Refresh命令
ldr r1, =0x05000000 @DirectCmd chip0 REFA
str r1, [r0, #DMC_DIRECTCMD]
26. 发MRS命令写入工作参数而不reset memory DLL
ldr r1, =0x00000442 @DirectCmd chip0 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
27. 等待最少200个时钟周期
28. 发EMRS命令写入工作参数,如果没有使用OCD校准,发EMRS命令设定OCD Calibration Default
ldr r1, =0x00010780 @DirectCmd chip0 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
29. 发EMRS命令退出OCD校准模式并写入工作参数
ldr r1, =0x00010400 @DirectCmd chip0 EMRS1 (OCD exit)
str r1, [r0, #DMC_DIRECTCMD]
30. 如果有两片DDR2,重新做第17步到29步
ldr r1, =0x07100000 @DirectCmd chip1 Deselect
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00120000 @DirectCmd chip1 EMRS2
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00130000 @DirectCmd chip1 EMRS3
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (MEM DLL on, DQS# disable)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100542 @DirectCmd chip1 MRS (MEM DLL reset) CL=4, BL=4
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x01100000 @DirectCmd chip1 PALL
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x05100000 @DirectCmd chip1 REFA
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00100442 @DirectCmd chip1 MRS (MEM DLL unreset)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110780 @DirectCmd chip1 EMRS1 (OCD default)
str r1, [r0, #DMC_DIRECTCMD]
ldr r1, =0x00110400 @DirectCmd chip1 EMRS1 (OCD exit)
31. 设置ConControl开启auto refresh counter (BIT5)
ldr r1, =0x0FF02030 @ConControl auto refresh on, revised: 0x0FFF23D0
str r1, [r0, #DMC_CONCONTROL] @ 0xF000_0000
32. 如果需要使用power down模式,设置MemControl寄存器
ldr r1, =0x00212400
@MemControl BL=4, 2 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
str r1, [r0, #DMC_MEMCONTROL]