1. 在arch/arm/mach-mx5/mx53_loco.c的引脚定义,将GPIO_3定义成MX53_PAD_GPIO_3__CCM_CLKO2。
2. 在clock.c中加入clko2的定义:
staticint _clk_clko2_set_parent(struct clk *clk, struct clk *parent)
{
u32 sel, reg;
if (parent == &esdhc1_clk[0])
sel = 3;
else if (parent == &usboh3_clk[0])
sel = 4;
else if (parent == &ssi1_clk[0])
sel = 18;
else if (parent == &usb_phy_clk[0])
sel= 25;else
return -EINVAL;
reg = __raw_readl(MXC_CCM_CCOSR);
printk("*******************************reg= 0x%8x,%d\n",reg,sel);
reg &= ~MXC_CCM_CCOSR_CKO2_SEL_MASK;
reg |= sel <<MXC_CCM_CCOSR_CKO2_SEL_OFFSET;
__raw_writel(reg, MXC_CCM_CCOSR);
printk("*******************************reg= 0x%8X\n",reg);
return 0;
}这里的sel是根据datesheet里面的寄存器值来了,只列出了几个(注这里是10进制的值)
static unsigned long _clk_clko2_get_rate(struct clk *clk) { u32 reg = __raw_readl(MXC_CCM_CCOSR); u32 div = ((reg & MXC_CCM_CCOSR_CKO2_DIV_MASK) >> MXC_CCM_CCOSR_CKO2_DIV_OFFSET) + 1; // printk("****_clk_clko2_get_rate = %d****\n",clk_get_rate(clk->parent) / div); return clk_get_rate(clk->parent) / div; }
static int _clk_clko2_set_rate(struct clk *clk, unsigned long rate) { u32 reg; u32 parent_rate = clk_get_rate(clk->parent); u32 div = parent_rate / rate;
if (div == 0) div++; if (((parent_rate / div) != rate) || (div > 8)) return -EINVAL;
reg = __raw_readl(MXC_CCM_CCOSR); reg &= ~MXC_CCM_CCOSR_CKO2_DIV_MASK; reg |= (div - 1) << MXC_CCM_CCOSR_CKO2_DIV_OFFSET; __raw_writel(reg, MXC_CCM_CCOSR); printk("****_clk_clko2_set_rate = %ld****\n",rate); return 0; } |
static unsigned long _clk_clko2_round_rate(struct clk *clk, unsigned long rate) { u32 parent_rate = clk_get_rate(clk->parent); u32 div = parent_rate / rate;
/* Make sure rate is not greater than the maximum value for the clock. * Also prevent a div of 0. */ if (div == 0) div++; else if (parent_rate % rate) div++;
if (div > 8) div = 8; return parent_rate / div; } |
static int _clk_clko2_enable(struct clk *clk) { u32 reg; reg = __raw_readl(MXC_CCM_CCOSR); reg |= MXC_CCM_CCOSR_CKO2_EN_OFFSET; printk("-------------------------------enable = 0x%8x\n",reg); __raw_writel(reg, MXC_CCM_CCOSR); return 0; } |
|
static void _clk_clko2_disable(struct clk *clk) { u32 reg;
reg = __raw_readl(MXC_CCM_CCOSR); reg &= ~MXC_CCM_CCOSR_CKO2_EN_OFFSET; __raw_writel(reg, MXC_CCM_CCOSR); } |
static struct clk clko2_clk = { // __INIT_CLK_DEBUG(clko2_clk) .parent = &usb_phy_clk[0], .enable = _clk_clko2_enable, .enable_reg = MXC_CCM_CCOSR, .enable_shift = MXC_CCM_CCOSR_CKO2_EN_OFFSET, .disable = _clk_clko2_disable, .set_parent = _clk_clko2_set_parent, .set_rate = _clk_clko2_set_rate, .get_rate = _clk_clko2_get_rate, .round_rate = _clk_clko2_round_rate, }; |
这里是对clko2的一些初始化,使能和设置频率
3. 在mx53_clock_init中加入clko2 初始化代码
clk_set_parent(&clko2_clk, &usb_phy_clk[0]); clk_set_rate(&clko2_clk, 8000000); clk_enable(&clko2_clk); |
4. 在clk_lookup lookups[]中加入
_REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk), |