Exemple #1
0
int set_high_bus_freq(int high_bus_freq)
{
	int ret = 0;
	unsigned long flags;
	unsigned long lp_lpm_clk;

	if (!low_bus_freq_mode)
		return ret;

	if (dvfs_per_active())
		return ret;

	/* Set the voltage to 1.25V for the LP domain. */
	ret = regulator_set_voltage(lp_regulator, 1250000, 1250000);
	udelay(100);
	if (ret < 0) {
		printk(KERN_ERR "COULD NOT SET LP VOLTAGE!!!!!!\n");
		return ret;
	}

	spin_lock_irqsave(&bus_freq_lock, flags);

	low_bus_freq_mode = 0;

	/* Set the LP clocks. */
	lp_lpm_clk = clk_get_rate(periph_apm_clk);
	clk_set_rate(axi_a_clk, clk_round_rate(axi_a_clk, lp_lpm_clk/5));
	clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, lp_lpm_clk/5));
	clk_set_rate(axi_c_clk, clk_round_rate(axi_c_clk, lp_lpm_clk/5));
	clk_set_rate(emi_core_clk, clk_round_rate(emi_core_clk, lp_lpm_clk/5));
	clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, lp_lpm_clk/5));
	/* Set emi_intr clock back to divide by 2. */
	clk_set_rate(emi_intr_clk, clk_round_rate(emi_intr_clk, lp_lpm_clk/10));

	/* Set the parent of main_bus_clk to be pll2 */
	clk_set_parent(main_bus_clk, pll2);

	high_bus_freq_mode = 1;

	spin_unlock_irqrestore(&bus_freq_lock, flags);

	start_dvfs_per();
	return ret;
}
Exemple #2
0
int set_high_bus_freq(int high_bus_freq)
{
	u32 reg;
	if (bus_freq_scaling_initialized) {
		mutex_lock(&bus_freq_mutex);
		/*
		 * If the CPU freq is 800MHz, set the bus to the high
		 * setpoint (133MHz) and DDR to 200MHz.
		 */
		if ((clk_get_rate(cpu_clk) >
				cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate)
				|| lp_high_freq)
			high_bus_freq = 1;

		stop_sdram_autogating();

		if (low_bus_freq_mode) {
			/* Relock PLL3 to 133MHz */
			if (cpu_is_mx50())
				exit_lpapm_mode_mx50(high_bus_freq);
			else if (cpu_is_mx51())
				exit_lpapm_mode_mx51();
			else
				exit_lpapm_mode_mx53();
			start_dvfs_per();
		}
		if (bus_freq_scaling_is_active) {
			if (!high_bus_freq_mode && high_bus_freq) {
				if (cpu_is_mx50()) {
					if (med_bus_freq_mode) {
						/* Increase SYS_CLK */
						reg = __raw_readl(MXC_CCM_CLK_SYS);
						reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK;
						reg |= 4 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET;
						__raw_writel(reg, MXC_CCM_CLK_SYS);

						/* Set the dividers to the default dividers */
						reg = __raw_readl(MXC_CCM_CBCDR);
						reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
							| MXC_CCM_CBCDR_AXI_B_PODF_MASK
							| MXC_CCM_CBCDR_AHB_PODF_MASK
							| MX50_CCM_CBCDR_WEIM_PODF_MASK);
						reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
							|1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
							|2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
							|0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
						__raw_writel(reg, MXC_CCM_CBCDR);

						while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
							udelay(10);
					}
				} else {
					clk_set_rate(ahb_clk,
						clk_round_rate(ahb_clk,
							lp_normal_rate));
					clk_set_rate(ddr_hf_clk,
						clk_round_rate(ddr_hf_clk,
							ddr_normal_rate));
				}
				/* Set to the high setpoint. */
				high_bus_freq_mode = 1;
				low_bus_freq_mode = 0;
				med_bus_freq_mode = 0;
			} else if (!med_bus_freq_mode && !high_bus_freq) {
				if (cpu_is_mx50()) {
					/* Set the dividers to the medium setpoint dividers */
					reg = __raw_readl(MXC_CCM_CBCDR);
					reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
						| MXC_CCM_CBCDR_AXI_B_PODF_MASK
						| MXC_CCM_CBCDR_AHB_PODF_MASK
						| MX50_CCM_CBCDR_WEIM_PODF_MASK);
					reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
						|3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
						|5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
						|0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
					__raw_writel(reg, MXC_CCM_CBCDR);

					while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
						udelay(10);
					/* Reduce SYS_CLK */
					reg = __raw_readl(MXC_CCM_CLK_SYS);
					reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK;
					reg |= 8 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET;
					__raw_writel(reg, MXC_CCM_CLK_SYS);
				} else {
					if (cpu_is_mx51())
						clk_set_rate(ddr_hf_clk,
							clk_round_rate(
							ddr_hf_clk,
							ddr_low_rate));
					clk_set_rate(ahb_clk,
					clk_round_rate(
						ahb_clk, lp_med_rate));
				}
				/* Set to the medium setpoint. */
				high_bus_freq_mode = 0;
				low_bus_freq_mode = 0;
				med_bus_freq_mode = 1;
			}
			if (cpu_is_mx50()) {
				if (med_bus_freq_mode &&
					(cur_ddr_rate != ddr_med_rate))
					set_ddr_freq(ddr_med_rate);
				if (high_bus_freq_mode &&
					(cur_ddr_rate != ddr_normal_rate))
					set_ddr_freq(ddr_normal_rate);
			}
		}
		start_sdram_autogating();
		mutex_unlock(&bus_freq_mutex);
	}
	return 0;
}
/*!
 * Enable DVFS Peripheral
 *
 */
int dvfs_enable(struct device *dev)
{
	if (dvfs_per_is_active)
		return 0;
	return (start_dvfs_per());
}