時鐘分頻原理
如果cpu是計算機的大腦,電流是計算機的血液,那么時鐘則是計算機的心臟,時鐘頻率決定了處理器運算的快慢,它的每一次“跳動”都驅動著處理器不停的執行命令。不同的是,人的各個部位心率是一樣的,但計算機卻有多個頻率,而且每個部位可能有不同的頻率,比如“大腦”有一個頻率,“手“有一個頻率,“腳”使用的是另外一個頻率,這樣就產生了兩個問題:怎么產生這些不同的頻率?處理器怎么與自己不同頻率的外設實現交互?
怎么產生這些不同的頻率?
為了獲取穩定的時鐘,我們一般使用外部晶振來提供,晶振是由石英和震蕩電路組成的,石英能夠提供穩定的頻率。一般一個計算機系統最少需要一個晶振,有些特殊的外設也會有自己特有的晶振,比如網卡,顯卡等,但是對于大多數連接cup的外設來說是沒有自己的晶振的,那么就需要cpu給他們提供時鐘,然而不同的外設需要的時鐘不一樣,cpu是怎么給這些外設提供不同的時鐘呢?
ARM處理器主要給外設提供了兩種連接總線,AHB總線(Advanced high Performance Bus)和APB總線,這兩種總線的時鐘在沒有初始化之前是一樣的,頻率等于外部晶振提供的頻率,在初始化以后,它們就可以為外設提供不同的時鐘了。
AHP和APB總線的內容將放到后面章節作為補充知識了解,因為他們對我們分析uboot的啟動過程關系不大。由于這兩種總線初始化以后,時鐘是不一樣的,所以連接的外設也不一樣,如下圖,一些工作頻率較高的外設掛接在AHB總線上,比如內存,nandflash,LCD控制器等,而工作頻率比較低的外設則掛接在APB總線上,比如UART串口,Watchdog,GPIO,USB等(注意:這里使用掛接,是因為這些設備是可以拔除的,而不影響其他外設的工作)。
我們這里先不管這些外設是怎么和總線連接的,但是先了解一點:連接在同一個總線上的外設,獲取到的時鐘是一樣的。當AHB和APB上的時鐘都不能滿足外設需求的時候,就需要PWM timer來幫忙了。
上面這張圖是s3c2440的時鐘生成圖,看上去挺復雜的,其實并不是那么回事,對于uboot的啟動來說,只要了解圖中紅色框框的部分就可以了,但是如果要編寫UBS驅動或者攝像頭驅動,則會涉及到圖中灰綠色的部分。因為我們只要分析uboot啟動過程中涉及到的東西,所以對USB和cam部分就不細講了。
圖中紅色框表示的是主時鐘的產生過程,灰綠色的框表示USB時鐘的產生過程,紅色線條表示輸出HCLK,綠色線條表示PCLK,黃色線條表示FCLK。
uboot啟動的時候,需要設置時鐘分頻,分頻的目的就是產生三種時鐘:PCLK、FCLK和HCLK,PCLK供APB總線使用,HCLK供AHB總線使用,FCLK則供cpu使用,而且從datasheet的電氣參數那一章可以查到FCLK,HCLK和PCLK的最大值分別是400MHz,100MHz和50MHz。下面就依照圖中的步驟來分析,這三種時鐘是怎么產生的。下圖是對上面這張圖的簡概:
1.時鐘源
為了減少外界環境對開發板的電磁干擾,降低制作成本,通常開發板的外部晶振時鐘頻率都是很低的。從圖中第一個紅框可以看出,cpu可以連接兩種外部時鐘源,一種是振蕩時鐘源,一種是時鐘信號,前者就是石英晶體振蕩電路,后者是其他振蕩器產生的時鐘信號,比如信號發生器產生的時鐘信號,雖然兩者都是特定頻率的正弦波形,但是在cpu的接線方式上是有不同的。
從這張表中可以看出,s3c2440可以連接兩個時鐘源,一個是主時鐘源,一個是USB時鐘源,如果主時鐘源需要接晶振源,則OM3需要為0,也就是要接地(這里暫時不討論ubs時鐘),同理,如果UBS時鐘源需要接晶振源,則OM2要接地。從電路圖中可以看到,OM2和OM3都接地,而且XTIpll引腳和XTOpll引腳接的是外部12M晶振,所以這里開發板的時鐘源是12M的外部晶振。(USB的時鐘源這里不討論)
需要注意的是,晶振提供的時鐘,只有在上電以后才開始起振的,而外部提供的信號時鐘是板子沒有上電的時候就已經在振蕩了,所以對晶振時鐘源需要作一個特殊的處理——變頻鎖定。
2.變頻鎖定
開發板剛上電的時候,晶振OSC開始提供晶振時鐘,由于系統剛剛上電,電壓信號等都還不穩定,這時復位信號(nRESET)拉低,那么外部晶振則直接作為系統時鐘FCLK,這時的FCLK是不規則的,為了讓cpu使用規則的時鐘頻率,需要將clock disable一小段時間,這個時間就是圖中的Lock Time,在這段時間里面,電壓會慢慢穩定,時鐘頻率也會調整到一個新的穩定狀態(VCO is adapted to new clock frequency),而且這段時間里面,FCLK是為0的,也就是說cpu是不會運行的,當這個Lock Time結束以后,FCLK就會獲得一個新的頻率(FCLK is new frequency)。注意這個時候的FCLK頻率就是晶振提供的頻率,他們的大小是一樣的,當經過倍頻以后,這個值將數倍的變化。
下面是變頻鎖定時間的設定寄存器:0~15位是設置主時鐘源鎖定時間的,后15位是設置USB鎖頻時間的,這里不考慮,值得注意的是對應的鎖頻時間可以從datasheet的電氣數據表中查到(PLL Lock Time)。
3.倍頻設置(鎖相環)
當cpu能夠獲取到穩定的時鐘時,就需要對時鐘進行倍頻了,現在知道外部晶振輸入的時鐘時12M,那怎樣把這個時鐘提高到100MHz,甚至是400MHz呢?這就涉及到了時鐘生成圖的第二個紅框框了(注意框框上面的S,P,M字樣),這個叫鎖相環(PLL),主頻的倍頻操作是由MPLL來設置的,而USB的倍頻操作是由UPLL來設置的,UPLL暫時不討論。所以要讓外部時鐘經過變化,擴大到400M,就需要對MPLLCON寄存器進行設置。
從上圖可以看出,不管是MLLCON或者UPLLCON,都由三個部分組成,主分頻、預分頻、后分頻控制位,這些分頻數值決定了12M進去的頻率,將會輸出多大頻率,下面這張表是手冊的推薦設置:比如我們要將12M是時鐘頻率倍頻成405M,則需要MDIV=0x7f,PDIV=0x2,SDIV=1,注意49M和96M是給USB的UPPLCON設置的。
當然也可以不參考這個表格,使用計算公式
4.設置比例(分頻器)
設置完PLL寄存器以后,當穩定的時鐘通過鎖相環則會輸出更大倍數的頻率,而這個更大倍數的頻率則是FCLK,現在這個值則是400MHz,而不是12MHz了,現在我們得到了想要的FCLK,那怎么得到PCLK和HCLK呢?下面就涉及到分頻器的設置。
怎么設置HDIVN和PCIVN的數值,主要查找下面的表:
比如我們要將HCLK設置為100,PCLK設置為50, 那么HCLK=FCLK/4,PCLK=FCLK/8,查表可知為1:4:8,所以HDIVN=0x2,PDIVN=0x1, dvin_UPLL是UBS的時鐘,這里不討論。
但是根據datasheet說明,當HDIV設置為非0的時候,cpu總線模式要進行改變,默認情況下FCLK=HCLK,cpu工作在fast bus mode快速總線模式下,HDIV設置為非0后,FCLK和HCLK不再相等,要將cpu改為異步總線模式,需要使用對應的代碼進行設置。
所以上面三步的代碼可總結如下:
[plain] view plain copy#define S3C2410_MPLL_200MHZ ((0x5c《《12)|(0x04《《4)|(0x00))
#define S3C2440_MPLL_200MHZ ((0x5c《《12)|(0x01《《4)|(0x02))
/*
* 對于MPLLCON寄存器,[19:12]為MDIV,[9:4]為PDIV,[1:0]為SDIV
* 有如下計算公式:
* S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
* S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)
* 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV
* 對于本開發板,Fin = 12MHz
* 設置CLKDIVN,令分頻比為:FCLK:HCLK:PCLK=1:2:4,
* FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
*/
void clock_init(void)
{
// LOCKTIME = 0x00ffffff; // 使用默認值即可
CLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
/* 如果HDIVN非0,CPU的總線模式應該從“fast bus mode”變為“asynchronous bus mode” */
__asm__(
“mrc p15, 0, r1, c1, c0, 0 ” /* 讀出控制寄存器 */
“orr r1, r1, #0xc0000000 ” /* 設置為“asynchronous bus mode” */
“mcr p15, 0, r1, c1, c0, 0 ” /* 寫入控制寄存器 */
);
/* 判斷是S3C2410還是S3C2440 */
if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))
{
MPLLCON = S3C2410_MPLL_200MHZ; /* 現在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
}
else
{
MPLLCON = S3C2440_MPLL_200MHZ; /* 現在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
}
}
對于USB和CAM的時鐘設置都是相似的,這里就不累述了
補充:
前面介紹了鎖相環寄存器的設置,這里對鎖相環的工作原理作一個簡述。一個12MHz的時鐘經過鎖相環以后,產生了400MHz的FCLK時鐘,它是怎么辦到的呢?
鎖相環的作用比較多,不僅可以倍頻,還可以合成頻率,音頻解碼等,實現原理有所不同,下圖是S3c2440的鎖相環實現原理圖:
(1)當外部時鐘Fin進入鎖相環的時候,預分頻器(Divider P)會將該時鐘進行處理得到Fref信號,這個信號是reference參考信號,用于后面分頻的相位參考。
(2)Fref將第一次進入PFD(Phase Frequency Detector)相位鑒定器,它主要完成Fref和Fvco的相位鑒定,當輸出和輸入信號的頻率和相位保持恒定不變的時候,鎖相環進入相位鎖定的狀態,當輸出和輸入信號的頻率和相位有差異的時候,則會發送信號給PUMP。
(3)PUMP會將PFD的控制信號轉換成合適電壓信號給循環濾波器
(4)濾波器會對從PUMP過來的波形進行過濾,然后將信號送給VCO
(5)VCO(Voltage Controlled Oscillator),壓控振蕩器,這里是倍頻的關鍵步驟,壓控振蕩器的振蕩頻率會隨時間而變,鎖相環進入“頻率牽引”,自動跟蹤捕捉輸入信號的頻率,然后將輸出進行主分頻(Divider M),產生Fvco.
(6)Fvco會進入PFD與Fref進行相位和頻率的差異對比,如果處在差異,則繼續進入循環,如果沒有差異,則PFD停止向PUMP發送信號,鎖相環進入相位鎖定的狀態。
(7)當鎖相環進入相位鎖定的狀態,VCO的輸出將通過后分頻器(Divider S)輸出MPLL或者UPLL。
所以要使用鎖相環,就需要設置XPLLCON的P,M,S;關于鎖相環的更具體的原理,請GOOGLE。
至于分頻器的工作原理比較簡單,主要是改變波形的占空比達到將高頻變低頻的效果,所以需要設置HDIVN和PDIVN。
總結:這篇文章分析了怎么設置時鐘分頻,讓cpu以及外部設備工作在更高的頻率上面,主要涉及三個寄存器的設置——LOCKTIMRE,MPLLCON,CLOCKDIVN
再回憶一下開發板啟動的過程,當開發板上電的時候,啟動過程是:進入管理模式——關看門狗——關中斷——時鐘分頻。。.
在設置時鐘分頻以前,cpu都是工作在12Mhz頻率的,當設置完時鐘分頻后,cpu的工作頻率將是400MHZ,這相當于完成了一個蛻變,從一個普通人變成了超人,多了幾十倍的反應速度,更加高效的執行后面的代碼。想想如果沒有對時鐘進行倍頻處理,仍然讓它運行在12MHz,處理同一件任務多要30多倍的時間,將是一件多么折磨人的事情。
接下來將會繼續對時鐘這個問題進行分析,雖然這里分析了怎么設置時鐘分頻,但是這只是開始,后面將對省電模式,快啟動,慢啟動,實時時鐘,pwm時鐘等內容進行講解。
評論