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

📄 clock.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	l = omap_readl(MOD_CONF_CTRL_1);	l &= ~(7 << 17);	l |= div << 17;	omap_writel(l, MOD_CONF_CTRL_1);	clk->rate = p_rate / (div + 1);	if (unlikely(clk->flags & RATE_PROPAGATES))		propagate_rate(clk);	return 0;}static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate){	return 96000000 / calc_ext_dsor(rate);}static void omap1_init_ext_clk(struct clk * clk){	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_enable(struct clk *clk){	int ret = 0;	if (clk->usecount++ == 0) {		if (likely(clk->parent)) {			ret = omap1_clk_enable(clk->parent);			if (unlikely(ret != 0)) {				clk->usecount--;				return ret;			}			if (clk->flags & CLOCK_NO_IDLE_PARENT)				omap1_clk_deny_idle(clk->parent);		}		ret = clk->enable(clk);		if (unlikely(ret != 0) && clk->parent) {			omap1_clk_disable(clk->parent);			clk->usecount--;		}	}	return ret;}static void omap1_clk_disable(struct clk *clk){	if (clk->usecount > 0 && !(--clk->usecount)) {		clk->disable(clk);		if (likely(clk->parent)) {			omap1_clk_disable(clk->parent);			if (clk->flags & CLOCK_NO_IDLE_PARENT)				omap1_clk_allow_idle(clk->parent);		}	}}static int omap1_clk_enable_generic(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 -EINVAL;	}	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_generic(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_CLOCKSstatic void __init omap1_clk_disable_unused(struct clk *clk){	__u32 regval32;	/* Clocks in the DSP domain need api_ck. Just assume bootloader	 * has not enabled any DSP clocks */	if ((u32)clk->enable_reg == DSP_IDLECT2) {		printk(KERN_INFO "Skipping reset check for DSP domain "		       "clock \"%s\"\n", clk->name);		return;	}	/* Is the clock already disabled? */	if (clk->flags & ENABLE_REG_32BIT) {		if (clk->flags & VIRTUAL_IO_ADDRESS)			regval32 = __raw_readl(clk->enable_reg);			else				regval32 = omap_readl(clk->enable_reg);	} else {		if (clk->flags & VIRTUAL_IO_ADDRESS)			regval32 = __raw_readw(clk->enable_reg);		else			regval32 = omap_readw(clk->enable_reg);	}	if ((regval32 & (1 << clk->enable_bit)) == 0)		return;	/* FIXME: This clock seems to be necessary but no-one	 * has asked for its activation. */	if (clk == &tc2_ck		// FIX: pm.c (SRAM), CCP, Camera	    || clk == &ck_dpll1out.clk	// FIX: SoSSI, SSR	    || clk == &arm_gpio_ck	// FIX: GPIO code for 1510		) {		printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",		       clk->name);		return;	}	printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);	clk->disable(clk);	printk(" done\n");}#else#define omap1_clk_disable_unused	NULL#endifstatic struct clk_functions omap1_clk_functions = {	.clk_enable		= omap1_clk_enable,	.clk_disable		= omap1_clk_disable,	.clk_round_rate		= omap1_clk_round_rate,	.clk_set_rate		= omap1_clk_set_rate,	.clk_disable_unused	= omap1_clk_disable_unused,};int __init omap1_clk_init(void){	struct clk ** clkp;	const struct omap_clock_config *info;	int crystal_type = 0; /* Default 12 MHz */	u32 reg;#ifdef CONFIG_DEBUG_LL	/* Resets some clocks that may be left on from bootloader,	 * but leaves serial clocks on. 	 */	omap_writel(0x3 << 29, MOD_CONF_CTRL_0);#endif	/* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */	reg = omap_readw(SOFT_REQ_REG) & (1 << 4);	omap_writew(reg, SOFT_REQ_REG);	if (!cpu_is_omap15xx())		omap_writew(0, SOFT_REQ_REG2);	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;		}		if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {			clk_register(*clkp);			continue;		}	}	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);	if (info != NULL) {		if (!cpu_is_omap15xx())			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(cpu_is_omap730() ? 0x3005 : 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);#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)	/* Select slicer output as OMAP input clock */	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);#endif	/* Amstrad Delta wants BCLK high when inactive */	if (machine_is_ams_delta())		omap_writel(omap_readl(ULPD_CLOCK_CTRL) |				(1 << SDW_MCLK_INV_BIT),				ULPD_CLOCK_CTRL);	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */	/* (on 730, bit 13 must not be cleared) */	if (cpu_is_omap730())		omap_writew(omap_readw(ARM_CKCTL) & 0x2fff, ARM_CKCTL);	else		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_enable(&armper_ck.clk);	clk_enable(&armxor_ck.clk);	clk_enable(&armtim_ck.clk); /* This should be done by timer code */	if (cpu_is_omap15xx())		clk_enable(&arm_gpio_ck);	return 0;}

⌨️ 快捷键说明

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