Davinci的時鐘管理是在arch/arm/mach-davici/clock.c中實現(xiàn).
最開始會調用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。
然后通過一個FOR循環(huán)注冊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)在啟動時,會將UART1設置為ENABLE狀態(tài)(通過PSC)。對于ARMCLK,它有個標示:flag=WLWAYS_ON,這表示在整個系統(tǒng)的運行過程中,對它的ENABLE,DISABLE都是無用的。
通過這樣的時鐘控制,就可以只在模塊工作的時候對模塊供給時鐘,節(jié)約能耗。在驅動中,一般在初始化時通過:
Clk_get
Clk_use
Clk_enable來使模塊處于ENABLE狀態(tài)。
在卸載時通過
Clk_unuse
Clk_disable來使模塊處于DISABLE狀態(tài).