IMX6ULL裸机程序--4.时钟树分析

时钟树分析

树根–时钟源

IMX6ULL的时钟源有两个:24M外部晶振和32.768K晶振,其中32.768K晶振用于内部RTC模块使用。24M外部晶振用于内核和各种外设使用,是时钟树的根源。
在这里插入图片描述

主干-- 7路PLL时钟源+8路PFD

显然一个24M频率的时钟不足以供内部外设使用,因此在24M的基础上,将其倍频分离出7路PLL时钟源如下:
在这里插入图片描述

  • ARM PLL :供ARM内核使用,最高可倍频到1.3Ghz。
  • 528 PLL:又叫System_PLL,此路固定为24M的22倍频,也就是528M,不可修改。在528 PLL基础上又分离出4路PFD。常 528_PLL 和这 4 路 PFD 是 I.MX6U 内部系统总线的时钟源,比如内处理逻辑单元、 DDR 接口、 NAND/NOR 接口等等。
  • USB1_PLL:用于USB1PHY。此路固定为24M的20倍频,也就是480M。此路也分离出4路PFD。
  • USB2_PLL:用于USB2PHY。此路固定为24M的20倍频,也就是480M。
  • ENET PLL:用于生成网络所需时钟,此路固定为24M的20+5/6倍频,也就是500M。
  • VIDEO PLL:用于显示相关外设,此路倍频可调整,范围在650~1300Mhz。最终输出时还可以分频,1/2/4/8/16分频。
  • AUDIO PLL:用于音频相关外设,此路倍频可调整,范围在650~1300Mhz。最终输出时还可以分频,1/2/4分频。

主分支-- CLOCK ROOT GENERATOR

在生成7路PLL和8路PFD后,系统产生了足够的时钟源,但是如何供给外设使用呢,这就需要CLOCK ROOT GENERATOR牵线搭桥。其作用就是根据实际需要,选择合适的时钟源,并对其进行分频,倍频,切换等工作,从而让外设拥有合适的时钟源。
在这里插入图片描述
我们以ESAI时钟为例:
在这里插入图片描述
1.时钟源选择器,由寄存器CCM->CSCMR2的ESAI_CLK_SEL位选择时钟源:PLL4,PLL5,PLL3_PFD2和pll3_sw_clk。
2. 前级分频器,由寄存器 CCM_CS1CDR 的 ESAI_CLK_PRED来确定的,可设置 1~8 分频,假如现在 PLL4=650MHz,我们选择 PLL4 作为 ESAI 时钟,前级分频选择 2 分频,那么此时的时钟就是 650/2=325MHz。
3. 后级分频器,分频值由寄存器
CCM_CS1CDR 的 ESAI_CLK_PODF 来决定,可设置 1~8 分频。假如我们设置为 8 分频的话,经过此分频器以后的时钟就是 325/8=40.625MHz。因此最终进入到 ESAI 外设的时钟就是40.625MHz。

果实 – 外设

略。

以上便是IMX6ULL时钟树分析,总的来说便是24M晶振输入,生成7路PLL和8路PFD,在经过各种分频倍频供给外设使用。

IMX6ULL时钟设置

内核时钟设置

原理分析

在这里插入图片描述

  1. 我们需要设置内核时钟为528M,因此PLL1频率为528*2=1056M。然后通过CACRR寄存器的ARM_PODF设置分频系数为2。PLL1 的频率可以通过寄存器 CCM_ANALOG_PLL_ARMn 来设置。
  2. 在修改 PLL1 时钟频率的时候我们需要先将内核时钟源改为其他的时钟源,可选时钟源如下,由CCSR控制。
    在这里插入图片描述

设置步骤

  • 设置寄存器 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。

PFD时钟设置

  • 8路PFD推荐值
    在这里插入图片描述

原理分析

  • 先设置 PLL2 的 4 路 PFD 频率,用到寄存器是 CCM_ANALOG_PFD_528n。

AHB,IPG和PERRCLK根时钟设置

。。。。。。。。。。。。。。。。。。。。

程序编写

程序主要修改bsp_clk.c

#include "bsp_clk.h"

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_clk.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 系统时钟驱动。
其他	   : 无
论坛 	   : www.openedv.com
日志	   : 初版V1.0 2019/1/4 左忠凯创建
***************************************************************/

/*
 * @description	: 使能I.MX6U所有外设时钟
 * @param 		: 无
 * @return 		: 无
 */
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;
}

/*
 * @description	: 初始化系统时钟为528Mhz,设置8路PFD时钟为推荐值。
 * @param 		: 无
 * @return 		: 无
 */
void imx6u_clkinit(void)
{
	unsigned int reg = 0;
	/*
		1.设置内核时钟为528M
		1.1.判断当前时钟源,若为PLL_main_clk,则切换时钟源到step_clk,修改完后再切回来
	*/
	if( ( ( ( CCM->CCSR )>>2 ) & 0x1 ) == 0)/*pll_main_clk*/
	{
		CCM->CCSR &= ~(1<<8);/* 设置step_clk时钟源为24M OSC */
		CCM->CCSR |= (1<<2);/*  切换到step_clk */
	}

	/*
		1.2 设置PLL_min_clk为1056M,配置 CCM_ANLOG->PLL_ARM 寄存器
		bit13: 1 使能时钟输出
		bit[6:0]: 88, 由公式: Fout = Fin * div_select / 2.0,
		1056=24*div_select/2.0, 得出: div_select=88。
	*/
	CCM_ANALOG->PLL_ARM = (1<<13)|((88<0)&0x7f);
	CCM->CCSR &= ~(1<<2);/* 将时钟源切回PLL_main_clk */
	CCM->CACRR = 1;/*  时钟分频1056/2 = 528 */


	/*
		2.设置PLL2的PFD
	*/
	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 */
	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 */

	/*
		3.设置PLL3的PFD
	*/
	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 */

	/*
		4.设置AHB时钟,最小6M 最大132M
	*/
	CCM->CBCMR &= ~(3<<18);/*清楚原有值*/
	CCM->CBCMR |= (1<<18);/*pre_periph_clk=PLL2_PFD2=396MHz*/
	CCM->CBCDR &= ~(1 << 25); /* periph_clk=pre_periph_clk=396MHz */
	while(CCM->CDHIPR & (1 << 5));/* 等待握手完成 */
#if 0
	CCM->CBCDR &= ~(7 << 10);/* CBCDR 的 AHB_PODF 清零 */
	CCM->CBCDR |= 2 << 10; /* AHB_PODF 3 分频, AHB_CLK_ROOT=132MH
	while(CCM->CDHIPR & (1 << 1));/* 等待握手完成 */
#endif
	/* 5、设置 IPG_CLK_ROOT 最小 3Mhz,最大 66Mhz */
	CCM->CBCDR &= ~(3 << 8); /* CBCDR 的 IPG_PODF 清零 */
	CCM->CBCDR |= 1 << 8; /* IPG_PODF 2 分频, IPG_CLK_ROOT=66MH
	/* 6、设置 PERCLK_CLK_ROOT 时钟 */
	CCM->CSCMR1 &= ~(1 << 6); /* PERCLK_CLK_ROOT 时钟源为 IPG */
	CCM->CSCMR1 &= ~(7 << 0); /* PERCLK_PODF 位清零,即 1 分频 */

}

烧录测试

发布了24 篇原创文章 · 获赞 6 · 访问量 3972

猜你喜欢

转载自blog.csdn.net/weixin_43482414/article/details/104667812