I.MX6U 的系统主频为 528MHz,有些型号可以跑到 696MHz,但是默认情况下内部 bootrom 会将 I.MX6U 的主频设置为 396MHz。
1.1 时钟原理图
系统时钟来源于两部分:32.768KHz 和24MHz 的晶振,其中 32.768KHz 晶振是 I.MX6U 的 RTC 时钟源,24MHz 晶振是 I.MX6U 内核和其它外设的时钟源.

1.2 7路PLL时钟源
不同的外设时钟源不同,NXP 将这些外设时钟源进行了分组,共 7 组,这7组时钟源都是从 24MHz 晶振 PLL 而来的。

1.2.1 ARM_PLL(PLL1)(内核时钟)
此路 PLL 是供 ARM 内核使用的,ARM 内核时钟就是由此 PLL 生成的
此 PLL 通过编程的方式最高可倍频到 1.3GHz。.
1.2.2 528_PLL(PLL2)(系统时钟,可用于其他外设)
也叫 System_PLL,固定的 22 倍频,不可编程。 PLL 时钟=24MHz * 22 = 528MHz
此 PLL 分出了 4 路 PFD,分别为:PLL2_PFD0~PLL2_PFD3,这 4 路 PFD 和 528_PLL 共同作为其它很多外设的根时钟源。
通常 528_PLL 和这 4 路 PFD 是 I.MX6U 内部系统总线的时钟源,比如内处理逻辑单元、DDR 接口、NAND/NOR 接口等等。
1.2.3 USB1_PLL(PLL3)(USBPHY,可用于其他外设)
此路 PLL 主要用于 USBPHY,此 PLL 也有四路 PFD,为:PLL3_PFD0~PLL3_PFD3
USB1_PLL 是固定的 20 倍频, 因此 USB1_PLL=24MHz *20=480MHz。
USB1_PLL虽然主要用于USB1PHY, 但是其和四路PFD同样也可以作为其他外设的根时钟源。
1.2.4 USB2_PLL(PLL7,没有写错)(USB2PHY,可用于其他外设)
此路PLL是给USB2PHY使用的。 同样的, 此路PLL固定为20倍频, 因此也是480MHz。
1.2.5 ENET_PLL(PLL6)(网络时钟)
此路 PLL 固定为 20+5/6 倍频,因此 ENET_PLL=24MHz * (20+5/6) = 500MHz。
此路 PLL 用于生成网络所需的时钟, 可以在此 PLL 的基础上生成 25/50/100/125MHz的网络时钟。
1.2.6 VIDEO_PLL(PLL5)(显示时钟,如LCD)
此路 PLL 用于显示相关的外设,比如 LCD,此路 PLL 的倍频可以调整
PLL 的输出范围在 650MHz~1300MHz。此路 PLL 在最终输出的时候还可以进行分频,可选 1/2/4/8/16 分频。
1.2.7 AUDIO_PLL(PLL4)(音频时钟)
此路 PLL 用于音频相关的外设,此路 PLL 的倍频可以调整
PLL的输出范围同样也是 650MHz~1300MHz,此路 PLL 在最终输出的时候也可以进行分频,可选1/2/4 分频。
1.3 时钟树
分为三部分,CLOCK_SWITCHER、CLOCK ROOT GENERATOR 和SYSTEM CLOCKS。
CLOCK_SWITCHER:就是 7 路 PLL 和8 路 PFD。
CLOCK ROOT GENERATOR:为CLOCK_SWITCHER和SYSTEM CLOCKS连接的。
SYSTEM CLOCKS:芯片外设。

1.3.1 以ESAI 外设为例

①、此部分是时钟源选择器,ESAI 有 4 个可选的时钟源:PLL4、PLL5、PLL3_PFD2 和pll3_sw_clk 。
由 寄 存 器 CCM->CSCMR2 的ESAI_CLK_SEL 位来决定。

②、 此部分是 ESAI 时钟的前级分频, 分频值由寄存器 CCM_CS1CDR 的 ESAI_CLK_PRED来确定的,可设置 1~8 分频.
假如现在 PLL4=650MHz,选择 PLL4 作为 ESAI 时钟,前级分频选择 2 分频,此时时钟650/2=325MHz。
③、分频器,进一步分频,分频值由寄存器CCM_CS1CDR 的 ESAI_CLK_PODF 来决定,可设置 1~8 分频。
假如我们设置为 8 分频的话,经过此分频器以后的时钟就是 325/8=40.625MHz。进入 ESAI 外设的时钟就是40.625MHz。
关于外设时钟配置相关内容全部都在《I.MX6ULL 参考手册》的第 18 章。
1.4 内核时钟设置
1.4.1 主频 528MHz
将 I.MX6U 的主频设置为 528MHz。ARM内核时钟如图示:

①、内核时钟源来自于 PLL1,假如此时 PLL1 为 996MHz。
②、 通过寄存器 CCM_CACRR 的 ARM_PODF 位对 PLL1 进行分频, 可选择 1/2/4/8 分频,
假如我们选择 2 分频,那么经过分频以后的时钟频率是 996/2=498MHz。
③、大家不要被此处的 2 分频给骗了,此处没有进行 2 分频
(我就被这个 2 分频骗了好久,主频一直配置不正确!)。
④、经过第②步 2 分频以后的 498MHz 就是 ARM 的内核时钟,也就是 I.MX6U 的主频。
假如设置内核主频为 528MHz, PLL1 可以设置为1056MHz,CCM_CACRR 的 ARM_PODF 位设置为 2 分频即可。
同理,将主频设置为 696MHz, PLL1 就可以设置为696MHz,CCM_CACRR 的 ARM_PODF 设置为 1 分频即可。
1.4.1.1 寄存器 CCM_CACRR (分频系数)
只有 ARM_PODF 位,可以设置为 0~7,分别对应 1~8 分频。如果要设置为2分频的话CCM_CACCR就要设置为1。

1.4.1.2 寄存器 CCM_ANALOG_PLL_ARMn (时钟频率)
ENABLE: 时钟输出使能位,此位设置为 1 使能 PLL1 输出, 如果设置为 0 的话就关闭 PLL1输出。
DIV_SELECT: 设置输出频率,范围为:54~108,PLL1 CLK = Fin *div_seclec/2.0,Fin=24MHz。
如果 PLL1 要输出 1056MHz 的话,div_select 就要设置为 88。

1.4.2 时钟源
修改 PLL1 时钟频率的时候需要先将内核时钟源改为其他的时钟源。
①、pll1_sw_clk 也就是 PLL1 的最终输出频率。
②、选择器,选择 pll1_sw_clk 的时钟源,由寄存器 CCM_CCSR 的PLL1_SW_CLK_SEL 位决定 pll1_sw_clk 是选择 pll1_main_clk 还是 step_clk。
正常情况下应该选择 pll1_main_clk,但是如果要对 pll1_main_clk(PLL1)的频率进行调整的话,比如我们要设置PLL1=1056MHz,此时就要先将 pll1_sw_clk 切换到 step_clk 上。等 pll1_main_clk 调整完成以后再切换回来。
③、选择器,选择 step_clk 的时钟源, 由寄存器 CCM_CCSR 的 STEP_SEL 位来决定 step_clk 是选择 osc_clk 还是 secondary_clk。一般选择 osc_clk,也就是 24MHz 的晶振。

1.4.2.1 寄存器 CCM_CCSR(选择时钟源)
①、设置寄存器 CCSR 的 STEP_SEL 位,设置 step_clk 的时钟源为 24M 的晶振。
②、设置寄存器 CCSR 的 PLL1_SW_CLK_SEL 位,设置 pll1_sw_clk 的时钟源为step_clk=24MHz,将 I.MX6U 的主频先设置为 24MHz,直接来自于外部的24M 晶振。
③、设置寄存器 CCM_ANALOG_PLL_ARMn,将 pll1_main_clk(PLL1)设置为 1056MHz。
④、设置寄存器 CCSR 的 PLL1_SW_CLK_SEL 位,重新将 pll1_sw_clk 的时钟源切换回
pll1_main_clk,切换回来以后的 pll1_sw_clk 就等于 1056MHz。
⑤、最后设置寄存器 CCM_CACRR 的 ARM_PODF 为 2 分频,I.MX6U 的内核主频就为1056/2=528MHz。

1.5 PFD 时钟设置(PLL的子时钟?)
PLL2、PLL3 和 PLL7 固定为 528MHz、480MHz 和 480MHz,PLL4~PLL6 都是针对特殊外设的,用到的时候再设置。
重点就是设置 PLL2 和 PLL3 的各自 4 路 PFD,NXP 推荐的这 8 路 PFD 频率如图示:

1.5.1 PLL2 的 4 路 PFD 频率(寄存器 CCM_ANALOG_PFD_528n)
寄存器 CCM_ANALOG_PFD_528n 其实分为四组,分别对应PFD0~PFD3,每组 8 个 bit。

以 PFD0 为例,看一下如何设置 PLL2_PFD0 的频率
PFD0_FRAC: PLL2_PFD0 的分频数,PLL2_PFD0 的计算公式为528x18/PFD0_FRAC,此为可设置的范围为 12~35 。
如 果 PLL2_PFD0 的 频 率 要 设 置 为 352MHz 的话,PFD0_FRAC=528x18/352=27。
PFD0_STABLE: 此位为只读位,可以通过读取此位判断 PLL2_PFD0 是否稳定。
PFD0_CLKGATE: PLL2_PFD0 输出使能位,为 1 的时候关闭 PLL2_PFD0 的输出,为 0 的时候使能输出。
如果要设置 PLL2_PFD0 的频率为 352MHz 的话需要设置 PFD0_FRAC 为 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,
这样 PLL2_PFD2 实际为 396MHz;PLL2_PFD3=297MHz 的话,PFD3_FRAC=32。
1.5.2 PLL3 的 4 路 PFD 频率(寄存器 CCM_ANALOG_PFD_480n )
寄存器 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。

1.6 AHB 、IPG 和 和 PERCLK 根时钟设置
I.MX6U 外设根时钟可设置范围:
AHB_CLK_ROOT 最高可以设置 132MHz,
IPG_CLK_ROOT和PERCLK_CLK_ROOT最高可以设置66MHz。
将AHB_CLK_ROOT、IPG_CLK_ROOT,PERCLK_CLK_ROOT 分别设置为132MHz 、66MHz 、66MHz 。

1.6.1 AHB_CLK_ROOT 和 IPG_CLK_ROOT时钟频率设置
①、 此选择器用来选择 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。
②、 此选择器用来选择 periph_clk 的时钟源, 由寄存器 CCM_CBCDR 的 PERIPH_CLK_SEL位与 PLL_bypass_en2 组成的或来选择。当 CCM_CBCDR 的 PERIPH_CLK_SEL 位为 0 的时候periph_clk=pr_periph_clk=396MHz。
③、通过 CBCDR 的 AHB_PODF 位来设置 AHB_CLK_ROOT 的分频值,可以设置 1~8 分频,如果想要 AHB_CLK_ROOT=132MHz 的话就应该设置为 3 分频: 396/3=132MHz。 图中虽然写的是默认 4 分频,但是 I.MX6U 的内部 boot rom 将其改为了 3 分频!
④、 通过 CBCDR 的 IPG_PODF 位来设置 IPG_CLK_ROOT 的分频值, 可以设置 1~4 分频,IPG_CLK_ROOT 时钟源是 AHB_CLK_ROOT,要想 IPG_CLK_ROOT=66MHz 的话就应该设置2 分频:132/2=66MHz。

1.6.1.1 寄存器 CCM_CBCDR(设置分频数)
PERIPH_CLK2_PODF:periph2 时钟分频,可设置 0~7,分别对应 1~8 分频。
PERIPH2_CLK_SEL:选择 peripheral2 的主时钟,如果为 0 的话选择 PLL2,如果为 1 的话选择 periph2_clk2_clk。修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
PERIPH_CLK_SEL:peripheral 主时钟选择,如果为 0 的话选择 PLL2,如果为 1 的话选择 periph_clk2_clock。修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
AXI_PODF:axi 时钟分频,可设置 0~7,分别对应 1~8 分频。
AHB_PODF:ahb 时钟分频,可设置 0~7,分别对应 1~8 分频。修改此位会引起一次与MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
IPG_PODF:ipg 时钟分频,可设置 0~3,分别对应 1~4 分频。
AXI_ALT_CLK_SEL:axi_alt 时钟选择,为 0 的话选择 PLL2_PFD2,如果为 1 的话选择PLL2_PFD1。
AXI_CLK_SEL:axi 时钟源选择,为 0 的话选择 periph_clk,为 1 的话选择 axi_alt 时钟。
FABRIC_MMDC_PODF:fabric/mmdc 时钟分频设置,可设置 0~7,分别对应 1~8 分频。
PERIPH2_CLK2_PODF:periph2_clk2 的时钟分频,可设置 0~7,分别对应 1~8 分频。

1.6.1.2 寄存器 CCM_CBCMR(选择时钟源)
LCDIF1_PODF:lcdif1 的时钟分频,可设置 0~7,分别对应 1~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。

1.6.2 PERCLK_CLK_ROOT 时钟频率设置
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 位来设置分频, 如果要设置 PERCLK_CLK_ROOT 为 66MHz的话就要设置为 1 分频。

1.6.2.1 寄存器 CCM_CSCMR1(选择时钟源)
用于外设时钟源的选择,比如 QSPI1、ACLK、GPMI、BCH 等外设.
PERCLK_CK_SEL:perclk 时钟源选择,为 0 的话选择 ipg clk,为 1 的话选择 osc clk。
PERCLK_PODF:perclk 的时钟分频,可设置 0~7,分别对应 1~8 分频。

本文详细解析了I.MX6U处理器的时钟系统架构,包括7路PLL时钟源的工作原理,主频设置方法,PFD时钟配置,以及AHB、IPG和PERCLK根时钟的频率设定过程。
868

被折叠的 条评论
为什么被折叠?



