admin 管理员组文章数量: 1086866
各时钟配置
1.内核时钟设置
各部分分析:
①、内核时钟源来自于PLL1,假如此时PLL1为996MHz。
②、通过寄存器CCM_CACRR的ARM_PODF位对PLL1进行分频,可选择1/2/4/8分频,假如我们选择2分频,那么经过分频以后的时钟频率是996/2=498MHz。
③、大家不要被此处的2分频给骗了,此处没有进行2分频。
④、经过第②步2分频以后的498MHz就是ARM的内核时钟,也就是I.MX6U的主频。
所以这里我们只需要配置两个寄存器就可以。
- CCM_CACRR 的 ARM_PODF 位设置分频
- 寄存器 CCM_ANALOG_PLL_ARMn 设置 PLL1 频率
CCM_CACRR 寄存器以及 ARM_PODF 位与分频的对应关系如下:
ARM_PODF 位,可以设置为 0~7,分别对应 1~8 分频,要设置 2分频就是给 001就行。
2.1.2 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可选择的时钟源如图:
修改I.MX6U主频的步骤就很清晰了,修改步骤如下:
①、 设置寄存器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。
2、PFD时钟设置
设置PLL2和PLL3的各自4路PFD,NXP推荐的这8路PFD频率如表所示:
PFD | NXP推荐频率值 |
---|---|
PLL2_PFD0 | 358MHz |
PLL2_PFD1 | 594MHz |
PLL2_PFD2 | 400MHz(实际396MHz) |
PLL2_PFD3 | 297MHz |
PLL3_PFD0 | 720MHz |
PLL3_PFD1 | 540MHz |
PLL3_PFD2 | 508.2MHz |
PLL3_PFD3 | 4454.7MHz |
先设置PLL2的4路PFD频率,用到寄存器是CCM_ANALOG_PFD_528n,寄存器结构如图所示:
从图中可以看出,寄存器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实际为396MHz;PLL2_PFD3=297MHz的话,PFD3_FRAC=32。
接下来设置PLL3_PFD0~PLL3_PFD3这4路PFD的频率,使用到的寄存器是CCM_ANALOG_PFD_480n,此寄存器结构如图所示:
从图中可以看出,寄存器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。
代码:
void imx6u_clkinit(void)
{unsigned int reg = 0;if((((CCM->CCSR) >> 2) & 0x1 ) == 0) /* 当前pll1_sw_clk使用的pll1_main_clk*/{ CCM->CCSR &= ~(1 << 8); /* 配置step_clk时钟源为24MH OSC */ CCM->CCSR |= (1 << 2); /* 配置pll1_sw_clk时钟源为step_clk */}CCM_ANALOG->PLL_ARM = (1 << 13) | ((66 << 0) & 0X7F); CCM->CCSR &= ~(1 << 2); CCM->CACRR = 0; reg = CCM_ANALOG->PFD_528;reg &= ~(0X3F3F3F3F); /* 清除原来的设置 */reg |= 32<<24; /* PLL2_PFD3=528*18/32=297Mhz */reg |= 24<<16; /* PLL2_PFD2=528*18/24=396Mhz(DDR使用的时钟,最大400Mhz) */reg |= 16<<8; /* PLL2_PFD1=528*18/16=594Mhz */reg |= 27<<0; /* PLL2_PFD0=528*18/27=352Mhz */CCM_ANALOG->PFD_528=reg; /* 设置PLL2_PFD0~3 */reg = 0; /* 清零 */reg = CCM_ANALOG->PFD_480;reg &= ~(0X3F3F3F3F); /* 清除原来的设置 */reg |= 19<<24; /* PLL3_PFD3=480*18/19=454.74Mhz */reg |= 17<<16; /* PLL3_PFD2=480*18/17=508.24Mhz */reg |= 16<<8; /* PLL3_PFD1=480*18/16=540Mhz */reg |= 12<<0; /* PLL3_PFD0=480*18/12=720Mhz */CCM_ANALOG->PFD_480=reg; /* 设置PLL3_PFD0~3 */ }
本文标签: 各时钟配置
版权声明:本文标题:各时钟配置 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1687882282a152922.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论