时钟频率修改流程
ZYNQ7000的时钟频率修改流程,如图 2.1所示。具体步骤如下:
步骤一:解除ZYNQ7000的寄存器写锁定;
步骤二:向对应寄存器写入我们需要设置的PLL倍频值和PLL配置参数;
步骤三:进行PLL的旁路模式转换和软件重启,使我们刚刚设置的PLL倍频值和PLL配置参数生效;
步骤四:重新使寄存器处于写锁定状态。
图 2.1 ZYNQ7000的时钟频率修改流程图
ZYNQ7000的ARM_PLL_CLK时钟频率修改的具体的代码实现如程序清单 2.1所示。不同平台的解除和锁定写锁定的方式可能不同,对于ZYNQ7000平台,需要写入0xDF0D到SLCR_UNLOCK寄存器解除写锁定,写入0x767B到SLCR_LOCK寄存器可以使相关寄存器的写操作无效。
程序清单 21 ZYNQ7000的时钟频率修改代码 /*********************************************************************************************************
** 函数名称: zynqPllFeedBackSet
** 功能描述: zynq的ARM_PLL_CLK时钟倍频设置
** 输 入 : NONE
** 输 出 : NONE
** 返 回 : NONE
*********************************************************************************************************/
VOID zynqPllFeedBackSet (VOID)
{
UINT32 uiClkCtrl;
UINT32 uiFeedBackDiv;
UINT32 uiNum;
uiNum = read32(ZYNQ_SLCR + SLCR_LOCKSTA);
if (0 != uiNum) {
write32(SLCR_UNLOCK_MAGIC, ZYNQ_SLCR + SLCR_UNLOCK); /* 写入0xDF0D,解除写锁定 */
uiNum = 0;
}
/*
* 设置ARM_PLL的倍频值
*/
uiClkCtrl = read32(ZYNQ_SLCR + ARM_PLL_CTL);
uiFeedBackDiv = uiClkCtrl &~ XZYNQ_SLCR_ARM_PLL_CTRL_PLL_FDIV_MASK;
uiFeedBackDiv |= (SLCR_FEED_BACK_DIV_VALUE << XZYNQ_SLCR_ARM_PLL_CTRL_PLL_FDIV_OFFSET);
write32(uiFeedBackDiv, ZYNQ_SLCR + ARM_PLL_CTL);
/*
* 设置ARM_PLL的配置参数
*/
uiClkCtrl = read32(ZYNQ_SLCR + ARM_PLL_CTL);
write32(SLCR_ARM_PLL_CFG, ZYNQ_SLCR + ARM_CLK_CFG);
/*
* 进行PLL的旁路模式转换和软件重启,使我们刚刚设置的PLL倍频值和PLL配置参数生效
*/
write32(SLCR_ARM_PLL_CTRL_BYPASS_FORCE | uiClkCtrl, ZYNQ_SLCR + ARM_PLL_CTL);
write32(SLCR_ARM_PLL_CTRL_RESET | uiClkCtrl, ZYNQ_SLCR + ARM_PLL_CTL);
read32(ZYNQ_SLCR + PLL_STATUS);
write32(uiClkCtrl &~ SLCR_ARM_PLL_CTRL_RESET, ZYNQ_SLCR + ARM_PLL_CTL);
write32(uiClkCtrl &~ SLCR_ARM_PLL_CTRL_BYPASS_FORCE, ZYNQ_SLCR + ARM_PLL_CTL);
if (0 == uiNum) {
write32(SLCR_LOCK_MAGIC, ZYNQ_SLCR + SLCR_LOCK); /* 写入0x760B,打开写锁定 */
uiNum = 1;
}
}