资料丨迅为IMX6ULL开发板-主频和时钟配置例程(二)
接上篇内容:如下
这个寄存器我们用到两个位:
STEP_SEL:选择 setp_clk 时钟源。
PLL1_SW_CLK_SEL:选择 pll1_sw_clk 时钟源。
到此,我们可以简单整理下修改主频思路:
1. 设置 CCSR 的 STEP_SEL 位,设置 step_clk 的时钟源为 24M。
2. 设置 CCSR 的 PLL1_SW_CLK_SEL 位,设置 pll1_sw_clk 的时钟源 step_clk=24MHz,通过这一步我们就将 I.MX6ULL 的主频先设置为 24MHz,直接来自于外部的 24M 时钟晶振。
3. 设置 CCM_ANALOG_PLL_ARMn,将 pll1_main_clk(PPL1)设置为 1056MHz。
4. 设置 CCSR 的 PLL1_SW_CLK_SEL 位,重新将 pll1_sw_clk 的时钟源切换回 pll1_main_clk,切换回
来以后的 pll1_sw_clk 就等于 1056MHz。
5. 设置 CCM_CACRR 的 ARM_PODF 为 2 分频,内核主频就是 1056/2=528MHz。PFD 时钟
我们还需要设置好其他的 PLL 和 PFD 时钟,PLL1 上一小节已经设置了,其他的 PPL 时钟有的是固定的
(PPL2-528MHz,PPL3-480MHz,PPL7-480MHz),有的暂时可以不需要设置(PPL4,PPL5,PPL6 分别对应音视频和网络)。
接下来就是设置 PFD 时钟。恩智浦有官方推荐数值如下表:
PLL2 的 4 路 PFD 频率,用到寄存器是 CCM_ANALOG_PFD_528n,寄存器结构如图 15.1.13 所示:
>
寄存器 CCM_ANALOG_PFD_528n 分为四组,分别对应 PFD0~PFD3,每组 8 个 bit,我们就以 PFD0 为例,看一下如何设置 PLL2_PFD0 的频率。
PFD0 对应的寄存器位如下:
PFD0_FRAC:PLL2_PFD0 的分频数,PLL2_PFD0 的计算公式为 528*18/PFD0_FRAC,可设置的范围为 12~35。
PFD0_STABLE:只读位,通过此位判断 PLL2_PFD0 是否稳定,新分频生效时此位取反。
PFD0_CLKGATE:PLL2_PFD0 输出使能位。1 表示关闭 PLL2_PFD0 输出;0 表示使能 PLL2_PFD0 输出
PLL2_PFD0 的频率为 352MHz,需要设置 PFD0_FRAC=528*18/352=27,PFD0_CLKGATE 为 0。
PLL2_PFD1~PLL2_PFD3 设置类似,频率计算公式都是 528*18/PFDX_FRAC(X=1~3),因此 PLL2_PFD1=594MHz的话,PFD1_FRAC=16;PLL2_PFD2=400MHz 的话,(PFD2_FRAC 不能整除,取最近的整数值)PFD2_FRAC=24,
实际为 396MHz;PLL2_PFD3=297MHz 的话,PFD3_FRAC=32。
接下来配置 PLL3_PFD0~PLL3_PFD3 这 4 路 PFD 的频率,使用到的寄存器是 CCM_ANALOG_PFD_480n,此寄存器结构如图 15.1.14 所示:
寄存器 CCM_ANALOG_PFD_480n 和 CCM_ANALOG_PFD_528n 的结构是一模一样的,寄存器位的含义也是一样的,只是频率计算公式不同,频率计算公式为 PLL3_PFDX=480*18/PFDX_FRAC(X=0~3)
设置 PLL3_PFD0=720MHz,PFD0_FRAC=12;
设置 PLL3_PFD1=540MHz,PFD1_FRAC=16;
设置 PLL3_PFD2=508.2MHz,PFD2_FRAC=17;
设置 PLL3_PFD3=454.7MHz,PFD3_FRAC=19。
AHB、IPG 和 PERCLK 根时钟
iMX6ULL 外设根时钟可设置范围如图 15.1.15 所示:
这里给大多数外设的根时钟设置范围,AHB_CLK_ROOT 最高可以设置 132MHz,IPG_CLK_ROOT 和PERCLK_CLK_ROOT 最高可以设置 66MHz。我们将 AHB_CLK_ROOT、IPG_CLK_ROOT 和 PERCLK_CLK_ROOT 分别设置为 132MHz、66MHz、66MHz。AHB_CLK_ROOT 和 IPG_CLK_ROOT 的设置如图 15.1.16 所示:
上图就是 AHB_CLK_ROOT 和 IPG_CLK_ROOT 的时钟图,图中分为了 4 部分:
1. 用来选择 pre_periph_clk 的时钟源,可以选择 PLL2、PLL2_PFD2、PLL2_PFD0 和 PLL2_PFD2/2。寄存 器 CCM_CBCMR 的 PRE_PERIPH_CLK_SEL 位 决 定 选 择 哪 一 个 , 默 认 选 择 PLL2_PFD2 , 因 此 默 认pre_periph_clk=PLL2_PFD2=396MHz。
2. 用来选择 periph_clk 的时钟源,由寄存器 CCM_CBCDR 的 ERIPH_CLK_SEL 位与 PLL_bypass_en2 组成的或门来选择。当 CCM_CBCDR 的 PERIPH_CLK_SEL 位为 0 的时候 periph_clk=pr_periph_clk=396MHz。
3. 通 过 CBCDR 的 AHB_PODF 位 来 设 置 AHB_CLK_ROOT 的 分 频 值 , 1~8 分 频 8 种 , 如 果 想 要AHB_CLK_ROOT=132MHz 的话就应该设置为 3 分频(默认):396/3=132MHz。
4. 通过 CBCDR 的 IPG_PODF 位来设置 IPG_CLK_ROOT 的分频值,1~4 分频 4 种,IPG_CLK_ROOT 时钟源是 AHB_CLK_ROOT,要想 IPG_CLK_ROOT=66MHz 的话就应该设置 2 分频(默认):132/2=66MHz。
最后要配置 PERCLK_CLK_ROOT 时钟频率。如图 15.1.17 所示:
可以看出,PERCLK_CLK_ROOT 时钟来源有两个,OSC(24MHz)和 IPG_CLK_ROOT,由寄存器 CCM_CSCMR1的 PERCLK_CLK_SEL 决定,如果该位为 0,则 PERCLK_CLK_ROOT 的时钟源是 IPG_CLK_ROOT=66MHz,可以通过设置寄存器 CCM_CSCMR1 的 PERCLK_PODF 位来配置分频,我们需要 66MHz 的 PERCLK_CLK_ROOT,所以这里配置为 1 分频。
在上面的设置中用到了三个寄存器。
寄存器 CCM_CBCDR 结构图如图 15.1.18:
该寄存器各位解释如下:
PERIPH_CLK2_PODF:periph2 时钟分频,可设置 1~8 分频 8 种。
PERIPH2_CLK_SEL:选择 peripheral2 的主时钟,修改此位会引起一次与 MMDC 的握手,修改完成以后要等待握手完成,握手完成信号由寄存器CCM_CDHIPR中指定位表示。为0选择PLL2;为1选择periph2_clk2_clk。PERIPH_CLK_SEL:peripheral 主时钟选择,修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握 手完成, 握手完成 信号由寄 存器 CCM_CDHIPR 中指定 位表示。 为 0 选择 PLL2;为 1 选择periph_clk2_clock。
AXI_PODF:axi 时钟分频,可设置 1~8 分频 8 种。
AHB_PODF:ahb 时钟分频,可设置 1~8 分频 8 种。修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
IPG_PODF:ipg 时钟分频,可设置 1~4 分频 4 种。
AXI_ALT_CLK_SEL:axi_alt 时钟选择。为 0 选择 PLL2_PFD2;为 1 选择 PLL3_PFD1。
AXI_CLK_SEL:axi 时钟源选择。为 0 选择 periph_clk;为 1 选择 axi_alt 时钟。
FABRIC_MMDC_PODF:fabric/mmdc 时钟分频设置,可设置 1~8 分频 8 种。
PERIPH2_CLK2_PODF:periph2_clk2 的时钟分频,可设置 1~8 分频 8 种。
寄存器 CCM_CBCMR 结构图图 15.1.19:
寄存器各个位的解释如下:
LCDIF1_PODF:lcdif1 的时钟分频,可设置 1~8 分频 8 种。
PRE_PERIPH2_CLK_SEL:pre_periph2 时钟源选择。为 00 选择 PLL2,为 01 选择 PLL2_PFD2,为 10 选择PLL2_PFD0,为 11 选择 PLL4。
PERIPH2_CLK2_SEL:periph2_clk2 时钟源选择。为 0 选择 pll3_sw_clk,为 1 选择 OSC。
PRE_PERIPH_CLK_SEL:pre_periph 时钟源选择。为 00 选择 PLL2,为 01 选择 PLL2_PFD2,为 10 选择
PLL2_PFD0,为 11 选择 PLL2_PFD2/2。
PERIPH_CLK2_SEL:peripheral_clk2 时钟源选择。为 00 选择 pll3_sw_clk,为 01 选择 osc_clk,为 10 选择pll2_bypass_clk。
接下来是寄存器 CCM_CSCMR1,结构如图 15.1.20 所示:
该寄存器我们主要用到 PERCLK_CLK_SEL 和 PERCLK_PODF 位,解释如下:
PERCLK_CK_SEL:perclk 时钟源选择。为 0 选择 ipg clk,为 1 选择 osc clk。
PERCLK_PODF:perclk 的时钟分频,可设置 1~8 分频 8 种。
这里要注意,我们在修改配置如下时钟选择器或者分频器的时候会引起与 MMDC 的握手发生:
1.mmdc_podf,2.periph_clk_sel,3.periph2_clk_sel,4.arm_podf,5.ahb_podf。在发生握手信号后需等待握手完成,寄存器 CCM_CDHIPR 中保存着握手信号是否完成,如果相应的位为 1 的话就表示握手没有完成,如果为 0 的话就表示握手完成,很简单,这里就不一一列举寄存器 CCM_CDHIPR 中的各个位了。
在修改 arm_podf 和 ahb_podf 时,要先关闭其时钟输出,等修改完成之后再开启,否则的话可能会出现在修改完成以后没有时钟输出的现象。
至此,iMX6ULL 的时钟系统就讲解完了,iMX6ULL 的时钟系统相对很复杂,大家要结合《I.MX6ULL 参考手册.pdf》中时钟相关的结构图来学习。