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

📄 clock.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
{	unsigned dsor;	__u16 ratio_bits;	/* Determine current rate and ensure clock is based on 96MHz APLL */	ratio_bits = omap_readw(clk->enable_reg) & ~1;	omap_writew(ratio_bits, clk->enable_reg);	ratio_bits = (ratio_bits & 0xfc) >> 2;	if (ratio_bits > 6)		dsor = (ratio_bits - 6) * 2 + 8;	else		dsor = ratio_bits + 2;	clk-> rate = 96000000 / dsor;}static int omap1_clk_use(struct clk *clk){	int ret = 0;	if (clk->usecount++ == 0) {		if (likely(clk->parent)) {			ret = omap1_clk_use(clk->parent);			if (unlikely(ret != 0)) {				clk->usecount--;				return ret;			}			if (clk->flags & CLOCK_NO_IDLE_PARENT)				if (!cpu_is_omap24xx())					omap1_clk_deny_idle(clk->parent);		}		ret = clk->enable(clk);		if (unlikely(ret != 0) && clk->parent) {			omap1_clk_unuse(clk->parent);			clk->usecount--;		}	}	return ret;}static void omap1_clk_unuse(struct clk *clk){	if (clk->usecount > 0 && !(--clk->usecount)) {		clk->disable(clk);		if (likely(clk->parent)) {			omap1_clk_unuse(clk->parent);			if (clk->flags & CLOCK_NO_IDLE_PARENT)				if (!cpu_is_omap24xx())					omap1_clk_allow_idle(clk->parent);		}	}}static int omap1_clk_enable(struct clk *clk){	__u16 regval16;	__u32 regval32;	if (clk->flags & ALWAYS_ENABLED)		return 0;	if (unlikely(clk->enable_reg == 0)) {		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",		       clk->name);		return 0;	}	if (clk->flags & ENABLE_REG_32BIT) {		if (clk->flags & VIRTUAL_IO_ADDRESS) {			regval32 = __raw_readl(clk->enable_reg);			regval32 |= (1 << clk->enable_bit);			__raw_writel(regval32, clk->enable_reg);		} else {			regval32 = omap_readl(clk->enable_reg);			regval32 |= (1 << clk->enable_bit);			omap_writel(regval32, clk->enable_reg);		}	} else {		if (clk->flags & VIRTUAL_IO_ADDRESS) {			regval16 = __raw_readw(clk->enable_reg);			regval16 |= (1 << clk->enable_bit);			__raw_writew(regval16, clk->enable_reg);		} else {			regval16 = omap_readw(clk->enable_reg);			regval16 |= (1 << clk->enable_bit);			omap_writew(regval16, clk->enable_reg);		}	}	return 0;}static void omap1_clk_disable(struct clk *clk){	__u16 regval16;	__u32 regval32;	if (clk->enable_reg == 0)		return;	if (clk->flags & ENABLE_REG_32BIT) {		if (clk->flags & VIRTUAL_IO_ADDRESS) {			regval32 = __raw_readl(clk->enable_reg);			regval32 &= ~(1 << clk->enable_bit);			__raw_writel(regval32, clk->enable_reg);		} else {			regval32 = omap_readl(clk->enable_reg);			regval32 &= ~(1 << clk->enable_bit);			omap_writel(regval32, clk->enable_reg);		}	} else {		if (clk->flags & VIRTUAL_IO_ADDRESS) {			regval16 = __raw_readw(clk->enable_reg);			regval16 &= ~(1 << clk->enable_bit);			__raw_writew(regval16, clk->enable_reg);		} else {			regval16 = omap_readw(clk->enable_reg);			regval16 &= ~(1 << clk->enable_bit);			omap_writew(regval16, clk->enable_reg);		}	}}static long omap1_clk_round_rate(struct clk *clk, unsigned long rate){	int dsor_exp;	if (clk->flags & RATE_FIXED)		return clk->rate;	if (clk->flags & RATE_CKCTL) {		dsor_exp = calc_dsor_exp(clk, rate);		if (dsor_exp < 0)			return dsor_exp;		if (dsor_exp > 3)			dsor_exp = 3;		return clk->parent->rate / (1 << dsor_exp);	}	if(clk->round_rate != 0)		return clk->round_rate(clk, rate);	return clk->rate;}static int omap1_clk_set_rate(struct clk *clk, unsigned long rate){	int  ret = -EINVAL;	int  dsor_exp;	__u16  regval;	if (clk->set_rate)		ret = clk->set_rate(clk, rate);	else if (clk->flags & RATE_CKCTL) {		dsor_exp = calc_dsor_exp(clk, rate);		if (dsor_exp > 3)			dsor_exp = -EINVAL;		if (dsor_exp < 0)			return dsor_exp;		regval = omap_readw(ARM_CKCTL);		regval &= ~(3 << clk->rate_offset);		regval |= dsor_exp << clk->rate_offset;		regval = verify_ckctl_value(regval);		omap_writew(regval, ARM_CKCTL);		clk->rate = clk->parent->rate / (1 << dsor_exp);		ret = 0;	}	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))		propagate_rate(clk);	return ret;}/*------------------------------------------------------------------------- * Omap1 clock reset and init functions *-------------------------------------------------------------------------*/#ifdef CONFIG_OMAP_RESET_CLOCKS/* * Resets some clocks that may be left on from bootloader, * but leaves serial clocks on. See also omap_late_clk_reset(). */static inline void omap1_early_clk_reset(void){	//omap_writel(0x3 << 29, MOD_CONF_CTRL_0);}static int __init omap1_late_clk_reset(void){	/* Turn off all unused clocks */	struct clk *p;	__u32 regval32;	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */	regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4);	omap_writew(regval32, SOFT_REQ_REG);	omap_writew(0, SOFT_REQ_REG2);	list_for_each_entry(p, &clocks, node) {		if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||			p->enable_reg == 0)			continue;		/* Clocks in the DSP domain need api_ck. Just assume bootloader		 * has not enabled any DSP clocks */		if ((u32)p->enable_reg == DSP_IDLECT2) {			printk(KERN_INFO "Skipping reset check for DSP domain "			       "clock \"%s\"\n", p->name);			continue;		}		/* Is the clock already disabled? */		if (p->flags & ENABLE_REG_32BIT) {			if (p->flags & VIRTUAL_IO_ADDRESS)				regval32 = __raw_readl(p->enable_reg);			else				regval32 = omap_readl(p->enable_reg);		} else {			if (p->flags & VIRTUAL_IO_ADDRESS)				regval32 = __raw_readw(p->enable_reg);			else				regval32 = omap_readw(p->enable_reg);		}		if ((regval32 & (1 << p->enable_bit)) == 0)			continue;		/* FIXME: This clock seems to be necessary but no-one		 * has asked for its activation. */		if (p == &tc2_ck         // FIX: pm.c (SRAM), CCP, Camera		    || p == &ck_dpll1out.clk // FIX: SoSSI, SSR		    || p == &arm_gpio_ck // FIX: GPIO code for 1510		    ) {			printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",			       p->name);			continue;		}		printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);		p->disable(p);		printk(" done\n");	}	return 0;}late_initcall(omap1_late_clk_reset);#else#define omap1_early_clk_reset()	{}#endifstatic struct clk_functions omap1_clk_functions = {	.clk_use		= omap1_clk_use,	.clk_unuse		= omap1_clk_unuse,	.clk_round_rate		= omap1_clk_round_rate,	.clk_set_rate		= omap1_clk_set_rate,};int __init omap1_clk_init(void){	struct clk ** clkp;	const struct omap_clock_config *info;	int crystal_type = 0; /* Default 12 MHz */	omap1_early_clk_reset();	clk_init(&omap1_clk_functions);	/* By default all idlect1 clocks are allowed to idle */	arm_idlect1_mask = ~0;	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {		if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {			clk_register(*clkp);			continue;		}		if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {			clk_register(*clkp);			continue;		}		if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {			clk_register(*clkp);			continue;		}	}	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);	if (info != NULL) {		if (!cpu_is_omap1510())			crystal_type = info->system_clock_type;	}#if defined(CONFIG_ARCH_OMAP730)	ck_ref.rate = 13000000;#elif defined(CONFIG_ARCH_OMAP16XX)	if (crystal_type == 2)		ck_ref.rate = 19200000;#endif	printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",	       omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),	       omap_readw(ARM_CKCTL));	/* We want to be in syncronous scalable mode */	omap_writew(0x1000, ARM_SYSST);#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER	/* Use values set by bootloader. Determine PLL rate and recalculate	 * dependent clocks as if kernel had changed PLL or divisors.	 */	{		unsigned pll_ctl_val = omap_readw(DPLL_CTL);		ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */		if (pll_ctl_val & 0x10) {			/* PLL enabled, apply multiplier and divisor */			if (pll_ctl_val & 0xf80)				ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;			ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;		} else {			/* PLL disabled, apply bypass divisor */			switch (pll_ctl_val & 0xc) {			case 0:				break;			case 0x4:				ck_dpll1.rate /= 2;				break;			default:				ck_dpll1.rate /= 4;				break;			}		}	}	propagate_rate(&ck_dpll1);#else	/* Find the highest supported frequency and enable it */	if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {		printk(KERN_ERR "System frequencies not set. Check your config.\n");		/* Guess sane values (60MHz) */		omap_writew(0x2290, DPLL_CTL);		omap_writew(0x1005, ARM_CKCTL);		ck_dpll1.rate = 60000000;		propagate_rate(&ck_dpll1);	}#endif	/* Cache rates for clocks connected to ck_ref (not dpll1) */	propagate_rate(&ck_ref);	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "		"%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,	       ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,	       arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);#ifdef CONFIG_MACH_OMAP_PERSEUS2	/* Select slicer output as OMAP input clock */	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);#endif	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */	omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);	/* Put DSP/MPUI into reset until needed */	omap_writew(0, ARM_RSTCT1);	omap_writew(1, ARM_RSTCT2);	omap_writew(0x400, ARM_IDLECT1);	/*	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)	 * of the ARM_IDLECT2 register must be set to zero. The power-on	 * default value of this bit is one.	 */	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */	/*	 * Only enable those clocks we will need, let the drivers	 * enable other clocks as necessary	 */	clk_use(&armper_ck.clk);	clk_use(&armxor_ck.clk);	clk_use(&armtim_ck.clk); /* This should be done by timer code */	if (cpu_is_omap1510())		clk_enable(&arm_gpio_ck);	return 0;}

⌨️ 快捷键说明

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