Linux启动过程分析(十一)--PLL各个外设时钟频率的设置

之前分析过da850evm_init中的其它函数,现在来看一下da850_evm_init_cpufreq()这个函数:

ret = da850_evm_init_cpufreq();
if (ret)
pr_warning("da850_evm_init: cpufreq registration failed: %d\n",ret);

这个函数的内容如下:

#ifdef CONFIG_CPU_FREQ
static __init int da850_evm_init_cpufreq(void)
{
	/*
	 * 始终将 da850-sdi的最大速度设置为 CONFIG_DA850_SDI_MAX_SPEED ,
	 * 并且取消掉原来用来设置“da850_max_speed"的”system_rev"逻辑
	 */
	da850_max_speed = CONFIG_DA850_SDI_MAX_SPEED;//
	return da850_register_cpufreq("pll0_sysclk3");
}

static struct clk pll0_sysclk3 = {
	.name		= "pll0_sysclk3",
	.parent		= &pll0_clk,
	.flags		= CLK_PLL,
	.div_reg	= PLLDIV3,
	.set_rate	= da850_set_pll0sysclk3_rate,
	.maxrate	= 152000000,
};

先来分析
/* Use PLL1_SYSCLK3 for the PLL0 bypass clock */
da850_set_pll0_bypass_src(true);
->


static void da850_set_pll0_bypass_src(bool pll1_sysclk3)
{
	struct clk *clk = &pll0_clk;
	struct pll_data *pll;
	unsigned int v;

	pll = clk->pll_data;
	v = __raw_readl(pll->base + PLLCTL);
	if (pll1_sysclk3)
		v |= PLLC0_PLL1_SYSCLK3_EXTCLKSRC;
	else
		v &= ~PLLC0_PLL1_SYSCLK3_EXTCLKSRC;
	__raw_writel(v, pll->base + PLLCTL);
}

v是从pll0_clk的PLLCTL寄存器中读出的值,然后再和 PLLC0_PLL1_SYSCLK3_EXTCLKSRC BIT(9)=1<<9相或,表示
使用PLL1_SYSCLK3 作为PLL0的旁路时钟。然后再将这个值写回寄存器中。
再来分析:

for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
		if (da850_freq_table[i].frequency <= da850_max_speed) {
			cpufreq_info.freq_table = &da850_freq_table[i];
			break;
		}

将小于456000KHz的频率都赋值给cpufreq_info.freq_table。
cpufreq_info的结构内容如下:


static struct davinci_cpufreq_config cpufreq_info = {
	.freq_table = da850_freq_table,
#ifdef CONFIG_REGULATOR
	.init = da850_regulator_init,
	.set_voltage = da850_set_voltage,
#endif
	.emif_rate = CONFIG_DA850_FIX_PLL0_SYSCLK3RATE,
};

da850_freq_table的内容如下:


static struct cpufreq_frequency_table da850_freq_table[] = {
	OPP(456),
	OPP(432),
	OPP(408),
	OPP(372),
	OPP(300),
	OPP(200),
	OPP(96),
	{
		.index		= 0,
		.frequency	= CPUFREQ_TABLE_END,
	},
};

又因为:

#define OPP(freq) 		\
	{				\
		.index = (unsigned int) &da850_opp_##freq,	\
		.frequency = freq * 1000, \
	}

以OPP(456)为例:

OPP(456)
{
.index =(unsigned int) &da850_opp_456,\
.frequency=freq*1000,\
}

展开da850_opp_456得到:

 static const struct da850_opp da850_opp_456 = {
	.freq		= 456000,
	.prediv		= 1,
	.mult		= 19,
	.postdiv	= 1,
	.cvdd_min	= 1300000,
	.cvdd_max	= 1350000,
};
发布了83 篇原创文章 · 获赞 127 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_40788950/article/details/85417578