⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock_34xx.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				ret = -EINVAL;		} else if (clk->set_rate != 0) {		/*call clk specific rate func*/			ret = clk->set_rate(clk, rate);		}	}	if (ret == 0)		clk->recalc(clk);	return ret;}/* Change the parent of a clock */static int omap3_clk_set_parent(struct clk *cclk, struct clk *new_parent){	int ret = -EINVAL;	DPRINTK("Clock name: %s, Parent name: %s\n", cclk->name,		new_parent->name);	if ((cclk->flags & VDD1_CONFIG_PARTICIPANT)	    || (cclk->flags & VDD2_CONFIG_PARTICIPANT))		return ret;	if (!(cclk->flags & SRC_SEL))		return ret;	if (cclk->usecount > 0)	/*if clock is currently active. */		_omap3_clk_disable(cclk); /* shut down clock to stop glitch */	ret = prcm_clk_set_source(cclk->prcmid, new_parent->prcmid);	if (ret != PRCM_PASS)		ret = -EINVAL;	if (cclk->usecount > 0)		_omap3_clk_enable(cclk);	if (ret == 0) {		cclk->parent = new_parent;		cclk->recalc(cclk);	}	return ret;}/* Return the parent of a clock */static struct clk *omap3_clk_get_parent(struct clk *clk){	return clk->parent;}static void omap3_table_recalc(struct clk *clk){	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))		return;	if (clk == &virt_vdd1_prcm_set)		clk->rate = curr_vdd1_prcm_set->speed;	else		clk->rate = curr_vdd2_prcm_set->speed;	DPRINTK("CLK RATE:%lu\n", clk->rate);}static long omap3_round_to_table_rate(struct clk *clk, unsigned long rate){	struct vdd_prcm_config *ptr;	long highest_rate;	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))		return -EINVAL;	highest_rate = -EINVAL;	if (clk == &virt_vdd1_prcm_set)		ptr = vdd1_rate_table + MAX_VDD1_OPP;	else		ptr = vdd2_rate_table + MAX_VDD2_OPP;	for (; ptr->speed; ptr--) {		highest_rate = ptr->speed;		DPRINTK("Highest speed : %lu, rate: %lu\n", highest_rate, rate);		if (ptr->speed <= rate)			break;	}	return highest_rate;}static int omap3_select_table_rate(struct clk *clk, unsigned long rate){	u8 cpu_mask = 0;	u32 cur_vdd_rate, current_opp;	struct vdd_prcm_config *prcm_vdd;	unsigned long found_speed = 0;	int ret = -EINVAL;	int div = 0;	if ((clk != &virt_vdd1_prcm_set) && (clk != &virt_vdd2_prcm_set))		return ret;	if (cpu_is_omap3430())		cpu_mask = RATE_IN_343X;	if (clk == &virt_vdd1_prcm_set)		prcm_vdd = vdd1_rate_table + MAX_VDD1_OPP;	else		prcm_vdd = vdd2_rate_table + MAX_VDD2_OPP;	for (; prcm_vdd->speed; prcm_vdd--) {		if (!(prcm_vdd->flags & cpu_mask))			continue;		if (prcm_vdd->speed <= rate) {			found_speed = prcm_vdd->speed;			DPRINTK("Found speed = %lu\n", found_speed);			break;		}	}	if (!found_speed) {		printk(KERN_INFO "Could not set table rate to %luMHz\n",		       rate / 1000000);		return -EINVAL;	}	if (clk == &virt_vdd1_prcm_set) {		ret =			prcm_get_processor_speed(clk->parent->prcmid,					&cur_vdd_rate);		if (ret != PRCM_PASS)			return -EINVAL;		current_opp = curr_vdd1_prcm_set->opp;	} else {		ret = prcm_get_dpll_rate(clk->parent->prcmid,						&cur_vdd_rate);		if (ret != PRCM_PASS)			return -EINVAL;		/* Now cur_vdd_rate holds value of core_ck */		/* The divider for l3_ck */		ret = prcm_clksel_get_divider((&l3_ck)->prcmid, &div);		if ((ret != PRCM_PASS) || (div == 0))			return -EINVAL;		cur_vdd_rate /= div;		current_opp = curr_vdd2_prcm_set->opp;	}	cur_vdd_rate *= 1000;	DPRINTK("Current rate:%lu\n", cur_vdd_rate);	if (cur_vdd_rate != found_speed) {		ret =			prcm_do_frequency_scaling(prcm_vdd->opp,					current_opp);		if (ret != PRCM_PASS)			return -EINVAL;	}	if (clk == &virt_vdd1_prcm_set) {		curr_vdd1_prcm_set = prcm_vdd;		omap3_clk_recalc(&mpu_ck);		omap3_propagate_rate(&mpu_ck);		omap3_clk_recalc(&iva2_ck);		omap3_propagate_rate(&iva2_ck);		/*Update loops_per_jiffy if processor speed is being changed*/		loops_per_jiffy = compute_lpj(loops_per_jiffy,				(cur_vdd_rate / 1000),				(found_speed / 1000));	} else {		curr_vdd2_prcm_set = prcm_vdd;		omap3_clk_recalc(&core_ck);		omap3_propagate_rate(&core_ck);		omap3_clk_recalc(&core_x2_ck);		omap3_propagate_rate(&core_x2_ck);		omap3_clk_recalc(&emul_core_alwon_ck);		omap3_propagate_rate(&emul_core_alwon_ck);	}	return 0;}/*-------------------------------------------------------------------------* * Omap3 clock reset and init functions *-------------------------------------------------------------------------*//* If usecount of clock is 0, disable it */static void omap3_disable_unused_clocks(struct clk *clk){	DPRINTK("Disabling unused clock \"%s\"...\n ", clk->name);	_omap3_clk_disable(clk);}/* Get the rate of oscillator by calling PRCM API */static void omap3_get_crystal_rate(struct clk *osc){	osc->rate = prcm_get_crystal_rate() * 1000;	DPRINTK("Rate:%d\n", osc->rate);}static struct clk_functions omap3_clk_functions = {	.clk_enable = omap3_clk_enable,	.clk_disable = omap3_clk_disable,	.clk_round_rate = omap3_clk_round_rate,	.clk_set_rate = omap3_clk_set_rate,	.clk_set_parent = omap3_clk_set_parent,	.clk_get_parent = omap3_clk_get_parent,	.clk_disable_unused = omap3_disable_unused_clocks,};/* * Set clocks for bypass mode for reboot to work. */void omap3_clk_prepare_for_reboot(void){	/* Will be implemented when frequency change code is in place */	return;}/* Get the parent clocks by reading registers and populate   the clock nodes with the correct parent information */static int omap3_update_sources(void){	struct clk **clkptr;	struct clk *cp;	u32 pid = 0, ret = -EINVAL;	for (clkptr = onchip_clks;	     clkptr < onchip_clks + ARRAY_SIZE(onchip_clks); clkptr++) {		cp = *clkptr;		if (cp->flags & SRC_SEL) {			ret = prcm_clk_get_source(cp->prcmid, &pid);			if (ret != PRCM_PASS) {				DPRINTK(KERN_ERR				"prcm_clk_get_source returned error for %s\n",					cp->name);				return -EINVAL;			}			switch (cp->prcmid) {			case PRCM_48M_FCLK:				if (pid == PRCM_DPLL4_M2X2_CLK)					cp->parent = &func_96m_ck;				else					cp->parent = &sys_alt_ck;				break;			case PRCM_TVOUT:				if (pid == PRCM_DPLL4_M3X2_CLK)					cp->parent = &dpll4_m3x2_ck;				else					cp->parent = &sys_alt_ck;				break;			case PRCM_USIM:				if (pid == PRCM_SYS_CLK)					cp->parent = &sys_ck;				else if (pid == PRCM_DPLL4_M2X2_CLK)					cp->parent = &cm_96m_ck;				else					cp->parent = &ext_mcbsp_ck;				break;			case PRCM_SGX_FCLK:				if (pid == PRCM_DPLL3_M2_CLK)					cp->parent = &core_ck;				else					cp->parent = &ext_mcbsp_ck;				break;			case PRCM_96M_CLK:				if (pid == PRCM_DPLL4_M2X2_CLK)					cp->parent = &cm_96m_ck;				else					cp->parent = &sys_ck;				break;			case PRCM_SYS_CLKOUT2:				if (pid == PRCM_DPLL3_M2_CLK)					cp->parent = &core_ck;				else if (pid == PRCM_SYS_CLK)					cp->parent = &sys_ck;				else if (pid == PRCM_DPLL4_M2X2_CLK)					cp->parent = &func_96m_ck;				else					cp->parent = &dss_tv_fck;				break;			case PRCM_MCBSP1:			case PRCM_MCBSP2:			case PRCM_MCBSP3:			case PRCM_MCBSP4:			case PRCM_MCBSP5:				if (pid == PRCM_DPLL4_M2X2_CLK)					cp->parent = &func_96m_ck;				else					cp->parent = &ext_mcbsp_ck;				break;			case PRCM_GPT1:			case PRCM_GPT2:			case PRCM_GPT3:			case PRCM_GPT4:			case PRCM_GPT5:			case PRCM_GPT6:			case PRCM_GPT7:			case PRCM_GPT8:			case PRCM_GPT9:			case PRCM_GPT10:			case PRCM_GPT11:				if (pid == PRCM_SYS_32K_CLK)					cp->parent = &sys_32k_ck;				else					cp->parent = &sys_ck;			}			DPRINTK("Parent updated for clock: %s\n", cp->name);			DPRINTK("Parent name: %s\n", cp->parent->name);		}	}	return 0;}/* Arch specific init */static int __init omap3_clk_arch_init(void){	struct vdd_prcm_config *vdd1_prcm;	struct vdd_prcm_config *vdd2_prcm;	u32 sys_clk_speed, mpu_speed, core_speed, l3_speed = 0;	int div;	/* Lock DPLL5 */	if (prcm_configure_dpll(DPLL5_PER2, -1, -1, -1))		panic("FATAL ERROR: Unable to Configure DPLL5\n");	if (prcm_enable_dpll(DPLL5_PER2))		panic("FATAL ERROR: Unable to Lock DPLL5\n");	omap3_get_crystal_rate(&osc_ck);	omap3_update_sources();	sys_clk_speed = prcm_get_system_clock_speed() * 1000;	prcm_get_processor_speed(DOM_MPU, &mpu_speed);	mpu_speed = mpu_speed * 1000;	prcm_get_dpll_rate((&core_ck)->prcmid, &core_speed);	core_speed = core_speed * 1000;	prcm_clksel_get_divider((&l3_ck)->prcmid, &div);	if (div != 0)		l3_speed = core_speed / div;	else		printk(KERN_ERR"Error: Divider for L3 returned 0 in omap3_clk"					"_arch_init\n");	DPRINTK("System clock speed: %lu, mpu speed : %lu, l3_speed : %lu"				"\n", sys_clk_speed, mpu_speed, l3_speed);	for (vdd1_prcm = vdd1_rate_table+MAX_VDD1_OPP; vdd1_prcm->speed;	vdd1_prcm--) {		DPRINTK("%lu\n", vdd1_prcm->speed);		if (vdd1_prcm->speed <= mpu_speed)			break;	}	curr_vdd1_prcm_set = vdd1_prcm;	for (vdd2_prcm = vdd2_rate_table+MAX_VDD2_OPP; vdd2_prcm->speed;		vdd2_prcm++) {		DPRINTK("%lu\n", vdd2_prcm->speed);		if (vdd2_prcm->speed <= l3_speed)			break;	}	curr_vdd2_prcm_set = vdd2_prcm;	propagate_rate(&osc_ck);	/* update main root fast */	propagate_rate(&sys_32k_ck);	/* update main root slow */	propagate_rate(&sys_alt_ck);	/* update alt ck tree */	DPRINTK("Rate propagation done for all clocks\n");	return 0;}arch_initcall(omap3_clk_arch_init);int __init omap3_clk_init(void){	struct clk **clkp;	resource_init();	clk_init(&omap3_clk_functions);	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);	     clkp++) {		if ((*clkp)->flags & CLOCK_IN_OMAP343X) {			clk_register(*clkp);			continue;		}	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -