• 资料丨迅为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》中时钟相关的结构图来学习。

  • 相关阅读:
    springcloud将多个微服务的swagger文档整合到同一个地址访问
    git 强制回滚到某个commit版本
    常用几个 mvn 命令
    @Resource @Autowired
    我们需要深度沟通
    python 中文乱码解决方案
    同一台电脑使用多个ssh私钥配置不同的github账号
    pyinstaller 打包 sentry_sdk 出现 ModuleNotFoundError 的解决方法
    Linux系统下强制踢掉登录用户
    zsh Ctrl+U 从当前位置删除到行首
  • 原文地址:https://www.cnblogs.com/liyue3/p/15060247.html
Copyright © 2020-2023  润新知