接上篇內容:如下 這個寄存器我們用到兩個位: STEP_SEL:選擇 setp_clk 時鐘源。 PLL1_SW_CLK_SEL:選擇 pll1_sw_clk 時鐘源。 到此,我們可以簡單整理下修改主頻思路: 1. 設置 CCSR 的 STEP_SEL 位,設置 step_clk 的時鐘源為 24M。 2. 設置 CCSR 的 PLL1_SW_CLK_SEL 位,設置 pll1_sw_clk 的時鐘源 step_clk=24MHz,通過這一步我們就將 I.MX6ULL 的主頻先設置為 24MHz,直接來自于外部的 24M 時鐘晶振。 3. 設置 CCM_ANALOG_PLL_ARMn,將 pll1_main_clk(PPL1)設置為 1056MHz。 4. 設置 CCSR 的 PLL1_SW_CLK_SEL 位,重新將 pll1_sw_clk 的時鐘源切換回 pll1_main_clk,切換回 來以后的 pll1_sw_clk 就等于 1056MHz。 5. 設置 CCM_CACRR 的 ARM_PODF 為 2 分頻,內核主頻就是 1056/2=528MHz。PFD 時鐘 我們還需要設置好其他的 PLL 和 PFD 時鐘,PLL1 上一小節已經設置了,其他的 PPL 時鐘有的是固定的 (PPL2-528MHz,PPL3-480MHz,PPL7-480MHz),有的暫時可以不需要設置(PPL4,PPL5,PPL6 分別對應音視頻和網絡)。 接下來就是設置 PFD 時鐘。恩智浦有官方推薦數值如下表: ![]() PLL2 的 4 路 PFD 頻率,用到寄存器是 CCM_ANALOG_PFD_528n,寄存器結構如圖 15.1.13 所示: ![]() 寄存器 CCM_ANALOG_PFD_528n 分為四組,分別對應 PFD0~PFD3,每組 8 個 bit,我們就以 PFD0 為例,看一下如何設置 PLL2_PFD0 的頻率。 PFD0 對應的寄存器位如下: PFD0_FRAC:PLL2_PFD0 的分頻數,PLL2_PFD0 的計算公式為 528*18/PFD0_FRAC,可設置的范圍為 12~35。 PFD0_STABLE:只讀位,通過此位判斷 PLL2_PFD0 是否穩定,新分頻生效時此位取反。 PFD0_CLKGATE:PLL2_PFD0 輸出使能位。1 表示關閉 PLL2_PFD0 輸出;0 表示使能 PLL2_PFD0 輸出 PLL2_PFD0 的頻率為 352MHz,需要設置 PFD0_FRAC=528*18/352=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, 實際為 396MHz;PLL2_PFD3=297MHz 的話,PFD3_FRAC=32。 接下來配置 PLL3_PFD0~PLL3_PFD3 這 4 路 PFD 的頻率,使用到的寄存器是 CCM_ANALOG_PFD_480n,此寄存器結構如圖 15.1.14 所示: ![]() 寄存器 CCM_ANALOG_PFD_480n 和 CCM_ANALOG_PFD_528n 的結構是一模一樣的,寄存器位的含義也是一樣的,只是頻率計算公式不同,頻率計算公式為 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。 AHB、IPG 和 PERCLK 根時鐘 iMX6ULL 外設根時鐘可設置范圍如圖 15.1.15 所示: ![]() 這里給大多數外設的根時鐘設置范圍,AHB_CLK_ROOT 最高可以設置 132MHz,IPG_CLK_ROOT 和PERCLK_CLK_ROOT 最高可以設置 66MHz。我們將 AHB_CLK_ROOT、IPG_CLK_ROOT 和 PERCLK_CLK_ROOT 分別設置為 132MHz、66MHz、66MHz。AHB_CLK_ROOT 和 IPG_CLK_ROOT 的設置如圖 15.1.16 所示: ![]() 上圖就是 AHB_CLK_ROOT 和 IPG_CLK_ROOT 的時鐘圖,圖中分為了 4 部分: 1. 用來選擇 pre_periph_clk 的時鐘源,可以選擇 PLL2、PLL2_PFD2、PLL2_PFD0 和 PLL2_PFD2/2。寄存 器 CCM_CBCMR 的 PRE_PERIPH_CLK_SEL 位 決 定 選 擇 哪 一 個 , 默 認 選 擇 PLL2_PFD2 , 因 此 默 認pre_periph_clk=PLL2_PFD2=396MHz。 2. 用來選擇 periph_clk 的時鐘源,由寄存器 CCM_CBCDR 的 ERIPH_CLK_SEL 位與 PLL_bypass_en2 組成的或門來選擇。當 CCM_CBCDR 的 PERIPH_CLK_SEL 位為 0 的時候 periph_clk=pr_periph_clk=396MHz。 3. 通 過 CBCDR 的 AHB_PODF 位 來 設 置 AHB_CLK_ROOT 的 分 頻 值 , 1~8 分 頻 8 種 , 如 果 想 要AHB_CLK_ROOT=132MHz 的話就應該設置為 3 分頻(默認):396/3=132MHz。 4. 通過 CBCDR 的 IPG_PODF 位來設置 IPG_CLK_ROOT 的分頻值,1~4 分頻 4 種,IPG_CLK_ROOT 時鐘源是 AHB_CLK_ROOT,要想 IPG_CLK_ROOT=66MHz 的話就應該設置 2 分頻(默認):132/2=66MHz。 最后要配置 PERCLK_CLK_ROOT 時鐘頻率。如圖 15.1.17 所示: ![]() 可以看出,PERCLK_CLK_ROOT 時鐘來源有兩個,OSC(24MHz)和 IPG_CLK_ROOT,由寄存器 CCM_CSCMR1的 PERCLK_CLK_SEL 決定,如果該位為 0,則 PERCLK_CLK_ROOT 的時鐘源是 IPG_CLK_ROOT=66MHz,可以通過設置寄存器 CCM_CSCMR1 的 PERCLK_PODF 位來配置分頻,我們需要 66MHz 的 PERCLK_CLK_ROOT,所以這里配置為 1 分頻。 在上面的設置中用到了三個寄存器。 寄存器 CCM_CBCDR 結構圖如圖 15.1.18: ![]() 該寄存器各位解釋如下: PERIPH_CLK2_PODF:periph2 時鐘分頻,可設置 1~8 分頻 8 種。 PERIPH2_CLK_SEL:選擇 peripheral2 的主時鐘,修改此位會引起一次與 MMDC 的握手,修改完成以后要等待握手完成,握手完成信號由寄存器CCM_CDHIPR中指定位表示。為0選擇PLL2;為1選擇periph2_clk2_clk。PERIPH_CLK_SEL:peripheral 主時鐘選擇,修改此位會引起一次與 MMDC 的握手,所以修改完成以后要等待握 手完成, 握手完成 信號由寄 存器 CCM_CDHIPR 中指定 位表示。 為 0 選擇 PLL2;為 1 選擇periph_clk2_clock。 AXI_PODF:axi 時鐘分頻,可設置 1~8 分頻 8 種。 AHB_PODF:ahb 時鐘分頻,可設置 1~8 分頻 8 種。修改此位會引起一次與 MMDC 的握手,所以修改完成以后要等待握手完成,握手完成信號由寄存器 CCM_CDHIPR 中指定位表示。 IPG_PODF:ipg 時鐘分頻,可設置 1~4 分頻 4 種。 AXI_ALT_CLK_SEL:axi_alt 時鐘選擇。為 0 選擇 PLL2_PFD2;為 1 選擇 PLL3_PFD1。 AXI_CLK_SEL:axi 時鐘源選擇。為 0 選擇 periph_clk;為 1 選擇 axi_alt 時鐘。 FABRIC_MMDC_PODF:fabric/mmdc 時鐘分頻設置,可設置 1~8 分頻 8 種。 PERIPH2_CLK2_PODF:periph2_clk2 的時鐘分頻,可設置 1~8 分頻 8 種。 寄存器 CCM_CBCMR 結構圖圖 15.1.19: ![]() 寄存器各個位的解釋如下: LCDIF1_PODF:lcdif1 的時鐘分頻,可設置 1~8 分頻 8 種。 PRE_PERIPH2_CLK_SEL:pre_periph2 時鐘源選擇。為 00 選擇 PLL2,為 01 選擇 PLL2_PFD2,為 10 選擇PLL2_PFD0,為 11 選擇 PLL4。 PERIPH2_CLK2_SEL:periph2_clk2 時鐘源選擇。為 0 選擇 pll3_sw_clk,為 1 選擇 OSC。 PRE_PERIPH_CLK_SEL:pre_periph 時鐘源選擇。為 00 選擇 PLL2,為 01 選擇 PLL2_PFD2,為 10 選擇 PLL2_PFD0,為 11 選擇 PLL2_PFD2/2。 PERIPH_CLK2_SEL:peripheral_clk2 時鐘源選擇。為 00 選擇 pll3_sw_clk,為 01 選擇 osc_clk,為 10 選擇pll2_bypass_clk。 接下來是寄存器 CCM_CSCMR1,結構如圖 15.1.20 所示: ![]() 該寄存器我們主要用到 PERCLK_CLK_SEL 和 PERCLK_PODF 位,解釋如下: PERCLK_CK_SEL:perclk 時鐘源選擇。為 0 選擇 ipg clk,為 1 選擇 osc clk。 PERCLK_PODF:perclk 的時鐘分頻,可設置 1~8 分頻 8 種。 這里要注意,我們在修改配置如下時鐘選擇器或者分頻器的時候會引起與 MMDC 的握手發生: 1.mmdc_podf,2.periph_clk_sel,3.periph2_clk_sel,4.arm_podf,5.ahb_podf。在發生握手信號后需等待握手完成,寄存器 CCM_CDHIPR 中保存著握手信號是否完成,如果相應的位為 1 的話就表示握手沒有完成,如果為 0 的話就表示握手完成,很簡單,這里就不一一列舉寄存器 CCM_CDHIPR 中的各個位了。 在修改 arm_podf 和 ahb_podf 時,要先關閉其時鐘輸出,等修改完成之后再開啟,否則的話可能會出現在修改完成以后沒有時鐘輸出的現象。 至此,iMX6ULL 的時鐘系統就講解完了,iMX6ULL 的時鐘系統相對很復雜,大家要結合《I.MX6ULL 參考手冊.pdf》中時鐘相關的結構圖來學習。 ![]() |