热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

i.MX6ULL终结者时钟系统和原理分析

1i.MX6ULL时钟系统iMX6ULL的系统主频为528MHz,有些型号可以跑到696MHz,但是默认情况下iMX6ULL的主频为396MHz。我们

1 i.MX6ULL时钟系统

iMX6ULL的系统主频为528MHz,有些型号可以跑到696MHz,但是默认情况下iMX6ULL 的主频为396MHz。我们想要让iMX6ULL运行时候达到最大性能,就需要将主频上调至最大528MHz,或者更大,其它的外设时钟也要设置到NXP官方推荐的值。
更多关于芯片的时钟可以查阅 《IMX6ULL参考手册.pdf》的第10章“Chapter 10 Clock and Power Management”和第18章“Chapter 18 Clock Controller Module (CCM)”,这两章有详细的讲解。

系统时钟
我们打开核心板原理图,搜索“RTC_XTALI”即可看到如图 1.1内容:
在这里插入图片描述


图 1.1

这里我们可以看到有两个晶振。32.768KHz的晶振是RTC(实时时钟)的时钟源。24MHz晶振是CPU内核及其他外设的时钟源。

PPL(Phase Locked Loop)时钟源
iMX6ULL系列外设所需要的时钟源,都是由24MHz晶振倍频产生的,一共有7组,如图 1.2所示:
在这里插入图片描述


图 1.2

PPL1(ARM_PLL):这个PPL供内核使用,可编程倍频器,最高可达1.3GHz。注意,此频率高于芯片支持的最大频率1.0 GHz。
PPL2(System_PLL或528_PLL):固定22倍频,产生528MHz。这个PPL还分出4路PFD,即PLL2_PFD0~PLL2_PFD3,
528_PLL和PLL2_PFD0~PLL2_PFD3
为各种总线提供时钟。他们不提供精确的或恒定的频率,可以实现动态调频。通常的,528_PLL和PLL2_PFD0~PLL2_PFD3作为系统内部总线,内部逻辑处理单元,DDR接口,NAND/NOR接口模块等的时钟源。
PPL3(USB1_PLL):用于USBPHY(OTG PHY),固定20倍频,同样分出4路PFD,即PLL3_PFD0~PLL3_PFD3,产生了480MHz的VCO频率和24MHz振荡器。主PPL和4路PFD也可作为其他接口时钟输入。
PPL4(Audio PLL):用于音频外设,提供低抖动和高精度音频时钟,频率范围为650MHz~1300MHz,频率分辨率优于1Hz。可以选择1/2/48/16分频。
PPL5(Video PLL):用于标准视频显示外设,提供低抖动和高精度音频时钟,频率范围为650MHz~1300MHz,频率分辨率优于1Hz。该时钟主要用作显示和视频接口的时钟。可以选择1/2/48/16分频。
PPL6(ENET_PLL):固定为20+5/6倍频,产生500MHz,在此基础上产生25/50/100/125MHz网络时钟。
PPL7(USB2_PLL):用于USB2PHY(OTG PHY),固定20倍频,产生了480MHz的VCO频率和24MHz振荡器。

时钟树
如此多的时钟分支都要一一对应不同的外设。我们要参考《IMX6ULL 参考手册.pdf》里的18.3小结“CCM Clock Tree”,来学习如何选择PPL时钟。
在这里插入图片描述


图 1.3

在这里插入图片描述


图 1.4

时钟树整体分为三个部分:CLOCK SWITCHER、CLOCK ROOT GENERATOR和SYSTEM CLOCKS。其中左边的CLOCK_SWITCHER就是我们上一小节讲解的那7路PLL和8路PFD,右边的SYSTEM CLOCKS就是芯片外设,中间的CLOCK ROOT GENERATOR部分的作用就是选择合适的时钟接入外设接口,负责给CLOCK SWITCHER和SYSTEM CLOCKS连线。就是在7路PLL和8路PFD选择合适时钟源,提供给外设使用。

我们以ESAI外设为例,ESAI时钟图 1.5所示:
在这里插入图片描述


图 1.5

这里的CLOCK ROOT GENERATOR又被分成三部分:
ESAI_CLK_SEL:时钟源选择器,手册中搜索“ESAI_CLK_SELESAI ”可知,有4个可选的时钟源:PLL4、PLL5、PLL3_PFD2和pll3_sw_clk。具体选择哪一路作为ESAI的时钟源是由寄存器CCM->CSCMR2 的ESAI_CLK_SEL 位来决定的,用户可以自由配置。如图 1.6所示:
在这里插入图片描述


图 1.6

1.ESAI_CLK_PRED:一次分频,手册中搜索“ESAI_CLK_PRED”可知,有1~8分频8种选择,分频值由寄存器CCM_CS1CDR的ESAI_CLK_PRED来确定的,假如现在PLL4=650MHz,我们选择PLL4作为ESAI时钟,一次分频选择2分频,那么此时的时钟就是650/2=325MHz。如图 1.7所示:
在这里插入图片描述


图 1.7

2.ESAI_CLK_PODF:二次分频,手册中搜索“ESAI_CLK_PODF”可知,在一次分频的基础上在此分频,有1~8分频8种选择,经过此分频器以后的时钟就是325/8=40.625MHz。因此最终进入到 ESAI 外设的时钟就是40.625MHz。

以上是以外设ESAI为例的设置方式,其他外设可以根据具体需求查看手册去配置。

内核时钟
上一节的时钟树上我们可以查找到ARM 内核时钟如图 1.8所示:
在这里插入图片描述


图 1.8

1.时钟源PPL1,默认为996MHz。
2.寄存器CCM_CACRR的低三位即ARM_PODF位对PLL1进行分频,有07分别对应18分频8种选择。这里选择2分频,经过分频之后就是996/2=498MHz,如图 1.9所示:
在这里插入图片描述


图 1.9

这样,出来的就是ARM的内核时钟,也就是芯片主频(498MHz)。
如果我们要设置528MHz,我们需要设置PPL1为1056MHz,寄存器CCM_CACRR的ARM_PODF位配置为2分频即可。如果我们要设置为696MHz主频。我们需要将PPL1设置为696MHz,那么寄存器CCM_CACRR的ARM_PODF位配置为2分频即可。
我们在来看下如何设置PPL1。PPL1是由寄存器CCM_ANALOG_PLL_ARMn决定的,结构如图 1.10:
在这里插入图片描述


图 1.10

寄存器CCM_ANALOG_PLL_ARMn 中有两个主要位:
ENABLE: 时钟输出使能。1:使能PLL1输出,0:关闭PLL1输出。
DIV_SELECT: 设置PLL1的输出频率,可设置范围为:54~108,PLL1 CLK = Fin *div_seclec/2.0,Fin=24MHz。如果PLL1要输出1056MHz的话,div_select就要设置为88。在修改PLL1时钟频率的时候我们需要先将内核时钟源改为其他的时钟源,PLL1可选择的时钟源如图 1.11所示:
在这里插入图片描述


图 1.11

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

这里我们就用到了一个寄存器 CCM_CCSR,结构如图 1.12所示:
在这里插入图片描述


图 1.12

这个寄存器我们用到两个位:
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时钟。恩智浦有官方推荐数值如下表:
PFD 推荐值(MHz)
PPL2_PFD0 352
PPL2_PFD1 594
PPL2_PFD2 400(实际为396)
PPL2_PFD3 297
PPL3_PFD0 720
PPL3_PFD1 540
PPL3_PFD2 508.2
PPL3_PFD3 454.7

PLL2的4路PFD频率,用到寄存器是CCM_ANALOG_PFD_528n,寄存器结构如图 1.13所示:
在这里插入图片描述


图 1.13

寄存器CCM_ANALOG_PFD_528n分为四组,分别对应PFD0~PFD3,每组8个bit,我们就以PFD0为例,看一下如何设置PLL2_PFD0的频率。

PFD0对应的寄存器位如下:
PFD0_FRAC:PLL2_PFD0的分频数,PLL2_PFD0的计算公式为52818/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,此寄存器结构如图 1.14所示:
在这里插入图片描述


图 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外设根时钟可设置范围如图 1.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的设置如图 1.16所示:
在这里插入图片描述


图 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时钟频率。如图 1.17所示:
在这里插入图片描述


图 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结构图如图 1.18:
在这里插入图片描述


图 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结构图图 1.19:
在这里插入图片描述


图 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,结构如图 1.20所示:
在这里插入图片描述


图 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》中时钟相关的结构图来学习。


2 原理分析

本章讲解的iMX6ULL的时钟属于CPU芯片内部设计。在这里插入图片描述


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文讨论了如何在不使用SearchBar display controller的情况下,单独使用SearchBar并捕获其textChange事件。作者介绍了实际状况,即左侧SliderMenu中的SearchBar需要在主页TableView中显示搜索结果。然后,作者提供了解决方案和步骤,帮助读者实现这一功能。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • Android源码中的Builder模式及其作用
    本文主要解释了什么是Builder模式以及其作用,并结合Android源码来分析Builder模式的实现。Builder模式是将产品的设计、表示和构建进行分离,通过引入建造者角色,简化了构建复杂产品的流程,并且使得产品的构建可以灵活适应变化。使用Builder模式可以解决开发者需要关注产品表示和构建步骤的问题,并且当构建流程发生变化时,无需修改代码即可适配新的构建流程。 ... [详细]
  • 如何使用PLEX播放组播、抓取信号源以及设置路由器
    本文介绍了如何使用PLEX播放组播、抓取信号源以及设置路由器。通过使用xTeve软件和M3U源,用户可以在PLEX上实现直播功能,并且可以自动匹配EPG信息和定时录制节目。同时,本文还提供了从华为itv盒子提取组播地址的方法以及如何在ASUS固件路由器上设置IPTV。在使用PLEX之前,建议先使用VLC测试是否可以正常播放UDPXY转发的iptv流。最后,本文还介绍了docker版xTeve的设置方法。 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • 关于extjs开发实战pdf的信息
    本文目录一览:1、extjs实用开发指南2、本 ... [详细]
  • 人工智能推理能力与假设检验
    最近Google的Deepmind开始研究如何让AI做数学题。这个问题的提出非常有启发,逻辑推理,发现新知识的能力应该是强人工智能出现自我意识之前最需要发展的能力。深度学习目前可以 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • Pycharm编辑器取消双击shift弹出搜索框的方法
    在使用Pycharm编辑器时,双击shift会弹出搜索框界面,导致输入失去焦点,给用户带来不便。本文介绍了取消双击shift弹出搜索框的方法:在Pycharm中双击shift,输入registry并回车,找到“ide.suppress.double.click.handler”并勾选后,关闭即可解决该问题。通过这个方法,你再也不会被shift问题困扰了。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文整理了Java中com.evernote.android.job.JobRequest.getTransientExtras()方法的一些代码示例,展示了 ... [详细]
author-avatar
wyyxit
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有