嵌入式Linux(六)主频和时钟配置实验

1. 目的

  默认I.MX6U工作频率为396MHz,但是6U标准的工作频率应该是528MHz,所以需要学习I.MX6U的时钟系统,配置系统时钟和外设时钟,使得系统时钟频率在528MHz,外设时钟频率按照NXP推荐设置。(我用的是6ULL,时钟频率可以比6U更高。)

2. I.MX6U系列时钟系统分析

2.1 原理图分析

  首先打开核心板的原理图,6U和6ULL的时钟部分原理图一样的。这里有一个32.768KHz的晶振作为RTC时钟源(实时时钟),24MHz的是内核和其它外设的时钟源,接到T16,T17两个IO。
嵌入式Linux(六)主频和时钟配置实验_第1张图片

2.2 7路PIL时钟源 & 时钟树

  NXP将不同外设的时钟分为7组,都是由24MHz的晶振分频来的。具体七路信息可以查看驱动开发手册。总体来讲,外设时钟一般来源于这些PLL和PLL分出的PFD
  简单来说就是24MHz分出7路PLL,再分出PFD连接到外设这样的树形结构,具体配置时钟可以查询参考手册第十八章。主要分为三个部分:
  ①CLOCK_SWITCHER:这一部分就是24MHz分出7路PLL和8路PFD。
  ②CLOCK_ROOT GENERATOR:这一部分选通PLL和PFD作为外设时钟源。
  ③SYSTEM_CLOCKS:这一部分就是芯片外设。

2.3 内核时钟设置

1. 通常要初始化的PLL和PFD:
  PLL1(ARM-PLL),PLL2(System_PLL),PLL2的PFD0-PFD3,PLL3,PLL3的PFD0-PFD3。
  其它外设时钟源推荐频率可以按照参考手册第十八章的最大值进行设置,使得性能更高。
在这里插入图片描述
  注意,这里第二个灰色的“/2”虽然画出来了,但实际上不存在,是个坑。

2. 假设要配置主频528MHz:
  注意PLL1为650MHz-1.3GHz,所以要得到528MHz,可以将PLL1设置为1056MHz

①设置PLL1为1056MHz。
  PLL1的pll1_main_clk频率由CCM_ANALOG_PLL_ARMn寄存器的DIV_SELECT位(bit6:0)设置。
  公式为:Output = fref✖DIV_SELECT/2
  这其中Output=1056MHz,fref=24MHz,计算得到DIV_SELECT=88。此外还要设置CCM_ANALOG_PLL_ARMn寄存器的ENABLE(bit13)=1。
  修改PLL1时钟频率时需要先将内核时钟源改为其它时钟源。如下图,可以看到PLL1时钟源可以来源于CCSR的pll1_main_clk,step_clk,由二号选择器选择。
  正常是pll1_main_clk,但是这里要修改主频,那就要先切换到step_clk,等pll1_main_clk修改完毕后切回。切换功能由CCSR寄存器的PLL1_SW_CLK_SEL位(bit2)决定。
  那么就要先设置step_clk,由CCSR的STEP_SEL位(bit8)选择,一般选osc_clk也就是24MHz的晶振。
设置CCM_CACRR寄存器的ARM_PODF(bit2:0)位为2分频(0-7分别对应1-8分频),经过这个2分频得到528MHz。注意,需要在第一步中切换回pll1_main_clk之前设置
嵌入式Linux(六)主频和时钟配置实验_第2张图片

③其它PLL和PFD时钟设置
  PLL2,PLL3,PLL7,频率分别固定为528MHz,480MHz,480MHz。不需要手动设置。
  PLL2和PLL3一共8路PFD推荐频率如下:
嵌入式Linux(六)主频和时钟配置实验_第3张图片
  PLL2的4路PFD由CCM_ANALOG_PFD_528n寄存器设置。该寄存器分为四组分别对应PFD0-3,每一组为8个bit。以PPL2_PFD0为例,计算公式为PLL2_PFD0 = 528×18/PFD0_FRAC
  PFD0_FRAC是PLL2_PFD0的分频数,可以设置为12-35。根据NXP推荐PLL2_PFD0=352MHz,代入公式可以得到PFD0_FRAC=27。
  PLL3的PFD则由CCM_ANALOG_PFD_480n设置,除了公式为PLL3_PFDx = 480×18/PFDx_FRAC,其他都一样。

④AHB,IPG,PERCLK根时钟设
  PERCLK和IPG_CLK是很多外设的时钟源,而AHB又控制这两者,所以要初始化这三个根时钟。
1)AHB_CLK_ROOT初始化:
  如下图是AHB_CLK_ROOT的通常来源(蓝框线路)。按照驱动开发手册列出的最大频率,AHB应设置为132MHz。
嵌入式Linux(六)主频和时钟配置实验_第4张图片
  首先需要设置CCM_CBCMR的PRE_PERIPH_CLK_SEL(bit19:18)选择PLL2_PFD0为输入,根据参考手册需要将bit19:18设置为01。
  然后设置CCM_CBCDR寄存器的PERIPH_CLK_SEL(bit25)为0,将刚设置好的periph_clk选通。
  最后设置CBCDR的AHB_PODF(bit12:10)位位010,也就是3分频,从而将PFD2连过来的396MHz分成132MHz。
  最后的最后,需要由CCM_CDHIPR寄存器的AHB_PODF_BUSY(bit1),PERIPH_CLK_SEL_BUSY(bit5)判断握手是否完成,1代表未完成,0代表握手完成。
2)PERCLK_CLK_ROOT和IPG_CLK_ROOT初始化:
  根据最大值设置IPGCLK和PERCLK为66MHz。前面已经设置好了AHBCLK,所以设置CBCDR的IPG_PODF(bit9:8)为2分频,设置CSCMR1的PERCLK_CLK_SEL(bit6)为0表示选通PERCLK的时钟源为IPG,CSCMR1的PERCLK_PODF(bit5:0)为1分频即可完成设置。
嵌入式Linux(六)主频和时钟配置实验_第5张图片

你可能感兴趣的:(嵌入式,linux,运维,服务器)