Linux——I.MX6U主频和时钟配置

目录

系统主频的配置

各个PLL时钟的配置

 其他外设时钟源配置


系统主频的配置

(1)要设置 ARM 内核主频为 528MHz,设置 CACRR 寄存器的 ARM_PODF位为2分频,然后设置 PLL1=1056MHz即可。CACRR的bit3~0为ARM_PODF位,可设置 0~7,分别对应 1~8 分频。应该设置 CACRR寄存器的 ARM_PODF=1。

(2)设置PLL1=1056MHz。PLL1=pll1_sw_clk。pll1_sw_clk有两路可以选择,分别为pll1_main_clk,和 step_clk,通过 CCSR 寄存器的 pll1_sw_clk_sel位(bit2)来选择。为0的时候选择 pl1_main_clk,为1的时候选额 step_clk。

(3)在修改 PLL1 的时候,也就是设置系统时钟的时候需要给 6ULL 一个临时的时钟,也就是 step_clk。在修改 PLL1的时候需要将 pll1_sw_clk切换到 step_clk上。”

(4)设置 step_clk。Step_clk也有两路来源,由 CCSR 的 step_sel 位(bit8)来设置,为 0的时候设置 step clk为 osC=24MHZ。为1的时候不重要,不用。

(5)时钟切换成功以后就可以修改 PLL1 的值。
(6)通过CCM_ANALOG_PLL_ARM 寄存器 DIV_SELECT位(bit6-0)来设置PLL1的频率,公式为: output = freq * DIV_SEL/2 =>DIV_SELECT位=88即可。PLL1=1056MHz

 还要设置CCM_ANALOG_PLL_ARM 寄存器的ENABLE位(bit113)为1,也就是使能输出。

(7)在切换回PLL1之前,设置CACRR寄存器的ARM_PODF=1!!

代码实现:

/*使能外设时钟*/
void clk_enable(void)
{
    CCM->CCGR0 = 0xFFFFFFFF;
    CCM->CCGR1 = 0xFFFFFFFF;
    CCM->CCGR2 = 0xFFFFFFFF;
    CCM->CCGR3 = 0xFFFFFFFF;
    CCM->CCGR4 = 0xFFFFFFFF;
    CCM->CCGR5 = 0xFFFFFFFF;
    CCM->CCGR6 = 0xFFFFFFFF;
}

/*初始化时钟*/
void imx6u_clkinit(void)
{
    /*初始化6u的主频为528MHz*/
    //系统时钟切换
    if(((CCM->CCSR >> 2)&0x1) == 0) //当前时钟使用pll1_main_clk,也就是PLL1
    {
        CCM->CCSR &= ~(1<<8);  //设置step_clk = osc_clk = 24MHz
        CCM->CCSR |= (1<<2);   //设置pll_sw_clk = step_clk = 24MHz
    }
    //设置PLL1=1056MHz
    CCM_ANALOG->PLL_ARM = (1<<13) | ((88<<0)&0x7f);
    CCM->CACRR = 1;  //设置2分频
    CCM->CCSR &= ~(1<<2);   //设置pll_sw_clk=pll_main_clk=1056MHz
}

各个PLL时钟的配置

PLL2和PLL3。PLL2固定为528MHz,PLL3固定为480MHz

NXP推荐的8路PFD频率如下:

(1)初始化PLL2_PFD0-PFD3。寄存器CCM_ANALOG_PFD_528用于设置4路PFD的时钟。比如PFD0 = 528*18/PFD0_FRAC。设置PFD0_FRAC位即可。比如PLL2_PFD0 = 352M = 528*18/PFD_FRAC,因此PFD0_FRAC=27。

实现代码:

    /*设置PLL2的4路PFD*/
    reg = CCM_ANALOG->PFD_528;    //寄存器地址
    reg &= ~(0x3F3F3F3F); 
    reg |= (32<<24);        //通过公式计算,配置寄存器的相应位,使得PLL2_PFD3=297MHz
    reg |= (24<<16);        //PLL2_PFD2=396MHz 
    reg |= (16<<8);         //PLL2_PFD1=594MHz
    reg |= (27<<0);         //PLL2_PFD0=352MHz 
    CCM_ANALOG->PFD_528 = reg;

(2)初始化PLL3_PFD0-PFD3。寄存器CCM_ANALOG_PFD_480用于设置4路PFD的时钟。

实现代码:

    /*设置PLL3的4路PFD*/
    reg = 0;
    reg = CCM_ANALOG->PFD_480;    //寄存器地址
    reg &= ~(0x3F3F3F3F); 
    reg |= (19<<24);        //通过公式计算,配置寄存器的相应位,使得PLL3_PFD3=454.7MHz
    reg |= (17<<16);        //PLL3_PFD2=508.2MHz 
    reg |= (16<<8);         //PLL3_PFD1=540MHz
    reg |= (12<<0);         //PLL3_PFD0=720MHz 
    CCM_ANALOG->PFD_480 = reg;

 其他外设时钟源配置

AHB_CLK_ROOT、PERCLK_CLK_ROOT 以及IPG_CLK_ROOT。

因为 PERCLK_CLK_ROOT和IPG_CLK_ROOT 要用到 AHB_CLK_ROOT,所以我们要初始 AHB_CLK_ROOT。

(1) AHB_CLK_ROOT的初始化:


AHB_CLK_ROOT=132MHz。
设置 CBCMR 寄存器的 PRE_PERIPH_CLK_SEL位,设置 CBCDR 寄存器的 PERIPH_CLK_SEL位 0。设置 CBCDR寄存器的 AHB_PODF位为2,也就是3分频,因此396/3=132MHz。

对照数据手册对应的寄存器操作如下: 

    /*设置AHB_CLK_ROOT为138MHz*/
    CCM->CBCMR &= ~(3<<18);  //清空寄存器的18、19位
    CCM->CBCMR |= (1<<18);   //设置pre_periph clock=PLL2_PFD2=396MHz
    CCM->CBCDR &= ~(1<<25);
    while(CCM->CDHIPR & (1<<5)); //等待握手信号
#if 0    
    CCM->CBCDR &= ~(7<<10);
    CCM->CBCDR |= (2<<10);   //3分频
    while(CCM->CDHIPR & (1<<1)); //等待握手信号
#endif

时钟总线图:

 PERCLK_CLK_ROOT=IPG_CLK_ROOT=66MHz 

(2)IPG_CLK_ROOT初始化

设置CBCDR寄存器IPG_PODF=1,也就是2分频。

(3)PERCLK_CLK_ROOT初始化

设置CSCMR1寄存器的PERCLK_CLK_SEL为为0,表示PERCLK的时钟源为IPG。 

代码操作寄存器实现:

    /*IPG_CLK_ROOT=66MHz*/
    CCM->CBCDR &= ~(3<<8);
    CCM->CBCDR |= (1<<8);

    /*PER_CLK_ROOT=66MHz*/
    CCM->CSCMR1 &= ~(1<<6);  //PERCLK_CLK_ROOT时钟源为IPG_CLK=66MHz
    CCM->CSCMR1 &= ~(0x3f<<0); //1分频,PERCLK_CLK_ROOT=66MHz

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值