分类: 嵌入式
2011-02-06 18:56:17
Davinci的时钟管理是在arch/arm/mach-davici/clock.c中实现.
最开始会调用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寄存器的值得出的值,系统晶振27M。根据PLL1_PLLM算是ARM CORE的频率armrate以及外围器件的频率commonrate。
然后通过一个FOR循环注册davinci_clks中的struct clk 。
Clk_register()是将这些struct clk加入clocks链表。
如果struct clk的usecount为1,还要通过clk_enable()使该模块处于enable状态。
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,
},
可见系统在启动时,会将UART1设置为ENABLE状态(通过PSC)。对于ARMCLK,它有个标示:flag=WLWAYS_ON,这表示在整个系统的运行过程中,对它的ENABLE,DISABLE都是无用的。
通过这样的时钟控制,就可以只在模块工作的时候对模块供给时钟,节约能耗。在驱动中,一般在初始化时通过:
Clk_get
Clk_use
Clk_enable来使模块处于ENABLE状态。
在卸载时通过
Clk_unuse
Clk_disable来使模块处于DISABLE状态.