8.1.5 PFD 时钟设置

        设置好主频以后我们还需要设置好其他的 PLL PFD 时钟,PLL1 上一小节已经设置了,
PLL2PLL3 PLL7 固定为 528MHz480MHz 480MHzPLL4~PLL6 都是针对特殊外设
的,用到的时候再设置。因此,接下来重点就是设置 PLL2 PLL3 的各自 4 PFDNXP
荐的这 8 PFD 频率如表 8.1.5.1 所示:
表 8.1.5.1 NXP 推荐的 PFD 频率
        先设置 PLL2 4 PFD 频率,用到寄存器是 CCM_ANALOG_PFD_528n,寄存器结构如
图 8.1.5.1 所示:
图 8.1.5.1 寄存器 CCM_ANALOG_PFD_528n 结构
        从图 8.1.5.1 可以看出,寄存器 CCM_ANALOG_PFD_528n 其实分为四组,分别对应
PFD0~PFD3,每组 8 bit,我们就以 PFD0 为例,看一下如何设置 PLL2_PFD0 的频率。PFD0
对应的寄存器位如下:
        PFD0_FRAC: PLL2_PFD0 的分频数,PLL2_PFD0 的计算公式为 528*18/PFD0_FRAC,此
为 可 设 置 的 范 围 为 12~35 。 如 果 PLL2_PFD0 的 频 率 要 设 置 为 352MHz 的 话
PFD0_FRAC=528*18/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 实际为 396MHzPLL2_PFD3=297MHz 的话,PFD3_FRAC=32。
接 下 来 设 置 PLL3_PFD0~PLL3_PFD3 4 PFD 的 频 率 , 使 用 到 的 寄 存 器 是
CCM_ANALOG_PFD_480n,此寄存器结构如图 8.1.5.2 所示:

        从图 16.1.5.2 可以看出,寄存器 CCM_ANALOG_PFD_480n CCM_ANALOG_PFD_528n
的结构是一模一样的,只是一个是 PLL2 的,一个是 PLL3 的。寄存器位的含义也是一样的,只
是 频 率 计 算 公 式 不 同 , 比 如 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。

8.1.6 AHBIPG PERCLK 根时钟设置

        7 路 PLL 8 PFD 设置完成以后最后还需要设置 AHB_CLK_ROOT IPG_CLK_ROOT
的时钟,I.MX6U 外设根时钟可设置范围如图 8.1.6.1 所示:

图 8.1.6.1 外设根时钟可设置范围
        图 8.1.6.1 给出了大多数外设的根时钟设置范围,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 的设计如图 8.1.6.2 所示:

图 8.1.6.2 总线时钟图
        图 8.1.6.2 就是 AHB_CLK_ROOT IPG_CLK_ROOT 的时钟图,图中分为了部分。
        ①、此选择器用来选择 pre_periph_clk 的时钟源,可以选择 PLL2PLL2_PFD2PLL2_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。图 8.1.6.2 中虽然写的是默认 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
        最后要设置的就是 PERCLK_CLK_ROOT 时钟频率,其时钟结构图如图 8.1.6.3 所示:

图 8.1.6.3 PERCLK_CLK_ROOT 时钟结构
        从图8.1.6.3可以看出 , 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 分频。
        在上面的设置中用到了三个寄存器:CCM_CBCDRCCM_CBCMR CCM_CSCMR1,我
们依次来看一下这些寄存器,CCM_CBCDR 寄存器结构如图 8.1.6.4 所示:

图 8.1.6.4 寄存器 CCM_CBCDR 结构
寄存器 CCM_CBCDR 各个位的含义如下:
PERIPH_CLK2_PODFperiph2 时钟分频,可设置 0~7,分别对应 1~8 分频。
PERIPH2_CLK_SEL:选择 peripheral2 的主时钟,如果为 0 的话选择 PLL2,如果为 1
话选择 periph2_clk2_clk。修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握
手完成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
PERIPH_CLK_SELperipheral 主时钟选择,如果为 0 的话选择 PLL2,如果为 1 的话选
periph_clk2_clock。修改此位会引起一次与 MMDC 的握手,所以修改完成以后要等待握手完
成,握手完成信号由寄存器 CCM_CDHIPR 中指定位表示。
AXI_PODFaxi 时钟分频,可设置 0~7,分别对应 1~8 分频。
AHB_PODFahb 时钟分频,可设置 0~7,分别对应 1~8 分频。修改此位会引起一次与
MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信号由寄存器 CCM_CDHIPR
指定位表示。
IPG_PODFipg 时钟分频,可设置 0~3,分别对应 1~4 分频。
AXI_ALT_CLK_SELaxi_alt 时钟选择,为 0 的话选择 PLL2_PFD2,如果为 1 的话选择
PLL3_PFD1
AXI_CLK_SELaxi 时钟源选择,为 0 的话选择 periph_clk,为 1 的话选择 axi_alt 时钟。
FABRIC_MMDC_PODFfabric/mmdc 时钟分频设置,可设置 0~7,分别对应 1~8 分频。
PERIPH2_CLK2_PODFperiph2_clk2 的时钟分频,可设置 0~7,分别对应 1~8 分频。
接下来看一下寄存器 CCM_CBCMR,寄存器结构如图 8.1.6.5 所示:

        寄存器 CCM_CBCMR 各个位的含义如下:
        LCDIF1_PODFlcdif1 的时钟分频,可设置 0~7,分别对应 1~8 分频。
        PRE_PERIPH2_CLK_SELpre_periph2 时钟源选择,00 选择 PLL201 选择 PLL2_PFD2,10 选择 PLL2_PFD011 选择 PLL4
        PERIPH2_CLK2_SELperiph2_clk2 时钟源选择为 0 的时候选择 pll3_sw_clk,为 1 的时候
选择 OSC
        PRE_PERIPH_CLK_SELpre_periph 时钟源选择,00 选择 PLL201 选择 PLL2_PFD210 选择 PLL2_PFD011 选择 PLL2_PFD2/2
        PERIPH_CLK2_SELperipheral_clk2 时钟源选择,00 选择 pll3_sw_clk01 选择 osc_clk,10 选择 pll2_bypass_clk
        最后看一下寄存器 CCM_CSCMR1,寄存器结构如图 8.1.6.6 所示:

图 8.1.6.6 寄存器 CCM_CSCMR1 结构
        此寄存器主要用于外设时钟源的选择,比如 QSPI1ACLKGPMIBCH 等外设,我们重
点看一下下面两个位:
        PERCLK_CK_SEL:perclk 时钟源选择,为 0 的话选择 ipg clk,为 1 的话选择 osc clk
        PERCLK_PODFperclk 的时钟分频,可设置 0~7,分别对应 1~8 分频。
        在修改如下时钟选择器或者分频器的时候会引起与 MMDC 的握手发生:
        ①、mmdc_podf
        ②、periph_clk_sel
        ③、periph2_clk_sel
        ④、arm_podf
        ⑤、ahb_podf
        发生握手信号以后需要等待握手完成,寄存器 CCM_CDHIPR 中保存着握手信号是否完成,
如果相应的位为 1 的话就表示握手没有完成,如果为 0 的话就表示握手完成,很简单,这里就
不详细的列举寄存器 CCM_CDHIPR 中的各个位了。
        另外在修改 arm_podf ahb_podf 的时候需要先关闭其时钟输出,等修改完成以后再打开,
否则的话可能会出现在修改完成以后没有时钟输出的问题。本教程需要修改寄存器
CCM_CBCDR AHB_PODF 位来设置 AHB_ROOT_CLK 的时钟,所以在修改之前必须先关闭
AHB_ROOT_CLK 的输出。但是笔者没有找到相应的寄存器,因此目前没法关闭,那也就没法
设置 AHB_PODF 了。不过 AHB_PODF 内部 boot rom 设置为了 3 分频,如果 pre_periph_clk
时钟源选择 PLL2_PFD2 的话,AHB_ROOT_CLK 也是 396MHz/3=132MHz
        至此,I.MX6U 的时钟系统就讲解完了,I.MX6U 的时钟系统还是很复杂的。本章我们也只是讲解了如何进行主频、 PLL、PFD 和一些总线时钟的设置,关于具体的外设时钟设置我们在学习到的时候在详细的讲解。
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐