Davinci的時(shí)鐘管理是在arch/arm/mach-davici/clock.c中實(shí)現(xiàn).
最開始會(huì)調(diào)用davinci_clk_init()。
void davinci_clk_init(void)
{
struct clk *clkp;
int count = 0;
commonrate = ((PLL1_PLLM + 1) * 27000000) / 6;
armrate = ((PLL1_PLLM + 1) * 27000000) / 2;
for (clkp = davinci_clks; count < DAVINCI_MAX_CLK; count++, clkp++) {
clk_register(clkp);
/* Turn on clocks that have been enabled in the
* table above */
if (clkp->usecount) {
clk_enable(clkp);
}
}
}
PLL1_PLLM是通過讀PLL寄存器的值得出的值,系統(tǒng)晶振27M。根據(jù)PLL1_PLLM算是ARM CORE的頻率armrate以及外圍器件的頻率commonrate。
然后通過一個(gè)FOR循環(huán)注冊(cè)davinci_clks中的struct clk 。
Clk_register()是將這些struct clk加入clocks鏈表。
如果struct clk的usecount為1,還要通過clk_enable()使該模塊處于enable狀態(tài)。
davinci_clks定義如下:
static struct clk davinci_clks[DAVINCI_MAX_CLK] = {
{
.name = "ARMCLK",
.rate = &armrate,
.lpsc = -1,
.flags = ALWAYS_ENABLED,
},
{
.name = "UART",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_UART0,
.usecount = 1,
},
{
.name = "EMACCLK",
.rate = &commonrate,
.lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
},
{
.name = "I2CCLK",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_I2C,
},
{
.name = "UART1",
.rate = &fixedrate,
.lpsc = DAVINCI_LPSC_UART1,
.usecount = 1,
},
可見系統(tǒng)在啟動(dòng)時(shí),會(huì)將UART1設(shè)置為ENABLE狀態(tài)(通過PSC)。對(duì)于ARMCLK,它有個(gè)標(biāo)示:flag=WLWAYS_ON,這表示在整個(gè)系統(tǒng)的運(yùn)行過程中,對(duì)它的ENABLE,DISABLE都是無用的。
通過這樣的時(shí)鐘控制,就可以只在模塊工作的時(shí)候?qū)δK供給時(shí)鐘,節(jié)約能耗。在驅(qū)動(dòng)中,一般在初始化時(shí)通過:
Clk_get
Clk_use
Clk_enable來使模塊處于ENABLE狀態(tài)。
在卸載時(shí)通過
Clk_unuse
Clk_disable來使模塊處于DISABLE狀態(tài).