S5PV210时钟

S5PV210时钟方式

外部晶振+内部时钟发生器+内部PLL产生高频时钟+内部分频器分频得到各种频率的时钟

时钟域概念

因为S5PV210的时钟体系比较复杂,内部外设模块太多,所以把整个内部的时钟分为3个时钟域。如下图:

这里写图片描述

  1. MSYS Domain: CPU(Cortex-A8内核)、DRAM控制器(DMC0和DMC1)、IRAM和IROM、3D模块等等。
  2. DSYS Domain: 与视频显示、编解码相关的模块,如HDMI
  3. PSYS Domain : 和内部的各种外设时钟有关,譬如串口、SD接口、I2C、SPI、USB等。

    S5PV210 把时钟分为3个时钟域是为了把高低速时钟频率相互独立开,能够适应各种内设和外设模块。

时钟来源

S5PV210外部有4个时钟接口,可以接4个外部晶振共SoC使用,SoC接上外部晶振上电后就可产生原始时钟,继而进行倍频产生高频时钟,再经过各种分频,产生各个模块需要的高速和低速时钟。如下图所示:
这里写图片描述

其中:
XRTCXT1:用于产生时钟频率,32.768KHz,通常用于时钟频率,也可用于System Timer,比较少用。
XXTI:用于系统定时器,长用于产生系统时钟,官方推荐使用24MHz的晶振。因为IROM被设计成基于24MHz的时钟输入。
XUSBXTI:长用于USB时钟,也可用于系统定时器,产生系统时钟,官方推荐使用24MHz的晶振。因为IROM被设计成基于24MHz的时钟输入。
XHDMIXTI:专用于HDMI模块,产生HDMI时钟,官方推荐使用27MHz的晶振。,因为VPLL或HDMI PHY 用于TV解码需要产生54MHz的时钟。

24MHz的时钟源经过SoC的倍频后会产生4个倍频器,分别是:APLL、MPLL、EPLL、VPLL。
APLL产生的倍频范围是:30MHz~1GHz
MPLL产生的倍频范围是:50MHz~2GHz
EPLL产生的倍频范围是:10MHz~600MHz
VPLL产生的倍频范围是:10MHz~600MHz
通常USB-OTG PHY使用XUSBXTI产生30MHz和48MHz,HDMI PHY使用XUSBXTI或XHDIMXTI产生54MHz
在S5PV210的应用中,通常Cortex A8内核和MSYS Clock时钟域使用APLL倍频
DSYS 时钟域和PSYS 时钟域和其他外设使用MPLL和EPLL倍频
而视频时钟则使用VPLL倍频

S5PV210的三个时钟域详解

S5PV210内部的各个外设都是接在(内部的AMBA总线)总线上的,AMBA总线有一条高频分支AHB和一条低频分支APB。
每个域都有各自对应的高频分支和低频分支,分别是:HCLK_XXX和HCLK_XXX,HCLK_XXX是高频分支,PCLK_XXX是低频分支。
这里写图片描述

在IROM代码中执行时第6步中初始化了时钟系统,这时给了系统一个默认推荐的运行频率。
这里写图片描述

这个时钟频率是三星推荐的S5PV210工作性能和稳定性最好的频率。
这里写图片描述
这里写图片描述

时钟框图详细

  1. 时钟分频框图
    这里写图片描述
  2. 各个外设的详细时钟分频框图
    这里写图片描述

    第一张图从左到右依次完成了原始时钟生产->PLL倍频得到高频时钟。
    第二张图从各中间时钟(第一张图中某个某个步骤生成的时钟)到各外设自己使用的外设(实际就是个别外设自己再额外分频的设置)
    图中两个比较重要的符号的作用,MUX开关和DIV分频器
    MUX开关就是个或门,实际对应摸个寄存器的某几个bit位的位置,设置值决定了哪条通道通的,分析这个可以知道右边的时钟是从哪条路来的,从而知道右边时钟是多少。

时钟初始化代码

// 时钟控制器基地址
#define ELFIN_CLOCK_POWER_BASE      0xE0100000  

// 时钟相关的寄存器相对时钟控制器基地址的偏移值
#define APLL_LOCK_OFFSET        0x00        
#define MPLL_LOCK_OFFSET        0x08

#define APLL_CON0_OFFSET        0x100
#define APLL_CON1_OFFSET        0x104
#define MPLL_CON_OFFSET         0x108

#define CLK_SRC0_OFFSET         0x200
#define CLK_SRC1_OFFSET         0x204
#define CLK_SRC2_OFFSET         0x208
#define CLK_SRC3_OFFSET         0x20c
#define CLK_SRC4_OFFSET         0x210
#define CLK_SRC5_OFFSET         0x214
#define CLK_SRC6_OFFSET         0x218
#define CLK_SRC_MASK0_OFFSET    0x280
#define CLK_SRC_MASK1_OFFSET    0x284

#define CLK_DIV0_OFFSET         0x300
#define CLK_DIV1_OFFSET         0x304
#define CLK_DIV2_OFFSET         0x308
#define CLK_DIV3_OFFSET         0x30c
#define CLK_DIV4_OFFSET         0x310
#define CLK_DIV5_OFFSET         0x314
#define CLK_DIV6_OFFSET         0x318
#define CLK_DIV7_OFFSET         0x31c

#define CLK_DIV0_MASK           0x7fffffff
// 这些M、P、S的配置值都是查数据手册中典型时钟配置值的推荐配置得来的。
// 这些配置值是三星推荐的,因此工作最稳定。如果是自己随便瞎拼凑出来的那就要
// 经过严格测试,才能保证一定对。
#define APLL_MDIV               0x7d        // 125
#define APLL_PDIV               0x3
#define APLL_SDIV               0x1

#define MPLL_MDIV               0x29b       // 667
#define MPLL_PDIV               0xc
#define MPLL_SDIV               0x1

#define set_pll(mdiv, pdiv, sdiv)   (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define APLL_VAL            set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_VAL            set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

#define REG_CLK_SRC0    (ELFIN_CLOCK_POWER_BASE + CLK_SRC0_OFFSET)
#define REG_APLL_LOCK   (ELFIN_CLOCK_POWER_BASE + APLL_LOCK_OFFSET)
#define REG_MPLL_LOCK   (ELFIN_CLOCK_POWER_BASE + MPLL_LOCK_OFFSET)
#define REG_CLK_DIV0    (ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET)
#define REG_APLL_CON0   (ELFIN_CLOCK_POWER_BASE + APLL_CON0_OFFSET)
#define REG_MPLL_CON    (ELFIN_CLOCK_POWER_BASE + MPLL_CON_OFFSET)

#define rREG_CLK_SRC0   (*(volatile unsigned int *)REG_CLK_SRC0)
#define rREG_APLL_LOCK  (*(volatile unsigned int *)REG_APLL_LOCK)
#define rREG_MPLL_LOCK  (*(volatile unsigned int *)REG_MPLL_LOCK)
#define rREG_CLK_DIV0   (*(volatile unsigned int *)REG_CLK_DIV0)
#define rREG_APLL_CON0  (*(volatile unsigned int *)REG_APLL_CON0)
#define rREG_MPLL_CON   (*(volatile unsigned int *)REG_MPLL_CON)

void clock_init(void)
{
    // 1 设置各种时钟开关,暂时不使用PLL
    rREG_CLK_SRC0 = 0x0;

    // 2 设置锁定时间,使用默认值:0x0FFF,保险起见我们设置为0xFFFF
    // 设置PLL后,时钟从Fin提升到目标频率时,需要一定的时间,即锁定时间
    rREG_APLL_LOCK = 0x0000ffff;
    rREG_MPLL_LOCK = 0x0000ffff;

    // 3 设置分频
    // 清bit[0~31]
    rREG_CLK_DIV0 = 0x14131440;

    // 4 设置PLL
    // FOUT = MDIV*FIN/(PDIV*2^(SDIV-1))=0x7d*24/(0x3*2^(1-1))=1000 MHz
    rREG_APLL_CON0 = APLL_VAL;
    // FOUT = MDIV*FIN/(PDIV*2^SDIV)=0x29b*24/(0xc*2^1)= 667 MHz
    rREG_MPLL_CON = MPLL_VAL;

    // 5 设置各种时钟开关,使用PLL
    rREG_CLK_SRC0 = 0x10001111;
}

时钟设置的寄存器详解

在寄存器中,clock source x - 设置MUX开关,clock divider control - 设置分频系数
涉及到的寄存器,可以参考官方数据手册里的section 02_system -> 3 CLOCK CONTROLLER ->3.7章节的内容。

xPLL_LOCK 寄存器:主要控制PLL锁定周期的。x : A/M/E/V

这里写图片描述

xPLL_CON/xPLL_CON0/xPLL_CON1 寄存器:主要是用来打开/关闭PLL电路,设置PLL的倍频产生,查看PLL锁定状态等

三星官方推荐设置参数:

这里写图片描述

APLL_CON0和APLL_CON1寄存器:

这里写图片描述

APLL_CON1寄存器暂时未用到

这里写图片描述

CLK_SRCn(n:0~6)寄存器:用来设置时钟源的,对应时钟框图中的MUX开关。

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

CLK_SRC_MASKn(n:0~1)寄存器:决定MUX开关n选1后是否能继续通过。默认的时钟都是打开的。

这里写图片描述
这里写图片描述

CLK_DIVn(n:0~7)寄存器:设置各模块的参数配置

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

CLK_GATE_x寄存器:类似于CLK_SRC_MASK,对时钟进行开关控制。不常用。
CLK_DIV_STATn(n:0~1)寄存器:查看DIV的状态是否已经完成还是在进行中

这里写图片描述
这里写图片描述

CLK_MUX_STATn(n:0~1)寄存器:查看MUX的状态是否已经完成还是在进行中

这里写图片描述
这里写图片描述

总结:最重要的有三类寄存器,分别是CON、SRC、DIV。其中CON决定PLL倍频多少,SRC决定走哪一条路,DIV决定分频多少。


转自:https://blog.csdn.net/vanity_lost/article/details/52563708?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值